OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3448 | 3448 |
3449 | 3449 |
3450 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 3450 void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
3451 ASSERT(!HasStackOverflow()); | 3451 ASSERT(!HasStackOverflow()); |
3452 ASSERT(current_block() != NULL); | 3452 ASSERT(current_block() != NULL); |
3453 ASSERT(current_block()->HasPredecessor()); | 3453 ASSERT(current_block()->HasPredecessor()); |
3454 ZoneList<Expression*>* subexprs = expr->values(); | 3454 ZoneList<Expression*>* subexprs = expr->values(); |
3455 int length = subexprs->length(); | 3455 int length = subexprs->length(); |
3456 HValue* context = environment()->LookupContext(); | 3456 HValue* context = environment()->LookupContext(); |
3457 | 3457 |
3458 HArrayLiteral* literal = new(zone()) HArrayLiteral(context, | 3458 FixedArray* literals = environment()->closure()->literals(); |
3459 expr->constant_elements(), | 3459 Handle<Object> raw_boilerplate(literals->get(expr->literal_index())); |
3460 length, | 3460 |
3461 expr->literal_index(), | 3461 // For now, no boilerplate causes a deopt. |
3462 expr->depth()); | 3462 if (raw_boilerplate->IsUndefined()) { |
| 3463 AddInstruction(new(zone()) HSoftDeoptimize); |
| 3464 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
| 3465 } |
| 3466 |
| 3467 Handle<JSObject> boilerplate(Handle<JSObject>::cast(raw_boilerplate)); |
| 3468 ElementsKind boilerplate_elements_kind = boilerplate->GetElementsKind(); |
| 3469 |
| 3470 HArrayLiteral* literal = new(zone()) HArrayLiteral( |
| 3471 context, |
| 3472 boilerplate, |
| 3473 length, |
| 3474 expr->literal_index(), |
| 3475 expr->depth()); |
| 3476 |
3463 // The array is expected in the bailout environment during computation | 3477 // The array is expected in the bailout environment during computation |
3464 // of the property values and is the value of the entire expression. | 3478 // of the property values and is the value of the entire expression. |
3465 PushAndAdd(literal); | 3479 PushAndAdd(literal); |
3466 | 3480 |
3467 HLoadElements* elements = NULL; | 3481 HLoadElements* elements = NULL; |
3468 | 3482 |
3469 for (int i = 0; i < length; i++) { | 3483 for (int i = 0; i < length; i++) { |
3470 Expression* subexpr = subexprs->at(i); | 3484 Expression* subexpr = subexprs->at(i); |
3471 // If the subexpression is a literal or a simple materialized literal it | 3485 // If the subexpression is a literal or a simple materialized literal it |
3472 // is already set in the cloned array. | 3486 // is already set in the cloned array. |
3473 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 3487 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
3474 | 3488 |
3475 CHECK_ALIVE(VisitForValue(subexpr)); | 3489 CHECK_ALIVE(VisitForValue(subexpr)); |
3476 HValue* value = Pop(); | 3490 HValue* value = Pop(); |
3477 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 3491 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
3478 | 3492 |
3479 elements = new(zone()) HLoadElements(literal); | 3493 elements = new(zone()) HLoadElements(literal); |
3480 AddInstruction(elements); | 3494 AddInstruction(elements); |
3481 | 3495 |
3482 HValue* key = AddInstruction( | 3496 HValue* key = AddInstruction( |
3483 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), | 3497 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), |
3484 Representation::Integer32())); | 3498 Representation::Integer32())); |
3485 HInstruction* elements_kind = | |
3486 AddInstruction(new(zone()) HElementsKind(literal)); | |
3487 HBasicBlock* store_fast = graph()->CreateBasicBlock(); | |
3488 // Two empty blocks to satisfy edge split form. | |
3489 HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock(); | |
3490 HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock(); | |
3491 HBasicBlock* store_generic = graph()->CreateBasicBlock(); | |
3492 HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock(); | |
3493 HBasicBlock* join = graph()->CreateBasicBlock(); | |
3494 | 3499 |
3495 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value); | 3500 switch (boilerplate_elements_kind) { |
3496 smicheck->SetSuccessorAt(0, store_fast_edgesplit1); | 3501 case FAST_SMI_ONLY_ELEMENTS: |
3497 smicheck->SetSuccessorAt(1, check_smi_only_elements); | 3502 case FAST_ELEMENTS: |
3498 current_block()->Finish(smicheck); | 3503 AddInstruction(new(zone()) HStoreKeyedFastElement( |
3499 store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast)); | 3504 elements, |
3500 | 3505 key, |
3501 set_current_block(check_smi_only_elements); | 3506 value, |
3502 HCompareConstantEqAndBranch* smi_elements_check = | 3507 boilerplate_elements_kind)); |
3503 new(zone()) HCompareConstantEqAndBranch(elements_kind, | 3508 break; |
3504 FAST_ELEMENTS, | 3509 case FAST_DOUBLE_ELEMENTS: |
3505 Token::EQ_STRICT); | 3510 AddInstruction(new(zone()) HStoreKeyedFastDoubleElement(elements, |
3506 smi_elements_check->SetSuccessorAt(0, store_fast_edgesplit2); | 3511 key, |
3507 smi_elements_check->SetSuccessorAt(1, store_generic); | 3512 value)); |
3508 current_block()->Finish(smi_elements_check); | 3513 break; |
3509 store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast)); | 3514 default: |
3510 | 3515 UNREACHABLE(); |
3511 set_current_block(store_fast); | 3516 break; |
3512 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); | 3517 } |
3513 store_fast->Goto(join); | |
3514 | |
3515 set_current_block(store_generic); | |
3516 AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); | |
3517 store_generic->Goto(join); | |
3518 | |
3519 join->SetJoinId(expr->id()); | |
3520 set_current_block(join); | |
3521 | 3518 |
3522 AddSimulate(expr->GetIdForElement(i)); | 3519 AddSimulate(expr->GetIdForElement(i)); |
3523 } | 3520 } |
3524 return ast_context()->ReturnValue(Pop()); | 3521 return ast_context()->ReturnValue(Pop()); |
3525 } | 3522 } |
3526 | 3523 |
3527 | 3524 |
3528 // Sets the lookup result and returns true if the store can be inlined. | 3525 // Sets the lookup result and returns true if the store can be inlined. |
3529 static bool ComputeStoredField(Handle<Map> type, | 3526 static bool ComputeStoredField(Handle<Map> type, |
3530 Handle<String> name, | 3527 Handle<String> name, |
(...skipping 3691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7222 } | 7219 } |
7223 } | 7220 } |
7224 | 7221 |
7225 #ifdef DEBUG | 7222 #ifdef DEBUG |
7226 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 7223 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
7227 if (allocator_ != NULL) allocator_->Verify(); | 7224 if (allocator_ != NULL) allocator_->Verify(); |
7228 #endif | 7225 #endif |
7229 } | 7226 } |
7230 | 7227 |
7231 } } // namespace v8::internal | 7228 } } // namespace v8::internal |
OLD | NEW |