/* * method to upcall into Java to return the value of the specified * property as a utf8 string, or NULL if does not exist. The caller * is responsible for setting a ResourceMark for proper cleanup of * the utf8 strings. */ const char* StatSampler::get_system_property(const char* name, TRAPS) { // setup the arguments to getProperty Handle key_str = java_lang_String::create_from_str(name, CHECK_NULL); // return value JavaValue result(T_OBJECT); // public static String getProperty(String key, String def); JavaCalls::call_static(&result, KlassHandle(THREAD, SystemDictionary::System_klass()), vmSymbolHandles::getProperty_name(), vmSymbolHandles::string_string_signature(), key_str, CHECK_NULL); oop value_oop = (oop)result.get_jobject(); if (value_oop == NULL) { return NULL; } // convert Java String to utf8 string char* value = java_lang_String::as_utf8_string(value_oop); return value; }
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); //signature-> // Invoke the method printf("%s[%d] [tid: %lu]: 开始调用Java中的静态方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), klass->external_name(), name->as_C_string(), signature->as_C_string()); JavaCalls::call(result, method, args, CHECK); }
void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; LinkInfo link_info(klass, name, signature, KlassHandle(), /*check_access*/false); LinkResolver::resolve_special_call(callinfo, link_info, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass()); LinkResolver::resolve_virtual_call( callinfo, receiver, recvrKlass, spec_klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
Metadata* AOTCompiledMethod::metadata_at(int index) const { if (index == 0) { // 0 is reserved return NULL; } assert(index - 1 < _metadata_size, ""); { Metadata** entry = _metadata_got + (index - 1); intptr_t meta = (intptr_t)*entry; if ((meta & 1) == 1) { // already resolved Metadata *m = (Metadata*)(meta & ~1); return m; } // The entry is string which we need to resolve. const char* meta_name = _heap->get_name_at((int)meta); int klass_len = build_u2_from((address)meta_name); const char* klass_name = meta_name + 2; // Quick check the current method's holder. Klass* k = _method->method_holder(); bool klass_matched = true; ResourceMark rm; // for signature_name() and find_method() if (strncmp(k->signature_name(), klass_name, klass_len) != 0) { // Does not match? // Search klass in got cells in DSO which have this compiled method. k = _heap->get_klass_from_got(klass_name, klass_len, _method); klass_matched = false; } int method_name_len = build_u2_from((address)klass_name + klass_len); if (method_name_len == 0) { // Array or Klass name only? meta = ((intptr_t)k) | 1; *entry = (Metadata*)meta; // Should be atomic on x64 return (Metadata*)k; } else { // Method // Quick check the current method's name. Method* m = _method; int signature_len = build_u2_from((address)klass_name + klass_len + 2 + method_name_len); int full_len = 2 + klass_len + 2 + method_name_len + 2 + signature_len; if (!klass_matched || memcmp(_name, meta_name, full_len) != 0) { // Does not match? Thread* thread = Thread::current(); KlassHandle klass = KlassHandle(thread, k); const char* method_name = klass_name + klass_len; m = AOTCodeHeap::find_method(klass, thread, method_name); } meta = ((intptr_t)m) | 1; *entry = (Metadata*)meta; // Should be atomic on x64 return (Metadata*)m; } } ShouldNotReachHere(); return NULL; }
void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) { CallInfo callinfo; Handle receiver = args->receiver(); KlassHandle recvrKlass(THREAD, receiver.is_null() ? (klassOop)NULL : receiver->klass()); LinkResolver::resolve_virtual_call( callinfo, receiver, recvrKlass, spec_klass, name, signature, KlassHandle(), false, true, CHECK); methodHandle method = callinfo.selected_method(); assert(method.not_null(), "should have thrown exception"); printf("%s[%d] [tid: %lu]: 开始调用Java中的方法[%s.%s%s]...\n", __FILE__, __LINE__, pthread_self(), spec_klass->external_name(), name->as_C_string(), signature->as_C_string()); // Invoke the method JavaCalls::call(result, method, args, CHECK); }
static BasicType as_BasicType(oop java_class, KlassHandle* reference_klass) { Klass* refk_oop = NULL; BasicType result = as_BasicType(java_class, &refk_oop); (*reference_klass) = KlassHandle(refk_oop); return result; }
KlassHandle Klass::base_create_klass(KlassHandle& klass, int size, const Klass_vtbl& vtbl, TRAPS) { klassOop ek = base_create_klass_oop(klass, size, vtbl, THREAD); return KlassHandle(THREAD, ek); }
// ------------------------------------------------------------------ // ciEnv::get_klass_by_name_impl ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* name, bool require_local) { ASSERT_IN_VM; EXCEPTION_CONTEXT; // Now we need to check the SystemDictionary Symbol* sym = name->get_symbol(); if (sym->byte_at(0) == 'L' && sym->byte_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, KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); ciSymbol* strippedname = get_symbol(strippedsym); return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local); } // Check for prior unloaded klass. The SystemDictionary's answers // can vary over time but the compiler needs consistency. ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); if (unloaded_klass != NULL) { if (require_local) return NULL; return unloaded_klass; } Handle loader(THREAD, (oop)NULL); Handle domain(THREAD, (oop)NULL); if (accessing_klass != NULL) { loader = Handle(THREAD, accessing_klass->loader()); domain = Handle(THREAD, accessing_klass->protection_domain()); } // setup up the proper type to return on OOM ciKlass* fail_type; if (sym->byte_at(0) == '[') { fail_type = _unloaded_ciobjarrayklass; } else { fail_type = _unloaded_ciinstance_klass; } KlassHandle found_klass; { ttyUnlocker ttyul; // release tty lock to avoid ordering problems MutexLocker ml(Compile_lock); Klass* kls; if (!require_local) { kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, KILL_COMPILE_ON_FATAL_(fail_type)); } else { kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, KILL_COMPILE_ON_FATAL_(fail_type)); } found_klass = KlassHandle(THREAD, kls); } // 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->byte_at(0) == '[' && (sym->byte_at(1) == '[' || sym->byte_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, KILL_COMPILE_ON_FATAL_(fail_type)); // Get element ciKlass recursively. ciKlass* elem_klass = get_klass_by_name_impl(accessing_klass, cpool, get_symbol(elem_sym), require_local); if (elem_klass != NULL && elem_klass->is_loaded()) { // Now make an array for it return ciObjArrayKlass::make_impl(elem_klass); } } 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) { found_klass = KlassHandle(THREAD, kls); break; } } } } if (found_klass() != NULL) { // Found it. Build a CI handle. return get_klass(found_klass()); } if (require_local) return NULL; // Not yet loaded into the VM, or not governed by loader constraints. // Make a CI representative for it. return get_unloaded_klass(accessing_klass, name); }