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 3514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3525 // different maps are identical. In that case we can avoid | 3525 // different maps are identical. In that case we can avoid |
3526 // repeatedly generating the same prototype map checks. | 3526 // repeatedly generating the same prototype map checks. |
3527 for (int i = 0; i < number_of_types; ++i) { | 3527 for (int i = 0; i < number_of_types; ++i) { |
3528 Handle<Map> map = types->at(i); | 3528 Handle<Map> map = types->at(i); |
3529 LookupResult lookup; | 3529 LookupResult lookup; |
3530 map->LookupInDescriptors(NULL, *name, &lookup); | 3530 map->LookupInDescriptors(NULL, *name, &lookup); |
3531 if (lookup.IsProperty() && lookup.type() == FIELD) { | 3531 if (lookup.IsProperty() && lookup.type() == FIELD) { |
3532 maps.Add(map); | 3532 maps.Add(map); |
3533 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3533 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
3534 SubgraphScope scope(this, subgraph); | 3534 SubgraphScope scope(this, subgraph); |
3535 HInstruction* instr = | 3535 HLoadNamedField* instr = |
3536 BuildLoadNamedField(object, expr, map, &lookup, false); | 3536 BuildLoadNamedField(object, expr, map, &lookup, false); |
3537 instr->set_position(expr->position()); | 3537 instr->set_position(expr->position()); |
| 3538 instr->ClearFlag(HValue::kUseGVN); // Don't do GVN on polymorphic loads. |
3538 PushAndAdd(instr); | 3539 PushAndAdd(instr); |
3539 subgraphs.Add(subgraph); | 3540 subgraphs.Add(subgraph); |
3540 } else { | 3541 } else { |
3541 needs_generic = true; | 3542 needs_generic = true; |
3542 } | 3543 } |
3543 } | 3544 } |
3544 | 3545 |
3545 // If none of the properties were named fields we generate a | 3546 // If none of the properties were named fields we generate a |
3546 // generic load. | 3547 // generic load. |
3547 if (maps.length() == 0) { | 3548 if (maps.length() == 0) { |
(...skipping 18 matching lines...) Expand all Loading... |
3566 | 3567 |
3567 HBasicBlock* new_exit_block = | 3568 HBasicBlock* new_exit_block = |
3568 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); | 3569 BuildTypeSwitch(&maps, &subgraphs, object, expr->id()); |
3569 subgraph()->set_exit_block(new_exit_block); | 3570 subgraph()->set_exit_block(new_exit_block); |
3570 } | 3571 } |
3571 | 3572 |
3572 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop()); | 3573 if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop()); |
3573 } | 3574 } |
3574 | 3575 |
3575 | 3576 |
3576 HInstruction* HGraphBuilder::BuildLoadNamedField(HValue* object, | 3577 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
3577 Property* expr, | 3578 Property* expr, |
3578 Handle<Map> type, | 3579 Handle<Map> type, |
3579 LookupResult* lookup, | 3580 LookupResult* lookup, |
3580 bool smi_and_map_check) { | 3581 bool smi_and_map_check) { |
3581 if (smi_and_map_check) { | 3582 if (smi_and_map_check) { |
3582 AddInstruction(new HCheckNonSmi(object)); | 3583 AddInstruction(new HCheckNonSmi(object)); |
3583 AddInstruction(new HCheckMap(object, type)); | 3584 AddInstruction(new HCheckMap(object, type)); |
3584 } | 3585 } |
3585 | 3586 |
3586 int index = lookup->GetLocalFieldIndexFromMap(*type); | 3587 int index = lookup->GetLocalFieldIndexFromMap(*type); |
3587 if (index < 0) { | 3588 if (index < 0) { |
3588 // Negative property indices are in-object properties, indexed | 3589 // Negative property indices are in-object properties, indexed |
3589 // from the end of the fixed part of the object. | 3590 // from the end of the fixed part of the object. |
3590 int offset = (index * kPointerSize) + type->instance_size(); | 3591 int offset = (index * kPointerSize) + type->instance_size(); |
(...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5674 } | 5675 } |
5675 | 5676 |
5676 #ifdef DEBUG | 5677 #ifdef DEBUG |
5677 if (graph_ != NULL) graph_->Verify(); | 5678 if (graph_ != NULL) graph_->Verify(); |
5678 if (chunk_ != NULL) chunk_->Verify(); | 5679 if (chunk_ != NULL) chunk_->Verify(); |
5679 if (allocator_ != NULL) allocator_->Verify(); | 5680 if (allocator_ != NULL) allocator_->Verify(); |
5680 #endif | 5681 #endif |
5681 } | 5682 } |
5682 | 5683 |
5683 } } // namespace v8::internal | 5684 } } // namespace v8::internal |
OLD | NEW |