Ejemplo n.º 1
0
CORD CORD_cat(CORD x, CORD y)
{
    size_t result_len;
    int depth;
    size_t lenx;

    if (x == CORD_EMPTY) return(y);
    if (y == CORD_EMPTY) return(x);
    if (CORD_IS_STRING(y)) {
        return(CORD_cat_char_star(x, y, strlen(y)));
    } else if (CORD_IS_STRING(x)) {
        lenx = strlen(x);
        depth = DEPTH(y) + 1;
    } else {
        int depthy = DEPTH(y);

        lenx = LEN(x);
        depth = DEPTH(x) + 1;
        if (depthy >= depth) depth = depthy + 1;
    }
    result_len = lenx + LEN(y);
    {
        struct Concatenation * result = GC_NEW(struct Concatenation);

        if (NULL == result) OUT_OF_MEMORY;
        result->header = CONCAT_HDR;
        result->depth = (char)depth;
        if (lenx <= MAX_LEFT_LEN)
            result->left_len = (unsigned char)lenx;
        result->len = (word)result_len;
        result->left = x;
        GC_PTR_STORE_AND_DIRTY((void *)&result->right, y);
        GC_reachable_here(x);
        if (depth >= MAX_DEPTH) {
            return(CORD_balance((CORD)result));
        } else {
            return((CORD) result);
        }
    }
}
Ejemplo n.º 2
0
CORD CORD_cat_char_star(CORD x, const char * y, size_t leny)
{
    size_t result_len;
    size_t lenx;
    int depth;

    if (x == CORD_EMPTY) return(y);
    if (leny == 0) return(x);
    if (CORD_IS_STRING(x)) {
        lenx = strlen(x);
        result_len = lenx + leny;
        if (result_len <= SHORT_LIMIT) {
            char * result = (char *)GC_MALLOC_ATOMIC(result_len + 1);

            if (result == 0) OUT_OF_MEMORY;
#           ifdef LINT2
                memcpy(result, x, lenx + 1);
#           else
                memcpy(result, x, lenx);
                                /* No need to copy the terminating zero */
                                /* as result[lenx] is written below.    */
#           endif
            memcpy(result + lenx, y, leny);
            result[result_len] = '\0';
            return((CORD) result);
        } else {
            depth = 1;
        }
    } else {
        CORD right;
        CORD left;
        char * new_right;

        lenx = LEN(x);

        if (leny <= SHORT_LIMIT/2
            && IS_CONCATENATION(x)
            && CORD_IS_STRING(right = ((CordRep *)x) -> concatenation.right)) {
            size_t right_len;

            /* Merge y into right part of x. */
            if (!CORD_IS_STRING(left = ((CordRep *)x) -> concatenation.left)) {
                right_len = lenx - LEN(left);
            } else if (((CordRep *)x) -> concatenation.left_len != 0) {
                right_len = lenx - ((CordRep *)x) -> concatenation.left_len;
            } else {
                right_len = strlen(right);
            }
            result_len = right_len + leny;  /* length of new_right */
            if (result_len <= SHORT_LIMIT) {
                new_right = (char *)GC_MALLOC_ATOMIC(result_len + 1);
                if (new_right == 0) OUT_OF_MEMORY;
                memcpy(new_right, right, right_len);
                memcpy(new_right + right_len, y, leny);
                new_right[result_len] = '\0';
                y = new_right;
                leny = result_len;
                x = left;
                lenx -= right_len;
                /* Now fall through to concatenate the two pieces: */
            }
            if (CORD_IS_STRING(x)) {
                depth = 1;
            } else {
                depth = DEPTH(x) + 1;
            }
        } else {
            depth = DEPTH(x) + 1;
        }
        result_len = lenx + leny;
    }
    {
      /* The general case; lenx, result_len is known: */
        struct Concatenation * result = GC_NEW(struct Concatenation);

        if (NULL == result) OUT_OF_MEMORY;
        result->header = CONCAT_HDR;
        result->depth = (char)depth;
        if (lenx <= MAX_LEFT_LEN)
            result->left_len = (unsigned char)lenx;
        result->len = (word)result_len;
        result->left = x;
        GC_PTR_STORE_AND_DIRTY((void *)&result->right, y);
        GC_reachable_here(x);
        if (depth >= MAX_DEPTH) {
            return(CORD_balance((CORD)result));
        } else {
            return((CORD) result);
        }
    }
}
Ejemplo n.º 3
0
tn * mktree(int n)
{
    tn * result = (tn *)GC_MALLOC(sizeof(tn));

    collectable_count++;
#   if defined(MACOS)
        /* get around static data limitations. */
        if (!live_indicators)
                live_indicators =
                    (GC_word*)NewPtrClear(MAX_FINALIZED * sizeof(GC_word));
        if (!live_indicators) {
          GC_printf("Out of memory\n");
          exit(1);
        }
#   endif
    if (n == 0) return(0);
    if (result == 0) {
        GC_printf("Out of memory\n");
        exit(1);
    }
    result -> level = n;
    result -> lchild = mktree(n-1);
    result -> rchild = mktree(n-1);
    if (counter++ % 17 == 0 && n >= 2) {
        tn * tmp = result -> lchild -> rchild;

        result -> lchild -> rchild = result -> rchild -> lchild;
        result -> rchild -> lchild = tmp;
    }
    if (counter++ % 119 == 0) {
        int my_index;

        {
#         ifdef PCR
            PCR_ThCrSec_EnterSys();
#         endif
#         if defined(GC_PTHREADS)
            static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
            pthread_mutex_lock(&incr_lock);
#         elif defined(GC_WIN32_THREADS)
            EnterCriticalSection(&incr_cs);
#         endif
                /* Losing a count here causes erroneous report of failure. */
          finalizable_count++;
          my_index = live_indicators_count++;
#         ifdef PCR
            PCR_ThCrSec_ExitSys();
#         endif
#         if defined(GC_PTHREADS)
            pthread_mutex_unlock(&incr_lock);
#         elif defined(GC_WIN32_THREADS)
            LeaveCriticalSection(&incr_cs);
#         endif
        }

        GC_REGISTER_FINALIZER((void *)result, finalizer, (void *)(GC_word)n,
                              (GC_finalization_proc *)0, (void * *)0);
        if (my_index >= MAX_FINALIZED) {
                GC_printf("live_indicators overflowed\n");
                FAIL;
        }
        live_indicators[my_index] = 13;
        if (GC_GENERAL_REGISTER_DISAPPEARING_LINK(
                (void * *)(&(live_indicators[my_index])),
                (void *)result) != 0) {
                GC_printf("GC_general_register_disappearing_link failed\n");
                FAIL;
        }
        if (GC_unregister_disappearing_link(
                (void * *)
                   (&(live_indicators[my_index]))) == 0) {
                GC_printf("GC_unregister_disappearing_link failed\n");
                FAIL;
        }
        if (GC_GENERAL_REGISTER_DISAPPEARING_LINK(
                (void * *)(&(live_indicators[my_index])),
                (void *)result) != 0) {
                GC_printf("GC_general_register_disappearing_link failed 2\n");
                FAIL;
        }
        GC_reachable_here(result);
    }
    return(result);
}