Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/deoptimization.cpp @ 20705:d3f3f7677537
6898462: The escape analysis with G1 cause crash assertion src/share/vm/runtime/vframeArray.cpp:94
Summary: OOM during reallocation of scalar replaced objects in deoptimization causes crashes
Reviewed-by: kvn, jrose
author | roland |
---|---|
date | Tue, 25 Nov 2014 17:33:59 +0100 |
parents | b186a900f63a |
children | 793204f5528a |
comparison
equal
deleted
inserted
replaced
20704:8c08b28b7eee | 20705:d3f3f7677537 |
---|---|
211 vf = vf->sender(); | 211 vf = vf->sender(); |
212 } | 212 } |
213 assert(vf->is_compiled_frame(), "Wrong frame type"); | 213 assert(vf->is_compiled_frame(), "Wrong frame type"); |
214 chunk->push(compiledVFrame::cast(vf)); | 214 chunk->push(compiledVFrame::cast(vf)); |
215 | 215 |
216 bool realloc_failures = false; | |
217 | |
216 #ifdef COMPILER2 | 218 #ifdef COMPILER2 |
217 // Reallocate the non-escaping objects and restore their fields. Then | 219 // Reallocate the non-escaping objects and restore their fields. Then |
218 // relock objects if synchronization on them was eliminated. | 220 // relock objects if synchronization on them was eliminated. |
219 if (DoEscapeAnalysis || EliminateNestedLocks) { | 221 if (DoEscapeAnalysis || EliminateNestedLocks) { |
220 if (EliminateAllocations) { | 222 if (EliminateAllocations) { |
241 if (TraceDeoptimization) { | 243 if (TraceDeoptimization) { |
242 ttyLocker ttyl; | 244 ttyLocker ttyl; |
243 tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread); | 245 tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread); |
244 } | 246 } |
245 } | 247 } |
246 bool reallocated = false; | |
247 if (objects != NULL) { | 248 if (objects != NULL) { |
248 JRT_BLOCK | 249 JRT_BLOCK |
249 reallocated = realloc_objects(thread, &deoptee, objects, THREAD); | 250 realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD); |
250 JRT_END | 251 JRT_END |
251 } | 252 reassign_fields(&deoptee, &map, objects, realloc_failures); |
252 if (reallocated) { | 253 } |
253 reassign_fields(&deoptee, &map, objects); | |
254 #ifndef PRODUCT | 254 #ifndef PRODUCT |
255 if (TraceDeoptimization) { | 255 if (TraceDeoptimization) { |
256 ttyLocker ttyl; | 256 ttyLocker ttyl; |
257 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); | 257 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); |
258 print_objects(objects); | 258 print_objects(objects, realloc_failures); |
259 } | 259 } |
260 #endif | 260 #endif |
261 } | |
262 if (save_oop_result) { | 261 if (save_oop_result) { |
263 // Restore result. | 262 // Restore result. |
264 deoptee.set_saved_oop_result(&map, return_value()); | 263 deoptee.set_saved_oop_result(&map, return_value()); |
265 } | 264 } |
266 } | 265 } |
271 for (int i = 0; i < chunk->length(); i++) { | 270 for (int i = 0; i < chunk->length(); i++) { |
272 compiledVFrame* cvf = chunk->at(i); | 271 compiledVFrame* cvf = chunk->at(i); |
273 assert (cvf->scope() != NULL,"expect only compiled java frames"); | 272 assert (cvf->scope() != NULL,"expect only compiled java frames"); |
274 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); | 273 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
275 if (monitors->is_nonempty()) { | 274 if (monitors->is_nonempty()) { |
276 relock_objects(monitors, thread); | 275 relock_objects(monitors, thread, realloc_failures); |
277 #ifndef PRODUCT | 276 #ifndef PRODUCT |
278 if (TraceDeoptimization) { | 277 if (TraceDeoptimization) { |
279 ttyLocker ttyl; | 278 ttyLocker ttyl; |
280 for (int j = 0; j < monitors->length(); j++) { | 279 for (int j = 0; j < monitors->length(); j++) { |
281 MonitorInfo* mi = monitors->at(j); | 280 MonitorInfo* mi = monitors->at(j); |
282 if (mi->eliminated()) { | 281 if (mi->eliminated()) { |
283 if (first) { | 282 if (first) { |
284 first = false; | 283 first = false; |
285 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); | 284 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); |
286 } | 285 } |
287 tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner()); | 286 if (mi->owner_is_scalar_replaced()) { |
287 Klass* k = java_lang_Class::as_Klass(mi->owner_klass()); | |
288 tty->print_cr(" failed reallocation for klass %s", k->external_name()); | |
289 } else { | |
290 tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner()); | |
291 } | |
288 } | 292 } |
289 } | 293 } |
290 } | 294 } |
291 #endif | 295 #endif |
292 } | 296 } |
297 // Ensure that no safepoint is taken after pointers have been stored | 301 // Ensure that no safepoint is taken after pointers have been stored |
298 // in fields of rematerialized objects. If a safepoint occurs from here on | 302 // in fields of rematerialized objects. If a safepoint occurs from here on |
299 // out the java state residing in the vframeArray will be missed. | 303 // out the java state residing in the vframeArray will be missed. |
300 No_Safepoint_Verifier no_safepoint; | 304 No_Safepoint_Verifier no_safepoint; |
301 | 305 |
302 vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk); | 306 vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures); |
303 | 307 #ifdef COMPILER2 |
304 assert(thread->vframe_array_head() == NULL, "Pending deopt!");; | 308 if (realloc_failures) { |
309 pop_frames_failed_reallocs(thread, array); | |
310 } | |
311 #endif | |
312 | |
313 assert(thread->vframe_array_head() == NULL, "Pending deopt!"); | |
305 thread->set_vframe_array_head(array); | 314 thread->set_vframe_array_head(array); |
306 | 315 |
307 // Now that the vframeArray has been created if we have any deferred local writes | 316 // Now that the vframeArray has been created if we have any deferred local writes |
308 // added by jvmti then we can free up that structure as the data is now in the | 317 // added by jvmti then we can free up that structure as the data is now in the |
309 // vframeArray | 318 // vframeArray |
751 Handle pending_exception(thread->pending_exception()); | 760 Handle pending_exception(thread->pending_exception()); |
752 const char* exception_file = thread->exception_file(); | 761 const char* exception_file = thread->exception_file(); |
753 int exception_line = thread->exception_line(); | 762 int exception_line = thread->exception_line(); |
754 thread->clear_pending_exception(); | 763 thread->clear_pending_exception(); |
755 | 764 |
765 bool failures = false; | |
766 | |
756 for (int i = 0; i < objects->length(); i++) { | 767 for (int i = 0; i < objects->length(); i++) { |
757 assert(objects->at(i)->is_object(), "invalid debug information"); | 768 assert(objects->at(i)->is_object(), "invalid debug information"); |
758 ObjectValue* sv = (ObjectValue*) objects->at(i); | 769 ObjectValue* sv = (ObjectValue*) objects->at(i); |
759 | 770 |
760 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); | 771 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
761 oop obj = NULL; | 772 oop obj = NULL; |
762 | 773 |
763 if (k->oop_is_instance()) { | 774 if (k->oop_is_instance()) { |
764 InstanceKlass* ik = InstanceKlass::cast(k()); | 775 InstanceKlass* ik = InstanceKlass::cast(k()); |
765 obj = ik->allocate_instance(CHECK_(false)); | 776 obj = ik->allocate_instance(THREAD); |
766 } else if (k->oop_is_typeArray()) { | 777 } else if (k->oop_is_typeArray()) { |
767 TypeArrayKlass* ak = TypeArrayKlass::cast(k()); | 778 TypeArrayKlass* ak = TypeArrayKlass::cast(k()); |
768 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); | 779 assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); |
769 int len = sv->field_size() / type2size[ak->element_type()]; | 780 int len = sv->field_size() / type2size[ak->element_type()]; |
770 obj = ak->allocate(len, CHECK_(false)); | 781 obj = ak->allocate(len, THREAD); |
771 } else if (k->oop_is_objArray()) { | 782 } else if (k->oop_is_objArray()) { |
772 ObjArrayKlass* ak = ObjArrayKlass::cast(k()); | 783 ObjArrayKlass* ak = ObjArrayKlass::cast(k()); |
773 obj = ak->allocate(sv->field_size(), CHECK_(false)); | 784 obj = ak->allocate(sv->field_size(), THREAD); |
774 } | 785 } |
775 | 786 |
776 assert(obj != NULL, "allocation failed"); | 787 if (obj == NULL) { |
788 failures = true; | |
789 } | |
790 | |
777 assert(sv->value().is_null(), "redundant reallocation"); | 791 assert(sv->value().is_null(), "redundant reallocation"); |
792 assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception"); | |
793 CLEAR_PENDING_EXCEPTION; | |
778 sv->set_value(obj); | 794 sv->set_value(obj); |
779 } | 795 } |
780 | 796 |
781 if (pending_exception.not_null()) { | 797 if (failures) { |
798 THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures); | |
799 } else if (pending_exception.not_null()) { | |
782 thread->set_pending_exception(pending_exception(), exception_file, exception_line); | 800 thread->set_pending_exception(pending_exception(), exception_file, exception_line); |
783 } | 801 } |
784 | 802 |
785 return true; | 803 return failures; |
786 } | 804 } |
787 | 805 |
788 // This assumes that the fields are stored in ObjectValue in the same order | 806 // This assumes that the fields are stored in ObjectValue in the same order |
789 // they are yielded by do_nonstatic_fields. | 807 // they are yielded by do_nonstatic_fields. |
790 class FieldReassigner: public FieldClosure { | 808 class FieldReassigner: public FieldClosure { |
918 } | 936 } |
919 } | 937 } |
920 | 938 |
921 | 939 |
922 // restore fields of all eliminated objects and arrays | 940 // restore fields of all eliminated objects and arrays |
923 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) { | 941 void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects, bool realloc_failures) { |
924 for (int i = 0; i < objects->length(); i++) { | 942 for (int i = 0; i < objects->length(); i++) { |
925 ObjectValue* sv = (ObjectValue*) objects->at(i); | 943 ObjectValue* sv = (ObjectValue*) objects->at(i); |
926 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); | 944 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
927 Handle obj = sv->value(); | 945 Handle obj = sv->value(); |
928 assert(obj.not_null(), "reallocation was missed"); | 946 assert(obj.not_null() || realloc_failures, "reallocation was missed"); |
947 if (obj.is_null()) { | |
948 continue; | |
949 } | |
929 | 950 |
930 if (k->oop_is_instance()) { | 951 if (k->oop_is_instance()) { |
931 InstanceKlass* ik = InstanceKlass::cast(k()); | 952 InstanceKlass* ik = InstanceKlass::cast(k()); |
932 FieldReassigner reassign(fr, reg_map, sv, obj()); | 953 FieldReassigner reassign(fr, reg_map, sv, obj()); |
933 ik->do_nonstatic_fields(&reassign); | 954 ik->do_nonstatic_fields(&reassign); |
940 } | 961 } |
941 } | 962 } |
942 | 963 |
943 | 964 |
944 // relock objects for which synchronization was eliminated | 965 // relock objects for which synchronization was eliminated |
945 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) { | 966 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread, bool realloc_failures) { |
946 for (int i = 0; i < monitors->length(); i++) { | 967 for (int i = 0; i < monitors->length(); i++) { |
947 MonitorInfo* mon_info = monitors->at(i); | 968 MonitorInfo* mon_info = monitors->at(i); |
948 if (mon_info->eliminated()) { | 969 if (mon_info->eliminated()) { |
949 assert(mon_info->owner() != NULL, "reallocation was missed"); | 970 assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed"); |
950 Handle obj = Handle(mon_info->owner()); | 971 if (!mon_info->owner_is_scalar_replaced()) { |
951 markOop mark = obj->mark(); | 972 Handle obj = Handle(mon_info->owner()); |
952 if (UseBiasedLocking && mark->has_bias_pattern()) { | 973 markOop mark = obj->mark(); |
953 // New allocated objects may have the mark set to anonymously biased. | 974 if (UseBiasedLocking && mark->has_bias_pattern()) { |
954 // Also the deoptimized method may called methods with synchronization | 975 // New allocated objects may have the mark set to anonymously biased. |
955 // where the thread-local object is bias locked to the current thread. | 976 // Also the deoptimized method may called methods with synchronization |
956 assert(mark->is_biased_anonymously() || | 977 // where the thread-local object is bias locked to the current thread. |
957 mark->biased_locker() == thread, "should be locked to current thread"); | 978 assert(mark->is_biased_anonymously() || |
958 // Reset mark word to unbiased prototype. | 979 mark->biased_locker() == thread, "should be locked to current thread"); |
959 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); | 980 // Reset mark word to unbiased prototype. |
960 obj->set_mark(unbiased_prototype); | 981 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); |
961 } | 982 obj->set_mark(unbiased_prototype); |
962 BasicLock* lock = mon_info->lock(); | 983 } |
963 ObjectSynchronizer::slow_enter(obj, lock, thread); | 984 BasicLock* lock = mon_info->lock(); |
964 } | 985 ObjectSynchronizer::slow_enter(obj, lock, thread); |
965 assert(mon_info->owner()->is_locked(), "object must be locked now"); | 986 assert(mon_info->owner()->is_locked(), "object must be locked now"); |
987 } | |
988 } | |
966 } | 989 } |
967 } | 990 } |
968 | 991 |
969 | 992 |
970 #ifndef PRODUCT | 993 #ifndef PRODUCT |
971 // print information about reallocated objects | 994 // print information about reallocated objects |
972 void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) { | 995 void Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects, bool realloc_failures) { |
973 fieldDescriptor fd; | 996 fieldDescriptor fd; |
974 | 997 |
975 for (int i = 0; i < objects->length(); i++) { | 998 for (int i = 0; i < objects->length(); i++) { |
976 ObjectValue* sv = (ObjectValue*) objects->at(i); | 999 ObjectValue* sv = (ObjectValue*) objects->at(i); |
977 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); | 1000 KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); |
978 Handle obj = sv->value(); | 1001 Handle obj = sv->value(); |
979 | 1002 |
980 tty->print(" object <" INTPTR_FORMAT "> of type ", (void *)sv->value()()); | 1003 tty->print(" object <" INTPTR_FORMAT "> of type ", (void *)sv->value()()); |
981 k->print_value(); | 1004 k->print_value(); |
982 tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); | 1005 assert(obj.not_null() || realloc_failures, "reallocation was missed"); |
1006 if (obj.is_null()) { | |
1007 tty->print(" allocation failed"); | |
1008 } else { | |
1009 tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); | |
1010 } | |
983 tty->cr(); | 1011 tty->cr(); |
984 | 1012 |
985 if (Verbose) { | 1013 if (Verbose && !obj.is_null()) { |
986 k->oop_print_on(obj(), tty); | 1014 k->oop_print_on(obj(), tty); |
987 } | 1015 } |
988 } | 1016 } |
989 } | 1017 } |
990 #endif | 1018 #endif |
991 #endif // COMPILER2 | 1019 #endif // COMPILER2 |
992 | 1020 |
993 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) { | 1021 vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) { |
994 Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); | 1022 Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); |
995 | 1023 |
996 #ifndef PRODUCT | 1024 #ifndef PRODUCT |
997 if (TraceDeoptimization) { | 1025 if (TraceDeoptimization) { |
998 ttyLocker ttyl; | 1026 ttyLocker ttyl; |
1031 frame sender = caller; | 1059 frame sender = caller; |
1032 | 1060 |
1033 // Since the Java thread being deoptimized will eventually adjust it's own stack, | 1061 // Since the Java thread being deoptimized will eventually adjust it's own stack, |
1034 // the vframeArray containing the unpacking information is allocated in the C heap. | 1062 // the vframeArray containing the unpacking information is allocated in the C heap. |
1035 // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames(). | 1063 // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames(). |
1036 vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr); | 1064 vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr, realloc_failures); |
1037 | 1065 |
1038 // Compare the vframeArray to the collected vframes | 1066 // Compare the vframeArray to the collected vframes |
1039 assert(array->structural_compare(thread, chunk), "just checking"); | 1067 assert(array->structural_compare(thread, chunk), "just checking"); |
1040 | 1068 |
1041 #ifndef PRODUCT | 1069 #ifndef PRODUCT |
1046 #endif // PRODUCT | 1074 #endif // PRODUCT |
1047 | 1075 |
1048 return array; | 1076 return array; |
1049 } | 1077 } |
1050 | 1078 |
1079 #ifdef COMPILER2 | |
1080 void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) { | |
1081 // Reallocation of some scalar replaced objects failed. Record | |
1082 // that we need to pop all the interpreter frames for the | |
1083 // deoptimized compiled frame. | |
1084 assert(thread->frames_to_pop_failed_realloc() == 0, "missed frames to pop?"); | |
1085 thread->set_frames_to_pop_failed_realloc(array->frames()); | |
1086 // Unlock all monitors here otherwise the interpreter will see a | |
1087 // mix of locked and unlocked monitors (because of failed | |
1088 // reallocations of synchronized objects) and be confused. | |
1089 for (int i = 0; i < array->frames(); i++) { | |
1090 MonitorChunk* monitors = array->element(i)->monitors(); | |
1091 if (monitors != NULL) { | |
1092 for (int j = 0; j < monitors->number_of_monitors(); j++) { | |
1093 BasicObjectLock* src = monitors->at(j); | |
1094 if (src->obj() != NULL) { | |
1095 ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread); | |
1096 } | |
1097 } | |
1098 array->element(i)->free_monitors(thread); | |
1099 #ifdef ASSERT | |
1100 array->element(i)->set_removed_monitors(); | |
1101 #endif | |
1102 } | |
1103 } | |
1104 } | |
1105 #endif | |
1051 | 1106 |
1052 static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { | 1107 static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { |
1053 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); | 1108 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
1054 for (int i = 0; i < monitors->length(); i++) { | 1109 for (int i = 0; i < monitors->length(); i++) { |
1055 MonitorInfo* mon_info = monitors->at(i); | 1110 MonitorInfo* mon_info = monitors->at(i); |