Esempio n. 1
0
/*
 * Generic procedure to rebuild a free list in hbp.
 * Also called directly from GC_malloc_many.
 * Sz is now in bytes.
 */
ptr_t GC_reclaim_generic(struct hblk * hbp, hdr *hhdr, size_t sz,
			 GC_bool init, ptr_t list, signed_word *count)
{
    ptr_t result = list;

    GC_ASSERT(GC_find_header((ptr_t)hbp) == hhdr);
    GC_remove_protection(hbp, 1, (hhdr)->hb_descr == 0 /* Pointer-free? */);
    if (init) {
      result = GC_reclaim_clear(hbp, hhdr, sz, list, count);
    } else {
      GC_ASSERT((hhdr)->hb_descr == 0 /* Pointer-free block */);
      result = GC_reclaim_uninit(hbp, hhdr, sz, list, count);
    } 
    if (IS_UNCOLLECTABLE(hhdr -> hb_obj_kind)) GC_set_hdr_marks(hhdr);
    return result;
}
Esempio n. 2
0
/*
 * Restore unmarked small objects in h of size sz to the object
 * free list.  Returns the new list.
 * Clears unmarked objects.  Sz is in bytes.
 */
STATIC ptr_t GC_reclaim_clear(struct hblk *hbp, hdr *hhdr, size_t sz,
                              ptr_t list, signed_word *count)
{
    word bit_no = 0;
    word *p, *q, *plim;
    signed_word n_bytes_found = 0;

    GC_ASSERT(hhdr == GC_find_header((ptr_t)hbp));
    GC_ASSERT(sz == hhdr -> hb_sz);
    GC_ASSERT((sz & (BYTES_PER_WORD-1)) == 0);
    p = (word *)(hbp->hb_body);
    plim = (word *)(hbp->hb_body + HBLKSIZE - sz);

    /* go through all words in block */
    while (p <= plim) {
        if( mark_bit_from_hdr(hhdr, bit_no) ) {
            p = (word *)((ptr_t)p + sz);
        } else {
            n_bytes_found += sz;
            /* object is available - put on list */
            obj_link(p) = list;
            list = ((ptr_t)p);
            /* Clear object, advance p to next object in the process */
            q = (word *)((ptr_t)p + sz);
#                   ifdef USE_MARK_BYTES
            GC_ASSERT(!(sz & 1)
                      && !((word)p & (2 * sizeof(word) - 1)));
            p[1] = 0;
            p += 2;
            while (p < q) {
                CLEAR_DOUBLE(p);
                p += 2;
            }
#                   else
            p++; /* Skip link field */
            while (p < q) {
                *p++ = 0;
            }
#                   endif
        }
        bit_no += MARK_BIT_OFFSET(sz);
    }
    *count += n_bytes_found;
    return(list);
}
Esempio n. 3
0
/* is p.                                                                */
STATIC void GC_print_type(ptr_t p)
{
    hdr * hhdr = GC_find_header(p);
    char buffer[GC_TYPE_DESCR_LEN + 1];
    int kind = hhdr -> hb_obj_kind;

    if (0 != GC_describe_type_fns[kind] && GC_is_marked(GC_base(p))) {
        /* This should preclude free list objects except with   */
        /* thread-local allocation.                             */
        buffer[GC_TYPE_DESCR_LEN] = 0;
        (GC_describe_type_fns[kind])(p, buffer);
        GC_ASSERT(buffer[GC_TYPE_DESCR_LEN] == 0);
        GC_err_puts(buffer);
    } else {
        switch(kind) {
          case PTRFREE:
            GC_err_puts("PTRFREE");
            break;
          case NORMAL:
            GC_err_puts("NORMAL");
            break;
          case UNCOLLECTABLE:
            GC_err_puts("UNCOLLECTABLE");
            break;
#         ifdef ATOMIC_UNCOLLECTABLE
            case AUNCOLLECTABLE:
              GC_err_puts("ATOMIC UNCOLLECTABLE");
              break;
#         endif
          case STUBBORN:
            GC_err_puts("STUBBORN");
            break;
          default:
            GC_err_printf("kind=%d descr=0x%lx", kind,
                          (unsigned long)(hhdr -> hb_descr));
        }
    }
}
Esempio n. 4
0
/* p points to somewhere inside an object with the debugging info.      */
STATIC void GC_print_obj(ptr_t p)
{
    oh * ohdr = (oh *)GC_base(p);
    ptr_t q;
    hdr * hhdr;
    int kind;
    const char *kind_str;
    char buffer[GC_TYPE_DESCR_LEN + 1];

    GC_ASSERT(I_DONT_HOLD_LOCK());
#   ifdef LINT2
      if (!ohdr) ABORT("Invalid GC_print_obj argument");
#   endif

    q = (ptr_t)(ohdr + 1);
    /* Print a type description for the object whose client-visible     */
    /* address is q.                                                    */
    hhdr = GC_find_header(q);
    kind = hhdr -> hb_obj_kind;
    if (0 != GC_describe_type_fns[kind] && GC_is_marked(ohdr)) {
        /* This should preclude free list objects except with   */
        /* thread-local allocation.                             */
        buffer[GC_TYPE_DESCR_LEN] = 0;
        (GC_describe_type_fns[kind])(q, buffer);
        GC_ASSERT(buffer[GC_TYPE_DESCR_LEN] == 0);
        kind_str = buffer;
    } else {
        switch(kind) {
          case PTRFREE:
            kind_str = "PTRFREE";
            break;
          case NORMAL:
            kind_str = "NORMAL";
            break;
          case UNCOLLECTABLE:
            kind_str = "UNCOLLECTABLE";
            break;
#         ifdef GC_ATOMIC_UNCOLLECTABLE
            case AUNCOLLECTABLE:
              kind_str = "ATOMIC_UNCOLLECTABLE";
              break;
#         endif
          default:
            kind_str = NULL;
                /* The alternative is to use snprintf(buffer) but it is */
                /* not quite portable (see vsnprintf in misc.c).        */
        }
    }

    if (NULL != kind_str) {
        GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz=%lu,") " %s)\n",
                      (void *)((ptr_t)ohdr + sizeof(oh)),
                      ohdr->oh_string, GET_OH_LINENUM(ohdr) /*, */
                      COMMA_IFNOT_SHORTDBG_HDRS((unsigned long)ohdr->oh_sz),
                      kind_str);
    } else {
        GC_err_printf("%p (%s:%d," IF_NOT_SHORTDBG_HDRS(" sz=%lu,")
                      " kind=%d descr=0x%lx)\n",
                      (void *)((ptr_t)ohdr + sizeof(oh)),
                      ohdr->oh_string, GET_OH_LINENUM(ohdr) /*, */
                      COMMA_IFNOT_SHORTDBG_HDRS((unsigned long)ohdr->oh_sz),
                      kind, (unsigned long)hhdr->hb_descr);
    }
    PRINT_CALL_CHAIN(ohdr);
}