Changeset 416
- Timestamp:
- Jan 28, 2004, 4:06:17 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/ccl/lisp-kernel/lisp-exceptions.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/lisp-kernel/lisp-exceptions.c
r174 r416 1187 1187 do_tsp_overflow (ExceptionInformation *xp, BytePtr addr) 1188 1188 { 1189 TCR *tcr = (TCR *)xpGPR(xp, rcontext); 1190 area *first_a = tcr->ts_area; 1191 area *a = first_a, *new_a, *maybe_new_a; 1192 BytePtr tspPtr = (BytePtr) xpGPR(xp, tsp); 1193 int frame_size = tspPtr - addr; 1194 BytePtr new_tsp; 1195 pc where = xpPC(xp); 1196 opcode instruction = *where; 1197 1198 preserved_registers pr; 1199 1200 sample_preserved_registers(xp, &pr); 1201 1202 if ((frame_size > TSTACK_SOFTPROT) || (frame_size < 0)) { 1203 Bug(xp, "TSP frame size out of range"); 1204 }; 1205 1206 for (; a && ((a->low > tspPtr) || (a->high < tspPtr)); a = a->older) { 1207 }; 1208 if (!a) 1209 Bug(xp, "Can't find TSP area"); 1210 1211 new_a = maybe_new_a = a->younger; 1212 1213 /* If no existing segment, allocate a new one */ 1214 if (! new_a) { 1215 #ifdef EXTEND_VSTACK 1216 new_a = allocate_area_with_c_gc_context(xp, allocate_tstack, MIN_TSTACK_SIZE); 1217 #endif 1218 if (! new_a) 1219 return do_hard_stack_overflow(xp, NULL, NULL); 1220 new_a->older = a; 1221 a->younger = new_a; 1222 }; 1223 1224 tcr->ts_area = new_a; 1225 a->active = tspPtr; 1226 new_tsp = new_a->high - frame_size; 1227 1228 /* Emulate current instruction, which must be a stwu or stwux */ 1229 if ((major_opcode_p(instruction, major_opcode_STWU) || 1230 X_opcode_p(instruction, major_opcode_X31, minor_opcode_STWUX)) && 1231 (RA_field(instruction) == tsp)) { 1232 /* (stwu rs D tsp) or (stwux rs tsp rb) */ 1233 LispObj *tspP = (LispObj *) new_tsp; 1234 unsigned reg = RS_field(instruction); 1235 1236 *tspP = xpGPR(xp, reg); 1237 xpPC(xp) += 1; 1238 } else { 1239 Bug(xp, "Instruction causing TSP overflow not stwu or stwux"); 1240 }; 1241 1242 /* Update the tsp. This must happen after the stwu has been emulated, so the 1243 link will work correctly 1244 */ 1245 xpGPR(xp, tsp) = (LispObj) new_tsp; 1246 new_a->active = new_tsp; /* Not really necessary */ 1247 1248 /* Don't signal an error if we found an existing segment. 1249 Unlike the VSP, this is not functionally important, but 1250 it has a noticeable performance impact. 1251 Also, don't signal an error if nilreg is not NIL. This happens 1252 when .SPcallback allocates a TSP frame to save the C saved registers. 1253 */ 1254 if ((maybe_new_a == NULL) && ((((unsigned) nrs_GC_EVENT_STATUS_BITS.vcell) & gc_allow_stack_overflows_bit) == 0)) { 1255 handle_error(xp, error_stack_overflow, tsp, 0, (unsigned) xpPC(xp)); 1256 }; 1257 1258 return 0; /* if we ever return. */ 1189 TCR* tcr = (TCR *) xpGPR(xp, rcontext); 1190 area *a = tcr->ts_area; 1191 protected_area_ptr tsp_soft = a->softprot; 1192 unprotect_area(tsp_soft); 1193 signal_stack_soft_overflow(xp,tsp); 1194 return 0; 1259 1195 } 1260 1196
Note:
See TracChangeset
for help on using the changeset viewer.
