Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index c90d38cc5c0ed57fa7ca26636728955735f2dc59..422976d46de23f5afd4a8698bcc683dde885f748 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3455,11 +3455,25 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
int length = subexprs->length(); |
HValue* context = environment()->LookupContext(); |
- HArrayLiteral* literal = new(zone()) HArrayLiteral(context, |
- expr->constant_elements(), |
- length, |
- expr->literal_index(), |
- expr->depth()); |
+ FixedArray* literals = environment()->closure()->literals(); |
+ Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
+ |
+ // For now, no boilerplate causes a deopt. |
+ if (raw_boilerplate->IsUndefined()) { |
+ AddInstruction(new(zone()) HSoftDeoptimize); |
+ return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
+ } |
+ |
+ Handle<JSObject> boilerplate(Handle<JSObject>::cast(raw_boilerplate)); |
+ ElementsKind boilerplate_elements_kind = boilerplate->GetElementsKind(); |
+ |
+ HArrayLiteral* literal = new(zone()) HArrayLiteral( |
+ context, |
+ boilerplate, |
+ length, |
+ expr->literal_index(), |
+ expr->depth()); |
+ |
// The array is expected in the bailout environment during computation |
// of the property values and is the value of the entire expression. |
PushAndAdd(literal); |
@@ -3482,42 +3496,25 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
HValue* key = AddInstruction( |
new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), |
Representation::Integer32())); |
- HInstruction* elements_kind = |
- AddInstruction(new(zone()) HElementsKind(literal)); |
- HBasicBlock* store_fast = graph()->CreateBasicBlock(); |
- // Two empty blocks to satisfy edge split form. |
- HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock(); |
- HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock(); |
- HBasicBlock* store_generic = graph()->CreateBasicBlock(); |
- HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock(); |
- HBasicBlock* join = graph()->CreateBasicBlock(); |
- |
- HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value); |
- smicheck->SetSuccessorAt(0, store_fast_edgesplit1); |
- smicheck->SetSuccessorAt(1, check_smi_only_elements); |
- current_block()->Finish(smicheck); |
- store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast)); |
- |
- set_current_block(check_smi_only_elements); |
- HCompareConstantEqAndBranch* smi_elements_check = |
- new(zone()) HCompareConstantEqAndBranch(elements_kind, |
- FAST_ELEMENTS, |
- Token::EQ_STRICT); |
- smi_elements_check->SetSuccessorAt(0, store_fast_edgesplit2); |
- smi_elements_check->SetSuccessorAt(1, store_generic); |
- current_block()->Finish(smi_elements_check); |
- store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast)); |
- |
- set_current_block(store_fast); |
- AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); |
- store_fast->Goto(join); |
- |
- set_current_block(store_generic); |
- AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); |
- store_generic->Goto(join); |
- join->SetJoinId(expr->id()); |
- set_current_block(join); |
+ switch (boilerplate_elements_kind) { |
+ case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_ELEMENTS: |
+ AddInstruction(new(zone()) HStoreKeyedFastElement( |
+ elements, |
+ key, |
+ value, |
+ boilerplate_elements_kind)); |
+ break; |
+ case FAST_DOUBLE_ELEMENTS: |
+ AddInstruction(new(zone()) HStoreKeyedFastDoubleElement(elements, |
+ key, |
+ value)); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ break; |
+ } |
AddSimulate(expr->GetIdForElement(i)); |
} |