~ubuntu-branches/ubuntu/natty/libgc/natty-updates

« back to all changes in this revision

Viewing changes to obj_map.c

  • Committer: Bazaar Package Importer
  • Author(s): Ryan Murray
  • Date: 2002-03-25 20:27:15 UTC
  • Revision ID: james.westby@ubuntu.com-20020325202715-terff7kao1wrwok5
Tags: upstream-6.0+6.1alpha4
ImportĀ upstreamĀ versionĀ 6.0+6.1alpha4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}