⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mark_rts.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program * for any purpose,  provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. */# include <stdio.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.	*//* Under Win32, we need to do a better job of filtering overlaps, so	*//* we resort to sequential search, and pay the price.			*//* This is really declared in gc_priv.h:struct roots {	ptr_t r_start;	ptr_t r_end; #	if !defined(MSWIN32) && !defined(MSWINCE)	  struct roots * r_next; #	endif	GC_bool r_tmp;	  	-- Delete before registering new dynamic libraries};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. */# if !defined(NO_DEBUGGING)/* For debugging:	*/void GC_print_static_roots(void){    register int i;    size_t total = 0;        for (i = 0; i < n_root_sets; i++) {        GC_printf("From %p to %p ",        	  GC_static_roots[i].r_start,        	  GC_static_roots[i].r_end);        if (GC_static_roots[i].r_tmp) {            GC_printf(" (temporary)\n");        } else {            GC_printf("\n");        }        total += GC_static_roots[i].r_end - GC_static_roots[i].r_start;    }    GC_printf("Total size: %ld\n", (unsigned long) total);    if (GC_root_size != total) {     	GC_printf("GC_root_size incorrect: %ld!!\n",     		  (unsigned long) GC_root_size);    }}# endif /* NO_DEBUGGING *//* Primarily for debugging support:	*//* Is the address p in one of the registered static			*//* root sections?							*/GC_bool GC_is_static_root(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(TRUE);    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(TRUE);        }    }    return(FALSE);}#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    struct roots * GC_root_index[RT_SIZE];	-- Hash table header.  Used only to check whether a range is	-- already present.	-- really defined in gc_priv.h*/static INLINE int rt_hash(ptr_t addr){    word result = (word) addr;#   if CPP_WORDSZ > 8*LOG_RT_SIZE	result ^= result >> 8*LOG_RT_SIZE;#   endif#   if CPP_WORDSZ > 4*LOG_RT_SIZE	result ^= result >> 4*LOG_RT_SIZE;#   endif    result ^= result >> 2*LOG_RT_SIZE;    result ^= result >> LOG_RT_SIZE;    result &= (RT_SIZE-1);    return(result);}/* Is a range starting at b already in the table? If so return a	*//* pointer to it, else NIL.						*/struct roots * GC_roots_present(ptr_t b){    int h = rt_hash(b);    struct roots *p = GC_root_index[h];        while (p != 0) {        if (p -> r_start == (ptr_t)b) return(p);        p = p -> r_next;    }    return(FALSE);}/* Add the given root structure to the index. */static void add_roots_to_index(struct roots *p){    int h = rt_hash(p -> r_start);        p -> r_next = GC_root_index[h];    GC_root_index[h] = p;}# else /* MSWIN32 || MSWINCE */#   define add_roots_to_index(p)# endifword GC_root_size = 0;void GC_add_roots(void *b, void *e){    DCL_LOCK_STATE;        if (!GC_is_initialized) GC_init();    LOCK();    GC_add_roots_inner((ptr_t)b, (ptr_t)e, FALSE);    UNLOCK();}/* Add [b,e) to the root set.  Adding the same interval a second time	*//* is a moderately fast noop, and hence benign.  We do not handle	*//* different but overlapping intervals efficiently.  (We do handle	*//* them correctly.)							*//* Tmp specifies that the interval may be deleted before 		*//* reregistering dynamic libraries.					*/ void GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp){    struct roots * old;    #   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			*/      /* balanced tree.  But the execution time here is		*/      /* virtually guaranteed to be dominated by the time it	*/      /* takes to scan the roots.				*/      {        register int i;                for (i = 0; i < n_root_sets; i++) {            old = GC_static_roots + i;            if (b <= old -> r_end && e >= old -> r_start) {                if (b < old -> r_start) {                    old -> r_start = b;                    GC_root_size += (old -> r_start - b);                }                if (e > old -> r_end) {                    old -> r_end = e;                    GC_root_size += (e - old -> r_end);                }                old -> r_tmp &= tmp;                break;            }        }        if (i < n_root_sets) {          /* merge other overlapping intervals */            struct roots *other;                        for (i++; i < n_root_sets; i++) {              other = GC_static_roots + i;              b = other -> r_start;              e = other -> r_end;              if (b <= old -> r_end && e >= old -> r_start) {                if (b < old -> r_start) {                    old -> r_start = b;                    GC_root_size += (old -> r_start - b);                }                if (e > old -> r_end) {                    old -> r_end = e;                    GC_root_size += (e - old -> r_end);                }                old -> r_tmp &= other -> r_tmp;                /* Delete this entry. */                  GC_root_size -= (other -> r_end - other -> r_start);                  other -> r_start = GC_static_roots[n_root_sets-1].r_start;                  other -> r_end = GC_static_roots[n_root_sets-1].r_end;                  n_root_sets--;              }            }          return;        }      }#   else      old = GC_roots_present(b);      if (old != 0) {        if (e <= old -> r_end) /* already there */ return;        /* else extend */        GC_root_size += e - old -> r_end;        old -> r_end = e;        return;      }#   endif    if (n_root_sets == MAX_ROOT_SETS) {        ABORT("Too many root sets\n");    }    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;#   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);    GC_root_size += e - b;    n_root_sets++;}static GC_bool roots_were_cleared = FALSE;void GC_clear_roots (void){    DCL_LOCK_STATE;        if (!GC_is_initialized) GC_init();    LOCK();    roots_were_cleared = TRUE;    n_root_sets = 0;    GC_root_size = 0;#   if !defined(MSWIN32) && !defined(MSWINCE)    {    	register int i;    	    	for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;    }#   endif    UNLOCK();}/* Internal use only; lock held.	*/static void GC_remove_root_at_pos(int i) {    GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);    GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;    GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;    GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;    n_root_sets--;}#if !defined(MSWIN32) && !defined(MSWINCE)static void GC_rebuild_root_index(void){    int i;    	    for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;    for (i = 0; i < n_root_sets; i++)	add_roots_to_index(GC_static_roots + i);}#endif/* Internal use only; lock held.	*/void GC_remove_tmp_roots(void){    int i;        for (i = 0; i < n_root_sets; ) {    	if (GC_static_roots[i].r_tmp) {            GC_remove_root_at_pos(i);    	} else {    	    i++;    }    }    #if !defined(MSWIN32) && !defined(MSWINCE)    GC_rebuild_root_index();    #endif}#if !defined(MSWIN32) && !defined(MSWINCE)void GC_remove_roots(void *b, void *e){    DCL_LOCK_STATE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -