Updates from 0.2.1 into 0.2.1-inu-1.5
This commit is contained in:
		
							
								
								
									
										128
									
								
								gc/mark_rts.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								gc/mark_rts.c
									
									
									
									
									
								
							| @@ -11,9 +11,8 @@ | ||||
|  * provided the above notices are retained, and a notice that the code was | ||||
|  * modified is included with the above copyright notice. | ||||
|  */ | ||||
| /* Boehm, October 9, 1995 1:06 pm PDT */ | ||||
| # include <stdio.h> | ||||
| # include "gc_priv.h" | ||||
| # include "private/gc_priv.h" | ||||
|  | ||||
| /* Data structure for list of root sets.				*/ | ||||
| /* We keep a hash table, so that we can filter out duplicate additions.	*/ | ||||
| @@ -23,7 +22,7 @@ | ||||
| struct roots { | ||||
| 	ptr_t r_start; | ||||
| 	ptr_t r_end; | ||||
|  #	ifndef MSWIN32 | ||||
|  #	if !defined(MSWIN32) && !defined(MSWINCE) | ||||
| 	  struct roots * r_next; | ||||
|  #	endif | ||||
| 	GC_bool r_tmp; | ||||
| @@ -33,6 +32,8 @@ struct roots { | ||||
| struct roots GC_static_roots[MAX_ROOT_SETS]; | ||||
| */ | ||||
|  | ||||
| int GC_no_dls = 0;	/* Register dynamic library data segments.	*/ | ||||
|  | ||||
| static int n_root_sets = 0; | ||||
|  | ||||
| 	/* GC_static_roots[0..n_root_sets) contains the valid root sets. */ | ||||
| @@ -69,11 +70,12 @@ void GC_print_static_roots() | ||||
| GC_bool GC_is_static_root(p) | ||||
| ptr_t p; | ||||
| { | ||||
|     static int last_root_set = 0; | ||||
|     static int last_root_set = MAX_ROOT_SETS; | ||||
|     register int i; | ||||
|      | ||||
|      | ||||
|     if (p >= GC_static_roots[last_root_set].r_start | ||||
|     if (last_root_set < n_root_sets | ||||
| 	&& p >= GC_static_roots[last_root_set].r_start | ||||
|         && p < GC_static_roots[last_root_set].r_end) return(TRUE); | ||||
|     for (i = 0; i < n_root_sets; i++) { | ||||
|     	if (p >= GC_static_roots[i].r_start | ||||
| @@ -85,7 +87,7 @@ ptr_t p; | ||||
|     return(FALSE); | ||||
| } | ||||
|  | ||||
| #ifndef MSWIN32 | ||||
| #if !defined(MSWIN32) && !defined(MSWINCE) | ||||
| /*  | ||||
| #   define LOG_RT_SIZE 6 | ||||
| #   define RT_SIZE (1 << LOG_RT_SIZE)  -- Power of 2, may be != MAX_ROOT_SETS | ||||
| @@ -137,7 +139,7 @@ struct roots *p; | ||||
|     GC_root_index[h] = p; | ||||
| } | ||||
|  | ||||
| # else /* MSWIN32 */ | ||||
| # else /* MSWIN32 || MSWINCE */ | ||||
|  | ||||
| #   define add_roots_to_index(p) | ||||
|  | ||||
| @@ -173,7 +175,7 @@ GC_bool tmp; | ||||
| { | ||||
|     struct roots * old; | ||||
|      | ||||
| #   ifdef MSWIN32 | ||||
| #   if defined(MSWIN32) || defined(MSWINCE) | ||||
|       /* Spend the time to ensure that there are no overlapping	*/ | ||||
|       /* or adjacent intervals.					*/ | ||||
|       /* This could be done faster with e.g. a			*/ | ||||
| @@ -242,7 +244,7 @@ GC_bool tmp; | ||||
|     GC_static_roots[n_root_sets].r_start = (ptr_t)b; | ||||
|     GC_static_roots[n_root_sets].r_end = (ptr_t)e; | ||||
|     GC_static_roots[n_root_sets].r_tmp = tmp; | ||||
| #   ifndef MSWIN32 | ||||
| #   if !defined(MSWIN32) && !defined(MSWINCE) | ||||
|       GC_static_roots[n_root_sets].r_next = 0; | ||||
| #   endif | ||||
|     add_roots_to_index(GC_static_roots + n_root_sets); | ||||
| @@ -250,15 +252,18 @@ GC_bool tmp; | ||||
|     n_root_sets++; | ||||
| } | ||||
|  | ||||
| static roots_were_cleared = FALSE; | ||||
|  | ||||
| void GC_clear_roots GC_PROTO((void)) | ||||
| { | ||||
|     DCL_LOCK_STATE; | ||||
|      | ||||
|     DISABLE_SIGNALS(); | ||||
|     LOCK(); | ||||
|     roots_were_cleared = TRUE; | ||||
|     n_root_sets = 0; | ||||
|     GC_root_size = 0; | ||||
| #   ifndef MSWIN32 | ||||
| #   if !defined(MSWIN32) && !defined(MSWINCE) | ||||
|     { | ||||
|     	register int i; | ||||
|     	 | ||||
| @@ -286,7 +291,7 @@ void GC_remove_tmp_roots() | ||||
|     	    i++; | ||||
|     	} | ||||
|     } | ||||
| #   ifndef MSWIN32 | ||||
| #   if !defined(MSWIN32) && !defined(MSWINCE) | ||||
|     { | ||||
|     	register int i; | ||||
|     	 | ||||
| @@ -298,11 +303,41 @@ void GC_remove_tmp_roots() | ||||
|      | ||||
| } | ||||
|  | ||||
| #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION) | ||||
| /* Workaround for the OS mapping and unmapping behind our back:		*/ | ||||
| /* Is the address p in one of the temporary static root sections?	*/ | ||||
| GC_bool GC_is_tmp_root(p) | ||||
| ptr_t p; | ||||
| { | ||||
|     static int last_root_set = MAX_ROOT_SETS; | ||||
|     register int i; | ||||
|      | ||||
|     if (last_root_set < n_root_sets | ||||
| 	&& p >= GC_static_roots[last_root_set].r_start | ||||
|         && p < GC_static_roots[last_root_set].r_end) | ||||
| 	return GC_static_roots[last_root_set].r_tmp; | ||||
|     for (i = 0; i < n_root_sets; i++) { | ||||
|     	if (p >= GC_static_roots[i].r_start | ||||
|             && p < GC_static_roots[i].r_end) { | ||||
|             last_root_set = i; | ||||
|             return GC_static_roots[i].r_tmp; | ||||
|         } | ||||
|     } | ||||
|     return(FALSE); | ||||
| } | ||||
| #endif /* MSWIN32 || _WIN32_WCE_EMULATION */ | ||||
|  | ||||
| ptr_t GC_approx_sp() | ||||
| { | ||||
|     word dummy; | ||||
|      | ||||
|  | ||||
| #   ifdef _MSC_VER | ||||
| #     pragma warning(disable:4172) | ||||
| #   endif | ||||
|     return((ptr_t)(&dummy)); | ||||
| #   ifdef _MSC_VER | ||||
| #     pragma warning(default:4172) | ||||
| #   endif | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -412,6 +447,8 @@ ptr_t cold_gc_frame; | ||||
| 	if (0 == cold_gc_frame) return; | ||||
| #       ifdef STACK_GROWS_DOWN | ||||
|     	  GC_push_all_eager(GC_approx_sp(), cold_gc_frame); | ||||
| 	  /* For IA64, the register stack backing store is handled 	*/ | ||||
| 	  /* in the thread-specific code.				*/ | ||||
| #       else | ||||
| 	  GC_push_all_eager( cold_gc_frame, GC_approx_sp() ); | ||||
| #       endif | ||||
| @@ -419,6 +456,32 @@ ptr_t cold_gc_frame; | ||||
| #   	ifdef STACK_GROWS_DOWN | ||||
|     	    GC_push_all_stack_partially_eager( GC_approx_sp(), GC_stackbottom, | ||||
| 					       cold_gc_frame ); | ||||
| #	    ifdef IA64 | ||||
| 	      /* We also need to push the register stack backing store. */ | ||||
| 	      /* This should really be done in the same way as the	*/ | ||||
| 	      /* regular stack.  For now we fudge it a bit.		*/ | ||||
| 	      /* Note that the backing store grows up, so we can't use	*/ | ||||
| 	      /* GC_push_all_stack_partially_eager.			*/ | ||||
| 	      { | ||||
| 		extern word GC_save_regs_ret_val; | ||||
| 			/* Previously set to backing store pointer.	*/ | ||||
| 		ptr_t bsp = (ptr_t) GC_save_regs_ret_val; | ||||
| 	        ptr_t cold_gc_bs_pointer; | ||||
| 		if (GC_all_interior_pointers) { | ||||
| 	          cold_gc_bs_pointer = bsp - 2048; | ||||
| 		  if (cold_gc_bs_pointer < BACKING_STORE_BASE) { | ||||
| 		    cold_gc_bs_pointer = BACKING_STORE_BASE; | ||||
| 		  } else { | ||||
| 		    GC_push_all_stack(BACKING_STORE_BASE, cold_gc_bs_pointer); | ||||
| 		  } | ||||
| 		} else { | ||||
| 		  cold_gc_bs_pointer = BACKING_STORE_BASE; | ||||
| 		} | ||||
| 		GC_push_all_eager(cold_gc_bs_pointer, bsp); | ||||
| 		/* All values should be sufficiently aligned that we	*/ | ||||
| 		/* dont have to worry about the boundary.		*/ | ||||
| 	      } | ||||
| #	    endif | ||||
| #       else | ||||
| 	    GC_push_all_stack_partially_eager( GC_stackbottom, GC_approx_sp(), | ||||
| 					       cold_gc_frame ); | ||||
| @@ -426,6 +489,23 @@ ptr_t cold_gc_frame; | ||||
| #   endif /* !THREADS */ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Push GC internal roots.  Only called if there is some reason to believe | ||||
|  * these would not otherwise get registered. | ||||
|  */ | ||||
| void GC_push_gc_structures GC_PROTO((void)) | ||||
| { | ||||
|     GC_push_finalizer_structures(); | ||||
|     GC_push_stubborn_structures(); | ||||
| #   if defined(THREADS) | ||||
|       GC_push_thread_structures(); | ||||
| #   endif | ||||
| } | ||||
|  | ||||
| #ifdef THREAD_LOCAL_ALLOC | ||||
|   void GC_mark_thread_local_free_lists(); | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Call the mark routines (GC_tl_push for a single pointer, GC_push_conditional | ||||
|  * on groups of pointers) on every top level accessible pointer. | ||||
| @@ -456,11 +536,14 @@ ptr_t cold_gc_frame; | ||||
|      * not robust against mark stack overflow. | ||||
|      */ | ||||
|      /* Reregister dynamic libraries, in case one got added.	*/ | ||||
| #      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(PCR)) \ | ||||
|            && !defined(SRC_M3) | ||||
| #      if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \ | ||||
| 	   || defined(PCR)) && !defined(SRC_M3) | ||||
|          GC_remove_tmp_roots(); | ||||
|          GC_register_dynamic_libraries(); | ||||
|          if (!GC_no_dls) GC_register_dynamic_libraries(); | ||||
| #      else | ||||
| 	 GC_no_dls = TRUE; | ||||
| #      endif | ||||
|  | ||||
|      /* Mark everything in static data areas                             */ | ||||
|        for (i = 0; i < n_root_sets; i++) { | ||||
|          GC_push_conditional_with_exclusions( | ||||
| @@ -468,6 +551,18 @@ ptr_t cold_gc_frame; | ||||
| 			     GC_static_roots[i].r_end, all); | ||||
|        } | ||||
|  | ||||
|      /* Mark from GC internal roots if those might otherwise have	*/ | ||||
|      /* been excluded.							*/ | ||||
|        if (GC_no_dls || roots_were_cleared) { | ||||
| 	   GC_push_gc_structures(); | ||||
|        } | ||||
|  | ||||
|      /* Mark thread local free lists, even if their mark 	*/ | ||||
|      /* descriptor excludes the link field.			*/ | ||||
| #      ifdef THREAD_LOCAL_ALLOC | ||||
|          GC_mark_thread_local_free_lists(); | ||||
| #      endif | ||||
|  | ||||
|     /* | ||||
|      * Now traverse stacks. | ||||
|      */ | ||||
| @@ -477,6 +572,9 @@ ptr_t cold_gc_frame; | ||||
| 	/* In the USE_GENERIC_PUSH_REGS case, this is done inside	*/ | ||||
| 	/* GC_push_regs, so that we catch callee-save registers saved	*/ | ||||
| 	/* inside the GC_push_regs frame.				*/ | ||||
| 	/* In the case of linux threads on Ia64, the hot section of	*/ | ||||
| 	/* the main stack is marked here, but the register stack	*/ | ||||
| 	/* backing store is handled in the threads-specific code.	*/ | ||||
| #   endif | ||||
|     if (GC_push_other_roots != 0) (*GC_push_other_roots)(); | ||||
|     	/* In the threads case, this also pushes thread stacks.	*/ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user