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