ValueStack* ValueStack::push_scope(IRScope* scope) {
  assert(scope->caller() == _scope, "scopes must have caller/callee relationship");
  ValueStack* res = new ValueStack(scope,
                                   scope->method()->max_locals(),
                                   max_stack_size() + scope->method()->max_stack());
  // Preserves stack and monitors.
  res->_stack.appendAll(&_stack);
  res->_locks.appendAll(&_locks);
  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
  return res;
}
ValueStack* ValueStack::pop_scope(bool should_eliminate_stores, int bci) {
  assert(_scope->caller() != NULL, "scope must have caller");
  IRScope* scope = _scope->caller();
  int max_stack = max_stack_size() - _scope->method()->max_stack();
  assert(max_stack >= 0, "stack underflow");
  ValueStack* res = new ValueStack(scope,
                                   scope->method()->max_locals(),
                                   max_stack);
  // Preserves stack and monitors. Restores local and store state from caller scope.
  res->_stack.appendAll(&_stack);
  res->_locks.appendAll(&_locks);
  ValueStack* caller = caller_state();
  if (caller != NULL) {
    for (int i = 0; i < caller->_locals.length(); i++) {
      res->_locals.at_put(i, caller->_locals.at(i));
      res->_stores.at_put(i, caller->_stores.at(i));
    }
    assert(res->_locals.length() == res->scope()->method()->max_locals(), "just checking");
    assert(res->_stores.length() == res->scope()->method()->max_locals(), "just checking");
  }
  assert(res->_stack.size() <= res->max_stack_size(), "stack overflow");
  if (EliminateStores && should_eliminate_stores) eliminate_stores(bci);
  return res;
}