Chromium Code Reviews| 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()); |
| } |