hotspot/src/share/vm/runtime/vframeArray.cpp
changeset 28039 bf5a8340bf8a
parent 25717 7493b8ac31b7
child 33160 c59f1676d27e
child 33148 68fa8b6c4340
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp	Fri Dec 05 15:16:01 2014 +0100
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp	Tue Nov 25 17:33:59 2014 +0100
@@ -57,7 +57,7 @@
   }
 }
 
-void vframeArrayElement::fill_in(compiledVFrame* vf) {
+void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
 
 // Copy the information from the compiled vframe to the
 // interpreter frame we will be creating to replace vf
@@ -65,6 +65,9 @@
   _method = vf->method();
   _bci    = vf->raw_bci();
   _reexecute = vf->should_reexecute();
+#ifdef ASSERT
+  _removed_monitors = false;
+#endif
 
   int index;
 
@@ -82,11 +85,15 @@
     // Migrate the BasicLocks from the stack to the monitor chunk
     for (index = 0; index < list->length(); index++) {
       MonitorInfo* monitor = list->at(index);
-      assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already");
-      assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
+      assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
       BasicObjectLock* dest = _monitors->at(index);
-      dest->set_obj(monitor->owner());
-      monitor->lock()->move_to(monitor->owner(), dest->lock());
+      if (monitor->owner_is_scalar_replaced()) {
+        dest->set_obj(NULL);
+      } else {
+        assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
+        dest->set_obj(monitor->owner());
+        monitor->lock()->move_to(monitor->owner(), dest->lock());
+      }
     }
   }
 
@@ -111,7 +118,7 @@
     StackValue* value = locs->at(index);
     switch(value->type()) {
       case T_OBJECT:
-        assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
+        assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
         // preserve object type
         _locals->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT ));
         break;
@@ -136,7 +143,7 @@
     StackValue* value = exprs->at(index);
     switch(value->type()) {
       case T_OBJECT:
-        assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
+        assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
         // preserve object type
         _expressions->add( new StackValue(cast_from_oop<intptr_t>((value->get_obj()())), T_OBJECT ));
         break;
@@ -287,7 +294,7 @@
 
   _frame.patch_pc(thread, pc);
 
-  assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors");
+  assert (!method()->is_synchronized() || locks > 0 || _removed_monitors, "synchronized methods must have monitors");
 
   BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin();
   for (int index = 0; index < locks; index++) {
@@ -439,7 +446,8 @@
 
 
 vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk,
-                                   RegisterMap *reg_map, frame sender, frame caller, frame self) {
+                                   RegisterMap *reg_map, frame sender, frame caller, frame self,
+                                   bool realloc_failures) {
 
   // Allocate the vframeArray
   vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part
@@ -451,19 +459,20 @@
   result->_caller = caller;
   result->_original = self;
   result->set_unroll_block(NULL); // initialize it
-  result->fill_in(thread, frame_size, chunk, reg_map);
+  result->fill_in(thread, frame_size, chunk, reg_map, realloc_failures);
   return result;
 }
 
 void vframeArray::fill_in(JavaThread* thread,
                           int frame_size,
                           GrowableArray<compiledVFrame*>* chunk,
-                          const RegisterMap *reg_map) {
+                          const RegisterMap *reg_map,
+                          bool realloc_failures) {
   // Set owner first, it is used when adding monitor chunks
 
   _frame_size = frame_size;
   for(int i = 0; i < chunk->length(); i++) {
-    element(i)->fill_in(chunk->at(i));
+    element(i)->fill_in(chunk->at(i), realloc_failures);
   }
 
   // Copy registers for callee-saved registers