Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |