Changeset 6526


Ignore:
Timestamp:
May 9, 2007, 8:59:10 AM (15 years ago)
Author:
gb
Message:

New tra handling.
new_heap_segment: try to avoid requesting too much when user sets
lisp_heap_gc_threshold to inappropriate value.
Pass old_valence down to fault handler, don't call out to lisp
on faults in foreign code.
Handle USE_MACH_EXCEPTION_LOCK conditionalization.

File:
1 edited

Legend:

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

    r6275 r6526  
    7878  if (newlimit > (natural) (a->high)) {
    7979    if (extend) {
    80       if (! resize_dynamic_heap(a->active, (newlimit-oldlimit)+lisp_heap_gc_threshold)) {
    81         return false;
    82       }
     80      natural extend_by = lisp_heap_gc_threshold;
     81      do {
     82        if (resize_dynamic_heap(a->active, (newlimit-oldlimit)+extend_by)) {
     83          break;
     84        }
     85        extend_by = align_to_power_of_2(extend_by>>1,log2_allocation_quantum);
     86        if (extend_by < 4<<20) {
     87          return false;
     88        }
     89      } while (1);
    8390    } else {
    8491      return false;
     
    316323  tra = xpGPR(xp,Ira0);
    317324  if (tag_of(tra) == tag_tra) {
    318     tra_f = tra - ((int *)tra)[-1];
     325    if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
     326        (*((unsigned char *)(tra+2)) == RECOVER_FN_FROM_RIP_BYTE2)) {
     327      int sdisp = (*(int *) (tra+3));
     328      tra_f = RECOVER_FN_FROM_RIP_LENGTH+tra+sdisp;
     329    }
    319330    if (fulltag_of(tra_f) != fulltag_function) {
    320331      tra_f = 0;
     
    566577
    567578Boolean
    568 handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
     579handle_fault(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
    569580{
    570581#ifdef FREEBSD
     
    587598    }
    588599  }
    589   {
    590     LispObj xcf = create_exception_callback_frame(xp),
    591       cmain = nrs_CMAIN.vcell;
    592     callback_to_lisp(tcr, cmain, xp, xcf, SIGBUS, is_write_fault(xp,info), (natural)addr, 0);
     600  if (old_valence == TCR_STATE_LISP) {
     601    LispObj cmain = nrs_CMAIN.vcell,
     602      xcf;
     603    if ((fulltag_of(cmain) == fulltag_misc) &&
     604      (header_subtag(header_of(cmain)) == subtag_macptr)) {
     605      xcf = create_exception_callback_frame(xp);
     606      callback_to_lisp(tcr, cmain, xp, xcf, SIGBUS, is_write_fault(xp,info), (natural)addr, 0);
     607    }
    593608  }
    594609  return false;
     
    719734
    720735Boolean
    721 handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr)
     736handle_exception(int signum, siginfo_t *info, ExceptionInformation  *context, TCR *tcr, int old_valence)
    722737{
    723738  pc program_counter = (pc)xpPC(context);
     
    770785
    771786    } else {
    772       return handle_fault(tcr, context, info);
     787      return handle_fault(tcr, context, info, old_valence);
    773788    }
    774789    break;
     
    824839#if SIGBUS != SIGNUM_FOR_INTN_TRAP
    825840  case SIGBUS:
    826     return handle_fault(tcr, context, info);
     841    return handle_fault(tcr, context, info, old_valence);
    827842#endif
    828843   
    829844#if SIGSEGV != SIGNUM_FOR_INTN_TRAP
    830845  case SIGSEGV:
    831     return handle_fault(tcr, context, info);
     846    return handle_fault(tcr, context, info, old_valence);
    832847#endif   
    833848   
     
    924939
    925940
    926   if (! handle_exception(signum, info, context, tcr)) {
     941  if (! handle_exception(signum, info, context, tcr, old_valence)) {
    927942    char msg[512];
    928943
     
    10411056
    10421057#ifdef DARWIN
    1043 /*
    1044    There seems to be a problem with thread-level exception handling;
    1045    Mach seems (under some cirumstances) to conclude that there's
    1046    no thread-level handler and exceptions get passed up to a
    1047    handler that raises Un*x signals.  Ignore those signals so that
    1048    the exception will repropagate and eventually get caught by
    1049    catch_exception_raise() at the thread level.
    1050 
    1051    Mach sucks, but no one understands how.
    1052 */
    1053 void
    1054 bogus_signal_handler()
    1055 {
    1056   /* This does nothing, but does it with signals masked */
     1058void
     1059bogus_signal_handler(int signum, siginfo_t *info, ExceptionInformation *xp)
     1060{
     1061  if (signum == SIGSYS) {
     1062    return;                     /* Leopard lossage */
     1063  }
    10571064}
    10581065#endif
     
    11601167        old_valence = prepare_to_wait_for_exception_lock(tcr, context);
    11611168        wait_for_exception_lock_in_handler(tcr, context, &xframe_link);
    1162         handle_exception(signum, info, context, tcr);
     1169        handle_exception(signum, info, context, tcr, old_valence);
    11631170        if (alloc_displacement) {
    11641171          tcr->save_allocptr -= alloc_displacement;
     
    17291736      }
    17301737    }
    1731     xpPC(xp) = xpGPR(xp,Ira0);
     1738    {
     1739      /* These subprimitives are called via CALL/RET; need
     1740         to pop the return address off the stack and set
     1741         the PC there. */
     1742      LispObj *rsp = (LispObj *)xpGPR(xp,Isp), ra = *rsp++;
     1743      xpPC(xp) = ra;
     1744      xpGPR(xp,Isp)=(LispObj)rsp;
     1745    }
    17321746    return;
    17331747  }
     
    19001914#define TCR_TO_EXCEPTION_PORT(tcr) ((mach_port_t)((natural)(tcr)))
    19011915
     1916#if USE_MACH_EXCEPTION_LOCK
    19021917pthread_mutex_t _mach_exception_lock, *mach_exception_lock;
     1918#endif
    19031919extern void pseudo_sigreturn(void);
    19041920
     
    22762292#endif
    22772293
     2294
    22782295kern_return_t
    22792296catch_exception_raise(mach_port_t exception_port,
     
    22952312
    22962313
     2314
    22972315#ifdef DEBUG_MACH_EXCEPTIONS
    22982316  fprintf(stderr, "obtaining Mach exception lock in exception thread\n");
     
    23002318
    23012319
    2302   if (pthread_mutex_trylock(mach_exception_lock) == 0) {
     2320  if (
     2321#if USE_MACH_EXCEPTION_LOCK
     2322      pthread_mutex_trylock(mach_exception_lock) == 0
     2323#else
     2324      1
     2325#endif
     2326      ) {
    23032327#ifdef X8664
    2304     thread_state_count = x86_THREAD_STATE64_COUNT;
    2305     call_kret = thread_get_state(thread,
    2306                                  x86_THREAD_STATE64,
    2307                                  (thread_state_t)&ts,
    2308                      &thread_state_count);
     2328    do {
     2329      thread_state_count = x86_THREAD_STATE64_COUNT;
     2330      call_kret = thread_get_state(thread,
     2331                                   x86_THREAD_STATE64,
     2332                                   (thread_state_t)&ts,
     2333                                   &thread_state_count);
     2334    } while (call_kret == KERN_ABORTED);
    23092335  MACH_CHECK_ERROR("getting thread state",call_kret);
    23102336#else
     
    23442370        }
    23452371        break;
    2346      
     2372         
    23472373      case EXC_SOFTWARE:
    2348           signum = SIGILL;
     2374        signum = SIGILL;
    23492375        break;
    2350      
     2376       
    23512377      case EXC_ARITHMETIC:
    23522378        signum = SIGFPE;
    23532379        break;
    2354 
     2380       
    23552381      default:
    23562382        break;
     
    23642390                                  &ts);
    23652391#if 0
    2366       fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr);
    2367 #endif
    2368 
     2392        fprintf(stderr, "Setup pseudosignal handling in 0x%x\n",tcr);
     2393#endif
     2394       
    23692395      } else {
    23702396        kret = 17;
    23712397      }
    23722398    }
     2399#if USE_MACH_EXCEPTION_LOCK
    23732400#ifdef DEBUG_MACH_EXCEPTIONS
    23742401    fprintf(stderr, "releasing Mach exception lock in exception thread\n");
    23752402#endif
    23762403    pthread_mutex_unlock(mach_exception_lock);
     2404#endif
    23772405  } else {
    23782406    SET_TCR_FLAG(tcr,TCR_FLAG_BIT_PENDING_EXCEPTION);
     
    23812409    fprintf(stderr, "deferring pending exception in 0x%x\n", tcr);
    23822410#endif
    2383     kret = 0;
     2411    kret = KERN_SUCCESS;
    23842412    if (tcr == gc_tcr) {
    23852413      int i;
     
    24372465  kern_return_t kret; 
    24382466  if (__exception_port_set == MACH_PORT_NULL) {
     2467#if USE_MACH_EXCEPTION_LOCK
    24392468    mach_exception_lock = &_mach_exception_lock;
    24402469    pthread_mutex_init(mach_exception_lock, NULL);
     2470#endif
    24412471
    24422472    kret = mach_port_allocate(mach_task_self(),
Note: See TracChangeset for help on using the changeset viewer.