1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
7 // #cgo noescape annotations for a C function means its arguments won't escape to heap.
9 // We assume that there won't be 100 new allocated heap objects in other places,
10 // i.e. runtime.ReadMemStats or other runtime background works.
12 // 1. at least 100 new allocated heap objects after invoking withoutNoEscape 100 times.
13 // 2. less than 100 new allocated heap objects after invoking withoutNoEscape 100 times.
16 #cgo noescape runCWithNoEscape
18 void runCWithNoEscape(void *p) {
20 void runCWithoutNoEscape(void *p) {
35 register("CgoNoEscape", CgoNoEscape)
41 C.runCWithNoEscape(unsafe.Pointer(&str))
45 func withoutNoEscape() {
47 C.runCWithoutNoEscape(unsafe.Pointer(&str))
51 // make GC stop to see the heap objects allocated
52 debug.SetGCPercent(-1)
54 var stats runtime.MemStats
55 runtime.ReadMemStats(&stats)
56 preHeapObjects := stats.HeapObjects
58 for i := 0; i < num; i++ {
62 runtime.ReadMemStats(&stats)
63 nowHeapObjects := stats.HeapObjects
65 if nowHeapObjects-preHeapObjects >= num {
66 fmt.Printf("too many heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects)
69 runtime.ReadMemStats(&stats)
70 preHeapObjects = stats.HeapObjects
72 for i := 0; i < num; i++ {
76 runtime.ReadMemStats(&stats)
77 nowHeapObjects = stats.HeapObjects
79 if nowHeapObjects-preHeapObjects < num {
80 fmt.Printf("too few heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects)