~ubuntu-branches/ubuntu/quantal/libgc/quantal

« back to all changes in this revision

Viewing changes to obj_map.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Egger
  • Date: 2011-02-19 12:19:56 UTC
  • mfrom: (1.3.2 upstream) (0.1.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: james.westby@ubuntu.com-20110219121956-67rb69xlt5nud3v2
Tags: 1:7.1-5
Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
# include "private/gc_priv.h"
23
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
24
/* Consider pointers that are offset bytes displaced from the beginning */
48
25
/* of an object to be valid.                                            */
49
26
 
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
 
27
void GC_register_displacement(size_t offset)
56
28
{
57
29
    DCL_LOCK_STATE;
58
30
    
59
 
    DISABLE_SIGNALS();
60
31
    LOCK();
61
32
    GC_register_displacement_inner(offset);
62
33
    UNLOCK();
63
 
    ENABLE_SIGNALS();
64
34
}
65
35
 
66
 
void GC_register_displacement_inner(offset) 
67
 
word offset;
 
36
void GC_register_displacement_inner(size_t offset) 
68
37
{
69
 
    register unsigned i;
70
 
    word map_entry = BYTES_TO_WORDS(offset);
71
 
    
72
38
    if (offset >= VALID_OFFSET_SZ) {
73
39
        ABORT("Bad argument to GC_register_displacement");
74
40
    }
75
 
    if (map_entry > MAX_OFFSET) map_entry = OFFSET_TOO_BIG;
76
41
    if (!GC_valid_offsets[offset]) {
77
42
      GC_valid_offsets[offset] = TRUE;
78
43
      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
44
    }
98
45
}
99
46
 
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;
 
47
#ifdef MARK_BIT_PER_GRANULE
 
48
/* Add a heap block map for objects of size granules to obj_map.        */
 
49
/* Return FALSE on failure.                                             */
 
50
/* A size of 0 granules is used for large objects.                      */
 
51
GC_bool GC_add_map_entry(size_t granules)
105
52
{
106
 
    register unsigned obj_start;
107
 
    register unsigned displ;
108
 
    register map_entry_type * new_map;
109
 
    word map_entry;
 
53
    unsigned displ;
 
54
    short * new_map;
110
55
    
111
 
    if (sz > MAXOBJSZ) sz = 0;
112
 
    if (GC_obj_map[sz] != 0) {
 
56
    if (granules > BYTES_TO_GRANULES(MAXOBJBYTES)) granules = 0;
 
57
    if (GC_obj_map[granules] != 0) {
113
58
        return(TRUE);
114
59
    }
115
 
    new_map = (map_entry_type *)GC_scratch_alloc(MAP_SIZE);
 
60
    new_map = (short *)GC_scratch_alloc(MAP_LEN * sizeof(short));
116
61
    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
 
        }
 
62
    if (GC_print_stats)
 
63
        GC_log_printf("Adding block map for size of %u granules (%u bytes)\n",
 
64
                  (unsigned)granules, (unsigned)(GRANULES_TO_BYTES(granules)));
 
65
    if (granules == 0) {
 
66
      for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) {
 
67
        new_map[displ] = 1;  /* Nonzero to get us out of marker fast path. */
 
68
      }
131
69
    } 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
 
        }
 
70
      for (displ = 0; displ < BYTES_TO_GRANULES(HBLKSIZE); displ++) {
 
71
        new_map[displ] = (short)(displ % granules);
 
72
      }
144
73
    }
145
 
    GC_obj_map[sz] = new_map;
 
74
    GC_obj_map[granules] = new_map;
146
75
    return(TRUE);
147
76
}
 
77
#endif
 
78
 
 
79
static GC_bool offsets_initialized = FALSE;
 
80
 
 
81
void GC_initialize_offsets(void)
 
82
{
 
83
    if (!offsets_initialized) {
 
84
      int i;
 
85
      if (GC_all_interior_pointers) {
 
86
        for (i = 0; i < VALID_OFFSET_SZ; ++i) GC_valid_offsets[i] = TRUE;
 
87
      }
 
88
      offsets_initialized = TRUE;
 
89
    }
 
90
}