Index: /trunk/source/lisp-kernel/memory.c
===================================================================
--- /trunk/source/lisp-kernel/memory.c	(revision 15461)
+++ /trunk/source/lisp-kernel/memory.c	(revision 15462)
@@ -1006,4 +1006,9 @@
   efficient and thread-safe mapping from port to TCR.  Soon.
 
+  News flash:  mach_port_allocate_name() is not only worse than we
+  imagine on 10.8, but it's worse than we can imagine.  Give up.
+  (This means that there are no longer any constraints on TCR addresses
+  and we could just use malloc here, but keep some of this code around
+  for now.)
 */
 
@@ -1015,97 +1020,51 @@
 but not so much that we waste lots of 32-bit memory. */
 
-#define LIMIT_32_BIT (natural)(0x09800000)
-
-#undef vm_region
-
-void
-link_tcr_list(TCR *head, TCR *buf, int n)
-{
+
+
+
+/* force 16-bit alignment, just in case */
+typedef struct {
+  TCR tcr;
+}  __attribute__ ((aligned(16))) MTCR;
+
+
+
+void
+link_tcr_list(TCR *head, MTCR *buf, int n)
+{
+  TCR *prev = head, *tcr;
+  int i;
+
+  for (i=0; i < n; i++, buf++) {
+    tcr = &(buf->tcr);
+    prev->next = tcr;
+    tcr->prev = prev;
+    head->prev = tcr;
+    tcr->next = head;
+    prev = tcr;
+  }
+}
+
+
+
+
+void
+map_tcr_cluster(TCR *head)
+{
+  MTCR *work = NULL;
   TCR *prev = head;
   int i;
-
-  for (i=0; i < n; i++, buf++) {
-    prev->next = buf;
-    buf->prev = prev;
-    head->prev = buf;
-    buf->next = head;
-    prev = buf;
-  }
-}
-
-TCR initial_tcrs[TCR_CLUSTER_COUNT];
-
-void
-map_tcr_cluster(TCR *head)
-{
-  TCR *work = NULL, *prev = head;
-  int i;
-  vm_address_t addr = (vm_address_t)0, nextaddr;
-  void *p;
-  vm_size_t request_size = align_to_power_of_2((TCR_CLUSTER_COUNT*sizeof(TCR)),log2_page_size), vm_size;
-#if WORD_SIZE==64
-  vm_region_basic_info_data_64_t vm_info;
-  mach_msg_type_number_t vm_info_size = VM_REGION_BASIC_INFO_COUNT_64;
-#else
-  vm_region_basic_info_data_t vm_info;
-  mach_msg_type_number_t vm_info_size = VM_REGION_BASIC_INFO_COUNT;
-#endif
-  mach_port_t vm_object_name = (mach_port_t) 0;
-  kern_return_t kret;
-
-  while (1) {
-    nextaddr = addr;
-#if WORD_SIZE==64
-    vm_info_size = VM_REGION_BASIC_INFO_COUNT_64;
-    kret = vm_region_64(mach_task_self(),
-                        &nextaddr,
-                        &vm_size,
-                        VM_REGION_BASIC_INFO_64,
-                        (vm_region_info_t)&vm_info,
-                        &vm_info_size,
-                        &vm_object_name);
-#else
-    vm_info_size = VM_REGION_BASIC_INFO_COUNT;
-    kret = vm_region(mach_task_self(),
-                     &nextaddr,
-                     &vm_size,
-                     VM_REGION_BASIC_INFO,
-                     (vm_region_info_t)&vm_info,
-                     &vm_info_size,
-                     &vm_object_name);
-#endif
-    if (kret != KERN_SUCCESS) {
-      break;
-    }
-    if (addr && ((nextaddr - addr) > request_size)) {
-      if ((addr + request_size) > LIMIT_32_BIT) {
-        break;
-      }
-      p = mmap((void *)addr,
-               request_size,
-               PROT_READ|PROT_WRITE,
-               MAP_PRIVATE|MAP_ANON,
-               -1,
-               0);
-      if (p == MAP_FAILED) {
-        break;
-      } else {
-        if (((natural)p > LIMIT_32_BIT) ||
-            ((((natural)p)+request_size) > LIMIT_32_BIT)) {
-          munmap(p, request_size);
-          nextaddr = 0;
-          vm_size = 0;
-        } else {
-          work = (TCR *) p;
-          break;
-        }
-      }
-    }
-    addr = nextaddr + vm_size;    
-  }
+  size_t request_size = align_to_power_of_2((TCR_CLUSTER_COUNT*sizeof(MTCR)),log2_page_size);
+
+  work = (MTCR *)mmap(NULL,
+                      request_size,
+                      PROT_READ|PROT_WRITE,
+                      MAP_PRIVATE|MAP_ANON,
+                      -1,
+                      0);
+
   if (!work) {
     Fatal("Can't allocate memory for thread-local storage.", "");
   }
-  
   link_tcr_list(head, work, TCR_CLUSTER_COUNT);
 }
@@ -1125,4 +1084,5 @@
 }
 
+
 TCR *
 darwin_allocate_tcr()
@@ -1132,5 +1092,4 @@
   if (head->next == NULL) { /* First time */
     head->next = head->prev = head;
-    link_tcr_list(head,initial_tcrs,TCR_CLUSTER_COUNT);
   }
 
Index: /trunk/source/lisp-kernel/thread_manager.c
===================================================================
--- /trunk/source/lisp-kernel/thread_manager.c	(revision 15461)
+++ /trunk/source/lisp-kernel/thread_manager.c	(revision 15462)
@@ -826,5 +826,5 @@
 allocate_tcr()
 {
-  TCR *tcr, *chain = NULL, *next;
+  TCR *tcr,  *next;
 #ifdef DARWIN
   extern Boolean use_mach_exception_handling;
@@ -846,26 +846,15 @@
 #ifdef DARWIN
     if (use_mach_exception_handling) {
-      thread_exception_port = (mach_port_t)((natural)tcr);
-      kret = mach_port_allocate_name(task_self,
-                                     MACH_PORT_RIGHT_RECEIVE,
-                                     thread_exception_port);
-    } else {
-      kret = KERN_SUCCESS;
-    }
-
-    if (kret != KERN_SUCCESS) {
-      tcr->next = chain;
-      chain = tcr;
-      continue;
-    }
-#endif
-    for (;chain;chain = next) {
-      next = chain->next;
-#ifdef DARWIN
-      darwin_free_tcr(chain);
-#else
-      free(chain);
-#endif
-    }
+      if (mach_port_allocate(task_self,
+                             MACH_PORT_RIGHT_RECEIVE,
+                             &thread_exception_port) == KERN_SUCCESS) {
+        tcr->io_datum = (void *)thread_exception_port;
+        associate_tcr_with_exception_port(thread_exception_port,tcr);
+      } else {
+        Fatal("Can't allocate Mach exception port for thread.", "");
+      }
+    }
+
+#endif
     return tcr;
   }
Index: /trunk/source/lisp-kernel/x86-exceptions.c
===================================================================
--- /trunk/source/lisp-kernel/x86-exceptions.c	(revision 15461)
+++ /trunk/source/lisp-kernel/x86-exceptions.c	(revision 15462)
@@ -2936,6 +2936,7 @@
 #endif
 
-#define TCR_FROM_EXCEPTION_PORT(p) ((TCR *)((natural)p))
-#define TCR_TO_EXCEPTION_PORT(tcr) ((mach_port_t)((natural)(tcr)))
+#define TCR_FROM_EXCEPTION_PORT(p) find_tcr_from_exception_port(p)
+#define TCR_TO_EXCEPTION_PORT(t) (mach_port_name_t)(((TCR *)t)->io_datum)
+
 
 extern void pseudo_sigreturn(void);
@@ -3262,4 +3263,58 @@
 #define DARWIN_EXCEPTION_HANDLER signal_handler
 
+#define EXCEPTION_PORT_BUCKETS 109
+
+TCR *
+exception_port_map[EXCEPTION_PORT_BUCKETS];
+
+pthread_mutex_t 
+exception_port_map_lock = PTHREAD_MUTEX_INITIALIZER;
+
+TCR *
+find_tcr_from_exception_port(mach_port_t port)
+{
+  TCR *tcr = NULL;
+  pthread_mutex_lock(&exception_port_map_lock);
+
+  tcr = exception_port_map[(unsigned)port % EXCEPTION_PORT_BUCKETS];
+
+  while (tcr) {
+    if (TCR_TO_EXCEPTION_PORT(tcr) == port) {
+      break;
+    }
+    tcr = (TCR *)tcr->pending_io_info;
+  }
+  pthread_mutex_unlock(&exception_port_map_lock);
+  return tcr;
+}
+
+void
+associate_tcr_with_exception_port(mach_port_t port, TCR *tcr)
+{
+  int b = (unsigned)port % EXCEPTION_PORT_BUCKETS;
+  pthread_mutex_lock(&exception_port_map_lock);
+
+  tcr->pending_io_info = (void *)(exception_port_map[b]);
+  exception_port_map[b] = tcr;
+  pthread_mutex_unlock(&exception_port_map_lock);
+}
+
+void
+disassociate_tcr_from_exception_port(mach_port_t port)
+{
+  TCR **prev = &(exception_port_map[(unsigned)port % EXCEPTION_PORT_BUCKETS]),
+    *tcr;
+  pthread_mutex_lock(&exception_port_map_lock);
+
+  while((tcr = *prev) != NULL) {
+    if (TCR_TO_EXCEPTION_PORT(tcr) == port) {
+      *prev = (TCR *)tcr->pending_io_info;
+      break;
+    }
+    prev = (TCR **)&(tcr->pending_io_info);
+  }
+  pthread_mutex_unlock(&exception_port_map_lock);
+}
+  
 
 kern_return_t
@@ -3394,5 +3449,5 @@
 {
   extern boolean_t exc_server();
-  mach_port_t p = TCR_TO_EXCEPTION_PORT(arg);
+  mach_port_t p = (mach_port_t)arg;
 
   mach_exception_thread = pthread_mach_thread_np(pthread_self());
@@ -3598,6 +3653,10 @@
   }
   if (use_mach_exception_handling) {
-    mach_port_deallocate(mach_task_self(),TCR_TO_EXCEPTION_PORT(tcr));
-    mach_port_destroy(mach_task_self(),TCR_TO_EXCEPTION_PORT(tcr));
+    mach_port_t task_self = mach_task_self(),
+      exception_port = TCR_TO_EXCEPTION_PORT(tcr);
+
+    disassociate_tcr_from_exception_port(exception_port);
+    mach_port_deallocate(task_self,exception_port);
+    mach_port_destroy(task_self,exception_port);
   }
 }
Index: /trunk/source/lisp-kernel/x86-exceptions.h
===================================================================
--- /trunk/source/lisp-kernel/x86-exceptions.h	(revision 15461)
+++ /trunk/source/lisp-kernel/x86-exceptions.h	(revision 15462)
@@ -86,4 +86,16 @@
 void callback_for_gc_notification(ExceptionInformation *xp, TCR *tcr);
 
+#ifdef DARWIN
+TCR *
+find_tcr_from_exception_port(mach_port_t);
+
+void
+associate_tcr_with_exception_port(mach_port_t, TCR *);
+
+void
+disassociate_tcr_from_exception_port(mach_port_t);
+#endif
+
+
 #endif /* X86_EXCEPTIONS_H */
 
