Commit 677e54e2 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Always store current context in the frames context slot.

Change the interpreter to always store the current context in the frame's
context slot instead of the function context. This makes it possible to
restore the correct context during deopt.

BUG=v8:4678,v8:4280
LOG=N

Review URL: https://codereview.chromium.org/1604923002

Cr-Commit-Position: refs/heads/master@{#33477}
parent 12ac11e9
......@@ -1069,8 +1069,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ ldr(kContextRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -1028,8 +1028,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ Ldr(kContextRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -155,8 +155,8 @@ Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
Node* BytecodeGraphBuilder::Environment::LookupRegister(
interpreter::Register the_register) const {
if (the_register.is_function_context()) {
return builder()->GetFunctionContext();
if (the_register.is_current_context()) {
return Context();
} else if (the_register.is_function_closure()) {
return builder()->GetFunctionClosure();
} else if (the_register.is_new_target()) {
......@@ -1034,9 +1034,10 @@ void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
void BytecodeGraphBuilder::VisitPushContext(
const interpreter::BytecodeArrayIterator& iterator) {
Node* context = environment()->LookupAccumulator();
environment()->BindRegister(iterator.GetRegisterOperand(0), context);
environment()->SetContext(context);
Node* new_context = environment()->LookupAccumulator();
environment()->BindRegister(iterator.GetRegisterOperand(0),
environment()->Context());
environment()->SetContext(new_context);
}
......
......@@ -80,7 +80,10 @@ void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; }
Node* InterpreterAssembler::GetContext() { return context_; }
void InterpreterAssembler::SetContext(Node* value) { context_ = value; }
void InterpreterAssembler::SetContext(Node* value) {
StoreRegister(value, interpreter::Register::current_context());
context_ = value;
}
Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; }
......
......@@ -800,8 +800,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ mov(ebx, Operand(ebx, esi, times_pointer_size, 0));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ mov(kContextRegister,
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -1341,7 +1341,7 @@ bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
return false;
}
if (reg.is_function_context() || reg.is_function_closure() ||
if (reg.is_current_context() || reg.is_function_closure() ||
reg.is_new_target()) {
return true;
} else if (reg.is_parameter()) {
......
......@@ -27,19 +27,26 @@ class BytecodeGenerator::ContextScope BASE_EMBEDDED {
: generator_(generator),
scope_(scope),
outer_(generator_->execution_context()),
register_(generator_->NextContextRegister()),
register_(Register::current_context()),
depth_(0),
should_pop_context_(should_pop_context) {
if (outer_) {
depth_ = outer_->depth_ + 1;
generator_->builder()->PushContext(register_);
// Push the outer context into a new context register.
Register outer_context_reg(builder()->first_context_register().index() +
outer_->depth_);
outer_->set_register(outer_context_reg);
generator_->builder()->PushContext(outer_context_reg);
}
generator_->set_execution_context(this);
}
~ContextScope() {
if (outer_ && should_pop_context_) {
DCHECK_EQ(register_.index(), Register::current_context().index());
generator_->builder()->PopContext(outer_->reg());
outer_->set_register(register_);
}
generator_->set_execution_context(outer_);
}
......@@ -67,6 +74,10 @@ class BytecodeGenerator::ContextScope BASE_EMBEDDED {
Register reg() const { return register_; }
private:
const BytecodeArrayBuilder* builder() const { return generator_->builder(); }
void set_register(Register reg) { register_ = reg; }
BytecodeGenerator* generator_;
Scope* scope_;
ContextScope* outer_;
......@@ -1866,7 +1877,7 @@ void BytecodeGenerator::VisitCall(Call* expr) {
DCHECK(Register::AreContiguous(callee, receiver));
Variable* variable = callee_expr->AsVariableProxy()->var();
builder()
->MoveRegister(execution_context()->reg(), context)
->MoveRegister(Register::current_context(), context)
.LoadLiteral(variable->name())
.StoreAccumulatorInRegister(name)
.CallRuntimeForPair(Runtime::kLoadLookupSlot, context, 2, callee);
......@@ -2480,24 +2491,6 @@ void BytecodeGenerator::VisitInScope(Statement* stmt, Scope* scope) {
}
Register BytecodeGenerator::NextContextRegister() const {
if (execution_context() == nullptr) {
// Return the incoming function context for the outermost execution context.
return Register::function_context();
}
Register previous = execution_context()->reg();
if (previous == Register::function_context()) {
// If the previous context was the incoming function context, then the next
// context register is the first local context register.
return builder_.first_context_register();
} else {
// Otherwise use the next local context register.
DCHECK_LT(previous.index(), builder_.last_context_register().index());
return Register(previous.index() + 1);
}
}
LanguageMode BytecodeGenerator::language_mode() const {
return info()->language_mode();
}
......
......@@ -42,7 +42,6 @@ class BytecodeGenerator final : public AstVisitor {
class RegisterAllocationScope;
void MakeBytecodeBody();
Register NextContextRegister() const;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
......
......@@ -294,7 +294,7 @@ std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start,
case interpreter::OperandType::kReg8:
case interpreter::OperandType::kReg16: {
Register reg = DecodeRegister(operand_start, op_type);
if (reg.is_function_context()) {
if (reg.is_current_context()) {
os << "<context>";
} else if (reg.is_function_closure()) {
os << "<closure>";
......@@ -358,7 +358,7 @@ static const int kLastParamRegisterIndex =
-InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize;
static const int kFunctionClosureRegisterIndex =
-InterpreterFrameConstants::kFunctionFromRegisterPointer / kPointerSize;
static const int kFunctionContextRegisterIndex =
static const int kCurrentContextRegisterIndex =
-InterpreterFrameConstants::kContextFromRegisterPointer / kPointerSize;
static const int kNewTargetRegisterIndex =
-InterpreterFrameConstants::kNewTargetFromRegisterPointer / kPointerSize;
......@@ -397,13 +397,13 @@ bool Register::is_function_closure() const {
}
Register Register::function_context() {
return Register(kFunctionContextRegisterIndex);
Register Register::current_context() {
return Register(kCurrentContextRegisterIndex);
}
bool Register::is_function_context() const {
return index() == kFunctionContextRegisterIndex;
bool Register::is_current_context() const {
return index() == kCurrentContextRegisterIndex;
}
......
......@@ -308,9 +308,9 @@ class Register {
static Register function_closure();
bool is_function_closure() const;
// Returns the register for the function's outer context.
static Register function_context();
bool is_function_context() const;
// Returns the register which holds the current context object.
static Register current_context();
bool is_current_context() const;
// Returns the register for the incoming new target value.
static Register new_target();
......
......@@ -816,12 +816,14 @@ void Interpreter::DoKeyedStoreICStrictWide(
// PushContext <context>
//
// Pushes the accumulator as the current context, and saves it in <context>
// Saves the current context in <context>, and pushes the accumulator as the
// new current context.
void Interpreter::DoPushContext(compiler::InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
Node* context = __ GetAccumulator();
__ SetContext(context);
__ StoreRegister(context, reg_index);
Node* new_context = __ GetAccumulator();
Node* old_context = __ GetContext();
__ StoreRegister(old_context, reg_index);
__ SetContext(new_context);
__ Dispatch();
}
......
......@@ -1058,8 +1058,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ lw(kContextRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -1049,8 +1049,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ ld(kContextRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -1058,8 +1058,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Operand(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ LoadP(kContextRegister,
MemOperand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -821,8 +821,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ movp(kContextRegister,
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -801,8 +801,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ mov(ebx, Operand(ebx, esi, times_pointer_size, 0));
// Get the context from the frame.
// TODO(rmcilroy): Update interpreter frame to expect current context at the
// context slot instead of the function context.
__ mov(kContextRegister,
Operand(kInterpreterRegisterFileRegister,
InterpreterFrameConstants::kContextFromRegisterPointer));
......
......@@ -2213,7 +2213,7 @@ TEST(BreakableBlocks) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::function_context().index();
int context = Register::current_context().index();
ExpectedSnippet<InstanceType> snippets[] = {
{"var x = 0;\n"
......@@ -2309,15 +2309,15 @@ TEST(BreakableBlocks) {
B(CallRuntime), U16(Runtime::kPushBlockContext), R(3), U8(2), //
B(PushContext), R(2), //
B(LdaTheHole), //
B(StaContextSlot), R(2), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(CreateClosure), U8(1), U8(0), //
B(Star), R(0), //
B(LdaSmi8), U8(10), //
B(StaContextSlot), R(2), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(Ldar), R(0), //
B(Star), R(1), //
B(Jump), U8(2), //
B(PopContext), R(context), //
B(PopContext), R(2), //
B(LdaUndefined), //
B(Return), //
},
......@@ -2342,9 +2342,9 @@ TEST(BreakableBlocks) {
U8(1), //
B(PushContext), R(2), //
B(LdaTheHole), //
B(StaContextSlot), R(2), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(2), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(LdaConstant), U8(0), //
B(Star), R(4), //
B(Ldar), R(closure), //
......@@ -2352,22 +2352,22 @@ TEST(BreakableBlocks) {
B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2), //
B(PushContext), R(3), //
B(LdaTheHole), //
B(StaContextSlot), R(3), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(CreateClosure), U8(1), U8(0), //
B(Star), R(0), //
B(LdaSmi8), U8(2), //
B(StaContextSlot), R(3), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(Ldar), R(0), //
B(Star), R(1), //
B(LdaContextSlot), R(3), U8(4), //
B(LdaContextSlot), R(context), U8(4), //
B(JumpIfToBooleanFalse), U8(6), //
B(PopContext), R(2), //
B(PopContext), R(3), //
B(Jump), U8(9), //
B(LdaSmi8), U8(3), //
B(StaContextSlot), R(3), U8(4), //
B(PopContext), R(2), //
B(StaContextSlot), R(context), U8(4), //
B(PopContext), R(3), //
B(LdaSmi8), U8(4), //
B(StaContextSlot), R(2), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(LdaUndefined), //
B(Return), //
},
......@@ -2389,7 +2389,7 @@ TEST(BasicLoops) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::function_context().index();
int context = Register::current_context().index();
ExpectedSnippet<InstanceType> snippets[] = {
{"var x = 0;\n"
......@@ -3027,23 +3027,23 @@ TEST(BasicLoops) {
B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2), //
B(PushContext), R(3), //
B(LdaTheHole), //
B(StaContextSlot), R(3), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(CreateClosure), U8(1), U8(0), //
B(Star), R(0), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(3), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(Ldar), R(0), //
B(Star), R(2), //
B(LdaContextSlot), R(3), U8(4), //
B(LdaContextSlot), R(context), U8(4), //
B(JumpIfToBooleanFalse), U8(6), //
B(PopContext), R(context), //
B(PopContext), R(3), //
B(Jump), U8(-44), //
B(LdaContextSlot), R(3), U8(4), //
B(LdaContextSlot), R(context), U8(4), //
B(ToNumber), //
B(Star), R(4), //
B(Inc), //
B(StaContextSlot), R(3), U8(4), //
B(PopContext), R(context), //
B(StaContextSlot), R(context), U8(4), //
B(PopContext), R(3), //
B(Jump), U8(-58), //
B(LdaUndefined), //
B(Return), //
......@@ -3353,6 +3353,7 @@ TEST(Delete) {
int deep_elements_flags =
ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
ExpectedSnippet<InstanceType> snippets[] = {
......@@ -3418,9 +3419,9 @@ TEST(Delete) {
B(PushContext), R(0), //
B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), //
B(Star), R(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(1), U8(0), //
B(LdaContextSlot), R(0), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Star), R(1), //
B(LdaSmi8), U8(1), //
B(DeletePropertyStrict), R(1), //
......@@ -3450,7 +3451,7 @@ TEST(GlobalDelete) {
BytecodeGeneratorHelper helper;
Zone zone;
int context = Register::function_context().index();
int context = Register::current_context().index();
int native_context_index = Context::NATIVE_CONTEXT_INDEX;
int global_context_index = Context::EXTENSION_INDEX;
FeedbackVectorSpec feedback_spec(&zone);
......@@ -4268,7 +4269,6 @@ TEST(TryCatch) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::function_context().index();
ExpectedSnippet<const char*> snippets[] = {
{"try { return 1; } catch(e) { return 2; }",
......@@ -4286,7 +4286,7 @@ TEST(TryCatch) {
B(CallRuntime), U16(Runtime::kPushCatchContext), R(2), U8(3), //
B(PushContext), R(0), //
B(LdaSmi8), U8(2), //
B(PopContext), R(context), //
B(PopContext), R(0), //
B(Return), //
// TODO(mstarzinger): Potential optimization, elide next bytes.
B(LdaUndefined), //
......@@ -4311,7 +4311,7 @@ TEST(TryCatch) {
B(Star), R(5), //
B(CallRuntime), U16(Runtime::kPushCatchContext), R(3), U8(3), //
B(PushContext), R(1), //
B(PopContext), R(context), //
B(PopContext), R(1), //
B(LdaSmi8), U8(2), //
B(Star), R(0), //
B(Jump), U8(25), //
......@@ -4324,7 +4324,7 @@ TEST(TryCatch) {
B(PushContext), R(1), //
B(LdaSmi8), U8(3), //
B(Star), R(0), //
B(PopContext), R(context), //
B(PopContext), R(1), //
B(LdaUndefined), //
B(Return), //
},
......@@ -4347,7 +4347,6 @@ TEST(TryFinally) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::function_context().index();
ExpectedSnippet<const char*> snippets[] = {
{"var a = 1; try { a = 2; } finally { a = 3; }",
......@@ -4399,7 +4398,7 @@ TEST(TryFinally) {
B(PushContext), R(1), //
B(LdaSmi8), U8(20), //
B(Star), R(0), //
B(PopContext), R(context), //
B(PopContext), R(1), //
B(LdaSmi8), U8(-1), //
B(Star), R(2), //
B(Jump), U8(7), //
......@@ -4440,7 +4439,7 @@ TEST(TryFinally) {
B(PushContext), R(1), //
B(LdaSmi8), U8(2), //
B(Star), R(0), //
B(PopContext), R(context), //
B(PopContext), R(1), //
B(Jump), U8(25), //
B(Star), R(7), //
B(LdaConstant), U8(0), //
......@@ -4451,7 +4450,7 @@ TEST(TryFinally) {
B(PushContext), R(1), //
B(LdaSmi8), U8(20), //
B(Star), R(0), //
B(PopContext), R(context), //
B(PopContext), R(1), //
B(LdaSmi8), U8(-1), //
B(Star), R(2), //
B(Jump), U8(7), //
......@@ -4623,7 +4622,7 @@ TEST(ContextVariables) {
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
int closure = Register::function_closure().index();
int context = Register::function_context().index();
int context = Register::current_context().index();
int new_target = Register::new_target().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
......@@ -4656,7 +4655,7 @@ TEST(ContextVariables) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Return), //
},
......@@ -4671,9 +4670,9 @@ TEST(ContextVariables) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(LdaSmi8), U8(2), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(CreateClosure), U8(0), U8(0), //
B(Return), //
},
......@@ -4692,7 +4691,7 @@ TEST(ContextVariables) {
B(CreateClosure), U8(0), U8(0), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot)), //
B(LdaContextSlot), R(0), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Return), //
},
1,
......@@ -4706,9 +4705,9 @@ TEST(ContextVariables) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(LdaTheHole), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(LdaConstant), U8(0), //
B(Star), R(2), //
B(Ldar), R(closure), //
......@@ -4716,11 +4715,11 @@ TEST(ContextVariables) {
B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2), //
B(PushContext), R(1), //
B(LdaTheHole), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(LdaSmi8), U8(2), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(1), U8(0), //
B(PopContext), R(context), //
B(PopContext), R(0), //
B(Return), //
},
2,
......@@ -4739,22 +4738,22 @@ TEST(ContextVariables) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateUnmappedArguments), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(first_context_slot + 2), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
REPEAT_249(COMMA, //
B(LdaZero), //
B(StaContextSlot), R(0), U8(wide_slot++)), //
B(StaContextSlot), R(context), U8(wide_slot++)), //
B(LdaUndefined), //
B(Star), R(2), //
B(LdaGlobalStrict), U8(0), U8(1), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(0), U8(0), //
B(LdaSmi8), U8(100), //
B(StaContextSlotWide), R(0), U16(256), //
B(LdaContextSlotWide), R(0), U16(256), //
B(StaContextSlotWide), R(context), U16(256), //
B(LdaContextSlotWide), R(context), U16(256), //
B(Return), //
},
1,
......@@ -4774,6 +4773,7 @@ TEST(ContextParameters) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
ExpectedSnippet<InstanceType> snippets[] = {
......@@ -4786,7 +4786,7 @@ TEST(ContextParameters) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(Ldar), R(helper.kLastParamIndex), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Return), //
},
......@@ -4801,10 +4801,10 @@ TEST(ContextParameters) {
R(closure), U8(1), //
B(PushContext), R(1), //
B(Ldar), R(helper.kLastParamIndex), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(LdaContextSlot), R(1), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Return), //
},
1,
......@@ -4818,9 +4818,9 @@ TEST(ContextParameters) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(Ldar), R(helper.kLastParamIndex - 3), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(helper.kLastParamIndex -1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Return), //
},
......@@ -4835,7 +4835,7 @@ TEST(ContextParameters) {
R(closure), U8(1), //
B(PushContext), R(0), //
B(Ldar), R(helper.kLastParamIndex), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Return), //
},
......@@ -4855,7 +4855,7 @@ TEST(OuterContextVariables) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
int context = Register::function_context().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
ExpectedSnippet<InstanceType> snippets[] = {
......@@ -4931,6 +4931,7 @@ TEST(CountOperators) {
i::NewTypeFeedbackVector(helper.isolate(), &store_feedback_spec);
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
int object_literal_flags =
......@@ -5084,13 +5085,13 @@ TEST(CountOperators) {
U8(1), //
B(PushContext), R(1), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(LdaContextSlot), R(1), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(ToNumber), //
B(Inc), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(Return), //
},
1,
......@@ -5104,14 +5105,14 @@ TEST(CountOperators) {
U8(1), //
B(PushContext), R(1), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(Star), R(0), //
B(LdaContextSlot), R(1), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(ToNumber), //
B(Star), R(2), //
B(Dec), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(Ldar), R(2), //
B(Return), //
},
......@@ -5235,6 +5236,7 @@ TEST(CompoundExpressions) {
Zone zone;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
FeedbackVectorSpec feedback_spec(&zone);
......@@ -5325,13 +5327,13 @@ TEST(CompoundExpressions) {
U8(1), //
B(PushContext), R(0), //
B(LdaSmi8), U8(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateClosure), U8(0), U8(0), //
B(LdaContextSlot), R(0), U8(first_context_slot), //
B(LdaContextSlot), R(context), U8(first_context_slot), //
B(Star), R(1), //
B(LdaSmi8), U8(24), //
B(BitwiseOr), R(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(LdaUndefined), //
B(Return), //
},
......@@ -5404,6 +5406,7 @@ TEST(CreateArguments) {
Zone zone;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
FeedbackVectorSpec feedback_spec(&zone);
......@@ -5452,7 +5455,7 @@ TEST(CreateArguments) {
U8(1), //
B(PushContext), R(1), //
B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(Star), R(0), //
B(Star), R(2), //
......@@ -5469,11 +5472,11 @@ TEST(CreateArguments) {
U8(1), //
B(PushContext), R(1), //
B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 2), //
B(StaContextSlot), R(1), U8(first_context_slot + 2), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex - 1), //
B(StaContextSlot), R(1), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(BytecodeGeneratorHelper::kLastParamIndex), //
B(StaContextSlot), R(1), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(Star), R(0), //
B(Return), //
......@@ -6793,6 +6796,7 @@ TEST(Eval) {
Zone zone;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int new_target = Register::new_target().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
......@@ -6807,12 +6811,12 @@ TEST(Eval) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(first_context_slot + 2), //
B(Mov), R(0), R(3), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(0), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......@@ -6849,6 +6853,7 @@ TEST(LookupSlot) {
BytecodeGeneratorHelper helper;
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int first_context_slot = Context::MIN_CONTEXT_SLOTS;
int new_target = Register::new_target().index();
......@@ -6862,12 +6867,12 @@ TEST(LookupSlot) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(first_context_slot + 2), //
B(Mov), R(0), R(3), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(0), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......@@ -6899,12 +6904,12 @@ TEST(LookupSlot) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(first_context_slot + 2), //
B(Mov), R(0), R(3), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(0), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......@@ -6937,14 +6942,14 @@ TEST(LookupSlot) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(first_context_slot), //
B(StaContextSlot), R(context), U8(first_context_slot), //
B(CreateMappedArguments), //
B(StaContextSlot), R(0), U8(first_context_slot + 1), //
B(StaContextSlot), R(context), U8(first_context_slot + 1), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(first_context_slot + 2), //
B(StaContextSlot), R(context), U8(first_context_slot + 2), //
B(LdaSmi8), U8(20), //
B(StaLookupSlotSloppy), U8(0), //
B(Mov), R(0), R(3), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(1), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......@@ -6990,6 +6995,7 @@ TEST(CallLookupSlot) {
i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
int closure = Register::function_closure().index();
int context = Register::current_context().index();
int new_target = Register::new_target().index();
ExpectedSnippet<InstanceType> snippets[] = {
......@@ -7002,14 +7008,14 @@ TEST(CallLookupSlot) {
U8(1), //
B(PushContext), R(0), //
B(Ldar), THIS(1), //
B(StaContextSlot), R(0), U8(4), //
B(StaContextSlot), R(context), U8(4), //
B(CreateMappedArguments), //
B(StaContextSlot), R(0), U8(5), //
B(StaContextSlot), R(context), U8(5), //
B(Ldar), R(new_target), //
B(StaContextSlot), R(0), U8(6), //
B(StaContextSlot), R(context), U8(6), //
B(CreateClosure), U8(0), U8(0), //
B(StaLookupSlotSloppy), U8(1), //
B(Mov), R(0), R(3), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(2), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......@@ -7027,7 +7033,7 @@ TEST(CallLookupSlot) {
U8(5), //
B(Star), R(1), //
B(Call), R(1), R(2), U8(1), U8(0), //
B(Mov), R(0), R(3), //
B(Mov), R(context), R(3), //
B(LdaConstant), U8(1), //
B(Star), R(4), //
B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), //
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
function outer(y) {
function inner() {
var x = 10;
(function() {
// Access x from inner function to force it to be context allocated.
x = 20;
%DeoptimizeFunction(inner);
})();
// Variable y should be read from the outer context.
return y;
};
%OptimizeFunctionOnNextCall(inner);
return inner();
}
assertEquals(30, outer(30));
......@@ -409,6 +409,16 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) {
}
TARGET_TEST_F(InterpreterAssemblerTest, GetSetContext) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
Node* context_node = m.Int32Constant(100);
m.SetContext(context_node);
EXPECT_THAT(m.GetContext(), context_node);
}
}
TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerForTest m(this, bytecode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment