6839872: remove implementation inheritance from JSR 292 APIs
Consolidate runtime support in java.dyn.MethodHandleNatives; include transitional compatibility logic Reviewed-by: twisti
This commit is contained in:
parent
c506cb0e5b
commit
6146dffe45
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -146,12 +146,14 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
break;
|
||||
case JVM_CONSTANT_MethodHandle :
|
||||
case JVM_CONSTANT_MethodType :
|
||||
if (!EnableMethodHandles ||
|
||||
_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
classfile_parse_error(
|
||||
(!EnableMethodHandles ?
|
||||
"This JVM does not support constant tag %u in class file %s" :
|
||||
"Class file version does not support constant tag %u in class file %s"),
|
||||
"Class file version does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
if (!EnableMethodHandles) {
|
||||
classfile_parse_error(
|
||||
"This JVM does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
if (tag == JVM_CONSTANT_MethodHandle) {
|
||||
@ -170,12 +172,14 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
|
||||
case JVM_CONSTANT_InvokeDynamicTrans : // this tag appears only in old classfiles
|
||||
case JVM_CONSTANT_InvokeDynamic :
|
||||
{
|
||||
if (!EnableInvokeDynamic ||
|
||||
_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
|
||||
classfile_parse_error(
|
||||
(!EnableInvokeDynamic ?
|
||||
"This JVM does not support constant tag %u in class file %s" :
|
||||
"Class file version does not support constant tag %u in class file %s"),
|
||||
"Class file version does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
if (!EnableInvokeDynamic) {
|
||||
classfile_parse_error(
|
||||
"This JVM does not support constant tag %u in class file %s",
|
||||
tag, CHECK);
|
||||
}
|
||||
cfs->guarantee_more(5, CHECK); // bsm_index, nt, tag/access_flags
|
||||
@ -2823,6 +2827,7 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
|
||||
}
|
||||
}
|
||||
|
||||
if (AllowTransitionalJSR292 && word_sig_index == 0) return;
|
||||
if (word_sig_index == 0)
|
||||
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
|
||||
"missing I or J signature (for vmentry) in java.dyn.MethodHandle");
|
||||
@ -2862,6 +2867,7 @@ void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
|
||||
}
|
||||
}
|
||||
|
||||
if (AllowTransitionalJSR292 && !found_vmentry) return;
|
||||
if (!found_vmentry)
|
||||
THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
|
||||
"missing vmentry byte field in java.dyn.MethodHandle");
|
||||
@ -3230,7 +3236,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
}
|
||||
|
||||
// adjust the vmentry field declaration in java.dyn.MethodHandle
|
||||
if (EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
|
||||
if (EnableMethodHandles && class_name == vmSymbols::java_dyn_MethodHandle() && class_loader.is_null()) {
|
||||
java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
if (AllowTransitionalJSR292 &&
|
||||
EnableMethodHandles && class_name == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
|
||||
// allow vmentry field in MethodHandleImpl also
|
||||
java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -66,6 +66,28 @@ static bool find_field(instanceKlass* ik,
|
||||
return ik->find_local_field(name_symbol, signature_symbol, fd);
|
||||
}
|
||||
|
||||
static bool find_hacked_field(instanceKlass* ik,
|
||||
Symbol* name_symbol, Symbol* signature_symbol,
|
||||
fieldDescriptor* fd,
|
||||
bool allow_super = false) {
|
||||
bool found = find_field(ik, name_symbol, signature_symbol, fd, allow_super);
|
||||
if (!found && AllowTransitionalJSR292) {
|
||||
Symbol* backup_sig = SystemDictionary::find_backup_signature(signature_symbol);
|
||||
if (backup_sig != NULL) {
|
||||
found = find_field(ik, name_symbol, backup_sig, fd, allow_super);
|
||||
if (TraceMethodHandles) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("MethodHandles: %s.%s: backup for %s => %s%s",
|
||||
ik->name()->as_C_string(), name_symbol->as_C_string(),
|
||||
signature_symbol->as_C_string(), backup_sig->as_C_string(),
|
||||
(found ? "" : " (NOT FOUND)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
#define find_field find_hacked_field /* remove after AllowTransitionalJSR292 */
|
||||
|
||||
// Helpful routine for computing field offsets at run time rather than hardcoding them
|
||||
static void
|
||||
compute_offset(int &dest_offset,
|
||||
@ -2200,13 +2222,15 @@ int sun_dyn_AdapterMethodHandle::_conversion_offset;
|
||||
void java_dyn_MethodHandle::compute_offsets() {
|
||||
klassOop k = SystemDictionary::MethodHandle_klass();
|
||||
if (k != NULL && EnableMethodHandles) {
|
||||
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true);
|
||||
compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), true);
|
||||
compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), true);
|
||||
bool allow_super = false;
|
||||
if (AllowTransitionalJSR292) allow_super = true; // temporary, to access sun.dyn.MethodHandleImpl
|
||||
compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), allow_super);
|
||||
compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), allow_super);
|
||||
compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), allow_super);
|
||||
|
||||
// Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots.
|
||||
// It is optional pending experiments to keep or toss.
|
||||
compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true);
|
||||
compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), allow_super);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2504,16 +2528,12 @@ oop java_dyn_MethodTypeForm::genericInvoker(oop mtform) {
|
||||
// Support for java_dyn_CallSite
|
||||
|
||||
int java_dyn_CallSite::_target_offset;
|
||||
int java_dyn_CallSite::_caller_method_offset;
|
||||
int java_dyn_CallSite::_caller_bci_offset;
|
||||
|
||||
void java_dyn_CallSite::compute_offsets() {
|
||||
if (!EnableInvokeDynamic) return;
|
||||
klassOop k = SystemDictionary::CallSite_klass();
|
||||
if (k != NULL) {
|
||||
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_dyn_MethodHandle_signature());
|
||||
compute_offset(_caller_method_offset, k, vmSymbols::vmmethod_name(), vmSymbols::sun_dyn_MemberName_signature());
|
||||
compute_offset(_caller_bci_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2525,22 +2545,6 @@ void java_dyn_CallSite::set_target(oop site, oop target) {
|
||||
site->obj_field_put(_target_offset, target);
|
||||
}
|
||||
|
||||
oop java_dyn_CallSite::caller_method(oop site) {
|
||||
return site->obj_field(_caller_method_offset);
|
||||
}
|
||||
|
||||
void java_dyn_CallSite::set_caller_method(oop site, oop ref) {
|
||||
site->obj_field_put(_caller_method_offset, ref);
|
||||
}
|
||||
|
||||
jint java_dyn_CallSite::caller_bci(oop site) {
|
||||
return site->int_field(_caller_bci_offset);
|
||||
}
|
||||
|
||||
void java_dyn_CallSite::set_caller_bci(oop site, jint bci) {
|
||||
site->int_field_put(_caller_bci_offset, bci);
|
||||
}
|
||||
|
||||
|
||||
// Support for java_security_AccessControlContext
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1887,27 +1887,99 @@ static const short wk_init_info[] = {
|
||||
0
|
||||
};
|
||||
|
||||
Symbol* SystemDictionary::find_backup_symbol(Symbol* symbol,
|
||||
const char* from_prefix,
|
||||
const char* to_prefix) {
|
||||
assert(AllowTransitionalJSR292, ""); // delete this subroutine
|
||||
Symbol* backup_symbol = NULL;
|
||||
size_t from_len = strlen(from_prefix);
|
||||
if (strncmp((const char*) symbol->base(), from_prefix, from_len) != 0)
|
||||
return NULL;
|
||||
char buf[100];
|
||||
size_t to_len = strlen(to_prefix);
|
||||
size_t tail_len = symbol->utf8_length() - from_len;
|
||||
size_t new_len = to_len + tail_len;
|
||||
guarantee(new_len < sizeof(buf), "buf too small");
|
||||
memcpy(buf, to_prefix, to_len);
|
||||
memcpy(buf + to_len, symbol->base() + from_len, tail_len);
|
||||
buf[new_len] = '\0';
|
||||
vmSymbols::SID backup_sid = vmSymbols::find_sid(buf);
|
||||
if (backup_sid != vmSymbols::NO_SID) {
|
||||
backup_symbol = vmSymbols::symbol_at(backup_sid);
|
||||
}
|
||||
return backup_symbol;
|
||||
}
|
||||
|
||||
Symbol* SystemDictionary::find_backup_class_name(Symbol* symbol) {
|
||||
assert(AllowTransitionalJSR292, ""); // delete this subroutine
|
||||
if (symbol == NULL) return NULL;
|
||||
Symbol* backup_symbol = find_backup_symbol(symbol, "java/lang/invoke/", "java/dyn/"); // AllowTransitionalJSR292 ONLY
|
||||
if (backup_symbol == NULL)
|
||||
backup_symbol = find_backup_symbol(symbol, "java/dyn/", "sun/dyn/"); // AllowTransitionalJSR292 ONLY
|
||||
return backup_symbol;
|
||||
}
|
||||
|
||||
Symbol* SystemDictionary::find_backup_signature(Symbol* symbol) {
|
||||
assert(AllowTransitionalJSR292, ""); // delete this subroutine
|
||||
if (symbol == NULL) return NULL;
|
||||
return find_backup_symbol(symbol, "Ljava/lang/invoke/", "Ljava/dyn/");
|
||||
}
|
||||
|
||||
bool SystemDictionary::initialize_wk_klass(WKID id, int init_opt, TRAPS) {
|
||||
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
|
||||
int info = wk_init_info[id - FIRST_WKID];
|
||||
int sid = (info >> CEIL_LG_OPTION_LIMIT);
|
||||
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
|
||||
klassOop* klassp = &_well_known_klasses[id];
|
||||
bool must_load = (init_opt < SystemDictionary::Opt);
|
||||
bool try_load = true;
|
||||
bool pre_load = (init_opt < SystemDictionary::Opt);
|
||||
bool try_load = true;
|
||||
if (init_opt == SystemDictionary::Opt_Kernel) {
|
||||
#ifndef KERNEL
|
||||
try_load = false;
|
||||
#endif //KERNEL
|
||||
}
|
||||
if ((*klassp) == NULL && try_load) {
|
||||
Symbol* backup_symbol = NULL; // symbol to try if the current symbol fails
|
||||
if (init_opt == SystemDictionary::Pre_JSR292) {
|
||||
if (!EnableMethodHandles) try_load = false; // do not bother to load such classes
|
||||
if (AllowTransitionalJSR292) {
|
||||
backup_symbol = find_backup_class_name(symbol);
|
||||
if (try_load && PreferTransitionalJSR292) {
|
||||
while (backup_symbol != NULL) {
|
||||
(*klassp) = resolve_or_null(backup_symbol, CHECK_0); // try backup early
|
||||
if (TraceMethodHandles) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("MethodHandles: try backup first for %s => %s (%s)",
|
||||
symbol->as_C_string(), backup_symbol->as_C_string(),
|
||||
((*klassp) == NULL) ? "no such class" : "backup load succeeded");
|
||||
}
|
||||
if ((*klassp) != NULL) return true;
|
||||
backup_symbol = find_backup_class_name(backup_symbol); // find next backup
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((*klassp) != NULL) return true;
|
||||
if (!try_load) return false;
|
||||
while (symbol != NULL) {
|
||||
bool must_load = (pre_load && (backup_symbol == NULL));
|
||||
if (must_load) {
|
||||
(*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
|
||||
} else {
|
||||
(*klassp) = resolve_or_null(symbol, CHECK_0); // load optional klass
|
||||
}
|
||||
if ((*klassp) != NULL) return true;
|
||||
// Go around again. Example of long backup sequence:
|
||||
// java.lang.invoke.MemberName, java.dyn.MemberName, sun.dyn.MemberName, ONLY if AllowTransitionalJSR292
|
||||
if (TraceMethodHandles && (backup_symbol != NULL)) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("MethodHandles: backup for %s => %s",
|
||||
symbol->as_C_string(), backup_symbol->as_C_string());
|
||||
}
|
||||
symbol = backup_symbol;
|
||||
if (AllowTransitionalJSR292)
|
||||
backup_symbol = find_backup_class_name(symbol);
|
||||
}
|
||||
return ((*klassp) != NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
void SystemDictionary::initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS) {
|
||||
@ -2348,6 +2420,8 @@ methodOop SystemDictionary::find_method_handle_invoke(Symbol* name,
|
||||
if (THREAD->is_Compiler_thread())
|
||||
return NULL; // do not attempt from within compiler
|
||||
bool for_invokeGeneric = (name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name));
|
||||
if (AllowInvokeForInvokeGeneric && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
|
||||
for_invokeGeneric = true;
|
||||
bool found_on_bcp = false;
|
||||
Handle mt = find_method_handle_type(signature, accessing_klass,
|
||||
for_invokeGeneric,
|
||||
@ -2531,10 +2605,14 @@ Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
|
||||
args.push_oop(caller_mname());
|
||||
args.push_int(caller_bci);
|
||||
JavaValue result(T_OBJECT);
|
||||
Symbol* makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_signature();
|
||||
if (AllowTransitionalJSR292 && SystemDictionaryHandles::MethodHandleNatives_klass()->name() == vmSymbols::sun_dyn_MethodHandleNatives()) {
|
||||
makeDynamicCallSite_signature = vmSymbols::makeDynamicCallSite_TRANS_signature();
|
||||
}
|
||||
JavaCalls::call_static(&result,
|
||||
SystemDictionary::MethodHandleNatives_klass(),
|
||||
vmSymbols::makeDynamicCallSite_name(),
|
||||
vmSymbols::makeDynamicCallSite_signature(),
|
||||
makeDynamicCallSite_signature,
|
||||
&args, CHECK_(empty));
|
||||
oop call_site_oop = (oop) result.get_jobject();
|
||||
assert(call_site_oop->is_oop()
|
||||
|
@ -144,18 +144,18 @@ class SymbolPropertyTable;
|
||||
template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
|
||||
\
|
||||
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
|
||||
template(MethodHandle_klass, java_dyn_MethodHandle, Opt) \
|
||||
template(MemberName_klass, sun_dyn_MemberName, Opt) \
|
||||
template(MethodHandleImpl_klass, sun_dyn_MethodHandleImpl, Opt) \
|
||||
template(MethodHandleNatives_klass, sun_dyn_MethodHandleNatives, Opt) \
|
||||
template(AdapterMethodHandle_klass, sun_dyn_AdapterMethodHandle, Opt) \
|
||||
template(BoundMethodHandle_klass, sun_dyn_BoundMethodHandle, Opt) \
|
||||
template(DirectMethodHandle_klass, sun_dyn_DirectMethodHandle, Opt) \
|
||||
template(MethodType_klass, java_dyn_MethodType, Opt) \
|
||||
template(MethodTypeForm_klass, java_dyn_MethodTypeForm, Opt) \
|
||||
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Opt) \
|
||||
template(Linkage_klass, java_dyn_Linkage, Opt) \
|
||||
template(CallSite_klass, java_dyn_CallSite, Opt) \
|
||||
template(MethodHandle_klass, java_dyn_MethodHandle, Pre_JSR292) \
|
||||
template(MemberName_klass, java_dyn_MemberName, Pre_JSR292) \
|
||||
template(MethodHandleImpl_klass, java_dyn_MethodHandleImpl, Pre_JSR292) /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(MethodHandleNatives_klass, java_dyn_MethodHandleNatives, Pre_JSR292) \
|
||||
template(AdapterMethodHandle_klass, java_dyn_AdapterMethodHandle, Pre_JSR292) \
|
||||
template(BoundMethodHandle_klass, java_dyn_BoundMethodHandle, Pre_JSR292) \
|
||||
template(DirectMethodHandle_klass, java_dyn_DirectMethodHandle, Pre_JSR292) \
|
||||
template(MethodType_klass, java_dyn_MethodType, Pre_JSR292) \
|
||||
template(MethodTypeForm_klass, java_dyn_MethodTypeForm, Pre_JSR292) \
|
||||
template(WrongMethodTypeException_klass, java_dyn_WrongMethodTypeException, Pre_JSR292) \
|
||||
template(Linkage_klass, java_dyn_Linkage, Pre_JSR292) \
|
||||
template(CallSite_klass, java_dyn_CallSite, Pre_JSR292) \
|
||||
/* Note: MethodHandle must be first, and CallSite last in group */ \
|
||||
\
|
||||
template(StringBuffer_klass, java_lang_StringBuffer, Pre) \
|
||||
@ -207,6 +207,7 @@ class SystemDictionary : AllStatic {
|
||||
|
||||
enum InitOption {
|
||||
Pre, // preloaded; error if not present
|
||||
Pre_JSR292, // preloaded if EnableMethodHandles
|
||||
|
||||
// Order is significant. Options before this point require resolve_or_fail.
|
||||
// Options after this point will use resolve_or_null instead.
|
||||
@ -401,6 +402,7 @@ public:
|
||||
}
|
||||
|
||||
static klassOop check_klass_Pre(klassOop k) { return check_klass(k); }
|
||||
static klassOop check_klass_Pre_JSR292(klassOop k) { return EnableInvokeDynamic ? check_klass(k) : k; }
|
||||
static klassOop check_klass_Opt(klassOop k) { return k; }
|
||||
static klassOop check_klass_Opt_Kernel(klassOop k) { return k; } //== Opt
|
||||
static klassOop check_klass_Opt_Only_JDK15(klassOop k) {
|
||||
@ -420,6 +422,8 @@ public:
|
||||
initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
|
||||
}
|
||||
|
||||
static Symbol* find_backup_symbol(Symbol* symbol, const char* from_prefix, const char* to_prefix);
|
||||
|
||||
public:
|
||||
#define WK_KLASS_DECLARE(name, ignore_symbol, option) \
|
||||
static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
|
||||
@ -441,6 +445,9 @@ public:
|
||||
|
||||
static void load_abstract_ownable_synchronizer_klass(TRAPS);
|
||||
|
||||
static Symbol* find_backup_class_name(Symbol* class_name_symbol);
|
||||
static Symbol* find_backup_signature(Symbol* signature_symbol);
|
||||
|
||||
private:
|
||||
// Tells whether ClassLoader.loadClassInternal is present
|
||||
static bool has_loadClassInternal() { return _has_loadClassInternal; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -277,6 +277,12 @@ vmSymbols::SID vmSymbols::find_sid(Symbol* symbol) {
|
||||
return sid;
|
||||
}
|
||||
|
||||
vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
|
||||
Symbol* symbol = SymbolTable::probe(symbol_name, (int) strlen(symbol_name));
|
||||
if (symbol == NULL) return NO_SID;
|
||||
return find_sid(symbol);
|
||||
}
|
||||
|
||||
static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
|
||||
#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
|
||||
switch (TYPE2(type, unboxing)) {
|
||||
|
@ -240,13 +240,18 @@
|
||||
/* internal classes known only to the JVM: */ \
|
||||
template(java_dyn_MethodTypeForm, "java/dyn/MethodTypeForm") \
|
||||
template(java_dyn_MethodTypeForm_signature, "Ljava/dyn/MethodTypeForm;") \
|
||||
template(sun_dyn_MemberName, "sun/dyn/MemberName") \
|
||||
template(sun_dyn_MemberName_signature, "Lsun/dyn/MemberName;") \
|
||||
template(sun_dyn_MethodHandleImpl, "sun/dyn/MethodHandleImpl") \
|
||||
template(sun_dyn_MethodHandleNatives, "sun/dyn/MethodHandleNatives") \
|
||||
template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") \
|
||||
template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") \
|
||||
template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") \
|
||||
template(java_dyn_MemberName, "java/dyn/MemberName") \
|
||||
template(java_dyn_MethodHandleImpl, "java/dyn/MethodHandleImpl") \
|
||||
template(java_dyn_MethodHandleNatives, "java/dyn/MethodHandleNatives") \
|
||||
template(java_dyn_AdapterMethodHandle, "java/dyn/AdapterMethodHandle") \
|
||||
template(java_dyn_BoundMethodHandle, "java/dyn/BoundMethodHandle") \
|
||||
template(java_dyn_DirectMethodHandle, "java/dyn/DirectMethodHandle") \
|
||||
template(sun_dyn_MemberName, "sun/dyn/MemberName") /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(sun_dyn_MethodHandleImpl, "sun/dyn/MethodHandleImpl") /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(sun_dyn_MethodHandleNatives, "sun/dyn/MethodHandleNatives") /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(sun_dyn_AdapterMethodHandle, "sun/dyn/AdapterMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(sun_dyn_BoundMethodHandle, "sun/dyn/BoundMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
|
||||
template(sun_dyn_DirectMethodHandle, "sun/dyn/DirectMethodHandle") /* AllowTransitionalJSR292 ONLY */ \
|
||||
/* internal up-calls made only by the JVM, via class sun.dyn.MethodHandleNatives: */ \
|
||||
template(findMethodHandleType_name, "findMethodHandleType") \
|
||||
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") \
|
||||
@ -255,7 +260,8 @@
|
||||
template(linkMethodHandleConstant_name, "linkMethodHandleConstant") \
|
||||
template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") \
|
||||
template(makeDynamicCallSite_name, "makeDynamicCallSite") \
|
||||
template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \
|
||||
template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Ljava/dyn/MemberName;I)Ljava/dyn/CallSite;") \
|
||||
template(makeDynamicCallSite_TRANS_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") /* AllowTransitionalJSR292 ONLY */ \
|
||||
NOT_LP64( do_alias(machine_word_signature, int_signature) ) \
|
||||
LP64_ONLY( do_alias(machine_word_signature, long_signature) ) \
|
||||
\
|
||||
@ -882,7 +888,8 @@
|
||||
\
|
||||
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
|
||||
/* (symbols invoke_name and invoke_signature defined above) */ \
|
||||
do_intrinsic(_checkSpreadArgument, sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
|
||||
do_intrinsic(_checkSpreadArgument, java_dyn_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
|
||||
do_intrinsic(_checkSpreadArgument_TRANS, sun_dyn_MethodHandleImpl, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) /* AllowTransitionalJSR292 ONLY */ \
|
||||
do_name( checkSpreadArgument_name, "checkSpreadArgument") \
|
||||
do_name( checkSpreadArgument_signature, "(Ljava/lang/Object;I)V") \
|
||||
do_intrinsic(_invokeExact, java_dyn_MethodHandle, invokeExact_name, object_array_object_signature, F_RN) \
|
||||
@ -995,6 +1002,7 @@ class vmSymbols: AllStatic {
|
||||
|
||||
// Returns symbol's SID if one is assigned, else NO_SID.
|
||||
static SID find_sid(Symbol* symbol);
|
||||
static SID find_sid(const char* symbol_name);
|
||||
|
||||
#ifndef PRODUCT
|
||||
// No need for this in the product:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -221,7 +221,9 @@ void LinkResolver::lookup_implicit_method(methodHandle& result,
|
||||
// Make sure the Java part of the runtime has been booted up.
|
||||
klassOop natives = SystemDictionary::MethodHandleNatives_klass();
|
||||
if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
|
||||
SystemDictionary::resolve_or_fail(vmSymbols::sun_dyn_MethodHandleNatives(),
|
||||
Symbol* natives_name = vmSymbols::java_dyn_MethodHandleNatives();
|
||||
if (natives != NULL && AllowTransitionalJSR292) natives_name = Klass::cast(natives)->name();
|
||||
SystemDictionary::resolve_or_fail(natives_name,
|
||||
Handle(),
|
||||
Handle(),
|
||||
true,
|
||||
|
@ -194,7 +194,7 @@ class instanceKlass: public Klass {
|
||||
// Implementors of this interface (not valid if it overflows)
|
||||
klassOop _implementors[implementors_limit];
|
||||
// invokedynamic bootstrap method (a java.dyn.MethodHandle)
|
||||
oop _bootstrap_method;
|
||||
oop _bootstrap_method; // AllowTransitionalJSR292 ONLY
|
||||
// Annotations for this class, or null if none.
|
||||
typeArrayOop _class_annotations;
|
||||
// Annotation objects (byte arrays) for fields, or null if no annotations.
|
||||
@ -529,7 +529,7 @@ class instanceKlass: public Klass {
|
||||
_enclosing_method_method_index = method_index; }
|
||||
|
||||
// JSR 292 support
|
||||
oop bootstrap_method() const { return _bootstrap_method; }
|
||||
oop bootstrap_method() const { return _bootstrap_method; } // AllowTransitionalJSR292 ONLY
|
||||
void set_bootstrap_method(oop mh) { oop_store(&_bootstrap_method, mh); }
|
||||
|
||||
// jmethodID support
|
||||
@ -817,7 +817,7 @@ private:
|
||||
oop* adr_signers() const { return (oop*)&this->_signers;}
|
||||
oop* adr_inner_classes() const { return (oop*)&this->_inner_classes;}
|
||||
oop* adr_implementors() const { return (oop*)&this->_implementors[0];}
|
||||
oop* adr_bootstrap_method() const { return (oop*)&this->_bootstrap_method;}
|
||||
oop* adr_bootstrap_method() const { return (oop*)&this->_bootstrap_method;} // AllowTransitionalJSR292 ONLY
|
||||
oop* adr_methods_jmethod_ids() const { return (oop*)&this->_methods_jmethod_ids;}
|
||||
oop* adr_methods_cached_itable_indices() const { return (oop*)&this->_methods_cached_itable_indices;}
|
||||
oop* adr_class_annotations() const { return (oop*)&this->_class_annotations;}
|
||||
|
@ -855,7 +855,7 @@ bool methodOopDesc::is_method_handle_invoke_name(vmSymbols::SID name_sid) {
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
|
||||
return true;
|
||||
}
|
||||
if (AllowTransitionalJSR292
|
||||
if ((AllowTransitionalJSR292 || AllowInvokeForInvokeGeneric)
|
||||
&& name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name))
|
||||
return true;
|
||||
return false;
|
||||
@ -1127,7 +1127,8 @@ void methodOopDesc::init_intrinsic_id() {
|
||||
id = vmIntrinsics::_invokeExact;
|
||||
break;
|
||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
|
||||
if (AllowTransitionalJSR292) id = vmIntrinsics::_invokeExact;
|
||||
if (AllowInvokeForInvokeGeneric) id = vmIntrinsics::_invokeGeneric;
|
||||
else if (AllowTransitionalJSR292) id = vmIntrinsics::_invokeExact;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -100,7 +100,6 @@ void MethodHandleChain::set_last_method(oop target, TRAPS) {
|
||||
BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) {
|
||||
// There is no direct indication of whether the argument is primitive or not.
|
||||
// It is implied by the _vmentry code, and by the MethodType of the target.
|
||||
// FIXME: Make it explicit MethodHandleImpl refactors out from MethodHandle
|
||||
BasicType arg_type = T_VOID;
|
||||
if (target != NULL) {
|
||||
oop mtype = java_dyn_MethodHandle::type(target);
|
||||
@ -960,6 +959,13 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
|
||||
if (m == NULL) {
|
||||
// Get the intrinsic methodOop.
|
||||
m = vmIntrinsics::method_for(iid);
|
||||
if (m == NULL && iid == vmIntrinsics::_checkSpreadArgument && AllowTransitionalJSR292) {
|
||||
m = vmIntrinsics::method_for(vmIntrinsics::_checkSpreadArgument_TRANS);
|
||||
}
|
||||
if (m == NULL) {
|
||||
ArgToken zero;
|
||||
lose(vmIntrinsics::name_at(iid), CHECK_(zero));
|
||||
}
|
||||
}
|
||||
|
||||
klassOop klass = m->method_holder();
|
||||
|
@ -2523,17 +2523,16 @@ JVM_ENTRY(void, MHI_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
|
||||
if (!AllowTransitionalJSR292)
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
|
||||
instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
|
||||
return JNIHandles::make_local(THREAD, ik->bootstrap_method());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
|
||||
// No special action required, yet.
|
||||
oop site_oop = JNIHandles::resolve(site_jh);
|
||||
if (!java_dyn_CallSite::is_instance(site_oop))
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
|
||||
java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
|
||||
if (!AllowTransitionalJSR292)
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2543,8 +2542,10 @@ JVM_END
|
||||
#define ADR "J"
|
||||
|
||||
#define LANG "Ljava/lang/"
|
||||
#define JDYN "Ljava/dyn/"
|
||||
#define IDYN "Lsun/dyn/"
|
||||
#define JLINV "Ljava/lang/invoke/" /* standard package */
|
||||
#define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
|
||||
#define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */
|
||||
// FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
|
||||
|
||||
#define OBJ LANG"Object;"
|
||||
#define CLS LANG"Class;"
|
||||
@ -2552,7 +2553,6 @@ JVM_END
|
||||
#define CST JDYN"CallSite;"
|
||||
#define MT JDYN"MethodType;"
|
||||
#define MH JDYN"MethodHandle;"
|
||||
#define MHI IDYN"MethodHandleImpl;"
|
||||
#define MEM IDYN"MemberName;"
|
||||
#define AMH IDYN"AdapterMethodHandle;"
|
||||
#define BMH IDYN"BoundMethodHandle;"
|
||||
@ -2581,12 +2581,38 @@ static JNINativeMethod methods[] = {
|
||||
};
|
||||
|
||||
// More entry points specifically for EnableInvokeDynamic.
|
||||
// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
|
||||
static JNINativeMethod methods2[] = {
|
||||
{CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)},
|
||||
{CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)},
|
||||
{CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)}
|
||||
};
|
||||
|
||||
static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
|
||||
for (int i = 0; i < num_methods; i++) {
|
||||
const char* sig = methods[i].signature;
|
||||
if (!strstr(sig, from_sig)) continue;
|
||||
size_t buflen = strlen(sig) + 100;
|
||||
char* buf = NEW_C_HEAP_ARRAY(char, buflen);
|
||||
char* bufp = buf;
|
||||
const char* sigp = sig;
|
||||
size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
|
||||
while (*sigp != '\0') {
|
||||
assert(bufp < buf + buflen - to_len - 1, "oob");
|
||||
if (strncmp(sigp, from_sig, from_len) != 0) {
|
||||
*bufp++ = *sigp++;
|
||||
} else {
|
||||
strcpy(bufp, to_sig);
|
||||
bufp += to_len;
|
||||
sigp += from_len;
|
||||
}
|
||||
}
|
||||
*bufp = '\0';
|
||||
methods[i].signature = buf; // replace with new signature
|
||||
if (TraceMethodHandles)
|
||||
tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
|
||||
}
|
||||
}
|
||||
|
||||
// This one function is exported, used by NativeLookup.
|
||||
|
||||
@ -2600,45 +2626,76 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
return; // bind nothing
|
||||
}
|
||||
|
||||
if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
|
||||
SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
|
||||
warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
|
||||
THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
|
||||
}
|
||||
|
||||
bool enable_MH = true;
|
||||
|
||||
{
|
||||
// Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
|
||||
bool registered_natives = false;
|
||||
bool try_plain = true, try_JDYN = true, try_IDYN = true;
|
||||
for (;;) {
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
||||
if (try_plain) { try_plain = false; }
|
||||
else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
|
||||
else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
|
||||
else { break; }
|
||||
int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
|
||||
if (env->ExceptionOccurred()) {
|
||||
MethodHandles::set_enabled(false);
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
enable_MH = false;
|
||||
env->ExceptionClear();
|
||||
// and try again...
|
||||
} else {
|
||||
registered_natives = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!registered_natives) {
|
||||
MethodHandles::set_enabled(false);
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
enable_MH = false;
|
||||
}
|
||||
|
||||
if (enable_MH) {
|
||||
bool found_raise_exception = false;
|
||||
KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
|
||||
KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
|
||||
if (MHI_klass.not_null()) {
|
||||
// Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
|
||||
bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
|
||||
for (;;) {
|
||||
KlassHandle try_klass;
|
||||
if (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
|
||||
else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
|
||||
else { break; }
|
||||
if (try_klass.is_null()) continue;
|
||||
TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
|
||||
TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
|
||||
methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop())
|
||||
methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop())
|
||||
->find_method(raiseException_name, raiseException_sig);
|
||||
if (raiseException_method != NULL && raiseException_method->is_static()) {
|
||||
MethodHandles::set_raise_exception_method(raiseException_method);
|
||||
} else {
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
enable_MH = false;
|
||||
found_raise_exception = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (!found_raise_exception) {
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
enable_MH = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable_MH) {
|
||||
// We need to link the MethodHandleImpl klass before we generate
|
||||
// the method handle adapters as the _raise_exception adapter uses
|
||||
// one of its methods (and its c2i-adapter).
|
||||
KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass();
|
||||
instanceKlass* ik = instanceKlass::cast(k());
|
||||
ik->link_class(CHECK);
|
||||
if (AllowTransitionalJSR292) {
|
||||
// We need to link the MethodHandleImpl klass before we generate
|
||||
// the method handle adapters as the _raise_exception adapter uses
|
||||
// one of its methods (and its c2i-adapter).
|
||||
KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass();
|
||||
instanceKlass* ik = instanceKlass::cast(k());
|
||||
ik->link_class(CHECK);
|
||||
}
|
||||
|
||||
MethodHandles::generate_adapters();
|
||||
MethodHandles::set_enabled(true);
|
||||
@ -2649,7 +2706,7 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
return; // bind nothing
|
||||
}
|
||||
|
||||
{
|
||||
if (AllowTransitionalJSR292) {
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
||||
int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
|
||||
@ -2657,8 +2714,6 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
MethodHandles::set_enabled(false);
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
env->ExceptionClear();
|
||||
} else {
|
||||
MethodHandles::set_enabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -107,29 +107,29 @@ extern "C" {
|
||||
void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
|
||||
}
|
||||
|
||||
static address lookup_special_native(char* jni_name) {
|
||||
// NB: To ignore the jni prefix and jni postfix strstr is used matching.
|
||||
if (!JDK_Version::is_gte_jdk14x_version()) {
|
||||
// These functions only exist for compatibility with 1.3.1 and earlier
|
||||
// Intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
|
||||
if (strstr(jni_name, "Java_java_io_ObjectOutputStream_getPrimitiveFieldValues") != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, JVM_GetPrimitiveFieldValues);
|
||||
}
|
||||
// Intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
|
||||
if (strstr(jni_name, "Java_java_io_ObjectInputStream_setPrimitiveFieldValues") != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, JVM_SetPrimitiveFieldValues);
|
||||
}
|
||||
}
|
||||
if (strstr(jni_name, "Java_sun_misc_Unsafe_registerNatives") != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, JVM_RegisterUnsafeMethods);
|
||||
}
|
||||
if (strstr(jni_name, "Java_sun_dyn_MethodHandleNatives_registerNatives") != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, JVM_RegisterMethodHandleMethods);
|
||||
}
|
||||
if (strstr(jni_name, "Java_sun_misc_Perf_registerNatives") != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, JVM_RegisterPerfMethods);
|
||||
}
|
||||
#define CC (char*) /* cast a literal from (const char*) */
|
||||
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
|
||||
|
||||
static JNINativeMethod lookup_special_native_methods[] = {
|
||||
// Next two functions only exist for compatibility with 1.3.1 and earlier.
|
||||
{ CC"Java_java_io_ObjectOutputStream_getPrimitiveFieldValues", NULL, FN_PTR(JVM_GetPrimitiveFieldValues) }, // intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
|
||||
{ CC"Java_java_io_ObjectInputStream_setPrimitiveFieldValues", NULL, FN_PTR(JVM_SetPrimitiveFieldValues) }, // intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
|
||||
|
||||
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
|
||||
{ CC"Java_sun_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
|
||||
{ CC"Java_java_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
|
||||
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }
|
||||
};
|
||||
|
||||
static address lookup_special_native(char* jni_name) {
|
||||
int i = !JDK_Version::is_gte_jdk14x_version() ? 0 : 2; // see comment in lookup_special_native_methods
|
||||
int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
|
||||
for (; i < count; i++) {
|
||||
// NB: To ignore the jni prefix and jni postfix strstr is used matching.
|
||||
if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
|
||||
return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3719,6 +3719,13 @@ class CommandLineFlags {
|
||||
experimental(bool, AllowTransitionalJSR292, true, \
|
||||
"recognize pre-PFD formats of invokedynamic") \
|
||||
\
|
||||
experimental(bool, PreferTransitionalJSR292, false, \
|
||||
"prefer pre-PFD APIs on boot class path, if they exist") \
|
||||
\
|
||||
experimental(bool, AllowInvokeForInvokeGeneric, false, \
|
||||
"accept MethodHandle.invoke and MethodHandle.invokeGeneric " \
|
||||
"as equivalent methods") \
|
||||
\
|
||||
develop(bool, TraceInvokeDynamic, false, \
|
||||
"trace internal invoke dynamic operations") \
|
||||
\
|
||||
|
Loading…
Reference in New Issue
Block a user