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

Side by Side Diff: src/hydrogen.cc

Issue 6065014: Fix an bug in deoptimization after polymorphic calls in effect contexts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 11 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698