]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: scan the type of an interface value
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Fri, 15 Mar 2013 20:07:52 +0000 (16:07 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 15 Mar 2013 20:07:52 +0000 (16:07 -0400)
R=golang-dev, rsc, bradfitz
CC=golang-dev
https://golang.org/cl/7744047

src/pkg/runtime/mgc0.c

index 5edaec0024957d4ab6e99419c868dc0aeb36da38..5a810c0788b68bbde59eb5abd870cdb821e9ce90 100644 (file)
@@ -754,11 +754,22 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                case GC_EFACE:
                        eface = (Eface*)(stack_top.b + pc[1]);
                        pc += 2;
-                       if(eface->type != nil && (eface->data >= arena_start && eface->data < arena_used)) {
-                               t = eface->type;
+                       if(eface->type == nil)
+                               continue;
+
+                       // eface->type
+                       t = eface->type;
+                       if((void*)t >= arena_start && (void*)t < arena_used) {
+                               *ptrbufpos++ = (PtrTarget){t, 0};
+                               if(ptrbufpos == ptrbuf_end)
+                                       flushptrbuf(ptrbuf, &ptrbufpos, &wp, &wbuf, &nobj);
+                       }
+
+                       // eface->data
+                       if(eface->data >= arena_start && eface->data < arena_used) {
                                if(t->size <= sizeof(void*)) {
                                        if((t->kind & KindNoPointers))
-                                               break;
+                                               continue;
 
                                        obj = eface->data;
                                        if((t->kind & ~KindNoPointers) == KindPtr)
@@ -774,7 +785,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                        iface = (Iface*)(stack_top.b + pc[1]);
                        pc += 2;
                        if(iface->tab == nil)
-                               break;
+                               continue;
                        
                        // iface->tab
                        if((void*)iface->tab >= arena_start && (void*)iface->tab < arena_used) {
@@ -788,7 +799,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                                t = iface->tab->type;
                                if(t->size <= sizeof(void*)) {
                                        if((t->kind & KindNoPointers))
-                                               break;
+                                               continue;
 
                                        obj = iface->data;
                                        if((t->kind & ~KindNoPointers) == KindPtr)
@@ -815,9 +826,8 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                case GC_END:
                        if(--stack_top.count != 0) {
                                // Next iteration of a loop if possible.
-                               elemsize = stack_top.elemsize;
-                               stack_top.b += elemsize;
-                               if(stack_top.b + elemsize <= end_b+PtrSize) {
+                               stack_top.b += stack_top.elemsize;
+                               if(stack_top.b + stack_top.elemsize <= end_b+PtrSize) {
                                        pc = stack_top.loop_or_ret;
                                        continue;
                                }
@@ -945,7 +955,7 @@ scanblock(Workbuf *wbuf, Obj *wp, uintptr nobj, bool keepworking)
                        *objbufpos++ = (Obj){obj, size, objti};
                        if(objbufpos == objbuf_end)
                                flushobjbuf(objbuf, &objbufpos, &wp, &wbuf, &nobj);
-                       break;
+                       continue;
 
                case GC_CHAN:
                        // There are no heap pointers in struct Hchan,