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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 2975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2986 __ PopReturnAddressTo(ebx); | 2986 __ PopReturnAddressTo(ebx); |
2987 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 2987 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
2988 __ add(esp, eax); | 2988 __ add(esp, eax); |
2989 __ PushReturnAddressFrom(ebx); | 2989 __ PushReturnAddressFrom(ebx); |
2990 { | 2990 { |
2991 FrameScope scope(masm, StackFrame::INTERNAL); | 2991 FrameScope scope(masm, StackFrame::INTERNAL); |
2992 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 2992 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
2993 } | 2993 } |
2994 } | 2994 } |
2995 | 2995 |
2996 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 2996 static void Generate_OnStackReplacementHelper(MacroAssembler* masm, |
| 2997 bool has_handler_frame) { |
2997 // Lookup the function in the JavaScript frame. | 2998 // Lookup the function in the JavaScript frame. |
2998 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2999 if (has_handler_frame) { |
| 3000 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 3001 __ mov(eax, Operand(eax, JavaScriptFrameConstants::kFunctionOffset)); |
| 3002 } else { |
| 3003 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3004 } |
| 3005 |
2999 { | 3006 { |
3000 FrameScope scope(masm, StackFrame::INTERNAL); | 3007 FrameScope scope(masm, StackFrame::INTERNAL); |
3001 // Pass function as argument. | 3008 // Pass function as argument. |
3002 __ push(eax); | 3009 __ push(eax); |
3003 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 3010 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
3004 } | 3011 } |
3005 | 3012 |
3006 Label skip; | 3013 Label skip; |
3007 // If the code object is null, just return to the unoptimized code. | 3014 // If the code object is null, just return to the caller. |
3008 __ cmp(eax, Immediate(0)); | 3015 __ cmp(eax, Immediate(0)); |
3009 __ j(not_equal, &skip, Label::kNear); | 3016 __ j(not_equal, &skip, Label::kNear); |
3010 __ ret(0); | 3017 __ ret(0); |
3011 | 3018 |
3012 __ bind(&skip); | 3019 __ bind(&skip); |
3013 | 3020 |
| 3021 // Drop any potential handler frame that is be sitting on top of the actual |
| 3022 // JavaScript frame. This is the case then OSR is triggered from bytecode. |
| 3023 if (has_handler_frame) { |
| 3024 __ leave(); |
| 3025 } |
| 3026 |
3014 // Load deoptimization data from the code object. | 3027 // Load deoptimization data from the code object. |
3015 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3028 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
3016 | 3029 |
3017 // Load the OSR entrypoint offset from the deoptimization data. | 3030 // Load the OSR entrypoint offset from the deoptimization data. |
3018 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( | 3031 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( |
3019 DeoptimizationInputData::kOsrPcOffsetIndex) - | 3032 DeoptimizationInputData::kOsrPcOffsetIndex) - |
3020 kHeapObjectTag)); | 3033 kHeapObjectTag)); |
3021 __ SmiUntag(ebx); | 3034 __ SmiUntag(ebx); |
3022 | 3035 |
3023 // Compute the target address = code_obj + header_size + osr_offset | 3036 // Compute the target address = code_obj + header_size + osr_offset |
3024 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3037 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
3025 | 3038 |
3026 // Overwrite the return address on the stack. | 3039 // Overwrite the return address on the stack. |
3027 __ mov(Operand(esp, 0), eax); | 3040 __ mov(Operand(esp, 0), eax); |
3028 | 3041 |
3029 // And "return" to the OSR entry point of the function. | 3042 // And "return" to the OSR entry point of the function. |
3030 __ ret(0); | 3043 __ ret(0); |
3031 } | 3044 } |
3032 | 3045 |
| 3046 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 3047 Generate_OnStackReplacementHelper(masm, false); |
| 3048 } |
| 3049 |
| 3050 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
| 3051 Generate_OnStackReplacementHelper(masm, true); |
| 3052 } |
| 3053 |
3033 #undef __ | 3054 #undef __ |
3034 } // namespace internal | 3055 } // namespace internal |
3035 } // namespace v8 | 3056 } // namespace v8 |
3036 | 3057 |
3037 #endif // V8_TARGET_ARCH_X87 | 3058 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |