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

📄 gcrefs.c

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 C
字号:
/* gcRefs.c * Maintain set of references in the garbage collector root set. * This is independent of the actual collection mechanism * * Copyright (c) 1996, 1997, 1998, 1999 *	Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution  * of this file.  */#include "config.h"#include "debug.h"#include "config-std.h"#include "config-mem.h"#include "gtypes.h"#include "gc.h"#include "locks.h"#include "thread.h"#include "jthread.h"#include "errors.h"#include "md.h"#define	REFOBJHASHSZ	128typedef struct _refObject {	const void*		mem;	unsigned int		ref;	struct _refObject*	next;} refObject;typedef struct _refTable {	refObject*		hash[REFOBJHASHSZ];} refTable;static refTable			refObjects;/* This is a bit homemade.  We need a 7-bit hash from the address here */#define	REFOBJHASH(V)	((((uintp)(V) >> 2) ^ ((uintp)(V) >> 9))%REFOBJHASHSZ)/* * Add a persistent reference to an object. */boolgc_add_ref(const void* mem){	uint32 idx;	refObject* obj;	idx = REFOBJHASH(mem);	for (obj = refObjects.hash[idx]; obj != 0; obj = obj->next) {		/* Found it - just increase reference */		if (obj->mem == mem) {			obj->ref++;			return true;		}	}	/* Not found - create a new one */	obj = (refObject*)gc_malloc(sizeof(refObject), GC_ALLOC_REF);	if (!obj) return false;		obj->mem = mem;	obj->ref = 1;	obj->next = refObjects.hash[idx];	refObjects.hash[idx] = obj;	return true;}/* * Remove a persistent reference to an object.  If the count becomes * zero then the reference is removed. */boolgc_rm_ref(const void* mem){	uint32 idx;	refObject** objp;	refObject* obj;	idx = REFOBJHASH(mem);	for (objp = &refObjects.hash[idx]; *objp != 0; objp = &obj->next) {		obj = *objp;		/* Found it - just decrease reference */		if (obj->mem == mem) {			obj->ref--;			if (obj->ref == 0) {				*objp = obj->next;				KFREE(obj);			}			return (true);		}	}	/* Not found!! */	return (false);}/*       * Walk the thread's internal context. * This is invoked by the garbage collector thread, which is not * stopped. *       * We will iterate through all threads, including the garbage collector * and those threads that haven't been started yet. */     static  void    TwalkThread(Collector* collector, jthread_t jtid){               void *from;        unsigned len;                  /* Don't walk the gc thread's stack.  It was not stopped and         * we hence don't have valid sp information.  In addition, there's         * absolutely no reason why we should walk it at all.         */        if (jtid == jthread_current()) {DBG(JTHREAD,                dprintf("%p NOT walking jtid %p\n", jthread_current(), jtid);    )                   return;        }                /* Ask threading system what the interesting stack range is;         * If the thread is too young, the threading system will return         * 0 from extract_stack.  In that case, we don't have walk anything.         */        if (jthread_extract_stack(jtid, &from, &len)) {DBG(JTHREAD|DBG_GCWALK,                dprintf("walking stack of `%s' thread\n", nameThread(jthread_get_data(jtid)->jlThread));    )                /* and walk it if needed */                GC_walkConservative(collector, from, len);        }}static Collector *running_collector;	/* XXX will be fixed on thread interface gets fixed. * The best way to fix this is not to use walkThreads at all. * * That very much depends on what best means.  If we don't explicitly * walk threads while pushing roots, we are stuck calling * soft_instanceof in walkObject, which is a big source of overhead. */static voidliveThreadWalker(jthread_t tid){  Collector *c = running_collector;  threadData *thread_data = jthread_get_data(tid);  GC_markObject(c, thread_data->jlThread);    if (thread_data->exceptObj != NULL)  {    GC_markObject(c, thread_data->exceptObj);  }  TwalkThread(c, tid);}/* * Walk the set of registered root references.   * This is invoked at the beginning of each GC cycle.  */voidgc_walk_refs(Collector* collector){        int i;	refObject* robj;DBG(GCWALK,	dprintf("Walking gc roots...\n");    )        /* Walk the referenced objects */        for (i = 0; i < REFOBJHASHSZ; i++) {                for (robj = refObjects.hash[i]; robj != 0; robj = robj->next) {                        GC_markObject(collector, (void *) robj->mem);                }        }DBG(GCWALK,	dprintf("Walking live threads...\n");    )	running_collector = collector;        /* Walk the thread objects as the threading system has them         * registered.  Terminating a thread will remove it from the         * threading system, and then we won't walk it here anymore         */	jthread_walkLiveThreads(liveThreadWalker);DBG(GCWALK,	dprintf("Following references now...\n");    )}

⌨️ 快捷键说明

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