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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 | 1025 |
1026 | 1026 |
1027 void MacroAssembler::PopTryHandler() { | 1027 void MacroAssembler::PopTryHandler() { |
1028 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 1028 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
1029 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | 1029 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); |
1030 pop(Operand::StaticVariable(handler_address)); | 1030 pop(Operand::StaticVariable(handler_address)); |
1031 add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); | 1031 add(esp, Immediate(StackHandlerConstants::kSize - kPointerSize)); |
1032 } | 1032 } |
1033 | 1033 |
1034 | 1034 |
1035 void MacroAssembler::JumpToHandlerEntry() { | |
1036 // Compute the handler entry address and jump to it. The handler table is | |
1037 // a fixed array of (smi-tagged) code offsets. | |
1038 // eax = exception, edi = code object, edx = state. | |
1039 mov(ebx, FieldOperand(edi, Code::kHandlerTableOffset)); | |
1040 shr(edx, StackHandler::kKindWidth); | |
1041 mov(edx, FieldOperand(ebx, edx, times_4, FixedArray::kHeaderSize)); | |
1042 SmiUntag(edx); | |
1043 lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); | |
1044 jmp(edi); | |
1045 } | |
1046 | |
1047 | |
1048 void MacroAssembler::Throw(Register value) { | |
1049 // Adjust this code if not the case. | |
1050 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | |
1051 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
1052 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
1053 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
1054 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
1055 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
1056 | |
1057 // The exception is expected in eax. | |
1058 if (!value.is(eax)) { | |
1059 mov(eax, value); | |
1060 } | |
1061 // Drop the stack pointer to the top of the top handler. | |
1062 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | |
1063 mov(esp, Operand::StaticVariable(handler_address)); | |
1064 // Restore the next handler. | |
1065 pop(Operand::StaticVariable(handler_address)); | |
1066 | |
1067 // Remove the code object and state, compute the handler address in edi. | |
1068 pop(edi); // Code object. | |
1069 pop(edx); // Index and state. | |
1070 | |
1071 // Restore the context and frame pointer. | |
1072 pop(esi); // Context. | |
1073 pop(ebp); // Frame pointer. | |
1074 | |
1075 // If the handler is a JS frame, restore the context to the frame. | |
1076 // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either | |
1077 // ebp or esi. | |
1078 Label skip; | |
1079 test(esi, esi); | |
1080 j(zero, &skip, Label::kNear); | |
1081 mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); | |
1082 bind(&skip); | |
1083 | |
1084 JumpToHandlerEntry(); | |
1085 } | |
1086 | |
1087 | |
1088 void MacroAssembler::ThrowUncatchable(Register value) { | |
1089 // Adjust this code if not the case. | |
1090 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); | |
1091 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
1092 STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); | |
1093 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); | |
1094 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); | |
1095 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); | |
1096 | |
1097 // The exception is expected in eax. | |
1098 if (!value.is(eax)) { | |
1099 mov(eax, value); | |
1100 } | |
1101 // Drop the stack pointer to the top of the top stack handler. | |
1102 ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); | |
1103 mov(esp, Operand::StaticVariable(handler_address)); | |
1104 | |
1105 // Unwind the handlers until the top ENTRY handler is found. | |
1106 Label fetch_next, check_kind; | |
1107 jmp(&check_kind, Label::kNear); | |
1108 bind(&fetch_next); | |
1109 mov(esp, Operand(esp, StackHandlerConstants::kNextOffset)); | |
1110 | |
1111 bind(&check_kind); | |
1112 STATIC_ASSERT(StackHandler::JS_ENTRY == 0); | |
1113 test(Operand(esp, StackHandlerConstants::kStateOffset), | |
1114 Immediate(StackHandler::KindField::kMask)); | |
1115 j(not_zero, &fetch_next); | |
1116 | |
1117 // Set the top handler address to next handler past the top ENTRY handler. | |
1118 pop(Operand::StaticVariable(handler_address)); | |
1119 | |
1120 // Remove the code object and state, compute the handler address in edi. | |
1121 pop(edi); // Code object. | |
1122 pop(edx); // Index and state. | |
1123 | |
1124 // Clear the context pointer and frame pointer (0 was saved in the handler). | |
1125 pop(esi); | |
1126 pop(ebp); | |
1127 | |
1128 JumpToHandlerEntry(); | |
1129 } | |
1130 | |
1131 | |
1132 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1035 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1133 Register scratch1, | 1036 Register scratch1, |
1134 Register scratch2, | 1037 Register scratch2, |
1135 Label* miss) { | 1038 Label* miss) { |
1136 Label same_contexts; | 1039 Label same_contexts; |
1137 | 1040 |
1138 DCHECK(!holder_reg.is(scratch1)); | 1041 DCHECK(!holder_reg.is(scratch1)); |
1139 DCHECK(!holder_reg.is(scratch2)); | 1042 DCHECK(!holder_reg.is(scratch2)); |
1140 DCHECK(!scratch1.is(scratch2)); | 1043 DCHECK(!scratch1.is(scratch2)); |
1141 | 1044 |
(...skipping 2069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3211 if (mag.shift > 0) sar(edx, mag.shift); | 3114 if (mag.shift > 0) sar(edx, mag.shift); |
3212 mov(eax, dividend); | 3115 mov(eax, dividend); |
3213 shr(eax, 31); | 3116 shr(eax, 31); |
3214 add(edx, eax); | 3117 add(edx, eax); |
3215 } | 3118 } |
3216 | 3119 |
3217 | 3120 |
3218 } } // namespace v8::internal | 3121 } } // namespace v8::internal |
3219 | 3122 |
3220 #endif // V8_TARGET_ARCH_X87 | 3123 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |