提交 b324b7b3 编写于 作者: J jrose

6862576: vmIntrinsics needs cleanup in order to support JSR 292 intrinsics

Summary: remove useless lazy evaluation of intrinsics; add LAST_COMPILER_INLINE to help categorize them
Reviewed-by: kvn
上级 fd5f88b7
...@@ -3231,6 +3231,16 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, ...@@ -3231,6 +3231,16 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
this_klass->set_minor_version(minor_version); this_klass->set_minor_version(minor_version);
this_klass->set_major_version(major_version); this_klass->set_major_version(major_version);
// Set up methodOop::intrinsic_id as soon as we know the names of methods.
// (We used to do this lazily, but now we query it in Rewriter,
// which is eagerly done for every method, so we might as well do it now,
// when everything is fresh in memory.)
if (methodOopDesc::klass_id_for_intrinsics(this_klass->as_klassOop()) != vmSymbols::NO_SID) {
for (int j = 0; j < methods->length(); j++) {
((methodOop)methods->obj_at(j))->init_intrinsic_id();
}
}
if (cached_class_file_bytes != NULL) { if (cached_class_file_bytes != NULL) {
// JVMTI: we have an instanceKlass now, tell it about the cached bytes // JVMTI: we have an instanceKlass now, tell it about the cached bytes
this_klass->set_cached_class_file(cached_class_file_bytes, this_klass->set_cached_class_file(cached_class_file_bytes,
......
...@@ -513,9 +513,6 @@ ...@@ -513,9 +513,6 @@
// //
// for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t)) // for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t))
#define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias) \ #define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias) \
do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
/* (symbol object_initializer_name defined above) */ \
\
do_intrinsic(_hashCode, java_lang_Object, hashCode_name, void_int_signature, F_R) \ do_intrinsic(_hashCode, java_lang_Object, hashCode_name, void_int_signature, F_R) \
do_name( hashCode_name, "hashCode") \ do_name( hashCode_name, "hashCode") \
do_intrinsic(_getClass, java_lang_Object, getClass_name, void_class_signature, F_R) \ do_intrinsic(_getClass, java_lang_Object, getClass_name, void_class_signature, F_R) \
...@@ -635,9 +632,6 @@ ...@@ -635,9 +632,6 @@
do_intrinsic(_equalsC, java_util_Arrays, equals_name, equalsC_signature, F_S) \ do_intrinsic(_equalsC, java_util_Arrays, equals_name, equalsC_signature, F_S) \
do_signature(equalsC_signature, "([C[C)Z") \ do_signature(equalsC_signature, "([C[C)Z") \
\ \
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
/* (symbols invoke_name and invoke_signature defined above) */ \
\
do_intrinsic(_compareTo, java_lang_String, compareTo_name, string_int_signature, F_R) \ do_intrinsic(_compareTo, java_lang_String, compareTo_name, string_int_signature, F_R) \
do_name( compareTo_name, "compareTo") \ do_name( compareTo_name, "compareTo") \
do_intrinsic(_indexOf, java_lang_String, indexOf_name, string_int_signature, F_R) \ do_intrinsic(_indexOf, java_lang_String, indexOf_name, string_int_signature, F_R) \
...@@ -656,8 +650,6 @@ ...@@ -656,8 +650,6 @@
do_name( attemptUpdate_name, "attemptUpdate") \ do_name( attemptUpdate_name, "attemptUpdate") \
do_signature(attemptUpdate_signature, "(JJ)Z") \ do_signature(attemptUpdate_signature, "(JJ)Z") \
\ \
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
\
/* support for sun.misc.Unsafe */ \ /* support for sun.misc.Unsafe */ \
do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \ do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
\ \
...@@ -819,10 +811,22 @@ ...@@ -819,10 +811,22 @@
do_name( prefetchReadStatic_name, "prefetchReadStatic") \ do_name( prefetchReadStatic_name, "prefetchReadStatic") \
do_intrinsic(_prefetchWriteStatic, sun_misc_Unsafe, prefetchWriteStatic_name, prefetch_signature, F_SN) \ do_intrinsic(_prefetchWriteStatic, sun_misc_Unsafe, prefetchWriteStatic_name, prefetch_signature, F_SN) \
do_name( prefetchWriteStatic_name, "prefetchWriteStatic") \ do_name( prefetchWriteStatic_name, "prefetchWriteStatic") \
/*== LAST_COMPILER_INLINE*/ \
/*the compiler does have special inlining code for these; bytecode inline is just fine */ \
\
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
\
do_intrinsic(_Object_init, java_lang_Object, object_initializer_name, void_method_signature, F_R) \
/* (symbol object_initializer_name defined above) */ \
\
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
/* (symbols invoke_name and invoke_signature defined above) */ \
\
/*end*/ /*end*/
// Class vmSymbols // Class vmSymbols
class vmSymbols: AllStatic { class vmSymbols: AllStatic {
...@@ -935,6 +939,7 @@ class vmIntrinsics: AllStatic { ...@@ -935,6 +939,7 @@ class vmIntrinsics: AllStatic {
#undef VM_INTRINSIC_ENUM #undef VM_INTRINSIC_ENUM
ID_LIMIT, ID_LIMIT,
LAST_COMPILER_INLINE = _prefetchWriteStatic,
FIRST_ID = _none + 1 FIRST_ID = _none + 1
}; };
...@@ -972,4 +977,7 @@ public: ...@@ -972,4 +977,7 @@ public:
static Flags flags_for(ID id); static Flags flags_for(ID id);
static const char* short_name_as_C_string(ID id, char* buf, int size); static const char* short_name_as_C_string(ID id, char* buf, int size);
// Access to intrinsic methods:
static methodOop method_for(ID id);
}; };
...@@ -273,6 +273,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, TRAPS) ...@@ -273,6 +273,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, TRAPS)
compute_index_maps(); compute_index_maps();
if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) { if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) {
bool did_rewrite = false;
int i = _methods->length(); int i = _methods->length();
while (i-- > 0) { while (i-- > 0) {
methodOop method = (methodOop)_methods->obj_at(i); methodOop method = (methodOop)_methods->obj_at(i);
...@@ -281,9 +282,11 @@ Rewriter::Rewriter(instanceKlassHandle klass, TRAPS) ...@@ -281,9 +282,11 @@ Rewriter::Rewriter(instanceKlassHandle klass, TRAPS)
// object for finalization if needed. // object for finalization if needed.
methodHandle m(THREAD, method); methodHandle m(THREAD, method);
rewrite_Object_init(m, CHECK); rewrite_Object_init(m, CHECK);
did_rewrite = true;
break; break;
} }
} }
assert(did_rewrite, "must find Object::<init> to rewrite it");
} }
// rewrite methods, in two passes // rewrite methods, in two passes
......
...@@ -68,7 +68,7 @@ methodOop methodKlass::allocate(constMethodHandle xconst, ...@@ -68,7 +68,7 @@ methodOop methodKlass::allocate(constMethodHandle xconst,
m->set_constants(NULL); m->set_constants(NULL);
m->set_max_stack(0); m->set_max_stack(0);
m->set_max_locals(0); m->set_max_locals(0);
m->clear_intrinsic_id_cache(); m->set_intrinsic_id(vmIntrinsics::_none);
m->set_method_data(NULL); m->set_method_data(NULL);
m->set_interpreter_throwout_count(0); m->set_interpreter_throwout_count(0);
m->set_vtable_index(methodOopDesc::garbage_vtable_index); m->set_vtable_index(methodOopDesc::garbage_vtable_index);
......
...@@ -962,26 +962,39 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod ...@@ -962,26 +962,39 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod
return newm; return newm;
} }
vmIntrinsics::ID methodOopDesc::compute_intrinsic_id() const { vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) {
assert(vmIntrinsics::_none == 0, "correct coding of default case");
const uintptr_t max_cache_uint = right_n_bits((int)(sizeof(_intrinsic_id_cache) * BitsPerByte));
assert((uintptr_t)vmIntrinsics::ID_LIMIT <= max_cache_uint, "else fix cache size");
// if loader is not the default loader (i.e., != NULL), we can't know the intrinsics // if loader is not the default loader (i.e., != NULL), we can't know the intrinsics
// because we are not loading from core libraries // because we are not loading from core libraries
if (instanceKlass::cast(method_holder())->class_loader() != NULL) return vmIntrinsics::_none; if (instanceKlass::cast(holder)->class_loader() != NULL)
return vmSymbols::NO_SID; // regardless of name, no intrinsics here
// see if the klass name is well-known: // see if the klass name is well-known:
symbolOop klass_name = instanceKlass::cast(method_holder())->name(); symbolOop klass_name = instanceKlass::cast(holder)->name();
vmSymbols::SID klass_id = vmSymbols::find_sid(klass_name); return vmSymbols::find_sid(klass_name);
if (klass_id == vmSymbols::NO_SID) return vmIntrinsics::_none; }
void methodOopDesc::init_intrinsic_id() {
assert(_intrinsic_id == vmIntrinsics::_none, "do this just once");
const uintptr_t max_id_uint = right_n_bits((int)(sizeof(_intrinsic_id) * BitsPerByte));
assert((uintptr_t)vmIntrinsics::ID_LIMIT <= max_id_uint, "else fix size");
// the klass name is well-known:
vmSymbols::SID klass_id = klass_id_for_intrinsics(method_holder());
assert(klass_id != vmSymbols::NO_SID, "caller responsibility");
// ditto for method and signature: // ditto for method and signature:
vmSymbols::SID name_id = vmSymbols::find_sid(name()); vmSymbols::SID name_id = vmSymbols::find_sid(name());
if (name_id == vmSymbols::NO_SID) return vmIntrinsics::_none; if (name_id == vmSymbols::NO_SID) return;
vmSymbols::SID sig_id = vmSymbols::find_sid(signature()); vmSymbols::SID sig_id = vmSymbols::find_sid(signature());
if (sig_id == vmSymbols::NO_SID) return vmIntrinsics::_none; if (sig_id == vmSymbols::NO_SID) return;
jshort flags = access_flags().as_short(); jshort flags = access_flags().as_short();
vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
if (id != vmIntrinsics::_none) {
set_intrinsic_id(id);
return;
}
// A few slightly irregular cases: // A few slightly irregular cases:
switch (klass_id) { switch (klass_id) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_StrictMath): case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_StrictMath):
...@@ -992,15 +1005,18 @@ vmIntrinsics::ID methodOopDesc::compute_intrinsic_id() const { ...@@ -992,15 +1005,18 @@ vmIntrinsics::ID methodOopDesc::compute_intrinsic_id() const {
case vmSymbols::VM_SYMBOL_ENUM_NAME(sqrt_name): case vmSymbols::VM_SYMBOL_ENUM_NAME(sqrt_name):
// pretend it is the corresponding method in the non-strict class: // pretend it is the corresponding method in the non-strict class:
klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Math); klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Math);
id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
break; break;
} }
} }
// return intrinsic id if any if (id != vmIntrinsics::_none) {
return vmIntrinsics::find_id(klass_id, name_id, sig_id, flags); // Set up its iid. It is an alias method.
set_intrinsic_id(id);
return;
}
} }
// These two methods are static since a GC may move the methodOopDesc // These two methods are static since a GC may move the methodOopDesc
bool methodOopDesc::load_signature_classes(methodHandle m, TRAPS) { bool methodOopDesc::load_signature_classes(methodHandle m, TRAPS) {
bool sig_is_loaded = true; bool sig_is_loaded = true;
......
...@@ -104,7 +104,7 @@ class methodOopDesc : public oopDesc { ...@@ -104,7 +104,7 @@ class methodOopDesc : public oopDesc {
u2 _max_stack; // Maximum number of entries on the expression stack u2 _max_stack; // Maximum number of entries on the expression stack
u2 _max_locals; // Number of local variables used by this method u2 _max_locals; // Number of local variables used by this method
u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words
u1 _intrinsic_id_cache; // Cache for intrinsic_id; 0 or 1+vmInt::ID u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
u1 _highest_tier_compile; // Highest compile level this method has ever seen. u1 _highest_tier_compile; // Highest compile level this method has ever seen.
u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
u2 _number_of_breakpoints; // fullspeed debugging support u2 _number_of_breakpoints; // fullspeed debugging support
...@@ -224,8 +224,6 @@ class methodOopDesc : public oopDesc { ...@@ -224,8 +224,6 @@ class methodOopDesc : public oopDesc {
int highest_tier_compile() { return _highest_tier_compile;} int highest_tier_compile() { return _highest_tier_compile;}
void set_highest_tier_compile(int level) { _highest_tier_compile = level;} void set_highest_tier_compile(int level) { _highest_tier_compile = level;}
void clear_intrinsic_id_cache() { _intrinsic_id_cache = 0; }
// Count of times method was exited via exception while interpreting // Count of times method was exited via exception while interpreting
void interpreter_throwout_increment() { void interpreter_throwout_increment() {
if (_interpreter_throwout_count < 65534) { if (_interpreter_throwout_count < 65534) {
...@@ -571,18 +569,12 @@ class methodOopDesc : public oopDesc { ...@@ -571,18 +569,12 @@ class methodOopDesc : public oopDesc {
void set_cached_itable_index(int index) { instanceKlass::cast(method_holder())->set_cached_itable_index(method_idnum(), index); } void set_cached_itable_index(int index) { instanceKlass::cast(method_holder())->set_cached_itable_index(method_idnum(), index); }
// Support for inlining of intrinsic methods // Support for inlining of intrinsic methods
vmIntrinsics::ID intrinsic_id() const { // returns zero if not an intrinsic vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; }
const u1& cache = _intrinsic_id_cache; void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; }
if (cache != 0) {
return (vmIntrinsics::ID)(cache - 1); // Helper routines for intrinsic_id() and vmIntrinsics::method().
} else { void init_intrinsic_id(); // updates from _none if a match
vmIntrinsics::ID id = compute_intrinsic_id(); static vmSymbols::SID klass_id_for_intrinsics(klassOop holder);
*(u1*)&cache = ((u1) id) + 1; // force the cache to be non-const
vmIntrinsics::verify_method(id, (methodOop) this);
assert((vmIntrinsics::ID)(cache - 1) == id, "proper conversion");
return id;
}
}
// On-stack replacement support // On-stack replacement support
bool has_osr_nmethod() { return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci) != NULL; } bool has_osr_nmethod() { return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci) != NULL; }
...@@ -635,9 +627,6 @@ class methodOopDesc : public oopDesc { ...@@ -635,9 +627,6 @@ class methodOopDesc : public oopDesc {
void set_size_of_parameters(int size) { _size_of_parameters = size; } void set_size_of_parameters(int size) { _size_of_parameters = size; }
private: private:
// Helper routine for intrinsic_id().
vmIntrinsics::ID compute_intrinsic_id() const;
// Inlined elements // Inlined elements
address* native_function_addr() const { assert(is_native(), "must be native"); return (address*) (this+1); } address* native_function_addr() const { assert(is_native(), "must be native"); return (address*) (this+1); }
address* signature_handler_addr() const { return native_function_addr() + 1; } address* signature_handler_addr() const { return native_function_addr() + 1; }
......
...@@ -101,7 +101,8 @@ CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) { ...@@ -101,7 +101,8 @@ CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) {
} }
} }
// Lazily create intrinsics for intrinsic IDs well-known in the runtime. // Lazily create intrinsics for intrinsic IDs well-known in the runtime.
if (m->intrinsic_id() != vmIntrinsics::_none) { if (m->intrinsic_id() != vmIntrinsics::_none &&
m->intrinsic_id() <= vmIntrinsics::LAST_COMPILER_INLINE) {
CallGenerator* cg = make_vm_intrinsic(m, is_virtual); CallGenerator* cg = make_vm_intrinsic(m, is_virtual);
if (cg != NULL) { if (cg != NULL) {
// Save it for next time: // Save it for next time:
......
...@@ -310,11 +310,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { ...@@ -310,11 +310,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
if (!InlineAtomicLong) return NULL; if (!InlineAtomicLong) return NULL;
break; break;
case vmIntrinsics::_Object_init:
case vmIntrinsics::_invoke:
// We do not intrinsify these; they are marked for other purposes.
return NULL;
case vmIntrinsics::_getCallerClass: case vmIntrinsics::_getCallerClass:
if (!UseNewReflection) return NULL; if (!UseNewReflection) return NULL;
if (!InlineReflectionGetCallerClass) return NULL; if (!InlineReflectionGetCallerClass) return NULL;
...@@ -327,6 +322,8 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) { ...@@ -327,6 +322,8 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
break; break;
default: default:
assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
break; break;
} }
...@@ -394,18 +391,11 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) { ...@@ -394,18 +391,11 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
} }
if (PrintIntrinsics) { if (PrintIntrinsics) {
switch (intrinsic_id()) { tty->print("Did not inline intrinsic %s%s at bci:%d in",
case vmIntrinsics::_invoke: vmIntrinsics::name_at(intrinsic_id()),
case vmIntrinsics::_Object_init: (is_virtual() ? " (virtual)" : ""), kit.bci());
// We do not expect to inline these, so do not produce any noise about them. kit.caller()->print_short_name(tty);
break; tty->print_cr(" (%d bytes)", kit.caller()->code_size());
default:
tty->print("Did not inline intrinsic %s%s at bci:%d in",
vmIntrinsics::name_at(intrinsic_id()),
(is_virtual() ? " (virtual)" : ""), kit.bci());
kit.caller()->print_short_name(tty);
tty->print_cr(" (%d bytes)", kit.caller()->code_size());
}
} }
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed); C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
return NULL; return NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册