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 2950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2961 __ PopReturnAddressTo(ebx); | 2961 __ PopReturnAddressTo(ebx); |
2962 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 2962 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
2963 __ add(esp, eax); | 2963 __ add(esp, eax); |
2964 __ PushReturnAddressFrom(ebx); | 2964 __ PushReturnAddressFrom(ebx); |
2965 { | 2965 { |
2966 FrameScope scope(masm, StackFrame::INTERNAL); | 2966 FrameScope scope(masm, StackFrame::INTERNAL); |
2967 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); | 2967 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
2968 } | 2968 } |
2969 } | 2969 } |
2970 | 2970 |
2971 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 2971 static void Generate_OnStackReplacementHelper(MacroAssembler* masm, |
| 2972 bool has_handler_frame) { |
2972 // Lookup the function in the JavaScript frame. | 2973 // Lookup the function in the JavaScript frame. |
2973 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2974 if (has_handler_frame) { |
| 2975 __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 2976 __ mov(eax, Operand(eax, JavaScriptFrameConstants::kFunctionOffset)); |
| 2977 } else { |
| 2978 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2979 } |
| 2980 |
2974 { | 2981 { |
2975 FrameScope scope(masm, StackFrame::INTERNAL); | 2982 FrameScope scope(masm, StackFrame::INTERNAL); |
2976 // Pass function as argument. | 2983 // Pass function as argument. |
2977 __ push(eax); | 2984 __ push(eax); |
2978 __ CallRuntime(Runtime::kCompileForOnStackReplacement); | 2985 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
2979 } | 2986 } |
2980 | 2987 |
2981 Label skip; | 2988 Label skip; |
2982 // If the code object is null, just return to the unoptimized code. | 2989 // If the code object is null, just return to the caller. |
2983 __ cmp(eax, Immediate(0)); | 2990 __ cmp(eax, Immediate(0)); |
2984 __ j(not_equal, &skip, Label::kNear); | 2991 __ j(not_equal, &skip, Label::kNear); |
2985 __ ret(0); | 2992 __ ret(0); |
2986 | 2993 |
2987 __ bind(&skip); | 2994 __ bind(&skip); |
2988 | 2995 |
| 2996 // Drop any potential handler frame that is be sitting on top of the actual |
| 2997 // JavaScript frame. This is the case then OSR is triggered from bytecode. |
| 2998 if (has_handler_frame) { |
| 2999 __ leave(); |
| 3000 } |
| 3001 |
2989 // Load deoptimization data from the code object. | 3002 // Load deoptimization data from the code object. |
2990 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 3003 __ mov(ebx, Operand(eax, Code::kDeoptimizationDataOffset - kHeapObjectTag)); |
2991 | 3004 |
2992 // Load the OSR entrypoint offset from the deoptimization data. | 3005 // Load the OSR entrypoint offset from the deoptimization data. |
2993 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( | 3006 __ mov(ebx, Operand(ebx, FixedArray::OffsetOfElementAt( |
2994 DeoptimizationInputData::kOsrPcOffsetIndex) - | 3007 DeoptimizationInputData::kOsrPcOffsetIndex) - |
2995 kHeapObjectTag)); | 3008 kHeapObjectTag)); |
2996 __ SmiUntag(ebx); | 3009 __ SmiUntag(ebx); |
2997 | 3010 |
2998 // Compute the target address = code_obj + header_size + osr_offset | 3011 // Compute the target address = code_obj + header_size + osr_offset |
2999 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); | 3012 __ lea(eax, Operand(eax, ebx, times_1, Code::kHeaderSize - kHeapObjectTag)); |
3000 | 3013 |
3001 // Overwrite the return address on the stack. | 3014 // Overwrite the return address on the stack. |
3002 __ mov(Operand(esp, 0), eax); | 3015 __ mov(Operand(esp, 0), eax); |
3003 | 3016 |
3004 // And "return" to the OSR entry point of the function. | 3017 // And "return" to the OSR entry point of the function. |
3005 __ ret(0); | 3018 __ ret(0); |
3006 } | 3019 } |
3007 | 3020 |
| 3021 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
| 3022 Generate_OnStackReplacementHelper(masm, false); |
| 3023 } |
| 3024 |
| 3025 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { |
| 3026 Generate_OnStackReplacementHelper(masm, true); |
| 3027 } |
| 3028 |
3008 #undef __ | 3029 #undef __ |
3009 } // namespace internal | 3030 } // namespace internal |
3010 } // namespace v8 | 3031 } // namespace v8 |
3011 | 3032 |
3012 #endif // V8_TARGET_ARCH_IA32 | 3033 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |