[interpreter] Add CreateFunctionContext bytecode

Add a new bytecode to create a function context. The handler inlines
FastNewFunctionContextStub.

BUG=v8:4280
LOG=n

Review-Url: https://codereview.chromium.org/2187523002
Cr-Commit-Position: refs/heads/master@{#38301}
This commit is contained in:
klaasb 2016-08-03 07:41:47 -07:00 committed by Commit bot
parent 588eefef6d
commit 8097eeb9f2
23 changed files with 137 additions and 89 deletions

View File

@ -4553,16 +4553,14 @@ void FastNewClosureStub::GenerateAssembly(CodeStubAssembler* assembler) const {
Generate(assembler, assembler->Parameter(0), assembler->Parameter(1)));
}
void FastNewFunctionContextStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
// static
compiler::Node* FastNewFunctionContextStub::Generate(
CodeStubAssembler* assembler, compiler::Node* function,
compiler::Node* slots, compiler::Node* context) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
Node* function = assembler->Parameter(Descriptor::kFunction);
Node* slots = assembler->Parameter(FastNewFunctionContextDescriptor::kSlots);
Node* context = assembler->Parameter(Descriptor::kContext);
Node* min_context_slots =
assembler->Int32Constant(Context::MIN_CONTEXT_SLOTS);
Node* length = assembler->Int32Add(slots, min_context_slots);
@ -4573,9 +4571,10 @@ void FastNewFunctionContextStub::GenerateAssembly(
// Create a new closure from the given function info in new space
Node* function_context = assembler->Allocate(size);
Isolate* isolate = assembler->isolate();
assembler->StoreMapNoWriteBarrier(
function_context,
assembler->HeapConstant(isolate()->factory()->function_context_map()));
assembler->HeapConstant(isolate->factory()->function_context_map()));
assembler->StoreObjectFieldNoWriteBarrier(function_context,
Context::kLengthOffset,
assembler->SmiFromWord32(length));
@ -4619,7 +4618,17 @@ void FastNewFunctionContextStub::GenerateAssembly(
}
assembler->Bind(&after_loop);
assembler->Return(function_context);
return function_context;
}
void FastNewFunctionContextStub::GenerateAssembly(
CodeStubAssembler* assembler) const {
typedef compiler::Node Node;
Node* function = assembler->Parameter(Descriptor::kFunction);
Node* slots = assembler->Parameter(FastNewFunctionContextDescriptor::kSlots);
Node* context = assembler->Parameter(Descriptor::kContext);
assembler->Return(Generate(assembler, function, slots, context));
}
void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) {

View File

@ -1082,6 +1082,11 @@ class FastNewFunctionContextStub final : public TurboFanCodeStub {
explicit FastNewFunctionContextStub(Isolate* isolate)
: TurboFanCodeStub(isolate) {}
static compiler::Node* Generate(CodeStubAssembler* assembler,
compiler::Node* function,
compiler::Node* slots,
compiler::Node* context);
private:
DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewFunctionContext);
DEFINE_TURBOFAN_CODE_STUB(FastNewFunctionContext, TurboFanCodeStub);

View File

@ -896,6 +896,13 @@ void BytecodeGraphBuilder::VisitCreateClosure() {
environment()->BindAccumulator(closure);
}
void BytecodeGraphBuilder::VisitCreateFunctionContext() {
uint32_t slots = bytecode_iterator().GetIndexOperand(0);
const Operator* op = javascript()->CreateFunctionContext(slots);
Node* context = NewNode(op, GetFunctionClosure());
environment()->BindAccumulator(context);
}
void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
FrameStateBeforeAndAfter states(this);
const Operator* op = javascript()->CreateArguments(type);

View File

@ -337,6 +337,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(int slots) {
Output(Bytecode::kCreateFunctionContext, UnsignedOperand(slots));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
CreateArgumentsType type) {
// TODO(rmcilroy): Consider passing the type as a bytecode operand rather

View File

@ -135,6 +135,9 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& CreateClosure(Handle<SharedFunctionInfo> shared_info,
int flags);
// Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots);
// Create a new arguments object in the accumulator.
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);

View File

@ -3010,8 +3010,8 @@ void BytecodeGenerator::VisitNewLocalFunctionContext() {
.StoreAccumulatorInRegister(scope_info)
.CallRuntime(Runtime::kNewScriptContext, closure, 2);
} else {
builder()->CallRuntime(Runtime::kNewFunctionContext,
Register::function_closure(), 1);
int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
builder()->CreateFunctionContext(slot_count);
}
execution_result()->SetResultInAccumulator();
}

View File

@ -227,6 +227,10 @@ namespace interpreter {
V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx, \
OperandType::kFlag8) \
\
/* Context allocation */ \
/* TODO(klaasb) rename Idx or add unsigned Imm OperandType? */ \
V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kIdx) \
\
/* Arguments allocation */ \
V(CreateMappedArguments, AccumulatorUse::kWrite) \
V(CreateUnmappedArguments, AccumulatorUse::kWrite) \

View File

@ -1717,6 +1717,18 @@ void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
}
}
// CreateFunctionContext <slots>
//
// Creates a new context with number of |slots| for the function closure.
void Interpreter::DoCreateFunctionContext(InterpreterAssembler* assembler) {
Node* closure = __ LoadRegister(Register::function_closure());
Node* slots = __ BytecodeOperandIdx(0);
Node* context = __ GetContext();
__ SetAccumulator(
FastNewFunctionContextStub::Generate(assembler, closure, slots, context));
__ Dispatch();
}
// CreateMappedArguments
//
// Creates a new mapped arguments object.

View File

@ -151,9 +151,9 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 130
bytecode array length: 127
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(2),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 89
bytecode array length: 86
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),

View File

@ -124,9 +124,9 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 126
bytecode array length: 123
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(2),
B(PushContext), R(3),
B(LdaTheHole),
B(Star), R(2),
@ -196,9 +196,9 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 75
bytecode array length: 72
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(3),
B(LdaTheHole),
B(Star), R(2),

View File

@ -111,9 +111,9 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 28
bytecode array length: 25
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 24
bytecode array length: 21
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -39,9 +39,9 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 37
bytecode array length: 34
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -70,9 +70,9 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 50
bytecode array length: 47
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -106,9 +106,9 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 52
bytecode array length: 49
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),

View File

@ -15,9 +15,9 @@ snippet: "
"
frame size: 1
parameter count: 2
bytecode array length: 17
bytecode array length: 14
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
B(Ldar), R(arg0),
B(StaContextSlot), R(context), U8(4),
@ -38,9 +38,9 @@ snippet: "
"
frame size: 2
parameter count: 2
bytecode array length: 22
bytecode array length: 19
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(Ldar), R(arg0),
B(StaContextSlot), R(context), U8(4),
@ -63,9 +63,9 @@ snippet: "
"
frame size: 1
parameter count: 5
bytecode array length: 22
bytecode array length: 19
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
B(Ldar), R(arg0),
B(StaContextSlot), R(context), U8(5),
@ -88,9 +88,9 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 17
bytecode array length: 14
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 10 E> */ B(StackCheck),
/* 26 S> */ B(Ldar), R(this),

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 12
bytecode array length: 9
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 41 S> */ B(CreateClosure), U8(0), U8(2),
@ -33,9 +33,9 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 17
bytecode array length: 14
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
@ -55,9 +55,9 @@ snippet: "
"
frame size: 1
parameter count: 1
bytecode array length: 22
bytecode array length: 19
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
@ -79,9 +79,9 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 24
bytecode array length: 21
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 41 S> */ B(LdrUndefined), R(2),
@ -105,9 +105,9 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 46
bytecode array length: 43
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -392,9 +392,9 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 1043
bytecode array length: 1040
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(253),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),

View File

@ -203,9 +203,9 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 26
bytecode array length: 23
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
@ -229,9 +229,9 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 30
bytecode array length: 27
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),

View File

@ -76,9 +76,9 @@ snippet: "
"
frame size: 2
parameter count: 2
bytecode array length: 21
bytecode array length: 18
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(Ldar), R(arg0),
B(StaContextSlot), R(context), U8(4),
@ -101,9 +101,9 @@ snippet: "
"
frame size: 2
parameter count: 4
bytecode array length: 28
bytecode array length: 25
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(1),
B(Ldar), R(arg0),
B(StaContextSlot), R(context), U8(6),

View File

@ -103,9 +103,9 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 29
bytecode array length: 26
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
/* 30 E> */ B(StackCheck),
/* 56 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1),

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 69
bytecode array length: 66
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),

View File

@ -15,7 +15,7 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 200
bytecode array length: 197
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(20),
@ -23,11 +23,11 @@ bytecodes: [
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1),
B(JumpIfTrue), U8(56),
B(JumpIfTrue), U8(53),
B(LdaSmi), U8(75),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
@ -108,7 +108,7 @@ bytecodes: [
constant pool: [
]
handlers: [
[38, 137, 143],
[35, 134, 140],
]
---
@ -118,7 +118,7 @@ snippet: "
"
frame size: 11
parameter count: 1
bytecode array length: 293
bytecode array length: 290
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(26),
@ -126,14 +126,14 @@ bytecodes: [
B(Star), R(1),
B(LdaZero),
B(TestEqualStrict), R(1),
B(JumpIfTrue), U8(62),
B(JumpIfTrue), U8(59),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(1),
B(JumpIfTrueConstant), U8(0),
B(LdaSmi), U8(75),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kAbort), R(2), U8(1),
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(2),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
@ -254,7 +254,7 @@ constant pool: [
kInstanceTypeDontCare,
]
handlers: [
[44, 221, 227],
[41, 218, 224],
]
---
@ -264,7 +264,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 772
bytecode array length: 769
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(26),
@ -272,14 +272,14 @@ bytecodes: [
B(Star), R(4),
B(LdaZero),
B(TestEqualStrict), R(4),
B(JumpIfTrue), U8(62),
B(JumpIfTrue), U8(59),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(4),
B(JumpIfTrueConstant), U8(3),
B(LdaSmi), U8(75),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(9),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
@ -598,9 +598,9 @@ constant pool: [
kInstanceTypeDontCare,
]
handlers: [
[44, 691, 697],
[150, 445, 451],
[153, 399, 401],
[548, 560, 562],
[41, 688, 694],
[147, 442, 448],
[150, 396, 398],
[545, 557, 559],
]

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 2
parameter count: 1
bytecode array length: 24
bytecode array length: 21
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -39,9 +39,9 @@ snippet: "
"
frame size: 3
parameter count: 1
bytecode array length: 37
bytecode array length: 34
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -70,9 +70,9 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 45
bytecode array length: 42
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -105,9 +105,9 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 47
bytecode array length: 44
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(1),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),

View File

@ -13,9 +13,9 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 71
bytecode array length: 68
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
@ -58,9 +58,9 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 72
bytecode array length: 69
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
@ -104,9 +104,9 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 73
bytecode array length: 70
bytecodes: [
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(CreateFunctionContext), U8(3),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),

View File

@ -104,6 +104,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
false);
builder.CreateClosure(shared_info, NOT_TENURED);
// Emit create context operation.
builder.CreateFunctionContext(1);
// Emit literal creation operations.
builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
.CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)