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

Side by Side Diff: src/hydrogen.cc

Issue 5971003: Fix GVN for polymorphic loads.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years 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
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 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 1448
1449 // Only move instructions that postdominate the loop header (i.e. are 1449 // Only move instructions that postdominate the loop header (i.e. are
1450 // always executed inside the loop). This is to avoid unnecessary 1450 // always executed inside the loop). This is to avoid unnecessary
1451 // deoptimizations assuming the loop is executed at least once. 1451 // deoptimizations assuming the loop is executed at least once.
1452 // TODO(fschneider): Better type feedback should give us information 1452 // TODO(fschneider): Better type feedback should give us information
1453 // about code that was never executed. 1453 // about code that was never executed.
1454 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, 1454 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
1455 HBasicBlock* loop_header) { 1455 HBasicBlock* loop_header) {
1456 if (!instr->IsChange() && 1456 if (!instr->IsChange() &&
1457 FLAG_aggressive_loop_invariant_motion) return true; 1457 FLAG_aggressive_loop_invariant_motion) return true;
1458
1459 // Don't hoist named loads that are part of polymorphic loads.
1460 if (instr->IsLoadNamedField() &&
Kevin Millikin (Chromium) 2010/12/20 12:34:34 You could accomplish essentially the same thing by
1461 HLoadNamedField::cast(instr)->is_polymorphic()) {
1462 return false;
1463 }
1464
1458 HBasicBlock* block = instr->block(); 1465 HBasicBlock* block = instr->block();
1459 bool result = true; 1466 bool result = true;
1460 if (block != loop_header) { 1467 if (block != loop_header) {
1461 for (int i = 1; i < loop_header->predecessors()->length(); ++i) { 1468 for (int i = 1; i < loop_header->predecessors()->length(); ++i) {
1462 bool found = false; 1469 bool found = false;
1463 HBasicBlock* pred = loop_header->predecessors()->at(i); 1470 HBasicBlock* pred = loop_header->predecessors()->at(i);
1464 while (pred != loop_header) { 1471 while (pred != loop_header) {
1465 if (pred == block) found = true; 1472 if (pred == block) found = true;
1466 pred = pred->dominator(); 1473 pred = pred->dominator();
1467 } 1474 }
(...skipping 2057 matching lines...) Expand 10 before | Expand all | Expand 10 after
3525 // different maps are identical. In that case we can avoid 3532 // different maps are identical. In that case we can avoid
3526 // repeatedly generating the same prototype map checks. 3533 // repeatedly generating the same prototype map checks.
3527 for (int i = 0; i < number_of_types; ++i) { 3534 for (int i = 0; i < number_of_types; ++i) {
3528 Handle<Map> map = types->at(i); 3535 Handle<Map> map = types->at(i);
3529 LookupResult lookup; 3536 LookupResult lookup;
3530 map->LookupInDescriptors(NULL, *name, &lookup); 3537 map->LookupInDescriptors(NULL, *name, &lookup);
3531 if (lookup.IsProperty() && lookup.type() == FIELD) { 3538 if (lookup.IsProperty() && lookup.type() == FIELD) {
3532 maps.Add(map); 3539 maps.Add(map);
3533 HSubgraph* subgraph = CreateBranchSubgraph(environment()); 3540 HSubgraph* subgraph = CreateBranchSubgraph(environment());
3534 SubgraphScope scope(this, subgraph); 3541 SubgraphScope scope(this, subgraph);
3535 HInstruction* instr = 3542 HLoadNamedField* instr =
3536 BuildLoadNamedField(object, expr, map, &lookup, false); 3543 BuildLoadNamedField(object, expr, map, &lookup, false);
3537 instr->set_position(expr->position()); 3544 instr->set_position(expr->position());
3545 instr->set_is_polymorphic(true);
3538 PushAndAdd(instr); 3546 PushAndAdd(instr);
3539 subgraphs.Add(subgraph); 3547 subgraphs.Add(subgraph);
3540 } else { 3548 } else {
3541 needs_generic = true; 3549 needs_generic = true;
3542 } 3550 }
3543 } 3551 }
3544 3552
3545 // If none of the properties were named fields we generate a 3553 // If none of the properties were named fields we generate a
3546 // generic load. 3554 // generic load.
3547 if (maps.length() == 0) { 3555 if (maps.length() == 0) {
(...skipping 18 matching lines...) Expand all
3566 3574
3567 HBasicBlock* new_exit_block = 3575 HBasicBlock* new_exit_block =
3568 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); 3576 BuildTypeSwitch(&maps, &subgraphs, object, expr->id());
3569 subgraph()->set_exit_block(new_exit_block); 3577 subgraph()->set_exit_block(new_exit_block);
3570 } 3578 }
3571 3579
3572 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop()); 3580 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop());
3573 } 3581 }
3574 3582
3575 3583
3576 HInstruction* HGraphBuilder::BuildLoadNamedField(HValue* object, 3584 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
3577 Property* expr, 3585 Property* expr,
3578 Handle<Map> type, 3586 Handle<Map> type,
3579 LookupResult* lookup, 3587 LookupResult* lookup,
3580 bool smi_and_map_check) { 3588 bool smi_and_map_check) {
3581 if (smi_and_map_check) { 3589 if (smi_and_map_check) {
3582 AddInstruction(new HCheckNonSmi(object)); 3590 AddInstruction(new HCheckNonSmi(object));
3583 AddInstruction(new HCheckMap(object, type)); 3591 AddInstruction(new HCheckMap(object, type));
3584 } 3592 }
3585 3593
3586 int index = lookup->GetLocalFieldIndexFromMap(*type); 3594 int index = lookup->GetLocalFieldIndexFromMap(*type);
3587 if (index < 0) { 3595 if (index < 0) {
3588 // Negative property indices are in-object properties, indexed 3596 // Negative property indices are in-object properties, indexed
3589 // from the end of the fixed part of the object. 3597 // from the end of the fixed part of the object.
3590 int offset = (index * kPointerSize) + type->instance_size(); 3598 int offset = (index * kPointerSize) + type->instance_size();
(...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after
5674 } 5682 }
5675 5683
5676 #ifdef DEBUG 5684 #ifdef DEBUG
5677 if (graph_ != NULL) graph_->Verify(); 5685 if (graph_ != NULL) graph_->Verify();
5678 if (chunk_ != NULL) chunk_->Verify(); 5686 if (chunk_ != NULL) chunk_->Verify();
5679 if (allocator_ != NULL) allocator_->Verify(); 5687 if (allocator_ != NULL) allocator_->Verify();
5680 #endif 5688 #endif
5681 } 5689 }
5682 5690
5683 } } // namespace v8::internal 5691 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698