root/gc/obj_map.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GC_invalidate_map
  2. GC_register_displacement
  3. GC_register_displacement_inner
  4. GC_add_map_entry

   1 /* 
   2  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
   3  * Copyright (c) 1991, 1992 by Xerox Corporation.  All rights reserved.
   4  * Copyright (c) 1999-2001 by Hewlett-Packard Company. All rights reserved.
   5  *
   6  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
   7  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
   8  *
   9  * Permission is hereby granted to use or copy this program
  10  * for any purpose,  provided the above notices are retained on all copies.
  11  * Permission to modify the code and to distribute modified code is granted,
  12  * provided the above notices are retained, and a notice that the code was
  13  * modified is included with the above copyright notice.
  14  */
  15   
  16 /* Routines for maintaining maps describing heap block
  17  * layouts for various object sizes.  Allows fast pointer validity checks
  18  * and fast location of object start locations on machines (such as SPARC)
  19  * with slow division.
  20  */
  21  
  22 # include "private/gc_priv.h"
  23 
  24 map_entry_type * GC_invalid_map = 0;
  25 
  26 /* Invalidate the object map associated with a block.   Free blocks     */
  27 /* are identified by invalid maps.                                      */
  28 void GC_invalidate_map(hhdr)
  29 hdr *hhdr;
  30 {
  31     register int displ;
  32     
  33     if (GC_invalid_map == 0) {
  34         GC_invalid_map = (map_entry_type *)GC_scratch_alloc(MAP_SIZE);
  35         if (GC_invalid_map == 0) {
  36             GC_err_printf0(
  37                 "Cant initialize GC_invalid_map: insufficient memory\n");
  38             EXIT();
  39         }
  40         for (displ = 0; displ < HBLKSIZE; displ++) {
  41             MAP_ENTRY(GC_invalid_map, displ) = OBJ_INVALID;
  42         }
  43     }
  44     hhdr -> hb_map = GC_invalid_map;
  45 }
  46 
  47 /* Consider pointers that are offset bytes displaced from the beginning */
  48 /* of an object to be valid.                                            */
  49 
  50 # if defined(__STDC__) || defined(__cplusplus)
  51     void GC_register_displacement(GC_word offset)
  52 # else
  53     void GC_register_displacement(offset) 
  54     GC_word offset;
  55 # endif
  56 {
  57     DCL_LOCK_STATE;
  58     
  59     DISABLE_SIGNALS();
  60     LOCK();
  61     GC_register_displacement_inner(offset);
  62     UNLOCK();
  63     ENABLE_SIGNALS();
  64 }
  65 
  66 void GC_register_displacement_inner(offset) 
  67 word offset;
  68 {
  69     register unsigned i;
  70     word map_entry = BYTES_TO_WORDS(offset);
  71     
  72     if (offset >= VALID_OFFSET_SZ) {
  73         ABORT("Bad argument to GC_register_displacement");
  74     }
  75     if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
  76     if (!GC_valid_offsets[offset]) {
  77       GC_valid_offsets[offset] = TRUE;
  78       GC_modws_valid_offsets[offset % sizeof(word)] = TRUE;
  79       if (!GC_all_interior_pointers) {
  80         for (i = 0; i <= MAXOBJSZ; i++) {
  81           if (GC_obj_map[i] != 0) {
  82              if (i == 0) {
  83                GC_obj_map[i][offset] = (map_entry_type)map_entry;
  84              } else {
  85                register unsigned j;
  86                register unsigned lb = WORDS_TO_BYTES(i);
  87                
  88                if (offset < lb) {
  89                  for (j = offset; j < HBLKSIZE; j += lb) {
  90                    GC_obj_map[i][j] = (map_entry_type)map_entry;
  91                  }
  92                }
  93              }
  94           }
  95         }
  96       }
  97     }
  98 }
  99 
 100 
 101 /* Add a heap block map for objects of size sz to obj_map.      */
 102 /* Return FALSE on failure.                                     */
 103 GC_bool GC_add_map_entry(sz)
 104 word sz;
 105 {
 106     register unsigned obj_start;
 107     register unsigned displ;
 108     register map_entry_type * new_map;
 109     word map_entry;
 110     
 111     if (sz > MAXOBJSZ) sz = 0;
 112     if (GC_obj_map[sz] != 0) {
 113         return(TRUE);
 114     }
 115     new_map = (map_entry_type *)GC_scratch_alloc(MAP_SIZE);
 116     if (new_map == 0) return(FALSE);
 117 #   ifdef PRINTSTATS
 118         GC_printf1("Adding block map for size %lu\n", (unsigned long)sz);
 119 #   endif
 120     for (displ = 0; displ < HBLKSIZE; displ++) {
 121         MAP_ENTRY(new_map,displ) = OBJ_INVALID;
 122     }
 123     if (sz == 0) {
 124         for(displ = 0; displ <= HBLKSIZE; displ++) {
 125             if (OFFSET_VALID(displ)) {
 126                 map_entry = BYTES_TO_WORDS(displ);
 127                 if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
 128                 MAP_ENTRY(new_map,displ) = (map_entry_type)map_entry;
 129             }
 130         }
 131     } else {
 132         for (obj_start = 0;
 133              obj_start + WORDS_TO_BYTES(sz) <= HBLKSIZE;
 134              obj_start += WORDS_TO_BYTES(sz)) {
 135              for (displ = 0; displ < WORDS_TO_BYTES(sz); displ++) {
 136                  if (OFFSET_VALID(displ)) {
 137                      map_entry = BYTES_TO_WORDS(displ);
 138                      if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
 139                      MAP_ENTRY(new_map, obj_start + displ) =
 140                                                 (map_entry_type)map_entry;
 141                  }
 142              }
 143         }
 144     }
 145     GC_obj_map[sz] = new_map;
 146     return(TRUE);
 147 }

/* [<][>][^][v][top][bottom][index][help] */