// Check if there are any JVM TI prefixes which have been applied to the native method name. // If any are found, remove them before attemping the look up of the // native implementation again. // See SetNativeMethodPrefix in the JVM TI Spec for more details. address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) { ResourceMark rm(THREAD); int prefix_count; char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count); char* in_name = method->name()->as_C_string(); char* wrapper_name = in_name; // last applied prefix will be first -- go backwards for (int i = prefix_count-1; i >= 0; i--) { char* prefix = prefixes[i]; size_t prefix_len = strlen(prefix); if (strncmp(prefix, wrapper_name, prefix_len) == 0) { // has this prefix remove it wrapper_name += prefix_len; } } if (wrapper_name != in_name) { // we have a name for a wrapping method int wrapper_name_len = (int)strlen(wrapper_name); TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len); if (wrapper_symbol != NULL) { KlassHandle kh(method->method_holder()); methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol, method->signature()); if (wrapper_method != NULL && !wrapper_method->is_native()) { // we found a wrapper method, use its native entry method->set_is_prefixed_native(); return lookup_entry(wrapper_method, in_base_library, THREAD); } } } return NULL; }
NativeSignatureIterator(methodHandle method) : SignatureIterator(method->signature()) { _method = method; _offset = 0; _jni_offset = 0; const int JNIEnv_words = 1; const int mirror_words = 1; _prepended = !is_static() ? JNIEnv_words : JNIEnv_words + mirror_words; }
VerificationType StackMapFrame::set_locals_from_arg( const methodHandle m, VerificationType thisKlass, TRAPS) { SignatureStream ss(m->signature()); int init_local_num = 0; if (!m->is_static()) { init_local_num++; // add one extra argument for instance method if (m->name() == vmSymbols::object_initializer_name() && thisKlass.name() != vmSymbols::java_lang_Object()) { _locals[0] = VerificationType::uninitialized_this_type(); _flags |= FLAG_THIS_UNINIT; } else { _locals[0] = thisKlass; } } // local num may be greater than size of parameters because long/double occupies two slots while(!ss.at_return_type()) { init_local_num += _verifier->change_sig_to_verificationType( &ss, &_locals[init_local_num], CHECK_VERIFY_(verifier(), VerificationType::bogus_type())); ss.next(); } _locals_size = init_local_num; switch (ss.type()) { case T_OBJECT: case T_ARRAY: { Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type())); // Create another symbol to save as signature stream unreferences // this symbol. Symbol* sig_copy = verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(), CHECK_(VerificationType::bogus_type())); assert(sig_copy == sig, "symbols don't match"); return VerificationType::reference_type(sig_copy); } case T_INT: return VerificationType::integer_type(); case T_BYTE: return VerificationType::byte_type(); case T_CHAR: return VerificationType::char_type(); case T_SHORT: return VerificationType::short_type(); case T_BOOLEAN: return VerificationType::boolean_type(); case T_FLOAT: return VerificationType::float_type(); case T_DOUBLE: return VerificationType::double_type(); case T_LONG: return VerificationType::long_type(); case T_VOID: return VerificationType::bogus_type(); default: ShouldNotReachHere(); } return VerificationType::bogus_type(); }
void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) { assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor"); assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor"); InstanceKlass* ik = method->method_holder(); if (ik->is_initialized() && ik->has_vanilla_constructor()) { // safe to skip constructor call } else { static JavaValue result(T_VOID); JavaCallArguments args(receiver); call(&result, method, &args, CHECK); } }
// Check all the formats of native implementation name to see if there is one // for the specified method. address NativeLookup::lookup_critical_entry(methodHandle method) { if (!CriticalJNINatives) return NULL; if (method->is_synchronized() || !method->is_static()) { // Only static non-synchronized methods are allowed return NULL; } ResourceMark rm; address entry = NULL; Symbol* signature = method->signature(); for (int end = 0; end < signature->utf8_length(); end++) { if (signature->byte_at(end) == 'L') { // Don't allow object types return NULL; } } // Compute critical name char* critical_name = critical_jni_name(method); // Compute argument size int args_size = 1 // JNIEnv + (method->is_static() ? 1 : 0) // class for static methods + method->size_of_parameters(); // actual parameters // 1) Try JNI short style entry = lookup_critical_style(method, critical_name, "", args_size, true); if (entry != NULL) return entry; // Compute long name char* long_name = long_jni_name(method); // 2) Try JNI long style entry = lookup_critical_style(method, critical_name, long_name, args_size, true); if (entry != NULL) return entry; // 3) Try JNI short style without os prefix/suffix entry = lookup_critical_style(method, critical_name, "", args_size, false); if (entry != NULL) return entry; // 4) Try JNI long style without os prefix/suffix entry = lookup_critical_style(method, critical_name, long_name, args_size, false); return entry; // NULL indicates not found }
Fingerprinter(methodHandle method) : SignatureIterator(method->signature()) { mh = method; _fingerprint = 0; }
Fingerprinter(Thread *thread, methodHandle method) : SignatureIterator(thread, method->signature()) { mh = method; _fingerprint = 0; }