Browse Source

Add -gc=custom option (#3302)

* Add -gc=custom option
pull/3418/head
Anuraag Agrawal 2 years ago
committed by GitHub
parent
commit
eebd2f648b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      compileopts/config.go
  2. 2
      compileopts/options.go
  3. 8
      compileopts/options_test.go
  4. 2
      src/internal/task/gc_stack_chain.go
  5. 2
      src/internal/task/gc_stack_noop.go
  6. 55
      src/runtime/gc_custom.go
  7. 2
      src/runtime/gc_stack_portable.go

2
compileopts/config.go

@ -105,7 +105,7 @@ func (c *Config) GC() string {
// that can be traced by the garbage collector. // that can be traced by the garbage collector.
func (c *Config) NeedsStackObjects() bool { func (c *Config) NeedsStackObjects() bool {
switch c.GC() { switch c.GC() {
case "conservative", "precise": case "conservative", "custom", "precise":
for _, tag := range c.BuildTags() { for _, tag := range c.BuildTags() {
if tag == "tinygo.wasm" { if tag == "tinygo.wasm" {
return true return true

2
compileopts/options.go

@ -8,7 +8,7 @@ import (
) )
var ( var (
validGCOptions = []string{"none", "leaking", "conservative", "precise"} validGCOptions = []string{"none", "leaking", "conservative", "custom", "precise"}
validSchedulerOptions = []string{"none", "tasks", "asyncify"} validSchedulerOptions = []string{"none", "tasks", "asyncify"}
validSerialOptions = []string{"none", "uart", "usb"} validSerialOptions = []string{"none", "uart", "usb"}
validPrintSizeOptions = []string{"none", "short", "full"} validPrintSizeOptions = []string{"none", "short", "full"}

8
compileopts/options_test.go

@ -9,7 +9,7 @@ import (
func TestVerifyOptions(t *testing.T) { func TestVerifyOptions(t *testing.T) {
expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, precise`) expectedGCError := errors.New(`invalid gc option 'incorrect': valid values are none, leaking, conservative, custom, precise`)
expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify`) expectedSchedulerError := errors.New(`invalid scheduler option 'incorrect': valid values are none, tasks, asyncify`)
expectedPrintSizeError := errors.New(`invalid size option 'incorrect': valid values are none, short, full`) expectedPrintSizeError := errors.New(`invalid size option 'incorrect': valid values are none, short, full`)
expectedPanicStrategyError := errors.New(`invalid panic option 'incorrect': valid values are print, trap`) expectedPanicStrategyError := errors.New(`invalid panic option 'incorrect': valid values are print, trap`)
@ -48,6 +48,12 @@ func TestVerifyOptions(t *testing.T) {
GC: "conservative", GC: "conservative",
}, },
}, },
{
name: "GCOptionCustom",
opts: compileopts.Options{
GC: "custom",
},
},
{ {
name: "InvalidSchedulerOption", name: "InvalidSchedulerOption",
opts: compileopts.Options{ opts: compileopts.Options{

2
src/internal/task/gc_stack_chain.go

@ -1,4 +1,4 @@
//go:build (gc.conservative || gc.precise) && tinygo.wasm //go:build (gc.conservative || gc.custom || gc.precise) && tinygo.wasm
package task package task

2
src/internal/task/gc_stack_noop.go

@ -1,4 +1,4 @@
//go:build !(gc.conservative || gc.precise) || !tinygo.wasm //go:build !(gc.conservative || gc.custom || gc.precise) || !tinygo.wasm
package task package task

55
src/runtime/gc_custom.go

@ -0,0 +1,55 @@
//go:build gc.custom
// +build gc.custom
package runtime
// This GC strategy allows an external GC to be plugged in instead of the builtin
// implementations.
//
// The interface defined in this file is not stable and can be broken at anytime, even
// across minor versions.
//
// runtime.markStack() must be called at the beginning of any GC cycle. //go:linkname
// on a function without a body can be used to access this internal function.
//
// The custom implementation must provide the following functions in the runtime package
// using the go:linkname directive:
//
// - func initHeap()
// - func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
// - func free(ptr unsafe.Pointer)
// - func markRoots(start, end uintptr)
// - func GC()
//
//
// In addition, if targeting wasi, the following functions should be exported for interoperability
// with wasi libraries that use them. Note, this requires the export directive, not go:linkname.
//
// - func malloc(size uintptr) unsafe.Pointer
// - func free(ptr unsafe.Pointer)
// - func calloc(nmemb, size uintptr) unsafe.Pointer
// - func realloc(oldPtr unsafe.Pointer, size uintptr) unsafe.Pointer
import (
"unsafe"
)
// initHeap is called when the heap is first initialized at program start.
func initHeap()
// alloc is called to allocate memory. layout is currently not used.
func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer
// free is called to explicitly free a previously allocated pointer.
func free(ptr unsafe.Pointer)
// markRoots is called with the start and end addresses to scan for references.
// It is currently only called with the top and bottom of the stack.
func markRoots(start, end uintptr)
// GC is called to explicitly run garbage collection.
func GC()
func setHeapEnd(newHeapEnd uintptr) {
// Heap is in custom GC so ignore for when called from wasm initialization.
}

2
src/runtime/gc_stack_portable.go

@ -1,4 +1,4 @@
//go:build (gc.conservative || gc.precise) && tinygo.wasm //go:build (gc.conservative || gc.custom || gc.precise) && tinygo.wasm
package runtime package runtime

Loading…
Cancel
Save