[interpreter] Add CreateWithContext bytecode

Generates a JSCreateWithContext node for TurboFan to optimize.

BUG=v8:4280
LOG=n

Review-Url: https://codereview.chromium.org/2255793002
Cr-Commit-Position: refs/heads/master@{#38723}
This commit is contained in:
klaasb 2016-08-18 08:14:43 -07:00 committed by Commit bot
parent 978347e079
commit 078842026e
8 changed files with 41 additions and 9 deletions

View File

@ -942,6 +942,15 @@ void BytecodeGraphBuilder::VisitCreateFunctionContext() {
environment()->BindAccumulator(context); environment()->BindAccumulator(context);
} }
void BytecodeGraphBuilder::VisitCreateWithContext() {
Node* object =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
const Operator* op = javascript()->CreateWithContext();
Node* context = NewNode(op, object, environment()->LookupAccumulator());
environment()->BindAccumulator(context);
}
void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) { void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
FrameStateBeforeAndAfter states(this); FrameStateBeforeAndAfter states(this);
const Operator* op = javascript()->CreateArguments(type); const Operator* op = javascript()->CreateArguments(type);

View File

@ -350,6 +350,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(int slots) {
return *this; return *this;
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateWithContext(Register object) {
Output(Bytecode::kCreateWithContext, RegisterOperand(object));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
CreateArgumentsType type) { CreateArgumentsType type) {
// TODO(rmcilroy): Consider passing the type as a bytecode operand rather // TODO(rmcilroy): Consider passing the type as a bytecode operand rather

View File

@ -142,6 +142,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
// Create a new context with size |slots|. // Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots); BytecodeArrayBuilder& CreateFunctionContext(int slots);
// Creates a new context for a with-statement with the |object| in a register
// and the closure in the accumulator.
BytecodeArrayBuilder& CreateWithContext(Register object);
// Create a new arguments object in the accumulator. // Create a new arguments object in the accumulator.
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type); BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);

View File

@ -3219,14 +3219,11 @@ void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
void BytecodeGenerator::VisitNewLocalWithContext() { void BytecodeGenerator::VisitNewLocalWithContext() {
AccumulatorResultScope accumulator_execution_result(this); AccumulatorResultScope accumulator_execution_result(this);
register_allocator()->PrepareForConsecutiveAllocations(2); Register extension_object = register_allocator()->NewRegister();
Register extension_object = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NextConsecutiveRegister();
builder()->CastAccumulatorToJSObject(extension_object); builder()->CastAccumulatorToJSObject(extension_object);
VisitFunctionClosureForContext(); VisitFunctionClosureForContext();
builder()->StoreAccumulatorInRegister(closure).CallRuntime( builder()->CreateWithContext(extension_object);
Runtime::kPushWithContext, extension_object, 2);
execution_result()->SetResultInAccumulator(); execution_result()->SetResultInAccumulator();
} }

View File

@ -237,6 +237,7 @@ namespace interpreter {
V(CreateBlockContext, AccumulatorUse::kReadWrite, OperandType::kIdx) \ V(CreateBlockContext, AccumulatorUse::kReadWrite, OperandType::kIdx) \
/* TODO(klaasb) rename Idx or add unsigned Imm OperandType? */ \ /* TODO(klaasb) rename Idx or add unsigned Imm OperandType? */ \
V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx) \ V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg) \
\ \
/* Arguments allocation */ \ /* Arguments allocation */ \
V(CreateMappedArguments, AccumulatorUse::kWrite) \ V(CreateMappedArguments, AccumulatorUse::kWrite) \

View File

@ -1821,6 +1821,20 @@ void Interpreter::DoCreateFunctionContext(InterpreterAssembler* assembler) {
__ Dispatch(); __ Dispatch();
} }
// CreateWithContext <register>
//
// Creates a new context for a with-statement with the object in |register| and
// the closure in the accumulator.
void Interpreter::DoCreateWithContext(InterpreterAssembler* assembler) {
Node* reg_index = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(reg_index);
Node* closure = __ GetAccumulator();
Node* context = __ GetContext();
__ SetAccumulator(
__ CallRuntime(Runtime::kPushWithContext, context, object, closure));
__ Dispatch();
}
// CreateMappedArguments // CreateMappedArguments
// //
// Creates a new mapped arguments object. // Creates a new mapped arguments object.

View File

@ -11,16 +11,16 @@ wrap: yes
snippet: " snippet: "
with ({x:42}) { return x; } with ({x:42}) { return x; }
" "
frame size: 4 frame size: 3
parameter count: 1 parameter count: 1
bytecode array length: 25 bytecode array length: 21
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1), /* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), R(1),
B(Ldar), R(1), B(Ldar), R(1),
B(ToObject), R(2), B(ToObject), R(2),
B(Mov), R(closure), R(3), B(Ldar), R(closure),
B(CallRuntime), U16(Runtime::kPushWithContext), R(2), U8(2), B(CreateWithContext), R(2),
B(PushContext), R(0), B(PushContext), R(0),
/* 50 S> */ B(LdaLookupSlot), U8(1), /* 50 S> */ B(LdaLookupSlot), U8(1),
B(PopContext), R(0), B(PopContext), R(0),

View File

@ -107,6 +107,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit create context operation. // Emit create context operation.
builder.CreateFunctionContext(1); builder.CreateFunctionContext(1);
builder.CreateWithContext(reg);
// Emit literal creation operations. // Emit literal creation operations.
builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0) builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
.CreateArrayLiteral(factory->NewFixedArray(1), 0, 0) .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)