#include "GCThread.h"
#include "GCUtils.h"
#include "Compact.h"
+#include "MarkStack.h"
#include "Prelude.h"
#include "Trace.h"
#include "LdvProfile.h"
to = alloc_for_copy(size,stp);
- TICK_GC_WORDS_COPIED(size);
-
from = (StgPtr)src;
to[0] = (W_)info;
for (i = 1; i < size; i++) { // unroll for small i
#if defined(PARALLEL_GC)
{
const StgInfoTable *new_info;
- new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info,
- (W_)info, MK_FORWARDING_PTR(to));
+ new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, (W_)info, MK_FORWARDING_PTR(to));
if (new_info != info) {
return evacuate(p); // does the failed_to_evac stuff
} else {
*p = TAG_CLOSURE(tag,(StgClosure*)to);
src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
- TICK_GC_WORDS_COPIED(size);
-
from = (StgPtr)src;
to[0] = (W_)info;
for (i = 1; i < size; i++) { // unroll for small i
* used to optimise evacuation of BLACKHOLEs.
*/
static rtsBool
-copyPart(StgClosure **p, const StgInfoTable *info, StgClosure *src,
- nat size_to_reserve, nat size_to_copy, step *stp)
+copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
{
StgPtr to, from;
nat i;
+ StgWord info;
- to = alloc_for_copy(size_to_reserve, stp);
+#if defined(PARALLEL_GC)
+spin:
+ info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
+ if (info == (W_)&stg_WHITEHOLE_info) {
+#ifdef PROF_SPIN
+ whitehole_spin++;
+#endif
+ goto spin;
+ }
+ if (IS_FORWARDING_PTR(info)) {
+ src->header.info = (const StgInfoTable *)info;
+ evacuate(p); // does the failed_to_evac stuff
+ return rtsFalse;
+ }
+#else
+ info = (W_)src->header.info;
+#endif
- TICK_GC_WORDS_COPIED(size_to_copy);
+ to = alloc_for_copy(size_to_reserve, stp);
+ *p = (StgClosure *)to;
from = (StgPtr)src;
- to[0] = (W_)info;
+ to[0] = info;
for (i = 1; i < size_to_copy; i++) { // unroll for small i
to[i] = from[i];
}
#if defined(PARALLEL_GC)
- {
- const StgInfoTable *new_info;
- new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info,
- (W_)info, MK_FORWARDING_PTR(to));
- if (new_info != info) {
- evacuate(p); // does the failed_to_evac stuff
- return rtsFalse;
- } else {
- *p = (StgClosure*)to;
- }
- }
-#else
- src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
- *p = (StgClosure*)to;
+ write_barrier();
#endif
-
+ src->header.info = (const StgInfoTable*)MK_FORWARDING_PTR(to);
+
#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.
*/
if (!is_marked((P_)q,bd)) {
mark((P_)q,bd);
- if (mark_stack_full()) {
- debugTrace(DEBUG_gc,"mark stack overflowed");
- mark_stack_overflowed = rtsTrue;
- reset_mark_stack();
- }
push_mark_stack((P_)q);
}
return;
copy(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),stp);
return;
+ // For ints and chars of low value, save space by replacing references to
+ // these with closures with references to common, shared ones in the RTS.
+ //
+ // * Except when compiling into Windows DLLs which don't support cross-package
+ // data references very well.
+ //
case CONSTR_0_1:
- {
+ {
+#if defined(__PIC__) && defined(mingw32_HOST_OS)
+ copy_tag_nolock(p,info,q,sizeofW(StgHeader)+1,stp,tag);
+#else
StgWord w = (StgWord)q->payload[0];
if (info == Czh_con_info &&
// unsigned, so always true: (StgChar)w >= MIN_CHARLIKE &&
else {
copy_tag_nolock(p,info,q,sizeofW(StgHeader)+1,stp,tag);
}
+#endif
return;
}
case CAF_BLACKHOLE:
case BLACKHOLE:
- copyPart(p,info,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
+ copyPart(p,q,BLACKHOLE_sizeW(),sizeofW(StgHeader),stp);
return;
case THUNK_SELECTOR:
goto loop;
}
- /* To evacuate a small TSO, we need to relocate the update frame
- * list it contains.
+ /* To evacuate a small TSO, we need to adjust the stack pointer
*/
{
StgTSO *new_tso;
StgPtr r, s;
rtsBool mine;
- mine = copyPart(p,info,(StgClosure *)tso, tso_sizeW(tso),
+ mine = copyPart(p,(StgClosure *)tso, tso_sizeW(tso),
sizeofW(StgTSO), stp);
if (mine) {
new_tso = (StgTSO *)*p;