Path: blob/master/src/hotspot/share/classfile/bytecodeAssembler.cpp
40949 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"2526#include "classfile/bytecodeAssembler.hpp"27#include "interpreter/bytecodes.hpp"28#include "memory/oopFactory.hpp"29#include "oops/constantPool.hpp"30#include "runtime/handles.inline.hpp"31#include "utilities/bytes.hpp"3233u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {3435u2 index = _entries.length();36bool created = false;37u2* probe = _indices.put_if_absent(bcpe, index, &created);38if (created) {39_entries.append(bcpe);40} else {41index = *probe;42}43return index + _orig->length();44}4546ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {47if (_entries.length() == 0) {48return _orig;49}5051ConstantPool* cp = ConstantPool::allocate(52_orig->pool_holder()->class_loader_data(),53_orig->length() + _entries.length(), CHECK_NULL);5455cp->set_pool_holder(_orig->pool_holder());56constantPoolHandle cp_h(THREAD, cp);57_orig->copy_cp_to(1, _orig->length() - 1, cp_h, 1, CHECK_NULL);5859// Preserve dynamic constant information from the original pool60cp->copy_fields(_orig);6162for (int i = 0; i < _entries.length(); ++i) {63BytecodeCPEntry entry = _entries.at(i);64int idx = i + _orig->length();65switch (entry._tag) {66case BytecodeCPEntry::UTF8:67entry._u.utf8->increment_refcount();68cp->symbol_at_put(idx, entry._u.utf8);69break;70case BytecodeCPEntry::KLASS:71cp->klass_index_at_put(72idx, entry._u.klass);73break;74case BytecodeCPEntry::STRING:75cp->unresolved_string_at_put(76idx, cp->symbol_at(entry._u.string));77break;78case BytecodeCPEntry::NAME_AND_TYPE:79cp->name_and_type_at_put(idx,80entry._u.name_and_type.name_index,81entry._u.name_and_type.type_index);82break;83case BytecodeCPEntry::METHODREF:84cp->method_at_put(idx,85entry._u.methodref.class_index,86entry._u.methodref.name_and_type_index);87break;88default:89ShouldNotReachHere();90}91}9293cp->initialize_unresolved_klasses(_orig->pool_holder()->class_loader_data(),94CHECK_NULL);95return cp;96}9798void BytecodeAssembler::append(u1 imm_u1) {99_code->append(imm_u1);100}101102void BytecodeAssembler::append(u2 imm_u2) {103_code->append(0);104_code->append(0);105Bytes::put_Java_u2(_code->adr_at(_code->length() - 2), imm_u2);106}107108void BytecodeAssembler::append(u4 imm_u4) {109_code->append(0);110_code->append(0);111_code->append(0);112_code->append(0);113Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4);114}115116void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) {117if (index < 4) {118_code->append(onebyteop + index);119} else {120_code->append(twobyteop);121_code->append((u2)index);122}123}124125void BytecodeAssembler::dup() {126_code->append(Bytecodes::_dup);127}128129void BytecodeAssembler::_new(Symbol* sym) {130u2 cpool_index = _cp->klass(sym);131_code->append(Bytecodes::_new);132append(cpool_index);133}134135void BytecodeAssembler::load_string(Symbol* sym) {136u2 cpool_index = _cp->string(sym);137if (cpool_index < 0x100) {138ldc(cpool_index);139} else {140ldc_w(cpool_index);141}142}143144void BytecodeAssembler::ldc(u1 index) {145_code->append(Bytecodes::_ldc);146append(index);147}148149void BytecodeAssembler::ldc_w(u2 index) {150_code->append(Bytecodes::_ldc_w);151append(index);152}153154void BytecodeAssembler::athrow() {155_code->append(Bytecodes::_athrow);156}157158void BytecodeAssembler::iload(u4 index) {159xload(index, Bytecodes::_iload_0, Bytecodes::_iload);160}161162void BytecodeAssembler::lload(u4 index) {163xload(index, Bytecodes::_lload_0, Bytecodes::_lload);164}165166void BytecodeAssembler::fload(u4 index) {167xload(index, Bytecodes::_fload_0, Bytecodes::_fload);168}169170void BytecodeAssembler::dload(u4 index) {171xload(index, Bytecodes::_dload_0, Bytecodes::_dload);172}173174void BytecodeAssembler::aload(u4 index) {175xload(index, Bytecodes::_aload_0, Bytecodes::_aload);176}177178void BytecodeAssembler::load(BasicType bt, u4 index) {179switch (bt) {180case T_BOOLEAN:181case T_CHAR:182case T_BYTE:183case T_SHORT:184case T_INT: iload(index); break;185case T_FLOAT: fload(index); break;186case T_DOUBLE: dload(index); break;187case T_LONG: lload(index); break;188default:189if (is_reference_type(bt)) {190aload(index);191break;192}193ShouldNotReachHere();194}195}196197void BytecodeAssembler::checkcast(Symbol* sym) {198u2 cpool_index = _cp->klass(sym);199_code->append(Bytecodes::_checkcast);200append(cpool_index);201}202203void BytecodeAssembler::invokespecial(Method* method) {204invokespecial(method->klass_name(), method->name(), method->signature());205}206207void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) {208u2 methodref_index = _cp->methodref(klss, name, sig);209_code->append(Bytecodes::_invokespecial);210append(methodref_index);211}212213void BytecodeAssembler::invokevirtual(Method* method) {214invokevirtual(method->klass_name(), method->name(), method->signature());215}216217void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) {218u2 methodref_index = _cp->methodref(klss, name, sig);219_code->append(Bytecodes::_invokevirtual);220append(methodref_index);221}222223void BytecodeAssembler::ireturn() {224_code->append(Bytecodes::_ireturn);225}226227void BytecodeAssembler::lreturn() {228_code->append(Bytecodes::_lreturn);229}230231void BytecodeAssembler::freturn() {232_code->append(Bytecodes::_freturn);233}234235void BytecodeAssembler::dreturn() {236_code->append(Bytecodes::_dreturn);237}238239void BytecodeAssembler::areturn() {240_code->append(Bytecodes::_areturn);241}242243void BytecodeAssembler::_return() {244_code->append(Bytecodes::_return);245}246247void BytecodeAssembler::_return(BasicType bt) {248switch (bt) {249case T_BOOLEAN:250case T_CHAR:251case T_BYTE:252case T_SHORT:253case T_INT: ireturn(); break;254case T_FLOAT: freturn(); break;255case T_DOUBLE: dreturn(); break;256case T_LONG: lreturn(); break;257case T_VOID: _return(); break;258default:259if (is_reference_type(bt)) {260areturn();261break;262}263ShouldNotReachHere();264}265}266267268