summaryrefslogtreecommitdiff
path: root/mark.c
diff options
context:
space:
mode:
authorIlya Kurdyukov <ilyakurdyukov@altlinux.org>2021-07-02 12:00:00 +0700
committerIvan Maidanski <ivmai@mail.ru>2022-01-12 09:59:55 +0300
commit9ddbbae8e860c779d7fa548daceb1130916059ff (patch)
tree272389e85cd443134e6351672ae3a5f4474f7899 /mark.c
parent7ef3eca8a709ce679664e280a44a828fb7caba5e (diff)
downloadbdwgc-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.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/mark.c b/mark.c
index 996efa54..a743ba16 100644
--- a/mark.c
+++ b/mark.c
@@ -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