Skip to content

Commit

Permalink
some cleanup and defensive programming in read/write barriers
Browse files Browse the repository at this point in the history
  • Loading branch information
shwestrick committed Feb 15, 2024
1 parent 5f8a951 commit 5023c0e
Showing 1 changed file with 7 additions and 190 deletions.
197 changes: 7 additions & 190 deletions runtime/gc/assign.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ objptr Assignable_readBarrier(
// can't rely on obj header becaues it may be forwarded.

s->cumulativeStatistics->numDisentanglementChecks++;
objptr ptr = *field;
objptr ptr = __atomic_load_n(field, __ATOMIC_ACQUIRE);
pointer objp = objptrToPointer(obj, NULL);
HM_HierarchicalHeap objHH = HM_getLevelHead(HM_getChunkOf(objp));
if (!isObjptr(ptr) || HM_HH_getDepth(objHH) == 0 || !ES_contains(NULL, obj))
Expand Down Expand Up @@ -98,7 +98,7 @@ static inline bool decheck_opt_fast (GC_state s, pointer p) {
void Assignable_writeBarrier(
GC_state s,
objptr dst,
ARG_USED_FOR_ASSERT objptr* field,
objptr* field,
objptr src)
{
assert(isObjptr(dst));
Expand Down Expand Up @@ -141,7 +141,7 @@ void Assignable_writeBarrier(

HM_HierarchicalHeap dstHH = HM_getLevelHead(HM_getChunkOf(dstp));

objptr readVal = *field;
objptr readVal = __atomic_load_n(field, __ATOMIC_ACQUIRE);
if (dstHH->depth >= 1 && isObjptr(readVal) && s->wsQueueTop!=BOGUS_OBJPTR) {
pointer currp = objptrToPointer(readVal, NULL);
HM_HierarchicalHeap currHH = HM_getLevelHead(HM_getChunkOf(currp));
Expand Down Expand Up @@ -206,204 +206,21 @@ void Assignable_writeBarrier(
}

if (dd > 0 && !ES_contains(NULL, dst)) {
/*if dst is not a suspect, it must be disentangled*/
// if (!dst_de) {
// printf("problematix: %p \n", dst);
// DIE("done");
// }
// assert (dst_de);
HM_HierarchicalHeap dhh = HM_HH_getHeapAtDepth(s, getThreadCurrent(s), dd);
ES_add(s, HM_HH_getSuspects(dhh), dst);
}
}
else if(dstHH->depth != 0) {
// traverseAndCheck(s, &dst, dst, NULL);

// SAM_NOTE: TODO: do we count this one??
s->cumulativeStatistics->numEntanglements++;
manage_entangled (s, src, HM_getChunkOf(dstp)->decheckState);
}


// if (!dst_de) {
// assert (ES_contains(NULL, dst));
// }

/* Depth comparisons make sense only when src && dst are on the same root-to-leaf path,
* checking this maybe expensive, so we approximate here.
* If both dst_de && src_de hold, they are on the same path
* Otherwise, we assume they are on different paths.
*/




// /* otherwise pin*/
// // bool primary_down_ptr = dst_de && dd < sd && (HM_HH_getConcurrentPack(dstHH)->ccstate == CC_UNREG);
// = dst_de ? dd :
// (uint32_t)lcaHeapDepth(HM_getChunkOf(srcp)->decheckState,
// HM_getChunkOf(dstp)->decheckState);
// enum PinType pt = dst_de ? PIN_DOWN : PIN_ANY;

// bool success = pinTemp(s, src, unpinDepth, pt);
// if (success || (dst_de && dd == unpinDepthOf (src))) {
// objptr fromObj = pt == PIN_DOWN ? dst : BOGUS_OBJPTR;
// struct HM_remembered remElem_ = {.object = src, .from = fromObj};
// HM_remembered remElem = &remElem_;
objptr newsrc = manage_entangled (s, src, HM_getChunkOf(dstp)->decheckState);

// HM_HierarchicalHeap shh = HM_HH_getHeapAtDepth(s, getThreadCurrent(s), sd);
// assert(NULL != shh);
// assert(HM_HH_getConcurrentPack(shh)->ccstate == CC_UNREG);

// HM_HH_rememberAtLevel(shh, remElem, false);
// LOG(LM_HH_PROMOTION, LL_INFO,
// "remembered downptr %"PRIu32"->%"PRIu32" from "FMTOBJPTR" to "FMTOBJPTR,
// dstHH->depth, srcHH->depth,
// dst, src);
// }
// this better be true... otherwise everything is going to explode
assert(newsrc == src);
}

// /*add dst to the suspect set*/
// if (dd > 0 && dst_de && !ES_contains(NULL, dst)) {
// /*if dst is not a suspect, it must be disentangled*/
// // if (!dst_de) {
// // printf("problematix: %p \n", dst);
// // DIE("done");
// // }
// // assert (dst_de);
// HM_HierarchicalHeap dhh = HM_HH_getHeapAtDepth(s, getThreadCurrent(s), dd);
// ES_add(s, HM_HH_getSuspects(dhh), dst);
// }
} else {
// assert (isPinned(src));
// assert (!hasFwdPtr(srcp));
// assert (pinType(getHeader(srcp)) == PIN_ANY);
traverseAndCheck(s, &src, src, NULL);
}


#if 0
/** This is disabled for now. In the future we will come back to
* managing entanglement.
*/
if (s->controls->manageEntanglement &&
getThreadCurrent(s)->decheckState.bits != DECHECK_BOGUS_BITS &&

((HM_getChunkOf(srcp)->decheckState.bits != DECHECK_BOGUS_BITS &&
!decheckIsOrdered(getThreadCurrent(s), HM_getChunkOf(srcp)->decheckState))
||
(HM_getChunkOf(dstp)->decheckState.bits != DECHECK_BOGUS_BITS &&
!decheckIsOrdered(getThreadCurrent(s), HM_getChunkOf(dstp)->decheckState))))
{
/** Nasty entanglement. To be safe, just pin the object. A safe unpin
* depth is the overall lca.
*/

int unpinDepth1 =
lcaHeapDepth(getThreadCurrent(s)->decheckState,
HM_getChunkOf(srcp)->decheckState);

int unpinDepth2 =
lcaHeapDepth(getThreadCurrent(s)->decheckState,
HM_getChunkOf(dstp)->decheckState);

int unpinDepth = (unpinDepth1 < unpinDepth2 ? unpinDepth1 : unpinDepth2);

if (pinObject(src, (uint32_t)unpinDepth)) {
/** Just remember it at some arbitrary place... */
HM_HH_rememberAtLevel(getThreadCurrent(s)->hierarchicalHeap, remElem);
}

return;
}
#endif


/* Up-pointer. */
// if (dstHH->depth > srcHH->depth)
// return;

/* Internal pointer. It's safe to ignore an internal pointer if:
* 1. it's contained entirely within one subheap, or
* 2. the pointed-to object (src) lives in an already snapshotted subregion
*/
// if ( (dstHH == srcHH) ||
// (dstHH->depth == srcHH->depth &&
// HM_HH_getConcurrentPack(srcHH)->ccstate != CC_UNREG) ) {
// // assert(...);
// // if (dstHH != srcHH) {
// // printf(
// // "ignore internal pointer "FMTPTR" --> "FMTPTR". dstHH == srcHH? %d\n",
// // (uintptr_t)dstp,
// // (uintptr_t)srcp,
// // srcHH == dstHH);
// // }
// return;
// }
/** Otherwise, its a down-pointer, so
* (i) make dst a suspect for entanglement, i.e., mark the suspect bit of dst's header
* (see pin.h for header-layout).
* the compiler checks this suspect bit and calls the read-barrier
* only when the bit is set.
* (ii) pin the src object
* (iii) remember the down pointer
*/

/* make dst a suspect for entanglement */
// uint32_t dd = dstHH->depth;
// if (dd > 0 && !ES_contains(NULL, dst)) {
// HM_HierarchicalHeap dhh = HM_HH_getHeapAtDepth(s, thread, dd);
// ES_add(s, HM_HH_getSuspects(dhh), dst);
// }

// if (decheck(s, src)) {
// uint32_t sd = srcHH->depth;
// bool dst_de = decheck(s, dst);
// assert (dd <= sd);
// bool true_down_ptr = dd < sd && (HM_HH_getConcurrentPack(dstHH)->ccstate == CC_UNREG) && dst_de;
// // bool unpinDepth = dst_de ? dd : lcaDepth(srcHH->tid, dstHH->tid);
// /* treat a pointer from a chained heap as a cross pointer */
// bool success = pinObject(src, dd, true_down_ptr ? PIN_DOWN : PIN_ANY);
// if (success)
// {
// HM_HierarchicalHeap shh = HM_HH_getHeapAtDepth(s, thread, sd);
// assert(NULL != shh);
// assert(HM_HH_getConcurrentPack(shh)->ccstate == CC_UNREG);
// HM_HH_rememberAtLevel(shh, remElem, false);

// LOG(LM_HH_PROMOTION, LL_INFO,
// "remembered downptr %"PRIu32"->%"PRIu32" from "FMTOBJPTR" to "FMTOBJPTR,
// dstHH->depth, srcHH->depth,
// dst, src);
// }
// if (!dst_de)
// {
// DIE("HAVE TO HANDLE ENTANGLED WRITES SEPARATELY");
// // HM_HierarchicalHeap lcaHeap = HM_HH_getHeapAtDepth(s, thread, unpinDepth);
// // ES_add(s, HM_HH_getSuspects(lcaHeap), ptr);
// }
// }


// // any concurrent pin can only decrease unpinDepth
// assert(unpinDepth <= dd);

// bool maybe_across_chain = write_de && (dd == unpinDepth) && (dd == sd);


/* SAM_NOTE: TODO: track bytes allocated here in
* thread->bytesAllocatedSinceLast...? */
}

// void Assignable_updateBarrier (GC_state s, objptr dst, objptr* field, objptr src) {
// Assignable_writeBarrier(s, dst, field, src, false);
// // *field = src;
// }
// void Assignable_casBarrier (objptr dst, objptr* field, objptr src) {
// GC_state s = pthread_getspecific(gcstate_key);
// Assignable_writeBarrier(s, dst, field, src);
// // cas(field, (*field), dst); //return?
// }




0 comments on commit 5023c0e

Please sign in to comment.