void GraalCompiler::compile_the_world() { HandleMark hm; JavaThread* THREAD = JavaThread::current(); TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", CHECK_ABORT); KlassHandle klass = GraalRuntime::load_required_class(name); TempNewSymbol compileTheWorld = SymbolTable::new_symbol("compileTheWorld", CHECK_ABORT); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(GraalRuntime::get_HotSpotGraalRuntime()); JavaCalls::call_special(&result, klass, compileTheWorld, vmSymbols::void_method_signature(), &args, CHECK_ABORT); }
JavaArgumentUnboxer(Symbol* signature, JavaCallArguments* jca, arrayOop args, bool is_static) : SignatureIterator(signature) { this->_return_type = T_ILLEGAL; _jca = jca; _index = 0; _args = args; if (!is_static) { _jca->push_oop(next_arg(T_OBJECT)); } iterate(); assert(_index == args->length(), "arg count mismatch with signature"); }
// Convenience method. Calls either the <init>() or <init>(Throwable) method when // creating a new exception Handle Exceptions::new_exception(Thread* thread, Symbol* name, Handle h_cause, Handle h_loader, Handle h_protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = NULL; if (h_cause.is_null()) { signature = vmSymbols::void_method_signature(); } else { signature = vmSymbols::throwable_void_signature(); args.push_oop(h_cause); } return new_exception(thread, name, signature, &args, h_loader, h_protection_domain); }
// Convenience method. Calls either the <init>() or <init>(String) method when // creating a new exception Handle Exceptions::new_exception(Thread* thread, symbolHandle h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; symbolHandle signature; if (message == NULL) { signature = vmSymbolHandles::void_method_signature(); } else { // We want to allocate storage, but we can't do that if there's // a pending exception, so we preserve any pending exception // around the allocation. // If we get an exception from the allocation, prefer that to // the exception we are trying to build, or the pending exception. // This is sort of like what PRESERVE_EXCEPTION_MARK does, except // for the preferencing and the early returns. Handle incoming_exception (thread, NULL); if (thread->has_pending_exception()) { incoming_exception = Handle(thread, thread->pending_exception()); thread->clear_pending_exception(); } Handle msg; if (to_utf8_safe == safe_to_utf8) { // Make a java UTF8 string. msg = java_lang_String::create_from_str(message, thread); } else { // Make a java string keeping the encoding scheme of the original string. msg = java_lang_String::create_from_platform_dependent_str(message, thread); } if (thread->has_pending_exception()) { Handle exception(thread, thread->pending_exception()); thread->clear_pending_exception(); return exception; } if (incoming_exception.not_null()) { return incoming_exception; } args.push_oop(msg); signature = vmSymbolHandles::string_void_signature(); } return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain); }
static Handle createGcInfo(GCMemoryManager *gcManager, GCStatInfo *gcStatInfo,TRAPS) { // Fill the arrays of MemoryUsage objects with before and after GC // per pool memory usage Klass* mu_klass = Management::java_lang_management_MemoryUsage_klass(CHECK_NH); instanceKlassHandle mu_kh(THREAD, mu_klass); // The array allocations below should use a handle containing mu_klass // as the first allocation could trigger a GC, causing the actual // klass oop to move, and leaving mu_klass pointing to the old // location. objArrayOop bu = oopFactory::new_objArray(mu_kh(), MemoryService::num_memory_pools(), CHECK_NH); objArrayHandle usage_before_gc_ah(THREAD, bu); objArrayOop au = oopFactory::new_objArray(mu_kh(), MemoryService::num_memory_pools(), CHECK_NH); objArrayHandle usage_after_gc_ah(THREAD, au); for (int i = 0; i < MemoryService::num_memory_pools(); i++) { Handle before_usage = MemoryService::create_MemoryUsage_obj(gcStatInfo->before_gc_usage_for_pool(i), CHECK_NH); Handle after_usage; MemoryUsage u = gcStatInfo->after_gc_usage_for_pool(i); if (u.max_size() == 0 && u.used() > 0) { // If max size == 0, this pool is a survivor space. // Set max size = -1 since the pools will be swapped after GC. MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1); after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK_NH); } else { after_usage = MemoryService::create_MemoryUsage_obj(u, CHECK_NH); } usage_before_gc_ah->obj_at_put(i, before_usage()); usage_after_gc_ah->obj_at_put(i, after_usage()); } // Current implementation only has 1 attribute (number of GC threads) // The type is 'I' objArrayOop extra_args_array = oopFactory::new_objArray(SystemDictionary::Integer_klass(), 1, CHECK_NH); objArrayHandle extra_array (THREAD, extra_args_array); Klass* itKlass = SystemDictionary::Integer_klass(); instanceKlassHandle intK(THREAD, itKlass); instanceHandle extra_arg_val = intK->allocate_instance_handle(CHECK_NH); { JavaValue res(T_VOID); JavaCallArguments argsInt; argsInt.push_oop(extra_arg_val); argsInt.push_int(gcManager->num_gc_threads()); JavaCalls::call_special(&res, intK, vmSymbols::object_initializer_name(), vmSymbols::int_void_signature(), &argsInt, CHECK_NH); } extra_array->obj_at_put(0,extra_arg_val()); Klass* gcInfoklass = Management::com_sun_management_GcInfo_klass(CHECK_NH); instanceKlassHandle ik(THREAD, gcInfoklass); Handle gcInfo_instance = ik->allocate_instance_handle(CHECK_NH); JavaValue constructor_result(T_VOID); JavaCallArguments constructor_args(16); constructor_args.push_oop(gcInfo_instance); constructor_args.push_oop(getGcInfoBuilder(gcManager,THREAD)); constructor_args.push_long(gcStatInfo->gc_index()); constructor_args.push_long(Management::ticks_to_ms(gcStatInfo->start_time())); constructor_args.push_long(Management::ticks_to_ms(gcStatInfo->end_time())); constructor_args.push_oop(usage_before_gc_ah); constructor_args.push_oop(usage_after_gc_ah); constructor_args.push_oop(extra_array); JavaCalls::call_special(&constructor_result, ik, vmSymbols::object_initializer_name(), vmSymbols::com_sun_management_GcInfo_constructor_signature(), &constructor_args, CHECK_NH); return Handle(gcInfo_instance()); }
inline void do_object(int begin, int end) { if (!is_return_type()) _jca->push_oop(next_arg(T_OBJECT)); }
inline void do_object() { _jca->push_oop(next_arg(T_OBJECT)); }
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) { JavaCallArguments args; // One oop argument args.push_oop(arg1); args.push_oop(arg2); call_static(result, klass, name, signature, &args, CHECK); }
// Returns an instanceHandle of a MemoryPool object. // It creates a MemoryPool instance when the first time // this function is called. instanceOop MemoryPool::get_memory_pool_instance(TRAPS) { // Must do an acquire so as to force ordering of subsequent // loads from anything _memory_pool_obj points to or implies. instanceOop pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj); if (pool_obj == NULL) { // It's ok for more than one thread to execute the code up to the locked region. // Extra pool instances will just be gc'ed. klassOop k = Management::sun_management_ManagementFactory_klass(CHECK_NULL); instanceKlassHandle ik(THREAD, k); Handle pool_name = java_lang_String::create_from_str(_name, CHECK_NULL); jlong usage_threshold_value = (_usage_threshold->is_high_threshold_supported() ? 0 : -1L); jlong gc_usage_threshold_value = (_gc_usage_threshold->is_high_threshold_supported() ? 0 : -1L); JavaValue result(T_OBJECT); JavaCallArguments args; args.push_oop(pool_name); // Argument 1 args.push_int((int) is_heap()); // Argument 2 symbolHandle method_name = vmSymbolHandles::createMemoryPool_name(); symbolHandle signature = vmSymbolHandles::createMemoryPool_signature(); args.push_long(usage_threshold_value); // Argument 3 args.push_long(gc_usage_threshold_value); // Argument 4 JavaCalls::call_static(&result, ik, method_name, signature, &args, CHECK_NULL); instanceOop p = (instanceOop) result.get_jobject(); instanceHandle pool(THREAD, p); { // Get lock since another thread may have create the instance MutexLocker ml(Management_lock); // Check if another thread has created the pool. We reload // _memory_pool_obj here because some other thread may have // initialized it while we were executing the code before the lock. // // The lock has done an acquire, so the load can't float above it, // but we need to do a load_acquire as above. pool_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_pool_obj); if (pool_obj != NULL) { return pool_obj; } // Get the address of the object we created via call_special. pool_obj = pool(); // Use store barrier to make sure the memory accesses associated // with creating the pool are visible before publishing its address. // The unlock will publish the store to _memory_pool_obj because // it does a release first. OrderAccess::release_store_ptr(&_memory_pool_obj, pool_obj); } } return pool_obj; }
void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JVMCIEnv* env) { JVMCI_EXCEPTION_CONTEXT bool is_osr = entry_bci != InvocationEntryBci; if (_bootstrapping && is_osr) { // no OSR compilations during bootstrap - the compiler is just too slow at this point, // and we know that there are no endless loops return; } JVMCIRuntime::initialize_well_known_classes(CHECK_ABORT); HandleMark hm; Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_ABORT); JavaValue method_result(T_OBJECT); JavaCallArguments args; args.push_long((jlong) (address) method()); JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, THREAD); JavaValue result(T_OBJECT); if (!HAS_PENDING_EXCEPTION) { JavaCallArguments args; args.push_oop(receiver); args.push_oop((oop)method_result.get_jobject()); args.push_int(entry_bci); args.push_long((jlong) (address) env); args.push_int(env->task()->compile_id()); JavaCalls::call_special(&result, receiver->klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD); } // An uncaught exception was thrown during compilation. Generally these // should be handled by the Java code in some useful way but if they leak // through to here report them instead of dying or silently ignoring them. if (HAS_PENDING_EXCEPTION) { Handle exception(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; java_lang_Throwable::java_printStackTrace(exception, THREAD); env->set_failure("exception throw", false); } else { oop result_object = (oop) result.get_jobject(); if (result_object != NULL) { oop failure_message = CompilationRequestResult::failureMessage(result_object); if (failure_message != NULL) { const char* failure_reason = java_lang_String::as_utf8_string(failure_message); env->set_failure(failure_reason, CompilationRequestResult::retry(result_object) != 0); } else { if (env->task()->code() == NULL) { env->set_failure("no nmethod produced", true); } else { env->task()->set_num_inlined_bytecodes(CompilationRequestResult::inlinedBytecodes(result_object)); Atomic::inc(&_methods_compiled); } } } else { assert(false, "JVMCICompiler.compileMethod should always return non-null"); } } }
instanceOop MemoryManager::get_memory_manager_instance(TRAPS) { // Must do an acquire so as to force ordering of subsequent // loads from anything _memory_mgr_obj points to or implies. instanceOop mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj); if (mgr_obj == NULL) { // It's ok for more than one thread to execute the code up to the locked region. // Extra manager instances will just be gc'ed. klassOop k = Management::sun_management_ManagementFactory_klass(CHECK_0); instanceKlassHandle ik(THREAD, k); Handle mgr_name = java_lang_String::create_from_str(name(), CHECK_0); JavaValue result(T_OBJECT); JavaCallArguments args; args.push_oop(mgr_name); // Argument 1 Symbol* method_name = NULL; Symbol* signature = NULL; if (is_gc_memory_manager()) { method_name = vmSymbols::createGarbageCollector_name(); signature = vmSymbols::createGarbageCollector_signature(); args.push_oop(Handle()); // Argument 2 (for future extension) } else { method_name = vmSymbols::createMemoryManager_name(); signature = vmSymbols::createMemoryManager_signature(); } JavaCalls::call_static(&result, ik, method_name, signature, &args, CHECK_0); instanceOop m = (instanceOop) result.get_jobject(); instanceHandle mgr(THREAD, m); { // Get lock before setting _memory_mgr_obj // since another thread may have created the instance MutexLocker ml(Management_lock); // Check if another thread has created the management object. We reload // _memory_mgr_obj here because some other thread may have initialized // it while we were executing the code before the lock. // // The lock has done an acquire, so the load can't float above it, but // we need to do a load_acquire as above. mgr_obj = (instanceOop)OrderAccess::load_ptr_acquire(&_memory_mgr_obj); if (mgr_obj != NULL) { return mgr_obj; } // Get the address of the object we created via call_special. mgr_obj = mgr(); // Use store barrier to make sure the memory accesses associated // with creating the management object are visible before publishing // its address. The unlock will publish the store to _memory_mgr_obj // because it does a release first. OrderAccess::release_store_ptr(&_memory_mgr_obj, mgr_obj); } } return mgr_obj; }
virtual void pushObject(void* obj) { _javaArgs->push_oop((oop) obj); }