github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/testdata/testprogcgo/cgonoescape.go (about) 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. 4 5 package main 6 7 // #cgo noescape annotations for a C function means its arguments won't escape to heap. 8 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. 11 // So, the tests are: 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. 14 15 /* 16 // TODO(#56378): #cgo noescape runCWithNoEscape 17 18 void runCWithNoEscape(void *p) { 19 } 20 void runCWithoutNoEscape(void *p) { 21 } 22 */ 23 import "C" 24 25 import ( 26 "fmt" 27 "runtime" 28 "runtime/debug" 29 "unsafe" 30 ) 31 32 const num = 100 33 34 func init() { 35 register("CgoNoEscape", CgoNoEscape) 36 } 37 38 //go:noinline 39 func withNoEscape() { 40 var str string 41 C.runCWithNoEscape(unsafe.Pointer(&str)) 42 } 43 44 //go:noinline 45 func withoutNoEscape() { 46 var str string 47 C.runCWithoutNoEscape(unsafe.Pointer(&str)) 48 } 49 50 func CgoNoEscape() { 51 // make GC stop to see the heap objects allocated 52 debug.SetGCPercent(-1) 53 54 var stats runtime.MemStats 55 runtime.ReadMemStats(&stats) 56 preHeapObjects := stats.HeapObjects 57 58 for i := 0; i < num; i++ { 59 withNoEscape() 60 } 61 62 runtime.ReadMemStats(&stats) 63 nowHeapObjects := stats.HeapObjects 64 65 if nowHeapObjects-preHeapObjects >= num { 66 fmt.Printf("too many heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects) 67 } 68 69 runtime.ReadMemStats(&stats) 70 preHeapObjects = stats.HeapObjects 71 72 for i := 0; i < num; i++ { 73 withoutNoEscape() 74 } 75 76 runtime.ReadMemStats(&stats) 77 nowHeapObjects = stats.HeapObjects 78 79 if nowHeapObjects-preHeapObjects < num { 80 fmt.Printf("too few heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects) 81 } 82 83 fmt.Println("OK") 84 }