src/hotspot/share/jvmci/jvmciEnv.cpp
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File
open Cdiff src/hotspot/share/jvmci/jvmciEnv.cpp
src/hotspot/share/jvmci/jvmciEnv.cpp
Print this page
*** 23,77 ****
*/
#include "precompiled.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "classfile/javaAssertions.hpp"
#include "classfile/systemDictionary.hpp"
- #include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/linkResolver.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
- #include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
- #include "oops/constantPool.inline.hpp"
- #include "oops/cpCache.inline.hpp"
- #include "oops/method.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
- #include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
! #include "runtime/sweeper.hpp"
#include "utilities/dtrace.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
! JVMCIEnv::JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter):
_task(task),
_system_dictionary_modification_counter(system_dictionary_modification_counter),
_retryable(true),
_failure_reason(NULL),
! _failure_reason_on_C_heap(false)
! {
// Get Jvmti capabilities under lock to get consistent values.
MutexLocker mu(JvmtiThreadState_lock);
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0;
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
_jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0;
}
! bool JVMCIEnv::jvmti_state_changed() const {
if (!jvmti_can_access_local_variables() &&
JvmtiExport::can_access_local_variables()) {
return true;
}
if (!jvmti_can_hotswap_or_post_breakpoint() &&
--- 23,76 ----
*/
#include "precompiled.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "classfile/javaAssertions.hpp"
+ #include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/codeCache.hpp"
#include "code/scopeDesc.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerOracle.hpp"
+ #ifdef INCLUDE_ALL_GCS
+ #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+ #endif
#include "interpreter/linkResolver.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/reflection.hpp"
#include "runtime/sharedRuntime.hpp"
! #include "runtime/javaCalls.hpp"
#include "utilities/dtrace.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
! #include <string.h>
!
! JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter):
_task(task),
_system_dictionary_modification_counter(system_dictionary_modification_counter),
_retryable(true),
_failure_reason(NULL),
! _failure_reason_on_C_heap(false) {
// Get Jvmti capabilities under lock to get consistent values.
MutexLocker mu(JvmtiThreadState_lock);
_jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0;
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
_jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0;
}
! bool JVMCICompileState::jvmti_state_changed() const {
if (!jvmti_can_access_local_variables() &&
JvmtiExport::can_access_local_variables()) {
return true;
}
if (!jvmti_can_hotswap_or_post_breakpoint() &&
*** 87,620 ****
return true;
}
return false;
}
! // ------------------------------------------------------------------
! // Note: the logic of this method should mirror the logic of
! // constantPoolOopDesc::verify_constant_pool_resolve.
! bool JVMCIEnv::check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass) {
! if (accessing_klass->is_objArray_klass()) {
! accessing_klass = ObjArrayKlass::cast(accessing_klass)->bottom_klass();
}
- if (!accessing_klass->is_instance_klass()) {
- return true;
}
! if (resolved_klass->is_objArray_klass()) {
! // Find the element klass, if this is an array.
! resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
! }
! if (resolved_klass->is_instance_klass()) {
! Reflection::VerifyClassAccessResults result =
! Reflection::verify_class_access(accessing_klass, InstanceKlass::cast(resolved_klass), true);
! return result == Reflection::ACCESS_OK;
}
- return true;
}
! // ------------------------------------------------------------------
! Klass* JVMCIEnv::get_klass_by_name_impl(Klass* accessing_klass,
! const constantPoolHandle& cpool,
! Symbol* sym,
! bool require_local) {
! JVMCI_EXCEPTION_CONTEXT;
!
! // Now we need to check the SystemDictionary
! if (sym->char_at(0) == 'L' &&
! sym->char_at(sym->utf8_length()-1) == ';') {
! // This is a name from a signature. Strip off the trimmings.
! // Call recursive to keep scope of strippedsym.
! TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
! sym->utf8_length()-2,
! CHECK_NULL);
! return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local);
! }
!
! Handle loader(THREAD, (oop)NULL);
! Handle domain(THREAD, (oop)NULL);
! if (accessing_klass != NULL) {
! loader = Handle(THREAD, accessing_klass->class_loader());
! domain = Handle(THREAD, accessing_klass->protection_domain());
}
-
- Klass* found_klass = NULL;
- {
- ttyUnlocker ttyul; // release tty lock to avoid ordering problems
- MutexLocker ml(Compile_lock);
- if (!require_local) {
- found_klass = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_NULL);
} else {
! found_klass = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_NULL);
}
}
! // If we fail to find an array klass, look again for its element type.
! // The element type may be available either locally or via constraints.
! // In either case, if we can find the element type in the system dictionary,
! // we must build an array type around it. The CI requires array klasses
! // to be loaded if their element klasses are loaded, except when memory
! // is exhausted.
! if (sym->char_at(0) == '[' &&
! (sym->char_at(1) == '[' || sym->char_at(1) == 'L')) {
! // We have an unloaded array.
! // Build it on the fly if the element class exists.
! TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
! sym->utf8_length()-1,
! CHECK_NULL);
! // Get element Klass recursively.
! Klass* elem_klass =
! get_klass_by_name_impl(accessing_klass,
! cpool,
! elem_sym,
! require_local);
! if (elem_klass != NULL) {
! // Now make an array for it
! return elem_klass->array_klass(THREAD);
}
}
! if (found_klass == NULL && !cpool.is_null() && cpool->has_preresolution()) {
! // Look inside the constant pool for pre-resolved class entries.
! for (int i = cpool->length() - 1; i >= 1; i--) {
! if (cpool->tag_at(i).is_klass()) {
! Klass* kls = cpool->resolved_klass_at(i);
! if (kls->name() == sym) {
! return kls;
}
}
}
}
! return found_klass;
}
! // ------------------------------------------------------------------
! Klass* JVMCIEnv::get_klass_by_name(Klass* accessing_klass,
! Symbol* klass_name,
! bool require_local) {
ResourceMark rm;
! constantPoolHandle cpool;
! return get_klass_by_name_impl(accessing_klass,
! cpool,
! klass_name,
! require_local);
! }
!
! // ------------------------------------------------------------------
! // Implementation of get_klass_by_index.
! Klass* JVMCIEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
! int index,
! bool& is_accessible,
! Klass* accessor) {
! JVMCI_EXCEPTION_CONTEXT;
! Klass* klass = ConstantPool::klass_at_if_loaded(cpool, index);
! Symbol* klass_name = NULL;
! if (klass == NULL) {
! klass_name = cpool->klass_name_at(index);
! }
!
! if (klass == NULL) {
! // Not found in constant pool. Use the name to do the lookup.
! Klass* k = get_klass_by_name_impl(accessor,
! cpool,
! klass_name,
! false);
! // Calculate accessibility the hard way.
! if (k == NULL) {
! is_accessible = false;
! } else if (k->class_loader() != accessor->class_loader() &&
! get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) {
! // Loaded only remotely. Not linked yet.
! is_accessible = false;
} else {
! // Linked locally, and we must also check public/private, etc.
! is_accessible = check_klass_accessibility(accessor, k);
}
- if (!is_accessible) {
- return NULL;
}
! return k;
}
! // It is known to be accessible, since it was found in the constant pool.
! is_accessible = true;
! return klass;
}
! // ------------------------------------------------------------------
! // Get a klass from the constant pool.
! Klass* JVMCIEnv::get_klass_by_index(const constantPoolHandle& cpool,
! int index,
! bool& is_accessible,
! Klass* accessor) {
! ResourceMark rm;
! return get_klass_by_index_impl(cpool, index, is_accessible, accessor);
}
! // ------------------------------------------------------------------
! // Implementation of get_field_by_index.
! //
! // Implementation note: the results of field lookups are cached
! // in the accessor klass.
! void JVMCIEnv::get_field_by_index_impl(InstanceKlass* klass, fieldDescriptor& field_desc,
! int index) {
! JVMCI_EXCEPTION_CONTEXT;
!
! assert(klass->is_linked(), "must be linked before using its constant-pool");
!
! constantPoolHandle cpool(thread, klass->constants());
!
! // Get the field's name, signature, and type.
! Symbol* name = cpool->name_ref_at(index);
!
! int nt_index = cpool->name_and_type_ref_index_at(index);
! int sig_index = cpool->signature_ref_index_at(nt_index);
! Symbol* signature = cpool->symbol_at(sig_index);
!
! // Get the field's declared holder.
! int holder_index = cpool->klass_ref_index_at(index);
! bool holder_is_accessible;
! Klass* declared_holder = get_klass_by_index(cpool, holder_index,
! holder_is_accessible,
! klass);
!
! // The declared holder of this field may not have been loaded.
! // Bail out with partial field information.
! if (!holder_is_accessible) {
! return;
}
- // Perform the field lookup.
- Klass* canonical_holder =
- InstanceKlass::cast(declared_holder)->find_field(name, signature, &field_desc);
- if (canonical_holder == NULL) {
- return;
}
! assert(canonical_holder == field_desc.field_holder(), "just checking");
}
! // ------------------------------------------------------------------
! // Get a field by index from a klass's constant pool.
! void JVMCIEnv::get_field_by_index(InstanceKlass* accessor, fieldDescriptor& fd, int index) {
! ResourceMark rm;
! return get_field_by_index_impl(accessor, fd, index);
}
! // ------------------------------------------------------------------
! // Perform an appropriate method lookup based on accessor, holder,
! // name, signature, and bytecode.
! methodHandle JVMCIEnv::lookup_method(InstanceKlass* accessor,
! Klass* holder,
! Symbol* name,
! Symbol* sig,
! Bytecodes::Code bc,
! constantTag tag) {
! // Accessibility checks are performed in JVMCIEnv::get_method_by_index_impl().
! assert(check_klass_accessibility(accessor, holder), "holder not accessible");
!
! methodHandle dest_method;
! LinkInfo link_info(holder, name, sig, accessor, LinkInfo::needs_access_check, tag);
! switch (bc) {
! case Bytecodes::_invokestatic:
! dest_method =
! LinkResolver::resolve_static_call_or_null(link_info);
! break;
! case Bytecodes::_invokespecial:
! dest_method =
! LinkResolver::resolve_special_call_or_null(link_info);
! break;
! case Bytecodes::_invokeinterface:
! dest_method =
! LinkResolver::linktime_resolve_interface_method_or_null(link_info);
! break;
! case Bytecodes::_invokevirtual:
! dest_method =
! LinkResolver::linktime_resolve_virtual_method_or_null(link_info);
! break;
! default: ShouldNotReachHere();
! }
!
! return dest_method;
}
! // ------------------------------------------------------------------
! methodHandle JVMCIEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
! int index, Bytecodes::Code bc,
! InstanceKlass* accessor) {
! if (bc == Bytecodes::_invokedynamic) {
! ConstantPoolCacheEntry* cpce = cpool->invokedynamic_cp_cache_entry_at(index);
! bool is_resolved = !cpce->is_f1_null();
! if (is_resolved) {
! // Get the invoker Method* from the constant pool.
! // (The appendix argument, if any, will be noted in the method's signature.)
! Method* adapter = cpce->f1_as_method();
! return methodHandle(adapter);
}
! return NULL;
}
! int holder_index = cpool->klass_ref_index_at(index);
! bool holder_is_accessible;
! Klass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
!
! // Get the method's name and signature.
! Symbol* name_sym = cpool->name_ref_at(index);
! Symbol* sig_sym = cpool->signature_ref_at(index);
!
! if (cpool->has_preresolution()
! || ((holder == SystemDictionary::MethodHandle_klass() || holder == SystemDictionary::VarHandle_klass()) &&
! MethodHandles::is_signature_polymorphic_name(holder, name_sym))) {
! // Short-circuit lookups for JSR 292-related call sites.
! // That is, do not rely only on name-based lookups, because they may fail
! // if the names are not resolvable in the boot class loader (7056328).
! switch (bc) {
! case Bytecodes::_invokevirtual:
! case Bytecodes::_invokeinterface:
! case Bytecodes::_invokespecial:
! case Bytecodes::_invokestatic:
! {
! Method* m = ConstantPool::method_at_if_loaded(cpool, index);
! if (m != NULL) {
! return m;
}
}
! break;
! default:
! break;
}
}
! if (holder_is_accessible) { // Our declared holder is loaded.
! constantTag tag = cpool->tag_ref_at(index);
! methodHandle m = lookup_method(accessor, holder, name_sym, sig_sym, bc, tag);
! if (!m.is_null()) {
! // We found the method.
! return m;
}
}
! // Either the declared holder was not loaded, or the method could
! // not be found.
! return NULL;
}
! // ------------------------------------------------------------------
! InstanceKlass* JVMCIEnv::get_instance_klass_for_declared_method_holder(Klass* method_holder) {
! // For the case of <array>.clone(), the method holder can be an ArrayKlass*
! // instead of an InstanceKlass*. For that case simply pretend that the
! // declared holder is Object.clone since that's where the call will bottom out.
! if (method_holder->is_instance_klass()) {
! return InstanceKlass::cast(method_holder);
! } else if (method_holder->is_array_klass()) {
! return SystemDictionary::Object_klass();
} else {
! ShouldNotReachHere();
}
- return NULL;
}
! // ------------------------------------------------------------------
! methodHandle JVMCIEnv::get_method_by_index(const constantPoolHandle& cpool,
! int index, Bytecodes::Code bc,
! InstanceKlass* accessor) {
! ResourceMark rm;
! return get_method_by_index_impl(cpool, index, bc, accessor);
}
! // ------------------------------------------------------------------
! // Check for changes to the system dictionary during compilation
! // class loads, evolution, breakpoints
! JVMCIEnv::CodeInstallResult JVMCIEnv::validate_compile_task_dependencies(Dependencies* dependencies, Handle compiled_code,
! JVMCIEnv* env, char** failure_detail) {
! // If JVMTI capabilities were enabled during compile, the compilation is invalidated.
! if (env != NULL && env->jvmti_state_changed()) {
! *failure_detail = (char*) "Jvmti state change during compilation invalidated dependencies";
! return JVMCIEnv::dependencies_failed;
! }
!
! // Dependencies must be checked when the system dictionary changes
! // or if we don't know whether it has changed (i.e., env == NULL).
! bool counter_changed = env == NULL || env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications();
! CompileTask* task = env == NULL ? NULL : env->task();
! Dependencies::DepType result = dependencies->validate_dependencies(task, counter_changed, failure_detail);
! if (result == Dependencies::end_marker) {
! return JVMCIEnv::ok;
! }
!
! if (!Dependencies::is_klass_type(result) || counter_changed) {
! return JVMCIEnv::dependencies_failed;
! }
! // The dependencies were invalid at the time of installation
! // without any intervening modification of the system
! // dictionary. That means they were invalidly constructed.
! return JVMCIEnv::dependencies_invalid;
! }
!
! // ------------------------------------------------------------------
! JVMCIEnv::CodeInstallResult JVMCIEnv::register_method(
! const methodHandle& method,
! nmethod*& nm,
! int entry_bci,
! CodeOffsets* offsets,
! int orig_pc_offset,
! CodeBuffer* code_buffer,
! int frame_words,
! OopMapSet* oop_map_set,
! ExceptionHandlerTable* handler_table,
! AbstractCompiler* compiler,
! DebugInformationRecorder* debug_info,
! Dependencies* dependencies,
! JVMCIEnv* env,
! int compile_id,
! bool has_unsafe_access,
! bool has_wide_vector,
! Handle installed_code,
! Handle compiled_code,
! Handle speculation_log) {
! JVMCI_EXCEPTION_CONTEXT;
! nm = NULL;
! int comp_level = CompLevel_full_optimization;
! char* failure_detail = NULL;
! JVMCIEnv::CodeInstallResult result;
{
! // To prevent compile queue updates.
! MutexLocker locker(MethodCompileQueue_lock, THREAD);
! // Prevent SystemDictionary::add_to_hierarchy from running
! // and invalidating our dependencies until we install this method.
! MutexLocker ml(Compile_lock);
!
! // Encode the dependencies now, so we can check them right away.
! dependencies->encode_content_bytes();
!
! // Record the dependencies for the current compile in the log
! if (LogCompilation) {
! for (Dependencies::DepStream deps(dependencies); deps.next(); ) {
! deps.log_dependency();
}
}
! // Check for {class loads, evolution, breakpoints} during compilation
! result = validate_compile_task_dependencies(dependencies, compiled_code, env, &failure_detail);
! if (result != JVMCIEnv::ok) {
! // While not a true deoptimization, it is a preemptive decompile.
! MethodData* mdp = method()->method_data();
! if (mdp != NULL) {
! mdp->inc_decompile_count();
! #ifdef ASSERT
! if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) {
! ResourceMark m;
! tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string());
}
! #endif
}
! // All buffers in the CodeBuffer are allocated in the CodeCache.
! // If the code buffer is created on each compile attempt
! // as in C2, then it must be freed.
! //code_buffer->free_blob();
! } else {
! ImplicitExceptionTable implicit_tbl;
! nm = nmethod::new_nmethod(method,
! compile_id,
! entry_bci,
! offsets,
! orig_pc_offset,
! debug_info, dependencies, code_buffer,
! frame_words, oop_map_set,
! handler_table, &implicit_tbl,
! compiler, comp_level,
! JNIHandles::make_weak_global(installed_code),
! JNIHandles::make_weak_global(speculation_log));
! // Free codeBlobs
! //code_buffer->free_blob();
! if (nm == NULL) {
! // The CodeCache is full. Print out warning and disable compilation.
! {
! MutexUnlocker ml(Compile_lock);
! MutexUnlocker locker(MethodCompileQueue_lock);
! CompileBroker::handle_full_code_cache(CodeCache::get_code_blob_type(comp_level));
! }
! } else {
! nm->set_has_unsafe_access(has_unsafe_access);
! nm->set_has_wide_vectors(has_wide_vector);
!
! // Record successful registration.
! // (Put nm into the task handle *before* publishing to the Java heap.)
! CompileTask* task = env == NULL ? NULL : env->task();
! if (task != NULL) {
! task->set_code(nm);
! }
!
! if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) {
! if (entry_bci == InvocationEntryBci) {
! if (TieredCompilation) {
! // If there is an old version we're done with it
! CompiledMethod* old = method->code();
! if (TraceMethodReplacement && old != NULL) {
! ResourceMark rm;
! char *method_name = method->name_and_sig_as_C_string();
! tty->print_cr("Replacing method %s", method_name);
}
! if (old != NULL ) {
! old->make_not_entrant();
}
}
! if (TraceNMethodInstalls) {
! ResourceMark rm;
! char *method_name = method->name_and_sig_as_C_string();
! ttyLocker ttyl;
! tty->print_cr("Installing method (%d) %s [entry point: %p]",
! comp_level,
! method_name, nm->entry_point());
}
- // Allow the code to be executed
- method->set_code(method, nm);
} else {
! if (TraceNMethodInstalls ) {
! ResourceMark rm;
! char *method_name = method->name_and_sig_as_C_string();
! ttyLocker ttyl;
! tty->print_cr("Installing osr method (%d) %s @ %d",
! comp_level,
! method_name,
! entry_bci);
}
! InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm);
}
}
! nm->make_in_use();
}
! result = nm != NULL ? JVMCIEnv::ok :JVMCIEnv::cache_full;
}
}
! // String creation must be done outside lock
! if (failure_detail != NULL) {
! // A failure to allocate the string is silently ignored.
! Handle message = java_lang_String::create_from_str(failure_detail, THREAD);
! HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message());
}
! // JVMTI -- compiled method notification (must be done outside lock)
! if (nm != NULL) {
! nm->post_compiled_method_load_event();
! if (env == NULL) {
! // This compile didn't come through the CompileBroker so perform the printing here
! DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
! nm->maybe_print_nmethod(directive);
! DirectivesStack::release(directive);
}
}
! return result;
}
--- 86,1406 ----
return true;
}
return false;
}
! JavaVM* JVMCIEnv::_shared_library_javavm = NULL;
! void* JVMCIEnv::_shared_library_handle = NULL;
! char* JVMCIEnv::_shared_library_path = NULL;
!
! void JVMCIEnv::copy_saved_properties() {
! assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");
!
! JavaThread* THREAD = JavaThread::current();
!
! Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
! }
! InstanceKlass* ik = InstanceKlass::cast(k);
! if (ik->should_be_initialized()) {
! ik->initialize(THREAD);
! if (HAS_PENDING_EXCEPTION) {
! JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
}
}
! // Get the serialized saved properties from HotSpot
! TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT);
! JavaValue result(T_OBJECT);
! JavaCallArguments args;
! JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties");
! }
! oop res = (oop) result.get_jobject();
! assert(res->is_typeArray(), "must be");
! assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");
! typeArrayOop ba = typeArrayOop(res);
! int serialized_properties_len = ba->length();
!
! // Copy serialized saved properties from HotSpot object into native buffer
! jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len);
! memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len);
!
! // Copy native buffer into shared library object
! JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this);
! if (has_pending_exception()) {
! describe_pending_exception(true);
! fatal("Error in copy_saved_properties");
! }
! copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
! if (has_pending_exception()) {
! describe_pending_exception(true);
! fatal("Error in copy_saved_properties");
! }
!
! // Initialize saved properties in shared library
! jclass servicesClass = JNIJVMCI::Services::clazz();
! jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
! JNIAccessMark jni(this);
! jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
! if (jni()->ExceptionCheck()) {
! jni()->ExceptionDescribe();
! fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
}
}
! JNIEnv* JVMCIEnv::attach_shared_library() {
! if (_shared_library_javavm == NULL) {
! MutexLocker locker(JVMCI_lock);
! if (_shared_library_javavm == NULL) {
!
! char path[JVM_MAXPATHLEN];
! char ebuf[1024];
! if (JVMCILibPath != NULL) {
! if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
! vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
}
} else {
! if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
! vm_exit_during_initialization("Unable to create path to JVMCI shared library");
}
}
! void* handle = os::dll_load(path, ebuf, sizeof ebuf);
! if (handle == NULL) {
! vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
! }
! _shared_library_handle = handle;
! _shared_library_path = strdup(path);
! jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
! typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
!
! JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(handle, "JNI_CreateJavaVM"));
! JNIEnv* env;
! if (JNI_CreateJavaVM == NULL) {
! vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", path);
! }
! ResourceMark rm;
! JavaVMInitArgs vm_args;
! vm_args.version = JNI_VERSION_1_2;
! vm_args.ignoreUnrecognized = JNI_TRUE;
! vm_args.options = NULL;
! vm_args.nOptions = 0;
!
! JavaVM* the_javavm = NULL;
! int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
! if (result == JNI_OK) {
! guarantee(env != NULL, "missing env");
! _shared_library_javavm = the_javavm;
! return env;
! } else {
! vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
! }
}
}
+ JNIEnv* env;
+ if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) {
+ guarantee(env != NULL, "missing env");
+ return env;
+ }
+ fatal("Error attaching current thread to JVMCI shared library JNI interface");
+ return NULL;
+ }
! void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) {
! // By default there is only one runtime which is the compiler runtime.
! _runtime = JVMCI::compiler_runtime();
! if (!UseJVMCINativeLibrary) {
! // In HotSpot mode, JNI isn't used at all.
! _is_hotspot = true;
! _env = NULL;
! return;
}
+
+ if (parent_env != NULL) {
+ // If the parent JNI environment is non-null then figure out whether it
+ // is a HotSpot or shared library JNIEnv and set the state appropriately.
+ JavaThread* thread = JavaThread::current();
+ if (thread->jni_environment() == parent_env) {
+ // Select the Java runtime
+ _runtime = JVMCI::java_runtime();
+ _is_hotspot = true;
+ _env = NULL;
+ return;
}
}
+
+ // Running in JVMCI shared library mode so get a shared library JNIEnv
+ _is_hotspot = false;
+ _env = attach_shared_library();
+ assert(parent_env == NULL || _env == parent_env, "must be");
+
+ if (parent_env == NULL) {
+ // There is no parent shared library JNI env so push
+ // a JNI local frame to release all local handles in
+ // this JVMCIEnv scope when it's closed.
+ assert(_throw_to_caller == false, "must be");
+ JNIAccessMark jni(this);
+ jint result = _env->PushLocalFrame(32);
+ if (result != JNI_OK) {
+ char message[256];
+ jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
+ JVMCIRuntime::exit_on_pending_exception(this, message);
+ }
}
+ }
+
+ JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line):
+ _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
+ init_env_mode_runtime(NULL);
+ }
! JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
! _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
! init_env_mode_runtime(NULL);
}
! JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line):
! _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
! init_env_mode_runtime(parent_env);
! assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
! }
!
! void JVMCIEnv::init(bool is_hotspot, const char* file, int line) {
! _compile_state = NULL;
! _throw_to_caller = false;
! _file = file;
! _line = line;
! if (is_hotspot) {
! _env = NULL;
! _is_hotspot = true;
! _runtime = JVMCI::java_runtime();
! } else {
! init_env_mode_runtime(NULL);
! }
! }
!
! // Prints a pending exception (if any) and its stack trace.
! void JVMCIEnv::describe_pending_exception(bool clear) {
! if (!is_hotspot()) {
! JNIAccessMark jni(this);
! if (jni()->ExceptionCheck()) {
! jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
! jni()->ExceptionDescribe();
! if (ex != NULL) {
! jni()->Throw(ex);
! }
! }
! } else {
! Thread* THREAD = Thread::current();
! if (HAS_PENDING_EXCEPTION) {
! JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
! }
! }
! }
!
! void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, Handle throwable) {
! assert(!is_hotspot(), "must_be");
! // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets
! // may not have been called.
! Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);
! JavaCallArguments jargs;
! jargs.push_oop(throwable);
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result,
! runtimeKlass,
! vmSymbols::encodeThrowable_name(),
! vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");
! }
!
! oop encoded_throwable_string = (oop) result.get_jobject();
!
ResourceMark rm;
! const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string);
!
! JNIAccessMark jni(this);
! jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars);
! jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
! JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
! jni_encoded_throwable_string);
! jni()->Throw(jni_throwable);
! }
!
! JVMCIEnv::~JVMCIEnv() {
! if (_throw_to_caller) {
! if (is_hotspot()) {
! // Nothing to do
} else {
! if (Thread::current()->is_Java_thread()) {
! JavaThread* THREAD = JavaThread::current();
! if (HAS_PENDING_EXCEPTION) {
! Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
! CLEAR_PENDING_EXCEPTION;
! translate_hotspot_exception_to_jni_exception(THREAD, throwable);
}
}
! }
! } else {
! if (!is_hotspot()) {
! // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
! JNIAccessMark jni(this);
! jni()->PopLocalFrame(NULL);
}
! if (has_pending_exception()) {
! char message[256];
! jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
! JVMCIRuntime::exit_on_pending_exception(this, message);
! }
! }
}
! JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
! jlong compile_state, int id) {
! if (is_hotspot()) {
! Thread* THREAD = Thread::current();
! JavaCallArguments jargs;
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
! jargs.push_int(entry_bci);
! jargs.push_long(compile_state);
! jargs.push_int(id);
! JavaValue result(T_OBJECT);
! JavaCalls::call_special(&result,
! HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
! vmSymbols::compileMethod_name(),
! vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
! JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
! JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
! method.as_jobject(), entry_bci, compile_state, id);
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! return wrap(result);
! }
}
! int JVMCIEnv::call_HotSpotJVMCIRuntime_adjustCompilationLevel (JVMCIObject runtime, InstanceKlass* declaringClass,
! JVMCIObject name, JVMCIObject signature, bool is_osr, int level, JVMCI_TRAPS) {
! if (is_hotspot()) {
! Thread* THREAD = Thread::current();
! JavaCallArguments jargs;
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
! jargs.push_oop(Handle(THREAD, declaringClass->java_mirror()));
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(name)));
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
! jargs.push_int(is_osr);
! jargs.push_int(level);
! JavaValue result(T_INT);
! JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::adjustCompilationLevel_name(), vmSymbols::adjustCompilationLevel_signature(), &jargs, THREAD);
! return result.get_jint();
! } else {
! JVMCIObject declaringClassName = create_string(declaringClass->external_name(), JVMCI_CHECK_(0));
! int result;
! {
! JNIAccessMark jni(this);
! result = jni()->CallNonvirtualIntMethod(runtime.as_jobject(),
! JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
! JNIJVMCI::HotSpotJVMCIRuntime::adjustCompilationLevel_method(),
! get_jobject(declaringClassName), get_jobject(name), get_jobject(signature), is_osr, level);
}
+ return result;
+ }
+ }
+ void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
+ if (is_hotspot()) {
+ Thread* THREAD = Thread::current();
+ JavaCallArguments jargs;
+ jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+ JavaValue result(T_VOID);
+ JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
+ } else {
+ JNIAccessMark jni(this);
+ jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
}
+ }
! void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
! HandleMark hm;
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
! JavaValue result(T_VOID);
! JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
! } else {
! JNIAccessMark jni(this);
! jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
! }
! if (has_pending_exception()) {
! // This should never happen as HotSpotJVMCIRuntime.shutdown() should
! // handle all exceptions.
! describe_pending_exception(true);
! }
}
! JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! return wrap(result);
! }
! }
!
! JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! return wrap(result);
! }
! }
!
! JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
! JavaValue result(T_OBJECT);
! JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! return wrap(result);
! }
}
!
! JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result,
! HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
! vmSymbols::callToString_name(),
! vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
! JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
! object.as_jobject());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! return wrap(result);
! }
}
! JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_int(kind);
! jargs.push_long(value);
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result,
! HotSpotJVMCI::PrimitiveConstant::klass(),
! vmSymbols::forTypeChar_name(),
! vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(),
! JNIJVMCI::PrimitiveConstant::forTypeChar_method(),
! kind, value);
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
}
+ return wrap(result);
+ }
+ }
! JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_float(value);
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result,
! HotSpotJVMCI::JavaConstant::klass(),
! vmSymbols::forFloat_name(),
! vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
! JNIJVMCI::JavaConstant::forFloat_method(),
! value);
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
}
+ return wrap(result);
+ }
+ }
! JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! JavaCallArguments jargs;
! jargs.push_double(value);
! JavaValue result(T_OBJECT);
! JavaCalls::call_static(&result,
! HotSpotJVMCI::JavaConstant::klass(),
! vmSymbols::forDouble_name(),
! vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject()));
! return wrap((oop) result.get_jobject());
! } else {
! JNIAccessMark jni(this);
! jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
! JNIJVMCI::JavaConstant::forDouble_method(),
! value);
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
}
+ return wrap(result);
}
! }
!
! JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
! JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
! JVMCIObject result = get_object_at(primitives, type);
! return result;
! }
!
! JVMCIObject JVMCIEnv::new_StackTraceElement(methodHandle method, int bci, JVMCI_TRAPS) {
! JavaThread* THREAD = JavaThread::current();
! Symbol* method_name_sym;
! Symbol* file_name_sym;
! int line_number;
! Handle mirror (THREAD, method->method_holder()->java_mirror());
! java_lang_StackTraceElement::decode(mirror, method, bci, method_name_sym, file_name_sym, line_number);
!
! InstanceKlass* holder = method->method_holder();
! const char* declaring_class_str = holder->external_name();
!
! if (is_hotspot()) {
! HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
! oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
! Handle obj = Handle(THREAD, objOop);
!
! oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
! HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
!
! oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
! HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
!
! if (file_name_sym != NULL) {
! oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
! HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
! }
! HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
! return wrap(obj());
! } else {
! JNIAccessMark jni(this);
! jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
! }
! jobject file_name = NULL;
! if (file_name != NULL) {
! file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
! if (jni()->ExceptionCheck()) {
! return JVMCIObject();
}
}
! jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
! JNIJVMCI::StackTraceElement::constructor(),
! declaring_class, method_name, file_name, line_number);
! return wrap(result);
}
+ }
+
+ JVMCIObject JVMCIEnv::new_HotSpotNmethod(methodHandle method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
+ JavaThread* THREAD = JavaThread::current();
+
+ JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
+
+ if (is_hotspot()) {
+ InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
+ if (ik->should_be_initialized()) {
+ ik->initialize(CHECK_(JVMCIObject()));
+ }
+ oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
+ Handle obj_h(THREAD, obj);
+ Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
+
+ // Call constructor
+ JavaCallArguments jargs;
+ jargs.push_oop(obj_h);
+ jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
+ jargs.push_oop(nameStr);
+ jargs.push_int(isDefault);
+ jargs.push_long(compileId);
+ JavaValue result(T_VOID);
+ JavaCalls::call_special(&result, ik,
+ vmSymbols::object_initializer_name(),
+ vmSymbols::method_string_bool_long_signature(),
+ &jargs, CHECK_(JVMCIObject()));
+ return wrap(obj_h());
+ } else {
+ JNIAccessMark jni(this);
+ jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);
+ if (jni()->ExceptionCheck()) {
+ return JVMCIObject();
}
! jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
! JNIJVMCI::HotSpotNmethod::constructor(),
! methodObject.as_jobject(), nameStr, isDefault);
! return wrap(result);
! }
! }
! JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
! if (object.is_null()) {
! return JVMCIObject();
! }
! if (is_hotspot()) {
! return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
! } else {
! JNIAccessMark jni(this);
! return wrap(jni()->NewLocalRef(object.as_jobject()));
! }
}
! JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
! if (object.is_null()) {
! return JVMCIObject();
! }
! if (is_hotspot()) {
! return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
} else {
! JNIAccessMark jni(this);
! return wrap(jni()->NewGlobalRef(object.as_jobject()));
}
}
+ JVMCIObject JVMCIEnv::make_weak(JVMCIObject object) {
+ if (object.is_null()) {
+ return JVMCIObject();
+ }
+ if (is_hotspot()) {
+ return wrap(JNIHandles::make_weak_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
+ } else {
+ JNIAccessMark jni(this);
+ return wrap(jni()->NewWeakGlobalRef(object.as_jobject()));
+ }
+ }
! void JVMCIEnv::destroy_local(JVMCIObject object) {
! if (is_hotspot()) {
! JNIHandles::destroy_local(object.as_jobject());
! } else {
! JNIAccessMark jni(this);
! jni()->DeleteLocalRef(object.as_jobject());
! }
}
! void JVMCIEnv::destroy_global(JVMCIObject object) {
! if (is_hotspot()) {
! JNIHandles::destroy_global(object.as_jobject());
! } else {
! JNIAccessMark jni(this);
! jni()->DeleteGlobalRef(object.as_jobject());
! }
! }
!
! void JVMCIEnv::destroy_weak(JVMCIObject object) {
! if (is_hotspot()) {
! JNIHandles::destroy_weak_global(object.as_jweak());
! } else {
! JNIAccessMark jni(this);
! jni()->DeleteWeakGlobalRef(object.as_jweak());
! }
! }
!
! const char* JVMCIEnv::klass_name(JVMCIObject object) {
! if (is_hotspot()) {
! return HotSpotJVMCI::resolve(object)->klass()->signature_name();
! } else {
! JVMCIObject name;
{
! JNIAccessMark jni(this);
! jclass jcl = jni()->GetObjectClass(object.as_jobject());
! jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
! name = JVMCIObject::create(result, is_hotspot());
! }
! return as_utf8_string(name);
! }
! }
! JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
! JVMCIObject method_object;
! if (method() == NULL) {
! return method_object;
! }
!
! Thread* THREAD = Thread::current();
! jmetadata handle = JVMCI::allocate_handle(method);
! jboolean exception = false;
! if (is_hotspot()) {
! JavaValue result(T_OBJECT);
! JavaCallArguments args;
! args.push_long((jlong) handle);
! JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
! vmSymbols::fromMetaspace_name(),
! vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! exception = true;
! } else {
! method_object = wrap((oop)result.get_jobject());
}
+ } else {
+ JNIAccessMark jni(this);
+ method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
+ JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
+ (jlong) handle));
+ exception = jni()->ExceptionCheck();
}
! if (exception) {
! JVMCI::release_handle(handle);
! return JVMCIObject();
}
!
! assert(asMethod(method_object) == method(), "must be");
! if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {
! JVMCI::release_handle(handle);
}
+ assert(!method_object.is_null(), "must be");
+ return method_object;
+ }
! JVMCIObject JVMCIEnv::get_jvmci_type(JVMCIKlassHandle& klass, JVMCI_TRAPS) {
! JVMCIObject type;
! if (klass.is_null()) {
! return type;
! }
! #ifdef INCLUDE_ALL_GCS
! if (UseG1GC) {
! // The klass might have come from a weak location so enqueue
! // the Class to make sure it's noticed by G1
! G1SATBCardTableModRefBS::enqueue(klass()->java_mirror());
! }
! #endif // Klass* don't require tracking as Metadata*
!
! jlong pointer = (jlong) klass();
! JavaThread* THREAD = JavaThread::current();
! JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
! jboolean exception = false;
! if (is_hotspot()) {
! JavaValue result(T_OBJECT);
! JavaCallArguments args;
! args.push_long(pointer);
! args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
! JavaCalls::call_static(&result,
! HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
! vmSymbols::fromMetaspace_name(),
! vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! exception = true;
! } else {
! type = wrap((oop)result.get_jobject());
}
! } else {
! JNIAccessMark jni(this);
!
! HandleMark hm(THREAD);
! type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
! JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
! pointer, signature.as_jstring()));
! exception = jni()->ExceptionCheck();
}
+ if (exception) {
+ return JVMCIObject();
}
!
! assert(type.is_non_null(), "must have result");
! return type;
! }
!
! JVMCIObject JVMCIEnv::get_jvmci_constant_pool(constantPoolHandle cp, JVMCI_TRAPS) {
! JVMCIObject cp_object;
! jmetadata handle = JVMCI::allocate_handle(cp);
! jboolean exception = false;
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! JavaValue result(T_OBJECT);
! JavaCallArguments args;
! args.push_long((jlong) handle);
! JavaCalls::call_static(&result,
! HotSpotJVMCI::HotSpotConstantPool::klass(),
! vmSymbols::fromMetaspace_name(),
! vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
! if (HAS_PENDING_EXCEPTION) {
! exception = true;
! } else {
! cp_object = wrap((oop)result.get_jobject());
}
} else {
! JNIAccessMark jni(this);
! cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
! JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
! (jlong) handle));
! exception = jni()->ExceptionCheck();
! }
!
! if (exception) {
! JVMCI::release_handle(handle);
! return JVMCIObject();
! }
!
! assert(!cp_object.is_null(), "must be");
! // Constant pools aren't cached so this is always a newly created object using the handle
! assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");
! return cp_object;
! }
!
! JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
! return wrap(result);
! } else {
! JNIAccessMark jni(this);
! jbooleanArray result = jni()->NewBooleanArray(length);
! return wrap(result);
}
! }
!
! JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
! return wrap(result);
! } else {
! JNIAccessMark jni(this);
! jbyteArray result = jni()->NewByteArray(length);
! return wrap(result);
}
+ }
+
+ JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
+ if (is_hotspot()) {
+ JavaThread* THREAD = JavaThread::current();
+ Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject()));
+ objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
+ return wrap(result);
+ } else {
+ JNIAccessMark jni(this);
+ jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);
+ return wrap(result);
}
! }
!
! JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
! return wrap(result);
! } else {
! JNIAccessMark jni(this);
! jintArray result = jni()->NewIntArray(length);
! return wrap(result);
}
! }
!
! JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
! return wrap(result);
! } else {
! JNIAccessMark jni(this);
! jlongArray result = jni()->NewLongArray(length);
! return wrap(result);
}
+ }
+
+ JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
+ if (is_hotspot()) {
+ JavaThread* THREAD = JavaThread::current();
+ HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
+ oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
+ HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
+ HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
+ HotSpotJVMCI::VMField::set_offset(this, obj, offset);
+ HotSpotJVMCI::VMField::set_address(this, obj, address);
+ HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value));
+ return wrap(obj);
+ } else {
+ JNIAccessMark jni(this);
+ jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(),
+ JNIJVMCI::VMField::constructor(),
+ get_jobject(name), get_jobject(type), offset, address, get_jobject(value));
+ return wrap(result);
}
+ }
! JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject()));
! oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject()));
! HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name));
! HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type));
! HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value));
! return wrap(obj);
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(),
! JNIJVMCI::VMFlag::constructor(),
! get_jobject(name), get_jobject(type), get_jobject(value));
! return wrap(result);
}
+ }
! JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject()));
! oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject()));
! HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass));
! HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name));
! HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor));
! HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id);
! return wrap(obj);
! } else {
! JNIAccessMark jni(this);
! jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(),
! JNIJVMCI::VMIntrinsicMethod::constructor(),
! get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id);
! return wrap(result);
! }
! }
! JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject()));
! oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject()));
! return wrap(obj);
! } else {
! ShouldNotReachHere();
! return JVMCIObject();
}
+ }
+ JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) {
+ if (is_hotspot()) {
+ JavaThread* THREAD = JavaThread::current();
+ HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject()));
+ oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject()));
+ return wrap(obj);
+ } else {
+ ShouldNotReachHere();
+ return JVMCIObject();
}
+ }
!
! JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) {
! JavaThread* THREAD = JavaThread::current();
! Handle obj = Handle(THREAD, objOop);
! if (obj.is_null()) {
! return JVMCIObject();
! }
! if (is_hotspot()) {
! HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject()));
! oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject()));
! HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj());
! HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed);
! return wrap(constant);
! } else {
! jlong handle = make_handle(obj);
! JNIAccessMark jni(this);
! jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(),
! JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(),
! handle, compressed, dont_register);
! return wrap(result);
! }
! }
!
!
! Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) {
! if (constant.is_null()) {
! return Handle();
! }
! JavaThread* THREAD = JavaThread::current();
! if (is_hotspot()) {
! assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
! oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
! return Handle(THREAD, obj);
! } else {
! assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type");
! jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
! oop result = resolve_handle(object_handle);
! if (result == NULL) {
! JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
! }
! return Handle(THREAD, result);
! }
! }
!
! JVMCIObject JVMCIEnv::wrap(jobject object) {
! return JVMCIObject::create(object, is_hotspot());
! }
!
! jlong JVMCIEnv::make_handle(Handle obj) {
! assert(!obj.is_null(), "should only create handle for non-NULL oops");
! jobject handle = JVMCI::make_global(obj);
! return (jlong) handle;
! }
!
! oop JVMCIEnv::resolve_handle(jlong objectHandle) {
! assert(objectHandle != 0, "should be a valid handle");
! oop obj = *((oopDesc**)objectHandle);
! if (obj != NULL) {
! oopDesc::verify(obj);
! }
! return obj;
! }
!
! JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) {
! if (is_hotspot()) {
! JavaThread* THREAD = JavaThread::current();
! Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject()));
! return HotSpotJVMCI::wrap(result());
! } else {
! jobject result;
! jboolean exception = false;
! {
! JNIAccessMark jni(this);
! result = jni()->NewStringUTF(str);
! exception = jni()->ExceptionCheck();
! }
! return wrap(result);
! }
! }
!
! bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) {
! if (is_hotspot()) {
! return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b);
! } else {
! JNIAccessMark jni(this);
! return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0;
! }
! }
!
! BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) {
! if (kind.is_null()) {
! JVMCI_THROW_(NullPointerException, T_ILLEGAL);
! }
! jchar ch = get_JavaKind_typeChar(kind);
! switch(ch) {
! case 'Z': return T_BOOLEAN;
! case 'B': return T_BYTE;
! case 'S': return T_SHORT;
! case 'C': return T_CHAR;
! case 'I': return T_INT;
! case 'F': return T_FLOAT;
! case 'J': return T_LONG;
! case 'D': return T_DOUBLE;
! case 'A': return T_OBJECT;
! case '-': return T_ILLEGAL;
! default:
! JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);
! }
! }
!
! void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) {
! // Ensure that all updates to the InstalledCode fields are consistent.
! if (get_InstalledCode_address(installed_code) != 0) {
! JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use");
! }
! if (!isa_HotSpotInstalledCode(installed_code)) {
! JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode");
! }
!
! // Ignore the version which can stay at 0
! if (cb->is_nmethod()) {
! nmethod* nm = cb->as_nmethod_or_null();
! if (!nm->is_alive()) {
! JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed");
! }
! if (nm->is_in_use()) {
! set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point());
! }
! } else {
! set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin());
! }
! set_InstalledCode_address(installed_code, (jlong) cb);
! set_HotSpotInstalledCode_size(installed_code, cb->size());
! set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin());
! set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size());
! }
!
!
! void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) {
! if (mirror.is_null()) {
! JVMCI_THROW(NullPointerException);
! }
!
! jlong nativeMethod = get_InstalledCode_address(mirror);
! nmethod* nm = JVMCIENV->asNmethod(mirror);
! if (nm == NULL) {
! // Nothing to do
! return;
! }
!
! Thread* THREAD = Thread::current();
! if (!mirror.is_hotspot() && !THREAD->is_Java_thread()) {
! // Calling back into native might cause the execution to block, so only allow this when calling
! // from a JavaThread, which is the normal case anyway.
! JVMCI_THROW_MSG(IllegalArgumentException,
! "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread");
! }
!
! nmethodLocker nml(nm);
! if (nm->is_alive()) {
! // Invalidating the HotSpotNmethod means we want the nmethod
! // to be deoptimized.
! nm->mark_for_deoptimization();
! VM_Deoptimize op;
! VMThread::execute(&op);
! }
!
! // A HotSpotNmethod instance can only reference a single nmethod
! // during its lifetime so simply clear it here.
! set_InstalledCode_address(mirror, 0);
! }
!
! Klass* JVMCIEnv::asKlass(JVMCIObject obj) {
! return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj);
}
+
+ Method* JVMCIEnv::asMethod(JVMCIObject obj) {
+ Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj);
+ return *metadataHandle;
+ }
+
+ ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) {
+ ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj);
+ return *metadataHandle;
+ }
+
+
+ CodeBlob* JVMCIEnv::asCodeBlob(JVMCIObject obj) {
+ address code = (address) get_InstalledCode_address(obj);
+ if (code == NULL) {
+ return NULL;
+ }
+ if (isa_HotSpotNmethod(obj)) {
+ jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj);
+ if (compile_id_snapshot != 0L) {
+ // A HotSpotNMethod not in an nmethod's oops table so look up
+ // the nmethod and then update the fields based on its state.
+ CodeBlob* cb = CodeCache::find_blob_unsafe(code);
+ if (cb == (CodeBlob*) code) {
+ // Found a live CodeBlob with the same address, make sure it's the same nmethod
+ nmethod* nm = cb->as_nmethod_or_null();
+ if (nm != NULL && nm->compile_id() == compile_id_snapshot) {
+ if (!nm->is_alive()) {
+ // Break the links from the mirror to the nmethod
+ set_InstalledCode_address(obj, 0);
+ set_InstalledCode_entryPoint(obj, 0);
+ } else if (nm->is_not_entrant()) {
+ // Zero the entry point so that the nmethod
+ // cannot be invoked by the mirror but can
+ // still be deoptimized.
+ set_InstalledCode_entryPoint(obj, 0);
+ }
+ return cb;
+ }
+ }
+ // Clear the InstalledCode fields of this HotSpotNmethod
+ // that no longer refers to an nmethod in the code cache.
+ set_InstalledCode_address(obj, 0);
+ set_InstalledCode_entryPoint(obj, 0);
+ return NULL;
+ }
+ }
+ return (CodeBlob*) code;
+ }
+
+
+ // Generate implementations for the initialize, new, isa, get and set methods for all the types and
+ // fields declared in the JVMCI_CLASSES_DO macro.
+
+ #define START_CLASS(className, fullClassName) \
+ void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \
+ if (is_hotspot()) { \
+ HotSpotJVMCI::className::initialize(JVMCI_CHECK); \
+ } else { \
+ JNIJVMCI::className::initialize(JVMCI_CHECK); \
+ } \
+ } \
+ JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \
+ if (is_hotspot()) { \
+ Thread* THREAD = Thread::current(); \
+ objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \
+ return (JVMCIObjectArray) wrap(array); \
+ } else { \
+ JNIAccessMark jni(this); \
+ jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \
+ return wrap(result); \
+ } \
+ } \
+ bool JVMCIEnv::isa_##className(JVMCIObject object) { \
+ if (is_hotspot()) { \
+ return HotSpotJVMCI::className::is_instance(this, object); \
+ } else { \
+ return JNIJVMCI::className::is_instance(this, object); \
+ } \
+ }
+
+ #define END_CLASS
+
+ #define FIELD(className, name, type, accessor, cast) \
+ type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \
+ if (is_hotspot()) { \
+ return HotSpotJVMCI::className::get_##name(this, obj); \
+ } else { \
+ return JNIJVMCI::className::get_##name(this, obj); \
+ } \
+ } \
+ void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
+ if (is_hotspot()) { \
+ HotSpotJVMCI::className::set_##name(this, obj, x); \
+ } else { \
+ JNIJVMCI::className::set_##name(this, obj, x); \
+ } \
+ }
+
+ #define EMPTY_CAST
+ #define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)
+ #define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)
+ #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
+ #define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)
+ #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)
+
+ #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
+ #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
+ #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
+
+ #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
+ #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
+
+ #define OOPISH_FIELD(className, name, type, accessor, cast) \
+ type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \
+ if (is_hotspot()) { \
+ return HotSpotJVMCI::className::get_##name(this, obj); \
+ } else { \
+ return JNIJVMCI::className::get_##name(this, obj); \
+ } \
+ } \
+ void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \
+ if (is_hotspot()) { \
+ HotSpotJVMCI::className::set_##name(this, obj, x); \
+ } else { \
+ JNIJVMCI::className::set_##name(this, obj, x); \
+ } \
+ }
+
+ #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \
+ type JVMCIEnv::get_##className##_##name() { \
+ if (is_hotspot()) { \
+ return HotSpotJVMCI::className::get_##name(this); \
+ } else { \
+ return JNIJVMCI::className::get_##name(this); \
+ } \
+ } \
+ void JVMCIEnv::set_##className##_##name(type x) { \
+ if (is_hotspot()) { \
+ HotSpotJVMCI::className::set_##name(this, x); \
+ } else { \
+ JNIJVMCI::className::set_##name(this, x); \
+ } \
+ }
+
+ #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
+ type JVMCIEnv::get_##className##_##name() { \
+ if (is_hotspot()) { \
+ return HotSpotJVMCI::className::get_##name(this); \
+ } else { \
+ return JNIJVMCI::className::get_##name(this); \
+ } \
+ } \
+ void JVMCIEnv::set_##className##_##name(type x) { \
+ if (is_hotspot()) { \
+ HotSpotJVMCI::className::set_##name(this, x); \
+ } else { \
+ JNIJVMCI::className::set_##name(this, x); \
+ } \
+ }
+ #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
+ #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
+ #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
+ #define CONSTRUCTOR(className, signature)
+
+ JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
+
+ #undef START_CLASS
+ #undef END_CLASS
+ #undef METHOD
+ #undef CONSTRUCTOR
+ #undef FIELD
+ #undef CHAR_FIELD
+ #undef INT_FIELD
+ #undef BOOLEAN_FIELD
+ #undef LONG_FIELD
+ #undef FLOAT_FIELD
+ #undef OBJECT_FIELD
+ #undef PRIMARRAY_FIELD
+ #undef OBJECTARRAY_FIELD
+ #undef STATIC_OOPISH_FIELD
+ #undef STATIC_OBJECT_FIELD
+ #undef STATIC_OBJECTARRAY_FIELD
+ #undef STATIC_INT_FIELD
+ #undef STATIC_BOOLEAN_FIELD
+ #undef EMPTY_CAST
src/hotspot/share/jvmci/jvmciEnv.cpp
Index
Unified diffs
Context diffs
Sdiffs
Frames
Patch
New
Old
Previous File
Next File