Commit c19a29f8 authored by oth's avatar oth Committed by Commit bot

Re-reland "[Interpreter] Add CreateClosure to BytecodeGraphBuilder."

Original issue's description:
> [Interpreter] Add CreateClosure to BytecodeGraphBuilder.
>
> Adds code and tests to support CreateClosure bytecode when building
> graphs.
>
> Committed: https://crrev.com/4cceb11b0929abcbc82bf0854554a9b66003335d
> Cr-Commit-Position: refs/heads/master@{#32224}

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#32342}
parent e3a46bc7
......@@ -643,7 +643,20 @@ void BytecodeGraphBuilder::VisitPopContext(
void BytecodeGraphBuilder::VisitCreateClosure(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
Handle<SharedFunctionInfo> shared_info =
Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0));
PretenureFlag tenured =
iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED;
const Operator* op = javascript()->CreateClosure(shared_info, tenured);
Node* closure = NewNode(op);
AddEmptyFrameStateInputs(closure);
environment()->BindAccumulator(closure);
}
void BytecodeGraphBuilder::VisitCreateClosureWide(
const interpreter::BytecodeArrayIterator& iterator) {
VisitCreateClosure(iterator);
}
......
......@@ -444,9 +444,18 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
PretenureFlag tenured) {
Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
size_t entry = GetConstantPoolEntry(shared_info);
DCHECK(FitsInImm8Operand(tenured));
Output(Bytecode::kCreateClosure, static_cast<uint8_t>(tenured));
if (FitsInIdx8Operand(entry)) {
Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry),
static_cast<uint8_t>(tenured));
} else if (FitsInIdx16Operand(entry)) {
Output(Bytecode::kCreateClosureWide, static_cast<uint16_t>(entry),
static_cast<uint8_t>(tenured));
} else {
UNIMPLEMENTED();
}
return *this;
}
......
......@@ -116,8 +116,9 @@ class BytecodeArrayBuilder {
int feedback_slot,
LanguageMode language_mode);
// Create a new closure for the SharedFunctionInfo in the accumulator.
BytecodeArrayBuilder& CreateClosure(PretenureFlag tenured);
// Create a new closure for the SharedFunctionInfo.
BytecodeArrayBuilder& CreateClosure(Handle<SharedFunctionInfo> shared_info,
PretenureFlag tenured);
// Create a new arguments object in the accumulator.
BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
......
......@@ -971,10 +971,8 @@ void BytecodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
Handle<SharedFunctionInfo> shared_info =
Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
CHECK(!shared_info.is_null()); // TODO(rmcilroy): Set stack overflow?
builder()
->LoadLiteral(shared_info)
.CreateClosure(expr->pretenure() ? TENURED : NOT_TENURED);
builder()->CreateClosure(shared_info,
expr->pretenure() ? TENURED : NOT_TENURED);
execution_result()->SetResultInAccumulator();
}
......
......@@ -161,7 +161,8 @@ namespace interpreter {
V(CreateObjectLiteral, OperandType::kIdx8, OperandType::kImm8) \
\
/* Closure allocation */ \
V(CreateClosure, OperandType::kImm8) \
V(CreateClosure, OperandType::kIdx8, OperandType::kImm8) \
V(CreateClosureWide, OperandType::kIdx16, OperandType::kImm8) \
\
/* Arguments allocation */ \
V(CreateMappedArguments, OperandType::kNone) \
......
......@@ -1356,15 +1356,16 @@ void Interpreter::DoCreateObjectLiteral(
}
// CreateClosure <tenured>
// CreateClosure <index> <tenured>
//
// Creates a new closure for SharedFunctionInfo in the accumulator with the
// PretenureFlag <tenured>.
// Creates a new closure for SharedFunctionInfo at position |index| in the
// constant pool and with the PretenureFlag <tenured>.
void Interpreter::DoCreateClosure(compiler::InterpreterAssembler* assembler) {
// TODO(rmcilroy): Possibly call FastNewClosureStub when possible instead of
// calling into the runtime.
Node* shared = __ GetAccumulator();
Node* tenured_raw = __ BytecodeOperandImm(0);
Node* index = __ BytecodeOperandIdx(0);
Node* shared = __ LoadConstantPoolEntry(index);
Node* tenured_raw = __ BytecodeOperandImm(1);
Node* tenured = __ SmiTag(tenured_raw);
Node* result =
__ CallRuntime(Runtime::kInterpreterNewClosure, shared, tenured);
......@@ -1373,6 +1374,16 @@ void Interpreter::DoCreateClosure(compiler::InterpreterAssembler* assembler) {
}
// CreateClosureWide <index> <tenured>
//
// Creates a new closure for SharedFunctionInfo at position |index| in the
// constant pool and with the PretenureFlag <tenured>.
void Interpreter::DoCreateClosureWide(
compiler::InterpreterAssembler* assembler) {
return DoCreateClosure(assembler);
}
// CreateMappedArguments
//
// Creates a new mapped arguments object.
......
......@@ -582,6 +582,45 @@ TEST(BytecodeGraphBuilderCallNew) {
}
TEST(BytecodeGraphBuilderCreateClosure) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
ExpectedSnippet<0> snippets[] = {
{"function f() {\n"
" function counter() { this.count = 20; }\n"
" var c = new counter();\n"
" return c.count;\n"
"}; f()",
{factory->NewNumberFromInt(20)}},
{"function f() {\n"
" function counter(arg0) { this.count = 17; this.x = arg0; }\n"
" var c = new counter(6);\n"
" return c.count + c.x;\n"
"}; f()",
{factory->NewNumberFromInt(23)}},
{"function f() {\n"
" function counter(arg0, arg1) {\n"
" this.count = 17; this.x = arg0; this.y = arg1;\n"
" }\n"
" var c = new counter(3, 5);\n"
" return c.count + c.x + c.y;\n"
"}; f()",
{factory->NewNumberFromInt(25)}},
};
size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
for (size_t i = 0; i < num_snippets; i++) {
BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet);
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*snippets[i].return_value()));
}
}
TEST(BytecodeGraphBuilderCallRuntime) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
......
......@@ -94,7 +94,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
// Emit closure operations.
builder.CreateClosure(NOT_TENURED);
Factory* factory = isolate()->factory();
Handle<SharedFunctionInfo> shared_info = factory->NewSharedFunctionInfo(
factory->NewStringFromStaticChars("function_a"), MaybeHandle<Code>(),
false);
builder.CreateClosure(shared_info, NOT_TENURED);
// Emit argument creation operations.
builder.CreateArguments(CreateArgumentsType::kMappedArguments)
......@@ -215,6 +219,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
}
builder.LoadLiteral(Smi::FromInt(20000000));
// CreateClosureWide
Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo(
factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(),
false);
builder.CreateClosure(shared_info2, NOT_TENURED);
builder.Return();
// Generate BytecodeArray.
......
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