Index: /trunk/ccl/lisp-kernel/x86-exceptions.c
===================================================================
--- /trunk/ccl/lisp-kernel/x86-exceptions.c	(revision 6525)
+++ /trunk/ccl/lisp-kernel/x86-exceptions.c	(revision 6526)
@@ -78,7 +78,14 @@
   if (newlimit > (natural) (a->high)) {
     if (extend) {
-      if (! resize_dynamic_heap(a->active, (newlimit-oldlimit)+lisp_heap_gc_threshold)) {
-        return false;
-      }
+      natural extend_by = lisp_heap_gc_threshold;
+      do {
+        if (resize_dynamic_heap(a->active, (newlimit-oldlimit)+extend_by)) {
+          break;
+        }
+        extend_by = align_to_power_of_2(extend_by>>1,log2_allocation_quantum);
+        if (extend_by < 4<<20) {
+          return false;
+        }
+      } while (1);
     } else {
       return false;
@@ -316,5 +323,9 @@
   tra = xpGPR(xp,Ira0);
   if (tag_of(tra) == tag_tra) {
-    tra_f = tra - ((int *)tra)[-1];
+    if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
+        (*((unsigned char *)(tra+2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
+      int sdisp = (*(int *) (tra+3));
+      tra_f = RECOVER_FN_FROM_RIP_LENGTH+tra+sdisp;
+    }
     if (fulltag_of(tra_f) != fulltag_function) {
       tra_f = 0;
@@ -566,5 +577,5 @@
 
 Boolean
-handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
+handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
 {
 #ifdef FREEBSD
@@ -587,8 +598,12 @@
     }
   }
-  {
-    LispObj xcf = create_exception_callback_frame(xp),
-      cmain = nrs_CMAIN.vcell;
-    callback_to_lisp(tcr, cmain, xp, xcf, SIGBUS, is_write_fault(xp,info), (natural)addr, 0);
+  if (old_valence == TCR_STATE_LISP) {
+    LispObj cmain = nrs_CMAIN.vcell,
+      xcf;
+    if ((fulltag_of(cmain) == fulltag_misc) &&
+      (header_subtag(header_of(cmain)) == subtag_macptr)) {
+      xcf = create_exception_callback_frame(xp);
+      callback_to_lisp(tcr, cmain, xp, xcf, SIGBUS, is_write_fault(xp,info), (natural)addr, 0);
+    }
   }
   return false;
@@ -719,5 +734,5 @@
 
 Boolean
-handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr)
+handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr, int old_valence)
 {
   pc program_counter = (pc)xpPC(context);
@@ -770,5 +785,5 @@
 
     } else {
-      return handle_fault(tcr, context, info);
+      return handle_fault(tcr, context, info, old_valence);
     }
     break;
@@ -824,10 +839,10 @@
 #if SIGBUS != SIGNUM_FOR_INTN_TRAP
   case SIGBUS:
-    return handle_fault(tcr, context, info);
+    return handle_fault(tcr, context, info, old_valence);
 #endif
     
 #if SIGSEGV != SIGNUM_FOR_INTN_TRAP
   case SIGSEGV:
-    return handle_fault(tcr, context, info);
+    return handle_fault(tcr, context, info, old_valence);
 #endif    
     
@@ -924,5 +939,5 @@
 
 
-  if (! handle_exception(signum, info, context, tcr)) {
+  if (! handle_exception(signum, info, context, tcr, old_valence)) {
     char msg[512];
 
@@ -1041,18 +1056,10 @@
 
 #ifdef DARWIN
-/* 
-   There seems to be a problem with thread-level exception handling;
-   Mach seems (under some cirumstances) to conclude that there's
-   no thread-level handler and exceptions get passed up to a
-   handler that raises Un*x signals.  Ignore those signals so that
-   the exception will repropagate and eventually get caught by
-   catch_exception_raise() at the thread level.
-
-   Mach sucks, but no one understands how.
-*/
-void
-bogus_signal_handler()
-{
-  /* This does nothing, but does it with signals masked */
+void
+bogus_signal_handler(int signum, siginfo_t *info, ExceptionInformation *xp)
+{
+  if (signum == SIGSYS) {
+    return;                     /* Leopard lossage */
+  }
 }
 #endif
@@ -1160,5 +1167,5 @@
         old_valence = prepare_to_wait_for_exception_lock(tcr, context);
         wait_for_exception_lock_in_handler(tcr, context, &xframe_link);
-        handle_exception(signum, info, context, tcr);
+        handle_exception(signum, info, context, tcr, old_valence);
         if (alloc_displacement) {
           tcr->save_allocptr -= alloc_displacement;
@@ -1729,5 +1736,12 @@
       }
     }
-    xpPC(xp) = xpGPR(xp,Ira0);
+    {
+      /* These subprimitives are called via CALL/RET; need
+         to pop the return address off the stack and set
+         the PC there. */
+      LispObj *rsp = (LispObj *)xpGPR(xp,Isp), ra = *rsp++;
+      xpPC(xp) = ra;
+      xpGPR(xp,Isp)=(LispObj)rsp;
+    }
     return;
   }
@@ -1900,5 +1914,7 @@
 #define TCR_TO_EXCEPTION_PORT(tcr) ((mach_port_t)((natural)(tcr)))
 
+#if USE_MACH_EXCEPTION_LOCK
 pthread_mutex_t _mach_exception_lock, *mach_exception_lock;
+#endif
 extern void pseudo_sigreturn(void);
 
@@ -2276,4 +2292,5 @@
 #endif
 
+
 kern_return_t
 catch_exception_raise(mach_port_t exception_port,
@@ -2295,4 +2312,5 @@
 
 
+
 #ifdef DEBUG_MACH_EXCEPTIONS
   fprintf(stderr, "obtaining Mach exception lock in exception thread\n");
@@ -2300,11 +2318,19 @@
 
 
-  if (pthread_mutex_trylock(mach_exception_lock) == 0) {
+  if (
+#if USE_MACH_EXCEPTION_LOCK
+      pthread_mutex_trylock(mach_exception_lock) == 0
+#else
+      1
+#endif
+      ) {
 #ifdef X8664
-    thread_state_count = x86_THREAD_STATE64_COUNT;
-    call_kret = thread_get_state(thread,
-                                 x86_THREAD_STATE64,
-                                 (thread_state_t)&ts,
-                     &thread_state_count);
+    do {
+      thread_state_count = x86_THREAD_STATE64_COUNT;
+      call_kret = thread_get_state(thread,
+                                   x86_THREAD_STATE64,
+                                   (thread_state_t)&ts,
+                                   &thread_state_count);
+    } while (call_kret == KERN_ABORTED);
   MACH_CHECK_ERROR("getting thread state",call_kret);
 #else
@@ -2344,13 +2370,13 @@
         }
         break;
-      
+          
       case EXC_SOFTWARE:
-          signum = SIGILL;
+        signum = SIGILL;
         break;
-      
+        
       case EXC_ARITHMETIC:
         signum = SIGFPE;
         break;
-
+        
       default:
         break;
@@ -2364,15 +2390,17 @@
                                   &ts);
 #if 0
-      fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr);
-#endif
-
+        fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr);
+#endif
+        
       } else {
         kret = 17;
       }
     }
+#if USE_MACH_EXCEPTION_LOCK
 #ifdef DEBUG_MACH_EXCEPTIONS
     fprintf(stderr, "releasing Mach exception lock in exception thread\n");
 #endif
     pthread_mutex_unlock(mach_exception_lock);
+#endif
   } else {
     SET_TCR_FLAG(tcr,TCR_FLAG_BIT_PENDING_EXCEPTION);
@@ -2381,5 +2409,5 @@
     fprintf(stderr, "deferring pending exception in 0x%x\n", tcr);
 #endif
-    kret = 0;
+    kret = KERN_SUCCESS;
     if (tcr == gc_tcr) {
       int i;
@@ -2437,6 +2465,8 @@
   kern_return_t kret;  
   if (__exception_port_set == MACH_PORT_NULL) {
+#if USE_MACH_EXCEPTION_LOCK
     mach_exception_lock = &_mach_exception_lock;
     pthread_mutex_init(mach_exception_lock, NULL);
+#endif
 
     kret = mach_port_allocate(mach_task_self(),
