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