[interpreter] Add CreateBlockContext bytecode

Allows us to create a corresponding TurboFan node, so TF can
optimize it.

BUG=v8:4280
LOG=n

Review-Url: https://codereview.chromium.org/2248633002
Cr-Commit-Position: refs/heads/master@{#38651}
This commit is contained in:
klaasb 2016-08-16 04:07:21 -07:00 committed by Commit bot
parent 095b28de21
commit b07444b16f
11 changed files with 65 additions and 49 deletions

View File

@ -926,6 +926,15 @@ void BytecodeGraphBuilder::VisitCreateClosure() {
environment()->BindAccumulator(closure);
}
void BytecodeGraphBuilder::VisitCreateBlockContext() {
Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
bytecode_iterator().GetConstantForIndexOperand(0));
const Operator* op = javascript()->CreateBlockContext(scope_info);
Node* context = NewNode(op, environment()->LookupAccumulator());
environment()->BindAccumulator(context);
}
void BytecodeGraphBuilder::VisitCreateFunctionContext() {
uint32_t slots = bytecode_iterator().GetIndexOperand(0);
const Operator* op = javascript()->CreateFunctionContext(slots);

View File

@ -338,6 +338,13 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(size_t entry,
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateBlockContext(
Handle<ScopeInfo> scope_info) {
size_t entry = GetConstantPoolEntry(scope_info);
Output(Bytecode::kCreateBlockContext, UnsignedOperand(entry));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateFunctionContext(int slots) {
Output(Bytecode::kCreateFunctionContext, UnsignedOperand(slots));
return *this;

View File

@ -135,6 +135,10 @@ class BytecodeArrayBuilder final : public ZoneObject {
// constant pool index |entry|.
BytecodeArrayBuilder& CreateClosure(size_t entry, int flags);
// Create a new local context for a |scope_info| and a closure which should be
// in the accumulator.
BytecodeArrayBuilder& CreateBlockContext(Handle<ScopeInfo> scope_info);
// Create a new context with size |slots|.
BytecodeArrayBuilder& CreateFunctionContext(int slots);

View File

@ -3211,18 +3211,9 @@ void BytecodeGenerator::VisitNewLocalBlockContext(Scope* scope) {
AccumulatorResultScope accumulator_execution_result(this);
DCHECK(scope->is_block_scope());
// Allocate a new local block context.
register_allocator()->PrepareForConsecutiveAllocations(2);
Register scope_info = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NextConsecutiveRegister();
builder()
->LoadLiteral(scope->GetScopeInfo(isolate()))
.StoreAccumulatorInRegister(scope_info);
VisitFunctionClosureForContext();
builder()
->StoreAccumulatorInRegister(closure)
.CallRuntime(Runtime::kPushBlockContext, scope_info, 2);
builder()->CreateBlockContext(scope->GetScopeInfo(isolate()));
execution_result()->SetResultInAccumulator();
}

View File

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

View File

@ -1795,6 +1795,20 @@ void Interpreter::DoCreateClosure(InterpreterAssembler* assembler) {
}
}
// CreateBlockContext <index>
//
// Creates a new block context with the scope info constant at |index| and the
// closure in the accumulator.
void Interpreter::DoCreateBlockContext(InterpreterAssembler* assembler) {
Node* index = __ BytecodeOperandIdx(0);
Node* scope_info = __ LoadConstantPoolEntry(index);
Node* closure = __ GetAccumulator();
Node* context = __ GetContext();
__ SetAccumulator(
__ CallRuntime(Runtime::kPushBlockContext, context, scope_info, closure));
__ Dispatch();
}
// CreateFunctionContext <slots>
//
// Creates a new context with number of |slots| for the function closure.

View File

@ -681,18 +681,16 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 105
bytecode array length: 97
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaZero),
B(Star), R(1),
/* 52 S> */ B(Ldar), R(1),
B(JumpIfToBooleanFalse), U8(97),
B(JumpIfToBooleanFalse), U8(89),
/* 45 E> */ B(StackCheck),
B(LdaConstant), U8(0),
B(Star), R(4),
B(Mov), R(closure), R(5),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(3),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -725,7 +723,7 @@ bytecodes: [
B(Ldar), R(4),
B(StaContextSlot), R(context), U8(4),
B(PopContext), R(3),
B(Jump), U8(-97),
B(Jump), U8(-89),
B(LdaUndefined),
/* 137 S> */ B(Return),
]

View File

@ -101,15 +101,13 @@ snippet: "
break outer;
}
"
frame size: 5
frame size: 3
parameter count: 1
bytecode array length: 40
bytecode array length: 32
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaConstant), U8(0),
B(Star), R(3),
B(Mov), R(closure), R(4),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(3), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(2),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -146,7 +144,7 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 115
bytecode array length: 107
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(2),
@ -155,10 +153,8 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaSmi), U8(1),
/* 42 E> */ B(StaContextSlot), R(context), U8(4),
B(LdaConstant), U8(0),
B(Star), R(4),
B(Mov), R(closure), R(5),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(4), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(3),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),

View File

@ -103,9 +103,9 @@ snippet: "
let a = 1;
{ let b = 2; return function() { a + b; }; }
"
frame size: 4
frame size: 2
parameter count: 1
bytecode array length: 43
bytecode array length: 35
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(0),
@ -114,10 +114,8 @@ bytecodes: [
/* 30 E> */ B(StackCheck),
/* 56 S> */ B(LdaSmi), U8(1),
/* 56 E> */ B(StaContextSlot), R(context), U8(4),
B(LdaConstant), U8(0),
B(Star), R(2),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(2), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),

View File

@ -264,7 +264,7 @@ snippet: "
"
frame size: 18
parameter count: 1
bytecode array length: 768
bytecode array length: 752
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(26),
@ -319,10 +319,8 @@ bytecodes: [
B(JumpConstant), U8(17),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(LdaConstant), U8(0),
B(Star), R(8),
B(Mov), R(closure), R(9),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(8), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(0),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -366,10 +364,8 @@ bytecodes: [
B(LdaContextSlot), R(1), U8(10),
B(StaContextSlot), R(1), U8(6),
/* 16 E> */ B(StackCheck),
B(LdaConstant), U8(7),
B(Star), R(12),
B(Mov), R(closure), R(13),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(12), U8(2),
B(Ldar), R(closure),
B(CreateBlockContext), U8(7),
B(PushContext), R(2),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
@ -423,7 +419,7 @@ bytecodes: [
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9),
B(Wide), B(Jump), U16(-223),
B(Wide), B(Jump), U16(-215),
B(Jump), U8(46),
B(Star), R(13),
B(LdaConstant), U8(11),
@ -598,9 +594,9 @@ constant pool: [
kInstanceTypeDontCare,
]
handlers: [
[41, 687, 693],
[147, 442, 448],
[150, 396, 398],
[544, 556, 558],
[41, 671, 677],
[139, 426, 432],
[142, 380, 382],
[528, 540, 542],
]

View File

@ -102,6 +102,8 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit closure operations.
builder.CreateClosure(0, NOT_TENURED);
builder.CreateBlockContext(factory->NewScopeInfo(1));
// Emit create context operation.
builder.CreateFunctionContext(1);