 Chromium Code Reviews
 Chromium Code Reviews| 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 |