hotspot/src/share/vm/runtime/vframe.cpp
changeset 23867 f144d430b1cf
parent 22234 da823d78ad65
child 24424 2658d7834c6e
--- a/hotspot/src/share/vm/runtime/vframe.cpp	Thu Apr 03 06:39:26 2014 -0400
+++ b/hotspot/src/share/vm/runtime/vframe.cpp	Sat Apr 05 21:33:11 2014 +0200
@@ -321,24 +321,38 @@
   }
 }
 
-StackValueCollection*  interpretedVFrame::expressions() const {
-  int length = fr().interpreter_frame_expression_stack_size();
-  if (method()->is_native()) {
-    // If the method is native, there is no expression stack
-    length = 0;
+StackValueCollection* interpretedVFrame::expressions() const {
+
+  InterpreterOopMap oop_mask;
+
+  if (!method()->is_native()) {
+    // Get oopmap describing oops and int for current bci
+    if (TraceDeoptimization && Verbose) {
+      methodHandle m_h(method());
+      OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
+    } else {
+      method()->mask_for(bci(), &oop_mask);
+    }
+  }
+
+  // If the bci is a call instruction, i.e. any of the invoke* instructions,
+  // the InterpreterOopMap does not include expression/operand stack liveness
+  // info in the oop_mask/bit_mask. This can lead to a discrepancy of what
+  // is actually on the expression stack compared to what is given by the
+  // oop_map. We need to use the length reported in the oop_map.
+  int length = oop_mask.expression_stack_size();
+
+  assert(fr().interpreter_frame_expression_stack_size() >= length,
+    "error in expression stack!");
+
+  StackValueCollection* result = new StackValueCollection(length);
+
+  if (0 == length) {
+    return result;
   }
 
   int nof_locals = method()->max_locals();
-  StackValueCollection* result = new StackValueCollection(length);
 
-  InterpreterOopMap oop_mask;
-  // Get oopmap describing oops and int for current bci
-  if (TraceDeoptimization && Verbose) {
-    methodHandle m_h(method());
-    OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
-  } else {
-    method()->mask_for(bci(), &oop_mask);
-  }
   // handle expressions
   for(int i=0; i < length; i++) {
     // Find stack location