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 3427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3438 HValue* value = environment()->Pop(); | 3438 HValue* value = environment()->Pop(); |
3439 HThrow* instr = new HThrow(value); | 3439 HThrow* instr = new HThrow(value); |
3440 instr->set_position(expr->position()); | 3440 instr->set_position(expr->position()); |
3441 AddInstruction(instr); | 3441 AddInstruction(instr); |
3442 AddSimulate(expr->id()); | 3442 AddSimulate(expr->id()); |
3443 current_block()->FinishExit(new HAbnormalExit); | 3443 current_block()->FinishExit(new HAbnormalExit); |
3444 set_current_block(NULL); | 3444 set_current_block(NULL); |
3445 } | 3445 } |
3446 | 3446 |
3447 | 3447 |
3448 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | |
3449 HValue* object, | |
3450 ZoneMapList* types, | |
3451 Handle<String> name) { | |
3452 // TODO(ager): We should recognize when the prototype chains for different | |
3453 // maps are identical. In that case we can avoid repeatedly generating the | |
3454 // same prototype map checks. | |
3455 int count = 0; | |
3456 HBasicBlock* join = NULL; | |
3457 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { | |
3458 Handle<Map> map = types->at(i); | |
3459 LookupResult lookup; | |
3460 map->LookupInDescriptors(NULL, *name, &lookup); | |
3461 if (lookup.IsProperty() && lookup.type() == FIELD) { | |
3462 if (count == 0) { | |
3463 AddInstruction(new HCheckNonSmi(object)); // Only needed once. | |
3464 join = graph()->CreateBasicBlock(); | |
3465 } | |
3466 ++count; | |
3467 HBasicBlock* if_true = graph()->CreateBasicBlock(); | |
3468 HBasicBlock* if_false = graph()->CreateBasicBlock(); | |
3469 HCompareMap* compare = new HCompareMap(object, map, if_true, if_false); | |
3470 current_block()->Finish(compare); | |
3471 | |
3472 set_current_block(if_true); | |
3473 HLoadNamedField* instr = | |
3474 BuildLoadNamedField(object, expr, map, &lookup, false); | |
3475 instr->set_position(expr->position()); | |
3476 instr->ClearFlag(HValue::kUseGVN); | |
3477 AddInstruction(instr); | |
3478 if (!ast_context()->IsEffect()) Push(instr); | |
3479 current_block()->Goto(join); | |
3480 | |
3481 set_current_block(if_false); | |
3482 } | |
3483 } | |
3484 | |
3485 // Finish up. Unconditionally deoptimize if we've handled all the maps we | |
3486 // know about and do not want to handle ones we've never seen. Otherwise | |
3487 // use a generic IC. | |
3488 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | |
3489 current_block()->FinishExitWithDeoptimization(); | |
3490 } else { | |
3491 HInstruction* instr = BuildLoadNamedGeneric(object, expr); | |
3492 instr->set_position(expr->position()); | |
3493 | |
3494 if (join != NULL) { | |
3495 AddInstruction(instr); | |
3496 if (!ast_context()->IsEffect()) Push(instr); | |
3497 current_block()->Goto(join); | |
3498 } else { | |
3499 ast_context()->ReturnInstruction(instr, expr->id()); | |
3500 return; | |
3501 } | |
3502 } | |
3503 | |
3504 ASSERT(join != NULL); | |
3505 join->SetJoinId(expr->id()); | |
3506 set_current_block(join); | |
3507 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | |
3508 } | |
3509 | |
3510 | |
3511 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 3448 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
3512 Property* expr, | 3449 Property* expr, |
3513 Handle<Map> type, | 3450 Handle<Map> type, |
3514 LookupResult* lookup, | 3451 LookupResult* lookup, |
3515 bool smi_and_map_check) { | 3452 bool smi_and_map_check) { |
3516 if (smi_and_map_check) { | 3453 if (smi_and_map_check) { |
3517 AddInstruction(new HCheckNonSmi(object)); | 3454 AddInstruction(new HCheckNonSmi(object)); |
3518 AddInstruction(new HCheckMap(object, type)); | 3455 AddInstruction(new HCheckMap(object, type)); |
3519 } | 3456 } |
3520 | 3457 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3741 instr = new HLoadFunctionPrototype(function); | 3678 instr = new HLoadFunctionPrototype(function); |
3742 | 3679 |
3743 } else if (expr->key()->IsPropertyName()) { | 3680 } else if (expr->key()->IsPropertyName()) { |
3744 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 3681 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
3745 ZoneMapList* types = expr->GetReceiverTypes(); | 3682 ZoneMapList* types = expr->GetReceiverTypes(); |
3746 | 3683 |
3747 HValue* obj = Pop(); | 3684 HValue* obj = Pop(); |
3748 if (expr->IsMonomorphic()) { | 3685 if (expr->IsMonomorphic()) { |
3749 instr = BuildLoadNamed(obj, expr, types->first(), name); | 3686 instr = BuildLoadNamed(obj, expr, types->first(), name); |
3750 } else if (types != NULL && types->length() > 1) { | 3687 } else if (types != NULL && types->length() > 1) { |
3751 HandlePolymorphicLoadNamedField(expr, obj, types, name); | 3688 AddInstruction(new HCheckNonSmi(obj)); |
3752 return; | 3689 instr = new HLoadNamedFieldPolymorphic(obj, types, name); |
3753 | |
3754 } else { | 3690 } else { |
3755 instr = BuildLoadNamedGeneric(obj, expr); | 3691 instr = BuildLoadNamedGeneric(obj, expr); |
3756 } | 3692 } |
3757 | 3693 |
3758 } else { | 3694 } else { |
3759 VISIT_FOR_VALUE(expr->key()); | 3695 VISIT_FOR_VALUE(expr->key()); |
3760 | 3696 |
3761 HValue* key = Pop(); | 3697 HValue* key = Pop(); |
3762 HValue* obj = Pop(); | 3698 HValue* obj = Pop(); |
3763 | 3699 |
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5942 } | 5878 } |
5943 } | 5879 } |
5944 | 5880 |
5945 #ifdef DEBUG | 5881 #ifdef DEBUG |
5946 if (graph_ != NULL) graph_->Verify(); | 5882 if (graph_ != NULL) graph_->Verify(); |
5947 if (allocator_ != NULL) allocator_->Verify(); | 5883 if (allocator_ != NULL) allocator_->Verify(); |
5948 #endif | 5884 #endif |
5949 } | 5885 } |
5950 | 5886 |
5951 } } // namespace v8::internal | 5887 } } // namespace v8::internal |
OLD | NEW |