return to;
}
-STATIC_INLINE void
-copy_tag(StgClosure **p, StgClosure *src, nat size, step *stp,StgWord tag)
-{
- StgPtr to, tagged_to, from;
- nat i;
- StgWord info;
-
-#ifdef THREADED_RTS
- do {
- info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
- // so.. what is it?
- } while (info == (W_)&stg_WHITEHOLE_info);
- if (info == (W_)&stg_EVACUATED_info) {
- src->header.info = (const StgInfoTable *)info;
- return evacuate(p); // does the failed_to_evac stuff
- }
-#else
- info = (W_)src->header.info;
- src->header.info = &stg_EVACUATED_info;
-#endif
-
- to = alloc_for_copy(size,stp);
- tagged_to = (StgPtr)TAG_CLOSURE(tag,(StgClosure*)to);
- *p = (StgClosure *)tagged_to;
-
- TICK_GC_WORDS_COPIED(size);
-
- from = (StgPtr)src;
- to[0] = info;
- for (i = 1; i < size; i++) { // unroll for small i
- to[i] = from[i];
- }
-
- ((StgEvacuated*)from)->evacuee = (StgClosure *)tagged_to;
-
- // retag pointer before updating EVACUATE closure and returning
-
-// if (to+size+2 < bd->start + BLOCK_SIZE_W) {
-// __builtin_prefetch(to + size + 2, 1);
-// }
-
-#ifdef THREADED_RTS
- write_barrier();
- ((StgEvacuated*)from)->header.info = &stg_EVACUATED_info;
-#endif
-
-#ifdef PROFILING
- // We store the size of the just evacuated object in the LDV word so that
- // the profiler can guess the position of the next object later.
- SET_EVACUAEE_FOR_LDV(from, size);
-#endif
-}
-
-/* Special version of copy() for when we only want to copy the info
- * pointer of an object, but reserve some padding after it. This is
- * used to optimise evacuation of BLACKHOLEs.
- */
-static void
-copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
-{
- StgPtr to, from;
- nat i;
- StgWord info;
-
-#ifdef THREADED_RTS
- do {
- info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
- } while (info == (W_)&stg_WHITEHOLE_info);
- if (info == (W_)&stg_EVACUATED_info) {
- src->header.info = (const StgInfoTable *)info;
- return evacuate(p); // does the failed_to_evac stuff
- }
-#else
- info = (W_)src->header.info;
- src->header.info = &stg_EVACUATED_info;
-#endif
-
- to = alloc_for_copy(size_to_reserve, stp);
- *p = (StgClosure *)to;
-
- TICK_GC_WORDS_COPIED(size_to_copy);
-
- from = (StgPtr)src;
- to[0] = info;
- for (i = 1; i < size_to_copy; i++) { // unroll for small i
- to[i] = from[i];
- }
-
- ((StgEvacuated*)from)->evacuee = (StgClosure *)to;
-#ifdef THREADED_RTS
- write_barrier();
- ((StgEvacuated*)from)->header.info = &stg_EVACUATED_info;
-#endif
-
-#ifdef PROFILING
- // We store the size of the just evacuated object in the LDV word so that
- // the profiler can guess the position of the next object later.
- SET_EVACUAEE_FOR_LDV(from, size_to_reserve);
- // fill the slop
- if (size_to_reserve - size_to_copy > 0)
- LDV_FILL_SLOP(to + size_to_copy - 1, (int)(size_to_reserve - size_to_copy));
-#endif
-}
-
-
-/* Copy wrappers that don't tag the closure after copying */
-STATIC_INLINE void
-copy(StgClosure **p, StgClosure *src, nat size, step *stp)
-{
- copy_tag(p,src,size,stp,0);
-}
-
/* -----------------------------------------------------------------------------
The evacuate() code
-------------------------------------------------------------------------- */
// In threaded mode, we'll use WHITEHOLE to lock the selector
// thunk while we evaluate it.
{
- info_ptr = (StgInfoTable *)xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
+ info_ptr = xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);
if (info_ptr == (W_)&stg_WHITEHOLE_info) {
do {
info_ptr = xchg((StgPtr)&p->header.info, (W_)&stg_WHITEHOLE_info);