OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 __ PushReturnAddressFrom(ecx); | 53 __ PushReturnAddressFrom(ecx); |
54 } | 54 } |
55 | 55 |
56 // JumpToExternalReference expects eax to contain the number of arguments | 56 // JumpToExternalReference expects eax to contain the number of arguments |
57 // including the receiver and the extra arguments. | 57 // including the receiver and the extra arguments. |
58 __ add(eax, Immediate(num_extra_args + 1)); | 58 __ add(eax, Immediate(num_extra_args + 1)); |
59 | 59 |
60 __ JumpToExternalReference(ExternalReference(id, masm->isolate())); | 60 __ JumpToExternalReference(ExternalReference(id, masm->isolate())); |
61 } | 61 } |
62 | 62 |
63 | 63 static void CallRuntimePassFunction(MacroAssembler* masm, |
64 static void CallRuntimePassFunction( | 64 Runtime::FunctionId function_id, |
65 MacroAssembler* masm, Runtime::FunctionId function_id) { | 65 Register output) { |
Michael Starzinger
2016/02/09 11:52:19
Instead of passing an output register this functio
mvstanton
2016/02/09 18:47:47
Most excellent idea, thanks!
| |
66 // ----------- S t a t e ------------- | 66 // ----------- S t a t e ------------- |
67 // -- eax : argument count (preserved for callee) | |
67 // -- edx : new target (preserved for callee) | 68 // -- edx : new target (preserved for callee) |
68 // -- edi : target function (preserved for callee) | 69 // -- edi : target function (preserved for callee) |
69 // ----------------------------------- | 70 // ----------------------------------- |
70 | 71 DCHECK(!output.is(eax) && !output.is(edx) && !output.is(edi)); |
71 FrameScope scope(masm, StackFrame::INTERNAL); | 72 FrameScope scope(masm, StackFrame::INTERNAL); |
73 // Push the number of arguments to the callee. | |
74 __ SmiTag(eax); | |
75 __ push(eax); | |
72 // Push a copy of the target function and the new target. | 76 // Push a copy of the target function and the new target. |
73 __ push(edi); | 77 __ push(edi); |
74 __ push(edx); | 78 __ push(edx); |
75 // Function is also the parameter to the runtime call. | 79 // Function is also the parameter to the runtime call. |
76 __ push(edi); | 80 __ push(edi); |
77 | 81 |
78 __ CallRuntime(function_id, 1); | 82 __ CallRuntime(function_id, 1); |
83 __ mov(output, eax); | |
84 | |
79 // Restore target function and new target. | 85 // Restore target function and new target. |
80 __ pop(edx); | 86 __ pop(edx); |
81 __ pop(edi); | 87 __ pop(edi); |
88 __ pop(eax); | |
89 __ SmiUntag(eax); | |
90 } | |
91 | |
92 static void GenerateTailCallToSharedCode(MacroAssembler* masm, | |
93 Register scratch) { | |
94 DCHECK(!scratch.is(eax) && !scratch.is(edi)); | |
95 __ mov(scratch, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
96 __ mov(scratch, FieldOperand(scratch, SharedFunctionInfo::kCodeOffset)); | |
97 __ lea(scratch, FieldOperand(scratch, Code::kHeaderSize)); | |
98 __ jmp(scratch); | |
99 } | |
100 | |
101 static void GenerateTailCallToReturnedCode(MacroAssembler* masm, | |
102 Register code) { | |
103 __ lea(code, FieldOperand(code, Code::kHeaderSize)); | |
104 __ jmp(code); | |
82 } | 105 } |
83 | 106 |
84 | 107 |
85 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | |
86 __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
87 __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kCodeOffset)); | |
88 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); | |
89 __ jmp(eax); | |
90 } | |
91 | |
92 | |
93 static void GenerateTailCallToReturnedCode(MacroAssembler* masm) { | |
94 __ lea(eax, FieldOperand(eax, Code::kHeaderSize)); | |
95 __ jmp(eax); | |
96 } | |
97 | |
98 | |
99 void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { | 108 void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { |
100 // Checking whether the queued function is ready for install is optional, | 109 // Checking whether the queued function is ready for install is optional, |
101 // since we come across interrupts and stack checks elsewhere. However, | 110 // since we come across interrupts and stack checks elsewhere. However, |
102 // not checking may delay installing ready functions, and always checking | 111 // not checking may delay installing ready functions, and always checking |
103 // would be quite expensive. A good compromise is to first check against | 112 // would be quite expensive. A good compromise is to first check against |
104 // stack limit as a cue for an interrupt signal. | 113 // stack limit as a cue for an interrupt signal. |
105 Label ok; | 114 Label ok; |
106 ExternalReference stack_limit = | 115 ExternalReference stack_limit = |
107 ExternalReference::address_of_stack_limit(masm->isolate()); | 116 ExternalReference::address_of_stack_limit(masm->isolate()); |
108 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 117 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
109 __ j(above_equal, &ok, Label::kNear); | 118 __ j(above_equal, &ok, Label::kNear); |
110 | 119 |
111 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 120 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode, ebx); |
112 GenerateTailCallToReturnedCode(masm); | 121 GenerateTailCallToReturnedCode(masm, ebx); |
113 | 122 |
114 __ bind(&ok); | 123 __ bind(&ok); |
115 GenerateTailCallToSharedCode(masm); | 124 GenerateTailCallToSharedCode(masm, ebx); |
116 } | 125 } |
117 | 126 |
118 | 127 |
119 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 128 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
120 bool is_api_function, | 129 bool is_api_function, |
121 bool create_implicit_receiver, | 130 bool create_implicit_receiver, |
122 bool check_derived_construct) { | 131 bool check_derived_construct) { |
123 // ----------- S t a t e ------------- | 132 // ----------- S t a t e ------------- |
124 // -- eax: number of arguments | 133 // -- eax: number of arguments |
125 // -- edi: constructor function | 134 // -- edi: constructor function |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
841 // This simulates the initial call to bytecode handlers in interpreter entry | 850 // This simulates the initial call to bytecode handlers in interpreter entry |
842 // trampoline. The return will never actually be taken, but our stack walker | 851 // trampoline. The return will never actually be taken, but our stack walker |
843 // uses this address to determine whether a frame is interpreted. | 852 // uses this address to determine whether a frame is interpreted. |
844 __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); | 853 __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); |
845 | 854 |
846 Generate_EnterBytecodeDispatch(masm); | 855 Generate_EnterBytecodeDispatch(masm); |
847 } | 856 } |
848 | 857 |
849 | 858 |
850 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { | 859 void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
851 CallRuntimePassFunction(masm, Runtime::kCompileLazy); | 860 CallRuntimePassFunction(masm, Runtime::kCompileLazy, ebx); |
852 GenerateTailCallToReturnedCode(masm); | 861 GenerateTailCallToReturnedCode(masm, ebx); |
853 } | 862 } |
854 | 863 |
855 | 864 |
856 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 865 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { |
857 CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent); | 866 CallRuntimePassFunction(masm, Runtime::kCompileOptimized_NotConcurrent, ebx); |
858 GenerateTailCallToReturnedCode(masm); | 867 GenerateTailCallToReturnedCode(masm, ebx); |
859 } | 868 } |
860 | 869 |
861 | 870 |
862 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 871 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { |
863 CallRuntimePassFunction(masm, Runtime::kCompileOptimized_Concurrent); | 872 CallRuntimePassFunction(masm, Runtime::kCompileOptimized_Concurrent, ebx); |
864 GenerateTailCallToReturnedCode(masm); | 873 GenerateTailCallToReturnedCode(masm, ebx); |
865 } | 874 } |
866 | 875 |
867 | 876 |
868 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { | 877 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { |
869 // For now, we are relying on the fact that make_code_young doesn't do any | 878 // For now, we are relying on the fact that make_code_young doesn't do any |
870 // garbage collection which allows us to save/restore the registers without | 879 // garbage collection which allows us to save/restore the registers without |
871 // worrying about which of them contain pointers. We also don't build an | 880 // worrying about which of them contain pointers. We also don't build an |
872 // internal frame to make the code faster, since we shouldn't have to do stack | 881 // internal frame to make the code faster, since we shouldn't have to do stack |
873 // crawls in MakeCodeYoung. This seems a bit fragile. | 882 // crawls in MakeCodeYoung. This seems a bit fragile. |
874 | 883 |
(...skipping 1897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2772 | 2781 |
2773 __ bind(&ok); | 2782 __ bind(&ok); |
2774 __ ret(0); | 2783 __ ret(0); |
2775 } | 2784 } |
2776 | 2785 |
2777 #undef __ | 2786 #undef __ |
2778 } // namespace internal | 2787 } // namespace internal |
2779 } // namespace v8 | 2788 } // namespace v8 |
2780 | 2789 |
2781 #endif // V8_TARGET_ARCH_IA32 | 2790 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |