OLD | NEW |
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 5511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5522 HValue* val, | 5522 HValue* val, |
5523 SmallMapList* maps) { | 5523 SmallMapList* maps) { |
5524 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 5524 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
5525 // double), always use the "worst case" code without a transition. This is | 5525 // double), always use the "worst case" code without a transition. This is |
5526 // much faster than transitioning the elements to the worst case, trading a | 5526 // much faster than transitioning the elements to the worst case, trading a |
5527 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. | 5527 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array. |
5528 bool has_double_maps = false; | 5528 bool has_double_maps = false; |
5529 bool has_smi_or_object_maps = false; | 5529 bool has_smi_or_object_maps = false; |
5530 bool has_js_array_access = false; | 5530 bool has_js_array_access = false; |
5531 bool has_non_js_array_access = false; | 5531 bool has_non_js_array_access = false; |
| 5532 bool has_seen_holey_elements = false; |
5532 Handle<Map> most_general_consolidated_map; | 5533 Handle<Map> most_general_consolidated_map; |
5533 for (int i = 0; i < maps->length(); ++i) { | 5534 for (int i = 0; i < maps->length(); ++i) { |
5534 Handle<Map> map = maps->at(i); | 5535 Handle<Map> map = maps->at(i); |
5535 // Don't allow mixing of JSArrays with JSObjects. | 5536 // Don't allow mixing of JSArrays with JSObjects. |
5536 if (map->instance_type() == JS_ARRAY_TYPE) { | 5537 if (map->instance_type() == JS_ARRAY_TYPE) { |
5537 if (has_non_js_array_access) return NULL; | 5538 if (has_non_js_array_access) return NULL; |
5538 has_js_array_access = true; | 5539 has_js_array_access = true; |
5539 } else if (has_js_array_access) { | 5540 } else if (has_js_array_access) { |
5540 return NULL; | 5541 return NULL; |
5541 } else { | 5542 } else { |
5542 has_non_js_array_access = true; | 5543 has_non_js_array_access = true; |
5543 } | 5544 } |
5544 // Don't allow mixed, incompatible elements kinds. | 5545 // Don't allow mixed, incompatible elements kinds. |
5545 if (map->has_fast_double_elements()) { | 5546 if (map->has_fast_double_elements()) { |
5546 if (has_smi_or_object_maps) return NULL; | 5547 if (has_smi_or_object_maps) return NULL; |
5547 has_double_maps = true; | 5548 has_double_maps = true; |
5548 } else if (map->has_fast_smi_or_object_elements()) { | 5549 } else if (map->has_fast_smi_or_object_elements()) { |
5549 if (has_double_maps) return NULL; | 5550 if (has_double_maps) return NULL; |
5550 has_smi_or_object_maps = true; | 5551 has_smi_or_object_maps = true; |
5551 } else { | 5552 } else { |
5552 return NULL; | 5553 return NULL; |
5553 } | 5554 } |
| 5555 // Remember if we've ever seen holey elements. |
| 5556 if (IsHoleyElementsKind(map->elements_kind())) { |
| 5557 has_seen_holey_elements = true; |
| 5558 } |
5554 // Remember the most general elements kind, the code for its load will | 5559 // Remember the most general elements kind, the code for its load will |
5555 // properly handle all of the more specific cases. | 5560 // properly handle all of the more specific cases. |
5556 if ((i == 0) || IsMoreGeneralElementsKindTransition( | 5561 if ((i == 0) || IsMoreGeneralElementsKindTransition( |
5557 most_general_consolidated_map->elements_kind(), | 5562 most_general_consolidated_map->elements_kind(), |
5558 map->elements_kind())) { | 5563 map->elements_kind())) { |
5559 most_general_consolidated_map = map; | 5564 most_general_consolidated_map = map; |
5560 } | 5565 } |
5561 } | 5566 } |
5562 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 5567 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
5563 | 5568 |
5564 HCheckMaps* check_maps = Add<HCheckMaps>(object, maps); | 5569 HCheckMaps* check_maps = Add<HCheckMaps>(object, maps); |
| 5570 // FAST_ELEMENTS is considered more general than FAST_HOLEY_SMI_ELEMENTS. |
| 5571 // If we've seen both, the consolidated load must use FAST_HOLEY_ELEMENTS. |
| 5572 ElementsKind consolidated_elements_kind = has_seen_holey_elements |
| 5573 ? GetHoleyElementsKind(most_general_consolidated_map->elements_kind()) |
| 5574 : most_general_consolidated_map->elements_kind(); |
5565 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 5575 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
5566 object, key, val, check_maps, | 5576 object, key, val, check_maps, |
5567 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | 5577 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
5568 most_general_consolidated_map->elements_kind(), | 5578 consolidated_elements_kind, |
5569 false, NEVER_RETURN_HOLE, STANDARD_STORE); | 5579 false, NEVER_RETURN_HOLE, STANDARD_STORE); |
5570 return instr; | 5580 return instr; |
5571 } | 5581 } |
5572 | 5582 |
5573 | 5583 |
5574 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( | 5584 HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
5575 HValue* object, | 5585 HValue* object, |
5576 HValue* key, | 5586 HValue* key, |
5577 HValue* val, | 5587 HValue* val, |
5578 Expression* prop, | 5588 Expression* prop, |
(...skipping 4261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9840 if (ShouldProduceTraceOutput()) { | 9850 if (ShouldProduceTraceOutput()) { |
9841 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9851 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9842 } | 9852 } |
9843 | 9853 |
9844 #ifdef DEBUG | 9854 #ifdef DEBUG |
9845 graph_->Verify(false); // No full verify. | 9855 graph_->Verify(false); // No full verify. |
9846 #endif | 9856 #endif |
9847 } | 9857 } |
9848 | 9858 |
9849 } } // namespace v8::internal | 9859 } } // namespace v8::internal |
OLD | NEW |