OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [boehm-gc/] [mallocx.c] - Blame information for rev 14

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/*
2
 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
3
 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
4
 * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
5
 * Copyright (c) 2000 by Hewlett-Packard Company.  All rights reserved.
6
 *
7
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9
 *
10
 * Permission is hereby granted to use or copy this program
11
 * for any purpose,  provided the above notices are retained on all copies.
12
 * Permission to modify the code and to distribute modified code is granted,
13
 * provided the above notices are retained, and a notice that the code was
14
 * modified is included with the above copyright notice.
15
 */
16
 
17
/*
18
 * These are extra allocation routines which are likely to be less
19
 * frequently used than those in malloc.c.  They are separate in the
20
 * hope that the .o file will be excluded from statically linked
21
 * executables.  We should probably break this up further.
22
 */
23
 
24
#include <stdio.h>
25
#include "private/gc_priv.h"
26
 
27
extern ptr_t GC_clear_stack();  /* in misc.c, behaves like identity */
28
void GC_extend_size_map();      /* in misc.c. */
29
GC_bool GC_alloc_reclaim_list();        /* in malloc.c */
30
 
31
/* Some externally visible but unadvertised variables to allow access to */
32
/* free lists from inlined allocators without including gc_priv.h        */
33
/* or introducing dependencies on internal data structure layouts.       */
34
ptr_t * GC_CONST GC_objfreelist_ptr = GC_objfreelist;
35
ptr_t * GC_CONST GC_aobjfreelist_ptr = GC_aobjfreelist;
36
ptr_t * GC_CONST GC_uobjfreelist_ptr = GC_uobjfreelist;
37
# ifdef ATOMIC_UNCOLLECTABLE
38
    ptr_t * GC_CONST GC_auobjfreelist_ptr = GC_auobjfreelist;
39
# endif
40
 
41
 
42
GC_PTR GC_generic_or_special_malloc(lb,knd)
43
word lb;
44
int knd;
45
{
46
    switch(knd) {
47
#     ifdef STUBBORN_ALLOC
48
        case STUBBORN:
49
            return(GC_malloc_stubborn((size_t)lb));
50
#     endif
51
        case PTRFREE:
52
            return(GC_malloc_atomic((size_t)lb));
53
        case NORMAL:
54
            return(GC_malloc((size_t)lb));
55
        case UNCOLLECTABLE:
56
            return(GC_malloc_uncollectable((size_t)lb));
57
#       ifdef ATOMIC_UNCOLLECTABLE
58
          case AUNCOLLECTABLE:
59
            return(GC_malloc_atomic_uncollectable((size_t)lb));
60
#       endif /* ATOMIC_UNCOLLECTABLE */
61
        default:
62
            return(GC_generic_malloc(lb,knd));
63
    }
64
}
65
 
66
 
67
/* Change the size of the block pointed to by p to contain at least   */
68
/* lb bytes.  The object may be (and quite likely will be) moved.     */
69
/* The kind (e.g. atomic) is the same as that of the old.             */
70
/* Shrinking of large blocks is not implemented well.                 */
71
# ifdef __STDC__
72
    GC_PTR GC_realloc(GC_PTR p, size_t lb)
73
# else
74
    GC_PTR GC_realloc(p,lb)
75
    GC_PTR p;
76
    size_t lb;
77
# endif
78
{
79
register struct hblk * h;
80
register hdr * hhdr;
81
register word sz;        /* Current size in bytes       */
82
register word orig_sz;   /* Original sz in bytes        */
83
int obj_kind;
84
 
85
    if (p == 0) return(GC_malloc(lb));   /* Required by ANSI */
86
    h = HBLKPTR(p);
87
    hhdr = HDR(h);
88
    sz = hhdr -> hb_sz;
89
    obj_kind = hhdr -> hb_obj_kind;
90
    sz = WORDS_TO_BYTES(sz);
91
    orig_sz = sz;
92
 
93
    if (sz > MAXOBJBYTES) {
94
        /* Round it up to the next whole heap block */
95
          register word descr;
96
 
97
          sz = (sz+HBLKSIZE-1) & (~HBLKMASK);
98
          hhdr -> hb_sz = BYTES_TO_WORDS(sz);
99
          descr = GC_obj_kinds[obj_kind].ok_descriptor;
100
          if (GC_obj_kinds[obj_kind].ok_relocate_descr) descr += sz;
101
          hhdr -> hb_descr = descr;
102
          if (IS_UNCOLLECTABLE(obj_kind)) GC_non_gc_bytes += (sz - orig_sz);
103
          /* Extra area is already cleared by GC_alloc_large_and_clear. */
104
    }
105
    if (ADD_SLOP(lb) <= sz) {
106
        if (lb >= (sz >> 1)) {
107
#           ifdef STUBBORN_ALLOC
108
                if (obj_kind == STUBBORN) GC_change_stubborn(p);
109
#           endif
110
            if (orig_sz > lb) {
111
              /* Clear unneeded part of object to avoid bogus pointer */
112
              /* tracing.                                             */
113
              /* Safe for stubborn objects.                           */
114
                BZERO(((ptr_t)p) + lb, orig_sz - lb);
115
            }
116
            return(p);
117
        } else {
118
            /* shrink */
119
              GC_PTR result =
120
                        GC_generic_or_special_malloc((word)lb, obj_kind);
121
 
122
              if (result == 0) return(0);
123
                  /* Could also return original object.  But this       */
124
                  /* gives the client warning of imminent disaster.     */
125
              BCOPY(p, result, lb);
126
#             ifndef IGNORE_FREE
127
                GC_free(p);
128
#             endif
129
              return(result);
130
        }
131
    } else {
132
        /* grow */
133
          GC_PTR result =
134
                GC_generic_or_special_malloc((word)lb, obj_kind);
135
 
136
          if (result == 0) return(0);
137
          BCOPY(p, result, sz);
138
#         ifndef IGNORE_FREE
139
            GC_free(p);
140
#         endif
141
          return(result);
142
    }
143
}
144
 
145
# if defined(REDIRECT_MALLOC) && !defined(REDIRECT_REALLOC)
146
#   define REDIRECT_REALLOC GC_realloc
147
# endif
148
 
149
# ifdef REDIRECT_REALLOC
150
 
151
/* As with malloc, avoid two levels of extra calls here.        */
152
# ifdef GC_ADD_CALLER
153
#   define RA GC_RETURN_ADDR,
154
# else
155
#   define RA
156
# endif
157
# define GC_debug_realloc_replacement(p, lb) \
158
        GC_debug_realloc(p, lb, RA "unknown", 0)
159
 
160
# ifdef __STDC__
161
    GC_PTR realloc(GC_PTR p, size_t lb)
162
# else
163
    GC_PTR realloc(p,lb)
164
    GC_PTR p;
165
    size_t lb;
166
# endif
167
  {
168
    return(REDIRECT_REALLOC(p, lb));
169
  }
170
 
171
# undef GC_debug_realloc_replacement
172
# endif /* REDIRECT_REALLOC */
173
 
174
 
175
/* The same thing, except caller does not hold allocation lock. */
176
/* We avoid holding allocation lock while we clear memory.      */
177
ptr_t GC_generic_malloc_ignore_off_page(lb, k)
178
register size_t lb;
179
register int k;
180
{
181
    register ptr_t result;
182
    word lw;
183
    word n_blocks;
184
    GC_bool init;
185
    DCL_LOCK_STATE;
186
 
187
    if (SMALL_OBJ(lb))
188
        return(GC_generic_malloc((word)lb, k));
189
    lw = ROUNDED_UP_WORDS(lb);
190
    n_blocks = OBJ_SZ_TO_BLOCKS(lw);
191
    init = GC_obj_kinds[k].ok_init;
192
    if (GC_have_errors) GC_print_all_errors();
193
    GC_INVOKE_FINALIZERS();
194
    DISABLE_SIGNALS();
195
    LOCK();
196
    result = (ptr_t)GC_alloc_large(lw, k, IGNORE_OFF_PAGE);
197
    if (0 != result) {
198
        if (GC_debugging_started) {
199
            BZERO(result, n_blocks * HBLKSIZE);
200
        } else {
201
#           ifdef THREADS
202
              /* Clear any memory that might be used for GC descriptors */
203
              /* before we release the lock.                          */
204
                ((word *)result)[0] = 0;
205
                ((word *)result)[1] = 0;
206
                ((word *)result)[lw-1] = 0;
207
                ((word *)result)[lw-2] = 0;
208
#           endif
209
        }
210
    }
211
    GC_words_allocd += lw;
212
    UNLOCK();
213
    ENABLE_SIGNALS();
214
    if (0 == result) {
215
        return((*GC_oom_fn)(lb));
216
    } else {
217
        if (init && !GC_debugging_started) {
218
            BZERO(result, n_blocks * HBLKSIZE);
219
        }
220
        return(result);
221
    }
222
}
223
 
224
# if defined(__STDC__) || defined(__cplusplus)
225
  void * GC_malloc_ignore_off_page(size_t lb)
226
# else
227
  char * GC_malloc_ignore_off_page(lb)
228
  register size_t lb;
229
# endif
230
{
231
    return((GC_PTR)GC_generic_malloc_ignore_off_page(lb, NORMAL));
232
}
233
 
234
# if defined(__STDC__) || defined(__cplusplus)
235
  void * GC_malloc_atomic_ignore_off_page(size_t lb)
236
# else
237
  char * GC_malloc_atomic_ignore_off_page(lb)
238
  register size_t lb;
239
# endif
240
{
241
    return((GC_PTR)GC_generic_malloc_ignore_off_page(lb, PTRFREE));
242
}
243
 
244
/* Increment GC_words_allocd from code that doesn't have direct access  */
245
/* to GC_arrays.                                                        */
246
# ifdef __STDC__
247
void GC_incr_words_allocd(size_t n)
248
{
249
    GC_words_allocd += n;
250
}
251
 
252
/* The same for GC_mem_freed.                           */
253
void GC_incr_mem_freed(size_t n)
254
{
255
    GC_mem_freed += n;
256
}
257
# endif /* __STDC__ */
258
 
259
/* Analogous to the above, but assumes a small object size, and         */
260
/* bypasses MERGE_SIZES mechanism.  Used by gc_inline.h.                */
261
ptr_t GC_generic_malloc_words_small_inner(lw, k)
262
register word lw;
263
register int k;
264
{
265
register ptr_t op;
266
register ptr_t *opp;
267
register struct obj_kind * kind = GC_obj_kinds + k;
268
 
269
    opp = &(kind -> ok_freelist[lw]);
270
    if( (op = *opp) == 0 ) {
271
        if (!GC_is_initialized) {
272
            GC_init_inner();
273
        }
274
        if (kind -> ok_reclaim_list != 0 || GC_alloc_reclaim_list(kind)) {
275
            op = GC_clear_stack(GC_allocobj((word)lw, k));
276
        }
277
        if (op == 0) {
278
            UNLOCK();
279
            ENABLE_SIGNALS();
280
            return ((*GC_oom_fn)(WORDS_TO_BYTES(lw)));
281
        }
282
    }
283
    *opp = obj_link(op);
284
    obj_link(op) = 0;
285
    GC_words_allocd += lw;
286
    return((ptr_t)op);
287
}
288
 
289
/* Analogous to the above, but assumes a small object size, and         */
290
/* bypasses MERGE_SIZES mechanism.  Used by gc_inline.h.                */
291
#ifdef __STDC__
292
     ptr_t GC_generic_malloc_words_small(size_t lw, int k)
293
#else 
294
     ptr_t GC_generic_malloc_words_small(lw, k)
295
     register word lw;
296
     register int k;
297
#endif
298
{
299
register ptr_t op;
300
DCL_LOCK_STATE;
301
 
302
    if (GC_have_errors) GC_print_all_errors();
303
    GC_INVOKE_FINALIZERS();
304
    DISABLE_SIGNALS();
305
    LOCK();
306
    op = GC_generic_malloc_words_small_inner(lw, k);
307
    UNLOCK();
308
    ENABLE_SIGNALS();
309
    return((ptr_t)op);
310
}
311
 
312
#if defined(THREADS) && !defined(SRC_M3)
313
 
314
extern signed_word GC_mem_found;   /* Protected by GC lock.  */
315
 
316
#ifdef PARALLEL_MARK
317
volatile signed_word GC_words_allocd_tmp = 0;
318
                        /* Number of words of memory allocated since    */
319
                        /* we released the GC lock.  Instead of         */
320
                        /* reacquiring the GC lock just to add this in, */
321
                        /* we add it in the next time we reacquire      */
322
                        /* the lock.  (Atomically adding it doesn't     */
323
                        /* work, since we would have to atomically      */
324
                        /* update it in GC_malloc, which is too         */
325
                        /* expensive.                                   */
326
#endif /* PARALLEL_MARK */
327
 
328
/* See reclaim.c: */
329
extern ptr_t GC_reclaim_generic();
330
 
331
/* Return a list of 1 or more objects of the indicated size, linked     */
332
/* through the first word in the object.  This has the advantage that   */
333
/* it acquires the allocation lock only once, and may greatly reduce    */
334
/* time wasted contending for the allocation lock.  Typical usage would */
335
/* be in a thread that requires many items of the same size.  It would  */
336
/* keep its own free list in thread-local storage, and call             */
337
/* GC_malloc_many or friends to replenish it.  (We do not round up      */
338
/* object sizes, since a call indicates the intention to consume many   */
339
/* objects of exactly this size.)                                       */
340
/* We return the free-list by assigning it to *result, since it is      */
341
/* not safe to return, e.g. a linked list of pointer-free objects,      */
342
/* since the collector would not retain the entire list if it were      */
343
/* invoked just as we were returning.                                   */
344
/* Note that the client should usually clear the link field.            */
345
void GC_generic_malloc_many(lb, k, result)
346
register word lb;
347
register int k;
348
ptr_t *result;
349
{
350
ptr_t op;
351
ptr_t p;
352
ptr_t *opp;
353
word lw;
354
word my_words_allocd = 0;
355
struct obj_kind * ok = &(GC_obj_kinds[k]);
356
DCL_LOCK_STATE;
357
 
358
#   if defined(GATHERSTATS) || defined(PARALLEL_MARK)
359
#     define COUNT_ARG , &my_words_allocd
360
#   else
361
#     define COUNT_ARG
362
#     define NEED_TO_COUNT
363
#   endif
364
    if (!SMALL_OBJ(lb)) {
365
        op = GC_generic_malloc(lb, k);
366
        if(0 != op) obj_link(op) = 0;
367
        *result = op;
368
        return;
369
    }
370
    lw = ALIGNED_WORDS(lb);
371
    if (GC_have_errors) GC_print_all_errors();
372
    GC_INVOKE_FINALIZERS();
373
    DISABLE_SIGNALS();
374
    LOCK();
375
    if (!GC_is_initialized) GC_init_inner();
376
    /* Do our share of marking work */
377
      if (GC_incremental && !GC_dont_gc) {
378
        ENTER_GC();
379
        GC_collect_a_little_inner(1);
380
        EXIT_GC();
381
      }
382
    /* First see if we can reclaim a page of objects waiting to be */
383
    /* reclaimed.                                                  */
384
    {
385
        struct hblk ** rlh = ok -> ok_reclaim_list;
386
        struct hblk * hbp;
387
        hdr * hhdr;
388
 
389
        rlh += lw;
390
        while ((hbp = *rlh) != 0) {
391
            hhdr = HDR(hbp);
392
            *rlh = hhdr -> hb_next;
393
            hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
394
#           ifdef PARALLEL_MARK
395
                {
396
                  signed_word my_words_allocd_tmp = GC_words_allocd_tmp;
397
 
398
                  GC_ASSERT(my_words_allocd_tmp >= 0);
399
                  /* We only decrement it while holding the GC lock.    */
400
                  /* Thus we can't accidentally adjust it down in more  */
401
                  /* than one thread simultaneously.                    */
402
                  if (my_words_allocd_tmp != 0) {
403
                    (void)GC_atomic_add(
404
                                (volatile GC_word *)(&GC_words_allocd_tmp),
405
                                (GC_word)(-my_words_allocd_tmp));
406
                    GC_words_allocd += my_words_allocd_tmp;
407
                  }
408
                }
409
                GC_acquire_mark_lock();
410
                ++ GC_fl_builder_count;
411
                UNLOCK();
412
                ENABLE_SIGNALS();
413
                GC_release_mark_lock();
414
#           endif
415
            op = GC_reclaim_generic(hbp, hhdr, lw,
416
                                    ok -> ok_init, 0 COUNT_ARG);
417
            if (op != 0) {
418
#             ifdef NEED_TO_COUNT
419
                /* We are neither gathering statistics, nor marking in  */
420
                /* parallel.  Thus GC_reclaim_generic doesn't count     */
421
                /* for us.                                              */
422
                for (p = op; p != 0; p = obj_link(p)) {
423
                  my_words_allocd += lw;
424
                }
425
#             endif
426
#             if defined(GATHERSTATS)
427
                /* We also reclaimed memory, so we need to adjust       */
428
                /* that count.                                          */
429
                /* This should be atomic, so the results may be         */
430
                /* inaccurate.                                          */
431
                GC_mem_found += my_words_allocd;
432
#             endif
433
#             ifdef PARALLEL_MARK
434
                *result = op;
435
                (void)GC_atomic_add(
436
                                (volatile GC_word *)(&GC_words_allocd_tmp),
437
                                (GC_word)(my_words_allocd));
438
                GC_acquire_mark_lock();
439
                -- GC_fl_builder_count;
440
                if (GC_fl_builder_count == 0) GC_notify_all_builder();
441
                GC_release_mark_lock();
442
                (void) GC_clear_stack(0);
443
                return;
444
#             else
445
                GC_words_allocd += my_words_allocd;
446
                goto out;
447
#             endif
448
            }
449
#           ifdef PARALLEL_MARK
450
              GC_acquire_mark_lock();
451
              -- GC_fl_builder_count;
452
              if (GC_fl_builder_count == 0) GC_notify_all_builder();
453
              GC_release_mark_lock();
454
              DISABLE_SIGNALS();
455
              LOCK();
456
              /* GC lock is needed for reclaim list access.     We      */
457
              /* must decrement fl_builder_count before reaquiring GC   */
458
              /* lock.  Hopefully this path is rare.                    */
459
#           endif
460
        }
461
    }
462
    /* Next try to use prefix of global free list if there is one.      */
463
    /* We don't refill it, but we need to use it up before allocating   */
464
    /* a new block ourselves.                                           */
465
      opp = &(GC_obj_kinds[k].ok_freelist[lw]);
466
      if ( (op = *opp) != 0 ) {
467
        *opp = 0;
468
        my_words_allocd = 0;
469
        for (p = op; p != 0; p = obj_link(p)) {
470
          my_words_allocd += lw;
471
          if (my_words_allocd >= BODY_SZ) {
472
            *opp = obj_link(p);
473
            obj_link(p) = 0;
474
            break;
475
          }
476
        }
477
        GC_words_allocd += my_words_allocd;
478
        goto out;
479
      }
480
    /* Next try to allocate a new block worth of objects of this size.  */
481
    {
482
        struct hblk *h = GC_allochblk(lw, k, 0);
483
        if (h != 0) {
484
          if (IS_UNCOLLECTABLE(k)) GC_set_hdr_marks(HDR(h));
485
          GC_words_allocd += BYTES_TO_WORDS(HBLKSIZE)
486
                               - BYTES_TO_WORDS(HBLKSIZE) % lw;
487
#         ifdef PARALLEL_MARK
488
            GC_acquire_mark_lock();
489
            ++ GC_fl_builder_count;
490
            UNLOCK();
491
            ENABLE_SIGNALS();
492
            GC_release_mark_lock();
493
#         endif
494
 
495
          op = GC_build_fl(h, lw, ok -> ok_init, 0);
496
#         ifdef PARALLEL_MARK
497
            *result = op;
498
            GC_acquire_mark_lock();
499
            -- GC_fl_builder_count;
500
            if (GC_fl_builder_count == 0) GC_notify_all_builder();
501
            GC_release_mark_lock();
502
            (void) GC_clear_stack(0);
503
            return;
504
#         else
505
            goto out;
506
#         endif
507
        }
508
    }
509
 
510
    /* As a last attempt, try allocating a single object.  Note that    */
511
    /* this may trigger a collection or expand the heap.                */
512
      op = GC_generic_malloc_inner(lb, k);
513
      if (0 != op) obj_link(op) = 0;
514
 
515
  out:
516
    *result = op;
517
    UNLOCK();
518
    ENABLE_SIGNALS();
519
    (void) GC_clear_stack(0);
520
}
521
 
522
GC_PTR GC_malloc_many(size_t lb)
523
{
524
    ptr_t result;
525
    GC_generic_malloc_many(lb, NORMAL, &result);
526
    return result;
527
}
528
 
529
/* Note that the "atomic" version of this would be unsafe, since the    */
530
/* links would not be seen by the collector.                            */
531
# endif
532
 
533
/* Allocate lb bytes of pointerful, traced, but not collectable data */
534
# ifdef __STDC__
535
    GC_PTR GC_malloc_uncollectable(size_t lb)
536
# else
537
    GC_PTR GC_malloc_uncollectable(lb)
538
    size_t lb;
539
# endif
540
{
541
register ptr_t op;
542
register ptr_t *opp;
543
register word lw;
544
DCL_LOCK_STATE;
545
 
546
    if( SMALL_OBJ(lb) ) {
547
#       ifdef MERGE_SIZES
548
          if (EXTRA_BYTES != 0 && lb != 0) lb--;
549
                  /* We don't need the extra byte, since this won't be  */
550
                  /* collected anyway.                                  */
551
          lw = GC_size_map[lb];
552
#       else
553
          lw = ALIGNED_WORDS(lb);
554
#       endif
555
        opp = &(GC_uobjfreelist[lw]);
556
        FASTLOCK();
557
        if( FASTLOCK_SUCCEEDED() && (op = *opp) != 0 ) {
558
            /* See above comment on signals.    */
559
            *opp = obj_link(op);
560
            obj_link(op) = 0;
561
            GC_words_allocd += lw;
562
            /* Mark bit ws already set on free list.  It will be        */
563
            /* cleared only temporarily during a collection, as a       */
564
            /* result of the normal free list mark bit clearing.        */
565
            GC_non_gc_bytes += WORDS_TO_BYTES(lw);
566
            FASTUNLOCK();
567
            return((GC_PTR) op);
568
        }
569
        FASTUNLOCK();
570
        op = (ptr_t)GC_generic_malloc((word)lb, UNCOLLECTABLE);
571
    } else {
572
        op = (ptr_t)GC_generic_malloc((word)lb, UNCOLLECTABLE);
573
    }
574
    if (0 == op) return(0);
575
    /* We don't need the lock here, since we have an undisguised        */
576
    /* pointer.  We do need to hold the lock while we adjust            */
577
    /* mark bits.                                                       */
578
    {
579
        register struct hblk * h;
580
 
581
        h = HBLKPTR(op);
582
        lw = HDR(h) -> hb_sz;
583
 
584
        DISABLE_SIGNALS();
585
        LOCK();
586
        GC_set_mark_bit(op);
587
        GC_non_gc_bytes += WORDS_TO_BYTES(lw);
588
        UNLOCK();
589
        ENABLE_SIGNALS();
590
        return((GC_PTR) op);
591
    }
592
}
593
 
594
#ifdef __STDC__
595
/* Not well tested nor integrated.      */
596
/* Debug version is tricky and currently missing.       */
597
#include <limits.h>
598
 
599
GC_PTR GC_memalign(size_t align, size_t lb)
600
{
601
    size_t new_lb;
602
    size_t offset;
603
    ptr_t result;
604
 
605
#   ifdef ALIGN_DOUBLE
606
        if (align <= WORDS_TO_BYTES(2) && lb > align) return GC_malloc(lb);
607
#   endif
608
    if (align <= WORDS_TO_BYTES(1)) return GC_malloc(lb);
609
    if (align >= HBLKSIZE/2 || lb >= HBLKSIZE/2) {
610
        if (align > HBLKSIZE) return GC_oom_fn(LONG_MAX-1024) /* Fail */;
611
        return GC_malloc(lb <= HBLKSIZE? HBLKSIZE : lb);
612
            /* Will be HBLKSIZE aligned.        */
613
    }
614
    /* We could also try to make sure that the real rounded-up object size */
615
    /* is a multiple of align.  That would be correct up to HBLKSIZE.      */
616
    new_lb = lb + align - 1;
617
    result = GC_malloc(new_lb);
618
    offset = (word)result % align;
619
    if (offset != 0) {
620
        offset = align - offset;
621
        if (!GC_all_interior_pointers) {
622
            if (offset >= VALID_OFFSET_SZ) return GC_malloc(HBLKSIZE);
623
            GC_register_displacement(offset);
624
        }
625
    }
626
    result = (GC_PTR) ((ptr_t)result + offset);
627
    GC_ASSERT((word)result % align == 0);
628
    return result;
629
}
630
#endif 
631
 
632
# ifdef ATOMIC_UNCOLLECTABLE
633
/* Allocate lb bytes of pointerfree, untraced, uncollectable data       */
634
/* This is normally roughly equivalent to the system malloc.            */
635
/* But it may be useful if malloc is redefined.                         */
636
# ifdef __STDC__
637
    GC_PTR GC_malloc_atomic_uncollectable(size_t lb)
638
# else
639
    GC_PTR GC_malloc_atomic_uncollectable(lb)
640
    size_t lb;
641
# endif
642
{
643
register ptr_t op;
644
register ptr_t *opp;
645
register word lw;
646
DCL_LOCK_STATE;
647
 
648
    if( SMALL_OBJ(lb) ) {
649
#       ifdef MERGE_SIZES
650
          if (EXTRA_BYTES != 0 && lb != 0) lb--;
651
                  /* We don't need the extra byte, since this won't be  */
652
                  /* collected anyway.                                  */
653
          lw = GC_size_map[lb];
654
#       else
655
          lw = ALIGNED_WORDS(lb);
656
#       endif
657
        opp = &(GC_auobjfreelist[lw]);
658
        FASTLOCK();
659
        if( FASTLOCK_SUCCEEDED() && (op = *opp) != 0 ) {
660
            /* See above comment on signals.    */
661
            *opp = obj_link(op);
662
            obj_link(op) = 0;
663
            GC_words_allocd += lw;
664
            /* Mark bit was already set while object was on free list. */
665
            GC_non_gc_bytes += WORDS_TO_BYTES(lw);
666
            FASTUNLOCK();
667
            return((GC_PTR) op);
668
        }
669
        FASTUNLOCK();
670
        op = (ptr_t)GC_generic_malloc((word)lb, AUNCOLLECTABLE);
671
    } else {
672
        op = (ptr_t)GC_generic_malloc((word)lb, AUNCOLLECTABLE);
673
    }
674
    if (0 == op) return(0);
675
    /* We don't need the lock here, since we have an undisguised        */
676
    /* pointer.  We do need to hold the lock while we adjust            */
677
    /* mark bits.                                                       */
678
    {
679
        register struct hblk * h;
680
 
681
        h = HBLKPTR(op);
682
        lw = HDR(h) -> hb_sz;
683
 
684
        DISABLE_SIGNALS();
685
        LOCK();
686
        GC_set_mark_bit(op);
687
        GC_non_gc_bytes += WORDS_TO_BYTES(lw);
688
        UNLOCK();
689
        ENABLE_SIGNALS();
690
        return((GC_PTR) op);
691
    }
692
}
693
 
694
#endif /* ATOMIC_UNCOLLECTABLE */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.