Chromium Code Reviews| 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 |