mirror of
https://github.com/golang/go
synced 2024-11-26 16:16:57 -07:00
runtime: replace lock() with casp() in the GC
Note: BitTarget will be removed by a forthcoming changeset. R=golang-dev, dvyukov CC=golang-dev, rsc https://golang.org/cl/7837044
This commit is contained in:
parent
175c401523
commit
2924638d26
@ -191,7 +191,7 @@ static struct {
|
|||||||
|
|
||||||
// markonly marks an object. It returns true if the object
|
// markonly marks an object. It returns true if the object
|
||||||
// has been marked by this function, false otherwise.
|
// has been marked by this function, false otherwise.
|
||||||
// This function isn't thread-safe and doesn't append the object to any buffer.
|
// This function doesn't append the object to any buffer.
|
||||||
static bool
|
static bool
|
||||||
markonly(void *obj)
|
markonly(void *obj)
|
||||||
{
|
{
|
||||||
@ -254,7 +254,17 @@ found:
|
|||||||
// Only care about allocated and not marked.
|
// Only care about allocated and not marked.
|
||||||
if((bits & (bitAllocated|bitMarked)) != bitAllocated)
|
if((bits & (bitAllocated|bitMarked)) != bitAllocated)
|
||||||
return false;
|
return false;
|
||||||
*bitp |= bitMarked<<shift;
|
if(work.nproc == 1)
|
||||||
|
*bitp |= bitMarked<<shift;
|
||||||
|
else {
|
||||||
|
for(;;) {
|
||||||
|
x = *bitp;
|
||||||
|
if(x & (bitMarked<<shift))
|
||||||
|
return false;
|
||||||
|
if(runtime·casp((void**)bitp, (void*)x, (void*)(x|(bitMarked<<shift))))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The object is now marked
|
// The object is now marked
|
||||||
return true;
|
return true;
|
||||||
@ -325,7 +335,6 @@ flushptrbuf(PtrTarget *ptrbuf, PtrTarget **ptrbufpos, Obj **_wp, Workbuf **_wbuf
|
|||||||
Obj *wp;
|
Obj *wp;
|
||||||
Workbuf *wbuf;
|
Workbuf *wbuf;
|
||||||
PtrTarget *ptrbuf_end;
|
PtrTarget *ptrbuf_end;
|
||||||
BitTarget *bitbufpos, *bt;
|
|
||||||
|
|
||||||
arena_start = runtime·mheap->arena_start;
|
arena_start = runtime·mheap->arena_start;
|
||||||
|
|
||||||
@ -359,8 +368,6 @@ flushptrbuf(PtrTarget *ptrbuf, PtrTarget **ptrbufpos, Obj **_wp, Workbuf **_wbuf
|
|||||||
{
|
{
|
||||||
// Multi-threaded version.
|
// Multi-threaded version.
|
||||||
|
|
||||||
bitbufpos = bitbuf;
|
|
||||||
|
|
||||||
while(ptrbuf < ptrbuf_end) {
|
while(ptrbuf < ptrbuf_end) {
|
||||||
obj = ptrbuf->p;
|
obj = ptrbuf->p;
|
||||||
ti = ptrbuf->ti;
|
ti = ptrbuf->ti;
|
||||||
@ -438,26 +445,22 @@ flushptrbuf(PtrTarget *ptrbuf, PtrTarget **ptrbufpos, Obj **_wp, Workbuf **_wbuf
|
|||||||
// Only care about allocated and not marked.
|
// Only care about allocated and not marked.
|
||||||
if((bits & (bitAllocated|bitMarked)) != bitAllocated)
|
if((bits & (bitAllocated|bitMarked)) != bitAllocated)
|
||||||
continue;
|
continue;
|
||||||
|
if(work.nproc == 1)
|
||||||
*bitbufpos++ = (BitTarget){obj, ti, bitp, shift};
|
*bitp |= bitMarked<<shift;
|
||||||
}
|
else {
|
||||||
|
for(;;) {
|
||||||
runtime·lock(&lock);
|
x = *bitp;
|
||||||
for(bt=bitbuf; bt<bitbufpos; bt++){
|
if(x & (bitMarked<<shift))
|
||||||
xbits = *bt->bitp;
|
goto continue_obj;
|
||||||
bits = xbits >> bt->shift;
|
if(runtime·casp((void**)bitp, (void*)x, (void*)(x|(bitMarked<<shift))))
|
||||||
if((bits & bitMarked) != 0)
|
break;
|
||||||
continue;
|
}
|
||||||
|
}
|
||||||
// Mark the block
|
|
||||||
*bt->bitp = xbits | (bitMarked << bt->shift);
|
|
||||||
|
|
||||||
// If object has no pointers, don't need to scan further.
|
// If object has no pointers, don't need to scan further.
|
||||||
if((bits & bitNoPointers) != 0)
|
if((bits & bitNoPointers) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
obj = bt->p;
|
|
||||||
|
|
||||||
// Ask span about size class.
|
// Ask span about size class.
|
||||||
// (Manually inlined copy of MHeap_Lookup.)
|
// (Manually inlined copy of MHeap_Lookup.)
|
||||||
x = (uintptr)obj >> PageShift;
|
x = (uintptr)obj >> PageShift;
|
||||||
@ -467,11 +470,11 @@ flushptrbuf(PtrTarget *ptrbuf, PtrTarget **ptrbufpos, Obj **_wp, Workbuf **_wbuf
|
|||||||
|
|
||||||
PREFETCH(obj);
|
PREFETCH(obj);
|
||||||
|
|
||||||
*wp = (Obj){obj, s->elemsize, bt->ti};
|
*wp = (Obj){obj, s->elemsize, ti};
|
||||||
wp++;
|
wp++;
|
||||||
nobj++;
|
nobj++;
|
||||||
|
continue_obj:;
|
||||||
}
|
}
|
||||||
runtime·unlock(&lock);
|
|
||||||
|
|
||||||
// If another proc wants a pointer, give it some.
|
// If another proc wants a pointer, give it some.
|
||||||
if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
|
if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
|
||||||
@ -588,7 +591,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
|||||||
Iface *iface;
|
Iface *iface;
|
||||||
Hmap *hmap;
|
Hmap *hmap;
|
||||||
MapType *maptype;
|
MapType *maptype;
|
||||||
bool didmark, mapkey_kind, mapval_kind;
|
bool mapkey_kind, mapval_kind;
|
||||||
struct hash_gciter map_iter;
|
struct hash_gciter map_iter;
|
||||||
struct hash_gciter_data d;
|
struct hash_gciter_data d;
|
||||||
Hchan *chan;
|
Hchan *chan;
|
||||||
@ -894,10 +897,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
|||||||
pc += 3;
|
pc += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
runtime·lock(&lock);
|
if(markonly(hmap)) {
|
||||||
didmark = markonly(hmap);
|
|
||||||
runtime·unlock(&lock);
|
|
||||||
if(didmark) {
|
|
||||||
maptype = (MapType*)pc[2];
|
maptype = (MapType*)pc[2];
|
||||||
if(hash_gciter_init(hmap, &map_iter)) {
|
if(hash_gciter_init(hmap, &map_iter)) {
|
||||||
mapkey_size = maptype->key->size;
|
mapkey_size = maptype->key->size;
|
||||||
@ -927,11 +927,9 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
|||||||
if(objbufpos+2 >= objbuf_end)
|
if(objbufpos+2 >= objbuf_end)
|
||||||
flushobjbuf(objbuf, &objbufpos, &wp, &wbuf, &nobj);
|
flushobjbuf(objbuf, &objbufpos, &wp, &wbuf, &nobj);
|
||||||
|
|
||||||
if(d.st != nil) {
|
if(d.st != nil)
|
||||||
runtime·lock(&lock);
|
|
||||||
markonly(d.st);
|
markonly(d.st);
|
||||||
runtime·unlock(&lock);
|
|
||||||
}
|
|
||||||
if(d.key_data != nil) {
|
if(d.key_data != nil) {
|
||||||
if(!(mapkey_kind & KindNoPointers) || d.indirectkey) {
|
if(!(mapkey_kind & KindNoPointers) || d.indirectkey) {
|
||||||
if(!d.indirectkey)
|
if(!d.indirectkey)
|
||||||
|
Loading…
Reference in New Issue
Block a user