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

Side by Side Diff: src/hydrogen.cc

Issue 16975006: Try convert polymorphic stores into a single monomorphic store. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Fixed bug in TryLoad Created 7 years, 6 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/property-details.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3776 matching lines...) Expand 10 before | Expand all | Expand 10 after
3787 } while (false) 3787 } while (false)
3788 3788
3789 3789
3790 #define CHECK_ALIVE(call) \ 3790 #define CHECK_ALIVE(call) \
3791 do { \ 3791 do { \
3792 call; \ 3792 call; \
3793 if (HasStackOverflow() || current_block() == NULL) return; \ 3793 if (HasStackOverflow() || current_block() == NULL) return; \
3794 } while (false) 3794 } while (false)
3795 3795
3796 3796
3797 #define CHECK_ALIVE_OR_RETURN(call, value) \
3798 do { \
3799 call; \
3800 if (HasStackOverflow() || current_block() == NULL) return value; \
3801 } while (false)
3802
3803
3797 void HOptimizedGraphBuilder::Bailout(const char* reason) { 3804 void HOptimizedGraphBuilder::Bailout(const char* reason) {
3798 current_info()->set_bailout_reason(reason); 3805 current_info()->set_bailout_reason(reason);
3799 SetStackOverflow(); 3806 SetStackOverflow();
3800 } 3807 }
3801 3808
3802 3809
3803 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) { 3810 void HOptimizedGraphBuilder::VisitForEffect(Expression* expr) {
3804 EffectContext for_effect(this); 3811 EffectContext for_effect(this);
3805 Visit(expr); 3812 Visit(expr);
3806 } 3813 }
(...skipping 2482 matching lines...) Expand 10 before | Expand all | Expand 10 after
6289 } 6296 }
6290 6297
6291 6298
6292 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( 6299 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
6293 Property* expr, 6300 Property* expr,
6294 HValue* object, 6301 HValue* object,
6295 SmallMapList* types, 6302 SmallMapList* types,
6296 Handle<String> name) { 6303 Handle<String> name) {
6297 // Use monomorphic load if property lookup results in the same field index 6304 // Use monomorphic load if property lookup results in the same field index
6298 // for all maps. Requires special map check on the set of all handled maps. 6305 // for all maps. Requires special map check on the set of all handled maps.
6306 if (types->length() > kMaxLoadPolymorphism) return NULL;
6307
6299 LookupResult lookup(isolate()); 6308 LookupResult lookup(isolate());
6300 int count; 6309 int count;
6301 Representation representation = Representation::None(); 6310 Representation representation = Representation::None();
6302 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 6311 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
6303 for (count = 0; 6312 for (count = 0; count < types->length(); ++count) {
6304 count < types->length() && count < kMaxLoadPolymorphism;
6305 ++count) {
6306 Handle<Map> map = types->at(count); 6313 Handle<Map> map = types->at(count);
6307 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 6314 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
6308 6315
6309 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 6316 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
6310 Representation new_representation = 6317 Representation new_representation =
6311 ComputeLoadStoreRepresentation(map, &lookup); 6318 ComputeLoadStoreRepresentation(map, &lookup);
6312 6319
6313 if (count == 0) { 6320 if (count == 0) {
6314 // First time through the loop; set access and representation. 6321 // First time through the loop; set access and representation.
6315 access = new_access; 6322 access = new_access;
6316 representation = new_representation;
6317 } else if (!representation.IsCompatibleForLoad(new_representation)) { 6323 } else if (!representation.IsCompatibleForLoad(new_representation)) {
6318 // Representations did not match. 6324 // Representations did not match.
6319 break; 6325 break;
6320 } else if (access.offset() != new_access.offset()) { 6326 } else if (access.offset() != new_access.offset()) {
6321 // Offsets did not match. 6327 // Offsets did not match.
6322 break; 6328 break;
6323 } else if (access.IsInobject() != new_access.IsInobject()) { 6329 } else if (access.IsInobject() != new_access.IsInobject()) {
6324 // In-objectness did not match. 6330 // In-objectness did not match.
6325 break; 6331 break;
6326 } 6332 }
6333 representation = representation.generalize(new_representation);
6327 } 6334 }
6328 6335
6329 if (count != types->length()) return NULL; 6336 if (count != types->length()) return NULL;
6330 6337
6331 // Everything matched; can use monomorphic load. 6338 // Everything matched; can use monomorphic load.
6332 BuildCheckNonSmi(object); 6339 BuildCheckNonSmi(object);
6333 AddInstruction(HCheckMaps::New(object, types, zone())); 6340 AddInstruction(HCheckMaps::New(object, types, zone()));
6334 return BuildLoadNamedField(object, access, representation); 6341 return BuildLoadNamedField(object, access, representation);
6335 } 6342 }
6336 6343
(...skipping 11 matching lines...) Expand all
6348 HValue* context = environment()->LookupContext(); 6355 HValue* context = environment()->LookupContext();
6349 instr = new(zone()) HLoadNamedFieldPolymorphic( 6356 instr = new(zone()) HLoadNamedFieldPolymorphic(
6350 context, object, types, name, zone()); 6357 context, object, types, name, zone());
6351 } 6358 }
6352 6359
6353 instr->set_position(expr->position()); 6360 instr->set_position(expr->position());
6354 return ast_context()->ReturnInstruction(instr, expr->id()); 6361 return ast_context()->ReturnInstruction(instr, expr->id());
6355 } 6362 }
6356 6363
6357 6364
6365 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
6366 Assignment* expr,
6367 HValue* object,
6368 HValue* value,
6369 SmallMapList* types,
6370 Handle<String> name) {
6371 // Use monomorphic store if property lookup results in the same field index
6372 // for all maps. Requires special map check on the set of all handled maps.
6373 if (types->length() > kMaxStorePolymorphism) return false;
6374
6375 // TODO(verwaest): Merge the checking logic with the code in
6376 // TryLoadPolymorphicAsMonomorphic.
6377 LookupResult lookup(isolate());
6378 int count;
6379 Representation representation = Representation::None();
6380 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
6381 for (count = 0; count < types->length(); ++count) {
6382 Handle<Map> map = types->at(count);
6383 // Pass false to ignore transitions.
6384 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
6385
6386 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
6387 Representation new_representation =
6388 ComputeLoadStoreRepresentation(map, &lookup);
6389
6390 if (count == 0) {
6391 // First time through the loop; set access and representation.
6392 access = new_access;
6393 representation = new_representation;
6394 } else if (!representation.IsCompatibleForStore(new_representation)) {
6395 // Representations did not match.
6396 break;
6397 } else if (access.offset() != new_access.offset()) {
6398 // Offsets did not match.
6399 break;
6400 } else if (access.IsInobject() != new_access.IsInobject()) {
6401 // In-objectness did not match.
6402 break;
6403 }
6404 }
6405
6406 if (count != types->length()) return false;
6407
6408 // Everything matched; can use monomorphic store.
6409 BuildCheckNonSmi(object);
6410 AddInstruction(HCheckMaps::New(object, types, zone()));
6411 HInstruction* store;
6412 CHECK_ALIVE_OR_RETURN(
6413 store = BuildStoreNamedField(object, name, value, types->at(0), &lookup),
6414 true);
6415 Push(value);
6416 store->set_position(expr->position());
6417 AddInstruction(store);
6418 AddSimulate(expr->AssignmentId());
6419 ast_context()->ReturnValue(Pop());
6420 return true;
6421 }
6422
6423
6358 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6424 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6359 Assignment* expr, 6425 Assignment* expr,
6360 HValue* object, 6426 HValue* object,
6361 HValue* value, 6427 HValue* value,
6362 SmallMapList* types, 6428 SmallMapList* types,
6363 Handle<String> name) { 6429 Handle<String> name) {
6430 if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) {
6431 return;
6432 }
6433
6364 // TODO(ager): We should recognize when the prototype chains for different 6434 // TODO(ager): We should recognize when the prototype chains for different
6365 // maps are identical. In that case we can avoid repeatedly generating the 6435 // maps are identical. In that case we can avoid repeatedly generating the
6366 // same prototype map checks. 6436 // same prototype map checks.
6367 int count = 0; 6437 int count = 0;
6368 HBasicBlock* join = NULL; 6438 HBasicBlock* join = NULL;
6369 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 6439 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
6370 Handle<Map> map = types->at(i); 6440 Handle<Map> map = types->at(i);
6371 LookupResult lookup(isolate()); 6441 LookupResult lookup(isolate());
6372 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6442 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6373 if (count == 0) { 6443 if (count == 0) {
6374 BuildCheckNonSmi(object); 6444 BuildCheckNonSmi(object);
6375 join = graph()->CreateBasicBlock(); 6445 join = graph()->CreateBasicBlock();
6376 } 6446 }
6377 ++count; 6447 ++count;
6378 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6448 HBasicBlock* if_true = graph()->CreateBasicBlock();
6379 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6449 HBasicBlock* if_false = graph()->CreateBasicBlock();
6380 HCompareMap* compare = 6450 HCompareMap* compare =
6381 new(zone()) HCompareMap(object, map, if_true, if_false); 6451 new(zone()) HCompareMap(object, map, if_true, if_false);
6382 current_block()->Finish(compare); 6452 current_block()->Finish(compare);
6383 6453
6384 set_current_block(if_true); 6454 set_current_block(if_true);
6385 HInstruction* instr; 6455 HInstruction* instr;
6386 CHECK_ALIVE(instr = 6456 CHECK_ALIVE(
6387 BuildStoreNamedField(object, name, value, map, &lookup)); 6457 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6388 instr->set_position(expr->position()); 6458 instr->set_position(expr->position());
6389 // Goto will add the HSimulate for the store. 6459 // Goto will add the HSimulate for the store.
6390 AddInstruction(instr); 6460 AddInstruction(instr);
6391 if (!ast_context()->IsEffect()) Push(value); 6461 if (!ast_context()->IsEffect()) Push(value);
6392 current_block()->Goto(join); 6462 current_block()->Goto(join);
6393 6463
6394 set_current_block(if_false); 6464 set_current_block(if_false);
6395 } 6465 }
6396 } 6466 }
6397 6467
(...skipping 23 matching lines...) Expand all
6421 Drop(1); 6491 Drop(1);
6422 } 6492 }
6423 } 6493 }
6424 return ast_context()->ReturnValue(value); 6494 return ast_context()->ReturnValue(value);
6425 } 6495 }
6426 } 6496 }
6427 6497
6428 ASSERT(join != NULL); 6498 ASSERT(join != NULL);
6429 join->SetJoinId(expr->id()); 6499 join->SetJoinId(expr->id());
6430 set_current_block(join); 6500 set_current_block(join);
6431 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 6501 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6432 } 6502 }
6433 6503
6434 6504
6435 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6505 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6436 Property* prop = expr->target()->AsProperty(); 6506 Property* prop = expr->target()->AsProperty();
6437 ASSERT(prop != NULL); 6507 ASSERT(prop != NULL);
6438 CHECK_ALIVE(VisitForValue(prop->obj())); 6508 CHECK_ALIVE(VisitForValue(prop->obj()));
6439 6509
6440 if (prop->key()->IsPropertyName()) { 6510 if (prop->key()->IsPropertyName()) {
6441 // Named store. 6511 // Named store.
(...skipping 5129 matching lines...) Expand 10 before | Expand all | Expand 10 after
11571 } 11641 }
11572 } 11642 }
11573 11643
11574 #ifdef DEBUG 11644 #ifdef DEBUG
11575 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11645 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11576 if (allocator_ != NULL) allocator_->Verify(); 11646 if (allocator_ != NULL) allocator_->Verify();
11577 #endif 11647 #endif
11578 } 11648 }
11579 11649
11580 } } // namespace v8::internal 11650 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/property-details.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698