Commit 26c17552 authored by klaasb's avatar klaasb Committed by Commit bot

[interpreter] Put object in register for ToObject/ForInPrepare

This gets rid of the Star bytecodes that were always dispatched to from
ToObject.
ToObject now outputs to register instead of to the accumulator and
ForInPrepare gets the receiver object from an input register.

BUG=v8:4820
LOG=n

Review-Url: https://codereview.chromium.org/2189463006
Cr-Commit-Position: refs/heads/master@{#38177}
parent 79ebd37d
......@@ -1340,27 +1340,23 @@ void BytecodeGraphBuilder::VisitTestInstanceOf() {
BuildCompareOp(javascript()->InstanceOf());
}
void BytecodeGraphBuilder::VisitToName() {
void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
FrameStateBeforeAndAfter states(this);
Node* value =
NewNode(javascript()->ToName(), environment()->LookupAccumulator());
Node* value = NewNode(js_op, environment()->LookupAccumulator());
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
&states);
}
void BytecodeGraphBuilder::VisitToName() {
BuildCastOperator(javascript()->ToName());
}
void BytecodeGraphBuilder::VisitToObject() {
FrameStateBeforeAndAfter states(this);
Node* node =
NewNode(javascript()->ToObject(), environment()->LookupAccumulator());
environment()->BindAccumulator(node, &states);
BuildCastOperator(javascript()->ToObject());
}
void BytecodeGraphBuilder::VisitToNumber() {
FrameStateBeforeAndAfter states(this);
Node* value =
NewNode(javascript()->ToNumber(), environment()->LookupAccumulator());
environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
&states);
BuildCastOperator(javascript()->ToNumber());
}
void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
......@@ -1458,10 +1454,11 @@ DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
void BytecodeGraphBuilder::BuildForInPrepare() {
FrameStateBeforeAndAfter states(this);
Node* receiver = environment()->LookupAccumulator();
Node* receiver =
environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
environment()->BindRegistersToProjections(
bytecode_iterator().GetRegisterOperand(0), prepare, &states);
bytecode_iterator().GetRegisterOperand(1), prepare, &states);
}
void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
......
......@@ -128,6 +128,7 @@ class BytecodeGraphBuilder {
void BuildBinaryOpWithImmediate(const Operator* op);
void BuildCompareOp(const Operator* op);
void BuildDelete(LanguageMode language_mode);
void BuildCastOperator(const Operator* op);
void BuildForInPrepare();
void BuildForInNext();
void BuildInvokeIntrinsic();
......
......@@ -383,8 +383,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
Output(Bytecode::kToObject);
BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject(
Register out) {
Output(Bytecode::kToObject, RegisterOperand(out));
return *this;
}
......@@ -498,8 +499,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
Register cache_info_triple) {
Output(Bytecode::kForInPrepare, RegisterOperand(cache_info_triple));
Register receiver, Register cache_info_triple) {
Output(Bytecode::kForInPrepare, RegisterOperand(receiver),
RegisterOperand(cache_info_triple));
return *this;
}
......
......@@ -214,9 +214,9 @@ class BytecodeArrayBuilder final : public ZoneObject {
// Casts accumulator and stores result in accumulator.
BytecodeArrayBuilder& CastAccumulatorToBoolean();
BytecodeArrayBuilder& CastAccumulatorToJSObject();
// Casts accumulator and stores result in register |out|.
BytecodeArrayBuilder& CastAccumulatorToJSObject(Register out);
BytecodeArrayBuilder& CastAccumulatorToName(Register out);
BytecodeArrayBuilder& CastAccumulatorToNumber(Register out);
......@@ -243,7 +243,8 @@ class BytecodeArrayBuilder final : public ZoneObject {
BytecodeArrayBuilder& Debugger();
// Complex flow control.
BytecodeArrayBuilder& ForInPrepare(Register cache_info_triple);
BytecodeArrayBuilder& ForInPrepare(Register receiver,
Register cache_info_triple);
BytecodeArrayBuilder& ForInDone(Register index, Register cache_length);
BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
Register cache_type_array_pair,
......
......@@ -983,7 +983,6 @@ void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) {
builder()->SetStatementPosition(stmt);
VisitForAccumulatorValue(stmt->expression());
builder()->CastAccumulatorToJSObject();
VisitNewLocalWithContext();
VisitInScope(stmt->statement(), stmt->scope());
}
......@@ -1201,8 +1200,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
builder()->JumpIfUndefined(&subject_undefined_label);
builder()->JumpIfNull(&subject_null_label);
Register receiver = register_allocator()->NewRegister();
builder()->CastAccumulatorToJSObject();
builder()->StoreAccumulatorInRegister(receiver);
builder()->CastAccumulatorToJSObject(receiver);
register_allocator()->PrepareForConsecutiveAllocations(3);
Register cache_type = register_allocator()->NextConsecutiveRegister();
......@@ -1210,7 +1208,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Register cache_length = register_allocator()->NextConsecutiveRegister();
// Used as kRegTriple and kRegPair in ForInPrepare and ForInNext.
USE(cache_array);
builder()->ForInPrepare(cache_type);
builder()->ForInPrepare(receiver, cache_type);
// Set up loop counter
Register index = register_allocator()->NewRegister();
......@@ -3071,7 +3069,7 @@ void BytecodeGenerator::VisitNewLocalWithContext() {
Register extension_object = register_allocator()->NextConsecutiveRegister();
Register closure = register_allocator()->NextConsecutiveRegister();
builder()->StoreAccumulatorInRegister(extension_object);
builder()->CastAccumulatorToJSObject(extension_object);
VisitFunctionClosureForContext();
builder()->StoreAccumulatorInRegister(closure).CallRuntime(
Runtime::kPushWithContext, extension_object, 2);
......
......@@ -213,7 +213,7 @@ namespace interpreter {
/* Cast operators */ \
V(ToName, AccumulatorUse::kRead, OperandType::kRegOut) \
V(ToNumber, AccumulatorUse::kRead, OperandType::kRegOut) \
V(ToObject, AccumulatorUse::kReadWrite) \
V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut) \
\
/* Literals */ \
V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
......@@ -251,7 +251,8 @@ namespace interpreter {
V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \
\
/* Complex flow control For..in */ \
V(ForInPrepare, AccumulatorUse::kRead, OperandType::kRegOutTriple) \
V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \
OperandType::kRegOutTriple) \
V(ForInDone, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg) \
V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \
OperandType::kRegPair, OperandType::kIdx) \
......
......@@ -1060,7 +1060,9 @@ void Interpreter::DoToNumber(InterpreterAssembler* assembler) {
//
// Cast the object referenced by the accumulator to a JSObject.
void Interpreter::DoToObject(InterpreterAssembler* assembler) {
DoUnaryOp(CodeFactory::ToObject(isolate_), assembler);
Node* result = BuildUnaryOp(CodeFactory::ToObject(isolate_), assembler);
__ StoreRegister(result, __ BytecodeOperandReg(0));
__ Dispatch();
}
// Inc
......@@ -1910,7 +1912,8 @@ void Interpreter::BuildForInPrepareResult(Node* output_register,
// |cache_info_triple + 2|, with the registers holding cache_type, cache_array,
// and cache_length respectively.
void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Node* object = __ GetAccumulator();
Node* object_reg = __ BytecodeOperandReg(0);
Node* object = __ LoadRegister(object_reg);
Node* context = __ GetContext();
Node* const zero_smi = __ SmiConstant(Smi::FromInt(0));
......@@ -1971,7 +1974,7 @@ void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
__ LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset);
Node* cache_array = __ LoadObjectField(
cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset);
Node* output_register = __ BytecodeOperandReg(0);
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, cache_type, cache_array,
cache_length, assembler);
__ Dispatch();
......@@ -1984,7 +1987,7 @@ void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
Node* cache_type = __ Projection(0, result_triple);
Node* cache_array = __ Projection(1, result_triple);
Node* cache_length = __ Projection(2, result_triple);
Node* output_register = __ BytecodeOperandReg(0);
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, cache_type, cache_array,
cache_length, assembler);
__ Dispatch();
......@@ -1993,7 +1996,7 @@ void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) {
__ Bind(&nothing_to_iterate);
{
// Receiver is null or undefined or descriptors are zero length.
Node* output_register = __ BytecodeOperandReg(0);
Node* output_register = __ BytecodeOperandReg(1);
BuildForInPrepareResult(output_register, zero_smi, zero_smi, zero_smi,
assembler);
__ Dispatch();
......
......@@ -72,9 +72,8 @@ bytecodes: [
B(Star), R(1),
/* 68 S> */ B(JumpIfUndefined), U8(37),
B(JumpIfNull), U8(35),
B(ToObject),
B(ForInPrepare), R(4),
B(Star), R(3),
B(ToObject), R(3),
B(ForInPrepare), R(3), R(4),
B(LdaZero),
B(Star), R(7),
/* 63 S> */ B(ForInDone), R(7), R(6),
......@@ -113,9 +112,8 @@ bytecodes: [
/* 59 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(3),
B(JumpIfUndefined), U8(44),
B(JumpIfNull), U8(42),
B(ToObject),
B(ForInPrepare), R(4),
B(Star), R(3),
B(ToObject), R(3),
B(ForInPrepare), R(3), R(4),
B(LdaZero),
B(Star), R(7),
/* 54 S> */ B(ForInDone), R(7), R(6),
......@@ -160,9 +158,8 @@ bytecodes: [
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(3),
B(JumpIfUndefined), U8(65),
B(JumpIfNull), U8(63),
B(ToObject),
B(ForInPrepare), R(2),
B(Star), R(1),
B(ToObject), R(1),
B(ForInPrepare), R(1), R(2),
B(LdaZero),
B(Star), R(5),
/* 68 S> */ B(ForInDone), R(5), R(4),
......@@ -213,9 +210,8 @@ bytecodes: [
/* 72 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(3),
B(JumpIfUndefined), U8(48),
B(JumpIfNull), U8(46),
B(ToObject),
B(ForInPrepare), R(2),
B(Star), R(1),
B(ToObject), R(1),
B(ForInPrepare), R(1), R(2),
B(LdaZero),
B(Star), R(5),
/* 65 S> */ B(ForInDone), R(5), R(4),
......
......@@ -1087,7 +1087,7 @@ snippet: "
"
frame size: 163
parameter count: 1
bytecode array length: 82
bytecode array length: 83
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 1503 S> */ B(Wide), B(LdaSmi), U16(1234),
......@@ -1095,11 +1095,10 @@ bytecodes: [
/* 1518 S> */ B(LdaZero),
B(Star), R(1),
/* 1534 S> */ B(Ldar), R(0),
B(JumpIfUndefined), U8(67),
B(JumpIfNull), U8(65),
B(ToObject),
B(Wide), B(ForInPrepare), R16(158),
B(Wide), B(Star), R16(157),
B(JumpIfUndefined), U8(68),
B(JumpIfNull), U8(66),
B(Wide), B(ToObject), R16(157),
B(Wide), B(ForInPrepare), R16(157), R16(158),
B(LdaZero),
B(Wide), B(Star), R16(161),
/* 1526 S> */ B(Wide), B(ForInDone), R16(161), R16(160),
......
......@@ -13,13 +13,12 @@ snippet: "
"
frame size: 4
parameter count: 1
bytecode array length: 25
bytecode array length: 24
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1),
B(Star), R(1),
B(ToObject),
B(Star), R(2),
B(ToObject), R(2),
B(Mov), R(closure), R(3),
B(CallRuntime), U16(Runtime::kPushWithContext), R(2), U8(2),
B(PushContext), R(0),
......
......@@ -181,7 +181,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit cast operator invocations.
builder.CastAccumulatorToNumber(reg)
.CastAccumulatorToJSObject()
.CastAccumulatorToJSObject(reg)
.CastAccumulatorToName(reg);
// Emit control flow. Return must be the last instruction.
......@@ -267,11 +267,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
BytecodeLabel after_rethrow;
builder.ReThrow().Bind(&after_rethrow);
builder.ForInPrepare(reg)
builder.ForInPrepare(reg, reg)
.ForInDone(reg, reg)
.ForInNext(reg, reg, reg, 1)
.ForInStep(reg);
builder.ForInPrepare(wide)
builder.ForInPrepare(reg, wide)
.ForInDone(reg, other)
.ForInNext(wide, wide, wide, 1024)
.ForInStep(reg);
......
......@@ -55,7 +55,7 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
.BinaryOperation(Token::Value::ADD, reg_0)
.StoreAccumulatorInRegister(param)
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, 1, reg_0)
.ForInPrepare(reg_0)
.ForInPrepare(reg_0, reg_0)
.CallRuntime(Runtime::kLoadIC_Miss, reg_0, 1)
.Debugger()
.LoadGlobal(0x10000000, TypeofMode::NOT_INSIDE_TYPEOF)
......@@ -239,7 +239,9 @@ TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
CHECK_EQ(iterator.current_offset(), offset);
CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
CHECK_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
CHECK_EQ(iterator.GetRegisterOperandRange(0), 3);
CHECK_EQ(iterator.GetRegisterOperandRange(0), 1);
CHECK_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
CHECK_EQ(iterator.GetRegisterOperandRange(1), 3);
CHECK(!iterator.done());
offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
iterator.Advance();
......
......@@ -163,9 +163,8 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
/* 3 42 E> */ B(Star), R8(1),
/* 5 68 S> */ B(JumpIfUndefined), U8(38),
/* 7 */ B(JumpIfNull), U8(36),
/* 9 */ B(ToObject),
/* 10 */ B(Star), R8(3),
/* 12 */ B(ForInPrepare), R8(4),
/* 9 */ B(ToObject), R8(3),
/* 11 */ B(ForInPrepare), R8(3), R8(4),
/* 14 */ B(LdaZero),
/* 15 */ B(Star), R8(7),
/* 17 63 S> */ B(ForInDone), R8(7), R8(6),
......@@ -199,11 +198,9 @@ TEST_F(BytecodeArrayWriterUnittest, ComplexExample) {
CHECK_EQ(max_register_count(), 2);
WriteJump(Bytecode::kJumpIfUndefined, &jump_end_1, {68, true});
WriteJump(Bytecode::kJumpIfNull, &jump_end_2);
Write(Bytecode::kToObject);
CHECK_EQ(max_register_count(), 2);
Write(Bytecode::kStar, R(3));
Write(Bytecode::kToObject, R(3));
CHECK_EQ(max_register_count(), 4);
Write(Bytecode::kForInPrepare, R(4));
Write(Bytecode::kForInPrepare, R(3), R(4));
CHECK_EQ(max_register_count(), 7);
Write(Bytecode::kLdaZero);
CHECK_EQ(max_register_count(), 7);
......
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