diff options
author | Ilya Kurdyukov <ilyakurdyukov@altlinux.org> | 2021-07-02 12:00:00 +0700 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-01-12 09:59:55 +0300 |
commit | 9ddbbae8e860c779d7fa548daceb1130916059ff (patch) | |
tree | 272389e85cd443134e6351672ae3a5f4474f7899 /mark.c | |
parent | 7ef3eca8a709ce679664e280a44a828fb7caba5e (diff) | |
download | bdwgc-9ddbbae8e860c779d7fa548daceb1130916059ff.tar.gz |
Support Elbrus 2000 (Linux/e2k)
(a port of altlinux libgc-e2k.patch (8ed786c))
Issue #411 (bdwgc).
* include/gc/gc.h [__GNUC__ && !__INTEL_COMPILER && __e2k__]
(GC_reachable_here): Specify "r" contraint for ptr.
* include/gc/gc.h [__e2k__] (GC_stack_base): Declare reg_base field.
* include/private/gc_priv.h [E2K] (GC_push_all_register_sections,
GC_save_regs_in_stack, GC_get_procedure_stack): Declare.
* include/private/gc_priv.h [E2K && __ptr64__] (LOAD_TAGGED_VALUE):
Define macro.
* include/private/gc_priv.h (LOAD_WORD_OR_CONTINUE): Likewise.
* include/private/gcconfig.h [LINUX && __e2k__] (E2K, mach_type_known):
Likewise.
* include/private/gcconfig.h [E2K] (MACH_TYPE, CPP_WORDSZ, ALIGNMENT,
HBLKSIZE): Likewise.
* include/private/gcconfig.h [E2K && LINUX] (DATASTART): Likewise.
* mach_dep.c [E2K] (VA_SIZE, E2K_PSHTP_SIZE, get_stack_index):
Likewise.
* include/private/gcconfig.h [GC_GNUC_PREREQ(2,8)]
(HAVE_BUILTIN_UNWIND_INIT): Do not define if E2K.
* include/private/gcconfig.h [E2K && LINUX] (__dso_handle): Declare
extern variable.
* include/private/pthread_support.h [E2K] (GC_Thread_Rep): Declare
backing_store_end and backing_store_ptr fields.
* mach_dep.c [E2K]: Include errno.h, sys/syscall.h, asm/e2k_syswork.h.
* mach_dep.c [E2K] (e2k_rwap_lo_fields, e2k_rwap_hi_fields): Declare
struct.
* mach_dep.c [E2K] (e2k_rwap_lo_u, e2k_rwap_hi_u): Declare union.
* mach_dep.c [E2K] (GC_get_procedure_stack, GC_save_regs_in_stack):
Implement.
* mach_dep.c [E2K] (GC_with_callee_saves_pushed): Call
GC_save_regs_in_stack() (not saving the result).
* mark.c (GC_mark_from, GC_push_all_eager): Use LOAD_WORD_OR_CONTINUE()
instead of direct dereference of current_p.
* mark.c [!SMALL_CONFIG] (GC_mark_from): Do not prefetch if E2K.
* mark_rts.c [E2K] (GC_push_all_register_sections): Implement but
ignore traced_stack_sect (add TODO item).
* mark_rts.c [!THREADS && E2K] (GC_push_current_stack): Call
GC_get_procedure_stack() and GC_push_all_register_sections().
* misc.c [E2K] (GC_call_with_stack_base): Initialize reg_base to 0.
* misc.c [!THREADS && E2K] (GC_do_blocking_inner,
GC_get_my_stackbottom): Likewise.
* os_dep.c [((HAVE_PTHREAD_ATTR_GET_NP || HAVE_PTHREAD_GETATTR_NP)
&& THREADS || !HAVE_GET_STACK_BASE) && E2K] (GC_get_stack_base):
Likewise.
* pthread_support.c [E2K] (GC_get_my_stackbottom): Likewise.
* pthread_stop_world.c [E2K] (GC_suspend_handler): Call
GC_with_callee_saves_pushed().
* pthread_stop_world.c [E2K] (GC_store_stack_ptr): Call
GC_save_regs_in_stack() and GC_get_procedure_stack().
* pthread_stop_world.c [E2K] (GC_suspend_handler_inner): Call
free(me->backing_store_end) before return.
* pthread_stop_world.c [E2K] (GC_push_all_stacks): Declare bs_lo,
bs_hi, stack_size local variables; call GC_save_regs_in_stack() and
GC_get_procedure_stack() (and free() at the end) for self thread;
call GC_push_all_register_sections().
* pthread_support.c [E2K] (GC_do_blocking_inner): Call
GC_save_regs_in_stack(); add FIXME.
Diffstat (limited to 'mark.c')
-rw-r--r-- | mark.c | 26 |
1 files changed, 12 insertions, 14 deletions
@@ -712,11 +712,11 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, # endif /* ENABLE_TRACE */ descr &= ~GC_DS_TAGS; credit -= WORDS_TO_BYTES(WORDSZ/2); /* guess */ - while (descr != 0) { - if ((descr & SIGNB) != 0) { - current = *(word *)current_p; - FIXUP_POINTER(current); - if (current >= (word)least_ha && current < (word)greatest_ha) { + for (; descr != 0; descr <<= 1, current_p += sizeof(word)) { + if ((descr & SIGNB) == 0) continue; + LOAD_WORD_OR_CONTINUE(current, current_p); + FIXUP_POINTER(current); + if (current >= (word)least_ha && current < (word)greatest_ha) { PREFETCH((ptr_t)current); # ifdef ENABLE_TRACE if (GC_trace_addr == current_p) { @@ -727,10 +727,7 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, # endif /* ENABLE_TRACE */ PUSH_CONTENTS((ptr_t)current, mark_stack_top, mark_stack_limit, current_p); - } } - descr <<= 1; - current_p += sizeof(word); } continue; case GC_DS_PROC: @@ -803,7 +800,8 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, { # define PREF_DIST 4 -# ifndef SMALL_CONFIG +# if !defined(SMALL_CONFIG) && !defined(E2K) + /* TODO: enable prefetching for E2K? */ word deferred; /* Try to prefetch the next pointer to be examined ASAP. */ @@ -836,11 +834,11 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, } # endif - while ((word)current_p <= (word)limit) { + for (; (word)current_p <= (word)limit; current_p += ALIGNMENT) { /* Empirically, unrolling this loop doesn't help a lot. */ /* Since PUSH_CONTENTS expands to a lot of code, */ /* we don't. */ - current = *(word *)current_p; + LOAD_WORD_OR_CONTINUE(current, current_p); FIXUP_POINTER(current); PREFETCH(current_p + PREF_DIST*CACHE_LINE_SIZE); if (current >= (word)least_ha && current < (word)greatest_ha) { @@ -857,10 +855,9 @@ GC_INNER mse * GC_mark_from(mse *mark_stack_top, mse *mark_stack, PUSH_CONTENTS((ptr_t)current, mark_stack_top, mark_stack_limit, current_p); } - current_p += ALIGNMENT; } -# ifndef SMALL_CONFIG +# if !defined(SMALL_CONFIG) && !defined(E2K) /* We still need to mark the entry we previously prefetched. */ /* We already know that it passes the preliminary pointer */ /* validity test. */ @@ -1582,8 +1579,9 @@ GC_API void GC_CALL GC_push_all_eager(void *bottom, void *top) lim = (word *)(((word)top) & ~(ALIGNMENT-1)) - 1; for (current_p = (ptr_t)(((word)bottom + ALIGNMENT-1) & ~(ALIGNMENT-1)); (word)current_p <= (word)lim; current_p += ALIGNMENT) { - REGISTER word q = *(word *)current_p; + REGISTER word q; + LOAD_WORD_OR_CONTINUE(q, current_p); GC_PUSH_ONE_STACK(q, current_p); } # undef GC_greatest_plausible_heap_addr |