]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: record argument size for all indirect function calls
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 31 Jul 2013 16:00:33 +0000 (20:00 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 31 Jul 2013 16:00:33 +0000 (20:00 +0400)
This is required to properly unwind reflect.methodValueCall/makeFuncStub.
Fixes #5954.
Stats for 'go install std':
61849 total INSTCALL
24655 currently have ArgSize metadata
27278 have ArgSize metadata with this change
godoc size before: 11351888, after: 11364288

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/12163043

src/cmd/5g/ggen.c
src/cmd/6g/ggen.c
src/cmd/8g/ggen.c
src/pkg/reflect/asm_386.s
src/pkg/reflect/asm_amd64.s
src/pkg/reflect/asm_arm.s
src/pkg/runtime/traceback_arm.c
src/pkg/runtime/traceback_x86.c

index 6e4f564618751152ffe47ce6d94fbff6b886f209..43354724dca80e507ce2b2db17181a4e6a7fdab9 100644 (file)
@@ -81,7 +81,12 @@ ginscall(Node *f, int proc)
                setmaxarg(f->type);
 
        arg = -1;
-       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+       // Most functions have a fixed-size argument block, so traceback uses that during unwind.
+       // Not all, though: there are some variadic functions in package runtime,
+       // and for those we emit call-specific metadata recorded by caller.
+       // Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
+       // so we do this for all indirect calls as well.
+       if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
                arg = f->type->argwid;
                if(proc == 1 || proc == 2)
                        arg += 3*widthptr;
index 7883dad593d07decfc0e824df5881f693b25302b..ec558f2e619b2ebcf7e0761fed291a8ed0ccd4d3 100644 (file)
@@ -79,7 +79,12 @@ ginscall(Node *f, int proc)
                setmaxarg(f->type);
 
        arg = -1;
-       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+       // Most functions have a fixed-size argument block, so traceback uses that during unwind.
+       // Not all, though: there are some variadic functions in package runtime,
+       // and for those we emit call-specific metadata recorded by caller.
+       // Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
+       // so we do this for all indirect calls as well.
+       if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
                arg = f->type->argwid;
                if(proc == 1 || proc == 2)
                        arg += 2*widthptr;
index 5570e128559266f1ad31a088eeda53be048a4d76..1677d9529b39077499bd2c5910aa8d73fe1d1022 100644 (file)
@@ -123,7 +123,12 @@ ginscall(Node *f, int proc)
                setmaxarg(f->type);
 
        arg = -1;
-       if(f->type != T && ((f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
+       // Most functions have a fixed-size argument block, so traceback uses that during unwind.
+       // Not all, though: there are some variadic functions in package runtime,
+       // and for those we emit call-specific metadata recorded by caller.
+       // Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
+       // so we do this for all indirect calls as well.
+       if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
                arg = f->type->argwid;
                if(proc == 1 || proc == 2)
                        arg += 2*widthptr;
index bbd068d98e46f37eb328ec2b84658230c76015a8..2d5ac0367d220dcebf828f8a58979b94b955adac 100644 (file)
@@ -5,6 +5,7 @@
 // makeFuncStub is the code half of the function returned by MakeFunc.
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·makeFuncStub(SB),7,$8
        MOVL    DX, 0(SP)
        LEAL    argframe+0(FP), CX
@@ -15,6 +16,7 @@ TEXT ·makeFuncStub(SB),7,$8
 // methodValueCall is the code half of the function returned by makeMethodValue.
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·methodValueCall(SB),7,$8
        MOVL    DX, 0(SP)
        LEAL    argframe+0(FP), CX
index 2e7fce55d6f7c9494aca2595fcbcbfe5def05297..7d3aaeba453c1ee17128fb633ae3c1ce1f4b5b6e 100644 (file)
@@ -5,6 +5,7 @@
 // makeFuncStub is the code half of the function returned by MakeFunc.
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·makeFuncStub(SB),7,$16
        MOVQ    DX, 0(SP)
        LEAQ    argframe+0(FP), CX
@@ -15,6 +16,7 @@ TEXT ·makeFuncStub(SB),7,$16
 // methodValueCall is the code half of the function returned by makeMethodValue.
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·methodValueCall(SB),7,$16
        MOVQ    DX, 0(SP)
        LEAQ    argframe+0(FP), CX
index fb1dddebe92bfbb3e8a889e3b88bdd0726affa34..bf10929dc6a2c17648ebecd35cbc70e4b7156bfd 100644 (file)
@@ -5,6 +5,7 @@
 // makeFuncStub is jumped to by the code generated by MakeFunc.
 // See the comment on the declaration of makeFuncStub in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·makeFuncStub(SB),7,$8
        MOVW    R7, 4(R13)
        MOVW    $argframe+0(FP), R1
@@ -15,6 +16,7 @@ TEXT ·makeFuncStub(SB),7,$8
 // methodValueCall is the code half of the function returned by makeMethodValue.
 // See the comment on the declaration of methodValueCall in makefunc.go
 // for more details.
+// No argsize here, gc generates argsize info at call site.
 TEXT ·methodValueCall(SB),7,$8
        MOVW    R7, 4(R13)
        MOVW    $argframe+0(FP), R1
index 563ba28c946602fb1fbca1b309c983b32d744000..4b9692c0767ae3fee29975f82bce7d0f828a3c74 100644 (file)
@@ -102,7 +102,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
                // Most functions have a fixed-size argument block,
                // so we can use metadata about the function f.
                // Not all, though: there are some variadic functions
-               // in package runtime, and for those we use call-specific
+               // in package runtime and reflect, and for those we use call-specific
                // metadata recorded by f's caller.
                if(callback != nil || printing) {
                        frame.argp = (byte*)frame.fp + sizeof(uintptr);
index b88797210e56801297f579229ffa16056f241832..c5197a6e105b703b3260a12ab67dc4ca8750358b 100644 (file)
@@ -118,7 +118,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip,
                // Most functions have a fixed-size argument block,
                // so we can use metadata about the function f.
                // Not all, though: there are some variadic functions
-               // in package runtime, and for those we use call-specific
+               // in package runtime and reflect, and for those we use call-specific
                // metadata recorded by f's caller.
                if(callback != nil || printing) {
                        frame.argp = (byte*)frame.fp;