0N/A/*
2273N/A * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#include "precompiled.hpp"
1879N/A#include "ci/ciConstant.hpp"
1879N/A#include "ci/ciEnv.hpp"
1879N/A#include "ci/ciField.hpp"
1879N/A#include "ci/ciInstance.hpp"
1879N/A#include "ci/ciInstanceKlass.hpp"
1879N/A#include "ci/ciInstanceKlassKlass.hpp"
1879N/A#include "ci/ciMethod.hpp"
1879N/A#include "ci/ciNullObject.hpp"
1879N/A#include "ci/ciObjArrayKlassKlass.hpp"
1879N/A#include "ci/ciTypeArrayKlassKlass.hpp"
1879N/A#include "ci/ciUtilities.hpp"
1879N/A#include "classfile/systemDictionary.hpp"
1879N/A#include "classfile/vmSymbols.hpp"
1879N/A#include "code/scopeDesc.hpp"
1879N/A#include "compiler/compileBroker.hpp"
1879N/A#include "compiler/compileLog.hpp"
1879N/A#include "compiler/compilerOracle.hpp"
1879N/A#include "gc_interface/collectedHeap.inline.hpp"
1879N/A#include "interpreter/linkResolver.hpp"
1879N/A#include "memory/allocation.inline.hpp"
1879N/A#include "memory/oopFactory.hpp"
1879N/A#include "memory/universe.inline.hpp"
1879N/A#include "oops/methodDataOop.hpp"
1879N/A#include "oops/objArrayKlass.hpp"
1879N/A#include "oops/oop.inline.hpp"
1879N/A#include "oops/oop.inline2.hpp"
1879N/A#include "prims/jvmtiExport.hpp"
1879N/A#include "runtime/init.hpp"
1879N/A#include "runtime/reflection.hpp"
1879N/A#include "runtime/sharedRuntime.hpp"
1879N/A#include "utilities/dtrace.hpp"
1879N/A#ifdef COMPILER1
1879N/A#include "c1/c1_Runtime1.hpp"
1879N/A#endif
1879N/A#ifdef COMPILER2
1879N/A#include "opto/runtime.hpp"
1879N/A#endif
0N/A
0N/A// ciEnv
0N/A//
0N/A// This class is the top level broker for requests from the compiler
0N/A// to the VM.
0N/A
0N/AciObject* ciEnv::_null_object_instance;
0N/AciMethodKlass* ciEnv::_method_klass_instance;
0N/AciKlassKlass* ciEnv::_klass_klass_instance;
0N/AciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance;
0N/AciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance;
0N/AciObjArrayKlassKlass* ciEnv::_obj_array_klass_klass_instance;
0N/A
1142N/A#define WK_KLASS_DEFN(name, ignore_s, ignore_o) ciInstanceKlass* ciEnv::_##name = NULL;
1142N/AWK_KLASSES_DO(WK_KLASS_DEFN)
1142N/A#undef WK_KLASS_DEFN
0N/A
0N/AciSymbol* ciEnv::_unloaded_cisymbol = NULL;
0N/AciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL;
0N/AciObjArrayKlass* ciEnv::_unloaded_ciobjarrayklass = NULL;
0N/A
0N/Ajobject ciEnv::_ArrayIndexOutOfBoundsException_handle = NULL;
0N/Ajobject ciEnv::_ArrayStoreException_handle = NULL;
0N/Ajobject ciEnv::_ClassCastException_handle = NULL;
0N/A
0N/A#ifndef PRODUCT
0N/Astatic bool firstEnv = true;
0N/A#endif /* PRODUCT */
0N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::ciEnv
0N/AciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) {
0N/A VM_ENTRY_MARK;
0N/A
0N/A // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
0N/A thread->set_env(this);
0N/A assert(ciEnv::current() == this, "sanity");
0N/A
0N/A _oop_recorder = NULL;
0N/A _debug_info = NULL;
0N/A _dependencies = NULL;
0N/A _failure_reason = NULL;
0N/A _compilable = MethodCompilable;
0N/A _break_at_compile = false;
0N/A _compiler_data = NULL;
0N/A#ifndef PRODUCT
0N/A assert(!firstEnv, "not initialized properly");
0N/A#endif /* !PRODUCT */
0N/A
0N/A _system_dictionary_modification_counter = system_dictionary_modification_counter;
0N/A _num_inlined_bytecodes = 0;
0N/A assert(task == NULL || thread->task() == task, "sanity");
0N/A _task = task;
0N/A _log = NULL;
0N/A
0N/A // Temporary buffer for creating symbols and such.
0N/A _name_buffer = NULL;
0N/A _name_buffer_len = 0;
0N/A
0N/A _arena = &_ciEnv_arena;
0N/A _factory = new (_arena) ciObjectFactory(_arena, 128);
0N/A
0N/A // Preload commonly referenced system ciObjects.
0N/A
0N/A // During VM initialization, these instances have not yet been created.
0N/A // Assertions ensure that these instances are not accessed before
0N/A // their initialization.
0N/A
0N/A assert(Universe::is_fully_initialized(), "should be complete");
0N/A
0N/A oop o = Universe::null_ptr_exception_instance();
0N/A assert(o != NULL, "should have been initialized");
0N/A _NullPointerException_instance = get_object(o)->as_instance();
0N/A o = Universe::arithmetic_exception_instance();
0N/A assert(o != NULL, "should have been initialized");
0N/A _ArithmeticException_instance = get_object(o)->as_instance();
0N/A
0N/A _ArrayIndexOutOfBoundsException_instance = NULL;
0N/A _ArrayStoreException_instance = NULL;
0N/A _ClassCastException_instance = NULL;
1080N/A _the_null_string = NULL;
1080N/A _the_min_jint_string = NULL;
0N/A}
0N/A
0N/AciEnv::ciEnv(Arena* arena) {
0N/A ASSERT_IN_VM;
0N/A
0N/A // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc.
0N/A CompilerThread* current_thread = CompilerThread::current();
0N/A assert(current_thread->env() == NULL, "must be");
0N/A current_thread->set_env(this);
0N/A assert(ciEnv::current() == this, "sanity");
0N/A
0N/A _oop_recorder = NULL;
0N/A _debug_info = NULL;
0N/A _dependencies = NULL;
0N/A _failure_reason = NULL;
0N/A _compilable = MethodCompilable_never;
0N/A _break_at_compile = false;
0N/A _compiler_data = NULL;
0N/A#ifndef PRODUCT
0N/A assert(firstEnv, "must be first");
0N/A firstEnv = false;
0N/A#endif /* !PRODUCT */
0N/A
0N/A _system_dictionary_modification_counter = 0;
0N/A _num_inlined_bytecodes = 0;
0N/A _task = NULL;
0N/A _log = NULL;
0N/A
0N/A // Temporary buffer for creating symbols and such.
0N/A _name_buffer = NULL;
0N/A _name_buffer_len = 0;
0N/A
0N/A _arena = arena;
0N/A _factory = new (_arena) ciObjectFactory(_arena, 128);
0N/A
0N/A // Preload commonly referenced system ciObjects.
0N/A
0N/A // During VM initialization, these instances have not yet been created.
0N/A // Assertions ensure that these instances are not accessed before
0N/A // their initialization.
0N/A
0N/A assert(Universe::is_fully_initialized(), "must be");
0N/A
0N/A oop o = Universe::null_ptr_exception_instance();
0N/A assert(o != NULL, "should have been initialized");
0N/A _NullPointerException_instance = get_object(o)->as_instance();
0N/A o = Universe::arithmetic_exception_instance();
0N/A assert(o != NULL, "should have been initialized");
0N/A _ArithmeticException_instance = get_object(o)->as_instance();
0N/A
0N/A _ArrayIndexOutOfBoundsException_instance = NULL;
0N/A _ArrayStoreException_instance = NULL;
0N/A _ClassCastException_instance = NULL;
1080N/A _the_null_string = NULL;
1080N/A _the_min_jint_string = NULL;
0N/A}
0N/A
0N/AciEnv::~ciEnv() {
0N/A CompilerThread* current_thread = CompilerThread::current();
2062N/A _factory->remove_symbols();
0N/A current_thread->set_env(NULL);
0N/A}
0N/A
0N/A// ------------------------------------------------------------------
780N/A// Cache Jvmti state
780N/Avoid ciEnv::cache_jvmti_state() {
780N/A VM_ENTRY_MARK;
780N/A // Get Jvmti capabilities under lock to get consistant values.
780N/A MutexLocker mu(JvmtiThreadState_lock);
780N/A _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint();
780N/A _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
1213N/A _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions();
780N/A}
780N/A
780N/A// ------------------------------------------------------------------
780N/A// Cache DTrace flags
780N/Avoid ciEnv::cache_dtrace_flags() {
780N/A // Need lock?
780N/A _dtrace_extended_probes = ExtendedDTraceProbes;
780N/A if (_dtrace_extended_probes) {
780N/A _dtrace_monitor_probes = true;
780N/A _dtrace_method_probes = true;
780N/A _dtrace_alloc_probes = true;
780N/A } else {
780N/A _dtrace_monitor_probes = DTraceMonitorProbes;
780N/A _dtrace_method_probes = DTraceMethodProbes;
780N/A _dtrace_alloc_probes = DTraceAllocProbes;
780N/A }
780N/A}
780N/A
780N/A// ------------------------------------------------------------------
0N/A// helper for lazy exception creation
2062N/AciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) {
0N/A VM_ENTRY_MARK;
0N/A if (handle == NULL) {
0N/A // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance.
0N/A klassOop k = SystemDictionary::find(name, Handle(), Handle(), THREAD);
0N/A jobject objh = NULL;
0N/A if (!HAS_PENDING_EXCEPTION && k != NULL) {
0N/A oop obj = instanceKlass::cast(k)->allocate_permanent_instance(THREAD);
0N/A if (!HAS_PENDING_EXCEPTION)
0N/A objh = JNIHandles::make_global(obj);
0N/A }
0N/A if (HAS_PENDING_EXCEPTION) {
0N/A CLEAR_PENDING_EXCEPTION;
0N/A } else {
0N/A handle = objh;
0N/A }
0N/A }
0N/A oop obj = JNIHandles::resolve(handle);
0N/A return obj == NULL? NULL: get_object(obj)->as_instance();
0N/A}
0N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::ArrayIndexOutOfBoundsException_instance, etc.
0N/AciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() {
0N/A if (_ArrayIndexOutOfBoundsException_instance == NULL) {
0N/A _ArrayIndexOutOfBoundsException_instance
0N/A = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle,
2062N/A vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
0N/A }
0N/A return _ArrayIndexOutOfBoundsException_instance;
0N/A}
0N/AciInstance* ciEnv::ArrayStoreException_instance() {
0N/A if (_ArrayStoreException_instance == NULL) {
0N/A _ArrayStoreException_instance
0N/A = get_or_create_exception(_ArrayStoreException_handle,
2062N/A vmSymbols::java_lang_ArrayStoreException());
0N/A }
0N/A return _ArrayStoreException_instance;
0N/A}
0N/AciInstance* ciEnv::ClassCastException_instance() {
0N/A if (_ClassCastException_instance == NULL) {
0N/A _ClassCastException_instance
0N/A = get_or_create_exception(_ClassCastException_handle,
2062N/A vmSymbols::java_lang_ClassCastException());
0N/A }
0N/A return _ClassCastException_instance;
0N/A}
0N/A
1080N/AciInstance* ciEnv::the_null_string() {
1080N/A if (_the_null_string == NULL) {
1080N/A VM_ENTRY_MARK;
1080N/A _the_null_string = get_object(Universe::the_null_string())->as_instance();
1080N/A }
1080N/A return _the_null_string;
1080N/A}
1080N/A
1080N/AciInstance* ciEnv::the_min_jint_string() {
1080N/A if (_the_min_jint_string == NULL) {
1080N/A VM_ENTRY_MARK;
1080N/A _the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance();
1080N/A }
1080N/A return _the_min_jint_string;
1080N/A}
1080N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::get_method_from_handle
0N/AciMethod* ciEnv::get_method_from_handle(jobject method) {
0N/A VM_ENTRY_MARK;
0N/A return get_object(JNIHandles::resolve(method))->as_method();
0N/A}
0N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::make_array
989N/AciArray* ciEnv::make_system_array(GrowableArray<ciObject*>* objects) {
0N/A VM_ENTRY_MARK;
0N/A int length = objects->length();
0N/A objArrayOop a = oopFactory::new_system_objArray(length, THREAD);
0N/A if (HAS_PENDING_EXCEPTION) {
0N/A CLEAR_PENDING_EXCEPTION;
0N/A record_out_of_memory_failure();
0N/A return NULL;
0N/A }
0N/A for (int i = 0; i < length; i++) {
0N/A a->obj_at_put(i, objects->at(i)->get_oop());
0N/A }
0N/A assert(a->is_perm(), "");
0N/A return get_object(a)->as_array();
0N/A}
0N/A
0N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::array_element_offset_in_bytes
0N/Aint ciEnv::array_element_offset_in_bytes(ciArray* a_h, ciObject* o_h) {
0N/A VM_ENTRY_MARK;
0N/A objArrayOop a = (objArrayOop)a_h->get_oop();
0N/A assert(a->is_objArray(), "");
0N/A int length = a->length();
0N/A oop o = o_h->get_oop();
0N/A for (int i = 0; i < length; i++) {
0N/A if (a->obj_at(i) == o) return i;
0N/A }
0N/A return -1;
0N/A}
0N/A
0N/A
0N/A// ------------------------------------------------------------------
0N/A// ciEnv::check_klass_accessiblity
0N/A//
0N/A// Note: the logic of this method should mirror the logic of
0N/A// constantPoolOopDesc::verify_constant_pool_resolve.
0N/Abool ciEnv::check_klass_accessibility(ciKlass* accessing_klass,
0N/A klassOop resolved_klass) {
0N/A if (accessing_klass == NULL || !accessing_klass->is_loaded()) {
0N/A return true;
0N/A }
0N/A if (accessing_klass->is_obj_array()) {
0N/A accessing_klass = accessing_klass->as_obj_array_klass()->base_element_klass();
0N/A }
0N/A if (!accessing_klass->is_instance_klass()) {
0N/A return true;
0N/A }
0N/A
0N/A if (resolved_klass->klass_part()->oop_is_objArray()) {
0N/A // Find the element klass, if this is an array.
0N/A resolved_klass = objArrayKlass::cast(resolved_klass)->bottom_klass();
0N/A }
0N/A if (resolved_klass->klass_part()->oop_is_instance()) {
0N/A return Reflection::verify_class_access(accessing_klass->get_klassOop(),
0N/A resolved_klass,
0N/A true);
0N/A }
0N/A return true;
0N/A}
0N/A
0N/A// ------------------------------------- Error!

 

There was an error!

null

java.lang.NullPointerException