diff src/share/vm/c1/c1_LinearScan.cpp @ 1819:f02a8bbe6ed4

6986046: C1 valuestack cleanup Summary: fixes an historical oddity in C1 with inlining where all of the expression stacks are kept in the topmost ValueStack instead of being in their respective ValueStacks. Reviewed-by: never Contributed-by: Christian Wimmer <cwimmer@uci.edu>
author roland
date Tue, 29 Dec 2009 19:08:54 +0100
parents 87b64980e2f1
children f95d63e2154a
line wrap: on
line diff
--- a/src/share/vm/c1/c1_LinearScan.cpp	Wed Sep 22 23:51:03 2010 -0700
+++ b/src/share/vm/c1/c1_LinearScan.cpp	Tue Dec 29 19:08:54 2009 +0100
@@ -2274,8 +2274,8 @@
 }
 
 void check_stack_depth(CodeEmitInfo* info, int stack_end) {
-  if (info->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) {
-    Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->bci());
+  if (info->stack()->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) {
+    Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci());
     switch (code) {
       case Bytecodes::_ifnull    : // fall through
       case Bytecodes::_ifnonnull : // fall through
@@ -2379,7 +2379,7 @@
 
   // add oops from lock stack
   assert(info->stack() != NULL, "CodeEmitInfo must always have a stack");
-  int locks_count = info->stack()->locks_size();
+  int locks_count = info->stack()->total_locks_size();
   for (int i = 0; i < locks_count; i++) {
     map->set_oop(frame_map()->monitor_object_regname(i));
   }
@@ -2762,19 +2762,13 @@
 }
 
 
-IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state, int cur_bci, int stack_end, int locks_end) {
+IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state) {
   IRScopeDebugInfo* caller_debug_info = NULL;
-  int stack_begin, locks_begin;
-
-  ValueStack* caller_state = cur_scope->caller_state();
+
+  ValueStack* caller_state = cur_state->caller_state();
   if (caller_state != NULL) {
     // process recursively to compute outermost scope first
-    stack_begin = caller_state->stack_size();
-    locks_begin = caller_state->locks_size();
-    caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state, cur_scope->caller_bci(), stack_begin, locks_begin);
-  } else {
-    stack_begin = 0;
-    locks_begin = 0;
+    caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state);
   }
 
   // initialize these to null.
@@ -2785,7 +2779,7 @@
   GrowableArray<MonitorValue*>* monitors    = NULL;
 
   // describe local variable values
-  int nof_locals = cur_scope->method()->max_locals();
+  int nof_locals = cur_state->locals_size();
   if (nof_locals > 0) {
     locals = new GrowableArray<ScopeValue*>(nof_locals);
 
@@ -2800,45 +2794,41 @@
     }
     assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals");
     assert(locals->length() == cur_state->locals_size(), "wrong number of locals");
-  }
-
+  } else if (cur_scope->method()->max_locals() > 0) {
+    assert(cur_state->kind() == ValueStack::EmptyExceptionState, "should be");
+    nof_locals = cur_scope->method()->max_locals();
+    locals = new GrowableArray<ScopeValue*>(nof_locals);
+    for(int i = 0; i < nof_locals; i++) {
+      locals->append(&_illegal_value);
+    }
+  }
 
   // describe expression stack
-  //
-  // When we inline methods containing exception handlers, the
-  // "lock_stacks" are changed to preserve expression stack values
-  // in caller scopes when exception handlers are present. This
-  // can cause callee stacks to be smaller than caller stacks.
-  if (stack_end > innermost_state->stack_size()) {
-    stack_end = innermost_state->stack_size();
-  }
-
-
-
-  int nof_stack = stack_end - stack_begin;
+  int nof_stack = cur_state->stack_size();
   if (nof_stack > 0) {
     expressions = new GrowableArray<ScopeValue*>(nof_stack);
 
-    int pos = stack_begin;
-    while (pos < stack_end) {
-      Value expression = innermost_state->stack_at_inc(pos);
+    int pos = 0;
+    while (pos < nof_stack) {
+      Value expression = cur_state->stack_at_inc(pos);
       append_scope_value(op_id, expression, expressions);
 
-      assert(expressions->length() + stack_begin == pos, "must match");
-    }
+      assert(expressions->length() == pos, "must match");
+    }
+    assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries");
   }
 
   // describe monitors
-  assert(locks_begin <= locks_end, "error in scope iteration");
-  int nof_locks = locks_end - locks_begin;
+  int nof_locks = cur_state->locks_size();
   if (nof_locks > 0) {
+    int lock_offset = cur_state->caller_state() != NULL ? cur_state->caller_state()->total_locks_size() : 0;
     monitors = new GrowableArray<MonitorValue*>(nof_locks);
-    for (int i = locks_begin; i < locks_end; i++) {
-      monitors->append(location_for_monitor_index(i));
-    }
-  }
-
-  return new IRScopeDebugInfo(cur_scope, cur_bci, locals, expressions, monitors, caller_debug_info);
+    for (int i = 0; i < nof_locks; i++) {
+      monitors->append(location_for_monitor_index(lock_offset + i));
+    }
+  }
+
+  return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info);
 }
 
 
@@ -2850,17 +2840,14 @@
 
   assert(innermost_scope != NULL && innermost_state != NULL, "why is it missing?");
 
-  int stack_end = innermost_state->stack_size();
-  int locks_end = innermost_state->locks_size();
-
-  DEBUG_ONLY(check_stack_depth(info, stack_end));
+  DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size()));
 
   if (info->_scope_debug_info == NULL) {
     // compute debug information
-    info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state, info->bci(), stack_end, locks_end);
+    info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state);
   } else {
     // debug information already set. Check that it is correct from the current point of view
-    DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state, info->bci(), stack_end, locks_end)));
+    DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state)));
   }
 }