OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 current_subgraph_->exit_block()->Finish( | 3096 current_subgraph_->exit_block()->Finish( |
3097 new HCompareMapAndBranch(receiver, | 3097 new HCompareMapAndBranch(receiver, |
3098 Handle<Map>(maps->first()), | 3098 Handle<Map>(maps->first()), |
3099 subgraphs->first()->entry_block(), | 3099 subgraphs->first()->entry_block(), |
3100 else_subgraph->entry_block())); | 3100 else_subgraph->entry_block())); |
3101 | 3101 |
3102 // Join all the call subgraphs in a new basic block and make | 3102 // Join all the call subgraphs in a new basic block and make |
3103 // this basic block the current basic block. | 3103 // this basic block the current basic block. |
3104 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 3104 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
3105 for (int i = 0; i < subgraphs->length(); ++i) { | 3105 for (int i = 0; i < subgraphs->length(); ++i) { |
3106 if (subgraphs->at(i)->HasExit()) { | 3106 HSubgraph* subgraph = subgraphs->at(i); |
3107 subgraphs->at(i)->exit_block()->Goto(join_block); | 3107 if (subgraph->HasExit()) { |
| 3108 // In an effect context the value of the type switch is not needed. |
| 3109 // There is no need to merge it at the join block only to discard it. |
| 3110 HBasicBlock* subgraph_exit = subgraph->exit_block(); |
| 3111 if (ast_context()->IsEffect()) { |
| 3112 subgraph_exit->last_environment()->Drop(1); |
| 3113 } |
| 3114 subgraph_exit->Goto(join_block); |
3108 } | 3115 } |
3109 } | 3116 } |
3110 | 3117 |
3111 if (join_block->predecessors()->is_empty()) return NULL; | 3118 if (join_block->predecessors()->is_empty()) return NULL; |
3112 join_block->SetJoinId(join_id); | 3119 join_block->SetJoinId(join_id); |
3113 return join_block; | 3120 return join_block; |
3114 } | 3121 } |
3115 | 3122 |
3116 | 3123 |
3117 // Sets the lookup result and returns true if the store can be inlined. | 3124 // Sets the lookup result and returns true if the store can be inlined. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3235 } | 3242 } |
3236 } | 3243 } |
3237 | 3244 |
3238 // If none of the properties were named fields we generate a | 3245 // If none of the properties were named fields we generate a |
3239 // generic store. | 3246 // generic store. |
3240 if (maps.length() == 0) { | 3247 if (maps.length() == 0) { |
3241 HInstruction* instr = new HStoreNamedGeneric(object, name, value); | 3248 HInstruction* instr = new HStoreNamedGeneric(object, name, value); |
3242 Push(value); | 3249 Push(value); |
3243 instr->set_position(expr->position()); | 3250 instr->set_position(expr->position()); |
3244 AddInstruction(instr); | 3251 AddInstruction(instr); |
3245 if (instr->HasSideEffects()) AddSimulate(expr->id()); | 3252 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3253 ast_context()->ReturnValue(Pop()); |
3246 } else { | 3254 } else { |
3247 // Build subgraph for generic store through IC. | 3255 // Build subgraph for generic store through IC. |
3248 { | 3256 { |
3249 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3257 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
3250 SubgraphScope scope(this, subgraph); | 3258 SubgraphScope scope(this, subgraph); |
3251 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3259 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
3252 subgraph->FinishExit(new HDeoptimize()); | 3260 subgraph->FinishExit(new HDeoptimize()); |
3253 } else { | 3261 } else { |
3254 HInstruction* instr = new HStoreNamedGeneric(object, name, value); | 3262 HInstruction* instr = new HStoreNamedGeneric(object, name, value); |
3255 Push(value); | 3263 Push(value); |
3256 instr->set_position(expr->position()); | 3264 instr->set_position(expr->position()); |
3257 AddInstruction(instr); | 3265 AddInstruction(instr); |
3258 } | 3266 } |
3259 subgraphs.Add(subgraph); | 3267 subgraphs.Add(subgraph); |
3260 } | 3268 } |
3261 | 3269 |
3262 HBasicBlock* new_exit_block = | 3270 HBasicBlock* new_exit_block = |
3263 BuildTypeSwitch(&maps, &subgraphs, object, expr->AssignmentId()); | 3271 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); |
3264 subgraph()->set_exit_block(new_exit_block); | 3272 subgraph()->set_exit_block(new_exit_block); |
| 3273 // In an effect context, we did not materialized the value in the |
| 3274 // predecessor environments so there's no need to handle it here. |
| 3275 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { |
| 3276 ast_context()->ReturnValue(Pop()); |
| 3277 } |
3265 } | 3278 } |
3266 | |
3267 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop()); | |
3268 } | 3279 } |
3269 | 3280 |
3270 | 3281 |
3271 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 3282 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
3272 Property* prop = expr->target()->AsProperty(); | 3283 Property* prop = expr->target()->AsProperty(); |
3273 ASSERT(prop != NULL); | 3284 ASSERT(prop != NULL); |
3274 expr->RecordTypeFeedback(oracle()); | 3285 expr->RecordTypeFeedback(oracle()); |
3275 VISIT_FOR_VALUE(prop->obj()); | 3286 VISIT_FOR_VALUE(prop->obj()); |
3276 | 3287 |
3277 HValue* value = NULL; | 3288 HValue* value = NULL; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3541 } else { | 3552 } else { |
3542 needs_generic = true; | 3553 needs_generic = true; |
3543 } | 3554 } |
3544 } | 3555 } |
3545 | 3556 |
3546 // If none of the properties were named fields we generate a | 3557 // If none of the properties were named fields we generate a |
3547 // generic load. | 3558 // generic load. |
3548 if (maps.length() == 0) { | 3559 if (maps.length() == 0) { |
3549 HInstruction* instr = BuildLoadNamedGeneric(object, expr); | 3560 HInstruction* instr = BuildLoadNamedGeneric(object, expr); |
3550 instr->set_position(expr->position()); | 3561 instr->set_position(expr->position()); |
3551 PushAndAdd(instr); | 3562 ast_context()->ReturnInstruction(instr, expr->id()); |
3552 if (instr->HasSideEffects()) AddSimulate(expr->id()); | |
3553 } else { | 3563 } else { |
3554 // Build subgraph for generic load through IC. | 3564 // Build subgraph for generic load through IC. |
3555 { | 3565 { |
3556 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3566 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
3557 SubgraphScope scope(this, subgraph); | 3567 SubgraphScope scope(this, subgraph); |
3558 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3568 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
3559 subgraph->FinishExit(new HDeoptimize()); | 3569 subgraph->FinishExit(new HDeoptimize()); |
3560 } else { | 3570 } else { |
3561 HInstruction* instr = BuildLoadNamedGeneric(object, expr); | 3571 HInstruction* instr = BuildLoadNamedGeneric(object, expr); |
3562 instr->set_position(expr->position()); | 3572 instr->set_position(expr->position()); |
3563 PushAndAdd(instr); | 3573 PushAndAdd(instr); |
3564 } | 3574 } |
3565 subgraphs.Add(subgraph); | 3575 subgraphs.Add(subgraph); |
3566 } | 3576 } |
3567 | 3577 |
3568 HBasicBlock* new_exit_block = | 3578 HBasicBlock* new_exit_block = |
3569 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); | 3579 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); |
3570 subgraph()->set_exit_block(new_exit_block); | 3580 subgraph()->set_exit_block(new_exit_block); |
| 3581 // In an effect context, we did not materialized the value in the |
| 3582 // predecessor environments so there's no need to handle it here. |
| 3583 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { |
| 3584 ast_context()->ReturnValue(Pop()); |
| 3585 } |
3571 } | 3586 } |
3572 | |
3573 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop()); | |
3574 } | 3587 } |
3575 | 3588 |
3576 | 3589 |
3577 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 3590 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
3578 Property* expr, | 3591 Property* expr, |
3579 Handle<Map> type, | 3592 Handle<Map> type, |
3580 LookupResult* lookup, | 3593 LookupResult* lookup, |
3581 bool smi_and_map_check) { | 3594 bool smi_and_map_check) { |
3582 if (smi_and_map_check) { | 3595 if (smi_and_map_check) { |
3583 AddInstruction(new HCheckNonSmi(object)); | 3596 AddInstruction(new HCheckNonSmi(object)); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3849 call->set_position(expr->position()); | 3862 call->set_position(expr->position()); |
3850 ProcessCall(call); | 3863 ProcessCall(call); |
3851 PushAndAdd(call); | 3864 PushAndAdd(call); |
3852 } | 3865 } |
3853 subgraphs.Add(subgraph); | 3866 subgraphs.Add(subgraph); |
3854 } | 3867 } |
3855 | 3868 |
3856 HBasicBlock* new_exit_block = | 3869 HBasicBlock* new_exit_block = |
3857 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); | 3870 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); |
3858 subgraph()->set_exit_block(new_exit_block); | 3871 subgraph()->set_exit_block(new_exit_block); |
3859 if (new_exit_block != NULL) ast_context()->ReturnValue(Pop()); | 3872 // In an effect context, we did not materialized the value in the |
| 3873 // predecessor environments so there's no need to handle it here. |
| 3874 if (new_exit_block != NULL && !ast_context()->IsEffect()) { |
| 3875 ast_context()->ReturnValue(Pop()); |
| 3876 } |
3860 } | 3877 } |
3861 } | 3878 } |
3862 | 3879 |
3863 | 3880 |
3864 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) { | 3881 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) { |
3865 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); | 3882 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); |
3866 SmartPointer<char> caller = | 3883 SmartPointer<char> caller = |
3867 graph()->info()->function()->debug_name()->ToCString(); | 3884 graph()->info()->function()->debug_name()->ToCString(); |
3868 if (result) { | 3885 if (result) { |
3869 PrintF("Inlined %s called from %s.\n", *callee, *caller); | 3886 PrintF("Inlined %s called from %s.\n", *callee, *caller); |
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5759 } | 5776 } |
5760 | 5777 |
5761 #ifdef DEBUG | 5778 #ifdef DEBUG |
5762 if (graph_ != NULL) graph_->Verify(); | 5779 if (graph_ != NULL) graph_->Verify(); |
5763 if (chunk_ != NULL) chunk_->Verify(); | 5780 if (chunk_ != NULL) chunk_->Verify(); |
5764 if (allocator_ != NULL) allocator_->Verify(); | 5781 if (allocator_ != NULL) allocator_->Verify(); |
5765 #endif | 5782 #endif |
5766 } | 5783 } |
5767 | 5784 |
5768 } } // namespace v8::internal | 5785 } } // namespace v8::internal |
OLD | NEW |