Commit 059fed3d authored by Jan Ziak's avatar Jan Ziak Committed by Russ Cox

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
parent 09cb91ed
...@@ -410,7 +410,7 @@ static void ...@@ -410,7 +410,7 @@ static void
scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking) scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
{ {
byte *b, *arena_start, *arena_used; 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; uintptr *pc, precise_type, nominal_size;
void *obj; void *obj;
Type *t; Type *t;
...@@ -463,7 +463,6 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking) ...@@ -463,7 +463,6 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
runtime·printf("scanblock %p %D\n", b, (int64)n); runtime·printf("scanblock %p %D\n", b, (int64)n);
} }
// TODO(atom): to be expanded in a next CL
if(ti != 0) { if(ti != 0) {
pc = (uintptr*)(ti & ~(uintptr)PC_BITS); pc = (uintptr*)(ti & ~(uintptr)PC_BITS);
precise_type = (ti & PRECISE); precise_type = (ti & PRECISE);
...@@ -476,6 +475,37 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking) ...@@ -476,6 +475,37 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
} else { } else {
stack_top.count = 1; 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 { } else {
pc = defaultProg; pc = defaultProg;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment