Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 5c0703bc37434ea91b475990e4f09349a596b2c2..d4e666ffdef00a1ee96746792c1395ba2e85f54a 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3457,73 +3457,70 @@ 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()); |
- // The array is expected in the bailout environment during computation |
- // of the property values and is the value of the entire expression. |
- PushAndAdd(literal); |
- |
- HLoadElements* elements = NULL; |
- |
- for (int i = 0; i < length; i++) { |
- Expression* subexpr = subexprs->at(i); |
- // If the subexpression is a literal or a simple materialized literal it |
- // is already set in the cloned array. |
- if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
+ FixedArray* literals = environment()->closure()->literals(); |
+ Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
- CHECK_ALIVE(VisitForValue(subexpr)); |
- HValue* value = Pop(); |
- if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
- |
- elements = new(zone()) HLoadElements(literal); |
- AddInstruction(elements); |
- |
- 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); |
+ // For now, no boilerplate causes a deopt. |
+ if (raw_boilerplate->IsUndefined()) { |
+ AddInstruction(new(zone()) HSoftDeoptimize); |
+ return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
+ } else { |
Jakob Kummerow
2011/11/30 14:04:51
Since the if-branch ends with a return statement,
danno
2011/12/01 14:41:11
Done.
|
+ 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); |
+ |
+ HLoadElements* elements = NULL; |
+ |
+ for (int i = 0; i < length; i++) { |
+ Expression* subexpr = subexprs->at(i); |
+ // If the subexpression is a literal or a simple materialized literal it |
+ // is already set in the cloned array. |
+ if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
+ |
+ CHECK_ALIVE(VisitForValue(subexpr)); |
+ HValue* value = Pop(); |
+ if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
+ |
+ elements = new(zone()) HLoadElements(literal); |
+ AddInstruction(elements); |
+ |
+ HValue* key = AddInstruction( |
+ new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), |
+ Representation::Integer32())); |
+ |
+ switch (boilerplate_elements_kind) { |
+ case FAST_SMI_ONLY_ELEMENTS: |
+ case FAST_ELEMENTS: |
+ AddInstruction(new(zone()) HStoreKeyedFastElement( |
Jakob Kummerow
2011/11/30 14:04:51
Hm... this will deopt if |value| doesn't match |bo
danno
2011/12/01 14:41:11
Done.
|
+ 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)); |
+ AddSimulate(expr->GetIdForElement(i)); |
+ } |
+ return ast_context()->ReturnValue(Pop()); |
} |
- return ast_context()->ReturnValue(Pop()); |
} |