mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8232613: Move Object.registerNatives into HotSpot
Reviewed-by: dholmes, adinn, coleenp, lfoltan, mchung
This commit is contained in:
parent
68e5c40f6f
commit
574263a884
13 changed files with 312 additions and 136 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderDataGraph.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/debugInfoRec.hpp"
|
||||
|
@ -378,7 +379,83 @@ void Method::set_itable_index(int index) {
|
|||
assert(valid_itable_index(), "");
|
||||
}
|
||||
|
||||
// The RegisterNatives call being attempted tried to register with a method that
|
||||
// is not native. Ask JVM TI what prefixes have been specified. Then check
|
||||
// to see if the native method is now wrapped with the prefixes. See the
|
||||
// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
|
||||
static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) {
|
||||
#if INCLUDE_JVMTI
|
||||
ResourceMark rm(THREAD);
|
||||
Method* method;
|
||||
int name_len = name->utf8_length();
|
||||
char* name_str = name->as_utf8();
|
||||
int prefix_count;
|
||||
char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
|
||||
for (int i = 0; i < prefix_count; i++) {
|
||||
char* prefix = prefixes[i];
|
||||
int prefix_len = (int)strlen(prefix);
|
||||
|
||||
// try adding this prefix to the method name and see if it matches another method name
|
||||
int trial_len = name_len + prefix_len;
|
||||
char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
|
||||
strcpy(trial_name_str, prefix);
|
||||
strcat(trial_name_str, name_str);
|
||||
TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
|
||||
if (trial_name == NULL) {
|
||||
continue; // no such symbol, so this prefix wasn't used, try the next prefix
|
||||
}
|
||||
method = k->lookup_method(trial_name, signature);
|
||||
if (method == NULL) {
|
||||
continue; // signature doesn't match, try the next prefix
|
||||
}
|
||||
if (method->is_native()) {
|
||||
method->set_is_prefixed_native();
|
||||
return method; // wahoo, we found a prefixed version of the method, return it
|
||||
}
|
||||
// found as non-native, so prefix is good, add it, probably just need more prefixes
|
||||
name_len = trial_len;
|
||||
name_str = trial_name_str;
|
||||
}
|
||||
#endif // INCLUDE_JVMTI
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
bool Method::register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) {
|
||||
Method* method = k->lookup_method(name, signature);
|
||||
if (method == NULL) {
|
||||
ResourceMark rm(THREAD);
|
||||
stringStream st;
|
||||
st.print("Method '");
|
||||
print_external_name(&st, k, name, signature);
|
||||
st.print("' name or signature does not match");
|
||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
|
||||
}
|
||||
if (!method->is_native()) {
|
||||
// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
|
||||
method = find_prefixed_native(k, name, signature, THREAD);
|
||||
if (method == NULL) {
|
||||
ResourceMark rm(THREAD);
|
||||
stringStream st;
|
||||
st.print("Method '");
|
||||
print_external_name(&st, k, name, signature);
|
||||
st.print("' is not declared as native");
|
||||
THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry != NULL) {
|
||||
method->set_native_function(entry, native_bind_event_is_interesting);
|
||||
} else {
|
||||
method->clear_native_function();
|
||||
}
|
||||
if (PrintJNIResolving) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("[Registering JNI native method %s.%s]",
|
||||
method->method_holder()->external_name(),
|
||||
method->name()->as_C_string());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Method::was_executed_more_than(int n) {
|
||||
// Invocation counter is reset when the Method* is compiled.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue