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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-dev/] [fsf-gcc-snapshot-1-mar-12/] [or1k-gcc/] [boehm-gc/] [gcj_mlc.c] - Diff between revs 721 and 783

Only display areas with differences | Details | Blame | View Log

Rev 721 Rev 783
/*
/*
 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
 * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
 * Copyright (c) 1999 by Hewlett-Packard Company.  All rights reserved.
 * Copyright (c) 1999 by Hewlett-Packard Company.  All rights reserved.
 *
 *
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
 *
 *
 * Permission is hereby granted to use or copy this program
 * Permission is hereby granted to use or copy this program
 * for any purpose,  provided the above notices are retained on all copies.
 * for any purpose,  provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 * modified is included with the above copyright notice.
 *
 *
 */
 */
/* Boehm, July 31, 1995 5:02 pm PDT */
/* Boehm, July 31, 1995 5:02 pm PDT */
 
 
/*
/*
 * This is an allocator interface tuned for gcj (the GNU static
 * This is an allocator interface tuned for gcj (the GNU static
 * java compiler).
 * java compiler).
 *
 *
 * Each allocated object has a pointer in its first word to a vtable,
 * Each allocated object has a pointer in its first word to a vtable,
 * which for our purposes is simply a structure describing the type of
 * which for our purposes is simply a structure describing the type of
 * the object.
 * the object.
 * This descriptor structure contains a GC marking descriptor at offset
 * This descriptor structure contains a GC marking descriptor at offset
 * MARK_DESCR_OFFSET.
 * MARK_DESCR_OFFSET.
 *
 *
 * It is hoped that this interface may also be useful for other systems,
 * It is hoped that this interface may also be useful for other systems,
 * possibly with some tuning of the constants.  But the immediate goal
 * possibly with some tuning of the constants.  But the immediate goal
 * is to get better gcj performance.
 * is to get better gcj performance.
 *
 *
 * We assume:
 * We assume:
 *  1) We have an ANSI conforming C compiler.
 *  1) We have an ANSI conforming C compiler.
 *  2) Counting on explicit initialization of this interface is OK.
 *  2) Counting on explicit initialization of this interface is OK.
 *  3) FASTLOCK is not a significant win.
 *  3) FASTLOCK is not a significant win.
 */
 */
 
 
#include "private/gc_pmark.h"
#include "private/gc_pmark.h"
#include "gc_gcj.h"
#include "gc_gcj.h"
#include "private/dbg_mlc.h"
#include "private/dbg_mlc.h"
 
 
#ifdef GC_GCJ_SUPPORT
#ifdef GC_GCJ_SUPPORT
 
 
GC_bool GC_gcj_malloc_initialized = FALSE;
GC_bool GC_gcj_malloc_initialized = FALSE;
 
 
int GC_gcj_kind;        /* Object kind for objects with descriptors     */
int GC_gcj_kind;        /* Object kind for objects with descriptors     */
                        /* in "vtable".                                 */
                        /* in "vtable".                                 */
int GC_gcj_debug_kind;  /* The kind of objects that is always marked    */
int GC_gcj_debug_kind;  /* The kind of objects that is always marked    */
                        /* with a mark proc call.                       */
                        /* with a mark proc call.                       */
 
 
ptr_t * GC_gcjobjfreelist;
ptr_t * GC_gcjobjfreelist;
ptr_t * GC_gcjdebugobjfreelist;
ptr_t * GC_gcjdebugobjfreelist;
 
 
/* Caller does not hold allocation lock. */
/* Caller does not hold allocation lock. */
void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
{
{
    register int i;
    register int i;
    GC_bool ignore_gcj_info;
    GC_bool ignore_gcj_info;
    DCL_LOCK_STATE;
    DCL_LOCK_STATE;
 
 
    GC_init();  /* In case it's not already done.       */
    GC_init();  /* In case it's not already done.       */
    DISABLE_SIGNALS();
    DISABLE_SIGNALS();
    LOCK();
    LOCK();
    if (GC_gcj_malloc_initialized) {
    if (GC_gcj_malloc_initialized) {
      UNLOCK();
      UNLOCK();
      ENABLE_SIGNALS();
      ENABLE_SIGNALS();
      return;
      return;
    }
    }
    GC_gcj_malloc_initialized = TRUE;
    GC_gcj_malloc_initialized = TRUE;
    ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
    ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
#   ifdef CONDPRINT
#   ifdef CONDPRINT
      if (GC_print_stats && ignore_gcj_info) {
      if (GC_print_stats && ignore_gcj_info) {
        GC_printf0("Gcj-style type information is disabled!\n");
        GC_printf0("Gcj-style type information is disabled!\n");
      }
      }
#   endif
#   endif
    GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */
    GC_ASSERT(GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */
    GC_mark_procs[mp_index] = (GC_mark_proc)mp;
    GC_mark_procs[mp_index] = (GC_mark_proc)mp;
    if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
    if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
    /* Set up object kind gcj-style indirect descriptor. */
    /* Set up object kind gcj-style indirect descriptor. */
      GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner();
      GC_gcjobjfreelist = (ptr_t *)GC_new_free_list_inner();
      if (ignore_gcj_info) {
      if (ignore_gcj_info) {
        /* Use a simple length-based descriptor, thus forcing a fully   */
        /* Use a simple length-based descriptor, thus forcing a fully   */
        /* conservative scan.                                           */
        /* conservative scan.                                           */
        GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist,
        GC_gcj_kind = GC_new_kind_inner((void **)GC_gcjobjfreelist,
                                        (0 | GC_DS_LENGTH),
                                        (0 | GC_DS_LENGTH),
                                        TRUE, TRUE);
                                        TRUE, TRUE);
      } else {
      } else {
        GC_gcj_kind = GC_new_kind_inner(
        GC_gcj_kind = GC_new_kind_inner(
                        (void **)GC_gcjobjfreelist,
                        (void **)GC_gcjobjfreelist,
                        (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS))
                        (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS))
                         | GC_DS_PER_OBJECT),
                         | GC_DS_PER_OBJECT),
                        FALSE, TRUE);
                        FALSE, TRUE);
      }
      }
    /* Set up object kind for objects that require mark proc call.      */
    /* Set up object kind for objects that require mark proc call.      */
      if (ignore_gcj_info) {
      if (ignore_gcj_info) {
        GC_gcj_debug_kind = GC_gcj_kind;
        GC_gcj_debug_kind = GC_gcj_kind;
        GC_gcjdebugobjfreelist = GC_gcjobjfreelist;
        GC_gcjdebugobjfreelist = GC_gcjobjfreelist;
      } else {
      } else {
        GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner();
        GC_gcjdebugobjfreelist = (ptr_t *)GC_new_free_list_inner();
        GC_gcj_debug_kind = GC_new_kind_inner(
        GC_gcj_debug_kind = GC_new_kind_inner(
                                (void **)GC_gcjdebugobjfreelist,
                                (void **)GC_gcjdebugobjfreelist,
                                GC_MAKE_PROC(mp_index,
                                GC_MAKE_PROC(mp_index,
                                             1 /* allocated with debug info */),
                                             1 /* allocated with debug info */),
                                FALSE, TRUE);
                                FALSE, TRUE);
      }
      }
    UNLOCK();
    UNLOCK();
    ENABLE_SIGNALS();
    ENABLE_SIGNALS();
}
}
 
 
ptr_t GC_clear_stack();
ptr_t GC_clear_stack();
 
 
#define GENERAL_MALLOC(lb,k) \
#define GENERAL_MALLOC(lb,k) \
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
 
 
#define GENERAL_MALLOC_IOP(lb,k) \
#define GENERAL_MALLOC_IOP(lb,k) \
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
    (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
 
 
/* We need a mechanism to release the lock and invoke finalizers.       */
/* We need a mechanism to release the lock and invoke finalizers.       */
/* We don't really have an opportunity to do this on a rarely executed  */
/* We don't really have an opportunity to do this on a rarely executed  */
/* path on which the lock is not held.  Thus we check at a              */
/* path on which the lock is not held.  Thus we check at a              */
/* rarely executed point at which it is safe to release the lock.       */
/* rarely executed point at which it is safe to release the lock.       */
/* We do this even where we could just call GC_INVOKE_FINALIZERS,       */
/* We do this even where we could just call GC_INVOKE_FINALIZERS,       */
/* since it's probably cheaper and certainly more uniform.              */
/* since it's probably cheaper and certainly more uniform.              */
/* FIXME - Consider doing the same elsewhere?                           */
/* FIXME - Consider doing the same elsewhere?                           */
static void maybe_finalize()
static void maybe_finalize()
{
{
   static int last_finalized_no = 0;
   static int last_finalized_no = 0;
 
 
   if (GC_gc_no == last_finalized_no) return;
   if (GC_gc_no == last_finalized_no) return;
   if (!GC_is_initialized) return;
   if (!GC_is_initialized) return;
   UNLOCK();
   UNLOCK();
   GC_INVOKE_FINALIZERS();
   GC_INVOKE_FINALIZERS();
   last_finalized_no = GC_gc_no;
   last_finalized_no = GC_gc_no;
   LOCK();
   LOCK();
}
}
 
 
/* Allocate an object, clear it, and store the pointer to the   */
/* Allocate an object, clear it, and store the pointer to the   */
/* type structure (vtable in gcj).                              */
/* type structure (vtable in gcj).                              */
/* This adds a byte at the end of the object if GC_malloc would.*/
/* This adds a byte at the end of the object if GC_malloc would.*/
void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
{
{
register ptr_t op;
register ptr_t op;
register ptr_t * opp;
register ptr_t * opp;
register word lw;
register word lw;
DCL_LOCK_STATE;
DCL_LOCK_STATE;
 
 
    if( EXPECT(SMALL_OBJ(lb), 1) ) {
    if( EXPECT(SMALL_OBJ(lb), 1) ) {
#       ifdef MERGE_SIZES
#       ifdef MERGE_SIZES
          lw = GC_size_map[lb];
          lw = GC_size_map[lb];
#       else
#       else
          lw = ALIGNED_WORDS(lb);
          lw = ALIGNED_WORDS(lb);
#       endif
#       endif
        opp = &(GC_gcjobjfreelist[lw]);
        opp = &(GC_gcjobjfreelist[lw]);
        LOCK();
        LOCK();
        op = *opp;
        op = *opp;
        if(EXPECT(op == 0, 0)) {
        if(EXPECT(op == 0, 0)) {
            maybe_finalize();
            maybe_finalize();
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
            op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
            if (0 == op) {
            if (0 == op) {
                UNLOCK();
                UNLOCK();
                return(GC_oom_fn(lb));
                return(GC_oom_fn(lb));
            }
            }
#           ifdef MERGE_SIZES
#           ifdef MERGE_SIZES
                lw = GC_size_map[lb];   /* May have been uninitialized. */
                lw = GC_size_map[lb];   /* May have been uninitialized. */
#           endif
#           endif
        } else {
        } else {
            *opp = obj_link(op);
            *opp = obj_link(op);
            GC_words_allocd += lw;
            GC_words_allocd += lw;
        }
        }
        *(void **)op = ptr_to_struct_containing_descr;
        *(void **)op = ptr_to_struct_containing_descr;
        GC_ASSERT(((void **)op)[1] == 0);
        GC_ASSERT(((void **)op)[1] == 0);
        UNLOCK();
        UNLOCK();
    } else {
    } else {
        LOCK();
        LOCK();
        maybe_finalize();
        maybe_finalize();
        op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
        op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
        if (0 == op) {
        if (0 == op) {
            UNLOCK();
            UNLOCK();
            return(GC_oom_fn(lb));
            return(GC_oom_fn(lb));
        }
        }
        *(void **)op = ptr_to_struct_containing_descr;
        *(void **)op = ptr_to_struct_containing_descr;
        UNLOCK();
        UNLOCK();
    }
    }
    return((GC_PTR) op);
    return((GC_PTR) op);
}
}
 
 
/* Similar to GC_gcj_malloc, but add debug info.  This is allocated     */
/* Similar to GC_gcj_malloc, but add debug info.  This is allocated     */
/* with GC_gcj_debug_kind.                                              */
/* with GC_gcj_debug_kind.                                              */
GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr,
GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr,
                           GC_EXTRA_PARAMS)
                           GC_EXTRA_PARAMS)
{
{
    GC_PTR result;
    GC_PTR result;
 
 
    /* We're careful to avoid extra calls, which could           */
    /* We're careful to avoid extra calls, which could           */
    /* confuse the backtrace.                                   */
    /* confuse the backtrace.                                   */
    LOCK();
    LOCK();
    maybe_finalize();
    maybe_finalize();
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
    if (result == 0) {
    if (result == 0) {
        UNLOCK();
        UNLOCK();
        GC_err_printf2("GC_debug_gcj_malloc(%ld, 0x%lx) returning NIL (",
        GC_err_printf2("GC_debug_gcj_malloc(%ld, 0x%lx) returning NIL (",
                       (unsigned long) lb,
                       (unsigned long) lb,
                       (unsigned long) ptr_to_struct_containing_descr);
                       (unsigned long) ptr_to_struct_containing_descr);
        GC_err_puts(s);
        GC_err_puts(s);
        GC_err_printf1(":%ld)\n", (unsigned long)i);
        GC_err_printf1(":%ld)\n", (unsigned long)i);
        return(GC_oom_fn(lb));
        return(GC_oom_fn(lb));
    }
    }
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
    UNLOCK();
    UNLOCK();
    if (!GC_debugging_started) {
    if (!GC_debugging_started) {
        GC_start_debugging();
        GC_start_debugging();
    }
    }
    ADD_CALL_CHAIN(result, ra);
    ADD_CALL_CHAIN(result, ra);
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
}
}
 
 
/* Similar to GC_gcj_malloc, but the size is in words, and we don't     */
/* Similar to GC_gcj_malloc, but the size is in words, and we don't     */
/* adjust it.  The size is assumed to be such that it can be    */
/* adjust it.  The size is assumed to be such that it can be    */
/* allocated as a small object.                                 */
/* allocated as a small object.                                 */
void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
{
{
ptr_t op;
ptr_t op;
ptr_t * opp;
ptr_t * opp;
DCL_LOCK_STATE;
DCL_LOCK_STATE;
 
 
    opp = &(GC_gcjobjfreelist[lw]);
    opp = &(GC_gcjobjfreelist[lw]);
    LOCK();
    LOCK();
    op = *opp;
    op = *opp;
    if( EXPECT(op == 0, 0) ) {
    if( EXPECT(op == 0, 0) ) {
        maybe_finalize();
        maybe_finalize();
        op = (ptr_t)GC_clear_stack(
        op = (ptr_t)GC_clear_stack(
                GC_generic_malloc_words_small_inner(lw, GC_gcj_kind));
                GC_generic_malloc_words_small_inner(lw, GC_gcj_kind));
        if (0 == op) {
        if (0 == op) {
            UNLOCK();
            UNLOCK();
            return GC_oom_fn(WORDS_TO_BYTES(lw));
            return GC_oom_fn(WORDS_TO_BYTES(lw));
        }
        }
    } else {
    } else {
        *opp = obj_link(op);
        *opp = obj_link(op);
        GC_words_allocd += lw;
        GC_words_allocd += lw;
    }
    }
    *(void **)op = ptr_to_struct_containing_descr;
    *(void **)op = ptr_to_struct_containing_descr;
    UNLOCK();
    UNLOCK();
    return((GC_PTR) op);
    return((GC_PTR) op);
}
}
 
 
/* And a debugging version of the above:        */
/* And a debugging version of the above:        */
void * GC_debug_gcj_fast_malloc(size_t lw,
void * GC_debug_gcj_fast_malloc(size_t lw,
                                void * ptr_to_struct_containing_descr,
                                void * ptr_to_struct_containing_descr,
                                GC_EXTRA_PARAMS)
                                GC_EXTRA_PARAMS)
{
{
    GC_PTR result;
    GC_PTR result;
    size_t lb = WORDS_TO_BYTES(lw);
    size_t lb = WORDS_TO_BYTES(lw);
 
 
    /* We clone the code from GC_debug_gcj_malloc, so that we   */
    /* We clone the code from GC_debug_gcj_malloc, so that we   */
    /* dont end up with extra frames on the stack, which could  */
    /* dont end up with extra frames on the stack, which could  */
    /* confuse the backtrace.                                   */
    /* confuse the backtrace.                                   */
    LOCK();
    LOCK();
    maybe_finalize();
    maybe_finalize();
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
    result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
    if (result == 0) {
    if (result == 0) {
        UNLOCK();
        UNLOCK();
        GC_err_printf2("GC_debug_gcj_fast_malloc(%ld, 0x%lx) returning NIL (",
        GC_err_printf2("GC_debug_gcj_fast_malloc(%ld, 0x%lx) returning NIL (",
                       (unsigned long) lw,
                       (unsigned long) lw,
                       (unsigned long) ptr_to_struct_containing_descr);
                       (unsigned long) ptr_to_struct_containing_descr);
        GC_err_puts(s);
        GC_err_puts(s);
        GC_err_printf1(":%ld)\n", (unsigned long)i);
        GC_err_printf1(":%ld)\n", (unsigned long)i);
        return GC_oom_fn(WORDS_TO_BYTES(lw));
        return GC_oom_fn(WORDS_TO_BYTES(lw));
    }
    }
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
    *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
    UNLOCK();
    UNLOCK();
    if (!GC_debugging_started) {
    if (!GC_debugging_started) {
        GC_start_debugging();
        GC_start_debugging();
    }
    }
    ADD_CALL_CHAIN(result, ra);
    ADD_CALL_CHAIN(result, ra);
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
    return (GC_store_debug_info(result, (word)lb, s, (word)i));
}
}
 
 
void * GC_gcj_malloc_ignore_off_page(size_t lb,
void * GC_gcj_malloc_ignore_off_page(size_t lb,
                                     void * ptr_to_struct_containing_descr)
                                     void * ptr_to_struct_containing_descr)
{
{
register ptr_t op;
register ptr_t op;
register ptr_t * opp;
register ptr_t * opp;
register word lw;
register word lw;
DCL_LOCK_STATE;
DCL_LOCK_STATE;
 
 
    if( SMALL_OBJ(lb) ) {
    if( SMALL_OBJ(lb) ) {
#       ifdef MERGE_SIZES
#       ifdef MERGE_SIZES
          lw = GC_size_map[lb];
          lw = GC_size_map[lb];
#       else
#       else
          lw = ALIGNED_WORDS(lb);
          lw = ALIGNED_WORDS(lb);
#       endif
#       endif
        opp = &(GC_gcjobjfreelist[lw]);
        opp = &(GC_gcjobjfreelist[lw]);
        LOCK();
        LOCK();
        if( (op = *opp) == 0 ) {
        if( (op = *opp) == 0 ) {
            maybe_finalize();
            maybe_finalize();
            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
            op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
#           ifdef MERGE_SIZES
#           ifdef MERGE_SIZES
                lw = GC_size_map[lb];   /* May have been uninitialized. */
                lw = GC_size_map[lb];   /* May have been uninitialized. */
#           endif
#           endif
        } else {
        } else {
            *opp = obj_link(op);
            *opp = obj_link(op);
            GC_words_allocd += lw;
            GC_words_allocd += lw;
        }
        }
        *(void **)op = ptr_to_struct_containing_descr;
        *(void **)op = ptr_to_struct_containing_descr;
        UNLOCK();
        UNLOCK();
    } else {
    } else {
        LOCK();
        LOCK();
        maybe_finalize();
        maybe_finalize();
        op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
        op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
        if (0 != op) {
        if (0 != op) {
          *(void **)op = ptr_to_struct_containing_descr;
          *(void **)op = ptr_to_struct_containing_descr;
        }
        }
        UNLOCK();
        UNLOCK();
    }
    }
    return((GC_PTR) op);
    return((GC_PTR) op);
}
}
 
 
#else
#else
 
 
char GC_no_gcj_support;
char GC_no_gcj_support;
 
 
#endif  /* GC_GCJ_SUPPORT */
#endif  /* GC_GCJ_SUPPORT */
 
 

powered by: WebSVN 2.1.0

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