Back to index

plt-scheme  4.2.1
Classes | Defines | Typedefs | Functions | Variables
test.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "gc.h"
#include "gc_typed.h"
#include "private/gc_priv.h"
#include "private/gcconfig.h"

Go to the source code of this file.

Classes

struct  SEXPR
struct  treenode

Defines

#define FAIL   GC_abort("Test failed");
#define INT_TO_SEXPR(x)   ((sexpr)(unsigned long)(x))
#define nil   (INT_TO_SEXPR(0))
#define car(x)   ((x) -> sexpr_car)
#define cdr(x)   ((x) -> sexpr_cdr)
#define is_nil(x)   ((x) == nil)
#define UNCOLLECTABLE_CDR(x)   (sexpr)(~(unsigned long)(cdr(x)))
#define fork_a_thread()
#define a   A.aa
#define BIG   4500
#define MAX_FINALIZED   8000
#define alloc8bytes()   GC_MALLOC_ATOMIC(8)
#define TREE_HEIGHT   16
#define TEST_FAIL_COUNT(n)   (fail_count >= (n))

Typedefs

typedef struct SEXPRsexpr
typedef struct treenode tn

Functions

sexpr cons (sexpr x, sexpr y)
sexpr small_cons (sexpr x, sexpr y)
sexpr small_cons_uncollectable (sexpr x, sexpr y)
sexpr reverse1 (sexpr x, sexpr y)
sexpr reverse (sexpr x)
sexpr ints (int low, int up)
sexpr uncollectable_ints (int low, int up)
void check_ints (sexpr list, int low, int up)
void check_uncollectable_ints (sexpr list, int low, int up)
void print_int_list (sexpr x)
void reverse_test ()
void finalizer (char *obj, char *client_data)
tnmktree (int n)
void chktree (tn *t, int n)
void alloc_small (int n)
void tree_test ()
void typed_test ()
void fail_proc1 (GC_PTR x)
void run_one_test ()
void check_heap_stats ()
void warn_proc (char *msg, GC_word p)
int main ()

Variables

int stubborn_count = 0
int uncollectable_count = 0
int collectable_count = 0
int atomic_count = 0
int realloc_count = 0
int extra_count = 0
struct {
char dummy
sexpr aa
A
int finalizable_count = 0
int finalized_count = 0
VOLATILE int dropped_something = 0
size_t counter = 0
GC_FAR GC_word live_indicators [MAX_FINALIZED] = {0}
int live_indicators_count = 0
unsigned n_tests = 0
GC_word bm_huge [10]
int fail_count = 0

Class Documentation

struct SEXPR

Definition at line 145 of file test.c.

Collaboration diagram for SEXPR:
Class Members
struct SEXPR * sexpr_car
struct SEXPR * sexpr_cdr
struct treenode

Definition at line 725 of file test.c.

Collaboration diagram for treenode:
Class Members
struct treenode * lchild
int level
struct treenode * rchild
struct treenode * x
struct treenode * y

Define Documentation

#define a   A.aa

Definition at line 597 of file test.c.

#define alloc8bytes ( )    GC_MALLOC_ATOMIC(8)

Definition at line 1005 of file test.c.

#define BIG   4500
#define car (   x)    ((x) -> sexpr_car)

Definition at line 157 of file test.c.

#define cdr (   x)    ((x) -> sexpr_cdr)

Definition at line 158 of file test.c.

#define FAIL   GC_abort("Test failed");

Definition at line 133 of file test.c.

#define fork_a_thread ( )

Definition at line 588 of file test.c.

#define INT_TO_SEXPR (   x)    ((sexpr)(unsigned long)(x))

Definition at line 153 of file test.c.

#define is_nil (   x)    ((x) == nil)

Definition at line 159 of file test.c.

#define MAX_FINALIZED   8000

Definition at line 783 of file test.c.

#define nil   (INT_TO_SEXPR(0))

Definition at line 156 of file test.c.

#define TEST_FAIL_COUNT (   n)    (fail_count >= (n))

Definition at line 1197 of file test.c.

#define TREE_HEIGHT   16

Definition at line 1033 of file test.c.

#define UNCOLLECTABLE_CDR (   x)    (sexpr)(~(unsigned long)(cdr(x)))

Definition at line 484 of file test.c.


Typedef Documentation

typedef struct SEXPR* sexpr

Definition at line 151 of file test.c.

typedef struct treenode tn

Function Documentation

Definition at line 1009 of file test.c.

{
    register int i;
    
    for (i = 0; i < n; i += 8) {
        atomic_count++;
        if (alloc8bytes() == 0) {
            (void)GC_printf0("Out of memory\n");
            FAIL;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1349 of file test.c.

{
    unsigned long max_heap_sz;
    register int i;
    int still_live;
    int late_finalize_count = 0;
    
#   ifdef VERY_SMALL_CONFIG
    /* these are something of a guess */
    if (sizeof(char *) > 4) {
        max_heap_sz = 4500000;
    } else {
       max_heap_sz = 2800000;
    }
#   else
    if (sizeof(char *) > 4) {
        max_heap_sz = 19000000;
    } else {
       max_heap_sz = 11000000;
    }
#   endif
#   ifndef ALIGN_DOUBLE
        /* We end up needing more small object pages. */
        max_heap_sz += 2000000;
#   endif
#   ifdef GC_DEBUG
       max_heap_sz *= 2;
#       ifdef SAVE_CALL_CHAIN
           max_heap_sz *= 3;
#           ifdef SAVE_CALL_COUNT
              max_heap_sz += max_heap_sz * SAVE_CALL_COUNT/4;
#          endif
#       endif
#   endif
    /* Garbage collect repeatedly so that all inaccessible objects    */
    /* can be finalized.                                       */
      while (GC_collect_a_little()) { }
      for (i = 0; i < 16; i++) {
        GC_gcollect();
        late_finalize_count += GC_invoke_finalizers();
      }
    (void)GC_printf1("Completed %lu tests\n", (unsigned long)n_tests);
    (void)GC_printf1("Allocated %lu collectable objects\n", (unsigned long)collectable_count);
    (void)GC_printf1("Allocated %lu uncollectable objects\n", (unsigned long)uncollectable_count);
    (void)GC_printf1("Allocated %lu atomic objects\n", (unsigned long)atomic_count);
    (void)GC_printf1("Allocated %lu stubborn objects\n", (unsigned long)stubborn_count);
    (void)GC_printf2("Finalized %lu/%lu objects - ",
                   (unsigned long)finalized_count,
                   (unsigned long)finalizable_count);
#   ifdef FINALIZE_ON_DEMAND
       if (finalized_count != late_finalize_count) {
            (void)GC_printf0("Demand finalization error\n");
           FAIL;
       }
#   endif
    if (finalized_count > finalizable_count
        || finalized_count < finalizable_count/2) {
        (void)GC_printf0("finalization is probably broken\n");
        FAIL;
    } else {
        (void)GC_printf0("finalization is probably ok\n");
    }
    still_live = 0;
    for (i = 0; i < MAX_FINALIZED; i++) {
       if (live_indicators[i] != 0) {
           still_live++;
       }
    }
    i = finalizable_count - finalized_count - still_live;
    if (0 != i) {
        (void)GC_printf2
            ("%lu disappearing links remain and %ld more objects were not finalized\n",
             (unsigned long) still_live, (long)i);
        if (i > 10) {
           GC_printf0("\tVery suspicious!\n");
       } else {
           GC_printf0("\tSlightly suspicious, but probably OK.\n");
       }
    }
    (void)GC_printf1("Total number of bytes allocated is %lu\n",
              (unsigned long)
                  WORDS_TO_BYTES(GC_words_allocd + GC_words_allocd_before_gc));
    (void)GC_printf1("Final heap size is %lu bytes\n",
                   (unsigned long)GC_get_heap_size());
    if (WORDS_TO_BYTES(GC_words_allocd + GC_words_allocd_before_gc)
#   ifdef VERY_SMALL_CONFIG
        < 2700000*n_tests) {
#   else
        < 33500000*n_tests) {
#   endif
        (void)GC_printf0("Incorrect execution - missed some allocations\n");
        FAIL;
    }
    if (GC_get_heap_size() > max_heap_sz*n_tests) {
        (void)GC_printf0("Unexpected heap growth - collector may be broken\n");
        FAIL;
    }
    (void)GC_printf0("Collector appears to work\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void check_ints ( sexpr  list,
int  low,
int  up 
)

Definition at line 465 of file test.c.

{
    if ((int)(GC_word)(car(car(list))) != low) {
        (void)GC_printf0(
           "List reversal produced incorrect list - collector is broken\n");
        FAIL;
    }
    if (low == up) {
        if (cdr(list) != nil) {
           (void)GC_printf0("List too long - collector is broken\n");
           FAIL;
        }
    } else {
        check_ints(cdr(list), low+1, up);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void check_uncollectable_ints ( sexpr  list,
int  low,
int  up 
)

Definition at line 486 of file test.c.

{
    if ((int)(GC_word)(car(car(list))) != low) {
        (void)GC_printf0(
           "Uncollectable list corrupted - collector is broken\n");
        FAIL;
    }
    if (low == up) {
        if (UNCOLLECTABLE_CDR(list) != nil) {
           (void)GC_printf0("Uncollectable list too long - collector is broken\n");
           FAIL;
        }
    } else {
        check_uncollectable_ints(UNCOLLECTABLE_CDR(list), low+1, up);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void chktree ( tn t,
int  n 
)

Definition at line 901 of file test.c.

{
    if (n == 0 && t != 0) {
        (void)GC_printf0("Clobbered a leaf - collector is broken\n");
        FAIL;
    }
    if (n == 0) return;
    if (t -> level != n) {
        (void)GC_printf1("Lost a node at level %lu - collector is broken\n",
                      (unsigned long)n);
        FAIL;
    }
    if (counter++ % 373 == 0) {
       collectable_count++;
       (void) GC_MALLOC(counter%5001);
    }
    chktree(t -> lchild, n-1);
    if (counter++ % 73 == 0) {
       collectable_count++;
       (void) GC_MALLOC(counter%373);
    }
    chktree(t -> rchild, n-1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

sexpr cons ( sexpr  x,
sexpr  y 
)

Definition at line 169 of file test.c.

{
    register sexpr r;
    register int *p;
    register int my_extra = extra_count;
    
    stubborn_count++;
    r = (sexpr) GC_MALLOC_STUBBORN(sizeof(struct SEXPR) + my_extra);
    if (r == 0) {
        (void)GC_printf0("Out of memory\n");
        exit(1);
    }
    for (p = (int *)r;
         ((char *)p) < ((char *)r) + my_extra + sizeof(struct SEXPR); p++) {
       if (*p) {
           (void)GC_printf1("Found nonzero at 0x%lx - allocator is broken\n",
                          (unsigned long)p);
           FAIL;
        }
        *p = 13;
    }
#   ifdef AT_END
       r = (sexpr)((char *)r + (my_extra & ~7));
#   endif
    r -> sexpr_car = x;
    r -> sexpr_cdr = y;
    my_extra++;
    if ( my_extra >= 5000 ) {
        extra_count = 0;
    } else {
        extra_count = my_extra;
    }
    GC_END_STUBBORN_CHANGE((char *)r);
    return(r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1159 of file test.c.

{
    fail_count++;
}

Here is the caller graph for this function:

void finalizer ( char *  obj,
char *  client_data 
)

Definition at line 738 of file test.c.

{
  tn * t = (tn *)obj;

# ifdef PCR
     PCR_ThCrSec_EnterSys();
# endif
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
    static mutex_t incr_lock;
    mutex_lock(&incr_lock);
# endif
# if  defined(GC_PTHREADS)
    static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&incr_lock);
# else
#   ifdef GC_WIN32_THREADS
      EnterCriticalSection(&incr_cs);
#   endif
# endif
  if ((int)(GC_word)client_data != t -> level) {
     (void)GC_printf0("Wrong finalization data - collector is broken\n");
     FAIL;
  }
  finalized_count++;
  t -> level = -1;   /* detect duplicate finalization immediately */
# ifdef PCR
    PCR_ThCrSec_ExitSys();
# endif
# if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
    mutex_unlock(&incr_lock);
# endif
# if defined(GC_PTHREADS)
    pthread_mutex_unlock(&incr_lock);
# else
#   ifdef GC_WIN32_THREADS
      LeaveCriticalSection(&incr_cs);
#   endif
# endif
}

Here is the call graph for this function:

sexpr ints ( int  low,
int  up 
)

Definition at line 384 of file test.c.

{
    if (low > up) {
       return(nil);
    } else {
        return(small_cons(small_cons(INT_TO_SEXPR(low), nil), ints(low+1, up)));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( void  )

Definition at line 1486 of file test.c.

{
#   if defined(DJGPP)
       int dummy;
#   endif
    n_tests = 0;
    
#   if defined(DJGPP)
       /* No good way to determine stack base from library; do it */
       /* manually on this platform.                              */
       GC_stackbottom = (GC_PTR)(&dummy);
#   endif
#   if defined(MACOS)
       /* Make sure we have lots and lots of stack space.      */
       SetMinimumStack(cMinStackSpace);
       /* Cheat and let stdio initialize toolbox for us.       */
       printf("Testing GC Macintosh port.\n");
#   endif
    GC_INIT();       /* Only needed on a few platforms. */
    (void) GC_set_warn_proc(warn_proc);
#   if (defined(MPROTECT_VDB) || defined(PROC_VDB)) \
          && !defined(MAKE_BACK_GRAPH)
      GC_enable_incremental();
      (void) GC_printf0("Switched to incremental mode\n");
#     if defined(MPROTECT_VDB)
       (void)GC_printf0("Emulating dirty bits with mprotect/signals\n");
#     else
#       ifdef PROC_VDB
       (void)GC_printf0("Reading dirty bits from /proc\n");
#       else
    (void)GC_printf0("Using DEFAULT_VDB dirty bit implementation\n");
#       endif
#      endif
#   endif
    run_one_test();
    check_heap_stats();
#   ifndef MSWINCE
    (void)fflush(stdout);
#   endif
#   ifdef LINT
       /* Entry points we should be testing, but aren't.                 */
       /* Some can be tested by defining GC_DEBUG at the top of this file */
       /* This is a bit SunOS4 specific.                          */                
       GC_noop(GC_expand_hp, GC_add_roots, GC_clear_roots,
               GC_register_disappearing_link,
               GC_register_finalizer_ignore_self,
              GC_debug_register_displacement,
               GC_print_obj, GC_debug_change_stubborn,
               GC_debug_end_stubborn_change, GC_debug_malloc_uncollectable,
               GC_debug_free, GC_debug_realloc, GC_generic_malloc_words_small,
               GC_init, GC_make_closure, GC_debug_invoke_finalizer,
               GC_page_was_ever_dirty, GC_is_fresh,
              GC_malloc_ignore_off_page, GC_malloc_atomic_ignore_off_page,
              GC_set_max_heap_size, GC_get_bytes_since_gc,
              GC_get_total_bytes, GC_pre_incr, GC_post_incr);
#   endif
#   ifdef MSWIN32
      GC_win32_free_heap();
#   endif
    return(0);
}

Here is the call graph for this function:

tn* mktree ( int  n)

Definition at line 794 of file test.c.

{
#   ifdef THREAD_LOCAL_ALLOC
      tn * result = (tn *)GC_LOCAL_MALLOC(sizeof(tn));
#   else
      tn * result = (tn *)GC_MALLOC(sizeof(tn));
#   endif
    
    collectable_count++;
#   ifdef THREAD_LOCAL_ALLOC
       /* Minimally exercise thread local allocation */
       {
         char * result = (char *)GC_LOCAL_MALLOC_ATOMIC(17);
        memset(result, 'a', 17);
       }
#   endif /* THREAD_LOCAL_ALLOC */
#   if defined(MACOS)
       /* get around static data limitations. */
       if (!live_indicators)
              live_indicators =
                  (GC_word*)NewPtrClear(MAX_FINALIZED * sizeof(GC_word));
       if (!live_indicators) {
          (void)GC_printf0("Out of memory\n");
          exit(1);
        }
#   endif
    if (n == 0) return(0);
    if (result == 0) {
        (void)GC_printf0("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_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
           static mutex_t incr_lock;
           mutex_lock(&incr_lock);
#        endif
#         if defined(GC_PTHREADS)
            static pthread_mutex_t incr_lock = PTHREAD_MUTEX_INITIALIZER;
            pthread_mutex_lock(&incr_lock);
#         else
#           ifdef GC_WIN32_THREADS
              EnterCriticalSection(&incr_cs);
#           endif
#         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_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
           mutex_unlock(&incr_lock);
#        endif
#        if defined(GC_PTHREADS)
           pthread_mutex_unlock(&incr_lock);
#        else
#           ifdef GC_WIN32_THREADS
              LeaveCriticalSection(&incr_cs);
#           endif
#         endif
       }

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 506 of file test.c.

{
    if (is_nil(x)) {
        (void)GC_printf0("NIL\n");
    } else {
        (void)GC_printf1("(%ld)", (long)(car(car(x))));
        if (!is_nil(cdr(x))) {
            (void)GC_printf0(", ");
            (void)print_int_list(cdr(x));
        } else {
            (void)GC_printf0("\n");
        }
    }
}

Here is the call graph for this function:

Definition at line 375 of file test.c.

{
#   ifdef TEST_WITH_SYSTEM_MALLOC
      malloc(100000);
#   endif
    return( reverse1(x, nil) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

sexpr reverse1 ( sexpr  x,
sexpr  y 
)

Definition at line 365 of file test.c.

{
    if (is_nil(x)) {
        return(y);
    } else {
        return( reverse1(cdr(x), cons(car(x), y)) );
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 603 of file test.c.

{
    int i;
    sexpr b;
    sexpr c;
    sexpr d;
    sexpr e;
    sexpr *f, *g, *h;
#   if defined(MSWIN32) || defined(MACOS)
      /* Win32S only allows 128K stacks */
#     define BIG 1000
#   else
#     if defined PCR
       /* PCR default stack is 100K.  Stack frames are up to 120 bytes. */
#      define BIG 700
#     else
#      if defined MSWINCE
         /* WinCE only allows 64K stacks */
#        define BIG 500
#      else
#        if defined(OSF1)
           /* OSF has limited stack space by default, and large frames. */
#           define BIG 200
#        else
#           define BIG 4500
#        endif
#      endif
#     endif
#   endif

    A.dummy = 17;
    a = ints(1, 49);
    b = ints(1, 50);
    c = ints(1, BIG);
    d = uncollectable_ints(1, 100);
    e = uncollectable_ints(1, 1);
    /* Check that realloc updates object descriptors correctly */
    collectable_count++;
    f = (sexpr *)GC_MALLOC(4 * sizeof(sexpr));
    realloc_count++;
    f = (sexpr *)GC_REALLOC((GC_PTR)f, 6 * sizeof(sexpr));
    f[5] = ints(1,17);
    collectable_count++;
    g = (sexpr *)GC_MALLOC(513 * sizeof(sexpr));
    realloc_count++;
    g = (sexpr *)GC_REALLOC((GC_PTR)g, 800 * sizeof(sexpr));
    g[799] = ints(1,18);
    collectable_count++;
    h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr));
    realloc_count++;
    h = (sexpr *)GC_REALLOC((GC_PTR)h, 2000 * sizeof(sexpr));
#   ifdef GC_GCJ_SUPPORT
      h[1999] = gcj_ints(1,200);
      for (i = 0; i < 51; ++i) 
        h[1999] = gcj_reverse(h[1999]);
      /* Leave it as the reveresed list for now. */
#   else
      h[1999] = ints(1,200);
#   endif
    /* Try to force some collections and reuse of small list elements */
      for (i = 0; i < 10; i++) {
        (void)ints(1, BIG);
      }
    /* Superficially test interior pointer recognition on stack */
      c = (sexpr)((char *)c + sizeof(char *));
      d = (sexpr)((char *)d + sizeof(char *));

#   ifdef __STDC__
        GC_FREE((void *)e);
#   else
        GC_FREE((char *)e);
#   endif
    check_ints(b,1,50);
    check_ints(a,1,49);
    for (i = 0; i < 50; i++) {
        check_ints(b,1,50);
        b = reverse(reverse(b));
    }
    check_ints(b,1,50);
    check_ints(a,1,49);
    for (i = 0; i < 60; i++) {
       if (i % 10 == 0) fork_a_thread();
       /* This maintains the invariant that a always points to a list of */
       /* 49 integers.  Thus this is thread safe without locks,         */
       /* assuming atomic pointer assignments.                          */
        a = reverse(reverse(a));
#       ifdef THREAD_LOCAL_ALLOC
         a = local_reverse(local_reverse(a));
#      endif
#      if !defined(AT_END) && !defined(THREADS)
         /* This is not thread safe, since realloc explicitly deallocates */
          if (i & 1) {
            a = (sexpr)GC_REALLOC((GC_PTR)a, 500);
          } else {
            a = (sexpr)GC_REALLOC((GC_PTR)a, 8200);
          }
#      endif
    }
    check_ints(a,1,49);
    check_ints(b,1,50);
    c = (sexpr)((char *)c - sizeof(char *));
    d = (sexpr)((char *)d - sizeof(char *));
    check_ints(c,1,BIG);
    check_uncollectable_ints(d, 1, 100);
    check_ints(f[5], 1,17);
    check_ints(g[799], 1,18);
#   ifdef GC_GCJ_SUPPORT
      h[1999] = gcj_reverse(h[1999]);
#   endif
    check_ints(h[1999], 1,200);
#   ifndef THREADS
       a = 0;
#   endif  
    b = c = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1200 of file test.c.

{
    char *x;
#   ifdef LINT
       char *y = 0;
#   else
       char *y = (char *)(size_t)fail_proc1;
#   endif
    DCL_LOCK_STATE;
    
#   ifdef FIND_LEAK
       (void)GC_printf0(
              "This test program is not designed for leak detection mode\n");
       (void)GC_printf0("Expect lots of problems.\n");
#   endif
    GC_FREE(0);
#   ifndef DBG_HDRS_ALL
      collectable_count += 3;
      if (GC_size(GC_malloc(7)) != 8 &&
         GC_size(GC_malloc(7)) != MIN_WORDS * sizeof(GC_word)
       || GC_size(GC_malloc(15)) != 16) {
           (void)GC_printf0("GC_size produced unexpected results\n");
           FAIL;
      }
      collectable_count += 1;
      if (GC_size(GC_malloc(0)) != MIN_WORDS * sizeof(GC_word)) {
       (void)GC_printf1("GC_malloc(0) failed: GC_size returns %ld\n",
                      GC_size(GC_malloc(0)));
           FAIL;
      }
      collectable_count += 1;
      if (GC_size(GC_malloc_uncollectable(0)) != MIN_WORDS * sizeof(GC_word)) {
       (void)GC_printf0("GC_malloc_uncollectable(0) failed\n");
           FAIL;
      }
      GC_is_valid_displacement_print_proc = fail_proc1;
      GC_is_visible_print_proc = fail_proc1;
      collectable_count += 1;
      x = GC_malloc(16);
      if (GC_base(x + 13) != x) {
       (void)GC_printf0("GC_base(heap ptr) produced incorrect result\n");
       FAIL;
      }
#     ifndef PCR
        if (GC_base(y) != 0) {
         (void)GC_printf0("GC_base(fn_ptr) produced incorrect result\n");
         FAIL;
        }
#     endif
      if (GC_same_obj(x+5, x) != x + 5) {
       (void)GC_printf0("GC_same_obj produced incorrect result\n");
       FAIL;
      }
      if (GC_is_visible(y) != y || GC_is_visible(x) != x) {
       (void)GC_printf0("GC_is_visible produced incorrect result\n");
       FAIL;
      }
      if (!TEST_FAIL_COUNT(1)) {
#      if!(defined(RS6000) || defined(POWERPC) || defined(IA64)) || defined(M68K)
         /* ON RS6000s function pointers point to a descriptor in the */
         /* data segment, so there should have been no failures.      */
         /* The same applies to IA64.  Something similar seems to     */
         /* be going on with NetBSD/M68K.                      */
         (void)GC_printf0("GC_is_visible produced wrong failure indication\n");
         FAIL;
#      endif
      }
      if (GC_is_valid_displacement(y) != y
        || GC_is_valid_displacement(x) != x
        || GC_is_valid_displacement(x + 3) != x + 3) {
       (void)GC_printf0(
              "GC_is_valid_displacement produced incorrect result\n");
       FAIL;
      }
#     if defined(__STDC__) && !defined(MSWIN32) && !defined(MSWINCE)
        /* Harder to test under Windows without a gc.h declaration.  */
        {
         size_t i;
         extern void *GC_memalign();

         GC_malloc(17);
         for (i = sizeof(GC_word); i < 512; i *= 2) {
           GC_word result = (GC_word) GC_memalign(i, 17);
           if (result % i != 0 || result == 0 || *(int *)result != 0) FAIL;
         } 
       }
#     endif
#     ifndef ALL_INTERIOR_POINTERS
#      if defined(RS6000) || defined(POWERPC)
        if (!TEST_FAIL_COUNT(1)) {
#      else
        if (GC_all_interior_pointers && !TEST_FAIL_COUNT(1)
           || !GC_all_interior_pointers && !TEST_FAIL_COUNT(2)) {
#      endif
         (void)GC_printf0("GC_is_valid_displacement produced wrong failure indication\n");
         FAIL;
        }
#     endif
#   endif /* DBG_HDRS_ALL */
    /* Test floating point alignment */
   collectable_count += 2;
       *(double *)GC_MALLOC(sizeof(double)) = 1.0;
       *(double *)GC_MALLOC(sizeof(double)) = 1.0;
#   ifdef GC_GCJ_SUPPORT
      GC_REGISTER_DISPLACEMENT(sizeof(struct fake_vtable *));
      GC_init_gcj_malloc(0, (void *)fake_gcj_mark_proc);
#   endif
    /* Make sure that fn arguments are visible to the collector.      */
#   ifdef __STDC__
      uniq(
        GC_malloc(12), GC_malloc(12), GC_malloc(12),
        (GC_gcollect(),GC_malloc(12)),
        GC_malloc(12), GC_malloc(12), GC_malloc(12),
       (GC_gcollect(),GC_malloc(12)),
        GC_malloc(12), GC_malloc(12), GC_malloc(12),
       (GC_gcollect(),GC_malloc(12)),
        GC_malloc(12), GC_malloc(12), GC_malloc(12),
       (GC_gcollect(),GC_malloc(12)),
        GC_malloc(12), GC_malloc(12), GC_malloc(12),
       (GC_gcollect(),GC_malloc(12)),
        (void *)0);
#   endif
    /* Repeated list reversal test. */
       reverse_test();
#   ifdef PRINTSTATS
       GC_printf0("-------------Finished reverse_test\n");
#   endif
#   ifndef DBG_HDRS_ALL
      typed_test();
#     ifdef PRINTSTATS
       GC_printf0("-------------Finished typed_test\n");
#     endif
#   endif /* DBG_HDRS_ALL */
    tree_test();
    LOCK();
    n_tests++;
    UNLOCK();
#   if defined(THREADS) && defined(HANDLE_FORK)
      if (fork() == 0) {
       GC_gcollect();
       tiny_reverse_test(0);
       GC_gcollect();
       GC_printf0("Finished a child process\n");
       exit(0);
      }
#   endif
    /* GC_printf1("Finished %x\n", pthread_self()); */
}

Here is the call graph for this function:

Here is the caller graph for this function:

sexpr small_cons ( sexpr  x,
sexpr  y 
)

Definition at line 297 of file test.c.

{
    register sexpr r;
    
    collectable_count++;
    r = (sexpr) GC_MALLOC(sizeof(struct SEXPR));
    if (r == 0) {
        (void)GC_printf0("Out of memory\n");
        exit(1);
    }
    r -> sexpr_car = x;
    r -> sexpr_cdr = y;
    return(r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 314 of file test.c.

{
    register sexpr r;
    
    uncollectable_count++;
    r = (sexpr) GC_MALLOC_UNCOLLECTABLE(sizeof(struct SEXPR));
    if (r == 0) {
        (void)GC_printf0("Out of memory\n");
        exit(1);
    }
    r -> sexpr_car = x;
    r -> sexpr_cdr = (sexpr)(~(unsigned long)y);
    return(r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1036 of file test.c.

{
    tn * root;
    register int i;
    
    root = mktree(TREE_HEIGHT);
#   ifndef VERY_SMALL_CONFIG
      alloc_small(5000000);
#   endif
    chktree(root, TREE_HEIGHT);
    if (finalized_count && ! dropped_something) {
        (void)GC_printf0("Premature finalization - collector is broken\n");
        FAIL;
    }
    dropped_something = 1;
    GC_noop(root);   /* Root needs to remain live until */
                     /* dropped_something is set.              */
    root = mktree(TREE_HEIGHT);
    chktree(root, TREE_HEIGHT);
    for (i = TREE_HEIGHT; i >= 0; i--) {
        root = mktree(i);
        chktree(root, i);
    }
#   ifndef VERY_SMALL_CONFIG
      alloc_small(5000000);
#   endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1080 of file test.c.

{
    GC_word * old, * new;
    GC_word bm3 = 0x3;
    GC_word bm2 = 0x2;
    GC_word bm_large = 0xf7ff7fff;
    GC_descr d1 = GC_make_descriptor(&bm3, 2);
    GC_descr d2 = GC_make_descriptor(&bm2, 2);
#   ifndef LINT
      GC_descr dummy = GC_make_descriptor(&bm_large, 32);
#   endif
    GC_descr d3 = GC_make_descriptor(&bm_large, 32);
    GC_descr d4 = GC_make_descriptor(bm_huge, 320);
    GC_word * x = (GC_word *)GC_malloc_explicitly_typed(2000, d4);
    register int i;
    
    collectable_count++;
    old = 0;
    for (i = 0; i < 4000; i++) {
       collectable_count++;
        new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d1);
        if (0 != new[0] || 0 != new[1]) {
           GC_printf0("Bad initialization by GC_malloc_explicitly_typed\n");
           FAIL;
       }
        new[0] = 17;
        new[1] = (GC_word)old;
        old = new;
       collectable_count++;
        new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d2);
        new[0] = 17;
        new[1] = (GC_word)old;
        old = new;
       collectable_count++;
        new = (GC_word *) GC_malloc_explicitly_typed(33 * sizeof(GC_word), d3);
        new[0] = 17;
        new[1] = (GC_word)old;
        old = new;
       collectable_count++;
        new = (GC_word *) GC_calloc_explicitly_typed(4, 2 * sizeof(GC_word),
                                               d1);
        new[0] = 17;
        new[1] = (GC_word)old;
        old = new;
       collectable_count++;
        if (i & 0xff) {
          new = (GC_word *) GC_calloc_explicitly_typed(7, 3 * sizeof(GC_word),
                                               d2);
        } else {
          new = (GC_word *) GC_calloc_explicitly_typed(1001,
                                                 3 * sizeof(GC_word),
                                                 d2);
          if (0 != new[0] || 0 != new[1]) {
           GC_printf0("Bad initialization by GC_malloc_explicitly_typed\n");
           FAIL;
         }
        }
        new[0] = 17;
        new[1] = (GC_word)old;
        old = new;
    }
    for (i = 0; i < 20000; i++) {
        if (new[0] != 17) {
            (void)GC_printf1("typed alloc failed at %lu\n",
                          (unsigned long)i);
            FAIL;
        }
        new[0] = 0;
        old = new;
        new = (GC_word *)(old[1]);
    }
    GC_gcollect();
    GC_noop(x);
}

Here is the call graph for this function:

Here is the caller graph for this function:

sexpr uncollectable_ints ( int  low,
int  up 
)

Definition at line 454 of file test.c.

{
    if (low > up) {
       return(nil);
    } else {
        return(small_cons_uncollectable(small_cons(INT_TO_SEXPR(low), nil),
               uncollectable_ints(low+1, up)));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void warn_proc ( char *  msg,
GC_word  p 
)

Definition at line 1470 of file test.c.

{
    GC_printf1(msg, (unsigned long)p);
    /*FAIL;*/
}

Here is the caller graph for this function:


Variable Documentation

struct { ... } A

Definition at line 84 of file test.c.

Initial value:
 {
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0x00ffffff,
}

Definition at line 1066 of file test.c.

Definition at line 83 of file test.c.

size_t counter = 0

Definition at line 781 of file test.c.

Definition at line 733 of file test.c.

Definition at line 162 of file test.c.

Definition at line 1155 of file test.c.

Definition at line 731 of file test.c.

Definition at line 732 of file test.c.

Definition at line 786 of file test.c.

Definition at line 792 of file test.c.

unsigned n_tests = 0

Definition at line 1064 of file test.c.

Definition at line 85 of file test.c.

Definition at line 81 of file test.c.

Definition at line 82 of file test.c.