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 }