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 5558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5569 HValue* dependency, | 5569 HValue* dependency, |
5570 Handle<Map> map, | 5570 Handle<Map> map, |
5571 bool is_store, | 5571 bool is_store, |
5572 KeyedAccessStoreMode store_mode) { | 5572 KeyedAccessStoreMode store_mode) { |
5573 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), | 5573 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), |
5574 dependency); | 5574 dependency); |
5575 if (dependency) { | 5575 if (dependency) { |
5576 checked_object->ClearGVNFlag(kDependsOnElementsKind); | 5576 checked_object->ClearGVNFlag(kDependsOnElementsKind); |
5577 } | 5577 } |
5578 | 5578 |
| 5579 if (is_store && map->prototype()->IsJSObject()) { |
| 5580 // monomorphic stores need a prototype chain check because shape |
| 5581 // changes could allow callbacks on elements in the chain that |
| 5582 // aren't compatible with monomorphic keyed stores. |
| 5583 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 5584 Object* holder = map->prototype(); |
| 5585 while (holder->GetPrototype(isolate())->IsJSObject()) { |
| 5586 holder = holder->GetPrototype(isolate()); |
| 5587 } |
| 5588 ASSERT(holder->GetPrototype(isolate())->IsNull()); |
| 5589 |
| 5590 BuildCheckPrototypeMaps(prototype, |
| 5591 Handle<JSObject>(JSObject::cast(holder))); |
| 5592 } |
| 5593 |
5579 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 5594 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
5580 return BuildUncheckedMonomorphicElementAccess( | 5595 return BuildUncheckedMonomorphicElementAccess( |
5581 checked_object, key, val, | 5596 checked_object, key, val, |
5582 map->instance_type() == JS_ARRAY_TYPE, | 5597 map->instance_type() == JS_ARRAY_TYPE, |
5583 map->elements_kind(), is_store, | 5598 map->elements_kind(), is_store, |
5584 load_mode, store_mode); | 5599 load_mode, store_mode); |
5585 } | 5600 } |
5586 | 5601 |
5587 | 5602 |
5588 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( | 5603 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5782 HValue* val, | 5797 HValue* val, |
5783 Expression* expr, | 5798 Expression* expr, |
5784 bool is_store, | 5799 bool is_store, |
5785 bool* has_side_effects) { | 5800 bool* has_side_effects) { |
5786 ASSERT(!expr->IsPropertyName()); | 5801 ASSERT(!expr->IsPropertyName()); |
5787 HInstruction* instr = NULL; | 5802 HInstruction* instr = NULL; |
5788 | 5803 |
5789 SmallMapList* types; | 5804 SmallMapList* types; |
5790 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); | 5805 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); |
5791 | 5806 |
| 5807 bool force_generic = false; |
| 5808 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) { |
| 5809 // Stores can't be mono/polymorphic if their prototype chain has dictionary |
| 5810 // elements. However a receiver map that has dictionary elements itself |
| 5811 // should be left to normal mono/poly behavior (the other maps may benefit |
| 5812 // from highly optimized stores). |
| 5813 for (int i = 0; i < types->length(); i++) { |
| 5814 Handle<Map> current_map = types->at(i); |
| 5815 if (current_map->DictionaryElementsInPrototypeChainOnly()) { |
| 5816 force_generic = true; |
| 5817 monomorphic = false; |
| 5818 break; |
| 5819 } |
| 5820 } |
| 5821 } |
| 5822 |
5792 if (monomorphic) { | 5823 if (monomorphic) { |
5793 Handle<Map> map = types->first(); | 5824 Handle<Map> map = types->first(); |
5794 if (map->has_slow_elements_kind()) { | 5825 if (map->has_slow_elements_kind()) { |
5795 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) | 5826 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) |
5796 : BuildLoadKeyedGeneric(obj, key); | 5827 : BuildLoadKeyedGeneric(obj, key); |
5797 AddInstruction(instr); | 5828 AddInstruction(instr); |
5798 } else { | 5829 } else { |
5799 BuildCheckHeapObject(obj); | 5830 BuildCheckHeapObject(obj); |
5800 instr = BuildMonomorphicElementAccess( | 5831 instr = BuildMonomorphicElementAccess( |
5801 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); | 5832 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); |
5802 } | 5833 } |
5803 } else if (types != NULL && !types->is_empty()) { | 5834 } else if (!force_generic && (types != NULL && !types->is_empty())) { |
5804 return HandlePolymorphicElementAccess( | 5835 return HandlePolymorphicElementAccess( |
5805 obj, key, val, types, is_store, | 5836 obj, key, val, types, is_store, |
5806 expr->GetStoreMode(), has_side_effects); | 5837 expr->GetStoreMode(), has_side_effects); |
5807 } else { | 5838 } else { |
5808 if (is_store) { | 5839 if (is_store) { |
5809 if (expr->IsAssignment() && | 5840 if (expr->IsAssignment() && |
5810 expr->AsAssignment()->HasNoTypeInformation()) { | 5841 expr->AsAssignment()->HasNoTypeInformation()) { |
5811 Add<HDeoptimize>("Insufficient type feedback for keyed store", | 5842 Add<HDeoptimize>("Insufficient type feedback for keyed store", |
5812 Deoptimizer::SOFT); | 5843 Deoptimizer::SOFT); |
5813 } | 5844 } |
(...skipping 4009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9823 if (ShouldProduceTraceOutput()) { | 9854 if (ShouldProduceTraceOutput()) { |
9824 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9855 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9825 } | 9856 } |
9826 | 9857 |
9827 #ifdef DEBUG | 9858 #ifdef DEBUG |
9828 graph_->Verify(false); // No full verify. | 9859 graph_->Verify(false); // No full verify. |
9829 #endif | 9860 #endif |
9830 } | 9861 } |
9831 | 9862 |
9832 } } // namespace v8::internal | 9863 } } // namespace v8::internal |
OLD | NEW |