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

« back to all changes in this revision

Viewing changes to gcj_mlc.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 (c) 1991-1994 by Xerox Corporation.  All rights reserved.
 
3
 * Copyright (c) 1999 by Hewlett-Packard Company.  All rights reserved.
 
4
 *
 
5
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 
6
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 
7
 *
 
8
 * Permission is hereby granted to use or copy this program
 
9
 * for any purpose,  provided the above notices are retained on all copies.
 
10
 * Permission to modify the code and to distribute modified code is granted,
 
11
 * provided the above notices are retained, and a notice that the code was
 
12
 * modified is included with the above copyright notice.
 
13
 *
 
14
 */
 
15
/* Boehm, July 31, 1995 5:02 pm PDT */
 
16
 
 
17
#ifdef GC_GCJ_SUPPORT
 
18
 
 
19
/*
 
20
 * This is an allocator interface tuned for gcj (the GNU static
 
21
 * java compiler).
 
22
 *
 
23
 * Each allocated object has a pointer in its first word to a vtable,
 
24
 * which for our purposes is simply a structure describing the type of
 
25
 * the object.
 
26
 * This descriptor structure contains a GC marking descriptor at offset
 
27
 * MARK_DESCR_OFFSET.
 
28
 *
 
29
 * It is hoped that this interface may also be useful for other systems,
 
30
 * possibly with some tuning of the constants.  But the immediate goal
 
31
 * is to get better gcj performance.
 
32
 *
 
33
 * We assume:
 
34
 *  1) We have an ANSI conforming C compiler.
 
35
 *  2) Counting on explicit initialization of this interface is OK.
 
36
 *  3) FASTLOCK is not a significant win.
 
37
 */
 
38
 
 
39
#include "private/gc_pmark.h"
 
40
#include "gc_gcj.h"
 
41
#include "private/dbg_mlc.h"
 
42
 
 
43
GC_bool GC_gcj_malloc_initialized = FALSE;
 
44
 
 
45
int GC_gcj_kind;        /* Object kind for objects with descriptors     */
 
46
                        /* in "vtable".                                 */
 
47
int GC_gcj_debug_kind;  /* The kind of objects that is always marked    */
 
48
                        /* with a mark proc call.                       */
 
49
 
 
50
ptr_t * GC_gcjobjfreelist;
 
51
ptr_t * GC_gcjdebugobjfreelist;
 
52
 
 
53
/* Caller does not hold allocation lock. */
 
54
void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
 
55
{
 
56
    register int i;
 
57
    GC_bool ignore_gcj_info;
 
58
    DCL_LOCK_STATE;
 
59
 
 
60
    GC_init();  /* In case it's not already done.       */
 
61
    DISABLE_SIGNALS();
 
62
    LOCK();
 
63
    if (GC_gcj_malloc_initialized) {
 
64
      UNLOCK();
 
65
      ENABLE_SIGNALS();
 
66
      return;
 
67
    }
 
68
    GC_gcj_malloc_initialized = TRUE;
 
69
    ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
 
70
#   ifdef CONDPRINT
 
71
      if (GC_print_stats && ignore_gcj_info) {
 
72
        GC_printf0("Gcj-style type information is disabled!\n");
 
73
      }
 
74
#   endif
 
75
    GC_mark_procs[mp_index] = (GC_mark_proc)mp;
 
76
    if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
 
77
    /* Set up object kind gcj-style indirect descriptor. */
 
78
      GC_gcjobjfreelist = (ptr_t *)
 
79
          GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
 
80
      if (GC_gcjobjfreelist == 0) ABORT("Couldn't allocate GC_gcjobjfreelist");
 
81
      BZERO(GC_gcjobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
 
82
      GC_gcj_kind = GC_n_kinds++;
 
83
      GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist;
 
84
      GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0;
 
85
      if (ignore_gcj_info) {
 
86
        /* Use a simple length-based descriptor, thus forcing a fully   */
 
87
        /* conservative scan.                                           */
 
88
        GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
 
89
        GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
 
90
      } else {
 
91
        GC_obj_kinds[GC_gcj_kind].ok_descriptor =
 
92
          (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS))
 
93
           | GC_DS_PER_OBJECT);
 
94
        GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE;
 
95
      }
 
96
      GC_obj_kinds[GC_gcj_kind].ok_init = TRUE;
 
97
    /* Set up object kind for objects that require mark proc call.      */
 
98
      GC_gcjdebugobjfreelist = (ptr_t *)
 
99
          GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
 
100
      if (GC_gcjdebugobjfreelist == 0)
 
101
          ABORT("Couldn't allocate GC_gcjdebugobjfreelist");
 
102
      BZERO(GC_gcjdebugobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
 
103
      GC_gcj_debug_kind = GC_n_kinds++;
 
104
      GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist;
 
105
      GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0;
 
106
      if (ignore_gcj_info) {
 
107
        GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
 
108
        GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
 
109
      } else {
 
110
        GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor =
 
111
          GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */);
 
112
        GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE;
 
113
      }
 
114
      GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE;
 
115
    UNLOCK();
 
116
    ENABLE_SIGNALS();
 
117
}
 
118
 
 
119
ptr_t GC_clear_stack();
 
120
 
 
121
#define GENERAL_MALLOC(lb,k) \
 
122
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
 
123
    
 
124
#define GENERAL_MALLOC_IOP(lb,k) \
 
125
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
 
126
 
 
127
/* Allocate an object, clear it, and store the pointer to the   */
 
128
/* type structure (vtable in gcj).                              */
 
129
/* This adds a byte at the end of the object if GC_malloc would.*/
 
130
void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
 
131
{
 
132
register ptr_t op;
 
133
register ptr_t * opp;
 
134
register word lw;
 
135
DCL_LOCK_STATE;
 
136
 
 
137
    if( EXPECT(SMALL_OBJ(lb), 1) ) {
 
138
#       ifdef MERGE_SIZES
 
139
          lw = GC_size_map[lb];
 
140
#       else
 
141
          lw = ALIGNED_WORDS(lb);
 
142
#       endif
 
143
        opp = &(GC_gcjobjfreelist[lw]);
 
144
        LOCK();
 
145
        op = *opp;
 
146
        if( EXPECT(op == 0, 0)) {
 
147
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
 
148
            if (0 == op) {
 
149
                UNLOCK();
 
150
                return(GC_oom_fn(lb));
 
151
            }
 
152
#           ifdef MERGE_SIZES
 
153
                lw = GC_size_map[lb];   /* May have been uninitialized. */
 
154
#           endif
 
155
        } else {
 
156
            *opp = obj_link(op);
 
157
            GC_words_allocd += lw;
 
158
        }
 
159
        *(void **)op = ptr_to_struct_containing_descr;
 
160
        GC_ASSERT(((void **)op)[1] == 0);
 
161
        UNLOCK();
 
162
    } else {
 
163
        LOCK();
 
164
        op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
 
165
        if (0 == op) {
 
166
            UNLOCK();
 
167
            return(GC_oom_fn(lb));
 
168
        }
 
169
        *(void **)op = ptr_to_struct_containing_descr;
 
170
        UNLOCK();
 
171
    }
 
172
    return((GC_PTR) op);
 
173
}
 
174
 
 
175
/* Similar to GC_gcj_malloc, but add debug info.  This is allocated     */
 
176
/* with GC_gcj_debug_kind.                                              */
 
177
GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr,
 
178
                           GC_EXTRA_PARAMS)
 
179
{
 
180
    GC_PTR result;
 
181
 
 
182
    /* We clone the code from GC_debug_gcj_malloc, so that we   */
 
183
    /* dont end up with extra frames on the stack, which could  */
 
184
    /* confuse the backtrace.                                   */
 
185
    LOCK();
 
186
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
 
187
    if (result == 0) {
 
188
        UNLOCK();
 
189
        GC_err_printf2("GC_debug_gcj_malloc(%ld, 0x%lx) returning NIL (",
 
190
                       (unsigned long) lb,
 
191
                       (unsigned long) ptr_to_struct_containing_descr);
 
192
        GC_err_puts(s);
 
193
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
194
        return(GC_oom_fn(lb));
 
195
    }
 
196
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
 
197
    UNLOCK();
 
198
    if (!GC_debugging_started) {
 
199
        GC_start_debugging();
 
200
    }
 
201
    ADD_CALL_CHAIN(result, ra);
 
202
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
 
203
}
 
204
 
 
205
/* Similar to GC_gcj_malloc, but the size is in words, and we don't     */
 
206
/* adjust it.  The size is assumed to be such that it can be    */
 
207
/* allocated as a small object.                                 */
 
208
void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
 
209
{
 
210
ptr_t op;
 
211
ptr_t * opp;
 
212
DCL_LOCK_STATE;
 
213
 
 
214
    opp = &(GC_gcjobjfreelist[lw]);
 
215
    LOCK();
 
216
    op = *opp;
 
217
    if( EXPECT(op == 0, 0) ) {
 
218
        op = (ptr_t)GC_clear_stack(
 
219
                GC_generic_malloc_words_small_inner(lw, GC_gcj_kind));
 
220
        if (0 == op) {
 
221
            UNLOCK();
 
222
            return GC_oom_fn(WORDS_TO_BYTES(lw));
 
223
        }
 
224
    } else {
 
225
        *opp = obj_link(op);
 
226
        GC_words_allocd += lw;
 
227
    }
 
228
    *(void **)op = ptr_to_struct_containing_descr;
 
229
    UNLOCK();
 
230
    return((GC_PTR) op);
 
231
}
 
232
 
 
233
/* And a debugging version of the above:        */
 
234
void * GC_debug_gcj_fast_malloc(size_t lw,
 
235
                                void * ptr_to_struct_containing_descr,
 
236
                                GC_EXTRA_PARAMS)
 
237
{
 
238
    GC_PTR result;
 
239
    size_t lb = WORDS_TO_BYTES(lw);
 
240
 
 
241
    /* We clone the code from GC_debug_gcj_malloc, so that we   */
 
242
    /* dont end up with extra frames on the stack, which could  */
 
243
    /* confuse the backtrace.                                   */
 
244
    LOCK();
 
245
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
 
246
    if (result == 0) {
 
247
        UNLOCK();
 
248
        GC_err_printf2("GC_debug_gcj_fast_malloc(%ld, 0x%lx) returning NIL (",
 
249
                       (unsigned long) lw,
 
250
                       (unsigned long) ptr_to_struct_containing_descr);
 
251
        GC_err_puts(s);
 
252
        GC_err_printf1(":%ld)\n", (unsigned long)i);
 
253
        return GC_oom_fn(WORDS_TO_BYTES(lw));
 
254
    }
 
255
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
 
256
    UNLOCK();
 
257
    if (!GC_debugging_started) {
 
258
        GC_start_debugging();
 
259
    }
 
260
    ADD_CALL_CHAIN(result, ra);
 
261
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
 
262
}
 
263
 
 
264
void * GC_gcj_malloc_ignore_off_page(size_t lb,
 
265
                                     void * ptr_to_struct_containing_descr) 
 
266
{
 
267
register ptr_t op;
 
268
register ptr_t * opp;
 
269
register word lw;
 
270
DCL_LOCK_STATE;
 
271
 
 
272
    if( SMALL_OBJ(lb) ) {
 
273
#       ifdef MERGE_SIZES
 
274
          lw = GC_size_map[lb];
 
275
#       else
 
276
          lw = ALIGNED_WORDS(lb);
 
277
#       endif
 
278
        opp = &(GC_gcjobjfreelist[lw]);
 
279
        LOCK();
 
280
        if( (op = *opp) == 0 ) {
 
281
            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
 
282
#           ifdef MERGE_SIZES
 
283
                lw = GC_size_map[lb];   /* May have been uninitialized. */
 
284
#           endif
 
285
        } else {
 
286
            *opp = obj_link(op);
 
287
            GC_words_allocd += lw;
 
288
        }
 
289
        *(void **)op = ptr_to_struct_containing_descr;
 
290
        UNLOCK();
 
291
    } else {
 
292
        op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
 
293
        if (0 != op) {
 
294
          *(void **)op = ptr_to_struct_containing_descr;
 
295
        }
 
296
        UNLOCK();
 
297
    }
 
298
    return((GC_PTR) op);
 
299
}
 
300
 
 
301
#else
 
302
 
 
303
char GC_no_gcj_support;
 
304
 
 
305
#endif  /* GC_GCJ_SUPPORT */