Commit 9a594e78 authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[Interpreter] Unify global and unallocated variable access.

Unifies the global and unallocated variable type accesses given that
--global_var_shortcuts is going away. Lda/StaGlobal is modified to use
Load/StoreICs on the global object. The named LoadIC and StoreIC bytecodes
are also modified so that they take a constant pool entry index for the
name rather than a register, avoiding unecessary LdaConstant bytecodes to
be emitted.

BUG=v8:4280
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#31482}
parent b0e4dce6
......@@ -249,6 +249,30 @@ void BytecodeGraphBuilder::VisitStar(
}
void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitLdaGlobalStrict(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalSloppy(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitStaGlobalStrict(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
}
void BytecodeGraphBuilder::VisitLdaContextSlot(
const interpreter::BytecodeArrayIterator& iterator) {
UNIMPLEMENTED();
......
......@@ -297,6 +297,12 @@ Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
}
Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
return raw_assembler_->Load(kMachAnyTagged, context,
IntPtrConstant(Context::SlotOffset(slot_index)));
}
Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) {
Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
......
......@@ -96,6 +96,7 @@ class InterpreterAssembler {
Node* LoadObjectField(Node* object, int offset);
// Load |slot_index| from |context|.
Node* LoadContextSlot(Node* context, int slot_index);
Node* LoadContextSlot(Node* context, Node* slot_index);
// Stores |value| into |slot_index| of |context|.
Node* StoreContextSlot(Node* context, Node* slot_index, Node* value);
......
......@@ -264,6 +264,32 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
size_t name_index, int feedback_slot, LanguageMode language_mode) {
Bytecode bytecode = BytecodeForLoadGlobal(language_mode);
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
size_t name_index, int feedback_slot, LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
int slot_index) {
DCHECK(slot_index >= 0);
......@@ -291,10 +317,12 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Register object, int feedback_slot, LanguageMode language_mode) {
Register object, size_t name_index, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForLoadIC(language_mode);
if (FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot));
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
......@@ -315,11 +343,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Register object, Register name, int feedback_slot,
Register object, size_t name_index, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreIC(language_mode);
if (FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), name.ToOperand(),
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
static_cast<uint8_t>(feedback_slot));
} else {
UNIMPLEMENTED();
......@@ -894,6 +922,40 @@ Bytecode BytecodeArrayBuilder::BytecodeForKeyedStoreIC(
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(
LanguageMode language_mode) {
switch (language_mode) {
case SLOPPY:
return Bytecode::kLdaGlobalSloppy;
case STRICT:
return Bytecode::kLdaGlobalStrict;
case STRONG:
UNIMPLEMENTED();
default:
UNREACHABLE();
}
return static_cast<Bytecode>(-1);
}
// static
Bytecode BytecodeArrayBuilder::BytecodeForStoreGlobal(
LanguageMode language_mode) {
switch (language_mode) {
case SLOPPY:
return Bytecode::kStaGlobalSloppy;
case STRICT:
return Bytecode::kStaGlobalStrict;
case STRONG:
UNIMPLEMENTED();
default:
UNREACHABLE();
}
return static_cast<Bytecode>(-1);
}
// static
bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) {
return kMinUInt8 <= value && value <= kMaxUInt8;
......
......@@ -64,6 +64,9 @@ class BytecodeArrayBuilder {
// Return true if the register |reg| represents a temporary register.
bool RegisterIsTemporary(Register reg) const;
// Gets a constant pool entry for the |object|.
size_t GetConstantPoolEntry(Handle<Object> object);
// Constant loads to accumulator.
BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value);
BytecodeArrayBuilder& LoadLiteral(Handle<Object> object);
......@@ -74,8 +77,10 @@ class BytecodeArrayBuilder {
BytecodeArrayBuilder& LoadFalse();
// Global loads to the accumulator and stores from the accumulator.
BytecodeArrayBuilder& LoadGlobal(int slot_index);
BytecodeArrayBuilder& StoreGlobal(int slot_index, LanguageMode language_mode);
BytecodeArrayBuilder& LoadGlobal(size_t name_index, int feedback_slot,
LanguageMode language_mode);
BytecodeArrayBuilder& StoreGlobal(size_t name_index, int feedback_slot,
LanguageMode language_mode);
// Load the object at |slot_index| in |context| into the accumulator.
BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index);
......@@ -87,14 +92,16 @@ class BytecodeArrayBuilder {
BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg);
// Load properties. The property name should be in the accumulator.
BytecodeArrayBuilder& LoadNamedProperty(Register object, int feedback_slot,
// Named load property.
BytecodeArrayBuilder& LoadNamedProperty(Register object, size_t name_index,
int feedback_slot,
LanguageMode language_mode);
// Keyed load property. The key should be in the accumulator.
BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot,
LanguageMode language_mode);
// Store properties. The value to be stored should be in the accumulator.
BytecodeArrayBuilder& StoreNamedProperty(Register object, Register name,
BytecodeArrayBuilder& StoreNamedProperty(Register object, size_t name_index,
int feedback_slot,
LanguageMode language_mode);
BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
......@@ -184,6 +191,8 @@ class BytecodeArrayBuilder {
static Bytecode BytecodeForKeyedLoadIC(LanguageMode language_mode);
static Bytecode BytecodeForStoreIC(LanguageMode language_mode);
static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode);
static Bytecode BytecodeForLoadGlobal(LanguageMode language_mode);
static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode);
static bool FitsInIdx8Operand(int value);
static bool FitsInIdx8Operand(size_t value);
......@@ -211,8 +220,6 @@ class BytecodeArrayBuilder {
uint32_t operand_value) const;
bool LastBytecodeInSameBlock() const;
size_t GetConstantPoolEntry(Handle<Object> object);
int BorrowTemporaryRegister();
void ReturnTemporaryRegister(int reg_index);
int PrepareForConsecutiveTemporaryRegisters(size_t count);
......
This diff is collapsed.
......@@ -42,13 +42,18 @@ class BytecodeGenerator : public AstVisitor {
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
Register VisitArguments(ZoneList<Expression*>* arguments);
void VisitArithmeticExpression(BinaryOperation* binop);
void VisitCommaExpression(BinaryOperation* binop);
void VisitLogicalOrExpression(BinaryOperation* binop);
void VisitLogicalAndExpression(BinaryOperation* binop);
void VisitPropertyLoad(Register obj, Property* expr);
void VisitPropertyLoadForAccumulator(Register obj, Property* expr);
void VisitVariableLoad(Variable* variable, FeedbackVectorSlot slot);
void VisitVariableAssignment(Variable* variable, FeedbackVectorSlot slot);
void VisitNewLocalFunctionContext();
void VisitBuildLocalActivationContext();
void VisitNewLocalBlockContext(Scope* scope);
......
......@@ -43,6 +43,12 @@ namespace interpreter {
V(LdaTrue, OperandType::kNone) \
V(LdaFalse, OperandType::kNone) \
\
/* Globals */ \
V(LdaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8) \
V(LdaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8) \
V(StaGlobalSloppy, OperandType::kIdx8, OperandType::kIdx8) \
V(StaGlobalStrict, OperandType::kIdx8, OperandType::kIdx8) \
\
/* Context operations */ \
V(PushContext, OperandType::kReg8) \
V(PopContext, OperandType::kReg8) \
......@@ -54,14 +60,14 @@ namespace interpreter {
V(Star, OperandType::kReg8) \
\
/* LoadIC operations */ \
V(LoadICSloppy, OperandType::kReg8, OperandType::kIdx8) \
V(LoadICStrict, OperandType::kReg8, OperandType::kIdx8) \
V(LoadICSloppy, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
V(LoadICStrict, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
V(KeyedLoadICSloppy, OperandType::kReg8, OperandType::kIdx8) \
V(KeyedLoadICStrict, OperandType::kReg8, OperandType::kIdx8) \
\
/* StoreIC operations */ \
V(StoreICSloppy, OperandType::kReg8, OperandType::kReg8, OperandType::kIdx8) \
V(StoreICStrict, OperandType::kReg8, OperandType::kReg8, OperandType::kIdx8) \
V(StoreICSloppy, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
V(StoreICStrict, OperandType::kReg8, OperandType::kIdx8, OperandType::kIdx8) \
V(KeyedStoreICSloppy, OperandType::kReg8, OperandType::kReg8, \
OperandType::kIdx8) \
V(KeyedStoreICStrict, OperandType::kReg8, OperandType::kReg8, \
......
This diff is collapsed.
......@@ -59,12 +59,23 @@ class Interpreter {
void DoCompareOp(Token::Value compare_op,
compiler::InterpreterAssembler* assembler);
// Generates code to perform a property load via |ic|.
void DoPropertyLoadIC(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a global load via |ic|.
void DoLoadGlobal(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a property store via |ic|.
void DoPropertyStoreIC(Callable ic,
compiler::InterpreterAssembler* assembler);
// Generates code to perform a global store via |ic|.
void DoStoreGlobal(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a named property load via |ic|.
void DoLoadIC(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a keyed property load via |ic|.
void DoKeyedLoadIC(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a namedproperty store via |ic|.
void DoStoreIC(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code to perform a keyed property store via |ic|.
void DoKeyedStoreIC(Callable ic, compiler::InterpreterAssembler* assembler);
// Generates code ro create a literal via |function_id|.
void DoCreateLiteral(Runtime::FunctionId function_id,
......
......@@ -780,9 +780,9 @@ TEST(InterpreterLoadNamedProperty) {
builder.set_locals_count(0);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.LoadNamedProperty(builder.Parameter(0), vector->GetIndex(slot),
i::SLOPPY)
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadNamedProperty(builder.Parameter(0), name_index,
vector->GetIndex(slot), i::SLOPPY)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
......@@ -879,13 +879,12 @@ TEST(InterpreterStoreNamedProperty) {
name = factory->string_table()->LookupString(isolate, name);
BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
builder.set_locals_count(1);
builder.set_locals_count(0);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.StoreAccumulatorInRegister(Register(0))
.LoadLiteral(Smi::FromInt(999))
.StoreNamedProperty(builder.Parameter(0), Register(0),
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadLiteral(Smi::FromInt(999))
.StoreNamedProperty(builder.Parameter(0), name_index,
vector->GetIndex(slot), i::STRICT)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
......@@ -998,8 +997,9 @@ TEST(InterpreterCall) {
builder.set_locals_count(1);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.LoadNamedProperty(builder.Parameter(0), slot_index, i::SLOPPY)
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index,
i::SLOPPY)
.StoreAccumulatorInRegister(Register(0))
.Call(Register(0), builder.Parameter(0), 0)
.Return();
......@@ -1020,8 +1020,9 @@ TEST(InterpreterCall) {
builder.set_locals_count(1);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.LoadNamedProperty(builder.Parameter(0), slot_index, i::SLOPPY)
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index,
i::SLOPPY)
.StoreAccumulatorInRegister(Register(0))
.Call(Register(0), builder.Parameter(0), 0)
.Return();
......@@ -1045,8 +1046,9 @@ TEST(InterpreterCall) {
builder.set_locals_count(4);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.LoadNamedProperty(builder.Parameter(0), slot_index, i::SLOPPY)
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index,
i::SLOPPY)
.StoreAccumulatorInRegister(Register(0))
.LoadAccumulatorWithRegister(builder.Parameter(0))
.StoreAccumulatorInRegister(Register(1))
......@@ -1075,8 +1077,9 @@ TEST(InterpreterCall) {
builder.set_locals_count(12);
builder.set_context_count(0);
builder.set_parameter_count(1);
builder.LoadLiteral(name)
.LoadNamedProperty(builder.Parameter(0), slot_index, i::SLOPPY)
size_t name_index = builder.GetConstantPoolEntry(name);
builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index,
i::SLOPPY)
.StoreAccumulatorInRegister(Register(0))
.LoadAccumulatorWithRegister(builder.Parameter(0))
.StoreAccumulatorInRegister(Register(1))
......
......@@ -43,6 +43,12 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
Register reg(0);
builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg);
// Emit global load / store operations.
builder.LoadGlobal(0, 1, LanguageMode::SLOPPY)
.LoadGlobal(0, 1, LanguageMode::STRICT)
.StoreGlobal(0, 1, LanguageMode::SLOPPY)
.StoreGlobal(0, 1, LanguageMode::STRICT);
// Emit context operations.
builder.PushContext(reg);
builder.PopContext(reg);
......@@ -50,13 +56,13 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.StoreContextSlot(reg, 1);
// Emit load / store property operations.
builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY)
builder.LoadNamedProperty(reg, 0, 0, LanguageMode::SLOPPY)
.LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY)
.StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY)
.StoreNamedProperty(reg, 0, 0, LanguageMode::SLOPPY)
.StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY)
.LoadNamedProperty(reg, 0, LanguageMode::STRICT)
.LoadNamedProperty(reg, 0, 0, LanguageMode::STRICT)
.LoadKeyedProperty(reg, 0, LanguageMode::STRICT)
.StoreNamedProperty(reg, reg, 0, LanguageMode::STRICT)
.StoreNamedProperty(reg, 0, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT);
// Emit closure operations.
......
......@@ -36,6 +36,7 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
Register reg_0(0);
Register reg_1(1);
Register reg_2 = Register::FromParameterIndex(2, builder.parameter_count());
int name_index = 21;
int feedback_slot = 97;
builder.LoadLiteral(heap_num_0)
......@@ -44,7 +45,7 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
.LoadLiteral(smi_0)
.LoadLiteral(smi_1)
.LoadAccumulatorWithRegister(reg_0)
.LoadNamedProperty(reg_1, feedback_slot, LanguageMode::SLOPPY)
.LoadNamedProperty(reg_1, name_index, feedback_slot, LanguageMode::SLOPPY)
.StoreAccumulatorInRegister(reg_2)
.CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1)
.Return();
......@@ -82,7 +83,8 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
CHECK_EQ(iterator.current_bytecode(), Bytecode::kLoadICSloppy);
CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
CHECK_EQ(iterator.GetIndexOperand(1), feedback_slot);
CHECK_EQ(iterator.GetIndexOperand(1), name_index);
CHECK_EQ(iterator.GetIndexOperand(2), feedback_slot);
CHECK(!iterator.done());
iterator.Advance();
......
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