]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: don't generate newobject call for 0-sized types
authorIskander Sharipov <quasilyte@gmail.com>
Fri, 28 Dec 2018 18:40:04 +0000 (21:40 +0300)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 26 Feb 2019 23:08:15 +0000 (23:08 +0000)
Emit &runtime.zerobase instead of a call to newobject for
allocations of zero sized objects in walk.go.

Fixes #29446

Change-Id: I11b67981d55009726a17c2e582c12ce0c258682e
Reviewed-on: https://go-review.googlesource.com/c/155840
Run-TryBot: Iskander Sharipov <quasilyte@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/walk.go
test/codegen/alloc.go [new file with mode: 0644]

index 57bf8a1e0e372aa0128271c715a2eb112d8beb92..1d6321212ef16a4ac56986cbf2cf285d3ca27b3f 100644 (file)
@@ -1940,6 +1940,16 @@ func callnew(t *types.Type) *Node {
                yyerror("%v is go:notinheap; heap allocation disallowed", t)
        }
        dowidth(t)
+
+       if t.Size() == 0 {
+               // Return &runtime.zerobase if we know that the requested size is 0.
+               // This is what runtime.mallocgc would return.
+               z := newname(Runtimepkg.Lookup("zerobase"))
+               z.SetClass(PEXTERN)
+               z.Type = t
+               return typecheck(nod(OADDR, z, nil), ctxExpr)
+       }
+
        fn := syslook("newobject")
        fn = substArgTypes(fn, t)
        v := mkcall1(fn, types.NewPtr(t), nil, typename(t))
diff --git a/test/codegen/alloc.go b/test/codegen/alloc.go
new file mode 100644 (file)
index 0000000..31455fd
--- /dev/null
@@ -0,0 +1,34 @@
+// asmcheck
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// These tests check that allocating a 0-size object does not
+// introduce a call to runtime.newobject.
+
+package codegen
+
+func zeroAllocNew1() *struct{} {
+       // 386:-`CALL\truntime\.newobject`
+       // amd64:-`CALL\truntime\.newobject`
+       // arm:-`CALL\truntime\.newobject`
+       // arm64:-`CALL\truntime\.newobject`
+       return new(struct{})
+}
+
+func zeroAllocNew2() *[0]int {
+       // 386:-`CALL\truntime\.newobject`
+       // amd64:-`CALL\truntime\.newobject`
+       // arm:-`CALL\truntime\.newobject`
+       // arm64:-`CALL\truntime\.newobject`
+       return new([0]int)
+}
+
+func zeroAllocSliceLit() []int {
+       // 386:-`CALL\truntime\.newobject`
+       // amd64:-`CALL\truntime\.newobject`
+       // arm:-`CALL\truntime\.newobject`
+       // arm64:-`CALL\truntime\.newobject`
+       return []int{}
+}