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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 11818021: Allocation Info Tracking, continued. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: A partial delta against Toon's previous review Created 7 years, 9 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/ia32/builtins-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 descriptor->deoptimization_handler_ = 53 descriptor->deoptimization_handler_ =
54 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry; 54 Runtime::FunctionForId(Runtime::kCreateObjectLiteralShallow)->entry;
55 } 55 }
56 56
57 57
58 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( 58 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
59 Isolate* isolate, 59 Isolate* isolate,
60 CodeStubInterfaceDescriptor* descriptor) { 60 CodeStubInterfaceDescriptor* descriptor) {
61 static Register registers[] = { edx, ecx }; 61 static Register registers[] = { edx, ecx };
62 descriptor->register_param_count_ = 2; 62 descriptor->register_param_count_ = 2;
63 descriptor->register_params_ = registers;
63 descriptor->stack_parameter_count_ = NULL; 64 descriptor->stack_parameter_count_ = NULL;
64 descriptor->register_params_ = registers;
65 descriptor->deoptimization_handler_ = 65 descriptor->deoptimization_handler_ =
66 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure); 66 FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure);
67 } 67 }
68 68
69 69
70 void TransitionElementsKindStub::InitializeInterfaceDescriptor( 70 void TransitionElementsKindStub::InitializeInterfaceDescriptor(
71 Isolate* isolate, 71 Isolate* isolate,
72 CodeStubInterfaceDescriptor* descriptor) { 72 CodeStubInterfaceDescriptor* descriptor) {
73 static Register registers[] = { eax, ebx }; 73 static Register registers[] = { eax, ebx };
74 descriptor->register_param_count_ = 2; 74 descriptor->register_param_count_ = 2;
75 descriptor->register_params_ = registers; 75 descriptor->register_params_ = registers;
76 descriptor->deoptimization_handler_ = 76 descriptor->deoptimization_handler_ =
77 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; 77 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
78 } 78 }
79 79
80 80
81 static void InitializeArrayConstructorDescriptor(Isolate* isolate, 81 static void InitializeArrayConstructorDescriptor(Isolate* isolate,
82 CodeStubInterfaceDescriptor* descriptor) { 82 CodeStubInterfaceDescriptor* descriptor) {
83 // register state
84 // edi -- constructor function
85 // ebx -- type info cell with elements kind
86 // eax -- number of arguments to the constructor function
83 static Register registers[] = { edi, ebx }; 87 static Register registers[] = { edi, ebx };
84 descriptor->register_param_count_ = 2; 88 descriptor->register_param_count_ = 2;
85 // stack param count needs (constructor pointer, and single argument) 89 // stack param count needs (constructor pointer, and single argument)
86 descriptor->stack_parameter_count_ = &eax; 90 descriptor->stack_parameter_count_ = &eax;
87 descriptor->register_params_ = registers; 91 descriptor->register_params_ = registers;
88 descriptor->extra_expression_stack_count_ = 1; 92 descriptor->extra_expression_stack_count_ = 1;
89 descriptor->deoptimization_handler_ = 93 descriptor->deoptimization_handler_ =
90 FUNCTION_ADDR(ArrayConstructor_StubFailure); 94 FUNCTION_ADDR(ArrayConstructor_StubFailure);
91 } 95 }
92 96
(...skipping 4723 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 void StackCheckStub::Generate(MacroAssembler* masm) { 4820 void StackCheckStub::Generate(MacroAssembler* masm) {
4817 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); 4821 __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
4818 } 4822 }
4819 4823
4820 4824
4821 void InterruptStub::Generate(MacroAssembler* masm) { 4825 void InterruptStub::Generate(MacroAssembler* masm) {
4822 __ TailCallRuntime(Runtime::kInterrupt, 0, 1); 4826 __ TailCallRuntime(Runtime::kInterrupt, 0, 1);
4823 } 4827 }
4824 4828
4825 4829
4830 static void GenerateRecordCallTargetNoArray(MacroAssembler* masm) {
4831 // Cache the called function in a global property cell. Cache states
4832 // are uninitialized, monomorphic (indicated by a JSFunction), and
4833 // megamorphic.
4834 // ebx : cache cell for call target
4835 // edi : the function to call
4836 ASSERT(!FLAG_optimize_constructed_arrays);
4837 Isolate* isolate = masm->isolate();
4838 Label initialize, done;
4839
4840 // Load the cache state into ecx.
4841 __ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
4842
4843 // A monomorphic cache hit or an already megamorphic state: invoke the
4844 // function without changing the state.
4845 __ cmp(ecx, edi);
4846 __ j(equal, &done, Label::kNear);
4847 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4848 __ j(equal, &done, Label::kNear);
4849
4850 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
4851 // megamorphic.
4852 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate)));
4853 __ j(equal, &initialize, Label::kNear);
4854 // MegamorphicSentinel is an immortal immovable object (undefined) so no
4855 // write-barrier is needed.
4856 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
4857 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4858 __ jmp(&done, Label::kNear);
4859
4860 // An uninitialized cache is patched with the function.
4861 __ bind(&initialize);
4862 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
4863 // No need for a write barrier here - cells are rescanned.
4864
4865 __ bind(&done);
4866 }
4867
4868
4826 static void GenerateRecordCallTarget(MacroAssembler* masm) { 4869 static void GenerateRecordCallTarget(MacroAssembler* masm) {
4827 // Cache the called function in a global property cell. Cache states 4870 // Cache the called function in a global property cell. Cache states
4828 // are uninitialized, monomorphic (indicated by a JSFunction), and 4871 // are uninitialized, monomorphic (indicated by a JSFunction), and
4829 // megamorphic. 4872 // megamorphic.
4830 // ebx : cache cell for call target 4873 // ebx : cache cell for call target
4831 // edi : the function to call 4874 // edi : the function to call
4875 ASSERT(FLAG_optimize_constructed_arrays);
4832 Isolate* isolate = masm->isolate(); 4876 Isolate* isolate = masm->isolate();
4833 Label initialize, done, miss, megamorphic, not_array_function; 4877 Label initialize, done, miss, megamorphic, not_array_function;
4834 4878
4835 // Load the cache state into ecx. 4879 // Load the cache state into ecx.
4836 __ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 4880 __ mov(ecx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
4837 4881
4838 // A monomorphic cache hit or an already megamorphic state: invoke the 4882 // A monomorphic cache hit or an already megamorphic state: invoke the
4839 // function without changing the state. 4883 // function without changing the state.
4840 __ cmp(ecx, edi); 4884 __ cmp(ecx, edi);
4841 __ j(equal, &done, Label::kFar); 4885 __ j(equal, &done);
4842 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); 4886 __ cmp(ecx, Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4843 __ j(equal, &done, Label::kFar); 4887 __ j(equal, &done);
4844 4888
4845 // Special handling of the Array() function, which caches not only the 4889 // Special handling of the Array() function, which caches not only the
4846 // monomorphic Array function but the initial ElementsKind with special 4890 // monomorphic Array function but the initial ElementsKind with special
4847 // sentinels 4891 // sentinels
4848 Handle<Object> terminal_kind_sentinel = 4892 Handle<Object> terminal_kind_sentinel =
4849 TypeFeedbackCells::MonomorphicArraySentinel(LAST_FAST_ELEMENTS_KIND); 4893 TypeFeedbackCells::MonomorphicArraySentinel(isolate,
4894 LAST_FAST_ELEMENTS_KIND);
4850 __ cmp(ecx, Immediate(terminal_kind_sentinel)); 4895 __ cmp(ecx, Immediate(terminal_kind_sentinel));
4851 __ j(above, &miss, Label::kFar); 4896 __ j(above, &miss);
4852 // Load the global or builtins object from the current context 4897 // Load the global or builtins object from the current context
4853 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 4898 __ LoadGlobalContext(ecx);
4854 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
4855 // Make sure the function is the Array() function 4899 // Make sure the function is the Array() function
4856 __ cmp(edi, Operand(ecx, 4900 __ cmp(edi, Operand(ecx,
4857 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); 4901 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
4858 Label megamorphic_pre; 4902 __ j(not_equal, &megamorphic);
4859 __ j(not_equal, &megamorphic_pre, Label::kFar);
4860 __ jmp(&done); 4903 __ jmp(&done);
4861 4904
4862 __ bind(&megamorphic_pre);
4863 __ jmp(&megamorphic, Label::kFar);
4864
4865 __ bind(&miss); 4905 __ bind(&miss);
4866 4906
4867 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 4907 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
4868 // megamorphic. 4908 // megamorphic.
4869 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate))); 4909 __ cmp(ecx, Immediate(TypeFeedbackCells::UninitializedSentinel(isolate)));
4870 __ j(equal, &initialize, Label::kFar); 4910 __ j(equal, &initialize);
4871 // MegamorphicSentinel is an immortal immovable object (undefined) so no 4911 // MegamorphicSentinel is an immortal immovable object (undefined) so no
4872 // write-barrier is needed. 4912 // write-barrier is needed.
4873 __ bind(&megamorphic); 4913 __ bind(&megamorphic);
4874 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 4914 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
4875 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate))); 4915 Immediate(TypeFeedbackCells::MegamorphicSentinel(isolate)));
4876 __ jmp(&done, Label::kNear); 4916 __ jmp(&done, Label::kNear);
4877 4917
4878 // An uninitialized cache is patched with the function or sentinel to 4918 // An uninitialized cache is patched with the function or sentinel to
4879 // indicate the ElementsKind if function is the Array constructor. 4919 // indicate the ElementsKind if function is the Array constructor.
4880 __ bind(&initialize); 4920 __ bind(&initialize);
4881 __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 4921 __ LoadGlobalContext(ecx);
4882 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalContextOffset));
4883 // Make sure the function is the Array() function 4922 // Make sure the function is the Array() function
4884 __ cmp(edi, Operand(ecx, 4923 __ cmp(edi, Operand(ecx,
4885 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); 4924 Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
4886 __ j(not_equal, &not_array_function); 4925 __ j(not_equal, &not_array_function);
4887 4926
4888 // The target function is the Array constructor, install a sentinel value in 4927 // The target function is the Array constructor, install a sentinel value in
4889 // the constructor's type info cell that will track the initial ElementsKind 4928 // the constructor's type info cell that will track the initial ElementsKind
4890 // that should be used for the array when its constructed. 4929 // that should be used for the array when its constructed.
4891 Handle<Object> initial_kind_sentinel = 4930 Handle<Object> initial_kind_sentinel =
4892 TypeFeedbackCells::MonomorphicArraySentinel( 4931 TypeFeedbackCells::MonomorphicArraySentinel(isolate,
4893 GetInitialFastElementsKind()); 4932 GetInitialFastElementsKind());
4894 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), 4933 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
4895 Immediate(initial_kind_sentinel)); 4934 Immediate(initial_kind_sentinel));
4896 __ jmp(&done); 4935 __ jmp(&done);
4897 4936
4898 __ bind(&not_array_function); 4937 __ bind(&not_array_function);
4899 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi); 4938 __ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset), edi);
4900 // No need for a write barrier here - cells are rescanned. 4939 // No need for a write barrier here - cells are rescanned.
4901 4940
4902 __ bind(&done); 4941 __ bind(&done);
(...skipping 24 matching lines...) Expand all
4927 __ bind(&receiver_ok); 4966 __ bind(&receiver_ok);
4928 } 4967 }
4929 4968
4930 // Check that the function really is a JavaScript function. 4969 // Check that the function really is a JavaScript function.
4931 __ JumpIfSmi(edi, &non_function); 4970 __ JumpIfSmi(edi, &non_function);
4932 // Goto slow case if we do not have a function. 4971 // Goto slow case if we do not have a function.
4933 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 4972 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
4934 __ j(not_equal, &slow); 4973 __ j(not_equal, &slow);
4935 4974
4936 if (RecordCallTarget()) { 4975 if (RecordCallTarget()) {
4937 GenerateRecordCallTarget(masm); 4976 if (FLAG_optimize_constructed_arrays) {
4977 GenerateRecordCallTarget(masm);
4978 } else {
4979 GenerateRecordCallTargetNoArray(masm);
4980 }
4938 } 4981 }
4939 4982
4940 // Fast-case: Just invoke the function. 4983 // Fast-case: Just invoke the function.
4941 ParameterCount actual(argc_); 4984 ParameterCount actual(argc_);
4942 4985
4943 if (ReceiverMightBeImplicit()) { 4986 if (ReceiverMightBeImplicit()) {
4944 Label call_as_function; 4987 Label call_as_function;
4945 __ cmp(eax, isolate->factory()->the_hole_value()); 4988 __ cmp(eax, isolate->factory()->the_hole_value());
4946 __ j(equal, &call_as_function); 4989 __ j(equal, &call_as_function);
4947 __ InvokeFunction(edi, 4990 __ InvokeFunction(edi,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
5000 // edi : constructor function 5043 // edi : constructor function
5001 Label slow, non_function_call; 5044 Label slow, non_function_call;
5002 5045
5003 // Check that function is not a smi. 5046 // Check that function is not a smi.
5004 __ JumpIfSmi(edi, &non_function_call); 5047 __ JumpIfSmi(edi, &non_function_call);
5005 // Check that function is a JSFunction. 5048 // Check that function is a JSFunction.
5006 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 5049 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
5007 __ j(not_equal, &slow); 5050 __ j(not_equal, &slow);
5008 5051
5009 if (RecordCallTarget()) { 5052 if (RecordCallTarget()) {
5010 GenerateRecordCallTarget(masm); 5053 if (FLAG_optimize_constructed_arrays) {
5054 GenerateRecordCallTarget(masm);
5055 } else {
5056 GenerateRecordCallTargetNoArray(masm);
5057 }
5011 } 5058 }
5012 5059
5013 // Jump to the function-specific construct stub. 5060 // Jump to the function-specific construct stub.
5014 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 5061 Register jmp_reg = FLAG_optimize_constructed_arrays ? ecx : ebx;
5015 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); 5062 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
5016 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); 5063 __ mov(jmp_reg, FieldOperand(jmp_reg,
5017 __ jmp(ecx); 5064 SharedFunctionInfo::kConstructStubOffset));
5065 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize));
5066 __ jmp(jmp_reg);
5018 5067
5019 // edi: called object 5068 // edi: called object
5020 // eax: number of arguments 5069 // eax: number of arguments
5021 // ecx: object map 5070 // ecx: object map
5022 Label do_call; 5071 Label do_call;
5023 __ bind(&slow); 5072 __ bind(&slow);
5024 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); 5073 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
5025 __ j(not_equal, &non_function_call); 5074 __ j(not_equal, &non_function_call);
5026 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 5075 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
5027 __ jmp(&do_call); 5076 __ jmp(&do_call);
(...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after
7759 // Restore ecx. 7808 // Restore ecx.
7760 __ pop(ecx); 7809 __ pop(ecx);
7761 __ ret(0); 7810 __ ret(0);
7762 } 7811 }
7763 7812
7764 #undef __ 7813 #undef __
7765 7814
7766 } } // namespace v8::internal 7815 } } // namespace v8::internal
7767 7816
7768 #endif // V8_TARGET_ARCH_IA32 7817 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698