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 3840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3851 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); | 3851 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); |
3852 } else { | 3852 } else { |
3853 instruction->ReplaceAllUsesWith(instruction->ActualValue()); | 3853 instruction->ReplaceAllUsesWith(instruction->ActualValue()); |
3854 } | 3854 } |
3855 } | 3855 } |
3856 } | 3856 } |
3857 } | 3857 } |
3858 } | 3858 } |
3859 | 3859 |
3860 | 3860 |
3861 template <class Instruction> | 3861 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) { |
3862 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | |
3863 int count = call->argument_count(); | |
3864 ZoneList<HValue*> arguments(count, zone()); | 3862 ZoneList<HValue*> arguments(count, zone()); |
3865 for (int i = 0; i < count; ++i) { | 3863 for (int i = 0; i < count; ++i) { |
3866 arguments.Add(Pop(), zone()); | 3864 arguments.Add(Pop(), zone()); |
3867 } | 3865 } |
3868 | 3866 |
3869 while (!arguments.is_empty()) { | 3867 while (!arguments.is_empty()) { |
3870 Add<HPushArgument>(arguments.RemoveLast()); | 3868 Add<HPushArgument>(arguments.RemoveLast()); |
3871 } | 3869 } |
3870 } | |
3871 | |
3872 | |
3873 template <class Instruction> | |
3874 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) { | |
3875 PushArgumentsFromEnvironment(call->argument_count()); | |
3872 return call; | 3876 return call; |
3873 } | 3877 } |
3874 | 3878 |
3875 | 3879 |
3876 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { | 3880 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { |
3877 // First special is HContext. | 3881 // First special is HContext. |
3878 HInstruction* context = Add<HContext>(); | 3882 HInstruction* context = Add<HContext>(); |
3879 environment()->BindContext(context); | 3883 environment()->BindContext(context); |
3880 | 3884 |
3881 // Create an arguments object containing the initial parameters. Set the | 3885 // Create an arguments object containing the initial parameters. Set the |
(...skipping 1562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5444 } | 5448 } |
5445 | 5449 |
5446 if (info->lookup()->IsPropertyCallbacks()) { | 5450 if (info->lookup()->IsPropertyCallbacks()) { |
5447 Push(checked_object); | 5451 Push(checked_object); |
5448 if (FLAG_inline_accessors && | 5452 if (FLAG_inline_accessors && |
5449 can_inline_accessor && | 5453 can_inline_accessor && |
5450 TryInlineGetter(info->accessor(), ast_id, return_id)) { | 5454 TryInlineGetter(info->accessor(), ast_id, return_id)) { |
5451 return NULL; | 5455 return NULL; |
5452 } | 5456 } |
5453 Add<HPushArgument>(Pop()); | 5457 Add<HPushArgument>(Pop()); |
5454 return New<HCallConstantFunction>(info->accessor(), 1); | 5458 return BuildCallConstantFunction(info->accessor(), 1, CALL_AS_METHOD); |
5455 } | 5459 } |
5456 | 5460 |
5457 ASSERT(info->lookup()->IsConstant()); | 5461 ASSERT(info->lookup()->IsConstant()); |
5458 return New<HConstant>(info->constant()); | 5462 return New<HConstant>(info->constant()); |
5459 } | 5463 } |
5460 | 5464 |
5461 | 5465 |
5462 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 5466 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
5463 BailoutId ast_id, | 5467 BailoutId ast_id, |
5464 BailoutId return_id, | 5468 BailoutId return_id, |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5729 Handle<JSObject> holder; | 5733 Handle<JSObject> holder; |
5730 if (LookupSetter(map, name, &setter, &holder)) { | 5734 if (LookupSetter(map, name, &setter, &holder)) { |
5731 AddCheckConstantFunction(holder, object, map); | 5735 AddCheckConstantFunction(holder, object, map); |
5732 if (FLAG_inline_accessors && | 5736 if (FLAG_inline_accessors && |
5733 TryInlineSetter(setter, ast_id, return_id, value)) { | 5737 TryInlineSetter(setter, ast_id, return_id, value)) { |
5734 return; | 5738 return; |
5735 } | 5739 } |
5736 Drop(2); | 5740 Drop(2); |
5737 Add<HPushArgument>(object); | 5741 Add<HPushArgument>(object); |
5738 Add<HPushArgument>(value); | 5742 Add<HPushArgument>(value); |
5739 instr = New<HCallConstantFunction>(setter, 2); | 5743 instr = BuildCallConstantFunction(setter, 2, CALL_AS_METHOD); |
5740 } else { | 5744 } else { |
5741 Drop(2); | 5745 Drop(2); |
5742 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5746 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
5743 name, | 5747 name, |
5744 value, | 5748 value, |
5745 map)); | 5749 map)); |
5746 } | 5750 } |
5747 } else if (types != NULL && types->length() > 1) { | 5751 } else if (types != NULL && types->length() > 1) { |
5748 Drop(2); | 5752 Drop(2); |
5749 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name); | 5753 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name); |
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6679 HValue* receiver, | 6683 HValue* receiver, |
6680 Handle<Map> receiver_map) { | 6684 Handle<Map> receiver_map) { |
6681 // Constant functions have the nice property that the map will change if they | 6685 // Constant functions have the nice property that the map will change if they |
6682 // are overwritten. Therefore it is enough to check the map of the holder and | 6686 // are overwritten. Therefore it is enough to check the map of the holder and |
6683 // its prototypes. | 6687 // its prototypes. |
6684 AddCheckMap(receiver, receiver_map); | 6688 AddCheckMap(receiver, receiver_map); |
6685 AddCheckPrototypeMaps(holder, receiver_map); | 6689 AddCheckPrototypeMaps(holder, receiver_map); |
6686 } | 6690 } |
6687 | 6691 |
6688 | 6692 |
6693 HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall( | |
6694 HValue* fun, HValue* call_kind_value, | |
6695 int argument_count, bool pass_argument_count) { | |
6696 return New<HCallJSFunction>( | |
6697 fun, call_kind_value, argument_count, pass_argument_count); | |
6698 } | |
6699 | |
6700 | |
6701 HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall( | |
6702 HValue* fun, HValue* context, HValue* call_kind_value, | |
6703 int argument_count, HValue* expected_param_count) { | |
6704 CallInterfaceDescriptor* descriptor = | |
6705 isolate()->call_descriptor(Isolate::ArgumentAdaptorCall); | |
6706 | |
6707 HValue* arity = Add<HConstant>(argument_count - 1); | |
6708 | |
6709 HValue *op_vals[] = { fun, context, call_kind_value, arity, | |
Toon Verwaest
2014/01/14 15:33:50
HValue* op_vals
Jarin
2014/01/14 19:08:08
Done.
| |
6710 expected_param_count }; | |
6711 | |
6712 Handle<Code> adaptor = | |
6713 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | |
6714 HConstant* adaptor_value = Add<HConstant>(adaptor); | |
6715 | |
6716 return New<HCallWithDescriptor>( | |
6717 adaptor_value, argument_count, descriptor, | |
6718 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6719 } | |
6720 | |
6721 | |
6722 HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction( | |
6723 Handle<JSFunction> jsfun, int argument_count, CallKind call_kind) { | |
6724 HValue* target = Add<HConstant>(jsfun); | |
6725 HValue* call_kind_value = Add<HConstant>(static_cast<int>(call_kind)); | |
6726 // For constant functions, we try to avoid calling the | |
6727 // argument adaptor and instead call the function directly | |
6728 int formal_parameter_count = jsfun->shared()->formal_parameter_count(); | |
6729 bool dont_adapt_arguments = | |
6730 (formal_parameter_count == | |
6731 SharedFunctionInfo::kDontAdaptArgumentsSentinel); | |
6732 int arity = argument_count - 1; | |
6733 bool can_invoke_directly = | |
6734 dont_adapt_arguments || formal_parameter_count == arity; | |
6735 if (can_invoke_directly) { | |
6736 return NewPlainFunctionCall(target, call_kind_value, | |
6737 argument_count, dont_adapt_arguments); | |
6738 } else { | |
6739 HValue* param_count_value = Add<HConstant>(formal_parameter_count); | |
6740 HValue* context = Add<HLoadNamedField>(target, | |
6741 HObjectAccess::ForFunctionContextPointer()); | |
6742 return NewArgumentAdaptorCall(target, context, call_kind_value, | |
6743 argument_count, param_count_value); | |
6744 } | |
6745 UNREACHABLE(); | |
6746 return NULL; | |
6747 } | |
6748 | |
6749 | |
6750 HInstruction* HOptimizedGraphBuilder::NewCallNamed( | |
6751 Handle<String> name, int argument_count) { | |
6752 CallInterfaceDescriptor* descriptor = | |
6753 isolate()->call_descriptor(Isolate::NamedCall); | |
6754 | |
6755 HValue* name_val = Add<HConstant>(name); | |
6756 HValue* op_vals[] = { context(), name_val }; | |
6757 | |
6758 int arity = argument_count - 1; | |
6759 Handle<Code> ic = | |
6760 isolate()->stub_cache()->ComputeCallInitialize(arity, | |
6761 RelocInfo::CODE_TARGET); | |
6762 HConstant* ic_value = Add<HConstant>(ic); | |
6763 | |
6764 return New<HCallWithDescriptor>( | |
6765 ic_value, argument_count, descriptor, | |
6766 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6767 } | |
6768 | |
6769 | |
6770 HInstruction* HOptimizedGraphBuilder::NewCallKeyed( | |
6771 HValue* key, int argument_count) { | |
6772 CallInterfaceDescriptor* descriptor = | |
6773 isolate()->call_descriptor(Isolate::KeyedCall); | |
6774 | |
6775 HValue* op_vals[] = { context(), key }; | |
6776 | |
6777 int arity = argument_count - 1; | |
6778 Handle<Code> ic = | |
6779 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); | |
6780 HConstant* ic_value = Add<HConstant>(ic); | |
6781 | |
6782 return New<HCallWithDescriptor>( | |
6783 ic_value, argument_count, descriptor, | |
6784 Vector<HValue*>(op_vals, descriptor->environment_length())); | |
6785 } | |
Toon Verwaest
2014/01/14 15:33:50
This code looks almost exactly the same as the cod
Jarin
2014/01/14 19:08:08
I tried this, but it seems to add about as much co
| |
6786 | |
6689 class FunctionSorter { | 6787 class FunctionSorter { |
6690 public: | 6788 public: |
6691 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } | 6789 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } |
6692 FunctionSorter(int index, int ticks, int ast_length, int src_length) | 6790 FunctionSorter(int index, int ticks, int ast_length, int src_length) |
6693 : index_(index), | 6791 : index_(index), |
6694 ticks_(ticks), | 6792 ticks_(ticks), |
6695 ast_length_(ast_length), | 6793 ast_length_(ast_length), |
6696 src_length_(src_length) { } | 6794 src_length_(src_length) { } |
6697 | 6795 |
6698 int index() const { return index_; } | 6796 int index() const { return index_; } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6734 if (FLAG_trace_inlining) { | 6832 if (FLAG_trace_inlining) { |
6735 Handle<JSFunction> caller = current_info()->closure(); | 6833 Handle<JSFunction> caller = current_info()->closure(); |
6736 SmartArrayPointer<char> caller_name = | 6834 SmartArrayPointer<char> caller_name = |
6737 caller->shared()->DebugName()->ToCString(); | 6835 caller->shared()->DebugName()->ToCString(); |
6738 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6836 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
6739 name->ToCString().get(), caller_name.get()); | 6837 name->ToCString().get(), caller_name.get()); |
6740 } | 6838 } |
6741 | 6839 |
6742 if (!TryInlineCall(expr)) { | 6840 if (!TryInlineCall(expr)) { |
6743 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6841 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
6744 HCallConstantFunction* call = | 6842 HInstruction* call = |
6745 New<HCallConstantFunction>(expr->target(), argument_count); | 6843 BuildCallConstantFunction(expr->target(), |
Toon Verwaest
2014/01/14 15:33:50
4-space indent.
Jarin
2014/01/14 19:08:08
Done.
| |
6746 PreProcessCall(call); | 6844 argument_count, |
6845 CALL_AS_METHOD); | |
6846 PushArgumentsFromEnvironment(argument_count); | |
6747 AddInstruction(call); | 6847 AddInstruction(call); |
6748 if (!ast_context()->IsEffect()) Push(call); | 6848 if (!ast_context()->IsEffect()) Push(call); |
6749 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); | 6849 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
6750 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 6850 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
6751 } | 6851 } |
6752 | 6852 |
6753 return true; | 6853 return true; |
6754 } | 6854 } |
6755 | 6855 |
6756 | 6856 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6850 caller->shared()->DebugName()->ToCString(); | 6950 caller->shared()->DebugName()->ToCString(); |
6851 PrintF("Trying to inline the polymorphic call to %s from %s\n", | 6951 PrintF("Trying to inline the polymorphic call to %s from %s\n", |
6852 name->ToCString().get(), | 6952 name->ToCString().get(), |
6853 caller_name.get()); | 6953 caller_name.get()); |
6854 } | 6954 } |
6855 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { | 6955 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { |
6856 // Trying to inline will signal that we should bailout from the | 6956 // Trying to inline will signal that we should bailout from the |
6857 // entire compilation by setting stack overflow on the visitor. | 6957 // entire compilation by setting stack overflow on the visitor. |
6858 if (HasStackOverflow()) return; | 6958 if (HasStackOverflow()) return; |
6859 } else { | 6959 } else { |
6860 HCallConstantFunction* call = | 6960 HInstruction* call = |
6861 New<HCallConstantFunction>(expr->target(), argument_count); | 6961 BuildCallConstantFunction(expr->target(), |
Toon Verwaest
2014/01/14 15:33:50
4-space indent.
Jarin
2014/01/14 19:08:08
Done.
| |
6862 PreProcessCall(call); | 6962 argument_count, |
6963 CALL_AS_METHOD); | |
6964 PushArgumentsFromEnvironment(argument_count); | |
6863 AddInstruction(call); | 6965 AddInstruction(call); |
6864 if (!ast_context()->IsEffect()) Push(call); | 6966 if (!ast_context()->IsEffect()) Push(call); |
6865 } | 6967 } |
6866 | 6968 |
6867 if (current_block() != NULL) Goto(join); | 6969 if (current_block() != NULL) Goto(join); |
6868 set_current_block(if_false); | 6970 set_current_block(if_false); |
6869 } | 6971 } |
6870 | 6972 |
6871 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6973 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
6872 // know about and do not want to handle ones we've never seen. Otherwise | 6974 // know about and do not want to handle ones we've never seen. Otherwise |
6873 // use a generic IC. | 6975 // use a generic IC. |
6874 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { | 6976 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) { |
6875 // Because the deopt may be the only path in the polymorphic call, make sure | 6977 // Because the deopt may be the only path in the polymorphic call, make sure |
6876 // that the environment stack matches the depth on deopt that it otherwise | 6978 // that the environment stack matches the depth on deopt that it otherwise |
6877 // would have had after a successful call. | 6979 // would have had after a successful call. |
6878 Drop(argument_count); | 6980 Drop(argument_count); |
6879 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 6981 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
6880 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); | 6982 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); |
6881 } else { | 6983 } else { |
6882 HCallNamed* call = New<HCallNamed>(name, argument_count); | 6984 HInstruction* call = NewCallNamed(name, argument_count); |
6883 PreProcessCall(call); | 6985 PushArgumentsFromEnvironment(argument_count); |
6884 | 6986 |
6885 if (join != NULL) { | 6987 if (join != NULL) { |
6886 AddInstruction(call); | 6988 AddInstruction(call); |
6887 if (!ast_context()->IsEffect()) Push(call); | 6989 if (!ast_context()->IsEffect()) Push(call); |
6888 Goto(join); | 6990 Goto(join); |
6889 } else { | 6991 } else { |
6890 return ast_context()->ReturnInstruction(call, expr->id()); | 6992 return ast_context()->ReturnInstruction(call, expr->id()); |
6891 } | 6993 } |
6892 } | 6994 } |
6893 | 6995 |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7591 ElementsKind kind = expr->KeyedArrayCallIsHoley() | 7693 ElementsKind kind = expr->KeyedArrayCallIsHoley() |
7592 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | 7694 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; |
7593 | 7695 |
7594 Handle<Map> map(isolate()->get_initial_js_array_map(kind)); | 7696 Handle<Map> map(isolate()->get_initial_js_array_map(kind)); |
7595 | 7697 |
7596 HValue* function = BuildMonomorphicElementAccess( | 7698 HValue* function = BuildMonomorphicElementAccess( |
7597 receiver, key, NULL, NULL, map, false, STANDARD_STORE); | 7699 receiver, key, NULL, NULL, map, false, STANDARD_STORE); |
7598 | 7700 |
7599 call = New<HCallFunction>(function, argument_count); | 7701 call = New<HCallFunction>(function, argument_count); |
7600 } else { | 7702 } else { |
7601 call = New<HCallKeyed>(key, argument_count); | 7703 call = NewCallKeyed(key, argument_count); |
7602 } | 7704 } |
7603 Drop(argument_count + 1); // 1 is the key. | 7705 Drop(argument_count + 1); // 1 is the key. |
7604 return ast_context()->ReturnInstruction(call, expr->id()); | 7706 return ast_context()->ReturnInstruction(call, expr->id()); |
7605 } | 7707 } |
7606 | 7708 |
7607 // Named function call. | 7709 // Named function call. |
7608 if (TryCallApply(expr)) return; | 7710 if (TryCallApply(expr)) return; |
7609 | 7711 |
7610 CHECK_ALIVE(VisitForValue(prop->obj())); | 7712 CHECK_ALIVE(VisitForValue(prop->obj())); |
7611 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7713 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
(...skipping 18 matching lines...) Expand all Loading... | |
7630 PrintF("\n"); | 7732 PrintF("\n"); |
7631 } | 7733 } |
7632 return; | 7734 return; |
7633 } | 7735 } |
7634 | 7736 |
7635 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || | 7737 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || |
7636 expr->check_type() != RECEIVER_MAP_CHECK) { | 7738 expr->check_type() != RECEIVER_MAP_CHECK) { |
7637 // When the target has a custom call IC generator, use the IC, | 7739 // When the target has a custom call IC generator, use the IC, |
7638 // because it is likely to generate better code. Also use the IC | 7740 // because it is likely to generate better code. Also use the IC |
7639 // when a primitive receiver check is required. | 7741 // when a primitive receiver check is required. |
7640 call = PreProcessCall(New<HCallNamed>(name, argument_count)); | 7742 call = NewCallNamed(name, argument_count); |
7743 PushArgumentsFromEnvironment(argument_count); | |
7641 } else { | 7744 } else { |
7642 AddCheckConstantFunction(expr->holder(), receiver, map); | 7745 AddCheckConstantFunction(expr->holder(), receiver, map); |
7643 | 7746 |
7644 if (TryInlineCall(expr)) return; | 7747 if (TryInlineCall(expr)) return; |
7645 call = PreProcessCall( | 7748 call = BuildCallConstantFunction(expr->target(), |
7646 New<HCallConstantFunction>(expr->target(), argument_count)); | 7749 argument_count, |
7750 CALL_AS_METHOD); | |
7751 PushArgumentsFromEnvironment(argument_count); | |
7647 } | 7752 } |
7648 } else if (types != NULL && types->length() > 1) { | 7753 } else if (types != NULL && types->length() > 1) { |
7649 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 7754 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
7650 HandlePolymorphicCallNamed(expr, receiver, types, name); | 7755 HandlePolymorphicCallNamed(expr, receiver, types, name); |
7651 return; | 7756 return; |
7652 | 7757 |
7653 } else { | 7758 } else { |
7654 call = PreProcessCall(New<HCallNamed>(name, argument_count)); | 7759 call = NewCallNamed(name, argument_count); |
7760 PushArgumentsFromEnvironment(argument_count); | |
7655 } | 7761 } |
7656 } else { | 7762 } else { |
7657 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 7763 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
7658 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { | 7764 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { |
7659 return Bailout(kPossibleDirectCallToEval); | 7765 return Bailout(kPossibleDirectCallToEval); |
7660 } | 7766 } |
7661 | 7767 |
7662 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 7768 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
7663 if (global_call) { | 7769 if (global_call) { |
7664 Variable* var = proxy->var(); | 7770 Variable* var = proxy->var(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7702 } | 7808 } |
7703 if (TryInlineCall(expr)) return; | 7809 if (TryInlineCall(expr)) return; |
7704 | 7810 |
7705 if (expr->target().is_identical_to(current_info()->closure())) { | 7811 if (expr->target().is_identical_to(current_info()->closure())) { |
7706 graph()->MarkRecursive(); | 7812 graph()->MarkRecursive(); |
7707 } | 7813 } |
7708 | 7814 |
7709 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7815 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
7710 // When the target has a custom call IC generator, use the IC, | 7816 // When the target has a custom call IC generator, use the IC, |
7711 // because it is likely to generate better code. | 7817 // because it is likely to generate better code. |
7712 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); | 7818 call = NewCallNamed(var->name(), argument_count); |
7819 PushArgumentsFromEnvironment(argument_count); | |
7713 } else { | 7820 } else { |
7714 call = PreProcessCall(New<HCallKnownGlobal>( | 7821 call = BuildCallConstantFunction(expr->target(), |
7715 expr->target(), argument_count)); | 7822 argument_count, CALL_AS_FUNCTION); |
7823 PushArgumentsFromEnvironment(argument_count); | |
7716 } | 7824 } |
7717 } else { | 7825 } else { |
7718 HGlobalObject* receiver = Add<HGlobalObject>(); | 7826 HGlobalObject* receiver = Add<HGlobalObject>(); |
7719 Push(Add<HPushArgument>(receiver)); | 7827 Push(Add<HPushArgument>(receiver)); |
7720 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7828 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
7721 | 7829 |
7722 call = New<HCallGlobal>(var->name(), argument_count); | 7830 call = New<HCallGlobal>(var->name(), argument_count); |
7723 Drop(argument_count); | 7831 Drop(argument_count); |
7724 } | 7832 } |
7725 | 7833 |
(...skipping 3066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10792 if (ShouldProduceTraceOutput()) { | 10900 if (ShouldProduceTraceOutput()) { |
10793 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10901 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10794 } | 10902 } |
10795 | 10903 |
10796 #ifdef DEBUG | 10904 #ifdef DEBUG |
10797 graph_->Verify(false); // No full verify. | 10905 graph_->Verify(false); // No full verify. |
10798 #endif | 10906 #endif |
10799 } | 10907 } |
10800 | 10908 |
10801 } } // namespace v8::internal | 10909 } } // namespace v8::internal |
OLD | NEW |