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

📄 dbg_mlc.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991-1995 by Xerox Corporation.  All rights reserved. * Copyright (c) 1997 by Silicon Graphics.  All rights reserved. * Copyright (c) 1999-2004 Hewlett-Packard Development Company, L.P. * * 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 "private/dbg_mlc.h"void GC_default_print_heap_obj_proc();GC_API void GC_register_finalizer_no_order    	GC_PROTO((GC_PTR obj, GC_finalization_proc fn, GC_PTR cd,		  GC_finalization_proc *ofn, GC_PTR *ocd));#ifndef SHORT_DBG_HDRS/* Check whether object with base pointer p has debugging info	*/ /* p is assumed to point to a legitimate object in our part	*//* of the heap.							*//* This excludes the check as to whether the back pointer is 	*//* odd, which is added by the GC_HAS_DEBUG_INFO macro.		*//* Note that if DBG_HDRS_ALL is set, uncollectable objects	*//* on free lists may not have debug information set.  Thus it's	*//* not always safe to return TRUE, even if the client does	*//* its part.							*/GC_bool GC_has_other_debug_info(p)ptr_t p;{    register oh * ohdr = (oh *)p;    register ptr_t body = (ptr_t)(ohdr + 1);    register word sz = GC_size((ptr_t) ohdr);        if (HBLKPTR((ptr_t)ohdr) != HBLKPTR((ptr_t)body)        || sz < DEBUG_BYTES + EXTRA_BYTES) {        return(FALSE);    }    if (ohdr -> oh_sz == sz) {    	/* Object may have had debug info, but has been deallocated	*/    	return(FALSE);    }    if (ohdr -> oh_sf == (START_FLAG ^ (word)body)) return(TRUE);    if (((word *)ohdr)[BYTES_TO_WORDS(sz)-1] == (END_FLAG ^ (word)body)) {        return(TRUE);    }    return(FALSE);}#endif#ifdef KEEP_BACK_PTRS# include <stdlib.h># if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \     || defined(HPUX) || defined(IRIX5) || defined(OSF1)#   define RANDOM() random()# else#   define RANDOM() (long)rand()# endif  /* Store back pointer to source in dest, if that appears to be possible. */  /* This is not completely safe, since we may mistakenly conclude that	   */  /* dest has a debugging wrapper.  But the error probability is very	   */  /* small, and this shouldn't be used in production code.		   */  /* We assume that dest is the real base pointer.  Source will usually    */  /* be a pointer to the interior of an object.				   */  void GC_store_back_pointer(ptr_t source, ptr_t dest)  {    if (GC_HAS_DEBUG_INFO(dest)) {      ((oh *)dest) -> oh_back_ptr = HIDE_BACK_PTR(source);    }  }  void GC_marked_for_finalization(ptr_t dest) {    GC_store_back_pointer(MARKED_FOR_FINALIZATION, dest);  }  /* Store information about the object referencing dest in *base_p	*/  /* and *offset_p.							*/  /*   source is root ==> *base_p = address, *offset_p = 0		*/  /*   source is heap object ==> *base_p != 0, *offset_p = offset 	*/  /*   Returns 1 on success, 0 if source couldn't be determined.	*/  /* Dest can be any address within a heap object.			*/  GC_ref_kind GC_get_back_ptr_info(void *dest, void **base_p, size_t *offset_p)  {    oh * hdr = (oh *)GC_base(dest);    ptr_t bp;    ptr_t bp_base;    if (!GC_HAS_DEBUG_INFO((ptr_t) hdr)) return GC_NO_SPACE;    bp = REVEAL_POINTER(hdr -> oh_back_ptr);    if (MARKED_FOR_FINALIZATION == bp) return GC_FINALIZER_REFD;    if (MARKED_FROM_REGISTER == bp) return GC_REFD_FROM_REG;    if (NOT_MARKED == bp) return GC_UNREFERENCED;#   if ALIGNMENT == 1      /* Heuristically try to fix off by 1 errors we introduced by 	*/      /* insisting on even addresses.					*/      {	ptr_t alternate_ptr = bp + 1;	ptr_t target = *(ptr_t *)bp;	ptr_t alternate_target = *(ptr_t *)alternate_ptr;	if (alternate_target >= GC_least_plausible_heap_addr	    && alternate_target <= GC_greatest_plausible_heap_addr	    && (target < GC_least_plausible_heap_addr		|| target > GC_greatest_plausible_heap_addr)) {	    bp = alternate_ptr;	}      }#   endif    bp_base = GC_base(bp);    if (0 == bp_base) {      *base_p = bp;      *offset_p = 0;      return GC_REFD_FROM_ROOT;    } else {      if (GC_HAS_DEBUG_INFO(bp_base)) bp_base += sizeof(oh);      *base_p = bp_base;      *offset_p = bp - bp_base;      return GC_REFD_FROM_HEAP;    }  }  /* Generate a random heap address.		*/  /* The resulting address is in the heap, but	*/  /* not necessarily inside a valid object.	*/  void *GC_generate_random_heap_address(void)  {    int i;    long heap_offset = RANDOM();    if (GC_heapsize > RAND_MAX) {	heap_offset *= RAND_MAX;	heap_offset += RANDOM();    }    heap_offset %= GC_heapsize;    	/* This doesn't yield a uniform distribution, especially if	*/        /* e.g. RAND_MAX = 1.5* GC_heapsize.  But for typical cases,	*/        /* it's not too bad.						*/    for (i = 0; i < GC_n_heap_sects; ++ i) {	int size = GC_heap_sects[i].hs_bytes;	if (heap_offset < size) {	    return GC_heap_sects[i].hs_start + heap_offset;	} else {	    heap_offset -= size;	}    }    ABORT("GC_generate_random_heap_address: size inconsistency");    /*NOTREACHED*/    return 0;  }  /* Generate a random address inside a valid marked heap object. */  void *GC_generate_random_valid_address(void)  {    ptr_t result;    ptr_t base;    for (;;) {	result = GC_generate_random_heap_address();  	base = GC_base(result);	if (0 == base) continue;	if (!GC_is_marked(base)) continue;	return result;    }  }  /* Print back trace for p */  void GC_print_backtrace(void *p)  {    void *current = p;    int i;    GC_ref_kind source;    size_t offset;    void *base;    GC_print_heap_obj(GC_base(current));    GC_err_printf0("\n");    for (i = 0; ; ++i) {      source = GC_get_back_ptr_info(current, &base, &offset);      if (GC_UNREFERENCED == source) {	GC_err_printf0("Reference could not be found\n");  	goto out;      }      if (GC_NO_SPACE == source) {	GC_err_printf0("No debug info in object: Can't find reference\n");	goto out;      }      GC_err_printf1("Reachable via %d levels of pointers from ",		 (unsigned long)i);      switch(source) {	case GC_REFD_FROM_ROOT:	  GC_err_printf1("root at 0x%lx\n\n", (unsigned long)base);	  goto out;	case GC_REFD_FROM_REG:	  GC_err_printf0("root in register\n\n");	  goto out;	case GC_FINALIZER_REFD:	  GC_err_printf0("list of finalizable objects\n\n");	  goto out;	case GC_REFD_FROM_HEAP:	  GC_err_printf1("offset %ld in object:\n", (unsigned long)offset);	  /* Take GC_base(base) to get real base, i.e. header. */	  GC_print_heap_obj(GC_base(base));	  GC_err_printf0("\n");	  break;      }      current = base;    }    out:;  }  /* Force a garbage collection and generate a backtrace from a	*/  /* random heap address.					*/  void GC_generate_random_backtrace_no_gc(void)  {    void * current;    current = GC_generate_random_valid_address();    GC_printf1("\n****Chose address 0x%lx in object\n", (unsigned long)current);    GC_print_backtrace(current);  }      void GC_generate_random_backtrace(void)  {    GC_gcollect();    GC_generate_random_backtrace_no_gc();  }    #endif /* KEEP_BACK_PTRS */# define CROSSES_HBLK(p, sz) \	(((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)/* Store debugging info into p.  Return displaced pointer. *//* Assumes we don't hold allocation lock.		   */ptr_t GC_store_debug_info(p, sz, string, integer)register ptr_t p;	/* base pointer */word sz; 	/* bytes */GC_CONST char * string;word integer;{    register word * result = (word *)((oh *)p + 1);    DCL_LOCK_STATE;        /* There is some argument that we should dissble signals here.	*/    /* But that's expensive.  And this way things should only appear	*/    /* inconsistent while we're in the handler.				*/    LOCK();    GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);    GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));#   ifdef KEEP_BACK_PTRS      ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);#   endif#   ifdef MAKE_BACK_GRAPH      ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0);#   endif    ((oh *)p) -> oh_string = string;    ((oh *)p) -> oh_int = integer;#   ifndef SHORT_DBG_HDRS      ((oh *)p) -> oh_sz = sz;      ((oh *)p) -> oh_sf = START_FLAG ^ (word)result;      ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] =         result[SIMPLE_ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result;#   endif    UNLOCK();    return((ptr_t)result);}#ifdef DBG_HDRS_ALL/* Store debugging info into p.  Return displaced pointer.	   *//* This version assumes we do hold the allocation lock.		   */ptr_t GC_store_debug_info_inner(p, sz, string, integer)register ptr_t p;	/* base pointer */word sz; 	/* bytes */char * string;word integer;{    register word * result = (word *)((oh *)p + 1);        /* There is some argument that we should disable signals here.	*/    /* But that's expensive.  And this way things should only appear	*/    /* inconsistent while we're in the handler.				*/    GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);    GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));#   ifdef KEEP_BACK_PTRS      ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);#   endif#   ifdef MAKE_BACK_GRAPH      ((oh *)p) -> oh_bg_ptr = HIDE_BACK_PTR((ptr_t)0);#   endif    ((oh *)p) -> oh_string = string;    ((oh *)p) -> oh_int = integer;#   ifndef SHORT_DBG_HDRS      ((oh *)p) -> oh_sz = sz;      ((oh *)p) -> oh_sf = START_FLAG ^ (word)result;      ((word *)p)[BYTES_TO_WORDS(GC_size(p))-1] =         result[SIMPLE_ROUNDED_UP_WORDS(sz)] = END_FLAG ^ (word)result;#   endif    return((ptr_t)result);}#endif#ifndef SHORT_DBG_HDRS/* Check the object with debugging info at ohdr		*//* return NIL if it's OK.  Else return clobbered	*//* address.						*/ptr_t GC_check_annotated_obj(ohdr)register oh * ohdr;{    register ptr_t body = (ptr_t)(ohdr + 1);    register word gc_sz = GC_size((ptr_t)ohdr);    if (ohdr -> oh_sz + DEBUG_BYTES > gc_sz) {        return((ptr_t)(&(ohdr -> oh_sz)));    }    if (ohdr -> oh_sf != (START_FLAG ^ (word)body)) {        return((ptr_t)(&(ohdr -> oh_sf)));    }    if (((word *)ohdr)[BYTES_TO_WORDS(gc_sz)-1] != (END_FLAG ^ (word)body)) {        return((ptr_t)((word *)ohdr + BYTES_TO_WORDS(gc_sz)-1));    }    if (((word *)body)[SIMPLE_ROUNDED_UP_WORDS(ohdr -> oh_sz)]        != (END_FLAG ^ (word)body)) {        return((ptr_t)((word *)body + SIMPLE_ROUNDED_UP_WORDS(ohdr -> oh_sz)));    }    return(0);}#endif /* !SHORT_DBG_HDRS */static GC_describe_type_fn GC_describe_type_fns[MAXOBJKINDS] = {0};void GC_register_describe_type_fn(kind, fn)int kind;GC_describe_type_fn fn;{  GC_describe_type_fns[kind] = fn;}/* Print a type description for the object whose client-visible address	*//* is p.								*/void GC_print_type(p)ptr_t p;{    hdr * hhdr = GC_find_header(p);    char buffer[GC_TYPE_DESCR_LEN + 1];    int kind = hhdr -> hb_obj_kind;    if (0 != GC_describe_type_fns[kind] && GC_is_marked(GC_base(p))) {	/* This should preclude free list objects except with	*/	/* thread-local allocation.				*/	buffer[GC_TYPE_DESCR_LEN] = 0;	(GC_describe_type_fns[kind])(p, buffer);	GC_ASSERT(buffer[GC_TYPE_DESCR_LEN] == 0);	GC_err_puts(buffer);    } else {	switch(kind) {	  case PTRFREE:	    GC_err_puts("PTRFREE");	    break;	  case NORMAL:	    GC_err_puts("NORMAL");	    break;	  case UNCOLLECTABLE:	    GC_err_puts("UNCOLLECTABLE");	    break;#	  ifdef ATOMIC_UNCOLLECTABLE	    case AUNCOLLECTABLE:	      GC_err_puts("ATOMIC UNCOLLECTABLE");	      break;#	  endif	  case STUBBORN:	    GC_err_puts("STUBBORN");	    break;	  default:	    GC_err_printf2("kind %ld, descr 0x%lx", kind, hhdr -> hb_descr);	}    }}    void GC_print_obj(p)ptr_t p;{    register oh * ohdr = (oh *)GC_base(p);        GC_ASSERT(!I_HOLD_LOCK());    GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));    GC_err_puts(ohdr -> oh_string);#   ifdef SHORT_DBG_HDRS      GC_err_printf1(":%ld, ", (unsigned long)(ohdr -> oh_int));#   else      GC_err_printf2(":%ld, sz=%ld, ", (unsigned long)(ohdr -> oh_int),

⌨️ 快捷键说明

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