Mercurial > hg > truffle
comparison src/share/vm/opto/library_call.cpp @ 12078:acedd49a1bce
8022675: Redundant class init check
Reviewed-by: kvn, twisti
author | rbackman |
---|---|
date | Thu, 08 Aug 2013 03:16:56 +0200 |
parents | b800986664f4 |
children | 29aa8936f03c |
comparison
equal
deleted
inserted
replaced
12077:e16282db4946 | 12078:acedd49a1bce |
---|---|
211 // Generates the guards that check whether the result of | 211 // Generates the guards that check whether the result of |
212 // Unsafe.getObject should be recorded in an SATB log buffer. | 212 // Unsafe.getObject should be recorded in an SATB log buffer. |
213 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); | 213 void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, bool need_mem_bar); |
214 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); | 214 bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile); |
215 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static); | 215 bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static); |
216 static bool klass_needs_init_guard(Node* kls); | |
216 bool inline_unsafe_allocate(); | 217 bool inline_unsafe_allocate(); |
217 bool inline_unsafe_copyMemory(); | 218 bool inline_unsafe_copyMemory(); |
218 bool inline_native_currentThread(); | 219 bool inline_native_currentThread(); |
219 #ifdef TRACE_HAVE_INTRINSICS | 220 #ifdef TRACE_HAVE_INTRINSICS |
220 bool inline_native_classID(); | 221 bool inline_native_classID(); |
2890 fatal_unexpected_iid(id); | 2891 fatal_unexpected_iid(id); |
2891 return false; | 2892 return false; |
2892 } | 2893 } |
2893 } | 2894 } |
2894 | 2895 |
2896 bool LibraryCallKit::klass_needs_init_guard(Node* kls) { | |
2897 if (!kls->is_Con()) { | |
2898 return true; | |
2899 } | |
2900 const TypeKlassPtr* klsptr = kls->bottom_type()->isa_klassptr(); | |
2901 if (klsptr == NULL) { | |
2902 return true; | |
2903 } | |
2904 ciInstanceKlass* ik = klsptr->klass()->as_instance_klass(); | |
2905 // don't need a guard for a klass that is already initialized | |
2906 return !ik->is_initialized(); | |
2907 } | |
2908 | |
2895 //----------------------------inline_unsafe_allocate--------------------------- | 2909 //----------------------------inline_unsafe_allocate--------------------------- |
2896 // public native Object sun.mics.Unsafe.allocateInstance(Class<?> cls); | 2910 // public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls); |
2897 bool LibraryCallKit::inline_unsafe_allocate() { | 2911 bool LibraryCallKit::inline_unsafe_allocate() { |
2898 if (callee()->is_static()) return false; // caller must have the capability! | 2912 if (callee()->is_static()) return false; // caller must have the capability! |
2899 | 2913 |
2900 null_check_receiver(); // null-check, then ignore | 2914 null_check_receiver(); // null-check, then ignore |
2901 Node* cls = null_check(argument(1)); | 2915 Node* cls = null_check(argument(1)); |
2903 | 2917 |
2904 Node* kls = load_klass_from_mirror(cls, false, NULL, 0); | 2918 Node* kls = load_klass_from_mirror(cls, false, NULL, 0); |
2905 kls = null_check(kls); | 2919 kls = null_check(kls); |
2906 if (stopped()) return true; // argument was like int.class | 2920 if (stopped()) return true; // argument was like int.class |
2907 | 2921 |
2908 // Note: The argument might still be an illegal value like | 2922 Node* test = NULL; |
2909 // Serializable.class or Object[].class. The runtime will handle it. | 2923 if (LibraryCallKit::klass_needs_init_guard(kls)) { |
2910 // But we must make an explicit check for initialization. | 2924 // Note: The argument might still be an illegal value like |
2911 Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset())); | 2925 // Serializable.class or Object[].class. The runtime will handle it. |
2912 // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler | 2926 // But we must make an explicit check for initialization. |
2913 // can generate code to load it as unsigned byte. | 2927 Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset())); |
2914 Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN); | 2928 // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler |
2915 Node* bits = intcon(InstanceKlass::fully_initialized); | 2929 // can generate code to load it as unsigned byte. |
2916 Node* test = _gvn.transform(new (C) SubINode(inst, bits)); | 2930 Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN); |
2917 // The 'test' is non-zero if we need to take a slow path. | 2931 Node* bits = intcon(InstanceKlass::fully_initialized); |
2932 test = _gvn.transform(new (C) SubINode(inst, bits)); | |
2933 // The 'test' is non-zero if we need to take a slow path. | |
2934 } | |
2918 | 2935 |
2919 Node* obj = new_instance(kls, test); | 2936 Node* obj = new_instance(kls, test); |
2920 set_result(obj); | 2937 set_result(obj); |
2921 return true; | 2938 return true; |
2922 } | 2939 } |