Commit a86fa968 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[interpreter] Refactor VisitArrayLiteral.

This factors out the element insertion code, so that it can be reused
elsewhere in a follow-up CL.

Change-Id: Ic085c8359b3024f381803ce64b49e976018277f9
Reviewed-on: https://chromium-review.googlesource.com/1010068Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52592}
parent a3b60675
...@@ -1429,6 +1429,8 @@ class ArrayLiteral final : public AggregateLiteral { ...@@ -1429,6 +1429,8 @@ class ArrayLiteral final : public AggregateLiteral {
ZoneList<Expression*>* values() const { return values_; } ZoneList<Expression*>* values() const { return values_; }
int first_spread_index() const { return first_spread_index_; }
bool is_empty() const; bool is_empty() const;
// Populate the depth field and flags, returns the depth. // Populate the depth field and flags, returns the depth.
...@@ -1453,16 +1455,6 @@ class ArrayLiteral final : public AggregateLiteral { ...@@ -1453,16 +1455,6 @@ class ArrayLiteral final : public AggregateLiteral {
return AggregateLiteral::ComputeFlags(disable_mementos); return AggregateLiteral::ComputeFlags(disable_mementos);
} }
// Provide a mechanism for iterating through values to rewrite spreads.
ZoneList<Expression*>::iterator FirstSpreadOrEndValue() const {
return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_
: values_->end();
}
ZoneList<Expression*>::iterator BeginValue() const {
return values_->begin();
}
ZoneList<Expression*>::iterator EndValue() const { return values_->end(); }
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
......
...@@ -1325,7 +1325,7 @@ void AstPrinter::VisitCompareOperation(CompareOperation* node) { ...@@ -1325,7 +1325,7 @@ void AstPrinter::VisitCompareOperation(CompareOperation* node) {
void AstPrinter::VisitSpread(Spread* node) { void AstPrinter::VisitSpread(Spread* node) {
IndentedScope indent(this, "...", node->position()); IndentedScope indent(this, "SPREAD", node->position());
Visit(node->expression()); Visit(node->expression());
} }
......
...@@ -2300,52 +2300,35 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -2300,52 +2300,35 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
builder()->LoadAccumulatorWithRegister(literal); builder()->LoadAccumulatorWithRegister(literal);
} }
void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { void BytecodeGenerator::BuildArrayLiteralElementsInsertion(
expr->InitDepthAndFlags(); Register array, int first_spread_index, ZoneList<Expression*>* elements,
bool skip_constants) {
// Deep-copy the literal boilerplate.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
if (expr->is_empty()) {
// Empty array literal fast-path.
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyArrayLiteral(literal_index);
return;
}
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
builder()->CreateArrayLiteral(entry, literal_index, flags);
array_literals_.push_back(std::make_pair(expr, entry));
Register literal = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(literal);
// We'll reuse the same literal slot for all of the non-constant
// subexpressions that use a keyed store IC.
Register index = register_allocator()->NewRegister(); Register index = register_allocator()->NewRegister();
int array_index = 0; int array_index = 0;
// Evaluate all the non-constant subexpressions and store them into the ZoneList<Expression*>::iterator iter = elements->begin();
// newly cloned array. ZoneList<Expression*>::iterator first_spread_or_end =
FeedbackSlot slot; first_spread_index >= 0 ? elements->begin() + first_spread_index
ZoneList<Expression*>::iterator iter = expr->BeginValue(); : elements->end();
for (; iter != expr->FirstSpreadOrEndValue(); ++iter, array_index++) {
// Evaluate subexpressions and store them into the array.
FeedbackSlot keyed_store_slot;
for (; iter != first_spread_or_end; ++iter, array_index++) {
Expression* subexpr = *iter; Expression* subexpr = *iter;
DCHECK(!subexpr->IsSpread()); DCHECK(!subexpr->IsSpread());
if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; if (skip_constants && CompileTimeValue::IsCompileTimeValue(subexpr))
if (slot.IsInvalid()) { continue;
slot = feedback_spec()->AddKeyedStoreICSlot(language_mode()); if (keyed_store_slot.IsInvalid()) {
keyed_store_slot = feedback_spec()->AddKeyedStoreICSlot(language_mode());
} }
builder() builder()
->LoadLiteral(Smi::FromInt(array_index)) ->LoadLiteral(Smi::FromInt(array_index))
.StoreAccumulatorInRegister(index); .StoreAccumulatorInRegister(index);
VisitForAccumulatorValue(subexpr); VisitForAccumulatorValue(subexpr);
builder()->StoreKeyedProperty(literal, index, feedback_index(slot), builder()->StoreKeyedProperty(
language_mode()); array, index, feedback_index(keyed_store_slot), language_mode());
} }
if (iter != expr->EndValue()) { if (iter != elements->end()) {
builder()->LoadLiteral(array_index).StoreAccumulatorInRegister(index); builder()->LoadLiteral(array_index).StoreAccumulatorInRegister(index);
// Handle the first spread element and everything that follows. // Handle the first spread element and everything that follows.
...@@ -2354,16 +2337,16 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -2354,16 +2337,16 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
// TODO(neis): Only create length_slot when there are holes. // TODO(neis): Only create length_slot when there are holes.
FeedbackSlot length_slot = FeedbackSlot length_slot =
feedback_spec()->AddStoreICSlot(LanguageMode::kStrict); feedback_spec()->AddStoreICSlot(LanguageMode::kStrict);
for (; iter != expr->EndValue(); ++iter) { for (; iter != elements->end(); ++iter) {
Expression* subexpr = *iter; Expression* subexpr = *iter;
if (subexpr->IsSpread()) { if (subexpr->IsSpread()) {
BuildArrayLiteralSpread(subexpr->AsSpread(), literal, index, index_slot, BuildArrayLiteralSpread(subexpr->AsSpread(), array, index, index_slot,
element_slot); element_slot);
} else if (!subexpr->IsTheHoleLiteral()) { } else if (!subexpr->IsTheHoleLiteral()) {
// literal[index++] = subexpr // literal[index++] = subexpr
VisitForAccumulatorValue(subexpr); VisitForAccumulatorValue(subexpr);
builder() builder()
->StoreInArrayLiteral(literal, index, feedback_index(element_slot)) ->StoreInArrayLiteral(array, index, feedback_index(element_slot))
.LoadAccumulatorWithRegister(index) .LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot)) .UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index); .StoreAccumulatorInRegister(index);
...@@ -2374,14 +2357,37 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -2374,14 +2357,37 @@ void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
->LoadAccumulatorWithRegister(index) ->LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot)) .UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index) .StoreAccumulatorInRegister(index)
.StoreNamedProperty(literal, length, feedback_index(length_slot), .StoreNamedProperty(array, length, feedback_index(length_slot),
LanguageMode::kStrict); LanguageMode::kStrict);
} }
} }
} }
builder()->LoadAccumulatorWithRegister(array);
}
// Restore literal array into accumulator. void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
builder()->LoadAccumulatorWithRegister(literal); expr->InitDepthAndFlags();
// Deep-copy the literal boilerplate.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
if (expr->is_empty()) {
// Empty array literal fast-path.
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyArrayLiteral(literal_index);
return;
}
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
size_t entry = builder()->AllocateDeferredConstantPoolEntry();
builder()->CreateArrayLiteral(entry, literal_index, flags);
array_literals_.push_back(std::make_pair(expr, entry));
Register literal = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(literal);
// Insert all elements except the constant ones, since they are already there.
BuildArrayLiteralElementsInsertion(literal, expr->first_spread_index(),
expr->values(), true);
} }
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array, void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
......
...@@ -177,6 +177,10 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -177,6 +177,10 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index, void BuildArrayLiteralSpread(Spread* spread, Register array, Register index,
FeedbackSlot index_slot, FeedbackSlot index_slot,
FeedbackSlot element_slot); FeedbackSlot element_slot);
void BuildArrayLiteralElementsInsertion(Register array,
int first_spread_index,
ZoneList<Expression*>* elements,
bool skip_constants);
void AllocateTopLevelRegisters(); void AllocateTopLevelRegisters();
void VisitArgumentsObject(Variable* variable); void VisitArgumentsObject(Variable* variable);
......
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