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_X64 | 5 #if V8_TARGET_ARCH_X64 |
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 2993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3004 __ PopReturnAddressTo(rbx); | 3004 __ PopReturnAddressTo(rbx); |
3005 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); | 3005 __ leap(rax, Operand(rax, times_pointer_size, 1 * kPointerSize)); |
3006 __ addp(rsp, rax); | 3006 __ addp(rsp, rax); |
3007 __ PushReturnAddressFrom(rbx); | 3007 __ PushReturnAddressFrom(rbx); |
3008 { | 3008 { |
3009 FrameScope scope(masm, StackFrame::INTERNAL); | 3009 FrameScope scope(masm, StackFrame::INTERNAL); |
3010 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 3010 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
3011 } | 3011 } |
3012 } | 3012 } |
3013 | 3013 |
3014 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 3014 static void Generate_OnStackReplacementHelper(MacroAssembler* masm, |
| 3015 bool has_handler_frame) { |
3015 // Lookup the function in the JavaScript frame. | 3016 // Lookup the function in the JavaScript frame. |
3016 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 3017 if (has_handler_frame) { |
| 3018 __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); |
| 3019 __ movp(rax, Operand(rax, JavaScriptFrameConstants::kFunctionOffset)); |
| 3020 } else { |
| 3021 __ movp(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3022 } |
| 3023 |
3017 { | 3024 { |
3018 FrameScope scope(masm, StackFrame::INTERNAL); | 3025 FrameScope scope(masm, StackFrame::INTERNAL); |
3019 // Pass function as argument. | 3026 // Pass function as argument. |
3020 __ Push(rax); | 3027 __ Push(rax); |
3021 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3028 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
3022 } | 3029 } |
3023 | 3030 |
3024 Label skip; | 3031 Label skip; |
3025 // If the code object is null, just return to the unoptimized code. | 3032 // If the code object is null, just return to the caller. |
3026 __ cmpp(rax, Immediate(0)); | 3033 __ cmpp(rax, Immediate(0)); |
3027 __ j(not_equal, &skip, Label::kNear); | 3034 __ j(not_equal, &skip, Label::kNear); |
3028 __ ret(0); | 3035 __ ret(0); |
3029 | 3036 |
3030 __ bind(&skip); | 3037 __ bind(&skip); |
3031 | 3038 |
| 3039 // Drop any potential handler frame that is be sitting on top of the actual |
| 3040 // JavaScript frame. This is the case then OSR is triggered from bytecode. |
| 3041 if (has_handler_frame) { |
| 3042 __ leave(); |
| 3043 } |
| 3044 |
3032 // Load deoptimization data from the code object. | 3045 // Load deoptimization data from the code object. |
3033 __ movp(rbx, Operand(rax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3046 __ movp(rbx, Operand(rax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
3034 | 3047 |
3035 // Load the OSR entrypoint offset from the deoptimization data. | 3048 // Load the OSR entrypoint offset from the deoptimization data. |
3036 __ SmiToInteger32( | 3049 __ SmiToInteger32( |
3037 rbx, Operand(rbx, FixedArray::OffsetOfElementAt( | 3050 rbx, Operand(rbx, FixedArray::OffsetOfElementAt( |
3038 DeoptimizationInputData::kOsrPcOffsetIndex) - | 3051 DeoptimizationInputData::kOsrPcOffsetIndex) - |
3039 kHeapObjectTag)); | 3052 kHeapObjectTag)); |
3040 | 3053 |
3041 // Compute the target address = code_obj + header_size + osr_offset | 3054 // Compute the target address = code_obj + header_size + osr_offset |
3042 __ leap(rax, Operand(rax, rbx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3055 __ leap(rax, Operand(rax, rbx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
3043 | 3056 |
3044 // Overwrite the return address on the stack. | 3057 // Overwrite the return address on the stack. |
3045 __ movq(StackOperandForReturnAddress(0), rax); | 3058 __ movq(StackOperandForReturnAddress(0), rax); |
3046 | 3059 |
3047 // And "return" to the OSR entry point of the function. | 3060 // And "return" to the OSR entry point of the function. |
3048 __ ret(0); | 3061 __ ret(0); |
3049 } | 3062 } |
3050 | 3063 |
| 3064 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 3065 Generate_OnStackReplacementHelper(masm, false); |
| 3066 } |
| 3067 |
| 3068 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
| 3069 Generate_OnStackReplacementHelper(masm, true); |
| 3070 } |
| 3071 |
3051 #undef __ | 3072 #undef __ |
3052 | 3073 |
3053 } // namespace internal | 3074 } // namespace internal |
3054 } // namespace v8 | 3075 } // namespace v8 |
3055 | 3076 |
3056 #endif // V8_TARGET_ARCH_X64 | 3077 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |