Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(918)

Side by Side Diff: src/hydrogen.cc

Issue 6516016: Refactor construction of polymorphic loads, stores, and calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 99 }
100 100
101 101
102 void HBasicBlock::AddInstruction(HInstruction* instr) { 102 void HBasicBlock::AddInstruction(HInstruction* instr) {
103 ASSERT(!IsStartBlock() || !IsFinished()); 103 ASSERT(!IsStartBlock() || !IsFinished());
104 ASSERT(!instr->IsLinked()); 104 ASSERT(!instr->IsLinked());
105 ASSERT(!IsFinished()); 105 ASSERT(!IsFinished());
106 if (first_ == NULL) { 106 if (first_ == NULL) {
107 HBlockEntry* entry = new HBlockEntry(); 107 HBlockEntry* entry = new HBlockEntry();
108 entry->InitializeAsFirst(this); 108 entry->InitializeAsFirst(this);
109 first_ = entry; 109 first_ = last_ = entry;
110 } 110 }
111 instr->InsertAfter(GetLastInstruction()); 111 instr->InsertAfter(last_);
112 last_ = instr;
112 } 113 }
113 114
114 115
115 HInstruction* HBasicBlock::GetLastInstruction() {
116 if (end_ != NULL) return end_->previous();
117 if (first_ == NULL) return NULL;
118 if (last_ == NULL) last_ = first_;
119 while (last_->next() != NULL) last_ = last_->next();
120 return last_;
121 }
122
123
124 HSimulate* HBasicBlock::CreateSimulate(int id) { 116 HSimulate* HBasicBlock::CreateSimulate(int id) {
125 ASSERT(HasEnvironment()); 117 ASSERT(HasEnvironment());
126 HEnvironment* environment = last_environment(); 118 HEnvironment* environment = last_environment();
127 ASSERT(id == AstNode::kNoNumber || 119 ASSERT(id == AstNode::kNoNumber ||
128 environment->closure()->shared()->VerifyBailoutId(id)); 120 environment->closure()->shared()->VerifyBailoutId(id));
129 121
130 int push_count = environment->push_count(); 122 int push_count = environment->push_count();
131 int pop_count = environment->pop_count(); 123 int pop_count = environment->pop_count();
132 124
133 int length = environment->length(); 125 int length = environment->length();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 UpdateEnvironment(env); 163 UpdateEnvironment(env);
172 } 164 }
173 165
174 166
175 void HBasicBlock::SetJoinId(int id) { 167 void HBasicBlock::SetJoinId(int id) {
176 int length = predecessors_.length(); 168 int length = predecessors_.length();
177 ASSERT(length > 0); 169 ASSERT(length > 0);
178 for (int i = 0; i < length; i++) { 170 for (int i = 0; i < length; i++) {
179 HBasicBlock* predecessor = predecessors_[i]; 171 HBasicBlock* predecessor = predecessors_[i];
180 ASSERT(predecessor->end()->IsGoto()); 172 ASSERT(predecessor->end()->IsGoto());
181 HSimulate* simulate = HSimulate::cast(predecessor->GetLastInstruction()); 173 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
182 // We only need to verify the ID once. 174 // We only need to verify the ID once.
183 ASSERT(i != 0 || 175 ASSERT(i != 0 ||
184 predecessor->last_environment()->closure()->shared() 176 predecessor->last_environment()->closure()->shared()
185 ->VerifyBailoutId(id)); 177 ->VerifyBailoutId(id));
186 simulate->set_ast_id(id); 178 simulate->set_ast_id(id);
187 } 179 }
188 } 180 }
189 181
190 182
191 bool HBasicBlock::Dominates(HBasicBlock* other) const { 183 bool HBasicBlock::Dominates(HBasicBlock* other) const {
(...skipping 2887 matching lines...) Expand 10 before | Expand all | Expand 10 after
3079 } 3071 }
3080 ast_context()->ReturnValue(Pop()); 3072 ast_context()->ReturnValue(Pop());
3081 } 3073 }
3082 3074
3083 3075
3084 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) { 3076 void HGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
3085 BAILOUT("CatchExtensionObject"); 3077 BAILOUT("CatchExtensionObject");
3086 } 3078 }
3087 3079
3088 3080
3089 HBasicBlock* HGraphBuilder::BuildTypeSwitch(ZoneMapList* maps, 3081 HBasicBlock* HGraphBuilder::BuildTypeSwitch(HValue* receiver,
3090 ZoneList<HSubgraph*>* subgraphs, 3082 ZoneMapList* maps,
3091 HValue* receiver, 3083 ZoneList<HSubgraph*>* body_graphs,
3084 HSubgraph* default_graph,
3092 int join_id) { 3085 int join_id) {
3093 ASSERT(subgraphs->length() == (maps->length() + 1)); 3086 ASSERT(maps->length() == body_graphs->length());
3087 HBasicBlock* join_block = graph()->CreateBasicBlock();
3088 AddInstruction(new HCheckNonSmi(receiver));
3094 3089
3095 // Build map compare subgraphs for all but the first map. 3090 for (int i = 0; i < maps->length(); ++i) {
3096 ZoneList<HSubgraph*> map_compare_subgraphs(maps->length() - 1); 3091 // Build the branches, connect all the target subgraphs to the join
3097 for (int i = maps->length() - 1; i > 0; --i) { 3092 // block. Use the default as a target of the last branch.
3098 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3093 HSubgraph* if_true = body_graphs->at(i);
3099 SubgraphScope scope(this, subgraph); 3094 HSubgraph* if_false = (i == maps->length() - 1)
3100 HSubgraph* else_subgraph = 3095 ? default_graph
3101 (i == (maps->length() - 1)) 3096 : CreateBranchSubgraph(environment());
3102 ? subgraphs->last() 3097 HCompareMap* compare =
3103 : map_compare_subgraphs.last(); 3098 new HCompareMap(receiver,
3104 HCompareMap* compare = new HCompareMap(receiver, 3099 maps->at(i),
3105 maps->at(i), 3100 if_true->entry_block(),
3106 subgraphs->at(i)->entry_block(), 3101 if_false->entry_block());
3107 else_subgraph->entry_block()); 3102 subgraph()->exit_block()->Finish(compare);
3108 current_subgraph_->exit_block()->Finish(compare); 3103
3109 map_compare_subgraphs.Add(subgraph); 3104 if (if_true->HasExit()) {
3105 // In an effect context the value of the type switch is not needed.
3106 // There is no need to merge it at the join block only to discard it.
3107 if (ast_context()->IsEffect()) {
3108 if_true->exit_block()->last_environment()->Drop(1);
3109 }
3110 if_true->exit_block()->Goto(join_block);
3111 }
3112
3113 subgraph()->set_exit_block(if_false->exit_block());
3110 } 3114 }
3111 3115
3112 // Generate first map check to end the current block. 3116 // Connect the default if necessary.
3113 AddInstruction(new HCheckNonSmi(receiver)); 3117 if (subgraph()->HasExit()) {
3114 HSubgraph* else_subgraph = 3118 if (ast_context()->IsEffect()) {
3115 (maps->length() == 1) ? subgraphs->at(1) : map_compare_subgraphs.last(); 3119 environment()->Drop(1);
3116 HCompareMap* compare = new HCompareMap(receiver,
3117 Handle<Map>(maps->first()),
3118 subgraphs->first()->entry_block(),
3119 else_subgraph->entry_block());
3120 current_subgraph_->exit_block()->Finish(compare);
3121
3122 // Join all the call subgraphs in a new basic block and make
3123 // this basic block the current basic block.
3124 HBasicBlock* join_block = graph_->CreateBasicBlock();
3125 for (int i = 0; i < subgraphs->length(); ++i) {
3126 HSubgraph* subgraph = subgraphs->at(i);
3127 if (subgraph->HasExit()) {
3128 // In an effect context the value of the type switch is not needed.
3129 // There is no need to merge it at the join block only to discard it.
3130 HBasicBlock* subgraph_exit = subgraph->exit_block();
3131 if (ast_context()->IsEffect()) {
3132 subgraph_exit->last_environment()->Drop(1);
3133 }
3134 subgraph_exit->Goto(join_block);
3135 } 3120 }
3121 subgraph()->exit_block()->Goto(join_block);
3136 } 3122 }
3137 3123
3138 if (join_block->predecessors()->is_empty()) return NULL; 3124 if (join_block->predecessors()->is_empty()) return NULL;
3139 join_block->SetJoinId(join_id); 3125 join_block->SetJoinId(join_id);
3140 return join_block; 3126 return join_block;
3141 } 3127 }
3142 3128
3143 3129
3144 // Sets the lookup result and returns true if the store can be inlined. 3130 // Sets the lookup result and returns true if the store can be inlined.
3145 static bool ComputeStoredField(Handle<Map> type, 3131 static bool ComputeStoredField(Handle<Map> type,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3231 } 3217 }
3232 3218
3233 3219
3234 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, 3220 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
3235 HValue* object, 3221 HValue* object,
3236 HValue* value, 3222 HValue* value,
3237 ZoneMapList* types, 3223 ZoneMapList* types,
3238 Handle<String> name) { 3224 Handle<String> name) {
3239 int number_of_types = Min(types->length(), kMaxStorePolymorphism); 3225 int number_of_types = Min(types->length(), kMaxStorePolymorphism);
3240 ZoneMapList maps(number_of_types); 3226 ZoneMapList maps(number_of_types);
3241 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); 3227 ZoneList<HSubgraph*> subgraphs(number_of_types);
3242 bool needs_generic = (types->length() > kMaxStorePolymorphism); 3228 bool needs_generic = (types->length() > kMaxStorePolymorphism);
3243 3229
3244 // Build subgraphs for each of the specific maps. 3230 // Build subgraphs for each of the specific maps.
3245 // 3231 //
3246 // TODO(ager): We should recognize when the prototype chains for 3232 // TODO(ager): We should recognize when the prototype chains for
3247 // different maps are identical. In that case we can avoid 3233 // different maps are identical. In that case we can avoid
3248 // repeatedly generating the same prototype map checks. 3234 // repeatedly generating the same prototype map checks.
3249 for (int i = 0; i < number_of_types; ++i) { 3235 for (int i = 0; i < number_of_types; ++i) {
3250 Handle<Map> map = types->at(i); 3236 Handle<Map> map = types->at(i);
3251 LookupResult lookup; 3237 LookupResult lookup;
3252 if (ComputeStoredField(map, name, &lookup)) { 3238 if (ComputeStoredField(map, name, &lookup)) {
3253 maps.Add(map);
3254 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3239 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3255 SubgraphScope scope(this, subgraph); 3240 SubgraphScope scope(this, subgraph);
3256 HInstruction* instr = 3241 HInstruction* instr =
3257 BuildStoreNamedField(object, name, value, map, &lookup, false); 3242 BuildStoreNamedField(object, name, value, map, &lookup, false);
3258 Push(value); 3243 Push(value);
3259 instr->set_position(expr->position()); 3244 instr->set_position(expr->position());
3260 AddInstruction(instr); 3245 AddInstruction(instr);
3246 maps.Add(map);
3261 subgraphs.Add(subgraph); 3247 subgraphs.Add(subgraph);
3262 } else { 3248 } else {
3263 needs_generic = true; 3249 needs_generic = true;
3264 } 3250 }
3265 } 3251 }
3266 3252
3267 // If none of the properties were named fields we generate a 3253 // If none of the properties were named fields we generate a
3268 // generic store. 3254 // generic store.
3269 if (maps.length() == 0) { 3255 if (maps.length() == 0) {
3270 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 3256 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
3271 Push(value); 3257 Push(value);
3272 instr->set_position(expr->position()); 3258 instr->set_position(expr->position());
3273 AddInstruction(instr); 3259 AddInstruction(instr);
3274 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); 3260 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3275 ast_context()->ReturnValue(Pop()); 3261 ast_context()->ReturnValue(Pop());
3276 } else { 3262 } else {
3277 // Build subgraph for generic store through IC. 3263 // Build subgraph for generic store through IC.
3278 { 3264 HSubgraph* default_graph = CreateBranchSubgraph(environment());
3279 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3265 { SubgraphScope scope(this, default_graph);
3280 SubgraphScope scope(this, subgraph);
3281 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3266 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3282 subgraph->FinishExit(new HDeoptimize()); 3267 default_graph->FinishExit(new HDeoptimize());
3283 } else { 3268 } else {
3284 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 3269 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
3285 Push(value); 3270 Push(value);
3286 instr->set_position(expr->position()); 3271 instr->set_position(expr->position());
3287 AddInstruction(instr); 3272 AddInstruction(instr);
3288 } 3273 }
3289 subgraphs.Add(subgraph);
3290 } 3274 }
3291 3275
3292 HBasicBlock* new_exit_block = 3276 HBasicBlock* new_exit_block =
3293 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); 3277 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id());
3294 subgraph()->set_exit_block(new_exit_block); 3278 subgraph()->set_exit_block(new_exit_block);
3295 // In an effect context, we did not materialized the value in the 3279 // In an effect context, we did not materialized the value in the
3296 // predecessor environments so there's no need to handle it here. 3280 // predecessor environments so there's no need to handle it here.
3297 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { 3281 if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
3298 ast_context()->ReturnValue(Pop()); 3282 ast_context()->ReturnValue(Pop());
3299 } 3283 }
3300 } 3284 }
3301 } 3285 }
3302 3286
3303 3287
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
3558 current_subgraph_->FinishExit(new HAbnormalExit); 3542 current_subgraph_->FinishExit(new HAbnormalExit);
3559 } 3543 }
3560 3544
3561 3545
3562 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 3546 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
3563 HValue* object, 3547 HValue* object,
3564 ZoneMapList* types, 3548 ZoneMapList* types,
3565 Handle<String> name) { 3549 Handle<String> name) {
3566 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); 3550 int number_of_types = Min(types->length(), kMaxLoadPolymorphism);
3567 ZoneMapList maps(number_of_types); 3551 ZoneMapList maps(number_of_types);
3568 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); 3552 ZoneList<HSubgraph*> subgraphs(number_of_types);
3569 bool needs_generic = (types->length() > kMaxLoadPolymorphism); 3553 bool needs_generic = (types->length() > kMaxLoadPolymorphism);
3570 3554
3571 // Build subgraphs for each of the specific maps. 3555 // Build subgraphs for each of the specific maps.
3572 // 3556 //
3573 // TODO(ager): We should recognize when the prototype chains for 3557 // TODO(ager): We should recognize when the prototype chains for
3574 // different maps are identical. In that case we can avoid 3558 // different maps are identical. In that case we can avoid
3575 // repeatedly generating the same prototype map checks. 3559 // repeatedly generating the same prototype map checks.
3576 for (int i = 0; i < number_of_types; ++i) { 3560 for (int i = 0; i < number_of_types; ++i) {
3577 Handle<Map> map = types->at(i); 3561 Handle<Map> map = types->at(i);
3578 LookupResult lookup; 3562 LookupResult lookup;
3579 map->LookupInDescriptors(NULL, *name, &lookup); 3563 map->LookupInDescriptors(NULL, *name, &lookup);
3580 if (lookup.IsProperty() && lookup.type() == FIELD) { 3564 if (lookup.IsProperty() && lookup.type() == FIELD) {
3581 maps.Add(map);
3582 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3565 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3583 SubgraphScope scope(this, subgraph); 3566 SubgraphScope scope(this, subgraph);
3584 HLoadNamedField* instr = 3567 HLoadNamedField* instr =
3585 BuildLoadNamedField(object, expr, map, &lookup, false); 3568 BuildLoadNamedField(object, expr, map, &lookup, false);
3586 instr->set_position(expr->position()); 3569 instr->set_position(expr->position());
3587 instr->ClearFlag(HValue::kUseGVN); // Don't do GVN on polymorphic loads. 3570 instr->ClearFlag(HValue::kUseGVN); // Don't do GVN on polymorphic loads.
3588 PushAndAdd(instr); 3571 PushAndAdd(instr);
3572 maps.Add(map);
3589 subgraphs.Add(subgraph); 3573 subgraphs.Add(subgraph);
3590 } else { 3574 } else {
3591 needs_generic = true; 3575 needs_generic = true;
3592 } 3576 }
3593 } 3577 }
3594 3578
3595 // If none of the properties were named fields we generate a 3579 // If none of the properties were named fields we generate a
3596 // generic load. 3580 // generic load.
3597 if (maps.length() == 0) { 3581 if (maps.length() == 0) {
3598 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3582 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3599 instr->set_position(expr->position()); 3583 instr->set_position(expr->position());
3600 ast_context()->ReturnInstruction(instr, expr->id()); 3584 ast_context()->ReturnInstruction(instr, expr->id());
3601 } else { 3585 } else {
3602 // Build subgraph for generic load through IC. 3586 // Build subgraph for generic load through IC.
3603 { 3587 HSubgraph* default_graph = CreateBranchSubgraph(environment());
3604 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3588 { SubgraphScope scope(this, default_graph);
3605 SubgraphScope scope(this, subgraph);
3606 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3589 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3607 subgraph->FinishExit(new HDeoptimize()); 3590 default_graph->FinishExit(new HDeoptimize());
3608 } else { 3591 } else {
3609 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3592 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3610 instr->set_position(expr->position()); 3593 instr->set_position(expr->position());
3611 PushAndAdd(instr); 3594 PushAndAdd(instr);
3612 } 3595 }
3613 subgraphs.Add(subgraph);
3614 } 3596 }
3615 3597
3616 HBasicBlock* new_exit_block = 3598 HBasicBlock* new_exit_block =
3617 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); 3599 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id());
3618 subgraph()->set_exit_block(new_exit_block); 3600 subgraph()->set_exit_block(new_exit_block);
3619 // In an effect context, we did not materialized the value in the 3601 // In an effect context, we did not materialized the value in the
3620 // predecessor environments so there's no need to handle it here. 3602 // predecessor environments so there's no need to handle it here.
3621 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { 3603 if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
3622 ast_context()->ReturnValue(Pop()); 3604 ast_context()->ReturnValue(Pop());
3623 } 3605 }
3624 } 3606 }
3625 } 3607 }
3626 3608
3627 3609
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
3884 } 3866 }
3885 3867
3886 3868
3887 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 3869 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
3888 HValue* receiver, 3870 HValue* receiver,
3889 ZoneMapList* types, 3871 ZoneMapList* types,
3890 Handle<String> name) { 3872 Handle<String> name) {
3891 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 3873 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
3892 int number_of_types = Min(types->length(), kMaxCallPolymorphism); 3874 int number_of_types = Min(types->length(), kMaxCallPolymorphism);
3893 ZoneMapList maps(number_of_types); 3875 ZoneMapList maps(number_of_types);
3894 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); 3876 ZoneList<HSubgraph*> subgraphs(number_of_types);
3895 bool needs_generic = (types->length() > kMaxCallPolymorphism); 3877 bool needs_generic = (types->length() > kMaxCallPolymorphism);
3896 3878
3897 // Build subgraphs for each of the specific maps. 3879 // Build subgraphs for each of the specific maps.
3898 // 3880 //
3899 // TODO(ager): We should recognize when the prototype chains for different 3881 // TODO(ager): We should recognize when the prototype chains for different
3900 // maps are identical. In that case we can avoid repeatedly generating the 3882 // maps are identical. In that case we can avoid repeatedly generating the
3901 // same prototype map checks. 3883 // same prototype map checks.
3902 for (int i = 0; i < number_of_types; ++i) { 3884 for (int i = 0; i < number_of_types; ++i) {
3903 Handle<Map> map = types->at(i); 3885 Handle<Map> map = types->at(i);
3904 if (expr->ComputeTarget(map, name)) { 3886 if (expr->ComputeTarget(map, name)) {
3905 maps.Add(map);
3906 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3887 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3907 SubgraphScope scope(this, subgraph); 3888 SubgraphScope scope(this, subgraph);
3908 AddCheckConstantFunction(expr, receiver, map, false); 3889 AddCheckConstantFunction(expr, receiver, map, false);
3909 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 3890 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
3910 PrintF("Trying to inline the polymorphic call to %s\n", 3891 PrintF("Trying to inline the polymorphic call to %s\n",
3911 *name->ToCString()); 3892 *name->ToCString());
3912 } 3893 }
3913 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { 3894 if (!FLAG_polymorphic_inlining || !TryInline(expr)) {
3914 // Check for bailout, as trying to inline might fail due to bailout 3895 // Check for bailout, as trying to inline might fail due to bailout
3915 // during hydrogen processing. 3896 // during hydrogen processing.
3916 CHECK_BAILOUT; 3897 CHECK_BAILOUT;
3917 HCall* call = new HCallConstantFunction(expr->target(), argument_count); 3898 HCall* call = new HCallConstantFunction(expr->target(), argument_count);
3918 call->set_position(expr->position()); 3899 call->set_position(expr->position());
3919 PreProcessCall(call); 3900 PreProcessCall(call);
3920 PushAndAdd(call); 3901 PushAndAdd(call);
3921 } 3902 }
3903 maps.Add(map);
3922 subgraphs.Add(subgraph); 3904 subgraphs.Add(subgraph);
3923 } else { 3905 } else {
3924 needs_generic = true; 3906 needs_generic = true;
3925 } 3907 }
3926 } 3908 }
3927 3909
3928 // If we couldn't compute the target for any of the maps just perform an 3910 // If we couldn't compute the target for any of the maps just perform an
3929 // IC call. 3911 // IC call.
3930 if (maps.length() == 0) { 3912 if (maps.length() == 0) {
3931 HContext* context = new HContext; 3913 HContext* context = new HContext;
3932 AddInstruction(context); 3914 AddInstruction(context);
3933 HCall* call = new HCallNamed(context, name, argument_count); 3915 HCall* call = new HCallNamed(context, name, argument_count);
3934 call->set_position(expr->position()); 3916 call->set_position(expr->position());
3935 PreProcessCall(call); 3917 PreProcessCall(call);
3936 ast_context()->ReturnInstruction(call, expr->id()); 3918 ast_context()->ReturnInstruction(call, expr->id());
3937 } else { 3919 } else {
3938 // Build subgraph for generic call through IC. 3920 // Build subgraph for generic call through IC.
3939 { 3921 HSubgraph* default_graph = CreateBranchSubgraph(environment());
3940 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3922 { SubgraphScope scope(this, default_graph);
3941 SubgraphScope scope(this, subgraph);
3942 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3923 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3943 subgraph->FinishExit(new HDeoptimize()); 3924 default_graph->FinishExit(new HDeoptimize());
3944 } else { 3925 } else {
3945 HContext* context = new HContext; 3926 HContext* context = new HContext;
3946 AddInstruction(context); 3927 AddInstruction(context);
3947 HCall* call = new HCallNamed(context, name, argument_count); 3928 HCall* call = new HCallNamed(context, name, argument_count);
3948 call->set_position(expr->position()); 3929 call->set_position(expr->position());
3949 PreProcessCall(call); 3930 PreProcessCall(call);
3950 PushAndAdd(call); 3931 PushAndAdd(call);
3951 } 3932 }
3952 subgraphs.Add(subgraph);
3953 } 3933 }
3954 3934
3955 HBasicBlock* new_exit_block = 3935 HBasicBlock* new_exit_block =
3956 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); 3936 BuildTypeSwitch(receiver, &maps, &subgraphs, default_graph, expr->id());
3957 subgraph()->set_exit_block(new_exit_block); 3937 subgraph()->set_exit_block(new_exit_block);
3958 // In an effect context, we did not materialized the value in the 3938 // In an effect context, we did not materialized the value in the
3959 // predecessor environments so there's no need to handle it here. 3939 // predecessor environments so there's no need to handle it here.
3960 if (new_exit_block != NULL && !ast_context()->IsEffect()) { 3940 if (new_exit_block != NULL && !ast_context()->IsEffect()) {
3961 ast_context()->ReturnValue(Pop()); 3941 ast_context()->ReturnValue(Pop());
3962 } 3942 }
3963 } 3943 }
3964 } 3944 }
3965 3945
3966 3946
(...skipping 2025 matching lines...) Expand 10 before | Expand all | Expand 10 after
5992 } 5972 }
5993 } 5973 }
5994 5974
5995 #ifdef DEBUG 5975 #ifdef DEBUG
5996 if (graph_ != NULL) graph_->Verify(); 5976 if (graph_ != NULL) graph_->Verify();
5997 if (allocator_ != NULL) allocator_->Verify(); 5977 if (allocator_ != NULL) allocator_->Verify();
5998 #endif 5978 #endif
5999 } 5979 }
6000 5980
6001 } } // namespace v8::internal 5981 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698