View | Details | Return to bug 10746 | Differences between
and this patch

Collapse All | Expand All

(-)mark.c (-28 / +139 lines)
Lines 19-24 Link Here
19
# include <stdio.h>
19
# include <stdio.h>
20
# include "private/gc_pmark.h"
20
# include "private/gc_pmark.h"
21
21
22
#if defined(MSWIN32) && defined(__GNUC__)
23
# include <excpt.h>
24
#endif
25
22
/* We put this here to minimize the risk of inlining. */
26
/* We put this here to minimize the risk of inlining. */
23
/*VARARGS*/
27
/*VARARGS*/
24
#ifdef __WATCOMC__
28
#ifdef __WATCOMC__
Lines 261-280 Link Here
261
/* remains valid until all marking is complete.		*/
265
/* remains valid until all marking is complete.		*/
262
/* A zero value indicates that it's OK to miss some	*/
266
/* A zero value indicates that it's OK to miss some	*/
263
/* register values.					*/
267
/* register values.					*/
264
GC_bool GC_mark_some(cold_gc_frame)
268
/* We hold the allocation lock.  In the case of 	*/
265
ptr_t cold_gc_frame;
269
/* incremental collection, the world may not be stopped.*/
270
#ifdef MSWIN32
271
  /* For win32, this is called after we establish a structured	*/
272
  /* exception handler, in case Windows unmaps one of our root	*/
273
  /* segments.  See below.  In either case, we acquire the 	*/
274
  /* allocator lock long before we get here.			*/
275
  GC_bool GC_mark_some_inner(cold_gc_frame)
276
  ptr_t cold_gc_frame;
277
#else
278
  GC_bool GC_mark_some(cold_gc_frame)
279
  ptr_t cold_gc_frame;
280
#endif
266
{
281
{
267
#if defined(MSWIN32) && !defined(__GNUC__)
268
  /* Windows 98 appears to asynchronously create and remove writable	*/
269
  /* memory mappings, for reasons we haven't yet understood.  Since	*/
270
  /* we look for writable regions to determine the root set, we may	*/
271
  /* try to mark from an address range that disappeared since we 	*/
272
  /* started the collection.  Thus we have to recover from faults here. */
273
  /* This code does not appear to be necessary for Windows 95/NT/2000.	*/ 
274
  /* Note that this code should never generate an incremental GC write	*/
275
  /* fault.								*/
276
  __try {
277
#endif /* defined(MSWIN32) && !defined(__GNUC__) */
278
    switch(GC_mark_state) {
282
    switch(GC_mark_state) {
279
    	case MS_NONE:
283
    	case MS_NONE:
280
    	    return(FALSE);
284
    	    return(FALSE);
Lines 395-417 Link Here
395
    	    ABORT("GC_mark_some: bad state");
399
    	    ABORT("GC_mark_some: bad state");
396
    	    return(FALSE);
400
    	    return(FALSE);
397
    }
401
    }
398
#if defined(MSWIN32) && !defined(__GNUC__)
402
}
399
  } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
403
400
	    EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
404
401
#   ifdef CONDPRINT
405
#ifdef MSWIN32
402
      if (GC_print_stats) {
406
403
	GC_printf0("Caught ACCESS_VIOLATION in marker. "
407
# ifdef __GNUC__
404
		   "Memory mapping disappeared.\n");
408
409
    typedef struct {
410
      EXCEPTION_REGISTRATION ex_reg;
411
      void *alt_path;
412
    } ext_ex_regn;
413
414
415
    static EXCEPTION_DISPOSITION mark_ex_handler(
416
        struct _EXCEPTION_RECORD *ex_rec, 
417
        void *est_frame,
418
        struct _CONTEXT *context,
419
        void *disp_ctxt)
420
    {
421
        if (ex_rec->ExceptionCode == STATUS_ACCESS_VIOLATION) {
422
          ext_ex_regn *xer = (ext_ex_regn *)est_frame;
423
424
          /* Unwind from the inner function assuming the standard */
425
          /* function prologue.                                   */
426
          /* Assumes code has not been compiled with              */
427
          /* -fomit-frame-pointer.                                */
428
          context->Esp = context->Ebp;
429
          context->Ebp = *((DWORD *)context->Esp);
430
          context->Esp = context->Esp - 8;
431
432
          /* Resume execution at the "real" handler within the    */
433
          /* wrapper function.                                    */
434
          context->Eip = (DWORD )(xer->alt_path);
435
436
          return ExceptionContinueExecution;
437
438
        } else {
439
            return ExceptionContinueSearch;
440
        }
441
    }
442
# endif /* __GNUC__ */
443
444
445
  GC_bool GC_mark_some(cold_gc_frame)
446
  ptr_t cold_gc_frame;
447
  {
448
      GC_bool ret_val;
449
450
#   ifndef __GNUC__
451
      /* Windows 98 appears to asynchronously create and remove  */
452
      /* writable memory mappings, for reasons we haven't yet    */
453
      /* understood.  Since we look for writable regions to      */
454
      /* determine the root set, we may try to mark from an      */
455
      /* address range that disappeared since we started the     */
456
      /* collection.  Thus we have to recover from faults here.  */
457
      /* This code does not appear to be necessary for Windows   */
458
      /* 95/NT/2000. Note that this code should never generate   */
459
      /* an incremental GC write fault.                          */
460
461
      __try {
462
463
#   else /* __GNUC__ */
464
465
      /* Manually install an exception handler since GCC does    */
466
      /* not yet support Structured Exception Handling (SEH) on  */
467
      /* Win32.                                                  */
468
469
      ext_ex_regn er;
470
471
      er.alt_path = &&handle_ex;
472
      er.ex_reg.handler = mark_ex_handler;
473
      asm volatile ("movl %%fs:0, %0" : "=r" (er.ex_reg.prev));
474
      asm volatile ("movl %0, %%fs:0" : : "r" (&er));
475
476
#   endif /* __GNUC__ */
477
478
          ret_val = GC_mark_some_inner(cold_gc_frame);
479
480
#   ifndef __GNUC__
481
482
      } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
483
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
484
485
#   else /* __GNUC__ */
486
487
          /* Prevent GCC from considering the following code unreachable */
488
          /* and thus eliminating it.                                    */
489
          if (er.alt_path != 0)
490
              goto rm_handler;
491
492
handle_ex:
493
          /* Execution resumes from here on an access violation. */
494
495
#   endif /* __GNUC__ */
496
497
#         ifdef CONDPRINT
498
            if (GC_print_stats) {
499
	      GC_printf0("Caught ACCESS_VIOLATION in marker. "
500
		         "Memory mapping disappeared.\n");
501
            }
502
#         endif /* CONDPRINT */
503
504
          /* We have bad roots on the stack.  Discard mark stack.  */
505
          /* Rescan from marked objects.  Redetermine roots.	 */
506
          GC_invalidate_mark_state();	
507
          scan_ptr = 0;
508
509
          ret_val = FALSE;
510
511
#   ifndef __GNUC__
512
405
      }
513
      }
406
#   endif /* CONDPRINT */
514
407
    /* We have bad roots on the stack.  Discard mark stack.  	*/
515
#   else /* __GNUC__ */
408
    /* Rescan from marked objects.  Redetermine roots.		*/
516
409
    GC_invalidate_mark_state();	
517
rm_handler:
410
    scan_ptr = 0;
518
      /* Uninstall the exception handler */
411
    return FALSE;
519
      asm volatile ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
520
521
#   endif /* __GNUC__ */
522
523
      return ret_val;
412
  }
524
  }
413
#endif /* defined(MSWIN32) && !defined(__GNUC__) */
525
#endif /* MSWIN32 */
414
}
415
526
416
527
417
GC_bool GC_mark_stack_empty()
528
GC_bool GC_mark_stack_empty()

Return to bug 10746