示例#1
0
/* Currently for debugger use only: */
void GC_print_free_list(int kind, size_t sz_in_granules)
{
    struct obj_kind * ok = &GC_obj_kinds[kind];
    ptr_t flh = ok -> ok_freelist[sz_in_granules];
    struct hblk *lastBlock = 0;
    int n;

    GC_printf("%d: %p;", 0, flh);

    for (n = 1; flh; n++) {
        struct hblk *block = HBLKPTR(flh);
        if (block != lastBlock) {
            GC_printf("\nIn heap block at %p:\n\t", block);
            lastBlock = block;
        }
        GC_printf("%d: %p;", n, flh);
        flh = obj_link(flh);
    }
}
示例#2
0
/* Explicitly deallocate an object p.                           */
GC_API void GC_CALL GC_free(void * p)
{
    struct hblk *h;
    hdr *hhdr;
    DCL_LOCK_STATE;

    // Note: if you want debug output here, use puts not GC_printf
    // the later crashes for some reason und
    //    puts("GC_free called");

    if (p == 0) return;

    // get the header for the block this pointer resides in
    h = HBLKPTR(p);
    if (!h) return;

    hhdr = HDR(h);
    if (!hhdr) return;

    //can't free anything from an uncollectable block!
    if( hhdr -> hb_obj_kind != UNCOLLECTABLE ) {
      // record at block level for now
      hhdr->hb_flags |= HAS_PENDING_FREE;

      GC_bytes_pending_free += hhdr->hb_sz;

      if( GC_pending_free_high < p ) {
        GC_pending_free_high = p;
      }
      if( GC_pending_free_low > p ) {
        GC_pending_free_low = p;
      }


    } else {
      GC_force_deallocate(p);
    }
}
示例#3
0
  GC_INNER void GC_free_inner(void * p)
  {
    struct hblk *h;
    hdr *hhdr;
    size_t sz; /* bytes */
    size_t ngranules;  /* sz in granules */
    void ** flh;
    int knd;
    struct obj_kind * ok;
    DCL_LOCK_STATE;

    h = HBLKPTR(p);
    hhdr = HDR(h);
    knd = hhdr -> hb_obj_kind;
    sz = hhdr -> hb_sz;
    ngranules = BYTES_TO_GRANULES(sz);
    ok = &GC_obj_kinds[knd];
    if (ngranules <= MAXOBJGRANULES) {
        GC_bytes_freed += sz;
        if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= sz;
        if (ok -> ok_init) {
            BZERO((word *)p + 1, sz-sizeof(word));
        }
        flh = &(ok -> ok_freelist[ngranules]);
        obj_link(p) = *flh;
        *flh = (ptr_t)p;
    } else {
        size_t nblocks = OBJ_SZ_TO_BLOCKS(sz);
        GC_bytes_freed += sz;
        if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= sz;
        if (nblocks > 1) {
          GC_large_allocd_bytes -= nblocks * HBLKSIZE;
        }
        GC_freehblk(h);
    }
  }
示例#4
0
/* debugging intolerably slow.)                                 */
GC_API void * GC_CALL GC_same_obj(void *p, void *q)
{
    struct hblk *h;
    hdr *hhdr;
    ptr_t base, limit;
    word sz;

    if (!GC_is_initialized) GC_init();
    hhdr = HDR((word)p);
    if (hhdr == 0) {
        if (divHBLKSZ((word)p) != divHBLKSZ((word)q)
            && HDR((word)q) != 0) {
            goto fail;
        }
        return(p);
    }
    /* If it's a pointer to the middle of a large object, move it       */
    /* to the beginning.                                                */
    if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
        h = HBLKPTR(p) - (word)hhdr;
        hhdr = HDR(h);
        while (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
           h = FORWARDED_ADDR(h, hhdr);
           hhdr = HDR(h);
        }
        limit = (ptr_t)h + hhdr -> hb_sz;
        if ((ptr_t)p >= limit || (ptr_t)q >= limit || (ptr_t)q < (ptr_t)h ) {
            goto fail;
        }
        return(p);
    }
    sz = hhdr -> hb_sz;
    if (sz > MAXOBJBYTES) {
      base = (ptr_t)HBLKPTR(p);
      limit = base + sz;
      if ((ptr_t)p >= limit) {
        goto fail;
      }
    } else {
      size_t offset;
      size_t pdispl = HBLKDISPL(p);

      offset = pdispl % sz;
      if (HBLKPTR(p) != HBLKPTR(q)) goto fail;
                /* W/o this check, we might miss an error if    */
                /* q points to the first object on a page, and  */
                /* points just before the page.                 */
      base = (ptr_t)p - offset;
      limit = base + sz;
    }
    /* [base, limit) delimits the object containing p, if any.  */
    /* If p is not inside a valid object, then either q is      */
    /* also outside any valid object, or it is outside          */
    /* [base, limit).                                           */
    if ((ptr_t)q >= limit || (ptr_t)q < base) {
        goto fail;
    }
    return(p);
fail:
    (*GC_same_obj_print_proc)((ptr_t)p, (ptr_t)q);
    return(p);
}
示例#5
0
/* Currently useless for multithreaded worlds.                          */
GC_API void * GC_CALL GC_is_visible(void *p)
{
    hdr *hhdr;

    if ((word)p & (ALIGNMENT - 1)) goto fail;
    if (!GC_is_initialized) GC_init();
#   ifdef THREADS
        hhdr = HDR((word)p);
        if (hhdr != 0 && GC_base(p) == 0) {
            goto fail;
        } else {
            /* May be inside thread stack.  We can't do much. */
            return(p);
        }
#   else
        /* Check stack first: */
          if (GC_on_stack(p)) return(p);
        hhdr = HDR((word)p);
        if (hhdr == 0) {
            if (GC_is_static_root(p)) return(p);
            /* Else do it again correctly:      */
#           if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || \
                defined(MSWINCE) || defined(PCR))
                GC_register_dynamic_libraries();
                if (GC_is_static_root(p))
                    return(p);
#           endif
            goto fail;
        } else {
            /* p points to the heap. */
            word descr;
            ptr_t base = GC_base(p);    /* Should be manually inlined? */

            if (base == 0) goto fail;
            if (HBLKPTR(base) != HBLKPTR(p)) hhdr = HDR((word)p);
            descr = hhdr -> hb_descr;
    retry:
            switch(descr & GC_DS_TAGS) {
                case GC_DS_LENGTH:
                    if ((word)((ptr_t)p - (ptr_t)base) > (word)descr) goto fail;
                    break;
                case GC_DS_BITMAP:
                    if ((ptr_t)p - (ptr_t)base
                         >= WORDS_TO_BYTES(BITMAP_BITS)
                         || ((word)p & (sizeof(word) - 1))) goto fail;
                    if (!(((word)1 << (WORDSZ - ((ptr_t)p - (ptr_t)base) - 1))
                          & descr)) goto fail;
                    break;
                case GC_DS_PROC:
                    /* We could try to decipher this partially.         */
                    /* For now we just punt.                            */
                    break;
                case GC_DS_PER_OBJECT:
                    if ((signed_word)descr >= 0) {
                      descr = *(word *)((ptr_t)base + (descr & ~GC_DS_TAGS));
                    } else {
                      ptr_t type_descr = *(ptr_t *)base;
                      descr = *(word *)(type_descr
                              - (descr - (GC_DS_PER_OBJECT
                                          - GC_INDIR_PER_OBJ_BIAS)));
                    }
                    goto retry;
            }
            return(p);
        }
#   endif
fail:
    (*GC_is_visible_print_proc)((ptr_t)p);
    return(p);
}