Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/ci/ciEnv.cpp
32285 views
/*1* Copyright (c) 1999, 2014, 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 "ci/ciConstant.hpp"26#include "ci/ciEnv.hpp"27#include "ci/ciField.hpp"28#include "ci/ciInstance.hpp"29#include "ci/ciInstanceKlass.hpp"30#include "ci/ciMethod.hpp"31#include "ci/ciNullObject.hpp"32#include "ci/ciReplay.hpp"33#include "ci/ciUtilities.hpp"34#include "classfile/systemDictionary.hpp"35#include "classfile/vmSymbols.hpp"36#include "code/scopeDesc.hpp"37#include "compiler/compileBroker.hpp"38#include "compiler/compileLog.hpp"39#include "compiler/compilerOracle.hpp"40#include "gc_interface/collectedHeap.inline.hpp"41#include "interpreter/linkResolver.hpp"42#include "jfr/jfrEvents.hpp"43#include "memory/allocation.inline.hpp"44#include "memory/oopFactory.hpp"45#include "memory/universe.inline.hpp"46#include "oops/methodData.hpp"47#include "oops/objArrayKlass.hpp"48#include "oops/oop.inline.hpp"49#include "oops/oop.inline2.hpp"50#include "prims/jvmtiExport.hpp"51#include "runtime/init.hpp"52#include "runtime/reflection.hpp"53#include "runtime/sharedRuntime.hpp"54#include "runtime/thread.inline.hpp"55#include "utilities/dtrace.hpp"56#include "utilities/macros.hpp"57#ifdef COMPILER158#include "c1/c1_Runtime1.hpp"59#endif60#ifdef COMPILER261#include "opto/runtime.hpp"62#endif6364// ciEnv65//66// This class is the top level broker for requests from the compiler67// to the VM.6869ciObject* ciEnv::_null_object_instance;7071#define WK_KLASS_DEFN(name, ignore_s, ignore_o) ciInstanceKlass* ciEnv::_##name = NULL;72WK_KLASSES_DO(WK_KLASS_DEFN)73#undef WK_KLASS_DEFN7475ciSymbol* ciEnv::_unloaded_cisymbol = NULL;76ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;77ciObjArrayKlass* ciEnv::_unloaded_ciobjarrayklass = NULL;7879jobject ciEnv::_ArrayIndexOutOfBoundsException_handle = NULL;80jobject ciEnv::_ArrayStoreException_handle = NULL;81jobject ciEnv::_ClassCastException_handle = NULL;8283#ifndef PRODUCT84static bool firstEnv = true;85#endif /* PRODUCT */8687// ------------------------------------------------------------------88// ciEnv::ciEnv89ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter)90: _ciEnv_arena(mtCompiler) {91VM_ENTRY_MARK;9293// Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.94thread->set_env(this);95assert(ciEnv::current() == this, "sanity");9697_oop_recorder = NULL;98_debug_info = NULL;99_dependencies = NULL;100_failure_reason = NULL;101_compilable = MethodCompilable;102_break_at_compile = false;103_compiler_data = NULL;104#ifndef PRODUCT105assert(!firstEnv, "not initialized properly");106#endif /* !PRODUCT */107108_system_dictionary_modification_counter = system_dictionary_modification_counter;109_num_inlined_bytecodes = 0;110assert(task == NULL || thread->task() == task, "sanity");111_task = task;112_log = NULL;113114// Temporary buffer for creating symbols and such.115_name_buffer = NULL;116_name_buffer_len = 0;117118_arena = &_ciEnv_arena;119_factory = new (_arena) ciObjectFactory(_arena, 128);120121// Preload commonly referenced system ciObjects.122123// During VM initialization, these instances have not yet been created.124// Assertions ensure that these instances are not accessed before125// their initialization.126127assert(Universe::is_fully_initialized(), "should be complete");128129oop o = Universe::null_ptr_exception_instance();130assert(o != NULL, "should have been initialized");131_NullPointerException_instance = get_object(o)->as_instance();132o = Universe::arithmetic_exception_instance();133assert(o != NULL, "should have been initialized");134_ArithmeticException_instance = get_object(o)->as_instance();135136_ArrayIndexOutOfBoundsException_instance = NULL;137_ArrayStoreException_instance = NULL;138_ClassCastException_instance = NULL;139_the_null_string = NULL;140_the_min_jint_string = NULL;141142_jvmti_can_hotswap_or_post_breakpoint = false;143_jvmti_can_access_local_variables = false;144_jvmti_can_post_on_exceptions = false;145_jvmti_can_pop_frame = false;146}147148ciEnv::ciEnv(Arena* arena) : _ciEnv_arena(mtCompiler) {149ASSERT_IN_VM;150151// Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.152CompilerThread* current_thread = CompilerThread::current();153assert(current_thread->env() == NULL, "must be");154current_thread->set_env(this);155assert(ciEnv::current() == this, "sanity");156157_oop_recorder = NULL;158_debug_info = NULL;159_dependencies = NULL;160_failure_reason = NULL;161_compilable = MethodCompilable_never;162_break_at_compile = false;163_compiler_data = NULL;164#ifndef PRODUCT165assert(firstEnv, "must be first");166firstEnv = false;167#endif /* !PRODUCT */168169_system_dictionary_modification_counter = 0;170_num_inlined_bytecodes = 0;171_task = NULL;172_log = NULL;173174// Temporary buffer for creating symbols and such.175_name_buffer = NULL;176_name_buffer_len = 0;177178_arena = arena;179_factory = new (_arena) ciObjectFactory(_arena, 128);180181// Preload commonly referenced system ciObjects.182183// During VM initialization, these instances have not yet been created.184// Assertions ensure that these instances are not accessed before185// their initialization.186187assert(Universe::is_fully_initialized(), "must be");188189_NullPointerException_instance = NULL;190_ArithmeticException_instance = NULL;191_ArrayIndexOutOfBoundsException_instance = NULL;192_ArrayStoreException_instance = NULL;193_ClassCastException_instance = NULL;194_the_null_string = NULL;195_the_min_jint_string = NULL;196197_jvmti_can_hotswap_or_post_breakpoint = false;198_jvmti_can_access_local_variables = false;199_jvmti_can_post_on_exceptions = false;200_jvmti_can_pop_frame = false;201}202203ciEnv::~ciEnv() {204CompilerThread* current_thread = CompilerThread::current();205_factory->remove_symbols();206// Need safepoint to clear the env on the thread. RedefineClasses might207// be reading it.208GUARDED_VM_ENTRY(current_thread->set_env(NULL);)209}210211// ------------------------------------------------------------------212// Cache Jvmti state213void ciEnv::cache_jvmti_state() {214VM_ENTRY_MARK;215// Get Jvmti capabilities under lock to get consistant values.216MutexLocker mu(JvmtiThreadState_lock);217_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();218_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();219_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions();220_jvmti_can_pop_frame = JvmtiExport::can_pop_frame();221}222223bool ciEnv::should_retain_local_variables() const {224return _jvmti_can_access_local_variables || _jvmti_can_pop_frame;225}226227bool ciEnv::jvmti_state_changed() const {228if (!_jvmti_can_access_local_variables &&229JvmtiExport::can_access_local_variables()) {230return true;231}232if (!_jvmti_can_hotswap_or_post_breakpoint &&233JvmtiExport::can_hotswap_or_post_breakpoint()) {234return true;235}236if (!_jvmti_can_post_on_exceptions &&237JvmtiExport::can_post_on_exceptions()) {238return true;239}240if (!_jvmti_can_pop_frame &&241JvmtiExport::can_pop_frame()) {242return true;243}244return false;245}246247// ------------------------------------------------------------------248// Cache DTrace flags249void ciEnv::cache_dtrace_flags() {250// Need lock?251_dtrace_extended_probes = ExtendedDTraceProbes;252if (_dtrace_extended_probes) {253_dtrace_monitor_probes = true;254_dtrace_method_probes = true;255_dtrace_alloc_probes = true;256} else {257_dtrace_monitor_probes = DTraceMonitorProbes;258_dtrace_method_probes = DTraceMethodProbes;259_dtrace_alloc_probes = DTraceAllocProbes;260}261}262263// ------------------------------------------------------------------264// helper for lazy exception creation265ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) {266VM_ENTRY_MARK;267if (handle == NULL) {268// Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance.269Klass* k = SystemDictionary::find(name, Handle(), Handle(), THREAD);270jobject objh = NULL;271if (!HAS_PENDING_EXCEPTION && k != NULL) {272oop obj = InstanceKlass::cast(k)->allocate_instance(THREAD);273if (!HAS_PENDING_EXCEPTION)274objh = JNIHandles::make_global(obj);275}276if (HAS_PENDING_EXCEPTION) {277CLEAR_PENDING_EXCEPTION;278} else {279handle = objh;280}281}282oop obj = JNIHandles::resolve(handle);283return obj == NULL? NULL: get_object(obj)->as_instance();284}285286ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() {287if (_ArrayIndexOutOfBoundsException_instance == NULL) {288_ArrayIndexOutOfBoundsException_instance289= get_or_create_exception(_ArrayIndexOutOfBoundsException_handle,290vmSymbols::java_lang_ArrayIndexOutOfBoundsException());291}292return _ArrayIndexOutOfBoundsException_instance;293}294ciInstance* ciEnv::ArrayStoreException_instance() {295if (_ArrayStoreException_instance == NULL) {296_ArrayStoreException_instance297= get_or_create_exception(_ArrayStoreException_handle,298vmSymbols::java_lang_ArrayStoreException());299}300return _ArrayStoreException_instance;301}302ciInstance* ciEnv::ClassCastException_instance() {303if (_ClassCastException_instance == NULL) {304_ClassCastException_instance305= get_or_create_exception(_ClassCastException_handle,306vmSymbols::java_lang_ClassCastException());307}308return _ClassCastException_instance;309}310311ciInstance* ciEnv::the_null_string() {312if (_the_null_string == NULL) {313VM_ENTRY_MARK;314_the_null_string = get_object(Universe::the_null_string())->as_instance();315}316return _the_null_string;317}318319ciInstance* ciEnv::the_min_jint_string() {320if (_the_min_jint_string == NULL) {321VM_ENTRY_MARK;322_the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance();323}324return _the_min_jint_string;325}326327// ------------------------------------------------------------------328// ciEnv::get_method_from_handle329ciMethod* ciEnv::get_method_from_handle(Method* method) {330VM_ENTRY_MARK;331return get_metadata(method)->as_method();332}333334// ------------------------------------------------------------------335// ciEnv::array_element_offset_in_bytes336int ciEnv::array_element_offset_in_bytes(ciArray* a_h, ciObject* o_h) {337VM_ENTRY_MARK;338objArrayOop a = (objArrayOop)a_h->get_oop();339assert(a->is_objArray(), "");340int length = a->length();341oop o = o_h->get_oop();342for (int i = 0; i < length; i++) {343if (a->obj_at(i) == o) return i;344}345return -1;346}347348349// ------------------------------------------------------------------350// ciEnv::check_klass_accessiblity351//352// Note: the logic of this method should mirror the logic of353// ConstantPool::verify_constant_pool_resolve.354bool ciEnv::check_klass_accessibility(ciKlass* accessing_klass,355Klass* resolved_klass) {356if (accessing_klass == NULL || !accessing_klass->is_loaded()) {357return true;358}359if (accessing_klass->is_obj_array_klass()) {360accessing_klass = accessing_klass->as_obj_array_klass()->base_element_klass();361}362if (!accessing_klass->is_instance_klass()) {363return true;364}365366if (resolved_klass->oop_is_objArray()) {367// Find the element klass, if this is an array.368resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();369}370if (resolved_klass->oop_is_instance()) {371return Reflection::verify_class_access(accessing_klass->get_Klass(),372resolved_klass,373true);374}375return true;376}377378// ------------------------------------------------------------------379// ciEnv::get_klass_by_name_impl380ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,381constantPoolHandle cpool,382ciSymbol* name,383bool require_local) {384ASSERT_IN_VM;385EXCEPTION_CONTEXT;386387// Now we need to check the SystemDictionary388Symbol* sym = name->get_symbol();389if (sym->byte_at(0) == 'L' &&390sym->byte_at(sym->utf8_length()-1) == ';') {391// This is a name from a signature. Strip off the trimmings.392// Call recursive to keep scope of strippedsym.393TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,394sym->utf8_length()-2,395KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));396ciSymbol* strippedname = get_symbol(strippedsym);397return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);398}399400// Check for prior unloaded klass. The SystemDictionary's answers401// can vary over time but the compiler needs consistency.402ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name);403if (unloaded_klass != NULL) {404if (require_local) return NULL;405return unloaded_klass;406}407408Handle loader(THREAD, (oop)NULL);409Handle domain(THREAD, (oop)NULL);410if (accessing_klass != NULL) {411loader = Handle(THREAD, accessing_klass->loader());412domain = Handle(THREAD, accessing_klass->protection_domain());413}414415// setup up the proper type to return on OOM416ciKlass* fail_type;417if (sym->byte_at(0) == '[') {418fail_type = _unloaded_ciobjarrayklass;419} else {420fail_type = _unloaded_ciinstance_klass;421}422KlassHandle found_klass;423{424ttyUnlocker ttyul; // release tty lock to avoid ordering problems425MutexLocker ml(Compile_lock);426Klass* kls;427if (!require_local) {428kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader,429KILL_COMPILE_ON_FATAL_(fail_type));430} else {431kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain,432KILL_COMPILE_ON_FATAL_(fail_type));433}434found_klass = KlassHandle(THREAD, kls);435}436437// If we fail to find an array klass, look again for its element type.438// The element type may be available either locally or via constraints.439// In either case, if we can find the element type in the system dictionary,440// we must build an array type around it. The CI requires array klasses441// to be loaded if their element klasses are loaded, except when memory442// is exhausted.443if (sym->byte_at(0) == '[' &&444(sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) {445// We have an unloaded array.446// Build it on the fly if the element class exists.447TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,448sym->utf8_length()-1,449KILL_COMPILE_ON_FATAL_(fail_type));450451// Get element ciKlass recursively.452ciKlass* elem_klass =453get_klass_by_name_impl(accessing_klass,454cpool,455get_symbol(elem_sym),456require_local);457if (elem_klass != NULL && elem_klass->is_loaded()) {458// Now make an array for it459return ciObjArrayKlass::make_impl(elem_klass);460}461}462463if (found_klass() == NULL && !cpool.is_null() && cpool->has_preresolution()) {464// Look inside the constant pool for pre-resolved class entries.465for (int i = cpool->length() - 1; i >= 1; i--) {466if (cpool->tag_at(i).is_klass()) {467Klass* kls = cpool->resolved_klass_at(i);468if (kls->name() == sym) {469found_klass = KlassHandle(THREAD, kls);470break;471}472}473}474}475476if (found_klass() != NULL) {477// Found it. Build a CI handle.478return get_klass(found_klass());479}480481if (require_local) return NULL;482483// Not yet loaded into the VM, or not governed by loader constraints.484// Make a CI representative for it.485return get_unloaded_klass(accessing_klass, name);486}487488// ------------------------------------------------------------------489// ciEnv::get_klass_by_name490ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass,491ciSymbol* klass_name,492bool require_local) {493GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass,494constantPoolHandle(),495klass_name,496require_local);)497}498499// ------------------------------------------------------------------500// ciEnv::get_klass_by_index_impl501//502// Implementation of get_klass_by_index.503ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,504int index,505bool& is_accessible,506ciInstanceKlass* accessor) {507EXCEPTION_CONTEXT;508KlassHandle klass; // = NULL;509Symbol* klass_name = NULL;510511if (cpool->tag_at(index).is_symbol()) {512klass_name = cpool->symbol_at(index);513} else {514// Check if it's resolved if it's not a symbol constant pool entry.515klass = KlassHandle(THREAD, ConstantPool::klass_at_if_loaded(cpool, index));516517if (klass.is_null()) {518// The klass has not been inserted into the constant pool.519// Try to look it up by name.520{521// We have to lock the cpool to keep the oop from being resolved522// while we are accessing it.523MonitorLockerEx ml(cpool->lock());524constantTag tag = cpool->tag_at(index);525if (tag.is_klass()) {526// The klass has been inserted into the constant pool527// very recently.528klass = KlassHandle(THREAD, cpool->resolved_klass_at(index));529} else {530assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag");531klass_name = cpool->unresolved_klass_at(index);532}533}534}535}536537if (klass.is_null()) {538// Not found in constant pool. Use the name to do the lookup.539ciKlass* k = get_klass_by_name_impl(accessor,540cpool,541get_symbol(klass_name),542false);543// Calculate accessibility the hard way.544if (!k->is_loaded()) {545is_accessible = false;546} else if (k->loader() != accessor->loader() &&547get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) {548// Loaded only remotely. Not linked yet.549is_accessible = false;550} else {551// Linked locally, and we must also check public/private, etc.552is_accessible = check_klass_accessibility(accessor, k->get_Klass());553}554return k;555}556557// Check for prior unloaded klass. The SystemDictionary's answers558// can vary over time but the compiler needs consistency.559ciSymbol* name = get_symbol(klass()->name());560ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name);561if (unloaded_klass != NULL) {562is_accessible = false;563return unloaded_klass;564}565566// It is known to be accessible, since it was found in the constant pool.567is_accessible = true;568return get_klass(klass());569}570571// ------------------------------------------------------------------572// ciEnv::get_klass_by_index573//574// Get a klass from the constant pool.575ciKlass* ciEnv::get_klass_by_index(constantPoolHandle cpool,576int index,577bool& is_accessible,578ciInstanceKlass* accessor) {579GUARDED_VM_ENTRY(return get_klass_by_index_impl(cpool, index, is_accessible, accessor);)580}581582// ------------------------------------------------------------------583// ciEnv::get_constant_by_index_impl584//585// Implementation of get_constant_by_index().586ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,587int pool_index, int cache_index,588ciInstanceKlass* accessor) {589bool ignore_will_link;590EXCEPTION_CONTEXT;591int index = pool_index;592if (cache_index >= 0) {593assert(index < 0, "only one kind of index at a time");594oop obj = cpool->resolved_references()->obj_at(cache_index);595if (obj != NULL) {596ciObject* ciobj = get_object(obj);597if (ciobj->is_array()) {598return ciConstant(T_ARRAY, ciobj);599} else {600assert(ciobj->is_instance(), "should be an instance");601return ciConstant(T_OBJECT, ciobj);602}603}604index = cpool->object_to_cp_index(cache_index);605}606constantTag tag = cpool->tag_at(index);607if (tag.is_int()) {608return ciConstant(T_INT, (jint)cpool->int_at(index));609} else if (tag.is_long()) {610return ciConstant((jlong)cpool->long_at(index));611} else if (tag.is_float()) {612return ciConstant((jfloat)cpool->float_at(index));613} else if (tag.is_double()) {614return ciConstant((jdouble)cpool->double_at(index));615} else if (tag.is_string()) {616oop string = NULL;617assert(cache_index >= 0, "should have a cache index");618if (cpool->is_pseudo_string_at(index)) {619string = cpool->pseudo_string_at(index, cache_index);620} else {621string = cpool->string_at(index, cache_index, THREAD);622if (HAS_PENDING_EXCEPTION) {623CLEAR_PENDING_EXCEPTION;624record_out_of_memory_failure();625return ciConstant();626}627}628ciObject* constant = get_object(string);629if (constant->is_array()) {630return ciConstant(T_ARRAY, constant);631} else {632assert (constant->is_instance(), "must be an instance, or not? ");633return ciConstant(T_OBJECT, constant);634}635} else if (tag.is_klass() || tag.is_unresolved_klass()) {636// 4881222: allow ldc to take a class type637ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor);638if (HAS_PENDING_EXCEPTION) {639CLEAR_PENDING_EXCEPTION;640record_out_of_memory_failure();641return ciConstant();642}643assert (klass->is_instance_klass() || klass->is_array_klass(),644"must be an instance or array klass ");645return ciConstant(T_OBJECT, klass->java_mirror());646} else if (tag.is_method_type()) {647// must execute Java code to link this CP entry into cache[i].f1648ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));649ciObject* ciobj = get_unloaded_method_type_constant(signature);650return ciConstant(T_OBJECT, ciobj);651} else if (tag.is_method_handle()) {652// must execute Java code to link this CP entry into cache[i].f1653int ref_kind = cpool->method_handle_ref_kind_at(index);654int callee_index = cpool->method_handle_klass_index_at(index);655ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor);656ciSymbol* name = get_symbol(cpool->method_handle_name_ref_at(index));657ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index));658ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind);659return ciConstant(T_OBJECT, ciobj);660} else {661ShouldNotReachHere();662return ciConstant();663}664}665666// ------------------------------------------------------------------667// ciEnv::get_constant_by_index668//669// Pull a constant out of the constant pool. How appropriate.670//671// Implementation note: this query is currently in no way cached.672ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool,673int pool_index, int cache_index,674ciInstanceKlass* accessor) {675GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);)676}677678// ------------------------------------------------------------------679// ciEnv::get_field_by_index_impl680//681// Implementation of get_field_by_index.682//683// Implementation note: the results of field lookups are cached684// in the accessor klass.685ciField* ciEnv::get_field_by_index_impl(ciInstanceKlass* accessor,686int index) {687ciConstantPoolCache* cache = accessor->field_cache();688if (cache == NULL) {689ciField* field = new (arena()) ciField(accessor, index);690return field;691} else {692ciField* field = (ciField*)cache->get(index);693if (field == NULL) {694field = new (arena()) ciField(accessor, index);695cache->insert(index, field);696}697return field;698}699}700701// ------------------------------------------------------------------702// ciEnv::get_field_by_index703//704// Get a field by index from a klass's constant pool.705ciField* ciEnv::get_field_by_index(ciInstanceKlass* accessor,706int index) {707GUARDED_VM_ENTRY(return get_field_by_index_impl(accessor, index);)708}709710// ------------------------------------------------------------------711// ciEnv::lookup_method712//713// Perform an appropriate method lookup based on accessor, holder,714// name, signature, and bytecode.715Method* ciEnv::lookup_method(InstanceKlass* accessor,716InstanceKlass* holder,717Symbol* name,718Symbol* sig,719Bytecodes::Code bc) {720EXCEPTION_CONTEXT;721KlassHandle h_accessor(THREAD, accessor);722KlassHandle h_holder(THREAD, holder);723LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));724methodHandle dest_method;725switch (bc) {726case Bytecodes::_invokestatic:727dest_method =728LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor);729break;730case Bytecodes::_invokespecial:731dest_method =732LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor);733break;734case Bytecodes::_invokeinterface:735dest_method =736LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig,737h_accessor, true);738break;739case Bytecodes::_invokevirtual:740dest_method =741LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig,742h_accessor, true);743break;744default: ShouldNotReachHere();745}746747return dest_method();748}749750751// ------------------------------------------------------------------752// ciEnv::get_method_by_index_impl753ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,754int index, Bytecodes::Code bc,755ciInstanceKlass* accessor) {756if (bc == Bytecodes::_invokedynamic) {757ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index);758bool is_resolved = !cpce->is_f1_null();759// FIXME: code generation could allow for null (unlinked) call site760// The call site could be made patchable as follows:761// Load the appendix argument from the constant pool.762// Test the appendix argument and jump to a known deopt routine if it is null.763// Jump through a patchable call site, which is initially a deopt routine.764// Patch the call site to the nmethod entry point of the static compiled lambda form.765// As with other two-component call sites, both values must be independently verified.766767if (is_resolved) {768// Get the invoker Method* from the constant pool.769// (The appendix argument, if any, will be noted in the method's signature.)770Method* adapter = cpce->f1_as_method();771return get_method(adapter);772}773774// Fake a method that is equivalent to a declared method.775ciInstanceKlass* holder = get_instance_klass(SystemDictionary::MethodHandle_klass());776ciSymbol* name = ciSymbol::invokeBasic_name();777ciSymbol* signature = get_symbol(cpool->signature_ref_at(index));778return get_unloaded_method(holder, name, signature, accessor);779} else {780const int holder_index = cpool->klass_ref_index_at(index);781bool holder_is_accessible;782ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);783ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);784785// Get the method's name and signature.786Symbol* name_sym = cpool->name_ref_at(index);787Symbol* sig_sym = cpool->signature_ref_at(index);788789if (cpool->has_preresolution()790|| (holder == ciEnv::MethodHandle_klass() &&791MethodHandles::is_signature_polymorphic_name(holder->get_Klass(), name_sym))) {792// Short-circuit lookups for JSR 292-related call sites.793// That is, do not rely only on name-based lookups, because they may fail794// if the names are not resolvable in the boot class loader (7056328).795switch (bc) {796case Bytecodes::_invokevirtual:797case Bytecodes::_invokeinterface:798case Bytecodes::_invokespecial:799case Bytecodes::_invokestatic:800{801Method* m = ConstantPool::method_at_if_loaded(cpool, index);802if (m != NULL) {803return get_method(m);804}805}806break;807}808}809810if (holder_is_accessible) { // Our declared holder is loaded.811InstanceKlass* lookup = declared_holder->get_instanceKlass();812Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);813if (m != NULL &&814(bc == Bytecodes::_invokestatic815? m->method_holder()->is_not_initialized()816: !m->method_holder()->is_loaded())) {817m = NULL;818}819#ifdef ASSERT820if (m != NULL && ReplayCompiles && !ciReplay::is_loaded(m)) {821m = NULL;822}823#endif824if (m != NULL) {825// We found the method.826return get_method(m);827}828}829830// Either the declared holder was not loaded, or the method could831// not be found. Create a dummy ciMethod to represent the failed832// lookup.833ciSymbol* name = get_symbol(name_sym);834ciSymbol* signature = get_symbol(sig_sym);835return get_unloaded_method(declared_holder, name, signature, accessor);836}837}838839840// ------------------------------------------------------------------841// ciEnv::get_instance_klass_for_declared_method_holder842ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* method_holder) {843// For the case of <array>.clone(), the method holder can be a ciArrayKlass844// instead of a ciInstanceKlass. For that case simply pretend that the845// declared holder is Object.clone since that's where the call will bottom out.846// A more correct fix would trickle out through many interfaces in CI,847// requiring ciInstanceKlass* to become ciKlass* and many more places would848// require checks to make sure the expected type was found. Given that this849// only occurs for clone() the more extensive fix seems like overkill so850// instead we simply smear the array type into Object.851guarantee(method_holder != NULL, "no method holder");852if (method_holder->is_instance_klass()) {853return method_holder->as_instance_klass();854} else if (method_holder->is_array_klass()) {855return current()->Object_klass();856} else {857ShouldNotReachHere();858}859return NULL;860}861862863// ------------------------------------------------------------------864// ciEnv::get_method_by_index865ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,866int index, Bytecodes::Code bc,867ciInstanceKlass* accessor) {868GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)869}870871872// ------------------------------------------------------------------873// ciEnv::name_buffer874char *ciEnv::name_buffer(int req_len) {875if (_name_buffer_len < req_len) {876if (_name_buffer == NULL) {877_name_buffer = (char*)arena()->Amalloc(sizeof(char)*req_len);878_name_buffer_len = req_len;879} else {880_name_buffer =881(char*)arena()->Arealloc(_name_buffer, _name_buffer_len, req_len);882_name_buffer_len = req_len;883}884}885return _name_buffer;886}887888// ------------------------------------------------------------------889// ciEnv::is_in_vm890bool ciEnv::is_in_vm() {891return JavaThread::current()->thread_state() == _thread_in_vm;892}893894bool ciEnv::system_dictionary_modification_counter_changed() {895return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications();896}897898// ------------------------------------------------------------------899// ciEnv::validate_compile_task_dependencies900//901// Check for changes during compilation (e.g. class loads, evolution,902// breakpoints, call site invalidation).903void ciEnv::validate_compile_task_dependencies(ciMethod* target) {904if (failing()) return; // no need for further checks905906// First, check non-klass dependencies as we might return early and907// not check klass dependencies if the system dictionary908// modification counter hasn't changed (see below).909for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {910if (deps.is_klass_type()) continue; // skip klass dependencies911Klass* witness = deps.check_dependency();912if (witness != NULL) {913record_failure("invalid non-klass dependency");914return;915}916}917918// Klass dependencies must be checked when the system dictionary919// changes. If logging is enabled all violated dependences will be920// recorded in the log. In debug mode check dependencies even if921// the system dictionary hasn't changed to verify that no invalid922// dependencies were inserted. Any violated dependences in this923// case are dumped to the tty.924bool counter_changed = system_dictionary_modification_counter_changed();925926bool verify_deps = trueInDebug;927if (!counter_changed && !verify_deps) return;928929int klass_violations = 0;930for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {931if (!deps.is_klass_type()) continue; // skip non-klass dependencies932Klass* witness = deps.check_dependency();933if (witness != NULL) {934klass_violations++;935if (!counter_changed) {936// Dependence failed but counter didn't change. Log a message937// describing what failed and allow the assert at the end to938// trigger.939deps.print_dependency(witness);940} else if (xtty == NULL) {941// If we're not logging then a single violation is sufficient,942// otherwise we want to log all the dependences which were943// violated.944break;945}946}947}948949if (klass_violations != 0) {950#ifdef ASSERT951if (!counter_changed && !PrintCompilation) {952// Print out the compile task that failed953_task->print_line();954}955#endif956assert(counter_changed, "failed dependencies, but counter didn't change");957record_failure("concurrent class loading");958}959}960961// ------------------------------------------------------------------962// ciEnv::register_method963void ciEnv::register_method(ciMethod* target,964int entry_bci,965CodeOffsets* offsets,966int orig_pc_offset,967CodeBuffer* code_buffer,968int frame_words,969OopMapSet* oop_map_set,970ExceptionHandlerTable* handler_table,971ImplicitExceptionTable* inc_table,972AbstractCompiler* compiler,973int comp_level,974bool has_unsafe_access,975bool has_wide_vectors,976RTMState rtm_state) {977VM_ENTRY_MARK;978nmethod* nm = NULL;979{980// To prevent compile queue updates.981MutexLocker locker(MethodCompileQueue_lock, THREAD);982983// Prevent SystemDictionary::add_to_hierarchy from running984// and invalidating our dependencies until we install this method.985// No safepoints are allowed. Otherwise, class redefinition can occur in between.986MutexLocker ml(Compile_lock);987No_Safepoint_Verifier nsv;988989// Change in Jvmti state may invalidate compilation.990if (!failing() && jvmti_state_changed()) {991record_failure("Jvmti state change invalidated dependencies");992}993994// Change in DTrace flags may invalidate compilation.995if (!failing() &&996( (!dtrace_extended_probes() && ExtendedDTraceProbes) ||997(!dtrace_method_probes() && DTraceMethodProbes) ||998(!dtrace_alloc_probes() && DTraceAllocProbes) )) {999record_failure("DTrace flags change invalidated dependencies");1000}10011002if (!failing()) {1003if (log() != NULL) {1004// Log the dependencies which this compilation declares.1005dependencies()->log_all_dependencies();1006}10071008// Encode the dependencies now, so we can check them right away.1009dependencies()->encode_content_bytes();10101011// Check for {class loads, evolution, breakpoints, ...} during compilation1012validate_compile_task_dependencies(target);1013}10141015methodHandle method(THREAD, target->get_Method());10161017#if INCLUDE_RTM_OPT1018if (!failing() && (rtm_state != NoRTM) &&1019(method()->method_data() != NULL) &&1020(method()->method_data()->rtm_state() != rtm_state)) {1021// Preemptive decompile if rtm state was changed.1022record_failure("RTM state change invalidated rtm code");1023}1024#endif10251026if (failing()) {1027// While not a true deoptimization, it is a preemptive decompile.1028MethodData* mdo = method()->method_data();1029if (mdo != NULL) {1030mdo->inc_decompile_count();1031}10321033// All buffers in the CodeBuffer are allocated in the CodeCache.1034// If the code buffer is created on each compile attempt1035// as in C2, then it must be freed.1036code_buffer->free_blob();1037return;1038}10391040assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");1041assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry");10421043nm = nmethod::new_nmethod(method,1044compile_id(),1045entry_bci,1046offsets,1047orig_pc_offset,1048debug_info(), dependencies(), code_buffer,1049frame_words, oop_map_set,1050handler_table, inc_table,1051compiler, comp_level);1052// Free codeBlobs1053code_buffer->free_blob();10541055if (nm != NULL) {1056nm->set_has_unsafe_access(has_unsafe_access);1057nm->set_has_wide_vectors(has_wide_vectors);1058#if INCLUDE_RTM_OPT1059nm->set_rtm_state(rtm_state);1060#endif10611062// Record successful registration.1063// (Put nm into the task handle *before* publishing to the Java heap.)1064if (task() != NULL) {1065task()->set_code(nm);1066}10671068if (entry_bci == InvocationEntryBci) {1069if (TieredCompilation) {1070// If there is an old version we're done with it1071nmethod* old = method->code();1072if (TraceMethodReplacement && old != NULL) {1073ResourceMark rm;1074char *method_name = method->name_and_sig_as_C_string();1075tty->print_cr("Replacing method %s", method_name);1076}1077if (old != NULL) {1078old->make_not_entrant();1079}1080}1081if (TraceNMethodInstalls) {1082ResourceMark rm;1083char *method_name = method->name_and_sig_as_C_string();1084ttyLocker ttyl;1085tty->print_cr("Installing method (%d) %s ",1086comp_level,1087method_name);1088}1089// Allow the code to be executed1090method->set_code(method, nm);1091} else {1092if (TraceNMethodInstalls) {1093ResourceMark rm;1094char *method_name = method->name_and_sig_as_C_string();1095ttyLocker ttyl;1096tty->print_cr("Installing osr method (%d) %s @ %d",1097comp_level,1098method_name,1099entry_bci);1100}1101method->method_holder()->add_osr_nmethod(nm);1102}1103}1104} // safepoints are allowed again11051106if (nm != NULL) {1107// JVMTI -- compiled method notification (must be done outside lock)1108nm->post_compiled_method_load_event();1109} else {1110// The CodeCache is full. Print out warning and disable compilation.1111record_failure("code cache is full");1112CompileBroker::handle_full_code_cache();1113}1114}111511161117// ------------------------------------------------------------------1118// ciEnv::find_system_klass1119ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) {1120VM_ENTRY_MARK;1121return get_klass_by_name_impl(NULL, constantPoolHandle(), klass_name, false);1122}11231124// ------------------------------------------------------------------1125// ciEnv::comp_level1126int ciEnv::comp_level() {1127if (task() == NULL) return CompLevel_highest_tier;1128return task()->comp_level();1129}11301131// ------------------------------------------------------------------1132// ciEnv::compile_id1133uint ciEnv::compile_id() {1134if (task() == NULL) return 0;1135return task()->compile_id();1136}11371138// ------------------------------------------------------------------1139// ciEnv::notice_inlined_method()1140void ciEnv::notice_inlined_method(ciMethod* method) {1141_num_inlined_bytecodes += method->code_size_for_inlining();1142}11431144// ------------------------------------------------------------------1145// ciEnv::num_inlined_bytecodes()1146int ciEnv::num_inlined_bytecodes() const {1147return _num_inlined_bytecodes;1148}11491150// ------------------------------------------------------------------1151// ciEnv::record_failure()1152void ciEnv::record_failure(const char* reason) {1153if (_failure_reason == NULL) {1154// Record the first failure reason.1155_failure_reason = reason;1156}1157}11581159// ------------------------------------------------------------------1160// ciEnv::record_method_not_compilable()1161void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) {1162int new_compilable =1163all_tiers ? MethodCompilable_never : MethodCompilable_not_at_tier ;11641165// Only note transitions to a worse state1166if (new_compilable > _compilable) {1167if (log() != NULL) {1168if (all_tiers) {1169log()->elem("method_not_compilable");1170} else {1171log()->elem("method_not_compilable_at_tier level='%d'",1172current()->task()->comp_level());1173}1174}1175_compilable = new_compilable;11761177// Reset failure reason; this one is more important.1178_failure_reason = NULL;1179record_failure(reason);1180}1181}11821183// ------------------------------------------------------------------1184// ciEnv::record_out_of_memory_failure()1185void ciEnv::record_out_of_memory_failure() {1186// If memory is low, we stop compiling methods.1187record_method_not_compilable("out of memory");1188}11891190ciInstance* ciEnv::unloaded_ciinstance() {1191GUARDED_VM_ENTRY(return _factory->get_unloaded_object_constant();)1192}11931194// ------------------------------------------------------------------1195// ciEnv::dump_replay_data*11961197// Don't change thread state and acquire any locks.1198// Safe to call from VM error reporter.11991200void ciEnv::dump_compile_data(outputStream* out) {1201CompileTask* task = this->task();1202Method* method = task->method();1203int entry_bci = task->osr_bci();1204int comp_level = task->comp_level();1205out->print("compile %s %s %s %d %d",1206method->klass_name()->as_quoted_ascii(),1207method->name()->as_quoted_ascii(),1208method->signature()->as_quoted_ascii(),1209entry_bci, comp_level);1210if (compiler_data() != NULL) {1211if (is_c2_compile(comp_level)) { // C2 or Shark1212#ifdef COMPILER21213// Dump C2 inlining data.1214((Compile*)compiler_data())->dump_inline_data(out);1215#endif1216} else if (is_c1_compile(comp_level)) { // C11217#ifdef COMPILER11218// Dump C1 inlining data.1219((Compilation*)compiler_data())->dump_inline_data(out);1220#endif1221}1222}1223out->cr();1224}12251226void ciEnv::dump_replay_data_unsafe(outputStream* out) {1227ResourceMark rm;1228#if INCLUDE_JVMTI1229out->print_cr("JvmtiExport can_access_local_variables %d", _jvmti_can_access_local_variables);1230out->print_cr("JvmtiExport can_hotswap_or_post_breakpoint %d", _jvmti_can_hotswap_or_post_breakpoint);1231out->print_cr("JvmtiExport can_post_on_exceptions %d", _jvmti_can_post_on_exceptions);1232#endif // INCLUDE_JVMTI12331234GrowableArray<ciMetadata*>* objects = _factory->get_ci_metadata();1235out->print_cr("# %d ciObject found", objects->length());1236for (int i = 0; i < objects->length(); i++) {1237objects->at(i)->dump_replay_data(out);1238}1239dump_compile_data(out);1240out->flush();1241}12421243void ciEnv::dump_replay_data(outputStream* out) {1244GUARDED_VM_ENTRY(1245MutexLocker ml(Compile_lock);1246dump_replay_data_unsafe(out);1247)1248}12491250void ciEnv::dump_replay_data(int compile_id) {1251static char buffer[O_BUFLEN];1252int ret = jio_snprintf(buffer, O_BUFLEN, "replay_pid%p_compid%d.log", os::current_process_id(), compile_id);1253if (ret > 0) {1254int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);1255if (fd != -1) {1256FILE* replay_data_file = os::open(fd, "w");1257if (replay_data_file != NULL) {1258fileStream replay_data_stream(replay_data_file, /*need_close=*/true);1259dump_replay_data(&replay_data_stream);1260tty->print_cr("# Compiler replay data is saved as: %s", buffer);1261} else {1262tty->print_cr("# Can't open file to dump replay data.");1263}1264}1265}1266}12671268void ciEnv::dump_inline_data(int compile_id) {1269static char buffer[O_BUFLEN];1270int ret = jio_snprintf(buffer, O_BUFLEN, "inline_pid%p_compid%d.log", os::current_process_id(), compile_id);1271if (ret > 0) {1272int fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);1273if (fd != -1) {1274FILE* inline_data_file = os::open(fd, "w");1275if (inline_data_file != NULL) {1276fileStream replay_data_stream(inline_data_file, /*need_close=*/true);1277GUARDED_VM_ENTRY(1278MutexLocker ml(Compile_lock);1279dump_compile_data(&replay_data_stream);1280)1281replay_data_stream.flush();1282tty->print("# Compiler inline data is saved as: ");1283tty->print_cr("%s", buffer);1284} else {1285tty->print_cr("# Can't open file to dump inline data.");1286}1287}1288}1289}129012911292