Beispiel #1
0
/*
 * A version of GC_push_all that treats all interior pointers as valid
 * and scans part of the area immediately, to make sure that saved
 * register values are not lost.
 * Cold_gc_frame delimits the stack section that must be scanned
 * eagerly.  A zero value indicates that no eager scanning is needed.
 * We don't need to worry about the MANUAL_VDB case here, since this
 * is only called in the single-threaded case.  We assume that we
 * cannot collect between an assignment and the corresponding
 * GC_dirty() call.
 */
STATIC void GC_push_all_stack_partially_eager(ptr_t bottom, ptr_t top,
                                              ptr_t cold_gc_frame)
{
#ifndef NEED_FIXUP_POINTER
  if (GC_all_interior_pointers) {
    /* Push the hot end of the stack eagerly, so that register values   */
    /* saved inside GC frames are marked before they disappear.         */
    /* The rest of the marking can be deferred until later.             */
    if (0 == cold_gc_frame) {
        GC_push_all_stack(bottom, top);
        return;
    }
    GC_ASSERT((word)bottom <= (word)cold_gc_frame
              && (word)cold_gc_frame <= (word)top);
#   ifdef STACK_GROWS_DOWN
        GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
        GC_push_all_eager(bottom, cold_gc_frame);
#   else /* STACK_GROWS_UP */
        GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t));
        GC_push_all_eager(cold_gc_frame, top);
#   endif /* STACK_GROWS_UP */
  } else
#endif
  /* else */ {
    GC_push_all_eager(bottom, top);
  }
# ifdef TRACE_BUF
    GC_add_trace_entry("GC_push_all_stack", (word)bottom, (word)top);
# endif
}
Beispiel #2
0
/*ARGSUSED*/
STATIC void GC_push_current_stack(ptr_t cold_gc_frame, void * context)
{
#   if defined(THREADS)
        if (0 == cold_gc_frame) return;
#       ifdef STACK_GROWS_DOWN
          GC_push_all_eager(GC_approx_sp(), cold_gc_frame);
          /* For IA64, the register stack backing store is handled      */
          /* in the thread-specific code.                               */
#       else
          GC_push_all_eager(cold_gc_frame, GC_approx_sp());
#       endif
#   else
        GC_push_all_stack_part_eager_sections(GC_approx_sp(), GC_stackbottom,
                                        cold_gc_frame, GC_traced_stack_sect);
#       ifdef IA64
              /* We also need to push the register stack backing store. */
              /* This should really be done in the same way as the      */
              /* regular stack.  For now we fudge it a bit.             */
              /* Note that the backing store grows up, so we can't use  */
              /* GC_push_all_stack_partially_eager.                     */
              {
                ptr_t bsp = GC_save_regs_ret_val;
                ptr_t cold_gc_bs_pointer = bsp - 2048;
                if (GC_all_interior_pointers &&
                    cold_gc_bs_pointer > BACKING_STORE_BASE) {
                  /* Adjust cold_gc_bs_pointer if below our innermost   */
                  /* "traced stack section" in backing store.           */
                  if (GC_traced_stack_sect != NULL && cold_gc_bs_pointer <
                                GC_traced_stack_sect->backing_store_end)
                    cold_gc_bs_pointer =
                                GC_traced_stack_sect->backing_store_end;
                  GC_push_all_register_sections(BACKING_STORE_BASE,
                        cold_gc_bs_pointer, FALSE, GC_traced_stack_sect);
                  GC_push_all_eager(cold_gc_bs_pointer, bsp);
                } else {
                  GC_push_all_register_sections(BACKING_STORE_BASE, bsp,
                                TRUE /* eager */, GC_traced_stack_sect);
                }
                /* All values should be sufficiently aligned that we    */
                /* don't have to worry about the boundary.              */
              }
#       endif
#   endif /* !THREADS */
}
Beispiel #3
0
 /* Similar to GC_push_all_stack_sections() but for IA-64 registers store. */
 GC_INNER void GC_push_all_register_sections(ptr_t bs_lo, ptr_t bs_hi,
                 int eager, struct GC_traced_stack_sect_s *traced_stack_sect)
 {
   while (traced_stack_sect != NULL) {
       ptr_t frame_bs_lo = traced_stack_sect -> backing_store_end;
       GC_ASSERT((word)frame_bs_lo <= (word)bs_hi);
       if (eager) {
           GC_push_all_eager(frame_bs_lo, bs_hi);
       } else {
           GC_push_all_stack(frame_bs_lo, bs_hi);
       }
       bs_hi = traced_stack_sect -> saved_backing_store_ptr;
       traced_stack_sect = traced_stack_sect -> prev;
   }
   GC_ASSERT((word)bs_lo <= (word)bs_hi);
   if (eager) {
       GC_push_all_eager(bs_lo, bs_hi);
   } else {
       GC_push_all_stack(bs_lo, bs_hi);
   }
 }