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 4637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4648 if (lookup.IsFound()) return false; | 4648 if (lookup.IsFound()) return false; |
4649 if (!lookup.IsCacheable()) return false; | 4649 if (!lookup.IsCacheable()) return false; |
4650 current = JSObject::cast(current)->GetPrototype(); | 4650 current = JSObject::cast(current)->GetPrototype(); |
4651 } | 4651 } |
4652 return true; | 4652 return true; |
4653 } | 4653 } |
4654 | 4654 |
4655 | 4655 |
4656 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 4656 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
4657 int position, | 4657 int position, |
4658 BailoutId return_id, | 4658 BailoutId ast_id, |
4659 HValue* object, | 4659 HValue* object, |
4660 SmallMapList* types, | 4660 SmallMapList* types, |
4661 Handle<String> name) { | 4661 Handle<String> name) { |
4662 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(object, types, name); | 4662 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(object, types, name); |
4663 if (instr != NULL) { | 4663 if (instr != NULL) { |
4664 instr->set_position(position); | 4664 instr->set_position(position); |
4665 return ast_context()->ReturnInstruction(instr, return_id); | 4665 return ast_context()->ReturnInstruction(instr, ast_id); |
4666 } | 4666 } |
4667 | 4667 |
4668 // Something did not match; must use a polymorphic load. | 4668 // Something did not match; must use a polymorphic load. |
4669 int count = 0; | 4669 int count = 0; |
4670 HBasicBlock* join = NULL; | 4670 HBasicBlock* join = NULL; |
4671 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { | 4671 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { |
4672 Handle<Map> map = types->at(i); | 4672 Handle<Map> map = types->at(i); |
4673 LookupResult lookup(isolate()); | 4673 LookupResult lookup(isolate()); |
4674 if (ComputeLoadStoreField(map, name, &lookup, false) || | 4674 if (ComputeLoadStoreField(map, name, &lookup, false) || |
4675 (lookup.IsCacheable() && | 4675 (lookup.IsCacheable() && |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4727 } else { | 4727 } else { |
4728 HValue* context = environment()->context(); | 4728 HValue* context = environment()->context(); |
4729 HInstruction* load = new(zone()) HLoadNamedGeneric(context, object, name); | 4729 HInstruction* load = new(zone()) HLoadNamedGeneric(context, object, name); |
4730 load->set_position(position); | 4730 load->set_position(position); |
4731 AddInstruction(load); | 4731 AddInstruction(load); |
4732 if (!ast_context()->IsEffect()) Push(load); | 4732 if (!ast_context()->IsEffect()) Push(load); |
4733 | 4733 |
4734 if (join != NULL) { | 4734 if (join != NULL) { |
4735 current_block()->Goto(join); | 4735 current_block()->Goto(join); |
4736 } else { | 4736 } else { |
4737 Add<HSimulate>(return_id, REMOVABLE_SIMULATE); | 4737 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
4738 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 4738 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
4739 return; | 4739 return; |
4740 } | 4740 } |
4741 } | 4741 } |
4742 | 4742 |
4743 ASSERT(join != NULL); | 4743 ASSERT(join != NULL); |
4744 join->SetJoinId(return_id); | 4744 join->SetJoinId(ast_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* value, | 4754 HValue* value, |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5115 case Variable::LOOKUP: | 5115 case Variable::LOOKUP: |
5116 return Bailout(kCompoundAssignmentToLookupSlot); | 5116 return Bailout(kCompoundAssignmentToLookupSlot); |
5117 } | 5117 } |
5118 return ast_context()->ReturnValue(Pop()); | 5118 return ast_context()->ReturnValue(Pop()); |
5119 | 5119 |
5120 } else if (prop != NULL) { | 5120 } else if (prop != NULL) { |
5121 if (prop->key()->IsPropertyName()) { | 5121 if (prop->key()->IsPropertyName()) { |
5122 // Named property. | 5122 // Named property. |
5123 CHECK_ALIVE(VisitForValue(prop->obj())); | 5123 CHECK_ALIVE(VisitForValue(prop->obj())); |
5124 HValue* object = Top(); | 5124 HValue* object = Top(); |
5125 PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); | 5125 PushLoad(prop, object, expr->position()); |
5126 | 5126 |
5127 CHECK_ALIVE(VisitForValue(expr->value())); | 5127 CHECK_ALIVE(VisitForValue(expr->value())); |
5128 HValue* right = Pop(); | 5128 HValue* right = Pop(); |
5129 HValue* left = Pop(); | 5129 HValue* left = Pop(); |
5130 | 5130 |
5131 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5131 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5132 PushAndAdd(instr); | 5132 PushAndAdd(instr); |
5133 if (instr->HasObservableSideEffects()) { | 5133 if (instr->HasObservableSideEffects()) { |
5134 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); | 5134 Add<HSimulate>(operation->id(), REMOVABLE_SIMULATE); |
5135 } | 5135 } |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5818 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 5818 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
5819 } | 5819 } |
5820 } | 5820 } |
5821 ast_context()->ReturnInstruction(result, expr->id()); | 5821 ast_context()->ReturnInstruction(result, expr->id()); |
5822 return true; | 5822 return true; |
5823 } | 5823 } |
5824 | 5824 |
5825 | 5825 |
5826 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 5826 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
5827 HValue* object, | 5827 HValue* object, |
5828 int position, | 5828 int position) { |
5829 BailoutId ast_id, | |
5830 BailoutId return_id) { | |
5831 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); | 5829 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
5832 Push(object); | 5830 Push(object); |
5833 BuildLoad(expr, position, ast_id, return_id); | 5831 BuildLoad(expr, position, expr->LoadId()); |
5834 } | 5832 } |
5835 | 5833 |
5836 | 5834 |
5837 void HOptimizedGraphBuilder::BuildLoad(Property* expr, | 5835 void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
5838 int position, | 5836 int position, |
5839 BailoutId ast_id, | 5837 BailoutId ast_id) { |
5840 BailoutId return_id) { | |
5841 HInstruction* instr = NULL; | 5838 HInstruction* instr = NULL; |
5842 if (expr->IsStringLength()) { | 5839 if (expr->IsStringLength()) { |
5843 HValue* string = Pop(); | 5840 HValue* string = Pop(); |
5844 BuildCheckHeapObject(string); | 5841 BuildCheckHeapObject(string); |
5845 HInstruction* checkstring = | 5842 HInstruction* checkstring = |
5846 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 5843 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
5847 instr = BuildLoadStringLength(string, checkstring); | 5844 instr = BuildLoadStringLength(string, checkstring); |
5848 } else if (expr->IsStringAccess()) { | 5845 } else if (expr->IsStringAccess()) { |
5849 CHECK_ALIVE(VisitForValue(expr->key())); | 5846 CHECK_ALIVE(VisitForValue(expr->key())); |
5850 HValue* index = Pop(); | 5847 HValue* index = Pop(); |
(...skipping 21 matching lines...) Expand all Loading... |
5872 monomorphic = CanInlinePropertyAccess(*map); | 5869 monomorphic = CanInlinePropertyAccess(*map); |
5873 } else if (object->HasMonomorphicJSObjectType()) { | 5870 } else if (object->HasMonomorphicJSObjectType()) { |
5874 map = object->GetMonomorphicJSObjectMap(); | 5871 map = object->GetMonomorphicJSObjectMap(); |
5875 monomorphic = CanInlinePropertyAccess(*map); | 5872 monomorphic = CanInlinePropertyAccess(*map); |
5876 } | 5873 } |
5877 if (monomorphic) { | 5874 if (monomorphic) { |
5878 Handle<JSFunction> getter; | 5875 Handle<JSFunction> getter; |
5879 Handle<JSObject> holder; | 5876 Handle<JSObject> holder; |
5880 if (LookupGetter(map, name, &getter, &holder)) { | 5877 if (LookupGetter(map, name, &getter, &holder)) { |
5881 AddCheckConstantFunction(holder, Top(), map); | 5878 AddCheckConstantFunction(holder, Top(), map); |
5882 if (FLAG_inline_accessors && TryInlineGetter(getter, return_id)) return; | 5879 if (FLAG_inline_accessors && |
| 5880 TryInlineGetter(getter, ast_id, expr->LoadId())) { |
| 5881 return; |
| 5882 } |
5883 Add<HPushArgument>(Pop()); | 5883 Add<HPushArgument>(Pop()); |
5884 instr = new(zone()) HCallConstantFunction(getter, 1); | 5884 instr = new(zone()) HCallConstantFunction(getter, 1); |
5885 } else { | 5885 } else { |
5886 instr = BuildLoadNamedMonomorphic(Pop(), name, map); | 5886 instr = BuildLoadNamedMonomorphic(Pop(), name, map); |
5887 } | 5887 } |
5888 } else if (types != NULL && types->length() > 1) { | 5888 } else if (types != NULL && types->length() > 1) { |
5889 return HandlePolymorphicLoadNamedField( | 5889 return HandlePolymorphicLoadNamedField( |
5890 position, return_id, Pop(), types, name); | 5890 position, ast_id, Pop(), types, name); |
5891 } else { | 5891 } else { |
5892 instr = BuildLoadNamedGeneric(Pop(), name, expr); | 5892 instr = BuildLoadNamedGeneric(Pop(), name, expr); |
5893 } | 5893 } |
5894 | 5894 |
5895 } else { | 5895 } else { |
5896 CHECK_ALIVE(VisitForValue(expr->key())); | 5896 CHECK_ALIVE(VisitForValue(expr->key())); |
5897 | 5897 |
5898 HValue* key = Pop(); | 5898 HValue* key = Pop(); |
5899 HValue* obj = Pop(); | 5899 HValue* obj = Pop(); |
5900 | 5900 |
5901 bool has_side_effects = false; | 5901 bool has_side_effects = false; |
5902 HValue* load = HandleKeyedElementAccess( | 5902 HValue* load = HandleKeyedElementAccess( |
5903 obj, key, NULL, expr, return_id, position, | 5903 obj, key, NULL, expr, ast_id, position, |
5904 false, // is_store | 5904 false, // is_store |
5905 &has_side_effects); | 5905 &has_side_effects); |
5906 if (has_side_effects) { | 5906 if (has_side_effects) { |
5907 if (ast_context()->IsEffect()) { | 5907 if (ast_context()->IsEffect()) { |
5908 Add<HSimulate>(return_id, REMOVABLE_SIMULATE); | 5908 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
5909 } else { | 5909 } else { |
5910 Push(load); | 5910 Push(load); |
5911 Add<HSimulate>(return_id, REMOVABLE_SIMULATE); | 5911 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
5912 Drop(1); | 5912 Drop(1); |
5913 } | 5913 } |
5914 } | 5914 } |
5915 return ast_context()->ReturnValue(load); | 5915 return ast_context()->ReturnValue(load); |
5916 } | 5916 } |
5917 instr->set_position(position); | 5917 instr->set_position(position); |
5918 return ast_context()->ReturnInstruction(instr, return_id); | 5918 return ast_context()->ReturnInstruction(instr, ast_id); |
5919 } | 5919 } |
5920 | 5920 |
5921 | 5921 |
5922 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 5922 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
5923 ASSERT(!HasStackOverflow()); | 5923 ASSERT(!HasStackOverflow()); |
5924 ASSERT(current_block() != NULL); | 5924 ASSERT(current_block() != NULL); |
5925 ASSERT(current_block()->HasPredecessor()); | 5925 ASSERT(current_block()->HasPredecessor()); |
5926 | 5926 |
5927 if (TryArgumentsAccess(expr)) return; | 5927 if (TryArgumentsAccess(expr)) return; |
5928 | 5928 |
5929 CHECK_ALIVE(VisitForValue(expr->obj())); | 5929 CHECK_ALIVE(VisitForValue(expr->obj())); |
5930 BuildLoad(expr, expr->position(), expr->id(), expr->id()); | 5930 BuildLoad(expr, expr->position(), expr->id()); |
5931 } | 5931 } |
5932 | 5932 |
5933 | 5933 |
5934 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, | 5934 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, |
5935 CompilationInfo* info) { | 5935 CompilationInfo* info) { |
5936 HConstant* constant_value = New<HConstant>(constant); | 5936 HConstant* constant_value = New<HConstant>(constant); |
5937 | 5937 |
5938 if (constant->map()->CanOmitMapChecks()) { | 5938 if (constant->map()->CanOmitMapChecks()) { |
5939 constant->map()->AddDependentCompilationInfo( | 5939 constant->map()->AddDependentCompilationInfo( |
5940 DependentCode::kPrototypeCheckGroup, info); | 5940 DependentCode::kPrototypeCheckGroup, info); |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6597 expr->target(), | 6597 expr->target(), |
6598 expr->arguments()->length(), | 6598 expr->arguments()->length(), |
6599 implicit_return_value, | 6599 implicit_return_value, |
6600 expr->id(), | 6600 expr->id(), |
6601 expr->ReturnId(), | 6601 expr->ReturnId(), |
6602 CONSTRUCT_CALL_RETURN); | 6602 CONSTRUCT_CALL_RETURN); |
6603 } | 6603 } |
6604 | 6604 |
6605 | 6605 |
6606 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 6606 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
| 6607 BailoutId ast_id, |
6607 BailoutId return_id) { | 6608 BailoutId return_id) { |
6608 return TryInline(CALL_AS_METHOD, | 6609 return TryInline(CALL_AS_METHOD, |
6609 getter, | 6610 getter, |
6610 0, | 6611 0, |
6611 NULL, | 6612 NULL, |
6612 return_id, | 6613 ast_id, |
6613 return_id, | 6614 return_id, |
6614 GETTER_CALL_RETURN); | 6615 GETTER_CALL_RETURN); |
6615 } | 6616 } |
6616 | 6617 |
6617 | 6618 |
6618 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 6619 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, |
6619 BailoutId id, | 6620 BailoutId id, |
6620 BailoutId assignment_id, | 6621 BailoutId assignment_id, |
6621 HValue* implicit_return_value) { | 6622 HValue* implicit_return_value) { |
6622 return TryInline(CALL_AS_METHOD, | 6623 return TryInline(CALL_AS_METHOD, |
(...skipping 930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7553 } else { | 7554 } else { |
7554 // Argument of the count operation is a property. | 7555 // Argument of the count operation is a property. |
7555 ASSERT(prop != NULL); | 7556 ASSERT(prop != NULL); |
7556 | 7557 |
7557 if (prop->key()->IsPropertyName()) { | 7558 if (prop->key()->IsPropertyName()) { |
7558 // Named property. | 7559 // Named property. |
7559 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 7560 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
7560 | 7561 |
7561 CHECK_ALIVE(VisitForValue(prop->obj())); | 7562 CHECK_ALIVE(VisitForValue(prop->obj())); |
7562 HValue* object = Top(); | 7563 HValue* object = Top(); |
7563 PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); | 7564 PushLoad(prop, object, expr->position()); |
7564 | 7565 |
7565 after = BuildIncrement(returns_original_input, expr); | 7566 after = BuildIncrement(returns_original_input, expr); |
7566 | 7567 |
7567 if (returns_original_input) { | 7568 if (returns_original_input) { |
7568 HValue* result = Pop(); | 7569 HValue* result = Pop(); |
7569 HValue* object = Pop(); | 7570 HValue* object = Pop(); |
7570 environment()->SetExpressionStackAt(0, result); | 7571 environment()->SetExpressionStackAt(0, result); |
7571 { | 7572 { |
7572 EffectContext for_effect(this); | 7573 EffectContext for_effect(this); |
7573 Push(object); | 7574 Push(object); |
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9713 if (ShouldProduceTraceOutput()) { | 9714 if (ShouldProduceTraceOutput()) { |
9714 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9715 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9715 } | 9716 } |
9716 | 9717 |
9717 #ifdef DEBUG | 9718 #ifdef DEBUG |
9718 graph_->Verify(false); // No full verify. | 9719 graph_->Verify(false); // No full verify. |
9719 #endif | 9720 #endif |
9720 } | 9721 } |
9721 | 9722 |
9722 } } // namespace v8::internal | 9723 } } // namespace v8::internal |
OLD | NEW |