mirror of
https://github.com/golang/go
synced 2024-10-03 06:35:29 +00:00
runtime: try to determine the actual type during garbage collection
If the scanned block has no typeinfo the garbage collector will attempt to get the actual type of the block. R=golang-dev, bradfitz, rsc CC=golang-dev https://golang.org/cl/7093045
This commit is contained in:
parent
09cb91eddc
commit
059fed3dfb
|
@ -410,7 +410,7 @@ static void
|
|||
scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
||||
{
|
||||
byte *b, *arena_start, *arena_used;
|
||||
uintptr n, i, end_b, elemsize, ti, objti, count;
|
||||
uintptr n, i, end_b, elemsize, ti, objti, count, type;
|
||||
uintptr *pc, precise_type, nominal_size;
|
||||
void *obj;
|
||||
Type *t;
|
||||
|
@ -463,7 +463,6 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
|||
runtime·printf("scanblock %p %D\n", b, (int64)n);
|
||||
}
|
||||
|
||||
// TODO(atom): to be expanded in a next CL
|
||||
if(ti != 0) {
|
||||
pc = (uintptr*)(ti & ~(uintptr)PC_BITS);
|
||||
precise_type = (ti & PRECISE);
|
||||
|
@ -476,6 +475,37 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
|
|||
} else {
|
||||
stack_top.count = 1;
|
||||
}
|
||||
} else if(UseSpanType) {
|
||||
type = runtime·gettype(b);
|
||||
if(type != 0) {
|
||||
t = (Type*)(type & ~(uintptr)(PtrSize-1));
|
||||
switch(type & (PtrSize-1)) {
|
||||
case TypeInfo_SingleObject:
|
||||
pc = (uintptr*)t->gc;
|
||||
precise_type = true; // type information about 'b' is precise
|
||||
stack_top.count = 1;
|
||||
stack_top.elemsize = pc[0];
|
||||
break;
|
||||
case TypeInfo_Array:
|
||||
pc = (uintptr*)t->gc;
|
||||
if(pc[0] == 0)
|
||||
goto next_block;
|
||||
precise_type = true; // type information about 'b' is precise
|
||||
stack_top.count = 0; // 0 means an infinite number of iterations
|
||||
stack_top.elemsize = pc[0];
|
||||
stack_top.loop_or_ret = pc+1;
|
||||
break;
|
||||
case TypeInfo_Map:
|
||||
// TODO(atom): to be expanded in a next CL
|
||||
pc = defaultProg;
|
||||
break;
|
||||
default:
|
||||
runtime·throw("scanblock: invalid type");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pc = defaultProg;
|
||||
}
|
||||
} else {
|
||||
pc = defaultProg;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue