Path: blob/master/src/hotspot/share/interpreter/rewriter.cpp
40949 views
/*1* Copyright (c) 1998, 2021, 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"25#include "cds/metaspaceShared.hpp"26#include "classfile/vmClasses.hpp"27#include "interpreter/bytecodes.hpp"28#include "interpreter/interpreter.hpp"29#include "interpreter/rewriter.hpp"30#include "memory/metadataFactory.hpp"31#include "memory/resourceArea.hpp"32#include "oops/constantPool.hpp"33#include "oops/generateOopMap.hpp"34#include "prims/methodHandles.hpp"35#include "runtime/fieldDescriptor.inline.hpp"36#include "runtime/handles.inline.hpp"3738// Computes a CPC map (new_index -> original_index) for constant pool entries39// that are referred to by the interpreter at runtime via the constant pool cache.40// Also computes a CP map (original_index -> new_index).41// Marks entries in CP which require additional processing.42void Rewriter::compute_index_maps() {43const int length = _pool->length();44init_maps(length);45bool saw_mh_symbol = false;46for (int i = 0; i < length; i++) {47int tag = _pool->tag_at(i).value();48switch (tag) {49case JVM_CONSTANT_InterfaceMethodref:50case JVM_CONSTANT_Fieldref : // fall through51case JVM_CONSTANT_Methodref : // fall through52add_cp_cache_entry(i);53break;54case JVM_CONSTANT_Dynamic:55assert(_pool->has_dynamic_constant(), "constant pool's _has_dynamic_constant flag not set");56add_resolved_references_entry(i);57break;58case JVM_CONSTANT_String : // fall through59case JVM_CONSTANT_MethodHandle : // fall through60case JVM_CONSTANT_MethodType : // fall through61add_resolved_references_entry(i);62break;63case JVM_CONSTANT_Utf8:64if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle() ||65_pool->symbol_at(i) == vmSymbols::java_lang_invoke_VarHandle()) {66saw_mh_symbol = true;67}68break;69}70}7172// Record limits of resolved reference map for constant pool cache indices73record_map_limits();7475guarantee((int) _cp_cache_map.length() - 1 <= (int) ((u2)-1),76"all cp cache indexes fit in a u2");7778if (saw_mh_symbol) {79_method_handle_invokers.at_grow(length, 0);80}81}8283// Unrewrite the bytecodes if an error occurs.84void Rewriter::restore_bytecodes(Thread* thread) {85int len = _methods->length();86bool invokespecial_error = false;8788for (int i = len-1; i >= 0; i--) {89Method* method = _methods->at(i);90scan_method(thread, method, true, &invokespecial_error);91assert(!invokespecial_error, "reversing should not get an invokespecial error");92}93}9495// Creates a constant pool cache given a CPC map96void Rewriter::make_constant_pool_cache(TRAPS) {97ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();98ConstantPoolCache* cache =99ConstantPoolCache::allocate(loader_data, _cp_cache_map,100_invokedynamic_cp_cache_map,101_invokedynamic_references_map, CHECK);102103// initialize object cache in constant pool104_pool->set_cache(cache);105cache->set_constant_pool(_pool());106107// _resolved_references is stored in pool->cache(), so need to be done after108// the above lines.109_pool->initialize_resolved_references(loader_data, _resolved_references_map,110_resolved_reference_limit,111THREAD);112113// Clean up constant pool cache if initialize_resolved_references() failed.114if (HAS_PENDING_EXCEPTION) {115MetadataFactory::free_metadata(loader_data, cache);116_pool->set_cache(NULL); // so the verifier isn't confused117} else {118DEBUG_ONLY(119if (DumpSharedSpaces) {120cache->verify_just_initialized();121})122}123}124125126127// The new finalization semantics says that registration of128// finalizable objects must be performed on successful return from the129// Object.<init> constructor. We could implement this trivially if130// <init> were never rewritten but since JVMTI allows this to occur, a131// more complicated solution is required. A special return bytecode132// is used only by Object.<init> to signal the finalization133// registration point. Additionally local 0 must be preserved so it's134// available to pass to the registration function. For simplicity we135// require that local 0 is never overwritten so it's available as an136// argument for registration.137138void Rewriter::rewrite_Object_init(const methodHandle& method, TRAPS) {139RawBytecodeStream bcs(method);140while (!bcs.is_last_bytecode()) {141Bytecodes::Code opcode = bcs.raw_next();142switch (opcode) {143case Bytecodes::_return: *bcs.bcp() = Bytecodes::_return_register_finalizer; break;144145case Bytecodes::_istore:146case Bytecodes::_lstore:147case Bytecodes::_fstore:148case Bytecodes::_dstore:149case Bytecodes::_astore:150if (bcs.get_index() != 0) continue;151152// fall through153case Bytecodes::_istore_0:154case Bytecodes::_lstore_0:155case Bytecodes::_fstore_0:156case Bytecodes::_dstore_0:157case Bytecodes::_astore_0:158THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),159"can't overwrite local 0 in Object.<init>");160break;161162default:163break;164}165}166}167168169// Rewrite a classfile-order CP index into a native-order CPC index.170void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) {171address p = bcp + offset;172if (!reverse) {173int cp_index = Bytes::get_Java_u2(p);174int cache_index = cp_entry_to_cp_cache(cp_index);175Bytes::put_native_u2(p, cache_index);176if (!_method_handle_invokers.is_empty())177maybe_rewrite_invokehandle(p - 1, cp_index, cache_index, reverse);178} else {179int cache_index = Bytes::get_native_u2(p);180int pool_index = cp_cache_entry_pool_index(cache_index);181Bytes::put_Java_u2(p, pool_index);182if (!_method_handle_invokers.is_empty())183maybe_rewrite_invokehandle(p - 1, pool_index, cache_index, reverse);184}185}186187// If the constant pool entry for invokespecial is InterfaceMethodref,188// we need to add a separate cpCache entry for its resolution, because it is189// different than the resolution for invokeinterface with InterfaceMethodref.190// These cannot share cpCache entries.191void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {192address p = bcp + offset;193if (!reverse) {194int cp_index = Bytes::get_Java_u2(p);195if (_pool->tag_at(cp_index).is_interface_method()) {196int cache_index = add_invokespecial_cp_cache_entry(cp_index);197if (cache_index != (int)(jushort) cache_index) {198*invokespecial_error = true;199}200Bytes::put_native_u2(p, cache_index);201} else {202rewrite_member_reference(bcp, offset, reverse);203}204} else {205rewrite_member_reference(bcp, offset, reverse);206}207}208209210// Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)211void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) {212if (!reverse) {213if ((*opc) == (u1)Bytecodes::_invokevirtual ||214// allow invokespecial as an alias, although it would be very odd:215(*opc) == (u1)Bytecodes::_invokespecial) {216assert(_pool->tag_at(cp_index).is_method(), "wrong index");217// Determine whether this is a signature-polymorphic method.218if (cp_index >= _method_handle_invokers.length()) return;219int status = _method_handle_invokers.at(cp_index);220assert(status >= -1 && status <= 1, "oob tri-state");221if (status == 0) {222if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&223MethodHandles::is_signature_polymorphic_name(vmClasses::MethodHandle_klass(),224_pool->name_ref_at(cp_index))) {225// we may need a resolved_refs entry for the appendix226add_invokedynamic_resolved_references_entry(cp_index, cache_index);227status = +1;228} else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&229MethodHandles::is_signature_polymorphic_name(vmClasses::VarHandle_klass(),230_pool->name_ref_at(cp_index))) {231// we may need a resolved_refs entry for the appendix232add_invokedynamic_resolved_references_entry(cp_index, cache_index);233status = +1;234} else {235status = -1;236}237_method_handle_invokers.at(cp_index) = status;238}239// We use a special internal bytecode for such methods (if non-static).240// The basic reason for this is that such methods need an extra "appendix" argument241// to transmit the call site's intended call type.242if (status > 0) {243(*opc) = (u1)Bytecodes::_invokehandle;244}245}246} else {247// Do not need to look at cp_index.248if ((*opc) == (u1)Bytecodes::_invokehandle) {249(*opc) = (u1)Bytecodes::_invokevirtual;250// Ignore corner case of original _invokespecial instruction.251// This is safe because (a) the signature polymorphic method was final, and252// (b) the implementation of MethodHandle will not call invokespecial on it.253}254}255}256257258void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {259address p = bcp + offset;260assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode");261if (!reverse) {262int cp_index = Bytes::get_Java_u2(p);263int cache_index = add_invokedynamic_cp_cache_entry(cp_index);264int resolved_index = add_invokedynamic_resolved_references_entry(cp_index, cache_index);265// Replace the trailing four bytes with a CPC index for the dynamic266// call site. Unlike other CPC entries, there is one per bytecode,267// not just one per distinct CP entry. In other words, the268// CPC-to-CP relation is many-to-one for invokedynamic entries.269// This means we must use a larger index size than u2 to address270// all these entries. That is the main reason invokedynamic271// must have a five-byte instruction format. (Of course, other JVM272// implementations can use the bytes for other purposes.)273// Note: We use native_u4 format exclusively for 4-byte indexes.274Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index));275// add the bcp in case we need to patch this bytecode if we also find a276// invokespecial/InterfaceMethodref in the bytecode stream277_patch_invokedynamic_bcps->push(p);278_patch_invokedynamic_refs->push(resolved_index);279} else {280int cache_index = ConstantPool::decode_invokedynamic_index(281Bytes::get_native_u4(p));282// We will reverse the bytecode rewriting _after_ adjusting them.283// Adjust the cache index by offset to the invokedynamic entries in the284// cpCache plus the delta if the invokedynamic bytecodes were adjusted.285int adjustment = cp_cache_delta() + _first_iteration_cp_cache_limit;286int cp_index = invokedynamic_cp_cache_entry_pool_index(cache_index - adjustment);287assert(_pool->tag_at(cp_index).is_invoke_dynamic(), "wrong index");288// zero out 4 bytes289Bytes::put_Java_u4(p, 0);290Bytes::put_Java_u2(p, cp_index);291}292}293294void Rewriter::patch_invokedynamic_bytecodes() {295// If the end of the cp_cache is the same as after initializing with the296// cpool, nothing needs to be done. Invokedynamic bytecodes are at the297// correct offsets. ie. no invokespecials added298int delta = cp_cache_delta();299if (delta > 0) {300int length = _patch_invokedynamic_bcps->length();301assert(length == _patch_invokedynamic_refs->length(),302"lengths should match");303for (int i = 0; i < length; i++) {304address p = _patch_invokedynamic_bcps->at(i);305int cache_index = ConstantPool::decode_invokedynamic_index(306Bytes::get_native_u4(p));307Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index + delta));308309// invokedynamic resolved references map also points to cp cache and must310// add delta to each.311int resolved_index = _patch_invokedynamic_refs->at(i);312assert(_invokedynamic_references_map.at(resolved_index) == cache_index,313"should be the same index");314_invokedynamic_references_map.at_put(resolved_index, cache_index + delta);315}316}317}318319320// Rewrite some ldc bytecodes to _fast_aldc321void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide,322bool reverse) {323if (!reverse) {324assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), "not ldc bytecode");325address p = bcp + offset;326int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p);327constantTag tag = _pool->tag_at(cp_index).value();328329if (tag.is_method_handle() ||330tag.is_method_type() ||331tag.is_string() ||332(tag.is_dynamic_constant() &&333// keep regular ldc interpreter logic for condy primitives334is_reference_type(Signature::basic_type(_pool->uncached_signature_ref_at(cp_index))))335) {336int ref_index = cp_entry_to_resolved_references(cp_index);337if (is_wide) {338(*bcp) = Bytecodes::_fast_aldc_w;339assert(ref_index == (u2)ref_index, "index overflow");340Bytes::put_native_u2(p, ref_index);341} else {342(*bcp) = Bytecodes::_fast_aldc;343assert(ref_index == (u1)ref_index, "index overflow");344(*p) = (u1)ref_index;345}346}347} else {348Bytecodes::Code rewritten_bc =349(is_wide ? Bytecodes::_fast_aldc_w : Bytecodes::_fast_aldc);350if ((*bcp) == rewritten_bc) {351address p = bcp + offset;352int ref_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p);353int pool_index = resolved_references_entry_to_pool_index(ref_index);354if (is_wide) {355(*bcp) = Bytecodes::_ldc_w;356assert(pool_index == (u2)pool_index, "index overflow");357Bytes::put_Java_u2(p, pool_index);358} else {359(*bcp) = Bytecodes::_ldc;360assert(pool_index == (u1)pool_index, "index overflow");361(*p) = (u1)pool_index;362}363}364}365}366367368// Rewrites a method given the index_map information369void Rewriter::scan_method(Thread* thread, Method* method, bool reverse, bool* invokespecial_error) {370371int nof_jsrs = 0;372bool has_monitor_bytecodes = false;373Bytecodes::Code c;374375// Bytecodes and their length376const address code_base = method->code_base();377const int code_length = method->code_size();378379int bc_length;380for (int bci = 0; bci < code_length; bci += bc_length) {381address bcp = code_base + bci;382int prefix_length = 0;383c = (Bytecodes::Code)(*bcp);384385// Since we have the code, see if we can get the length386// directly. Some more complicated bytecodes will report387// a length of zero, meaning we need to make another method388// call to calculate the length.389bc_length = Bytecodes::length_for(c);390if (bc_length == 0) {391bc_length = Bytecodes::length_at(method, bcp);392393// length_at will put us at the bytecode after the one modified394// by 'wide'. We don't currently examine any of the bytecodes395// modified by wide, but in case we do in the future...396if (c == Bytecodes::_wide) {397prefix_length = 1;398c = (Bytecodes::Code)bcp[1];399}400}401402// Continuing with an invalid bytecode will fail in the loop below.403// So guarantee here.404guarantee(bc_length > 0, "Verifier should have caught this invalid bytecode");405406switch (c) {407case Bytecodes::_lookupswitch : {408#ifndef ZERO409Bytecode_lookupswitch bc(method, bcp);410(*bcp) = (411bc.number_of_pairs() < BinarySwitchThreshold412? Bytecodes::_fast_linearswitch413: Bytecodes::_fast_binaryswitch414);415#endif416break;417}418case Bytecodes::_fast_linearswitch:419case Bytecodes::_fast_binaryswitch: {420#ifndef ZERO421(*bcp) = Bytecodes::_lookupswitch;422#endif423break;424}425426case Bytecodes::_invokespecial : {427rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);428break;429}430431case Bytecodes::_putstatic :432case Bytecodes::_putfield : {433if (!reverse) {434// Check if any final field of the class given as parameter is modified435// outside of initializer methods of the class. Fields that are modified436// are marked with a flag. For marked fields, the compilers do not perform437// constant folding (as the field can be changed after initialization).438//439// The check is performed after verification and only if verification has440// succeeded. Therefore, the class is guaranteed to be well-formed.441InstanceKlass* klass = method->method_holder();442u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);443constantPoolHandle cp(thread, method->constants());444Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));445446if (klass->name() == ref_class_name) {447Symbol* field_name = cp->name_ref_at(bc_index);448Symbol* field_sig = cp->signature_ref_at(bc_index);449450fieldDescriptor fd;451if (klass->find_field(field_name, field_sig, &fd) != NULL) {452if (fd.access_flags().is_final()) {453if (fd.access_flags().is_static()) {454if (!method->is_static_initializer()) {455fd.set_has_initialized_final_update(true);456}457} else {458if (!method->is_object_initializer()) {459fd.set_has_initialized_final_update(true);460}461}462}463}464}465}466}467// fall through468case Bytecodes::_getstatic : // fall through469case Bytecodes::_getfield : // fall through470case Bytecodes::_invokevirtual : // fall through471case Bytecodes::_invokestatic :472case Bytecodes::_invokeinterface:473case Bytecodes::_invokehandle : // if reverse=true474rewrite_member_reference(bcp, prefix_length+1, reverse);475break;476case Bytecodes::_invokedynamic:477rewrite_invokedynamic(bcp, prefix_length+1, reverse);478break;479case Bytecodes::_ldc:480case Bytecodes::_fast_aldc: // if reverse=true481maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);482break;483case Bytecodes::_ldc_w:484case Bytecodes::_fast_aldc_w: // if reverse=true485maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);486break;487case Bytecodes::_jsr : // fall through488case Bytecodes::_jsr_w : nof_jsrs++; break;489case Bytecodes::_monitorenter : // fall through490case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break;491492default: break;493}494}495496// Update access flags497if (has_monitor_bytecodes) {498method->set_has_monitor_bytecodes();499}500501// The present of a jsr bytecode implies that the method might potentially502// have to be rewritten, so we run the oopMapGenerator on the method503if (nof_jsrs > 0) {504method->set_has_jsrs();505// Second pass will revisit this method.506assert(method->has_jsrs(), "didn't we just set this?");507}508}509510// After constant pool is created, revisit methods containing jsrs.511methodHandle Rewriter::rewrite_jsrs(const methodHandle& method, TRAPS) {512ResourceMark rm(THREAD);513ResolveOopMapConflicts romc(method);514methodHandle new_method = romc.do_potential_rewrite(CHECK_(methodHandle()));515// Update monitor matching info.516if (romc.monitor_safe()) {517new_method->set_guaranteed_monitor_matching();518}519520return new_method;521}522523void Rewriter::rewrite_bytecodes(TRAPS) {524assert(_pool->cache() == NULL, "constant pool cache must not be set yet");525526// determine index maps for Method* rewriting527compute_index_maps();528529if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) {530bool did_rewrite = false;531int i = _methods->length();532while (i-- > 0) {533Method* method = _methods->at(i);534if (method->intrinsic_id() == vmIntrinsics::_Object_init) {535// rewrite the return bytecodes of Object.<init> to register the536// object for finalization if needed.537methodHandle m(THREAD, method);538rewrite_Object_init(m, CHECK);539did_rewrite = true;540break;541}542}543assert(did_rewrite, "must find Object::<init> to rewrite it");544}545546// rewrite methods, in two passes547int len = _methods->length();548bool invokespecial_error = false;549550for (int i = len-1; i >= 0; i--) {551Method* method = _methods->at(i);552scan_method(THREAD, method, false, &invokespecial_error);553if (invokespecial_error) {554// If you get an error here, there is no reversing bytecodes555// This exception is stored for this class and no further attempt is556// made at verifying or rewriting.557THROW_MSG(vmSymbols::java_lang_InternalError(),558"This classfile overflows invokespecial for interfaces "559"and cannot be loaded");560return;561}562}563564// May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref565// entries had to be added.566patch_invokedynamic_bytecodes();567}568569void Rewriter::rewrite(InstanceKlass* klass, TRAPS) {570#if INCLUDE_CDS571if (klass->is_shared()) {572assert(!klass->is_rewritten(), "rewritten shared classes cannot be rewritten again");573assert(klass->can_be_verified_at_dumptime(), "only shared old classes aren't rewritten");574}575#endif // INCLUDE_CDS576ResourceMark rm(THREAD);577constantPoolHandle cpool(THREAD, klass->constants());578Rewriter rw(klass, cpool, klass->methods(), CHECK);579// (That's all, folks.)580}581582Rewriter::Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS)583: _klass(klass),584_pool(cpool),585_methods(methods),586_cp_map(cpool->length()),587_cp_cache_map(cpool->length() / 2),588_reference_map(cpool->length()),589_resolved_references_map(cpool->length() / 2),590_invokedynamic_references_map(cpool->length() / 2),591_method_handle_invokers(cpool->length()),592_invokedynamic_cp_cache_map(cpool->length() / 4)593{594595// Rewrite bytecodes - exception here exits.596rewrite_bytecodes(CHECK);597598// Stress restoring bytecodes599if (StressRewriter) {600restore_bytecodes(THREAD);601rewrite_bytecodes(CHECK);602}603604// allocate constant pool cache, now that we've seen all the bytecodes605make_constant_pool_cache(THREAD);606607// Restore bytecodes to their unrewritten state if there are exceptions608// rewriting bytecodes or allocating the cpCache609if (HAS_PENDING_EXCEPTION) {610restore_bytecodes(THREAD);611return;612}613614// Relocate after everything, but still do this under the is_rewritten flag,615// so methods with jsrs in custom class lists in aren't attempted to be616// rewritten in the RO section of the shared archive.617// Relocated bytecodes don't have to be restored, only the cp cache entries618int len = _methods->length();619for (int i = len-1; i >= 0; i--) {620methodHandle m(THREAD, _methods->at(i));621622if (m->has_jsrs()) {623m = rewrite_jsrs(m, THREAD);624// Restore bytecodes to their unrewritten state if there are exceptions625// relocating bytecodes. If some are relocated, that is ok because that626// doesn't affect constant pool to cpCache rewriting.627if (HAS_PENDING_EXCEPTION) {628restore_bytecodes(THREAD);629return;630}631// Method might have gotten rewritten.632methods->at_put(i, m());633}634}635}636637638