| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1095 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); | 1095 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
| 1096 CEntryStub ces(1); | 1096 CEntryStub ces(1); |
| 1097 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1097 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
| 1098 } | 1098 } |
| 1099 #endif | 1099 #endif |
| 1100 | 1100 |
| 1101 | 1101 |
| 1102 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 1102 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 1103 HandlerType type) { | 1103 HandlerType type) { |
| 1104 // Adjust this code if not the case. | 1104 // Adjust this code if not the case. |
| 1105 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 1105 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 1106 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 1107 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| 1108 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| 1109 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); |
| 1110 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 1111 |
| 1106 // The pc (return address) is passed in register lr. | 1112 // The pc (return address) is passed in register lr. |
| 1107 if (try_location == IN_JAVASCRIPT) { | 1113 if (try_location == IN_JAVASCRIPT) { |
| 1108 if (type == TRY_CATCH_HANDLER) { | 1114 if (type == TRY_CATCH_HANDLER) { |
| 1109 mov(r3, Operand(StackHandler::TRY_CATCH)); | 1115 mov(r3, Operand(StackHandler::TRY_CATCH)); |
| 1110 } else { | 1116 } else { |
| 1111 mov(r3, Operand(StackHandler::TRY_FINALLY)); | 1117 mov(r3, Operand(StackHandler::TRY_FINALLY)); |
| 1112 } | 1118 } |
| 1113 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize | 1119 stm(db_w, sp, r3.bit() | cp.bit() | fp.bit() | lr.bit()); |
| 1114 && StackHandlerConstants::kFPOffset == 2 * kPointerSize | |
| 1115 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 1116 stm(db_w, sp, r3.bit() | fp.bit() | lr.bit()); | |
| 1117 // Save the current handler as the next handler. | 1120 // Save the current handler as the next handler. |
| 1118 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 1121 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1119 ldr(r1, MemOperand(r3)); | 1122 ldr(r1, MemOperand(r3)); |
| 1120 ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 1121 push(r1); | 1123 push(r1); |
| 1122 // Link this handler as the new current one. | 1124 // Link this handler as the new current one. |
| 1123 str(sp, MemOperand(r3)); | 1125 str(sp, MemOperand(r3)); |
| 1124 } else { | 1126 } else { |
| 1125 // Must preserve r0-r4, r5-r7 are available. | 1127 // Must preserve r0-r4, r5-r7 are available. |
| 1126 ASSERT(try_location == IN_JS_ENTRY); | 1128 ASSERT(try_location == IN_JS_ENTRY); |
| 1127 // The frame pointer does not point to a JS frame so we save NULL | 1129 // The frame pointer does not point to a JS frame so we save NULL |
| 1128 // for fp. We expect the code throwing an exception to check fp | 1130 // for fp. We expect the code throwing an exception to check fp |
| 1129 // before dereferencing it to restore the context. | 1131 // before dereferencing it to restore the context. |
| 1130 mov(ip, Operand(0, RelocInfo::NONE)); // To save a NULL frame pointer. | 1132 mov(r5, Operand(StackHandler::ENTRY)); // State. |
| 1131 mov(r6, Operand(StackHandler::ENTRY)); | 1133 mov(r6, Operand(Smi::FromInt(0))); // Indicates no context. |
| 1132 ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize | 1134 mov(r7, Operand(0, RelocInfo::NONE)); // NULL frame pointer. |
| 1133 && StackHandlerConstants::kFPOffset == 2 * kPointerSize | 1135 stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | lr.bit()); |
| 1134 && StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 1135 stm(db_w, sp, r6.bit() | ip.bit() | lr.bit()); | |
| 1136 // Save the current handler as the next handler. | 1136 // Save the current handler as the next handler. |
| 1137 mov(r7, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 1137 mov(r7, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1138 ldr(r6, MemOperand(r7)); | 1138 ldr(r6, MemOperand(r7)); |
| 1139 ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 1140 push(r6); | 1139 push(r6); |
| 1141 // Link this handler as the new current one. | 1140 // Link this handler as the new current one. |
| 1142 str(sp, MemOperand(r7)); | 1141 str(sp, MemOperand(r7)); |
| 1143 } | 1142 } |
| 1144 } | 1143 } |
| 1145 | 1144 |
| 1146 | 1145 |
| 1147 void MacroAssembler::PopTryHandler() { | 1146 void MacroAssembler::PopTryHandler() { |
| 1148 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); | 1147 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
| 1149 pop(r1); | 1148 pop(r1); |
| 1150 mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 1149 mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1151 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | 1150 add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); |
| 1152 str(r1, MemOperand(ip)); | 1151 str(r1, MemOperand(ip)); |
| 1153 } | 1152 } |
| 1154 | 1153 |
| 1155 | 1154 |
| 1156 void MacroAssembler::Throw(Register value) { | 1155 void MacroAssembler::Throw(Register value) { |
| 1156 // Adjust this code if not the case. |
| 1157 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 1158 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 1159 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| 1160 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| 1161 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); |
| 1162 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 1157 // r0 is expected to hold the exception. | 1163 // r0 is expected to hold the exception. |
| 1158 if (!value.is(r0)) { | 1164 if (!value.is(r0)) { |
| 1159 mov(r0, value); | 1165 mov(r0, value); |
| 1160 } | 1166 } |
| 1161 | 1167 |
| 1162 // Adjust this code if not the case. | |
| 1163 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | |
| 1164 | |
| 1165 // Drop the sp to the top of the handler. | 1168 // Drop the sp to the top of the handler. |
| 1166 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 1169 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1167 ldr(sp, MemOperand(r3)); | 1170 ldr(sp, MemOperand(r3)); |
| 1168 | 1171 |
| 1169 // Restore the next handler and frame pointer, discard handler state. | 1172 // Restore the next handler. |
| 1170 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 1171 pop(r2); | 1173 pop(r2); |
| 1172 str(r2, MemOperand(r3)); | 1174 str(r2, MemOperand(r3)); |
| 1173 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | |
| 1174 ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state. | |
| 1175 | 1175 |
| 1176 // Before returning we restore the context from the frame pointer if | 1176 // Restore context and frame pointer, discard state (r3). |
| 1177 // not NULL. The frame pointer is NULL in the exception handler of a | 1177 ldm(ia_w, sp, r3.bit() | cp.bit() | fp.bit()); |
| 1178 // JS entry frame. | 1178 |
| 1179 cmp(fp, Operand(0, RelocInfo::NONE)); | 1179 // If the handler is a JS frame, restore the context to the frame. |
| 1180 // Set cp to NULL if fp is NULL. | 1180 // (r3 == ENTRY) == (fp == 0) == (cp == 0), so we could test any |
| 1181 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq); | 1181 // of them. |
| 1182 // Restore cp otherwise. | 1182 cmp(r3, Operand(StackHandler::ENTRY)); |
| 1183 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); | 1183 str(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); |
| 1184 |
| 1184 #ifdef DEBUG | 1185 #ifdef DEBUG |
| 1185 if (emit_debug_code()) { | 1186 if (emit_debug_code()) { |
| 1186 mov(lr, Operand(pc)); | 1187 mov(lr, Operand(pc)); |
| 1187 } | 1188 } |
| 1188 #endif | 1189 #endif |
| 1189 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 1190 pop(pc); | 1190 pop(pc); |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 | 1193 |
| 1194 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, | 1194 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type, |
| 1195 Register value) { | 1195 Register value) { |
| 1196 // Adjust this code if not the case. | 1196 // Adjust this code if not the case. |
| 1197 STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 1197 STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize); |
| 1198 | 1198 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
| 1199 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); |
| 1200 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); |
| 1201 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize); |
| 1202 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize); |
| 1199 // r0 is expected to hold the exception. | 1203 // r0 is expected to hold the exception. |
| 1200 if (!value.is(r0)) { | 1204 if (!value.is(r0)) { |
| 1201 mov(r0, value); | 1205 mov(r0, value); |
| 1202 } | 1206 } |
| 1203 | 1207 |
| 1204 // Drop sp to the top stack handler. | 1208 // Drop sp to the top stack handler. |
| 1205 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); | 1209 mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); |
| 1206 ldr(sp, MemOperand(r3)); | 1210 ldr(sp, MemOperand(r3)); |
| 1207 | 1211 |
| 1208 // Unwind the handlers until the ENTRY handler is found. | 1212 // Unwind the handlers until the ENTRY handler is found. |
| 1209 Label loop, done; | 1213 Label loop, done; |
| 1210 bind(&loop); | 1214 bind(&loop); |
| 1211 // Load the type of the current stack handler. | 1215 // Load the type of the current stack handler. |
| 1212 const int kStateOffset = StackHandlerConstants::kStateOffset; | 1216 const int kStateOffset = StackHandlerConstants::kStateOffset; |
| 1213 ldr(r2, MemOperand(sp, kStateOffset)); | 1217 ldr(r2, MemOperand(sp, kStateOffset)); |
| 1214 cmp(r2, Operand(StackHandler::ENTRY)); | 1218 cmp(r2, Operand(StackHandler::ENTRY)); |
| 1215 b(eq, &done); | 1219 b(eq, &done); |
| 1216 // Fetch the next handler in the list. | 1220 // Fetch the next handler in the list. |
| 1217 const int kNextOffset = StackHandlerConstants::kNextOffset; | 1221 const int kNextOffset = StackHandlerConstants::kNextOffset; |
| 1218 ldr(sp, MemOperand(sp, kNextOffset)); | 1222 ldr(sp, MemOperand(sp, kNextOffset)); |
| 1219 jmp(&loop); | 1223 jmp(&loop); |
| 1220 bind(&done); | 1224 bind(&done); |
| 1221 | 1225 |
| 1222 // Set the top handler address to next handler past the current ENTRY handler. | 1226 // Set the top handler address to next handler past the current ENTRY handler. |
| 1223 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | |
| 1224 pop(r2); | 1227 pop(r2); |
| 1225 str(r2, MemOperand(r3)); | 1228 str(r2, MemOperand(r3)); |
| 1226 | 1229 |
| 1227 if (type == OUT_OF_MEMORY) { | 1230 if (type == OUT_OF_MEMORY) { |
| 1228 // Set external caught exception to false. | 1231 // Set external caught exception to false. |
| 1229 ExternalReference external_caught( | 1232 ExternalReference external_caught( |
| 1230 Isolate::k_external_caught_exception_address, isolate()); | 1233 Isolate::k_external_caught_exception_address, isolate()); |
| 1231 mov(r0, Operand(false, RelocInfo::NONE)); | 1234 mov(r0, Operand(false, RelocInfo::NONE)); |
| 1232 mov(r2, Operand(external_caught)); | 1235 mov(r2, Operand(external_caught)); |
| 1233 str(r0, MemOperand(r2)); | 1236 str(r0, MemOperand(r2)); |
| 1234 | 1237 |
| 1235 // Set pending exception and r0 to out of memory exception. | 1238 // Set pending exception and r0 to out of memory exception. |
| 1236 Failure* out_of_memory = Failure::OutOfMemoryException(); | 1239 Failure* out_of_memory = Failure::OutOfMemoryException(); |
| 1237 mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 1240 mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
| 1238 mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, | 1241 mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 1239 isolate()))); | 1242 isolate()))); |
| 1240 str(r0, MemOperand(r2)); | 1243 str(r0, MemOperand(r2)); |
| 1241 } | 1244 } |
| 1242 | 1245 |
| 1243 // Stack layout at this point. See also StackHandlerConstants. | 1246 // Stack layout at this point. See also StackHandlerConstants. |
| 1244 // sp -> state (ENTRY) | 1247 // sp -> state (ENTRY) |
| 1248 // cp |
| 1245 // fp | 1249 // fp |
| 1246 // lr | 1250 // lr |
| 1247 | 1251 |
| 1248 // Discard handler state (r2 is not used) and restore frame pointer. | 1252 // Restore context and frame pointer, discard state (r2). |
| 1249 STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); | 1253 ldm(ia_w, sp, r2.bit() | cp.bit() | fp.bit()); |
| 1250 ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state. | |
| 1251 // Before returning we restore the context from the frame pointer if | |
| 1252 // not NULL. The frame pointer is NULL in the exception handler of a | |
| 1253 // JS entry frame. | |
| 1254 cmp(fp, Operand(0, RelocInfo::NONE)); | |
| 1255 // Set cp to NULL if fp is NULL. | |
| 1256 mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq); | |
| 1257 // Restore cp otherwise. | |
| 1258 ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); | |
| 1259 #ifdef DEBUG | 1254 #ifdef DEBUG |
| 1260 if (emit_debug_code()) { | 1255 if (emit_debug_code()) { |
| 1261 mov(lr, Operand(pc)); | 1256 mov(lr, Operand(pc)); |
| 1262 } | 1257 } |
| 1263 #endif | 1258 #endif |
| 1264 STATIC_ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); | |
| 1265 pop(pc); | 1259 pop(pc); |
| 1266 } | 1260 } |
| 1267 | 1261 |
| 1268 | 1262 |
| 1269 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1263 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
| 1270 Register scratch, | 1264 Register scratch, |
| 1271 Label* miss) { | 1265 Label* miss) { |
| 1272 Label same_contexts; | 1266 Label same_contexts; |
| 1273 | 1267 |
| 1274 ASSERT(!holder_reg.is(scratch)); | 1268 ASSERT(!holder_reg.is(scratch)); |
| (...skipping 1960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3235 void CodePatcher::EmitCondition(Condition cond) { | 3229 void CodePatcher::EmitCondition(Condition cond) { |
| 3236 Instr instr = Assembler::instr_at(masm_.pc_); | 3230 Instr instr = Assembler::instr_at(masm_.pc_); |
| 3237 instr = (instr & ~kCondMask) | cond; | 3231 instr = (instr & ~kCondMask) | cond; |
| 3238 masm_.emit(instr); | 3232 masm_.emit(instr); |
| 3239 } | 3233 } |
| 3240 | 3234 |
| 3241 | 3235 |
| 3242 } } // namespace v8::internal | 3236 } } // namespace v8::internal |
| 3243 | 3237 |
| 3244 #endif // V8_TARGET_ARCH_ARM | 3238 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |