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; }