From 059fed3dfb6f480598c72ab18fe28b322151ba38 Mon Sep 17 00:00:00 2001 From: Jan Ziak <0xe2.0x9a.0x9b@gmail.com> Date: Fri, 18 Jan 2013 16:56:17 -0500 Subject: [PATCH] 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 --- src/pkg/runtime/mgc0.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index b612e6216a..994bb3f64c 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -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; } -- 2.48.1