Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(446)

Side by Side Diff: src/hydrogen.cc

Issue 132623005: A64: Synchronize with r18642. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3901 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 3912 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand());
3913 } else { 3913 } else {
3914 instruction->ReplaceAllUsesWith(instruction->ActualValue()); 3914 instruction->ReplaceAllUsesWith(instruction->ActualValue());
3915 } 3915 }
3916 } 3916 }
3917 } 3917 }
3918 } 3918 }
3919 } 3919 }
3920 3920
3921 3921
3922 template <class Instruction> 3922 void HOptimizedGraphBuilder::PushArgumentsFromEnvironment(int count) {
3923 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
3924 int count = call->argument_count();
3925 ZoneList<HValue*> arguments(count, zone()); 3923 ZoneList<HValue*> arguments(count, zone());
3926 for (int i = 0; i < count; ++i) { 3924 for (int i = 0; i < count; ++i) {
3927 arguments.Add(Pop(), zone()); 3925 arguments.Add(Pop(), zone());
3928 } 3926 }
3929 3927
3930 while (!arguments.is_empty()) { 3928 while (!arguments.is_empty()) {
3931 Add<HPushArgument>(arguments.RemoveLast()); 3929 Add<HPushArgument>(arguments.RemoveLast());
3932 } 3930 }
3931 }
3932
3933
3934 template <class Instruction>
3935 HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
3936 PushArgumentsFromEnvironment(call->argument_count());
3933 return call; 3937 return call;
3934 } 3938 }
3935 3939
3936 3940
3937 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 3941 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
3938 // First special is HContext. 3942 // First special is HContext.
3939 HInstruction* context = Add<HContext>(); 3943 HInstruction* context = Add<HContext>();
3940 environment()->BindContext(context); 3944 environment()->BindContext(context);
3941 3945
3942 // Create an arguments object containing the initial parameters. Set the 3946 // Create an arguments object containing the initial parameters. Set the
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after
5494 } 5498 }
5495 5499
5496 if (info->lookup()->IsPropertyCallbacks()) { 5500 if (info->lookup()->IsPropertyCallbacks()) {
5497 Push(checked_object); 5501 Push(checked_object);
5498 if (FLAG_inline_accessors && 5502 if (FLAG_inline_accessors &&
5499 can_inline_accessor && 5503 can_inline_accessor &&
5500 TryInlineGetter(info->accessor(), ast_id, return_id)) { 5504 TryInlineGetter(info->accessor(), ast_id, return_id)) {
5501 return NULL; 5505 return NULL;
5502 } 5506 }
5503 Add<HPushArgument>(Pop()); 5507 Add<HPushArgument>(Pop());
5504 return New<HCallConstantFunction>(info->accessor(), 1); 5508 return BuildCallConstantFunction(info->accessor(), 1);
5505 } 5509 }
5506 5510
5507 ASSERT(info->lookup()->IsConstant()); 5511 ASSERT(info->lookup()->IsConstant());
5508 return New<HConstant>(info->constant()); 5512 return New<HConstant>(info->constant());
5509 } 5513 }
5510 5514
5511 5515
5512 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 5516 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
5513 BailoutId ast_id, 5517 BailoutId ast_id,
5514 BailoutId return_id, 5518 BailoutId return_id,
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
5779 Handle<JSObject> holder; 5783 Handle<JSObject> holder;
5780 if (LookupSetter(map, name, &setter, &holder)) { 5784 if (LookupSetter(map, name, &setter, &holder)) {
5781 AddCheckConstantFunction(holder, object, map); 5785 AddCheckConstantFunction(holder, object, map);
5782 if (FLAG_inline_accessors && 5786 if (FLAG_inline_accessors &&
5783 TryInlineSetter(setter, ast_id, return_id, value)) { 5787 TryInlineSetter(setter, ast_id, return_id, value)) {
5784 return; 5788 return;
5785 } 5789 }
5786 Drop(2); 5790 Drop(2);
5787 Add<HPushArgument>(object); 5791 Add<HPushArgument>(object);
5788 Add<HPushArgument>(value); 5792 Add<HPushArgument>(value);
5789 instr = New<HCallConstantFunction>(setter, 2); 5793 instr = BuildCallConstantFunction(setter, 2);
5790 } else { 5794 } else {
5791 Drop(2); 5795 Drop(2);
5792 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 5796 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5793 name, 5797 name,
5794 value, 5798 value,
5795 map)); 5799 map));
5796 } 5800 }
5797 } else if (types != NULL && types->length() > 1) { 5801 } else if (types != NULL && types->length() > 1) {
5798 Drop(2); 5802 Drop(2);
5799 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name); 5803 return HandlePolymorphicStoreNamedField(ast_id, object, value, types, name);
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
6741 HValue* receiver, 6745 HValue* receiver,
6742 Handle<Map> receiver_map) { 6746 Handle<Map> receiver_map) {
6743 // Constant functions have the nice property that the map will change if they 6747 // Constant functions have the nice property that the map will change if they
6744 // are overwritten. Therefore it is enough to check the map of the holder and 6748 // are overwritten. Therefore it is enough to check the map of the holder and
6745 // its prototypes. 6749 // its prototypes.
6746 AddCheckMap(receiver, receiver_map); 6750 AddCheckMap(receiver, receiver_map);
6747 AddCheckPrototypeMaps(holder, receiver_map); 6751 AddCheckPrototypeMaps(holder, receiver_map);
6748 } 6752 }
6749 6753
6750 6754
6755 HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(
6756 HValue* fun, int argument_count, bool pass_argument_count) {
6757 return New<HCallJSFunction>(
6758 fun, argument_count, pass_argument_count);
6759 }
6760
6761
6762 HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
6763 HValue* fun, HValue* context,
6764 int argument_count, HValue* expected_param_count) {
6765 CallInterfaceDescriptor* descriptor =
6766 isolate()->call_descriptor(Isolate::ArgumentAdaptorCall);
6767
6768 HValue* arity = Add<HConstant>(argument_count - 1);
6769
6770 HValue* op_vals[] = { fun, context, arity, expected_param_count };
6771
6772 Handle<Code> adaptor =
6773 isolate()->builtins()->ArgumentsAdaptorTrampoline();
6774 HConstant* adaptor_value = Add<HConstant>(adaptor);
6775
6776 return New<HCallWithDescriptor>(
6777 adaptor_value, argument_count, descriptor,
6778 Vector<HValue*>(op_vals, descriptor->environment_length()));
6779 }
6780
6781
6782 HInstruction* HOptimizedGraphBuilder::BuildCallConstantFunction(
6783 Handle<JSFunction> jsfun, int argument_count) {
6784 HValue* target = Add<HConstant>(jsfun);
6785 // For constant functions, we try to avoid calling the
6786 // argument adaptor and instead call the function directly
6787 int formal_parameter_count = jsfun->shared()->formal_parameter_count();
6788 bool dont_adapt_arguments =
6789 (formal_parameter_count ==
6790 SharedFunctionInfo::kDontAdaptArgumentsSentinel);
6791 int arity = argument_count - 1;
6792 bool can_invoke_directly =
6793 dont_adapt_arguments || formal_parameter_count == arity;
6794 if (can_invoke_directly) {
6795 return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments);
6796 } else {
6797 HValue* param_count_value = Add<HConstant>(formal_parameter_count);
6798 HValue* context = Add<HLoadNamedField>(target,
6799 HObjectAccess::ForFunctionContextPointer());
6800 return NewArgumentAdaptorCall(target, context,
6801 argument_count, param_count_value);
6802 }
6803 UNREACHABLE();
6804 return NULL;
6805 }
6806
6807
6808 HInstruction* HOptimizedGraphBuilder::NewCallNamed(
6809 Handle<String> name, int argument_count) {
6810 CallInterfaceDescriptor* descriptor =
6811 isolate()->call_descriptor(Isolate::NamedCall);
6812 HValue* op_vals[] = { context(), Add<HConstant>(name) };
6813 int arity = argument_count - 1;
6814 Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize(arity);
6815
6816 return New<HCallWithDescriptor>(
6817 Add<HConstant>(ic), argument_count, descriptor,
6818 Vector<HValue*>(op_vals, descriptor->environment_length()));
6819 }
6820
6821
6822 HInstruction* HOptimizedGraphBuilder::NewCallKeyed(
6823 HValue* key, int argument_count) {
6824 CallInterfaceDescriptor* descriptor =
6825 isolate()->call_descriptor(Isolate::KeyedCall);
6826 HValue* op_vals[] = { context(), key };
6827 int arity = argument_count - 1;
6828 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
6829
6830 return New<HCallWithDescriptor>(
6831 Add<HConstant>(ic), argument_count, descriptor,
6832 Vector<HValue*>(op_vals, descriptor->environment_length()));
6833 }
6834
6751 class FunctionSorter { 6835 class FunctionSorter {
6752 public: 6836 public:
6753 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { } 6837 FunctionSorter() : index_(0), ticks_(0), ast_length_(0), src_length_(0) { }
6754 FunctionSorter(int index, int ticks, int ast_length, int src_length) 6838 FunctionSorter(int index, int ticks, int ast_length, int src_length)
6755 : index_(index), 6839 : index_(index),
6756 ticks_(ticks), 6840 ticks_(ticks),
6757 ast_length_(ast_length), 6841 ast_length_(ast_length),
6758 src_length_(src_length) { } 6842 src_length_(src_length) { }
6759 6843
6760 int index() const { return index_; } 6844 int index() const { return index_; }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6796 if (FLAG_trace_inlining) { 6880 if (FLAG_trace_inlining) {
6797 Handle<JSFunction> caller = current_info()->closure(); 6881 Handle<JSFunction> caller = current_info()->closure();
6798 SmartArrayPointer<char> caller_name = 6882 SmartArrayPointer<char> caller_name =
6799 caller->shared()->DebugName()->ToCString(); 6883 caller->shared()->DebugName()->ToCString();
6800 PrintF("Trying to inline the polymorphic call to %s from %s\n", 6884 PrintF("Trying to inline the polymorphic call to %s from %s\n",
6801 name->ToCString().get(), caller_name.get()); 6885 name->ToCString().get(), caller_name.get());
6802 } 6886 }
6803 6887
6804 if (!TryInlineCall(expr)) { 6888 if (!TryInlineCall(expr)) {
6805 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6889 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6806 HCallConstantFunction* call = 6890 HInstruction* call = BuildCallConstantFunction(
6807 New<HCallConstantFunction>(expr->target(), argument_count); 6891 expr->target(), argument_count);
6808 PreProcessCall(call); 6892 PushArgumentsFromEnvironment(argument_count);
6809 AddInstruction(call); 6893 AddInstruction(call);
6810 if (!ast_context()->IsEffect()) Push(call); 6894 if (!ast_context()->IsEffect()) Push(call);
6811 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); 6895 Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE);
6812 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6896 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6813 } 6897 }
6814 6898
6815 return true; 6899 return true;
6816 } 6900 }
6817 6901
6818 6902
6819 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( 6903 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed(
6820 Call* expr, 6904 Call* expr,
6821 HValue* receiver, 6905 HValue* receiver,
6822 SmallMapList* types, 6906 SmallMapList* types,
6823 Handle<String> name) { 6907 Handle<String> name) {
6824 if (TryCallPolymorphicAsMonomorphic(expr, receiver, types, name)) return; 6908 if (TryCallPolymorphicAsMonomorphic(expr, receiver, types, name)) return;
6825 6909
6826 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 6910 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
6911 HBasicBlock* join = NULL;
6912 FunctionSorter order[kMaxCallPolymorphism];
6913 int ordered_functions = 0;
6827 6914
6828 Handle<Map> initial_string_map( 6915 Handle<Map> initial_string_map(
6829 isolate()->native_context()->string_function()->initial_map()); 6916 isolate()->native_context()->string_function()->initial_map());
6830 Handle<Map> string_marker_map( 6917 Handle<Map> string_marker_map(
6831 JSObject::cast(initial_string_map->prototype())->map()); 6918 JSObject::cast(initial_string_map->prototype())->map());
6832 Handle<Map> initial_number_map( 6919 Handle<Map> initial_number_map(
6833 isolate()->native_context()->number_function()->initial_map()); 6920 isolate()->native_context()->number_function()->initial_map());
6834 Handle<Map> number_marker_map( 6921 Handle<Map> number_marker_map(
6835 JSObject::cast(initial_number_map->prototype())->map()); 6922 JSObject::cast(initial_number_map->prototype())->map());
6836 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map(); 6923 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
6837 6924
6838 bool handle_smi = false; 6925 bool handle_smi = false;
6839 6926
6840 // A map from functions to a set of receivers' maps.
6841 struct FuncMapEntry {
6842 Handle<JSFunction> func;
6843 SmallMapList maps;
6844 };
6845 FuncMapEntry func_map[kMaxCallPolymorphism];
6846 FunctionSorter order[kMaxCallPolymorphism];
6847 int func_count = 0;
6848 int maps_count = 0;
6849
6850 for (int i = 0; 6927 for (int i = 0;
6851 i < types->length() && func_count < kMaxCallPolymorphism; 6928 i < types->length() && ordered_functions < kMaxCallPolymorphism;
6852 ++i) { 6929 ++i) {
6853 Handle<Map> map = types->at(i); 6930 Handle<Map> map = types->at(i);
6854 if (expr->ComputeTarget(map, name)) { 6931 if (expr->ComputeTarget(map, name)) {
6855 if (map.is_identical_to(number_marker_map)) handle_smi = true; 6932 if (map.is_identical_to(number_marker_map)) handle_smi = true;
6856 6933 order[ordered_functions++] =
6857 // Try to find the target function among known targets. 6934 FunctionSorter(i,
6858 int func_index = 0; 6935 expr->target()->shared()->profiler_ticks(),
6859 for (; func_index < func_count; ++func_index) { 6936 InliningAstSize(expr->target()),
6860 if (*func_map[func_index].func == *expr->target()) { 6937 expr->target()->shared()->SourceSize());
6861 break;
6862 }
6863 }
6864 FuncMapEntry* entry = &func_map[func_index];
6865 if (func_index == func_count) {
6866 // Entry not found, "allocate" it.
6867 entry->func = expr->target();
6868 entry->maps.Reserve(types->length() - maps_count, zone());
6869 order[func_index] =
6870 FunctionSorter(func_index,
6871 entry->func->shared()->profiler_ticks(),
6872 InliningAstSize(entry->func),
6873 entry->func->shared()->SourceSize());
6874 ++func_count;
6875 }
6876 entry->maps.Add(map, zone());
6877 ++maps_count;
6878 } 6938 }
6879 } 6939 }
6880 6940
6881 std::sort(order, order + func_count); 6941 std::sort(order, order + ordered_functions);
6882 6942
6883 HBasicBlock* number_block = NULL; 6943 HBasicBlock* number_block = NULL;
6884 HBasicBlock* join = NULL;
6885 6944
6886 if (func_count > 0) { 6945 for (int fn = 0; fn < ordered_functions; ++fn) {
6887 // Only needed once. 6946 int i = order[fn].index();
6888 join = graph()->CreateBasicBlock(); 6947 Handle<Map> map = types->at(i);
6889 if (handle_smi) { 6948 if (fn == 0) {
6890 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock(); 6949 // Only needed once.
6891 HBasicBlock* not_smi_block = graph()->CreateBasicBlock(); 6950 join = graph()->CreateBasicBlock();
6892 number_block = graph()->CreateBasicBlock(); 6951 if (handle_smi) {
6893 FinishCurrentBlock( 6952 HBasicBlock* empty_smi_block = graph()->CreateBasicBlock();
6894 New<HIsSmiAndBranch>(receiver, empty_smi_block, not_smi_block)); 6953 HBasicBlock* not_smi_block = graph()->CreateBasicBlock();
6895 Goto(empty_smi_block, number_block); 6954 number_block = graph()->CreateBasicBlock();
6896 set_current_block(not_smi_block); 6955 FinishCurrentBlock(New<HIsSmiAndBranch>(
6956 receiver, empty_smi_block, not_smi_block));
6957 Goto(empty_smi_block, number_block);
6958 set_current_block(not_smi_block);
6959 } else {
6960 BuildCheckHeapObject(receiver);
6961 }
6962 }
6963 HBasicBlock* if_true = graph()->CreateBasicBlock();
6964 HBasicBlock* if_false = graph()->CreateBasicBlock();
6965 HUnaryControlInstruction* compare;
6966
6967 if (handle_smi && map.is_identical_to(number_marker_map)) {
6968 compare = New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
6969 map = initial_number_map;
6970 expr->set_number_check(
6971 Handle<JSObject>(JSObject::cast(map->prototype())));
6972 } else if (map.is_identical_to(string_marker_map)) {
6973 compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
6974 map = initial_string_map;
6975 expr->set_string_check(
6976 Handle<JSObject>(JSObject::cast(map->prototype())));
6897 } else { 6977 } else {
6898 BuildCheckHeapObject(receiver); 6978 compare = New<HCompareMap>(receiver, map, if_true, if_false);
6899 } 6979 expr->set_map_check();
6900 }
6901
6902 for (int fn = 0; fn < func_count; ++fn) {
6903 int i = order[fn].index();
6904 FuncMapEntry* func_map_entry = &func_map[i];
6905
6906 HBasicBlock* call_block = graph()->CreateBasicBlock();
6907 HBasicBlock* if_false = NULL;
6908
6909 int maps_count = func_map_entry->maps.length();
6910 for (int m = 0; m < maps_count; ++m) {
6911 Handle<Map> map = func_map_entry->maps.at(m);
6912 HBasicBlock* if_true = graph()->CreateBasicBlock();
6913 if_false = graph()->CreateBasicBlock();
6914 HUnaryControlInstruction* compare;
6915
6916 if (handle_smi && map.is_identical_to(number_marker_map)) {
6917 compare =
6918 New<HCompareMap>(receiver, heap_number_map, if_true, if_false);
6919 map = initial_number_map;
6920 expr->set_number_check(
6921 Handle<JSObject>(JSObject::cast(map->prototype())));
6922 } else if (map.is_identical_to(string_marker_map)) {
6923 compare = New<HIsStringAndBranch>(receiver, if_true, if_false);
6924 map = initial_string_map;
6925 expr->set_string_check(
6926 Handle<JSObject>(JSObject::cast(map->prototype())));
6927 } else {
6928 compare = New<HCompareMap>(receiver, map, if_true, if_false);
6929 expr->set_map_check();
6930 }
6931
6932 FinishCurrentBlock(compare);
6933
6934 if (expr->check_type() == NUMBER_CHECK) {
6935 Goto(if_true, number_block);
6936 if_true = number_block;
6937 number_block->SetJoinId(expr->id());
6938 }
6939 set_current_block(if_true);
6940
6941 expr->ComputeTarget(map, name);
6942 ASSERT(*expr->target() == *func_map_entry->func);
6943
6944 AddCheckPrototypeMaps(expr->holder(), map);
6945
6946 Goto(if_true, call_block);
6947
6948 set_current_block(if_false);
6949 } 6980 }
6950 6981
6951 // Generate call once for all corresponding maps. 6982 FinishCurrentBlock(compare);
6952 call_block->SetJoinId(expr->id());
6953 set_current_block(call_block);
6954 6983
6984 if (expr->check_type() == NUMBER_CHECK) {
6985 Goto(if_true, number_block);
6986 if_true = number_block;
6987 number_block->SetJoinId(expr->id());
6988 }
6989 set_current_block(if_true);
6990
6991 expr->ComputeTarget(map, name);
6992 AddCheckPrototypeMaps(expr->holder(), map);
6955 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 6993 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
6956 Handle<JSFunction> caller = current_info()->closure(); 6994 Handle<JSFunction> caller = current_info()->closure();
6957 SmartArrayPointer<char> caller_name = 6995 SmartArrayPointer<char> caller_name =
6958 caller->shared()->DebugName()->ToCString(); 6996 caller->shared()->DebugName()->ToCString();
6959 PrintF("Trying to inline the polymorphic call to %s from %s\n", 6997 PrintF("Trying to inline the polymorphic call to %s from %s\n",
6960 name->ToCString().get(), 6998 name->ToCString().get(),
6961 caller_name.get()); 6999 caller_name.get());
6962 } 7000 }
6963 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) { 7001 if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
6964 // Trying to inline will signal that we should bailout from the 7002 // Trying to inline will signal that we should bailout from the
6965 // entire compilation by setting stack overflow on the visitor. 7003 // entire compilation by setting stack overflow on the visitor.
6966 if (HasStackOverflow()) return; 7004 if (HasStackOverflow()) return;
6967 } else { 7005 } else {
6968 HCallConstantFunction* call = 7006 HInstruction* call = BuildCallConstantFunction(
6969 New<HCallConstantFunction>(expr->target(), argument_count); 7007 expr->target(), argument_count);
6970 PreProcessCall(call); 7008 PushArgumentsFromEnvironment(argument_count);
6971 AddInstruction(call); 7009 AddInstruction(call);
6972 if (!ast_context()->IsEffect()) Push(call); 7010 if (!ast_context()->IsEffect()) Push(call);
6973 } 7011 }
7012
6974 if (current_block() != NULL) Goto(join); 7013 if (current_block() != NULL) Goto(join);
6975
6976 set_current_block(if_false); 7014 set_current_block(if_false);
6977 } 7015 }
6978 7016
6979 // Finish up. Unconditionally deoptimize if we've handled all the maps we 7017 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6980 // know about and do not want to handle ones we've never seen. Otherwise 7018 // know about and do not want to handle ones we've never seen. Otherwise
6981 // use a generic IC. 7019 // use a generic IC.
6982 if (maps_count == types->length() && FLAG_deoptimize_uncommon_cases) { 7020 if (ordered_functions == types->length() && FLAG_deoptimize_uncommon_cases) {
6983 // Because the deopt may be the only path in the polymorphic call, make sure 7021 // Because the deopt may be the only path in the polymorphic call, make sure
6984 // that the environment stack matches the depth on deopt that it otherwise 7022 // that the environment stack matches the depth on deopt that it otherwise
6985 // would have had after a successful call. 7023 // would have had after a successful call.
6986 Drop(argument_count); 7024 Drop(argument_count);
6987 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); 7025 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0());
6988 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join); 7026 FinishExitWithHardDeoptimization("Unknown map in polymorphic call", join);
6989 } else { 7027 } else {
6990 HCallNamed* call = New<HCallNamed>(name, argument_count); 7028 HInstruction* call = NewCallNamed(name, argument_count);
6991 PreProcessCall(call); 7029 PushArgumentsFromEnvironment(argument_count);
6992 7030
6993 if (join != NULL) { 7031 if (join != NULL) {
6994 AddInstruction(call); 7032 AddInstruction(call);
6995 if (!ast_context()->IsEffect()) Push(call); 7033 if (!ast_context()->IsEffect()) Push(call);
6996 Goto(join); 7034 Goto(join);
6997 } else { 7035 } else {
6998 return ast_context()->ReturnInstruction(call, expr->id()); 7036 return ast_context()->ReturnInstruction(call, expr->id());
6999 } 7037 }
7000 } 7038 }
7001 7039
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
7064 if (target_shared->dont_inline() || target_shared->dont_optimize()) { 7102 if (target_shared->dont_inline() || target_shared->dont_optimize()) {
7065 TraceInline(target, caller, "target contains unsupported syntax [early]"); 7103 TraceInline(target, caller, "target contains unsupported syntax [early]");
7066 return kNotInlinable; 7104 return kNotInlinable;
7067 } 7105 }
7068 7106
7069 int nodes_added = target_shared->ast_node_count(); 7107 int nodes_added = target_shared->ast_node_count();
7070 return nodes_added; 7108 return nodes_added;
7071 } 7109 }
7072 7110
7073 7111
7074 bool HOptimizedGraphBuilder::TryInline(CallKind call_kind, 7112 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
7075 Handle<JSFunction> target,
7076 int arguments_count, 7113 int arguments_count,
7077 HValue* implicit_return_value, 7114 HValue* implicit_return_value,
7078 BailoutId ast_id, 7115 BailoutId ast_id,
7079 BailoutId return_id, 7116 BailoutId return_id,
7080 InliningKind inlining_kind) { 7117 InliningKind inlining_kind) {
7081 int nodes_added = InliningAstSize(target); 7118 int nodes_added = InliningAstSize(target);
7082 if (nodes_added == kNotInlinable) return false; 7119 if (nodes_added == kNotInlinable) return false;
7083 7120
7084 Handle<JSFunction> caller = current_info()->closure(); 7121 Handle<JSFunction> caller = current_info()->closure();
7085 7122
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
7365 set_current_block(function_return()); 7402 set_current_block(function_return());
7366 } else { 7403 } else {
7367 set_current_block(NULL); 7404 set_current_block(NULL);
7368 } 7405 }
7369 delete target_state; 7406 delete target_state;
7370 return true; 7407 return true;
7371 } 7408 }
7372 7409
7373 7410
7374 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { 7411 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) {
7375 // The function call we are inlining is a method call if the call 7412 return TryInline(expr->target(),
7376 // is a property call.
7377 CallKind call_kind = (expr->expression()->AsProperty() == NULL)
7378 ? CALL_AS_FUNCTION
7379 : CALL_AS_METHOD;
7380
7381 return TryInline(call_kind,
7382 expr->target(),
7383 expr->arguments()->length(), 7413 expr->arguments()->length(),
7384 NULL, 7414 NULL,
7385 expr->id(), 7415 expr->id(),
7386 expr->ReturnId(), 7416 expr->ReturnId(),
7387 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN); 7417 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN);
7388 } 7418 }
7389 7419
7390 7420
7391 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 7421 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
7392 HValue* implicit_return_value) { 7422 HValue* implicit_return_value) {
7393 return TryInline(CALL_AS_FUNCTION, 7423 return TryInline(expr->target(),
7394 expr->target(),
7395 expr->arguments()->length(), 7424 expr->arguments()->length(),
7396 implicit_return_value, 7425 implicit_return_value,
7397 expr->id(), 7426 expr->id(),
7398 expr->ReturnId(), 7427 expr->ReturnId(),
7399 CONSTRUCT_CALL_RETURN); 7428 CONSTRUCT_CALL_RETURN);
7400 } 7429 }
7401 7430
7402 7431
7403 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 7432 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
7404 BailoutId ast_id, 7433 BailoutId ast_id,
7405 BailoutId return_id) { 7434 BailoutId return_id) {
7406 return TryInline(CALL_AS_METHOD, 7435 return TryInline(getter,
7407 getter,
7408 0, 7436 0,
7409 NULL, 7437 NULL,
7410 ast_id, 7438 ast_id,
7411 return_id, 7439 return_id,
7412 GETTER_CALL_RETURN); 7440 GETTER_CALL_RETURN);
7413 } 7441 }
7414 7442
7415 7443
7416 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 7444 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
7417 BailoutId id, 7445 BailoutId id,
7418 BailoutId assignment_id, 7446 BailoutId assignment_id,
7419 HValue* implicit_return_value) { 7447 HValue* implicit_return_value) {
7420 return TryInline(CALL_AS_METHOD, 7448 return TryInline(setter,
7421 setter,
7422 1, 7449 1,
7423 implicit_return_value, 7450 implicit_return_value,
7424 id, assignment_id, 7451 id, assignment_id,
7425 SETTER_CALL_RETURN); 7452 SETTER_CALL_RETURN);
7426 } 7453 }
7427 7454
7428 7455
7429 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 7456 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
7430 Call* expr, 7457 Call* expr,
7431 int arguments_count) { 7458 int arguments_count) {
7432 return TryInline(CALL_AS_METHOD, 7459 return TryInline(function,
7433 function,
7434 arguments_count, 7460 arguments_count,
7435 NULL, 7461 NULL,
7436 expr->id(), 7462 expr->id(),
7437 expr->ReturnId(), 7463 expr->ReturnId(),
7438 NORMAL_RETURN); 7464 NORMAL_RETURN);
7439 } 7465 }
7440 7466
7441 7467
7442 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, 7468 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr,
7443 bool drop_extra) { 7469 bool drop_extra) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
7734 ElementsKind kind = expr->KeyedArrayCallIsHoley() 7760 ElementsKind kind = expr->KeyedArrayCallIsHoley()
7735 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; 7761 ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
7736 7762
7737 Handle<Map> map(isolate()->get_initial_js_array_map(kind)); 7763 Handle<Map> map(isolate()->get_initial_js_array_map(kind));
7738 7764
7739 HValue* function = BuildMonomorphicElementAccess( 7765 HValue* function = BuildMonomorphicElementAccess(
7740 receiver, key, NULL, NULL, map, false, STANDARD_STORE); 7766 receiver, key, NULL, NULL, map, false, STANDARD_STORE);
7741 7767
7742 call = New<HCallFunction>(function, argument_count); 7768 call = New<HCallFunction>(function, argument_count);
7743 } else { 7769 } else {
7744 call = New<HCallKeyed>(key, argument_count); 7770 call = NewCallKeyed(key, argument_count);
7745 } 7771 }
7746 Drop(argument_count + 1); // 1 is the key. 7772 Drop(argument_count + 1); // 1 is the key.
7747 return ast_context()->ReturnInstruction(call, expr->id()); 7773 return ast_context()->ReturnInstruction(call, expr->id());
7748 } 7774 }
7749 7775
7750 // Named function call. 7776 // Named function call.
7751 if (TryCallApply(expr)) return; 7777 if (TryCallApply(expr)) return;
7752 7778
7753 CHECK_ALIVE(VisitForValue(prop->obj())); 7779 CHECK_ALIVE(VisitForValue(prop->obj()));
7754 CHECK_ALIVE(VisitExpressions(expr->arguments())); 7780 CHECK_ALIVE(VisitExpressions(expr->arguments()));
(...skipping 18 matching lines...) Expand all
7773 PrintF("\n"); 7799 PrintF("\n");
7774 } 7800 }
7775 return; 7801 return;
7776 } 7802 }
7777 7803
7778 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) || 7804 if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
7779 expr->check_type() != RECEIVER_MAP_CHECK) { 7805 expr->check_type() != RECEIVER_MAP_CHECK) {
7780 // When the target has a custom call IC generator, use the IC, 7806 // When the target has a custom call IC generator, use the IC,
7781 // because it is likely to generate better code. Also use the IC 7807 // because it is likely to generate better code. Also use the IC
7782 // when a primitive receiver check is required. 7808 // when a primitive receiver check is required.
7783 call = PreProcessCall(New<HCallNamed>(name, argument_count)); 7809 call = NewCallNamed(name, argument_count);
7810 PushArgumentsFromEnvironment(argument_count);
7784 } else { 7811 } else {
7785 AddCheckConstantFunction(expr->holder(), receiver, map); 7812 AddCheckConstantFunction(expr->holder(), receiver, map);
7786 7813
7787 if (TryInlineCall(expr)) return; 7814 if (TryInlineCall(expr)) return;
7788 call = PreProcessCall( 7815 call = BuildCallConstantFunction(expr->target(), argument_count);
7789 New<HCallConstantFunction>(expr->target(), argument_count)); 7816 PushArgumentsFromEnvironment(argument_count);
7790 } 7817 }
7791 } else if (types != NULL && types->length() > 1) { 7818 } else if (types != NULL && types->length() > 1) {
7792 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 7819 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
7793 HandlePolymorphicCallNamed(expr, receiver, types, name); 7820 HandlePolymorphicCallNamed(expr, receiver, types, name);
7794 return; 7821 return;
7795 7822
7796 } else { 7823 } else {
7797 call = PreProcessCall(New<HCallNamed>(name, argument_count)); 7824 call = NewCallNamed(name, argument_count);
7825 PushArgumentsFromEnvironment(argument_count);
7798 } 7826 }
7799 } else { 7827 } else {
7800 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 7828 VariableProxy* proxy = expr->expression()->AsVariableProxy();
7801 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 7829 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
7802 return Bailout(kPossibleDirectCallToEval); 7830 return Bailout(kPossibleDirectCallToEval);
7803 } 7831 }
7804 7832
7805 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 7833 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
7806 if (global_call) { 7834 if (global_call) {
7807 Variable* var = proxy->var(); 7835 Variable* var = proxy->var();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
7848 } 7876 }
7849 7877
7850 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { 7878 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
7851 // We're about to install a contextual IC, which expects the global 7879 // We're about to install a contextual IC, which expects the global
7852 // object as receiver rather than the global proxy. 7880 // object as receiver rather than the global proxy.
7853 HGlobalObject* global_object = Add<HGlobalObject>(); 7881 HGlobalObject* global_object = Add<HGlobalObject>();
7854 const int receiver_index = argument_count - 1; 7882 const int receiver_index = argument_count - 1;
7855 environment()->SetExpressionStackAt(receiver_index, global_object); 7883 environment()->SetExpressionStackAt(receiver_index, global_object);
7856 // When the target has a custom call IC generator, use the IC, 7884 // When the target has a custom call IC generator, use the IC,
7857 // because it is likely to generate better code. 7885 // because it is likely to generate better code.
7858 call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count)); 7886 call = NewCallNamed(var->name(), argument_count);
7887 PushArgumentsFromEnvironment(argument_count);
7859 } else { 7888 } else {
7860 call = PreProcessCall(New<HCallKnownGlobal>( 7889 call = BuildCallConstantFunction(expr->target(), argument_count);
7861 expr->target(), argument_count)); 7890 PushArgumentsFromEnvironment(argument_count);
7862 } 7891 }
7863 } else { 7892 } else {
7864 HGlobalObject* receiver = Add<HGlobalObject>(); 7893 HGlobalObject* receiver = Add<HGlobalObject>();
7865 Push(Add<HPushArgument>(receiver)); 7894 Push(Add<HPushArgument>(receiver));
7866 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 7895 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
7867 7896
7868 call = New<HCallGlobal>(var->name(), argument_count); 7897 call = NewCallNamed(var->name(), argument_count);
7869 Drop(argument_count); 7898 Drop(argument_count);
7870 } 7899 }
7871 7900
7872 } else if (expr->IsMonomorphic()) { 7901 } else if (expr->IsMonomorphic()) {
7873 // The function is on the stack in the unoptimized code during 7902 // The function is on the stack in the unoptimized code during
7874 // evaluation of the arguments. 7903 // evaluation of the arguments.
7875 CHECK_ALIVE(VisitForValue(expr->expression())); 7904 CHECK_ALIVE(VisitForValue(expr->expression()));
7876 HValue* function = Top(); 7905 HValue* function = Top();
7877 7906
7878 Add<HCheckValue>(function, expr->target()); 7907 Add<HCheckValue>(function, expr->target());
(...skipping 3106 matching lines...) Expand 10 before | Expand all | Expand 10 after
10985 if (ShouldProduceTraceOutput()) { 11014 if (ShouldProduceTraceOutput()) {
10986 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11015 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10987 } 11016 }
10988 11017
10989 #ifdef DEBUG 11018 #ifdef DEBUG
10990 graph_->Verify(false); // No full verify. 11019 graph_->Verify(false); // No full verify.
10991 #endif 11020 #endif
10992 } 11021 }
10993 11022
10994 } } // namespace v8::internal 11023 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698