From 00650007bfcd134c5fe237d43c2180fad1a495c1 Mon Sep 17 00:00:00 2001 From: jinye Date: Mon, 25 Aug 2025 15:25:17 +0800 Subject: [PATCH] reflect:add original init path --- .../goexperiment/exp_prefetchmalloc_off.go | 8 +++++++ .../goexperiment/exp_prefetchmalloc_on.go | 8 +++++++ src/internal/goexperiment/flags.go | 3 +++ src/reflect/type.go | 9 +++---- src/runtime/export_test.go | 9 +++---- src/runtime/malloc.go | 5 +++- src/runtime/mgcpacer_test.go | 24 +++++++++++++++++-- 7 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 src/internal/goexperiment/exp_prefetchmalloc_off.go create mode 100644 src/internal/goexperiment/exp_prefetchmalloc_on.go diff --git a/src/internal/goexperiment/exp_prefetchmalloc_off.go b/src/internal/goexperiment/exp_prefetchmalloc_off.go new file mode 100644 index 000000000..86c815872 --- /dev/null +++ b/src/internal/goexperiment/exp_prefetchmalloc_off.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build !goexperiment.prefetchmalloc + +package goexperiment + +const PrefetchMalloc = false +const PrefetchMallocInt = 0 \ No newline at end of file diff --git a/src/internal/goexperiment/exp_prefetchmalloc_on.go b/src/internal/goexperiment/exp_prefetchmalloc_on.go new file mode 100644 index 000000000..21ac1c6a2 --- /dev/null +++ b/src/internal/goexperiment/exp_prefetchmalloc_on.go @@ -0,0 +1,8 @@ +// Code generated by mkconsts.go. DO NOT EDIT. + +//go:build goexperiment.prefetchmalloc + +package goexperiment + +const PrefetchMalloc = true +const PrefetchMallocInt = 1 \ No newline at end of file diff --git a/src/internal/goexperiment/flags.go b/src/internal/goexperiment/flags.go index ae3cbaf89..1524ffcc1 100644 --- a/src/internal/goexperiment/flags.go +++ b/src/internal/goexperiment/flags.go @@ -109,4 +109,7 @@ type Flags struct { // CacheProg adds support to cmd/go to use a child process to implement // the build cache; see https://github.com/golang/go/issues/59719. CacheProg bool + + // Kunpeng malloc prefetch optimization. + PrefetchMalloc bool } diff --git a/src/reflect/type.go b/src/reflect/type.go index b943352d3..4bbae367f 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -1714,17 +1714,18 @@ func MapOf(key, elem Type) Type { } var funcTypes []Type -var funcTypesMutex sync.RWMutex +var funcTypesMutex sync.Mutex +var funcTypesRWMutex sync.RWMutex var kpAtomicOpt bool func initFuncTypes(n int) Type { if kpAtomicOpt { - funcTypesMutex.RLock() + funcTypesRWMutex.RLock() if n < len(funcTypes) && funcTypes[n] != nil { - defer funcTypesMutex.RUnlock() + defer funcTypesRWMutex.RUnlock() return funcTypes[n] } - funcTypesMutex.RUnlock() + funcTypesRWMutex.RUnlock() } funcTypesMutex.Lock() defer funcTypesMutex.Unlock() diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index f7ce5033f..48cb99195 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -1439,25 +1439,26 @@ func GCTestPointerClass(p unsafe.Pointer) string { const Raceenabled = raceenabled const ( - GCBackgroundUtilization = gcBackgroundUtilization - GCGoalUtilization = gcGoalUtilization DefaultHeapMinimum = defaultHeapMinimum MemoryLimitHeapGoalHeadroomPercent = memoryLimitHeapGoalHeadroomPercent MemoryLimitMinHeapGoalHeadroom = memoryLimitMinHeapGoalHeadroom ) +var GCBackgroundUtilization = gcController.gcRatio +var GCGoalUtilization = gcGoalUtilization + type GCController struct { gcControllerState } -func NewGCController(gcPercent int, memoryLimit int64) *GCController { +func NewGCController(gcPercent int, memoryLimit int64, gcRatio float64) *GCController { // Force the controller to escape. We're going to // do 64-bit atomics on it, and if it gets stack-allocated // on a 32-bit architecture, it may get allocated unaligned // space. g := Escape(new(GCController)) g.gcControllerState.test = true // Mark it as a test copy. - g.init(int32(gcPercent), memoryLimit) + g.init(int32(gcPercent), memoryLimit, gcRatio) return g } diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 7b44e2372..e0d3151e7 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -102,6 +102,7 @@ package runtime import ( "internal/goarch" + "internal/goexperiment" "internal/goos" "runtime/internal/atomic" "runtime/internal/math" @@ -1259,7 +1260,9 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer { x = add(x, size-dataSize) } - sys.Prefetch(uintptr(unsafe.Add(x, size))) + if goexperiment.PrefetchMalloc { + sys.Prefetch(uintptr(unsafe.Add(x, size))) + } return x } diff --git a/src/runtime/mgcpacer_test.go b/src/runtime/mgcpacer_test.go index ef1483d62..32d4943c4 100644 --- a/src/runtime/mgcpacer_test.go +++ b/src/runtime/mgcpacer_test.go @@ -24,6 +24,7 @@ func TestGcPacer(t *testing.T) { name: "Steady", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -49,6 +50,7 @@ func TestGcPacer(t *testing.T) { name: "SteadyBigStacks", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(132.0), @@ -77,6 +79,7 @@ func TestGcPacer(t *testing.T) { name: "SteadyBigGlobals", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 128 << 20, nCores: 8, allocRate: constant(132.0), @@ -105,6 +108,7 @@ func TestGcPacer(t *testing.T) { name: "StepAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0).sum(ramp(66.0, 1).delay(50)), @@ -128,6 +132,7 @@ func TestGcPacer(t *testing.T) { name: "HeavyStepAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33).sum(ramp(330, 1).delay(50)), @@ -151,6 +156,7 @@ func TestGcPacer(t *testing.T) { name: "StepScannableFrac", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(128.0), @@ -176,6 +182,7 @@ func TestGcPacer(t *testing.T) { name: "HighGOGC", gcPercent: 1500, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: random(7, 0x53).offset(165), @@ -217,6 +224,7 @@ func TestGcPacer(t *testing.T) { name: "OscAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: oscillate(13, 0, 8).offset(67), @@ -241,6 +249,7 @@ func TestGcPacer(t *testing.T) { name: "JitterAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: random(13, 0xf).offset(132), @@ -266,6 +275,7 @@ func TestGcPacer(t *testing.T) { name: "HeavyJitterAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: random(33.0, 0x0).offset(330), @@ -295,6 +305,7 @@ func TestGcPacer(t *testing.T) { name: "SmallHeapSlowAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(1.0), @@ -332,6 +343,7 @@ func TestGcPacer(t *testing.T) { name: "MediumHeapSlowAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(1.0), @@ -369,6 +381,7 @@ func TestGcPacer(t *testing.T) { name: "LargeHeapSlowAlloc", gcPercent: 100, memoryLimit: math.MaxInt64, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(1.0), @@ -407,6 +420,7 @@ func TestGcPacer(t *testing.T) { name: "SteadyMemoryLimit", gcPercent: 100, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -436,6 +450,7 @@ func TestGcPacer(t *testing.T) { name: "SteadyMemoryLimitNoGCPercent", gcPercent: -1, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -465,6 +480,7 @@ func TestGcPacer(t *testing.T) { name: "ExceedMemoryLimit", gcPercent: 100, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -499,6 +515,7 @@ func TestGcPacer(t *testing.T) { name: "ExceedMemoryLimitNoGCPercent", gcPercent: -1, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -538,6 +555,7 @@ func TestGcPacer(t *testing.T) { name: "MaintainMemoryLimit", gcPercent: 100, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -571,6 +589,7 @@ func TestGcPacer(t *testing.T) { name: "MaintainMemoryLimitNoGCPercent", gcPercent: -1, memoryLimit: 512 << 20, + gcRatio: 0.25, globalsBytes: 32 << 10, nCores: 8, allocRate: constant(33.0), @@ -607,7 +626,7 @@ func TestGcPacer(t *testing.T) { t.Run(e.name, func(t *testing.T) { t.Parallel() - c := NewGCController(e.gcPercent, e.memoryLimit) + c := NewGCController(e.gcPercent, e.memoryLimit, e.gcRatio) var bytesAllocatedBlackLast int64 results := make([]gcCycleResult, 0, e.length) for i := 0; i < e.length; i++ { @@ -762,6 +781,7 @@ type gcExecTest struct { gcPercent int memoryLimit int64 + gcRatio float64 globalsBytes uint64 nCores int @@ -1034,7 +1054,7 @@ func applyMemoryLimitHeapGoalHeadroom(goal uint64) uint64 { func TestIdleMarkWorkerCount(t *testing.T) { const workers = 10 - c := NewGCController(100, math.MaxInt64) + c := NewGCController(100, math.MaxInt64, 0.25) c.SetMaxIdleMarkWorkers(workers) for i := 0; i < workers; i++ { if !c.NeedIdleMarkWorker() { -- Gitee