Commit a0a8b606 authored by mythria's avatar mythria Committed by Commit bot

[Interpreter] Adds support for wide variant of load/store lookup slots.

Adds implementation and tests for wide variant of load/store lookup slots.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#33111}
parent 007de5d2
......@@ -765,6 +765,18 @@ void BytecodeGraphBuilder::BuildStaLookupSlot(
}
void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
const interpreter::BytecodeArrayIterator& iterator) {
VisitLdaLookupSlot(iterator);
}
void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
const interpreter::BytecodeArrayIterator& iterator) {
VisitLdaLookupSlotInsideTypeof(iterator);
}
void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
......@@ -777,6 +789,18 @@ void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
}
void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
const interpreter::BytecodeArrayIterator& iterator) {
VisitStaLookupSlotSloppy(iterator);
}
void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
const interpreter::BytecodeArrayIterator& iterator) {
VisitStaLookupSlotStrict(iterator);
}
void BytecodeGraphBuilder::BuildNamedLoad(
const interpreter::BytecodeArrayIterator& iterator) {
FrameStateBeforeAndAfter states(this, iterator);
......
......@@ -466,6 +466,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
size_t name_index = GetConstantPoolEntry(name);
if (FitsInIdx8Operand(name_index)) {
Output(bytecode, static_cast<uint8_t>(name_index));
} else if (FitsInIdx16Operand(name_index)) {
Output(BytecodeForWideOperands(bytecode),
static_cast<uint16_t>(name_index));
} else {
UNIMPLEMENTED();
}
......@@ -479,6 +482,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
size_t name_index = GetConstantPoolEntry(name);
if (FitsInIdx8Operand(name_index)) {
Output(bytecode, static_cast<uint8_t>(name_index));
} else if (FitsInIdx16Operand(name_index)) {
Output(BytecodeForWideOperands(bytecode),
static_cast<uint16_t>(name_index));
} else {
UNIMPLEMENTED();
}
......@@ -1327,6 +1333,14 @@ Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
return Bytecode::kStaGlobalSloppyWide;
case Bytecode::kStaGlobalStrict:
return Bytecode::kStaGlobalStrictWide;
case Bytecode::kLdaLookupSlot:
return Bytecode::kLdaLookupSlotWide;
case Bytecode::kLdaLookupSlotInsideTypeof:
return Bytecode::kLdaLookupSlotInsideTypeofWide;
case Bytecode::kStaLookupSlotStrict:
return Bytecode::kStaLookupSlotStrictWide;
case Bytecode::kStaLookupSlotSloppy:
return Bytecode::kStaLookupSlotSloppyWide;
default:
UNREACHABLE();
return static_cast<Bytecode>(-1);
......
......@@ -70,8 +70,12 @@ namespace interpreter {
/* Load-Store lookup slots */ \
V(LdaLookupSlot, OperandType::kIdx8) \
V(LdaLookupSlotInsideTypeof, OperandType::kIdx8) \
V(LdaLookupSlotWide, OperandType::kIdx16) \
V(LdaLookupSlotInsideTypeofWide, OperandType::kIdx16) \
V(StaLookupSlotSloppy, OperandType::kIdx8) \
V(StaLookupSlotStrict, OperandType::kIdx8) \
V(StaLookupSlotSloppyWide, OperandType::kIdx16) \
V(StaLookupSlotStrictWide, OperandType::kIdx16) \
\
/* Register-accumulator transfers */ \
V(Ldar, OperandType::kReg8) \
......
......@@ -477,6 +477,26 @@ void Interpreter::DoLdaLookupSlotInsideTypeof(
}
// LdaLookupSlotWide <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically.
void Interpreter::DoLdaLookupSlotWide(
compiler::InterpreterAssembler* assembler) {
DoLdaLookupSlot(assembler);
}
// LdaLookupSlotInsideTypeofWide <name_index>
//
// Lookup the object with the name in constant pool entry |name_index|
// dynamically without causing a NoReferenceError.
void Interpreter::DoLdaLookupSlotInsideTypeofWide(
compiler::InterpreterAssembler* assembler) {
DoLdaLookupSlotInsideTypeof(assembler);
}
void Interpreter::DoStoreLookupSlot(LanguageMode language_mode,
compiler::InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
......@@ -511,6 +531,26 @@ void Interpreter::DoStaLookupSlotStrict(
}
// StaLookupSlotSloppyWide <name_index>
//
// Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in sloppy mode.
void Interpreter::DoStaLookupSlotSloppyWide(
compiler::InterpreterAssembler* assembler) {
DoStaLookupSlotSloppy(assembler);
}
// StaLookupSlotStrictWide <name_index>
//
// Store the object in accumulator to the object with the name in constant
// pool entry |name_index| in strict mode.
void Interpreter::DoStaLookupSlotStrictWide(
compiler::InterpreterAssembler* assembler) {
DoStaLookupSlotStrict(assembler);
}
void Interpreter::DoLoadIC(Callable ic,
compiler::InterpreterAssembler* assembler) {
Node* code_target = __ HeapConstant(ic.code());
......
......@@ -1038,6 +1038,8 @@ TEST(BytecodeGraphBuilderLookupSlot) {
{"return x;", {factory->NewNumber(12)}},
{"return obj.val;", {factory->NewNumber(3.1414)}},
{"return typeof x;", {factory->NewStringFromStaticChars("number")}},
{"return typeof dummy;",
{factory->NewStringFromStaticChars("undefined")}},
{"x = 23; return x;", {factory->NewNumber(23)}},
{"'use strict'; obj.val = 23.456; return obj.val;",
{factory->NewNumber(23.456)}}};
......@@ -1056,6 +1058,50 @@ TEST(BytecodeGraphBuilderLookupSlot) {
}
TEST(BytecodeGraphBuilderLookupSlotWide) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
Factory* factory = isolate->factory();
const char* function_prologue =
"var f;"
"var x = 12;"
"y = 10;"
"var obj = {val:3.1414};"
"var z = 30;"
"function f1() {"
" var z = 20;"
" eval(\"function t() {";
const char* function_epilogue =
" }; f = t; t();\");"
"}"
"f1();";
ExpectedSnippet<0> snippets[] = {
{"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x;",
{factory->NewNumber(12)}},
{"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return typeof x;",
{factory->NewStringFromStaticChars("number")}},
{"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x = 23;",
{factory->NewNumber(23)}},
{"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;",
{factory->NewNumber(23.456)}}};
size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
for (size_t i = 0; i < num_snippets; i++) {
ScopedVector<char> script(3072);
SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet,
function_epilogue);
BytecodeGraphTester tester(isolate, zone, script.start(), "t");
auto callable = tester.GetCallable<>();
Handle<Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*snippets[i].return_value()));
}
}
bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value,
Handle<Object> rhs_value) {
switch (opcode) {
......
......@@ -5838,6 +5838,103 @@ TEST(LookupSlotInEval) {
}
TEST(LookupSlotWideInEval) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
const char* function_prologue =
"var f;"
"var x = 1;"
"function f1() {"
" eval(\"function t() {";
const char* function_epilogue =
" }; f = t; f();\");"
"}"
"f1();";
int const_count[] = {0, 0, 0, 0};
ExpectedSnippet<InstanceType, 257> snippets[] = {
{REPEAT_256(SPACE, "var y = 2.3;")
"return x;",
1 * kPointerSize,
1,
1028,
{
REPEAT_256(SPACE, //
B(LdaConstant), U8(const_count[0]++), //
B(Star), R(0), ) //
B(LdaLookupSlotWide), U16(256), //
B(Return) //
},
257,
{REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
{REPEAT_256(SPACE, "var y = 2.3;")
"return typeof x;",
1 * kPointerSize,
1,
1029,
{
REPEAT_256(SPACE, //
B(LdaConstant), U8(const_count[1]++), //
B(Star), R(0), ) //
B(LdaLookupSlotInsideTypeofWide), U16(256), //
B(TypeOf), //
B(Return) //
},
257,
{REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
{REPEAT_256(SPACE, "var y = 2.3;")
"x = 10;",
1 * kPointerSize,
1,
1031,
{
REPEAT_256(SPACE, //
B(LdaConstant), U8(const_count[2]++), //
B(Star), R(0), ) //
B(LdaSmi8), U8(10), //
B(StaLookupSlotSloppyWide), U16(256), //
B(LdaUndefined), //
B(Return) //
},
257,
{REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
{"'use strict';"
REPEAT_256(SPACE, "var y = 2.3;")
"x = 10;",
1 * kPointerSize,
1,
1031,
{
REPEAT_256(SPACE,
B(LdaConstant), U8(const_count[3]++), //
B(Star), R(0), ) //
B(LdaSmi8), U8(10), //
B(StaLookupSlotStrictWide), U16(256), //
B(LdaUndefined), //
B(Return) //
},
257,
{REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE),
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}},
};
for (size_t i = 0; i < arraysize(snippets); i++) {
std::string script = std::string(function_prologue) +
std::string(snippets[i].code_snippet) +
std::string(function_epilogue);
// TODO(mythria): use * as filter when function declarations are supported
// inside eval.
Handle<BytecodeArray> bytecode_array =
helper.MakeBytecode(script.c_str(), "t", "f");
CheckBytecodeArrayEqual(snippets[i], bytecode_array);
}
}
TEST(DeleteLookupSlot) {
InitializedHandleScope handle_scope;
BytecodeGeneratorHelper helper;
......
......@@ -3213,6 +3213,7 @@ TEST(InterpreterLookupSlot) {
std::pair<const char*, Handle<Object>> lookup_slot[] = {
{"return x;", handle(Smi::FromInt(1), isolate)},
{"return typeof x;", factory->NewStringFromStaticChars("number")},
{"return typeof dummy;", factory->NewStringFromStaticChars("undefined")},
{"x = 10; return x;", handle(Smi::FromInt(10), isolate)},
{"'use strict'; x = 20; return x;", handle(Smi::FromInt(20), isolate)},
};
......@@ -3231,6 +3232,50 @@ TEST(InterpreterLookupSlot) {
}
TEST(InterpreterLookupSlotWide) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
i::Factory* factory = isolate->factory();
const char* function_prologue =
"var f;"
"var x = 1;"
"function f1() {"
" eval(\"function t() {";
const char* function_epilogue =
" }; f = t;\");"
"}"
"f1();";
std::ostringstream str;
str << "var y = 2.3;";
for (int i = 1; i < 256; i++) {
str << "y = " << 2.3 + i << ";";
}
std::string init_function_body = str.str();
std::pair<std::string, Handle<Object>> lookup_slot[] = {
{init_function_body + "return x;", handle(Smi::FromInt(1), isolate)},
{init_function_body + "return typeof x;",
factory->NewStringFromStaticChars("number")},
{init_function_body + "return x = 10;",
handle(Smi::FromInt(10), isolate)},
{"'use strict';" + init_function_body + "x = 20; return x;",
handle(Smi::FromInt(20), isolate)},
};
for (size_t i = 0; i < arraysize(lookup_slot); i++) {
std::string script = std::string(function_prologue) + lookup_slot[i].first +
std::string(function_epilogue);
InterpreterTester tester(handles.main_isolate(), script.c_str(), "t");
auto callable = tester.GetCallable<>();
Handle<i::Object> return_value = callable().ToHandleChecked();
CHECK(return_value->SameValue(*lookup_slot[i].second));
}
}
TEST(TemporaryRegisterAllocation) {
HandleAndZoneScope handles;
i::Isolate* isolate = handles.main_isolate();
......
......@@ -240,6 +240,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
// Emit wide load / store lookup slots.
builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF)
.LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF)
.StoreLookupSlot(wide_name, LanguageMode::SLOPPY)
.StoreLookupSlot(wide_name, LanguageMode::STRICT);
// CreateClosureWide
Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo(
factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(),
......
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