| 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 |