| 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 4733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4744 join->SetJoinId(return_id); | 4744 join->SetJoinId(return_id); |
| 4745 set_current_block(join); | 4745 set_current_block(join); |
| 4746 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 4746 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 4747 } | 4747 } |
| 4748 | 4748 |
| 4749 | 4749 |
| 4750 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( | 4750 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( |
| 4751 int position, | 4751 int position, |
| 4752 BailoutId assignment_id, | 4752 BailoutId assignment_id, |
| 4753 HValue* object, | 4753 HValue* object, |
| 4754 HValue* store_value, | 4754 HValue* value, |
| 4755 HValue* result_value, | |
| 4756 SmallMapList* types, | 4755 SmallMapList* types, |
| 4757 Handle<String> name) { | 4756 Handle<String> name) { |
| 4758 // Use monomorphic store if property lookup results in the same field index | 4757 // Use monomorphic store if property lookup results in the same field index |
| 4759 // for all maps. Requires special map check on the set of all handled maps. | 4758 // for all maps. Requires special map check on the set of all handled maps. |
| 4760 if (types->length() > kMaxStorePolymorphism) return false; | 4759 if (types->length() > kMaxStorePolymorphism) return false; |
| 4761 | 4760 |
| 4762 // TODO(verwaest): Merge the checking logic with the code in | 4761 // TODO(verwaest): Merge the checking logic with the code in |
| 4763 // TryLoadPolymorphicAsMonomorphic. | 4762 // TryLoadPolymorphicAsMonomorphic. |
| 4764 LookupResult lookup(isolate()); | 4763 LookupResult lookup(isolate()); |
| 4765 int count; | 4764 int count; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4791 } | 4790 } |
| 4792 | 4791 |
| 4793 if (count != types->length()) return false; | 4792 if (count != types->length()) return false; |
| 4794 | 4793 |
| 4795 // Everything matched; can use monomorphic store. | 4794 // Everything matched; can use monomorphic store. |
| 4796 BuildCheckHeapObject(object); | 4795 BuildCheckHeapObject(object); |
| 4797 HCheckMaps* checked_object = Add<HCheckMaps>(object, types); | 4796 HCheckMaps* checked_object = Add<HCheckMaps>(object, types); |
| 4798 HInstruction* store; | 4797 HInstruction* store; |
| 4799 CHECK_ALIVE_OR_RETURN( | 4798 CHECK_ALIVE_OR_RETURN( |
| 4800 store = BuildStoreNamedField( | 4799 store = BuildStoreNamedField( |
| 4801 checked_object, name, store_value, types->at(count - 1), &lookup), | 4800 checked_object, name, value, types->at(count - 1), &lookup), |
| 4802 true); | 4801 true); |
| 4803 if (!ast_context()->IsEffect()) Push(result_value); | 4802 if (!ast_context()->IsEffect()) Push(value); |
| 4804 store->set_position(position); | 4803 store->set_position(position); |
| 4805 AddInstruction(store); | 4804 AddInstruction(store); |
| 4806 Add<HSimulate>(assignment_id); | 4805 Add<HSimulate>(assignment_id); |
| 4807 if (!ast_context()->IsEffect()) Drop(1); | 4806 if (!ast_context()->IsEffect()) Drop(1); |
| 4808 ast_context()->ReturnValue(result_value); | 4807 ast_context()->ReturnValue(value); |
| 4809 return true; | 4808 return true; |
| 4810 } | 4809 } |
| 4811 | 4810 |
| 4812 | 4811 |
| 4813 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 4812 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
| 4814 int position, | 4813 int position, |
| 4815 BailoutId assignment_id, | 4814 BailoutId assignment_id, |
| 4816 HValue* object, | 4815 HValue* object, |
| 4817 HValue* store_value, | 4816 HValue* value, |
| 4818 HValue* result_value, | |
| 4819 SmallMapList* types, | 4817 SmallMapList* types, |
| 4820 Handle<String> name) { | 4818 Handle<String> name) { |
| 4821 if (TryStorePolymorphicAsMonomorphic( | 4819 if (TryStorePolymorphicAsMonomorphic( |
| 4822 position, assignment_id, object, | 4820 position, assignment_id, object, value, types, name)) { |
| 4823 store_value, result_value, types, name)) { | |
| 4824 return; | 4821 return; |
| 4825 } | 4822 } |
| 4826 | 4823 |
| 4827 // TODO(ager): We should recognize when the prototype chains for different | 4824 // TODO(ager): We should recognize when the prototype chains for different |
| 4828 // maps are identical. In that case we can avoid repeatedly generating the | 4825 // maps are identical. In that case we can avoid repeatedly generating the |
| 4829 // same prototype map checks. | 4826 // same prototype map checks. |
| 4830 int count = 0; | 4827 int count = 0; |
| 4831 HBasicBlock* join = NULL; | 4828 HBasicBlock* join = NULL; |
| 4832 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 4829 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
| 4833 Handle<Map> map = types->at(i); | 4830 Handle<Map> map = types->at(i); |
| 4834 LookupResult lookup(isolate()); | 4831 LookupResult lookup(isolate()); |
| 4835 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 4832 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
| 4836 if (count == 0) { | 4833 if (count == 0) { |
| 4837 BuildCheckHeapObject(object); | 4834 BuildCheckHeapObject(object); |
| 4838 join = graph()->CreateBasicBlock(); | 4835 join = graph()->CreateBasicBlock(); |
| 4839 } | 4836 } |
| 4840 ++count; | 4837 ++count; |
| 4841 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4838 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 4842 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4839 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 4843 HCompareMap* compare = | 4840 HCompareMap* compare = |
| 4844 new(zone()) HCompareMap(object, map, if_true, if_false); | 4841 new(zone()) HCompareMap(object, map, if_true, if_false); |
| 4845 current_block()->Finish(compare); | 4842 current_block()->Finish(compare); |
| 4846 | 4843 |
| 4847 set_current_block(if_true); | 4844 set_current_block(if_true); |
| 4848 HInstruction* instr; | 4845 HInstruction* instr; |
| 4849 CHECK_ALIVE(instr = BuildStoreNamedField( | 4846 CHECK_ALIVE(instr = BuildStoreNamedField( |
| 4850 compare, name, store_value, map, &lookup)); | 4847 compare, name, value, map, &lookup)); |
| 4851 instr->set_position(position); | 4848 instr->set_position(position); |
| 4852 // Goto will add the HSimulate for the store. | 4849 // Goto will add the HSimulate for the store. |
| 4853 AddInstruction(instr); | 4850 AddInstruction(instr); |
| 4854 if (!ast_context()->IsEffect()) Push(result_value); | 4851 if (!ast_context()->IsEffect()) Push(value); |
| 4855 current_block()->Goto(join); | 4852 current_block()->Goto(join); |
| 4856 | 4853 |
| 4857 set_current_block(if_false); | 4854 set_current_block(if_false); |
| 4858 } | 4855 } |
| 4859 } | 4856 } |
| 4860 | 4857 |
| 4861 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 4858 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 4862 // know about and do not want to handle ones we've never seen. Otherwise | 4859 // know about and do not want to handle ones we've never seen. Otherwise |
| 4863 // use a generic IC. | 4860 // use a generic IC. |
| 4864 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 4861 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
| 4865 FinishExitWithHardDeoptimization("Unknown map in polymorphic store", join); | 4862 FinishExitWithHardDeoptimization("Unknown map in polymorphic store", join); |
| 4866 } else { | 4863 } else { |
| 4867 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); | 4864 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); |
| 4868 instr->set_position(position); | 4865 instr->set_position(position); |
| 4869 AddInstruction(instr); | 4866 AddInstruction(instr); |
| 4870 | 4867 |
| 4871 if (join != NULL) { | 4868 if (join != NULL) { |
| 4872 if (!ast_context()->IsEffect()) { | 4869 if (!ast_context()->IsEffect()) { |
| 4873 Push(result_value); | 4870 Push(value); |
| 4874 } | 4871 } |
| 4875 current_block()->Goto(join); | 4872 current_block()->Goto(join); |
| 4876 } else { | 4873 } else { |
| 4877 // The HSimulate for the store should not see the stored value in | 4874 // The HSimulate for the store should not see the stored value in |
| 4878 // effect contexts (it is not materialized at expr->id() in the | 4875 // effect contexts (it is not materialized at expr->id() in the |
| 4879 // unoptimized code). | 4876 // unoptimized code). |
| 4880 if (instr->HasObservableSideEffects()) { | 4877 if (instr->HasObservableSideEffects()) { |
| 4881 if (ast_context()->IsEffect()) { | 4878 if (ast_context()->IsEffect()) { |
| 4882 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); | 4879 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); |
| 4883 } else { | 4880 } else { |
| 4884 Push(result_value); | 4881 Push(value); |
| 4885 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); | 4882 Add<HSimulate>(assignment_id, REMOVABLE_SIMULATE); |
| 4886 Drop(1); | 4883 Drop(1); |
| 4887 } | 4884 } |
| 4888 } | 4885 } |
| 4889 return ast_context()->ReturnValue(result_value); | 4886 return ast_context()->ReturnValue(value); |
| 4890 } | 4887 } |
| 4891 } | 4888 } |
| 4892 | 4889 |
| 4893 ASSERT(join != NULL); | 4890 ASSERT(join != NULL); |
| 4894 join->SetJoinId(assignment_id); | 4891 join->SetJoinId(assignment_id); |
| 4895 set_current_block(join); | 4892 set_current_block(join); |
| 4896 if (!ast_context()->IsEffect()) { | 4893 if (!ast_context()->IsEffect()) { |
| 4897 ast_context()->ReturnValue(Pop()); | 4894 ast_context()->ReturnValue(Pop()); |
| 4898 } | 4895 } |
| 4899 } | 4896 } |
| 4900 | 4897 |
| 4901 | 4898 |
| 4902 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 4899 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
| 4903 Property* prop = expr->target()->AsProperty(); | 4900 Property* prop = expr->target()->AsProperty(); |
| 4904 ASSERT(prop != NULL); | 4901 ASSERT(prop != NULL); |
| 4905 CHECK_ALIVE(VisitForValue(prop->obj())); | 4902 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 4906 | 4903 |
| 4907 if (prop->key()->IsPropertyName()) { | 4904 if (prop->key()->IsPropertyName()) { |
| 4908 // Named store. | 4905 // Named store. |
| 4909 CHECK_ALIVE(VisitForValue(expr->value())); | 4906 CHECK_ALIVE(VisitForValue(expr->value())); |
| 4910 HValue* value = environment()->ExpressionStackAt(0); | 4907 HValue* value = environment()->ExpressionStackAt(0); |
| 4911 HValue* object = environment()->ExpressionStackAt(1); | 4908 HValue* object = environment()->ExpressionStackAt(1); |
| 4912 | 4909 |
| 4913 if (expr->IsUninitialized()) { | 4910 if (expr->IsUninitialized()) { |
| 4914 Add<HDeoptimize>("Insufficient type feedback for property assignment", | 4911 Add<HDeoptimize>("Insufficient type feedback for property assignment", |
| 4915 Deoptimizer::SOFT); | 4912 Deoptimizer::SOFT); |
| 4916 } | 4913 } |
| 4917 return BuildStoreNamed(expr, expr->id(), expr->position(), | 4914 return BuildStoreNamed(expr, expr->id(), expr->position(), |
| 4918 expr->AssignmentId(), prop, object, value, value); | 4915 expr->AssignmentId(), prop, object, value); |
| 4919 } else { | 4916 } else { |
| 4920 // Keyed store. | 4917 // Keyed store. |
| 4921 CHECK_ALIVE(VisitForValue(prop->key())); | 4918 CHECK_ALIVE(VisitForValue(prop->key())); |
| 4922 CHECK_ALIVE(VisitForValue(expr->value())); | 4919 CHECK_ALIVE(VisitForValue(expr->value())); |
| 4923 HValue* value = environment()->ExpressionStackAt(0); | 4920 HValue* value = environment()->ExpressionStackAt(0); |
| 4924 HValue* key = environment()->ExpressionStackAt(1); | 4921 HValue* key = environment()->ExpressionStackAt(1); |
| 4925 HValue* object = environment()->ExpressionStackAt(2); | 4922 HValue* object = environment()->ExpressionStackAt(2); |
| 4926 bool has_side_effects = false; | 4923 bool has_side_effects = false; |
| 4927 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), | 4924 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), |
| 4928 expr->position(), | 4925 expr->position(), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4980 } | 4977 } |
| 4981 } | 4978 } |
| 4982 | 4979 |
| 4983 | 4980 |
| 4984 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 4981 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
| 4985 BailoutId id, | 4982 BailoutId id, |
| 4986 int position, | 4983 int position, |
| 4987 BailoutId assignment_id, | 4984 BailoutId assignment_id, |
| 4988 Property* prop, | 4985 Property* prop, |
| 4989 HValue* object, | 4986 HValue* object, |
| 4990 HValue* store_value, | 4987 HValue* value) { |
| 4991 HValue* result_value) { | |
| 4992 Literal* key = prop->key()->AsLiteral(); | 4988 Literal* key = prop->key()->AsLiteral(); |
| 4993 Handle<String> name = Handle<String>::cast(key->value()); | 4989 Handle<String> name = Handle<String>::cast(key->value()); |
| 4994 ASSERT(!name.is_null()); | 4990 ASSERT(!name.is_null()); |
| 4995 | 4991 |
| 4996 HInstruction* instr = NULL; | 4992 HInstruction* instr = NULL; |
| 4997 SmallMapList* types = expr->GetReceiverTypes(); | 4993 SmallMapList* types = expr->GetReceiverTypes(); |
| 4998 bool monomorphic = expr->IsMonomorphic(); | 4994 bool monomorphic = expr->IsMonomorphic(); |
| 4999 Handle<Map> map; | 4995 Handle<Map> map; |
| 5000 if (monomorphic) { | 4996 if (monomorphic) { |
| 5001 map = types->first(); | 4997 map = types->first(); |
| 5002 monomorphic = CanInlinePropertyAccess(*map); | 4998 monomorphic = CanInlinePropertyAccess(*map); |
| 5003 } | 4999 } |
| 5004 if (monomorphic) { | 5000 if (monomorphic) { |
| 5005 Handle<JSFunction> setter; | 5001 Handle<JSFunction> setter; |
| 5006 Handle<JSObject> holder; | 5002 Handle<JSObject> holder; |
| 5007 if (LookupSetter(map, name, &setter, &holder)) { | 5003 if (LookupSetter(map, name, &setter, &holder)) { |
| 5008 AddCheckConstantFunction(holder, object, map); | 5004 AddCheckConstantFunction(holder, object, map); |
| 5009 if (FLAG_inline_accessors) { | 5005 if (FLAG_inline_accessors && |
| 5010 if (result_value != store_value) { | 5006 TryInlineSetter(setter, id, assignment_id, value)) { |
| 5011 // The result_value and object are already pushed by CountOperation. | 5007 return; |
| 5012 // Push(store_value) to complete the arguments to the setter. | |
| 5013 Push(store_value); | |
| 5014 bool check = TryInlineSetter(setter, id, assignment_id, store_value); | |
| 5015 // Drop the result of the setter to return result_value that's on the | |
| 5016 // stack already. | |
| 5017 Drop(1); | |
| 5018 if (check) return; | |
| 5019 } else if (TryInlineSetter(setter, id, assignment_id, store_value)) { | |
| 5020 return; | |
| 5021 } | |
| 5022 } | 5008 } |
| 5023 Drop(2); | 5009 Drop(2); |
| 5024 Add<HPushArgument>(object); | 5010 Add<HPushArgument>(object); |
| 5025 Add<HPushArgument>(store_value); | 5011 Add<HPushArgument>(value); |
| 5026 instr = new(zone()) HCallConstantFunction(setter, 2); | 5012 instr = new(zone()) HCallConstantFunction(setter, 2); |
| 5027 } else { | 5013 } else { |
| 5028 Drop(2); | 5014 Drop(2); |
| 5029 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5015 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
| 5030 name, | 5016 name, |
| 5031 store_value, | 5017 value, |
| 5032 map)); | 5018 map)); |
| 5033 } | 5019 } |
| 5034 } else if (types != NULL && types->length() > 1) { | 5020 } else if (types != NULL && types->length() > 1) { |
| 5035 Drop(2); | 5021 Drop(2); |
| 5036 return HandlePolymorphicStoreNamedField( | 5022 return HandlePolymorphicStoreNamedField( |
| 5037 position, id, object, | 5023 position, id, object, value, types, name); |
| 5038 store_value, result_value, types, name); | |
| 5039 } else { | 5024 } else { |
| 5040 Drop(2); | 5025 Drop(2); |
| 5041 instr = BuildStoreNamedGeneric(object, name, store_value); | 5026 instr = BuildStoreNamedGeneric(object, name, value); |
| 5042 } | 5027 } |
| 5043 | 5028 |
| 5044 if (!ast_context()->IsEffect()) Push(result_value); | 5029 if (!ast_context()->IsEffect()) Push(value); |
| 5045 instr->set_position(position); | 5030 instr->set_position(position); |
| 5046 AddInstruction(instr); | 5031 AddInstruction(instr); |
| 5047 if (instr->HasObservableSideEffects()) { | 5032 if (instr->HasObservableSideEffects()) { |
| 5048 Add<HSimulate>(id, REMOVABLE_SIMULATE); | 5033 Add<HSimulate>(id, REMOVABLE_SIMULATE); |
| 5049 } | 5034 } |
| 5050 if (!ast_context()->IsEffect()) Drop(1); | 5035 if (!ast_context()->IsEffect()) Drop(1); |
| 5051 return ast_context()->ReturnValue(result_value); | 5036 return ast_context()->ReturnValue(value); |
| 5052 } | 5037 } |
| 5053 | 5038 |
| 5054 | 5039 |
| 5055 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 5040 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 5056 Expression* target = expr->target(); | 5041 Expression* target = expr->target(); |
| 5057 VariableProxy* proxy = target->AsVariableProxy(); | 5042 VariableProxy* proxy = target->AsVariableProxy(); |
| 5058 Property* prop = target->AsProperty(); | 5043 Property* prop = target->AsProperty(); |
| 5059 ASSERT(proxy == NULL || prop == NULL); | 5044 ASSERT(proxy == NULL || prop == NULL); |
| 5060 | 5045 |
| 5061 // We have a second position recorded in the FullCodeGenerator to have | 5046 // We have a second position recorded in the FullCodeGenerator to have |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5143 HValue* right = Pop(); | 5128 HValue* right = Pop(); |
| 5144 HValue* left = Pop(); | 5129 HValue* left = Pop(); |
| 5145 | 5130 |
| 5146 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5131 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
| 5147 PushAndAdd(instr); | 5132 PushAndAdd(instr); |
| 5148 if (instr->HasObservableSideEffects()) { | 5133 if (instr->HasObservableSideEffects()) { |
| 5149 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); | 5134 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); |
| 5150 } | 5135 } |
| 5151 | 5136 |
| 5152 return BuildStoreNamed(expr, expr->id(), expr->position(), | 5137 return BuildStoreNamed(expr, expr->id(), expr->position(), |
| 5153 expr->AssignmentId(), prop, object, instr, instr); | 5138 expr->AssignmentId(), prop, object, instr); |
| 5154 } else { | 5139 } else { |
| 5155 // Keyed property. | 5140 // Keyed property. |
| 5156 CHECK_ALIVE(VisitForValue(prop->obj())); | 5141 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 5157 CHECK_ALIVE(VisitForValue(prop->key())); | 5142 CHECK_ALIVE(VisitForValue(prop->key())); |
| 5158 HValue* obj = environment()->ExpressionStackAt(1); | 5143 HValue* obj = environment()->ExpressionStackAt(1); |
| 5159 HValue* key = environment()->ExpressionStackAt(0); | 5144 HValue* key = environment()->ExpressionStackAt(0); |
| 5160 | 5145 |
| 5161 bool has_side_effects = false; | 5146 bool has_side_effects = false; |
| 5162 HValue* load = HandleKeyedElementAccess( | 5147 HValue* load = HandleKeyedElementAccess( |
| 5163 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, | 5148 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, |
| (...skipping 2407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7571 | 7556 |
| 7572 if (prop->key()->IsPropertyName()) { | 7557 if (prop->key()->IsPropertyName()) { |
| 7573 // Named property. | 7558 // Named property. |
| 7574 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 7559 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 7575 | 7560 |
| 7576 CHECK_ALIVE(VisitForValue(prop->obj())); | 7561 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7577 HValue* object = Top(); | 7562 HValue* object = Top(); |
| 7578 PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); | 7563 PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); |
| 7579 | 7564 |
| 7580 after = BuildIncrement(returns_original_input, expr); | 7565 after = BuildIncrement(returns_original_input, expr); |
| 7581 HValue* result = returns_original_input ? Pop() : after; | 7566 |
| 7582 if (returns_original_input) { | 7567 if (returns_original_input) { |
| 7583 environment()->SetExpressionStackAt(1, result); | 7568 HValue* result = Pop(); |
| 7569 HValue* object = Pop(); |
| 7570 environment()->SetExpressionStackAt(0, result); |
| 7571 { |
| 7572 EffectContext for_effect(this); |
| 7573 Push(object); |
| 7574 Push(after); |
| 7575 return BuildStoreNamed(expr, expr->id(), expr->position(), |
| 7576 expr->AssignmentId(), prop, object, after); |
| 7577 } |
| 7584 } | 7578 } |
| 7585 | 7579 |
| 7586 return BuildStoreNamed(expr, expr->id(), expr->position(), | 7580 return BuildStoreNamed(expr, expr->id(), expr->position(), |
| 7587 expr->AssignmentId(), prop, object, after, result); | 7581 expr->AssignmentId(), prop, object, after); |
| 7588 } else { | 7582 } else { |
| 7589 // Keyed property. | 7583 // Keyed property. |
| 7590 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 7584 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
| 7591 | 7585 |
| 7592 CHECK_ALIVE(VisitForValue(prop->obj())); | 7586 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7593 CHECK_ALIVE(VisitForValue(prop->key())); | 7587 CHECK_ALIVE(VisitForValue(prop->key())); |
| 7594 HValue* obj = environment()->ExpressionStackAt(1); | 7588 HValue* obj = environment()->ExpressionStackAt(1); |
| 7595 HValue* key = environment()->ExpressionStackAt(0); | 7589 HValue* key = environment()->ExpressionStackAt(0); |
| 7596 | 7590 |
| 7597 bool has_side_effects = false; | 7591 bool has_side_effects = false; |
| (...skipping 2120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9718 if (ShouldProduceTraceOutput()) { | 9712 if (ShouldProduceTraceOutput()) { |
| 9719 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9713 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9720 } | 9714 } |
| 9721 | 9715 |
| 9722 #ifdef DEBUG | 9716 #ifdef DEBUG |
| 9723 graph_->Verify(false); // No full verify. | 9717 graph_->Verify(false); // No full verify. |
| 9724 #endif | 9718 #endif |
| 9725 } | 9719 } |
| 9726 | 9720 |
| 9727 } } // namespace v8::internal | 9721 } } // namespace v8::internal |
| OLD | NEW |