Commit 108e96a4 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Interpreter] Move ToName elision into BytecodeGenerator.

Moves the ToName elision out of the peephole optimizer and into the
BytecodeGenerator.

BUG=v8:6194

Change-Id: Ic355adbe21f967dc5d52babdd37100a260c62c26
Reviewed-on: https://chromium-review.googlesource.com/467466
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44427}
parent f2ea3d66
......@@ -1555,13 +1555,7 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
old_receiver = new_receiver;
}
if (property->key()->IsStringLiteral()) {
VisitForRegisterValue(property->key(), key);
} else {
VisitForAccumulatorValue(property->key());
builder()->ConvertAccumulatorToName(key);
}
BuildLoadPropertyKey(property, key);
if (property->is_static() && property->is_computed_name()) {
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
......@@ -1825,9 +1819,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::COMPUTED:
case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
Register key = register_allocator()->NewRegister();
VisitForAccumulatorValue(property->key());
builder()->ConvertAccumulatorToName(key);
BuildLoadPropertyKey(property, key);
Register value = VisitForRegisterValue(property->value());
VisitSetHomeObject(value, literal, property);
......@@ -1850,8 +1842,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
case ObjectLiteral::Property::SETTER: {
RegisterList args = register_allocator()->NewRegisterList(4);
builder()->MoveRegister(literal, args[0]);
VisitForAccumulatorValue(property->key());
builder()->ConvertAccumulatorToName(args[1]);
BuildLoadPropertyKey(property, args[1]);
VisitForRegisterValue(property->value(), args[2]);
VisitSetHomeObject(args[2], literal, property);
builder()
......@@ -3562,6 +3553,16 @@ void BytecodeGenerator::BuildPushUndefinedIntoRegisterList(
builder()->LoadUndefined().StoreAccumulatorInRegister(reg);
}
void BytecodeGenerator::BuildLoadPropertyKey(LiteralProperty* property,
Register out_reg) {
if (property->key()->IsStringLiteral()) {
VisitForRegisterValue(property->key(), out_reg);
} else {
VisitForAccumulatorValue(property->key());
builder()->ConvertAccumulatorToName(out_reg);
}
}
// Visits the expression |expr| for testing its boolean value and jumping to the
// |then| or |other| label depending on value and short-circuit semantics
void BytecodeGenerator::VisitForTest(Expression* expr,
......
......@@ -163,6 +163,8 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildPushUndefinedIntoRegisterList(RegisterList* reg_list);
void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
// Visitors for obtaining expression result in the accumulator, in a
// register, or just getting the effect. Some visitors return a TypeHint which
// specifies the type of the result of the visited expression.
......
......@@ -618,11 +618,6 @@ class V8_EXPORT_PRIVATE Bytecodes final {
return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
}
// Returns true if |bytecode| puts a name in the accumulator.
static constexpr bool PutsNameInAccumulator(Bytecode bytecode) {
return bytecode == Bytecode::kTypeOf;
}
// Returns true if the bytecode is a call or a constructor call.
static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
......
......@@ -79,10 +79,6 @@ const char* PeepholeActionTableWriter::kNamespaceElements[] = {"v8", "internal",
// static
PeepholeActionAndData PeepholeActionTableWriter::LookupActionAndData(
Bytecode last, Bytecode current) {
if (current == Bytecode::kToName && Bytecodes::PutsNameInAccumulator(last)) {
return {PeepholeAction::kChangeBytecodeAction, Bytecode::kStar};
}
// Nop are placeholders for holding source position information and can be
// elided if there is no source information.
if (last == Bytecode::kNop) {
......
......@@ -382,7 +382,7 @@ bytecodes: [
B(Star), R(3),
B(StaDataPropertyInLiteral), R(1), R(2), U8(0), U8(5),
B(LdaConstant), U8(3),
B(ToName), R(3),
B(Star), R(3),
B(CreateClosure), U8(4), U8(2), U8(2),
B(Star), R(4),
B(LdaZero),
......@@ -390,7 +390,7 @@ bytecodes: [
B(Mov), R(1), R(2),
B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), R(2), U8(4),
B(LdaConstant), U8(3),
B(ToName), R(3),
B(Star), R(3),
B(CreateClosure), U8(5), U8(3), U8(2),
B(Star), R(4),
B(LdaZero),
......
......@@ -188,33 +188,6 @@ TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) {
CHECK_EQ(last_written(), third);
}
TEST_F(BytecodePeepholeOptimizerTest, LdarToName) {
BytecodeNode first(Bytecode::kLdar, Register(0).ToOperand());
BytecodeNode second(Bytecode::kToName, Register(0).ToOperand());
optimizer()->Write(&first);
CHECK_EQ(write_count(), 0);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written(), first);
Flush();
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written(), second);
}
TEST_F(BytecodePeepholeOptimizerTest, TypeOfToName) {
BytecodeNode first(Bytecode::kTypeOf);
BytecodeNode second(Bytecode::kToName, Register(0).ToOperand());
optimizer()->Write(&first);
CHECK_EQ(write_count(), 0);
optimizer()->Write(&second);
CHECK_EQ(write_count(), 1);
CHECK_EQ(last_written(), first);
Flush();
CHECK_EQ(write_count(), 2);
CHECK_EQ(last_written(), second);
CHECK_EQ(last_written().bytecode(), Bytecode::kStar);
}
// Tests covering BytecodePeepholeOptimizer::CanElideLast().
TEST_F(BytecodePeepholeOptimizerTest, LdaTrueLdaFalse) {
......
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