Chromium Code Reviews| 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 5766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5777 true); | 5777 true); |
| 5778 Push(value); | 5778 Push(value); |
| 5779 store->set_position(position); | 5779 store->set_position(position); |
| 5780 AddInstruction(store); | 5780 AddInstruction(store); |
| 5781 AddSimulate(assignment_id); | 5781 AddSimulate(assignment_id); |
| 5782 ast_context()->ReturnValue(Pop()); | 5782 ast_context()->ReturnValue(Pop()); |
| 5783 return true; | 5783 return true; |
| 5784 } | 5784 } |
| 5785 | 5785 |
| 5786 | 5786 |
| 5787 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedFieldHelper( | |
| 5788 HValue* object, | |
| 5789 Handle<String> name, | |
| 5790 HValue* value, | |
| 5791 SmallMapList* types, | |
| 5792 int current_type, | |
| 5793 int stored_count, | |
| 5794 int position) { | |
| 5795 HInstruction* instr = NULL; | |
| 5796 if (stored_count == kMaxStorePolymorphism || | |
| 5797 (current_type == types->length() - 1)) { | |
|
Toon Verwaest
2013/07/08 16:49:00
remove the - 1
| |
| 5798 if (FLAG_deoptimize_uncommon_cases) { | |
| 5799 AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); | |
|
Toon Verwaest
2013/07/08 16:49:00
Soft deopts aren't counted towards MaxDeopt to sto
| |
| 5800 } else { | |
| 5801 instr = BuildStoreNamedGeneric(object, name, value); | |
| 5802 instr->set_position(position); | |
| 5803 AddInstruction(instr); | |
| 5804 } | |
| 5805 return; | |
| 5806 } | |
| 5807 | |
| 5808 Handle<Map> map = types->at(current_type); | |
| 5809 LookupResult lookup(isolate()); | |
| 5810 if (!ComputeLoadStoreField(map, name, &lookup, true)) { | |
| 5811 HandlePolymorphicStoreNamedFieldHelper(object, name, value, types, | |
| 5812 current_type + 1, stored_count, | |
| 5813 position); | |
| 5814 return; | |
| 5815 } | |
| 5816 | |
| 5817 IfBuilder builder(this); | |
| 5818 builder.If<HCompareMap>(object, map); | |
| 5819 | |
| 5820 builder.Then(); | |
| 5821 CHECK_ALIVE(instr = BuildStoreNamedField(object, name, value, map, &lookup)); | |
| 5822 instr->set_position(position); | |
| 5823 AddInstruction(instr); | |
| 5824 | |
| 5825 builder.Else(); | |
| 5826 HandlePolymorphicStoreNamedFieldHelper(object, name, value, types, | |
| 5827 current_type + 1, stored_count + 1, | |
| 5828 position); | |
| 5829 builder.End(); | |
| 5830 } | |
| 5831 | |
| 5832 | |
| 5787 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 5833 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
| 5788 BailoutId id, | 5834 BailoutId id, |
| 5789 int position, | 5835 int position, |
| 5790 BailoutId assignment_id, | 5836 BailoutId assignment_id, |
| 5791 HValue* object, | 5837 HValue* object, |
| 5792 HValue* value, | 5838 HValue* value, |
| 5793 SmallMapList* types, | 5839 SmallMapList* types, |
| 5794 Handle<String> name) { | 5840 Handle<String> name) { |
| 5795 if (TryStorePolymorphicAsMonomorphic( | 5841 if (TryStorePolymorphicAsMonomorphic( |
| 5796 position, assignment_id, object, value, types, name)) { | 5842 position, assignment_id, object, value, types, name)) { |
| 5797 return; | 5843 return; |
| 5798 } | 5844 } |
| 5799 | 5845 |
| 5800 // TODO(ager): We should recognize when the prototype chains for different | 5846 { |
| 5801 // maps are identical. In that case we can avoid repeatedly generating the | 5847 Add<HCheckHeapObject>(object); |
| 5802 // same prototype map checks. | 5848 NoObservableSideEffectsScope no_effects(this); |
| 5803 int count = 0; | 5849 HandlePolymorphicStoreNamedFieldHelper(object, name, value, types, |
| 5804 HBasicBlock* join = NULL; | 5850 0, 0, position); |
| 5805 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | |
| 5806 Handle<Map> map = types->at(i); | |
| 5807 LookupResult lookup(isolate()); | |
| 5808 if (ComputeLoadStoreField(map, name, &lookup, true)) { | |
| 5809 if (count == 0) { | |
| 5810 BuildCheckHeapObject(object); | |
| 5811 join = graph()->CreateBasicBlock(); | |
| 5812 } | |
| 5813 ++count; | |
| 5814 HBasicBlock* if_true = graph()->CreateBasicBlock(); | |
| 5815 HBasicBlock* if_false = graph()->CreateBasicBlock(); | |
| 5816 HCompareMap* compare = | |
| 5817 new(zone()) HCompareMap(object, map, if_true, if_false); | |
| 5818 current_block()->Finish(compare); | |
| 5819 | |
| 5820 set_current_block(if_true); | |
| 5821 HInstruction* instr; | |
| 5822 CHECK_ALIVE( | |
| 5823 instr = BuildStoreNamedField(object, name, value, map, &lookup)); | |
| 5824 instr->set_position(position); | |
| 5825 // Goto will add the HSimulate for the store. | |
| 5826 AddInstruction(instr); | |
| 5827 if (!ast_context()->IsEffect()) Push(value); | |
| 5828 current_block()->Goto(join); | |
| 5829 | |
| 5830 set_current_block(if_false); | |
| 5831 } | |
| 5832 } | 5851 } |
| 5833 | 5852 |
| 5834 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 5853 if (ast_context()->IsEffect()) { |
| 5835 // know about and do not want to handle ones we've never seen. Otherwise | 5854 AddSimulate(id, REMOVABLE_SIMULATE); |
| 5836 // use a generic IC. | |
| 5837 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | |
| 5838 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | |
| 5839 } else { | 5855 } else { |
| 5840 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); | 5856 Push(value); |
| 5841 instr->set_position(position); | 5857 AddSimulate(id, REMOVABLE_SIMULATE); |
| 5842 AddInstruction(instr); | 5858 ast_context()->ReturnValue(Pop()); |
| 5843 | |
| 5844 if (join != NULL) { | |
| 5845 if (!ast_context()->IsEffect()) Push(value); | |
| 5846 current_block()->Goto(join); | |
| 5847 } else { | |
| 5848 // The HSimulate for the store should not see the stored value in | |
| 5849 // effect contexts (it is not materialized at expr->id() in the | |
| 5850 // unoptimized code). | |
| 5851 if (instr->HasObservableSideEffects()) { | |
| 5852 if (ast_context()->IsEffect()) { | |
| 5853 AddSimulate(id, REMOVABLE_SIMULATE); | |
| 5854 } else { | |
| 5855 Push(value); | |
| 5856 AddSimulate(id, REMOVABLE_SIMULATE); | |
| 5857 Drop(1); | |
| 5858 } | |
| 5859 } | |
| 5860 return ast_context()->ReturnValue(value); | |
| 5861 } | |
| 5862 } | 5859 } |
| 5863 | |
| 5864 ASSERT(join != NULL); | |
| 5865 join->SetJoinId(id); | |
| 5866 set_current_block(join); | |
| 5867 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | |
| 5868 } | 5860 } |
| 5869 | 5861 |
| 5870 | 5862 |
| 5871 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 5863 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| 5872 Property* prop = expr->target()->AsProperty(); | 5864 Property* prop = expr->target()->AsProperty(); |
| 5873 ASSERT(prop != NULL); | 5865 ASSERT(prop != NULL); |
| 5874 CHECK_ALIVE(VisitForValue(prop->obj())); | 5866 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5875 | 5867 |
| 5876 if (prop->key()->IsPropertyName()) { | 5868 if (prop->key()->IsPropertyName()) { |
| 5877 // Named store. | 5869 // Named store. |
| (...skipping 4959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10837 if (ShouldProduceTraceOutput()) { | 10829 if (ShouldProduceTraceOutput()) { |
| 10838 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10830 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10839 } | 10831 } |
| 10840 | 10832 |
| 10841 #ifdef DEBUG | 10833 #ifdef DEBUG |
| 10842 graph_->Verify(false); // No full verify. | 10834 graph_->Verify(false); // No full verify. |
| 10843 #endif | 10835 #endif |
| 10844 } | 10836 } |
| 10845 | 10837 |
| 10846 } } // namespace v8::internal | 10838 } } // namespace v8::internal |
| OLD | NEW |