Changeset 416


Ignore:
Timestamp:
Jan 28, 2004, 4:06:17 PM (21 years ago)
Author:
Gary Byers
Message:

kinder, gentler do_tsp_overflow

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/lisp-exceptions.c

    r174 r416  
    11871187do_tsp_overflow (ExceptionInformation *xp, BytePtr addr)
    11881188{
    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;
    12591195}
    12601196
Note: See TracChangeset for help on using the changeset viewer.