提交 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,
this_klass->set_minor_version(minor_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) {
// JVMTI: we have an instanceKlass now, tell it about the cached bytes
this_klass->set_cached_class_file(cached_class_file_bytes,
......
......@@ -513,9 +513,6 @@
//
// 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) \
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_name( hashCode_name, "hashCode") \
do_intrinsic(_getClass, java_lang_Object, getClass_name, void_class_signature, F_R) \
......@@ -635,9 +632,6 @@
do_intrinsic(_equalsC, java_util_Arrays, equals_name, equalsC_signature, F_S) \
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_name( compareTo_name, "compareTo") \
do_intrinsic(_indexOf, java_lang_String, indexOf_name, string_int_signature, F_R) \
......@@ -656,8 +650,6 @@
do_name( attemptUpdate_name, "attemptUpdate") \
do_signature(attemptUpdate_signature, "(JJ)Z") \
\
do_intrinsic(_fillInStackTrace, java_lang_Throwable, fillInStackTrace_name, void_throwable_signature, F_RNY) \
\
/* support for sun.misc.Unsafe */ \
do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
\
......@@ -819,10 +811,22 @@
do_name( prefetchReadStatic_name, "prefetchReadStatic") \
do_intrinsic(_prefetchWriteStatic, sun_misc_Unsafe, prefetchWriteStatic_name, prefetch_signature, F_SN) \
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*/
// Class vmSymbols
class vmSymbols: AllStatic {
......@@ -935,6 +939,7 @@ class vmIntrinsics: AllStatic {
#undef VM_INTRINSIC_ENUM
ID_LIMIT,
LAST_COMPILER_INLINE = _prefetchWriteStatic,
FIRST_ID = _none + 1
};
......@@ -972,4 +977,7 @@ public:
static Flags flags_for(ID id);
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)
compute_index_maps();
if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) {
bool did_rewrite = false;
int i = _methods->length();
while (i-- > 0) {
methodOop method = (methodOop)_methods->obj_at(i);
......@@ -281,9 +282,11 @@ Rewriter::Rewriter(instanceKlassHandle klass, TRAPS)
// object for finalization if needed.
methodHandle m(THREAD, method);
rewrite_Object_init(m, CHECK);
did_rewrite = true;
break;
}
}
assert(did_rewrite, "must find Object::<init> to rewrite it");
}
// rewrite methods, in two passes
......
......@@ -68,7 +68,7 @@ methodOop methodKlass::allocate(constMethodHandle xconst,
m->set_constants(NULL);
m->set_max_stack(0);
m->set_max_locals(0);
m->clear_intrinsic_id_cache();
m->set_intrinsic_id(vmIntrinsics::_none);
m->set_method_data(NULL);
m->set_interpreter_throwout_count(0);
m->set_vtable_index(methodOopDesc::garbage_vtable_index);
......
......@@ -962,26 +962,39 @@ methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_cod
return newm;
}
vmIntrinsics::ID methodOopDesc::compute_intrinsic_id() const {
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");
vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) {
// if loader is not the default loader (i.e., != NULL), we can't know the intrinsics
// 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:
symbolOop klass_name = instanceKlass::cast(method_holder())->name();
vmSymbols::SID klass_id = vmSymbols::find_sid(klass_name);
if (klass_id == vmSymbols::NO_SID) return vmIntrinsics::_none;
symbolOop klass_name = instanceKlass::cast(holder)->name();
return vmSymbols::find_sid(klass_name);
}
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:
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());
if (sig_id == vmSymbols::NO_SID) return vmIntrinsics::_none;
if (sig_id == vmSymbols::NO_SID) return;
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:
switch (klass_id) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_StrictMath):
......@@ -992,15 +1005,18 @@ vmIntrinsics::ID methodOopDesc::compute_intrinsic_id() const {
case vmSymbols::VM_SYMBOL_ENUM_NAME(sqrt_name):
// pretend it is the corresponding method in the non-strict class:
klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_Math);
id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
break;
}
}
// return intrinsic id if any
return vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
if (id != vmIntrinsics::_none) {
// 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
bool methodOopDesc::load_signature_classes(methodHandle m, TRAPS) {
bool sig_is_loaded = true;
......
......@@ -104,7 +104,7 @@ class methodOopDesc : public oopDesc {
u2 _max_stack; // Maximum number of entries on the expression stack
u2 _max_locals; // Number of local variables used by this method
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.
u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
u2 _number_of_breakpoints; // fullspeed debugging support
......@@ -224,8 +224,6 @@ class methodOopDesc : public oopDesc {
int highest_tier_compile() { return _highest_tier_compile;}
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
void interpreter_throwout_increment() {
if (_interpreter_throwout_count < 65534) {
......@@ -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); }
// Support for inlining of intrinsic methods
vmIntrinsics::ID intrinsic_id() const { // returns zero if not an intrinsic
const u1& cache = _intrinsic_id_cache;
if (cache != 0) {
return (vmIntrinsics::ID)(cache - 1);
} else {
vmIntrinsics::ID id = compute_intrinsic_id();
*(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;
}
}
vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; }
void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; }
// Helper routines for intrinsic_id() and vmIntrinsics::method().
void init_intrinsic_id(); // updates from _none if a match
static vmSymbols::SID klass_id_for_intrinsics(klassOop holder);
// On-stack replacement support
bool has_osr_nmethod() { return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci) != NULL; }
......@@ -635,9 +627,6 @@ class methodOopDesc : public oopDesc {
void set_size_of_parameters(int size) { _size_of_parameters = size; }
private:
// Helper routine for intrinsic_id().
vmIntrinsics::ID compute_intrinsic_id() const;
// Inlined elements
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; }
......
......@@ -101,7 +101,8 @@ CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) {
}
}
// 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);
if (cg != NULL) {
// Save it for next time:
......
......@@ -310,11 +310,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
if (!InlineAtomicLong) return NULL;
break;
case vmIntrinsics::_Object_init:
case vmIntrinsics::_invoke:
// We do not intrinsify these; they are marked for other purposes.
return NULL;
case vmIntrinsics::_getCallerClass:
if (!UseNewReflection) return NULL;
if (!InlineReflectionGetCallerClass) return NULL;
......@@ -327,6 +322,8 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
break;
default:
assert(id <= vmIntrinsics::LAST_COMPILER_INLINE, "caller responsibility");
assert(id != vmIntrinsics::_Object_init && id != vmIntrinsics::_invoke, "enum out of order?");
break;
}
......@@ -394,18 +391,11 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
}
if (PrintIntrinsics) {
switch (intrinsic_id()) {
case vmIntrinsics::_invoke:
case vmIntrinsics::_Object_init:
// We do not expect to inline these, so do not produce any noise about them.
break;
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());
}
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);
return NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册