-
-// Same as copy() above, except the object will be allocated in memory
-// that will not be scavenged. Used for object that have no pointer
-// fields.
-STATIC_INLINE void
-copy_noscav_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);
- } 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_noscav(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;
-
-#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
-}
-
-