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

Side by Side Diff: src/hydrogen.cc

Issue 163403003: Return on the polymorphic hard deopt case to ensure we don't polute phis with fake type information. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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') | 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 } 1036 }
1037 builder_->GotoNoSimulate(current->block_, merge_block); 1037 builder_->GotoNoSimulate(current->block_, merge_block);
1038 } 1038 }
1039 current = current->next_; 1039 current = current->next_;
1040 } 1040 }
1041 1041
1042 // Merge deopt blocks, padding when necessary. 1042 // Merge deopt blocks, padding when necessary.
1043 current = merge_at_join_blocks_; 1043 current = merge_at_join_blocks_;
1044 while (current != NULL) { 1044 while (current != NULL) {
1045 if (current->deopt_ && current->block_ != NULL) { 1045 if (current->deopt_ && current->block_ != NULL) {
1046 builder_->PadEnvironmentForContinuation(current->block_, 1046 current->block_->FinishExit(
1047 merge_block); 1047 HAbnormalExit::New(builder_->zone(), NULL), RelocInfo::kNoPosition);
1048 builder_->GotoNoSimulate(current->block_, merge_block);
1049 } 1048 }
1050 current = current->next_; 1049 current = current->next_;
1051 } 1050 }
1052 builder_->set_current_block(merge_block); 1051 builder_->set_current_block(merge_block);
1053 } 1052 }
1054 1053
1055 1054
1056 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 1055 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
1057 HValue* context, 1056 HValue* context,
1058 LoopBuilder::Direction direction) 1057 LoopBuilder::Direction direction)
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 return header; 1243 return header;
1245 } 1244 }
1246 1245
1247 1246
1248 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1247 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1249 if (obj->type().IsHeapObject()) return obj; 1248 if (obj->type().IsHeapObject()) return obj;
1250 return Add<HCheckHeapObject>(obj); 1249 return Add<HCheckHeapObject>(obj);
1251 } 1250 }
1252 1251
1253 1252
1254 void HGraphBuilder::FinishExitWithHardDeoptimization( 1253 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1255 const char* reason, HBasicBlock* continuation) {
1256 PadEnvironmentForContinuation(current_block(), continuation);
1257 Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1254 Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1258 if (graph()->IsInsideNoSideEffectsScope()) { 1255 FinishExitCurrentBlock(New<HAbnormalExit>());
1259 GotoNoSimulate(continuation);
1260 } else {
1261 Goto(continuation);
1262 }
1263 } 1256 }
1264 1257
1265 1258
1266 void HGraphBuilder::PadEnvironmentForContinuation(
1267 HBasicBlock* from,
1268 HBasicBlock* continuation) {
1269 if (continuation->last_environment() != NULL) {
1270 // When merging from a deopt block to a continuation, resolve differences in
1271 // environment by pushing constant 0 and popping extra values so that the
1272 // environments match during the join. Push 0 since it has the most specific
1273 // representation, and will not influence representation inference of the
1274 // phi.
1275 int continuation_env_length = continuation->last_environment()->length();
1276 while (continuation_env_length != from->last_environment()->length()) {
1277 if (continuation_env_length > from->last_environment()->length()) {
1278 from->last_environment()->Push(graph()->GetConstant0());
1279 } else {
1280 from->last_environment()->Pop();
1281 }
1282 }
1283 } else {
1284 ASSERT(continuation->predecessors()->length() == 0);
1285 }
1286 }
1287
1288
1289 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) { 1259 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
1290 return Add<HCheckMaps>(obj, map, top_info()); 1260 return Add<HCheckMaps>(obj, map, top_info());
1291 } 1261 }
1292 1262
1293 1263
1294 HValue* HGraphBuilder::BuildCheckString(HValue* string) { 1264 HValue* HGraphBuilder::BuildCheckString(HValue* string) {
1295 if (!string->type().IsString()) { 1265 if (!string->type().IsString()) {
1296 ASSERT(!string->IsConstant() || 1266 ASSERT(!string->IsConstant() ||
1297 !HConstant::cast(string)->HasStringValue()); 1267 !HConstant::cast(string)->HasStringValue());
1298 BuildCheckHeapObject(string); 1268 BuildCheckHeapObject(string);
(...skipping 4396 matching lines...) Expand 10 before | Expand all | Expand 10 after
5695 } 5665 }
5696 5666
5697 if (current_block() != NULL) Goto(join); 5667 if (current_block() != NULL) Goto(join);
5698 set_current_block(if_false); 5668 set_current_block(if_false);
5699 } 5669 }
5700 5670
5701 // Finish up. Unconditionally deoptimize if we've handled all the maps we 5671 // Finish up. Unconditionally deoptimize if we've handled all the maps we
5702 // know about and do not want to handle ones we've never seen. Otherwise 5672 // know about and do not want to handle ones we've never seen. Otherwise
5703 // use a generic IC. 5673 // use a generic IC.
5704 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 5674 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
5705 // Because the deopt may be the only path in the polymorphic load, make sure 5675 FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
5706 // that the environment stack matches the depth on deopt that it otherwise
5707 // would have had after a successful load.
5708 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
5709 FinishExitWithHardDeoptimization("Uknown map in polymorphic access", join);
5710 } else { 5676 } else {
5711 HInstruction* instr = BuildNamedGeneric(access_type, object, name, value); 5677 HInstruction* instr = BuildNamedGeneric(access_type, object, name, value);
5712 AddInstruction(instr); 5678 AddInstruction(instr);
5713 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); 5679 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value);
5714 5680
5715 if (join != NULL) { 5681 if (join != NULL) {
5716 Goto(join); 5682 Goto(join);
5717 } else { 5683 } else {
5718 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5684 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5719 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 5685 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
6421 // The caller will use has_side_effects and add a correct Simulate. 6387 // The caller will use has_side_effects and add a correct Simulate.
6422 access->SetFlag(HValue::kHasNoObservableSideEffects); 6388 access->SetFlag(HValue::kHasNoObservableSideEffects);
6423 if (access_type == LOAD) { 6389 if (access_type == LOAD) {
6424 Push(access); 6390 Push(access);
6425 } 6391 }
6426 NoObservableSideEffectsScope scope(this); 6392 NoObservableSideEffectsScope scope(this);
6427 GotoNoSimulate(join); 6393 GotoNoSimulate(join);
6428 set_current_block(other_map); 6394 set_current_block(other_map);
6429 } 6395 }
6430 6396
6397 // Ensure that we visited at least one map above that goes to join. This is
6398 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit
6399 // rather than joining the join block. If this becomes an issue, insert a
6400 // generic access in the case length() == 0.
6401 ASSERT(join->predecessors()->length() > 0);
6431 // Deopt if none of the cases matched. 6402 // Deopt if none of the cases matched.
6432 NoObservableSideEffectsScope scope(this); 6403 NoObservableSideEffectsScope scope(this);
6433 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access", 6404 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access");
6434 join);
6435 set_current_block(join); 6405 set_current_block(join);
6436 return access_type == STORE ? NULL : Pop(); 6406 return access_type == STORE ? NULL : Pop();
6437 } 6407 }
6438 6408
6439 6409
6440 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 6410 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
6441 HValue* obj, 6411 HValue* obj,
6442 HValue* key, 6412 HValue* key,
6443 HValue* val, 6413 HValue* val,
6444 Expression* expr, 6414 Expression* expr,
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
6912 } 6882 }
6913 6883
6914 if (current_block() != NULL) Goto(join); 6884 if (current_block() != NULL) Goto(join);
6915 set_current_block(if_false); 6885 set_current_block(if_false);
6916 } 6886 }
6917 6887
6918 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6888 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6919 // know about and do not want to handle ones we've never seen. Otherwise 6889 // know about and do not want to handle ones we've never seen. Otherwise
6920 // use a generic IC. 6890 // use a generic IC.
6921 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { 6891 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6922 // Because the deopt may be the only path in the polymorphic call, make sure 6892 FinishExitWithHardDeoptimization("Unknown map in polymorphic call");
6923 // that the environment stack matches the depth on deopt that it otherwise
6924 // would have had after a successful call.
6925 Drop(1); // Drop receiver.
6926 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
6927 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
6928 } else { 6893 } else {
6929 Property* prop = expr->expression()->AsProperty(); 6894 Property* prop = expr->expression()->AsProperty();
6930 HInstruction* function = BuildNamedGeneric( 6895 HInstruction* function = BuildNamedGeneric(
6931 LOAD, receiver, name, NULL, prop->IsUninitialized()); 6896 LOAD, receiver, name, NULL, prop->IsUninitialized());
6932 AddInstruction(function); 6897 AddInstruction(function);
6933 Push(function); 6898 Push(function);
6934 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 6899 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
6935 6900
6936 environment()->SetExpressionStackAt(1, function); 6901 environment()->SetExpressionStackAt(1, function);
6937 environment()->SetExpressionStackAt(0, receiver); 6902 environment()->SetExpressionStackAt(0, receiver);
(...skipping 4249 matching lines...) Expand 10 before | Expand all | Expand 10 after
11187 if (ShouldProduceTraceOutput()) { 11152 if (ShouldProduceTraceOutput()) {
11188 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11153 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11189 } 11154 }
11190 11155
11191 #ifdef DEBUG 11156 #ifdef DEBUG
11192 graph_->Verify(false); // No full verify. 11157 graph_->Verify(false); // No full verify.
11193 #endif 11158 #endif
11194 } 11159 }
11195 11160
11196 } } // namespace v8::internal 11161 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698