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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 2954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2965 | 2965 |
2966 | 2966 |
2967 void MacroAssembler::PopTryHandler() { | 2967 void MacroAssembler::PopTryHandler() { |
2968 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 2968 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
2969 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 2969 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
2970 Pop(ExternalOperand(handler_address)); | 2970 Pop(ExternalOperand(handler_address)); |
2971 addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 2971 addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
2972 } | 2972 } |
2973 | 2973 |
2974 | 2974 |
2975 void MacroAssembler::JumpToHandlerEntry() { | |
2976 // Compute the handler entry address and jump to it. The handler table is | |
2977 // a fixed array of (smi-tagged) code offsets. | |
2978 // rax = exception, rdi = code object, rdx = state. | |
2979 movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset)); | |
2980 shrp(rdx, Immediate(StackHandler::kKindWidth)); | |
2981 movp(rdx, | |
2982 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); | |
2983 SmiToInteger64(rdx, rdx); | |
2984 leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize)); | |
2985 jmp(rdi); | |
2986 } | |
2987 | |
2988 | |
2989 void MacroAssembler::Throw(Register value) { | |
2990 // Adjust this code if not the case. | |
2991 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + | |
2992 kFPOnStackSize); | |
2993 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
2994 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
2995 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
2996 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
2997 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
2998 | |
2999 // The exception is expected in rax. | |
3000 if (!value.is(rax)) { | |
3001 movp(rax, value); | |
3002 } | |
3003 // Drop the stack pointer to the top of the top handler. | |
3004 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | |
3005 movp(rsp, ExternalOperand(handler_address)); | |
3006 // Restore the next handler. | |
3007 Pop(ExternalOperand(handler_address)); | |
3008 | |
3009 // Remove the code object and state, compute the handler address in rdi. | |
3010 Pop(rdi); // Code object. | |
3011 Pop(rdx); // Offset and state. | |
3012 | |
3013 // Restore the context and frame pointer. | |
3014 Pop(rsi); // Context. | |
3015 popq(rbp); // Frame pointer. | |
3016 | |
3017 // If the handler is a JS frame, restore the context to the frame. | |
3018 // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either | |
3019 // rbp or rsi. | |
3020 Label skip; | |
3021 testp(rsi, rsi); | |
3022 j(zero, &skip, Label::kNear); | |
3023 movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); | |
3024 bind(&skip); | |
3025 | |
3026 JumpToHandlerEntry(); | |
3027 } | |
3028 | |
3029 | |
3030 void MacroAssembler::ThrowUncatchable(Register value) { | |
3031 // Adjust this code if not the case. | |
3032 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + | |
3033 kFPOnStackSize); | |
3034 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
3035 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
3036 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
3037 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
3038 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
3039 | |
3040 // The exception is expected in rax. | |
3041 if (!value.is(rax)) { | |
3042 movp(rax, value); | |
3043 } | |
3044 // Drop the stack pointer to the top of the top stack handler. | |
3045 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | |
3046 Load(rsp, handler_address); | |
3047 | |
3048 // Unwind the handlers until the top ENTRY handler is found. | |
3049 Label fetch_next, check_kind; | |
3050 jmp(&check_kind, Label::kNear); | |
3051 bind(&fetch_next); | |
3052 movp(rsp, Operand(rsp, StackHandlerConstants::kNextOffset)); | |
3053 | |
3054 bind(&check_kind); | |
3055 STATIC_ASSERT(StackHandler::JS_ENTRY == 0); | |
3056 testl(Operand(rsp, StackHandlerConstants::kStateOffset), | |
3057 Immediate(StackHandler::KindField::kMask)); | |
3058 j(not_zero, &fetch_next); | |
3059 | |
3060 // Set the top handler address to next handler past the top ENTRY handler. | |
3061 Pop(ExternalOperand(handler_address)); | |
3062 | |
3063 // Remove the code object and state, compute the handler address in rdi. | |
3064 Pop(rdi); // Code object. | |
3065 Pop(rdx); // Offset and state. | |
3066 | |
3067 // Clear the context pointer and frame pointer (0 was saved in the handler). | |
3068 Pop(rsi); | |
3069 popq(rbp); | |
3070 | |
3071 JumpToHandlerEntry(); | |
3072 } | |
3073 | |
3074 | |
3075 void MacroAssembler::Ret() { | 2975 void MacroAssembler::Ret() { |
3076 ret(0); | 2976 ret(0); |
3077 } | 2977 } |
3078 | 2978 |
3079 | 2979 |
3080 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { | 2980 void MacroAssembler::Ret(int bytes_dropped, Register scratch) { |
3081 if (is_uint16(bytes_dropped)) { | 2981 if (is_uint16(bytes_dropped)) { |
3082 ret(bytes_dropped); | 2982 ret(bytes_dropped); |
3083 } else { | 2983 } else { |
3084 PopReturnAddressTo(scratch); | 2984 PopReturnAddressTo(scratch); |
(...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); | 5034 if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); |
5135 movl(rax, dividend); | 5035 movl(rax, dividend); |
5136 shrl(rax, Immediate(31)); | 5036 shrl(rax, Immediate(31)); |
5137 addl(rdx, rax); | 5037 addl(rdx, rax); |
5138 } | 5038 } |
5139 | 5039 |
5140 | 5040 |
5141 } } // namespace v8::internal | 5041 } } // namespace v8::internal |
5142 | 5042 |
5143 #endif // V8_TARGET_ARCH_X64 | 5043 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |