/[emacs]/emacs/gc/mark.c
ViewVC logotype

Diff of /emacs/gc/mark.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2.2.1 by fx, Thu Jun 5 18:23:04 2003 UTC revision 1.2.2.1.2.1 by fx, Mon Jun 16 15:19:52 2003 UTC
# Line 19  Line 19 
19  # include <stdio.h>  # include <stdio.h>
20  # include "private/gc_pmark.h"  # include "private/gc_pmark.h"
21    
22    #if defined(MSWIN32) && defined(__GNUC__)
23    # include <excpt.h>
24    #endif
25    
26  /* We put this here to minimize the risk of inlining. */  /* We put this here to minimize the risk of inlining. */
27  /*VARARGS*/  /*VARARGS*/
28  #ifdef __WATCOMC__  #ifdef __WATCOMC__
# Line 261  static void alloc_mark_stack(); Line 265  static void alloc_mark_stack();
265  /* remains valid until all marking is complete.         */  /* remains valid until all marking is complete.         */
266  /* A zero value indicates that it's OK to miss some     */  /* A zero value indicates that it's OK to miss some     */
267  /* register values.                                     */  /* register values.                                     */
268  GC_bool GC_mark_some(cold_gc_frame)  /* We hold the allocation lock.  In the case of         */
269  ptr_t cold_gc_frame;  /* 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
281  {  {
 #if defined(MSWIN32) && !defined(__GNUC__)  
   /* Windows 98 appears to asynchronously create and remove writable    */  
   /* memory mappings, for reasons we haven't yet understood.  Since     */  
   /* we look for writable regions to determine the root set, we may     */  
   /* try to mark from an address range that disappeared since we        */  
   /* started the collection.  Thus we have to recover from faults here. */  
   /* This code does not appear to be necessary for Windows 95/NT/2000.  */  
   /* Note that this code should never generate an incremental GC write  */  
   /* fault.                                                             */  
   __try {  
 #endif /* defined(MSWIN32) && !defined(__GNUC__) */  
282      switch(GC_mark_state) {      switch(GC_mark_state) {
283          case MS_NONE:          case MS_NONE:
284              return(FALSE);              return(FALSE);
# Line 395  ptr_t cold_gc_frame; Line 399  ptr_t cold_gc_frame;
399              ABORT("GC_mark_some: bad state");              ABORT("GC_mark_some: bad state");
400              return(FALSE);              return(FALSE);
401      }      }
402  #if defined(MSWIN32) && !defined(__GNUC__)  }
403    } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?  
404              EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {  
405  #   ifdef CONDPRINT  #ifdef MSWIN32
406        if (GC_print_stats) {  
407          GC_printf0("Caught ACCESS_VIOLATION in marker. "  # ifdef __GNUC__
408                     "Memory mapping disappeared.\n");  
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    
513        }        }
514  #   endif /* CONDPRINT */  
515      /* We have bad roots on the stack.  Discard mark stack.     */  #   else /* __GNUC__ */
516      /* Rescan from marked objects.  Redetermine roots.          */  
517      GC_invalidate_mark_state();  rm_handler:
518      scan_ptr = 0;        /* Uninstall the exception handler */
519      return FALSE;        asm volatile ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
520    
521    #   endif /* __GNUC__ */
522    
523          return ret_val;
524    }    }
525  #endif /* defined(MSWIN32) && !defined(__GNUC__) */  #endif /* MSWIN32 */
 }  
526    
527    
528  GC_bool GC_mark_stack_empty()  GC_bool GC_mark_stack_empty()

Legend:
Removed from v.1.2.2.1  
changed lines
  Added in v.1.2.2.1.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26