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 5444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5455 } | 5455 } |
5456 | 5456 |
5457 | 5457 |
5458 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5458 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
5459 HValue* key) { | 5459 HValue* key) { |
5460 HValue* context = environment()->LookupContext(); | 5460 HValue* context = environment()->LookupContext(); |
5461 return new(zone()) HLoadKeyedGeneric(context, object, key); | 5461 return new(zone()) HLoadKeyedGeneric(context, object, key); |
5462 } | 5462 } |
5463 | 5463 |
5464 | 5464 |
5465 LoadKeyedHoleMode HOptimizedGraphBuilder::GetKeyedHoleMode(Handle<Map> map) { | |
5466 // Loads from a "stock" fast holey double arrays can elide the hole check. | |
5467 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | |
5468 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | |
5469 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | |
5470 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | |
5471 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | |
5472 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); | |
5473 load_mode = ALLOW_RETURN_HOLE; | |
5474 graph()->MarkDependsOnEmptyArrayProtoElements(); | |
5475 } | |
5476 return load_mode; | |
5477 } | |
5478 | |
5479 | |
5465 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( | 5480 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( |
5466 HValue* object, | 5481 HValue* object, |
5467 HValue* key, | 5482 HValue* key, |
5468 HValue* val, | 5483 HValue* val, |
5469 HValue* dependency, | 5484 HValue* dependency, |
5470 Handle<Map> map, | 5485 Handle<Map> map, |
5471 bool is_store, | 5486 bool is_store, |
5472 KeyedAccessStoreMode store_mode) { | 5487 KeyedAccessStoreMode store_mode) { |
5473 HCheckMaps* mapcheck = HCheckMaps::New( | 5488 HCheckMaps* mapcheck = HCheckMaps::New( |
5474 object, map, zone(), top_info(), dependency); | 5489 object, map, zone(), top_info(), dependency); |
5475 AddInstruction(mapcheck); | 5490 AddInstruction(mapcheck); |
5476 if (dependency) { | 5491 if (dependency) { |
5477 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 5492 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
5478 } | 5493 } |
5479 | 5494 |
5480 // Loads from a "stock" fast holey double arrays can elide the hole check. | |
5481 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | |
5482 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | |
5483 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | |
5484 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | |
5485 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | |
5486 Add<HCheckPrototypeMaps>(prototype, object_prototype, zone(), top_info()); | |
5487 load_mode = ALLOW_RETURN_HOLE; | |
5488 graph()->MarkDependsOnEmptyArrayProtoElements(); | |
5489 } | |
5490 | |
5491 return BuildUncheckedMonomorphicElementAccess( | 5495 return BuildUncheckedMonomorphicElementAccess( |
5492 object, key, val, | 5496 object, key, val, |
5493 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | 5497 mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
5494 map->elements_kind(), is_store, load_mode, store_mode); | 5498 map->elements_kind(), is_store, |
5499 GetKeyedHoleMode(map), store_mode); | |
5495 } | 5500 } |
5496 | 5501 |
5497 | 5502 |
5498 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( | 5503 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
5499 HValue* object, | 5504 HValue* object, |
5500 HValue* key, | 5505 HValue* key, |
5501 HValue* val, | 5506 HValue* val, |
5502 SmallMapList* maps) { | 5507 SmallMapList* maps) { |
5503 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 5508 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
5504 // double), always use the "worst case" code without a transition. This is | 5509 // double), always use the "worst case" code without a transition. This is |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5645 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 5650 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
5646 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 5651 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
5647 HCompareMap* mapcompare = | 5652 HCompareMap* mapcompare = |
5648 new(zone()) HCompareMap(object, map, this_map, other_map); | 5653 new(zone()) HCompareMap(object, map, this_map, other_map); |
5649 current_block()->Finish(mapcompare); | 5654 current_block()->Finish(mapcompare); |
5650 | 5655 |
5651 set_current_block(this_map); | 5656 set_current_block(this_map); |
5652 HInstruction* checked_key = NULL; | 5657 HInstruction* checked_key = NULL; |
5653 HInstruction* access = NULL; | 5658 HInstruction* access = NULL; |
5654 if (IsFastElementsKind(elements_kind)) { | 5659 if (IsFastElementsKind(elements_kind)) { |
5655 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5660 access = BuildUncheckedMonomorphicElementAccess( |
5656 AddInstruction(HCheckMaps::New( | 5661 object, key, val, |
5657 elements, isolate()->factory()->fixed_array_map(), | 5662 NULL, |
Jakob Kummerow
2013/07/31 09:43:00
I'm pretty sure that you need to pass |mapcompare|
| |
5658 zone(), top_info(), mapcompare)); | 5663 map->instance_type() == JS_ARRAY_TYPE, |
5659 } | 5664 elements_kind, is_store, |
5660 if (map->instance_type() == JS_ARRAY_TYPE) { | 5665 GetKeyedHoleMode(map), |
5661 HInstruction* length = AddLoad( | 5666 store_mode); |
5662 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare); | |
5663 checked_key = Add<HBoundsCheck>(key, length); | |
5664 } else { | |
5665 HInstruction* length = AddLoadFixedArrayLength(elements); | |
5666 checked_key = Add<HBoundsCheck>(key, length); | |
5667 } | |
5668 access = AddFastElementAccess( | |
5669 elements, checked_key, val, mapcompare, | |
5670 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); | |
5671 } else if (IsDictionaryElementsKind(elements_kind)) { | 5667 } else if (IsDictionaryElementsKind(elements_kind)) { |
5672 if (is_store) { | 5668 if (is_store) { |
5673 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 5669 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
5674 } else { | 5670 } else { |
5675 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 5671 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
5676 } | 5672 } |
5677 } else { | 5673 } else { |
5678 ASSERT(IsExternalArrayElementsKind(elements_kind)); | 5674 ASSERT(IsExternalArrayElementsKind(elements_kind)); |
Jakob Kummerow
2013/07/31 09:43:00
AFAICS BuildUncheckedMonomorphicElementAccess can
| |
5679 HInstruction* length = AddLoadFixedArrayLength(elements); | 5675 HInstruction* length = AddLoadFixedArrayLength(elements); |
5680 checked_key = Add<HBoundsCheck>(key, length); | 5676 checked_key = Add<HBoundsCheck>(key, length); |
5681 HLoadExternalArrayPointer* external_elements = | 5677 HLoadExternalArrayPointer* external_elements = |
5682 Add<HLoadExternalArrayPointer>(elements); | 5678 Add<HLoadExternalArrayPointer>(elements); |
5683 access = AddExternalArrayElementAccess( | 5679 access = AddExternalArrayElementAccess( |
5684 external_elements, checked_key, val, | 5680 external_elements, checked_key, val, |
5685 mapcompare, elements_kind, is_store); | 5681 mapcompare, elements_kind, is_store); |
5686 } | 5682 } |
5687 *has_side_effects |= access->HasObservableSideEffects(); | 5683 *has_side_effects |= access->HasObservableSideEffects(); |
5688 // The caller will use has_side_effects and add a correct Simulate. | 5684 // The caller will use has_side_effects and add a correct Simulate. |
(...skipping 4223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9912 if (ShouldProduceTraceOutput()) { | 9908 if (ShouldProduceTraceOutput()) { |
9913 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9909 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9914 } | 9910 } |
9915 | 9911 |
9916 #ifdef DEBUG | 9912 #ifdef DEBUG |
9917 graph_->Verify(false); // No full verify. | 9913 graph_->Verify(false); // No full verify. |
9918 #endif | 9914 #endif |
9919 } | 9915 } |
9920 | 9916 |
9921 } } // namespace v8::internal | 9917 } } // namespace v8::internal |
OLD | NEW |