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

📄 typd_mlc.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved. * opyright (c) 1999-2000 by Hewlett-Packard Company.  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. * *//* * Some simple primitives for allocation with explicit type information. * Simple objects are allocated such that they contain a GC_descr at the * end (in the last allocated word).  This descriptor may be a procedure * which then examines an extended descriptor passed as its environment. * * Arrays are treated as simple objects if they have sufficiently simple * structure.  Otherwise they are allocated from an array kind that supplies * a special mark procedure.  These arrays contain a pointer to a * complex_descriptor as their last word. * This is done because the environment field is too small, and the collector * must trace the complex_descriptor. * * Note that descriptors inside objects may appear cleared, if we encounter a * false refrence to an object on a free list.  In the GC_descr case, this * is OK, since a 0 descriptor corresponds to examining no fields. * In the complex_descriptor case, we explicitly check for that case. * * MAJOR PARTS OF THIS CODE HAVE NOT BEEN TESTED AT ALL and are not testable, * since they are not accessible through the current interface. */#include "private/gc_pmark.h"#include "gc_typed.h"# define TYPD_EXTRA_BYTES (sizeof(word) - EXTRA_BYTES)GC_bool GC_explicit_typing_initialized = FALSE;int GC_explicit_kind;	/* Object kind for objects with indirect	*/			/* (possibly extended) descriptors.		*/int GC_array_kind;	/* Object kind for objects with complex		*/			/* descriptors and GC_array_mark_proc.		*//* Extended descriptors.  GC_typed_mark_proc understands these.	*//* These are used for simple objects that are larger than what	*//* can be described by a BITMAP_BITS sized bitmap.		*/typedef struct {	word ed_bitmap;	/* lsb corresponds to first word.	*/	GC_bool ed_continued;	/* next entry is continuation.	*/} ext_descr;/* Array descriptors.  GC_array_mark_proc understands these.	*//* We may eventually need to add provisions for headers and	*//* trailers.  Hence we provide for tree structured descriptors, *//* though we don't really use them currently.			*/typedef union ComplexDescriptor {    struct LeafDescriptor {	/* Describes simple array	*/        word ld_tag;#	define LEAF_TAG 1	word ld_size;		/* bytes per element	*/				/* multiple of ALIGNMENT	*/	word ld_nelements;	/* Number of elements.	*/	GC_descr ld_descriptor; /* A simple length, bitmap,	*/				/* or procedure descriptor.	*/    } ld;    struct ComplexArrayDescriptor {        word ad_tag;#	define ARRAY_TAG 2	word ad_nelements;	union ComplexDescriptor * ad_element_descr;    } ad;    struct SequenceDescriptor {        word sd_tag;#	define SEQUENCE_TAG 3	union ComplexDescriptor * sd_first;	union ComplexDescriptor * sd_second;    } sd;} complex_descriptor;#define TAG ld.ld_tagext_descr * GC_ext_descriptors;	/* Points to array of extended 	*/				/* descriptors.			*/word GC_ed_size = 0;	/* Current size of above arrays.	*/# define ED_INITIAL_SIZE 100;word GC_avail_descr = 0;	/* Next available slot.		*/int GC_typed_mark_proc_index;	/* Indices of my mark		*/int GC_array_mark_proc_index;	/* procedures.			*//* Add a multiword bitmap to GC_ext_descriptors arrays.  Return	*//* starting index.						*//* Returns -1 on failure.					*//* Caller does not hold allocation lock.			*/signed_word GC_add_ext_descriptor(bm, nbits)GC_bitmap bm;word nbits;{    register size_t nwords = divWORDSZ(nbits + WORDSZ-1);    register signed_word result;    register word i;    register word last_part;    register int extra_bits;    DCL_LOCK_STATE;    DISABLE_SIGNALS();    LOCK();    while (GC_avail_descr + nwords >= GC_ed_size) {    	ext_descr * new;    	size_t new_size;    	word ed_size = GC_ed_size;    	    	UNLOCK();        ENABLE_SIGNALS();    	if (ed_size == 0) {    	    new_size = ED_INITIAL_SIZE;    	} else {    	    new_size = 2 * ed_size;    	    if (new_size > MAX_ENV) return(-1);    	}     	new = (ext_descr *) GC_malloc_atomic(new_size * sizeof(ext_descr));    	if (new == 0) return(-1);    	DISABLE_SIGNALS();        LOCK();        if (ed_size == GC_ed_size) {            if (GC_avail_descr != 0) {    	        BCOPY(GC_ext_descriptors, new,    	              GC_avail_descr * sizeof(ext_descr));    	    }    	    GC_ed_size = new_size;    	    GC_ext_descriptors = new;    	}  /* else another thread already resized it in the meantime */    }    result = GC_avail_descr;    for (i = 0; i < nwords-1; i++) {        GC_ext_descriptors[result + i].ed_bitmap = bm[i];        GC_ext_descriptors[result + i].ed_continued = TRUE;    }    last_part = bm[i];    /* Clear irrelevant bits. */    extra_bits = nwords * WORDSZ - nbits;    last_part <<= extra_bits;    last_part >>= extra_bits;    GC_ext_descriptors[result + i].ed_bitmap = last_part;    GC_ext_descriptors[result + i].ed_continued = FALSE;    GC_avail_descr += nwords;    UNLOCK();    ENABLE_SIGNALS();    return(result);}/* Table of bitmap descriptors for n word long all pointer objects.	*/GC_descr GC_bm_table[WORDSZ/2];	/* Return a descriptor for the concatenation of 2 nwords long objects,	*//* each of which is described by descriptor.				*//* The result is known to be short enough to fit into a bitmap		*//* descriptor.								*//* Descriptor is a GC_DS_LENGTH or GC_DS_BITMAP descriptor.		*/GC_descr GC_double_descr(descriptor, nwords)register GC_descr descriptor;register word nwords;{    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {        descriptor = GC_bm_table[BYTES_TO_WORDS((word)descriptor)];    };    descriptor |= (descriptor & ~GC_DS_TAGS) >> nwords;    return(descriptor);}complex_descriptor * GC_make_sequence_descriptor();/* Build a descriptor for an array with nelements elements,	*//* each of which can be described by a simple descriptor.	*//* We try to optimize some common cases.			*//* If the result is COMPLEX, then a complex_descr* is returned  *//* in *complex_d.							*//* If the result is LEAF, then we built a LeafDescriptor in	*//* the structure pointed to by leaf.				*//* The tag in the leaf structure is not set.			*//* If the result is SIMPLE, then a GC_descr			*//* is returned in *simple_d.					*//* If the result is NO_MEM, then				*//* we failed to allocate the descriptor.			*//* The implementation knows that GC_DS_LENGTH is 0.		*//* *leaf, *complex_d, and *simple_d may be used as temporaries	*//* during the construction.					*/# define COMPLEX 2# define LEAF 1# define SIMPLE 0# define NO_MEM (-1)int GC_make_array_descriptor(nelements, size, descriptor,			     simple_d, complex_d, leaf)word size;word nelements;GC_descr descriptor;GC_descr *simple_d;complex_descriptor **complex_d;struct LeafDescriptor * leaf;{#   define OPT_THRESHOLD 50	/* For larger arrays, we try to combine descriptors of adjacent	*/	/* descriptors to speed up marking, and to reduce the amount	*/	/* of space needed on the mark stack.				*/    if ((descriptor & GC_DS_TAGS) == GC_DS_LENGTH) {      if ((word)descriptor == size) {    	*simple_d = nelements * descriptor;    	return(SIMPLE);      } else if ((word)descriptor == 0) {        *simple_d = (GC_descr)0;        return(SIMPLE);      }    }    if (nelements <= OPT_THRESHOLD) {      if (nelements <= 1) {        if (nelements == 1) {            *simple_d = descriptor;            return(SIMPLE);        } else {            *simple_d = (GC_descr)0;            return(SIMPLE);        }      }    } else if (size <= BITMAP_BITS/2    	       && (descriptor & GC_DS_TAGS) != GC_DS_PROC    	       && (size & (sizeof(word)-1)) == 0) {      int result =                GC_make_array_descriptor(nelements/2, 2*size,      				   GC_double_descr(descriptor,      				   		   BYTES_TO_WORDS(size)),      				   simple_d, complex_d, leaf);      if ((nelements & 1) == 0) {          return(result);      } else {          struct LeafDescriptor * one_element =              (struct LeafDescriptor *)        	GC_malloc_atomic(sizeof(struct LeafDescriptor));                    if (result == NO_MEM || one_element == 0) return(NO_MEM);          one_element -> ld_tag = LEAF_TAG;          one_element -> ld_size = size;          one_element -> ld_nelements = 1;          one_element -> ld_descriptor = descriptor;          switch(result) {            case SIMPLE:            {              struct LeafDescriptor * beginning =                (struct LeafDescriptor *)        	  GC_malloc_atomic(sizeof(struct LeafDescriptor));              if (beginning == 0) return(NO_MEM);              beginning -> ld_tag = LEAF_TAG;              beginning -> ld_size = size;              beginning -> ld_nelements = 1;              beginning -> ld_descriptor = *simple_d;              *complex_d = GC_make_sequence_descriptor(              			(complex_descriptor *)beginning,              			(complex_descriptor *)one_element);              break;            }            case LEAF:            {              struct LeafDescriptor * beginning =                (struct LeafDescriptor *)        	  GC_malloc_atomic(sizeof(struct LeafDescriptor));              if (beginning == 0) return(NO_MEM);              beginning -> ld_tag = LEAF_TAG;              beginning -> ld_size = leaf -> ld_size;              beginning -> ld_nelements = leaf -> ld_nelements;              beginning -> ld_descriptor = leaf -> ld_descriptor;              *complex_d = GC_make_sequence_descriptor(              			(complex_descriptor *)beginning,              			(complex_descriptor *)one_element);              break;            }            case COMPLEX:              *complex_d = GC_make_sequence_descriptor(              			*complex_d,              			(complex_descriptor *)one_element);              break;          }          return(COMPLEX);      }    }    {        leaf -> ld_size = size;        leaf -> ld_nelements = nelements;        leaf -> ld_descriptor = descriptor;        return(LEAF);    }}complex_descriptor * GC_make_sequence_descriptor(first, second)complex_descriptor * first;complex_descriptor * second;{    struct SequenceDescriptor * result =        (struct SequenceDescriptor *)        	GC_malloc(sizeof(struct SequenceDescriptor));    /* Can't result in overly conservative marking, since tags are	*/    /* very small integers. Probably faster than maintaining type	*/    /* info.								*/        if (result != 0) {    	result -> sd_tag = SEQUENCE_TAG;        result -> sd_first = first;        result -> sd_second = second;    }    return((complex_descriptor *)result);}#ifdef UNDEFINEDcomplex_descriptor * GC_make_complex_array_descriptor(nelements, descr)word nelements;complex_descriptor * descr;{    struct ComplexArrayDescriptor * result =        (struct ComplexArrayDescriptor *)        	GC_malloc(sizeof(struct ComplexArrayDescriptor));        if (result != 0) {    	result -> ad_tag = ARRAY_TAG;        result -> ad_nelements = nelements;        result -> ad_element_descr = descr;    }    return((complex_descriptor *)result);}#endifptr_t * GC_eobjfreelist;ptr_t * GC_arobjfreelist;mse * GC_typed_mark_proc GC_PROTO((register word * addr,				   register mse * mark_stack_ptr,				   mse * mark_stack_limit,				   word env));mse * GC_array_mark_proc GC_PROTO((register word * addr,				   register mse * mark_stack_ptr,				   mse * mark_stack_limit,				   word env));/* Caller does not hold allocation lock. */void GC_init_explicit_typing(){    register int i;    DCL_LOCK_STATE;    #   ifdef PRINTSTATS     	if (sizeof(struct LeafDescriptor) % sizeof(word) != 0)     	    ABORT("Bad leaf descriptor size");#   endif    DISABLE_SIGNALS();    LOCK();    if (GC_explicit_typing_initialized) {      UNLOCK();      ENABLE_SIGNALS();      return;    }    GC_explicit_typing_initialized = TRUE;    /* Set up object kind with simple indirect descriptor. */      GC_eobjfreelist = (ptr_t *)GC_new_free_list_inner();      GC_explicit_kind = GC_new_kind_inner(		      	    (void **)GC_eobjfreelist,		      	    (((word)WORDS_TO_BYTES(-1)) | GC_DS_PER_OBJECT),			    TRUE, TRUE);    		/* Descriptors are in the last word of the object. */      GC_typed_mark_proc_index = GC_new_proc_inner(GC_typed_mark_proc);    /* Set up object kind with array descriptor. */      GC_arobjfreelist = (ptr_t *)GC_new_free_list_inner();      GC_array_mark_proc_index = GC_new_proc_inner(GC_array_mark_proc);      GC_array_kind = GC_new_kind_inner(		      	    (void **)GC_arobjfreelist,			    GC_MAKE_PROC(GC_array_mark_proc_index, 0),			    FALSE, TRUE);      for (i = 0; i < WORDSZ/2; i++) {          GC_descr d = (((word)(-1)) >> (WORDSZ - i)) << (WORDSZ - i);          d |= GC_DS_BITMAP;          GC_bm_table[i] = d;      }    UNLOCK();    ENABLE_SIGNALS();}# if defined(__STDC__) || defined(__cplusplus)    mse * GC_typed_mark_proc(register word * addr,			     register mse * mark_stack_ptr,			     mse * mark_stack_limit,			     word env)# else    mse * GC_typed_mark_proc(addr, mark_stack_ptr, mark_stack_limit, env)    register word * addr;    register mse * mark_stack_ptr;    mse * mark_stack_limit;    word env;# endif

⌨️ 快捷键说明

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