Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/vframeArray.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 | 0bf37f737702 |
children | 7848fc12602b |
comparison
equal
deleted
inserted
replaced
20704:8c08b28b7eee | 20705:d3f3f7677537 |
---|---|
54 jt->remove_monitor_chunk(chunk); | 54 jt->remove_monitor_chunk(chunk); |
55 delete chunk; | 55 delete chunk; |
56 } | 56 } |
57 } | 57 } |
58 | 58 |
59 void vframeArrayElement::fill_in(compiledVFrame* vf) { | 59 void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) { |
60 | 60 |
61 // Copy the information from the compiled vframe to the | 61 // Copy the information from the compiled vframe to the |
62 // interpreter frame we will be creating to replace vf | 62 // interpreter frame we will be creating to replace vf |
63 | 63 |
64 _method = vf->method(); | 64 _method = vf->method(); |
65 _bci = vf->raw_bci(); | 65 _bci = vf->raw_bci(); |
66 _reexecute = vf->should_reexecute(); | 66 _reexecute = vf->should_reexecute(); |
67 #ifdef ASSERT | |
68 _removed_monitors = false; | |
69 #endif | |
67 | 70 |
68 int index; | 71 int index; |
69 | 72 |
70 // Get the monitors off-stack | 73 // Get the monitors off-stack |
71 | 74 |
79 vf->thread()->add_monitor_chunk(_monitors); | 82 vf->thread()->add_monitor_chunk(_monitors); |
80 | 83 |
81 // Migrate the BasicLocks from the stack to the monitor chunk | 84 // Migrate the BasicLocks from the stack to the monitor chunk |
82 for (index = 0; index < list->length(); index++) { | 85 for (index = 0; index < list->length(); index++) { |
83 MonitorInfo* monitor = list->at(index); | 86 MonitorInfo* monitor = list->at(index); |
84 assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already"); | 87 assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); |
85 assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased"); | |
86 BasicObjectLock* dest = _monitors->at(index); | 88 BasicObjectLock* dest = _monitors->at(index); |
87 dest->set_obj(monitor->owner()); | 89 if (monitor->owner_is_scalar_replaced()) { |
88 monitor->lock()->move_to(monitor->owner(), dest->lock()); | 90 dest->set_obj(NULL); |
91 } else { | |
92 assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased"); | |
93 dest->set_obj(monitor->owner()); | |
94 monitor->lock()->move_to(monitor->owner(), dest->lock()); | |
95 } | |
89 } | 96 } |
90 } | 97 } |
91 | 98 |
92 // Convert the vframe locals and expressions to off stack | 99 // Convert the vframe locals and expressions to off stack |
93 // values. Because we will not gc all oops can be converted to | 100 // values. Because we will not gc all oops can be converted to |
108 _locals = new StackValueCollection(locs->size()); | 115 _locals = new StackValueCollection(locs->size()); |
109 for(index = 0; index < locs->size(); index++) { | 116 for(index = 0; index < locs->size(); index++) { |
110 StackValue* value = locs->at(index); | 117 StackValue* value = locs->at(index); |
111 switch(value->type()) { | 118 switch(value->type()) { |
112 case T_OBJECT: | 119 case T_OBJECT: |
113 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); | 120 assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); |
114 // preserve object type | 121 // preserve object type |
115 _locals->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT )); | 122 _locals->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT )); |
116 break; | 123 break; |
117 case T_CONFLICT: | 124 case T_CONFLICT: |
118 // A dead local. Will be initialized to null/zero. | 125 // A dead local. Will be initialized to null/zero. |
133 _expressions = new StackValueCollection(exprs->size()); | 140 _expressions = new StackValueCollection(exprs->size()); |
134 for(index = 0; index < exprs->size(); index++) { | 141 for(index = 0; index < exprs->size(); index++) { |
135 StackValue* value = exprs->at(index); | 142 StackValue* value = exprs->at(index); |
136 switch(value->type()) { | 143 switch(value->type()) { |
137 case T_OBJECT: | 144 case T_OBJECT: |
138 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); | 145 assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); |
139 // preserve object type | 146 // preserve object type |
140 _expressions->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT )); | 147 _expressions->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT )); |
141 break; | 148 break; |
142 case T_CONFLICT: | 149 case T_CONFLICT: |
143 // A dead stack element. Will be initialized to null/zero. | 150 // A dead stack element. Will be initialized to null/zero. |
284 // we placed in the skeletal frame now that we finally know the | 291 // we placed in the skeletal frame now that we finally know the |
285 // exact interpreter address we should use. | 292 // exact interpreter address we should use. |
286 | 293 |
287 _frame.patch_pc(thread, pc); | 294 _frame.patch_pc(thread, pc); |
288 | 295 |
289 assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors"); | 296 assert (!method()->is_synchronized() || locks > 0 || _removed_monitors, "synchronized methods must have monitors"); |
290 | 297 |
291 BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin(); | 298 BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin(); |
292 for (int index = 0; index < locks; index++) { | 299 for (int index = 0; index < locks; index++) { |
293 top = iframe()->previous_monitor_in_interpreter_frame(top); | 300 top = iframe()->previous_monitor_in_interpreter_frame(top); |
294 BasicObjectLock* src = _monitors->at(index); | 301 BasicObjectLock* src = _monitors->at(index); |
436 } | 443 } |
437 | 444 |
438 | 445 |
439 | 446 |
440 vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, | 447 vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, |
441 RegisterMap *reg_map, frame sender, frame caller, frame self) { | 448 RegisterMap *reg_map, frame sender, frame caller, frame self, |
449 bool realloc_failures) { | |
442 | 450 |
443 // Allocate the vframeArray | 451 // Allocate the vframeArray |
444 vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part | 452 vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part |
445 sizeof(vframeArrayElement) * (chunk->length() - 1), // variable part | 453 sizeof(vframeArrayElement) * (chunk->length() - 1), // variable part |
446 mtCompiler); | 454 mtCompiler); |
448 result->_owner_thread = thread; | 456 result->_owner_thread = thread; |
449 result->_sender = sender; | 457 result->_sender = sender; |
450 result->_caller = caller; | 458 result->_caller = caller; |
451 result->_original = self; | 459 result->_original = self; |
452 result->set_unroll_block(NULL); // initialize it | 460 result->set_unroll_block(NULL); // initialize it |
453 result->fill_in(thread, frame_size, chunk, reg_map); | 461 result->fill_in(thread, frame_size, chunk, reg_map, realloc_failures); |
454 return result; | 462 return result; |
455 } | 463 } |
456 | 464 |
457 void vframeArray::fill_in(JavaThread* thread, | 465 void vframeArray::fill_in(JavaThread* thread, |
458 int frame_size, | 466 int frame_size, |
459 GrowableArray<compiledVFrame*>* chunk, | 467 GrowableArray<compiledVFrame*>* chunk, |
460 const RegisterMap *reg_map) { | 468 const RegisterMap *reg_map, |
469 bool realloc_failures) { | |
461 // Set owner first, it is used when adding monitor chunks | 470 // Set owner first, it is used when adding monitor chunks |
462 | 471 |
463 _frame_size = frame_size; | 472 _frame_size = frame_size; |
464 for(int i = 0; i < chunk->length(); i++) { | 473 for(int i = 0; i < chunk->length(); i++) { |
465 element(i)->fill_in(chunk->at(i)); | 474 element(i)->fill_in(chunk->at(i), realloc_failures); |
466 } | 475 } |
467 | 476 |
468 // Copy registers for callee-saved registers | 477 // Copy registers for callee-saved registers |
469 if (reg_map != NULL) { | 478 if (reg_map != NULL) { |
470 for(int i = 0; i < RegisterMap::reg_count; i++) { | 479 for(int i = 0; i < RegisterMap::reg_count; i++) { |