From 364ced625593b7e48a3d4f211634228222ef0ed1 Mon Sep 17 00:00:00 2001 From: David Chase Date: Fri, 13 May 2022 13:16:58 -0400 Subject: [PATCH] runtime: tweak js and plan9 to avoid/disable write barrier & gc problems runtime code for js contains possible write barriers that fail the nowritebarrierrec check when internal local package naming conventions are changed. The problem was there all already; this allows the code to compile, and it seems to work anyway in the (single-threaded) js/wasm environment. The offending operations are noted with TODO, which is an improvement. runtime code for plan9 contained an apparent allocation that was not really an allocation; rewrite to remove the potential allocation to avoid nowritebarrierrec problems. This CL is a prerequisite for a pending code cleanup, https://go-review.googlesource.com/c/go/+/393715 Updates #51734. Change-Id: I93f31831ff9b92632137dd7b0055eaa721c81556 Reviewed-on: https://go-review.googlesource.com/c/go/+/405901 Run-TryBot: David Chase TryBot-Result: Gopher Robot Reviewed-by: Michael Knyszek Reviewed-by: Matthew Dempsky --- src/runtime/lock_js.go | 8 ++++++++ src/runtime/os_js.go | 2 +- src/runtime/os_plan9.go | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/runtime/lock_js.go b/src/runtime/lock_js.go index 80ee50da351..f71e7a2b4a5 100644 --- a/src/runtime/lock_js.go +++ b/src/runtime/lock_js.go @@ -144,8 +144,12 @@ func notetsleepg(n *note, ns int64) bool { } // checkTimeouts resumes goroutines that are waiting on a note which has reached its deadline. +// TODO(drchase): need to understand if write barriers are really okay in this context. +// +//go:yeswritebarrierrec func checkTimeouts() { now := nanotime() + // TODO: map iteration has the write barriers in it; is that okay? for n, nt := range notesWithTimeout { if n.key == note_cleared && now >= nt.deadline { n.key = note_timeout @@ -175,6 +179,9 @@ var idleID int32 // If an event handler returned, we resume it and it will pause the execution. // beforeIdle either returns the specific goroutine to schedule next or // indicates with otherReady that some goroutine became ready. +// TODO(drchase): need to understand if write barriers are really okay in this context. +// +//go:yeswritebarrierrec func beforeIdle(now, pollUntil int64) (gp *g, otherReady bool) { delay := int64(-1) if pollUntil != 0 { @@ -196,6 +203,7 @@ func beforeIdle(now, pollUntil int64) (gp *g, otherReady bool) { } if len(events) == 0 { + // TODO: this is the line that requires the yeswritebarrierrec go handleAsyncEvent() return nil, true } diff --git a/src/runtime/os_js.go b/src/runtime/os_js.go index 7ec1210b73c..34cc0271f05 100644 --- a/src/runtime/os_js.go +++ b/src/runtime/os_js.go @@ -129,7 +129,7 @@ func initsig(preinit bool) { // //go:nowritebarrier func newosproc(mp *m) { - panic("newosproc: not implemented") + throw("newosproc: not implemented") } func setProcessCPUProfiler(hz int32) {} diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go index 1a0c0e9363e..13bc3be4abf 100644 --- a/src/runtime/os_plan9.go +++ b/src/runtime/os_plan9.go @@ -437,7 +437,9 @@ func exit(e int32) { } else { // build error string var tmp [32]byte - status = append(itoa(tmp[:len(tmp)-1], uint64(e)), 0) + sl := itoa(tmp[:len(tmp)-1], uint64(e)) + // Don't append, rely on the existing data being zero. + status = tmp[:len(sl)+1] } goexitsall(&status[0]) exits(&status[0])