Commit d098bffd authored by Daniel Morsing's avatar Daniel Morsing

cmd/gc, runtime: avoid unnecessary copy on type assertion.

When the first result of a type assertion is blank, the compiler would still copy out a potentially large non-interface type.

Fixes #1021.

R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/6812079
parent 433b2f17
...@@ -54,6 +54,8 @@ char *runtimeimport = ...@@ -54,6 +54,8 @@ char *runtimeimport =
"func @\"\".assertI2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" "func @\"\".assertI2I2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
"func @\"\".assertI2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n" "func @\"\".assertI2T(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any)\n"
"func @\"\".assertI2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n" "func @\"\".assertI2T2(@\"\".typ *byte, @\"\".iface any) (@\"\".ret any, @\"\".ok bool)\n"
"func @\"\".assertI2TOK(@\"\".typ *byte, @\"\".iface any) (@\"\".ok bool)\n"
"func @\"\".assertE2TOK(@\"\".typ *byte, @\"\".iface any) (@\"\".ok bool)\n"
"func @\"\".ifaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n" "func @\"\".ifaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
"func @\"\".efaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n" "func @\"\".efaceeq(@\"\".i1 any, @\"\".i2 any) (@\"\".ret bool)\n"
"func @\"\".ifacethash(@\"\".i1 any) (@\"\".ret uint32)\n" "func @\"\".ifacethash(@\"\".i1 any) (@\"\".ret uint32)\n"
......
...@@ -76,6 +76,8 @@ func assertI2I(typ *byte, iface any) (ret any) ...@@ -76,6 +76,8 @@ func assertI2I(typ *byte, iface any) (ret any)
func assertI2I2(typ *byte, iface any) (ret any, ok bool) func assertI2I2(typ *byte, iface any) (ret any, ok bool)
func assertI2T(typ *byte, iface any) (ret any) func assertI2T(typ *byte, iface any) (ret any)
func assertI2T2(typ *byte, iface any) (ret any, ok bool) func assertI2T2(typ *byte, iface any) (ret any, ok bool)
func assertI2TOK(typ *byte, iface any) (ok bool)
func assertE2TOK(typ *byte, iface any) (ok bool)
func ifaceeq(i1 any, i2 any) (ret bool) func ifaceeq(i1 any, i2 any) (ret bool)
func efaceeq(i1 any, i2 any) (ret bool) func efaceeq(i1 any, i2 any) (ret bool)
......
...@@ -686,6 +686,31 @@ walkexpr(Node **np, NodeList **init) ...@@ -686,6 +686,31 @@ walkexpr(Node **np, NodeList **init)
n->ninit = nil; n->ninit = nil;
r = n->rlist->n; r = n->rlist->n;
walkexprlistsafe(n->list, init); walkexprlistsafe(n->list, init);
if(isblank(n->list->n) && !isinter(r->type)) {
strcpy(buf, "assert");
p = buf+strlen(buf);
if(isnilinter(r->left->type))
*p++ = 'E';
else
*p++ = 'I';
*p++ = '2';
*p++ = 'T';
*p++ = 'O';
*p++ = 'K';
*p = '\0';
fn = syslook(buf, 1);
ll = list1(typename(r->type));
ll = list(ll, r->left);
argtype(fn, r->left->type);
n1 = nod(OCALL, fn, N);
n1->list = ll;
n = nod(OAS, n->list->next->n, n1);
typecheck(&n, Etop);
walkexpr(&n, init);
goto ret;
}
r->op = ODOTTYPE2; r->op = ODOTTYPE2;
walkexpr(&r, init); walkexpr(&r, init);
ll = ascompatet(n->op, n->list, &r->type, 0, init); ll = ascompatet(n->op, n->list, &r->type, 0, init);
......
...@@ -278,6 +278,13 @@ runtime·assertI2T2(Type *t, Iface i, ...) ...@@ -278,6 +278,13 @@ runtime·assertI2T2(Type *t, Iface i, ...)
copyout(t, &i.data, ret); copyout(t, &i.data, ret);
} }
void
runtime·assertI2TOK(Type *t, Iface i, bool ok)
{
ok = i.tab!=nil && i.tab->type==t;
FLUSH(&ok);
}
static void assertE2Tret(Type *t, Eface e, byte *ret); static void assertE2Tret(Type *t, Eface e, byte *ret);
// func ifaceE2T(typ *byte, iface any) (ret any) // func ifaceE2T(typ *byte, iface any) (ret any)
...@@ -334,6 +341,13 @@ runtime·assertE2T2(Type *t, Eface e, ...) ...@@ -334,6 +341,13 @@ runtime·assertE2T2(Type *t, Eface e, ...)
copyout(t, &e.data, ret); copyout(t, &e.data, ret);
} }
void
runtime·assertE2TOK(Type *t, Eface e, bool ok)
{
ok = t==e.type;
FLUSH(&ok);
}
// func convI2E(elem any) (ret any) // func convI2E(elem any) (ret any)
void void
runtime·convI2E(Iface i, Eface ret) runtime·convI2E(Iface i, Eface ret)
......
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