all: make WebAssembly initial linear memory size configurable
When the target supports it, allow the (initial) heap size to be configured. Currently only supported in WebAssembly. This also changes the default heap size of WebAssembly from 64kB to 1MB.
Этот коммит содержится в:
родитель
152caa3b0a
коммит
d627208c48
2 изменённых файлов: 44 добавлений и 2 удалений
41
main.go
41
main.go
|
@ -55,6 +55,7 @@ type BuildConfig struct {
|
|||
ldFlags []string
|
||||
tags string
|
||||
wasmAbi string
|
||||
heapSize int64
|
||||
testConfig compiler.TestConfig
|
||||
}
|
||||
|
||||
|
@ -240,10 +241,16 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
|
|||
// Prepare link command.
|
||||
executable := filepath.Join(dir, "main")
|
||||
tmppath := executable // final file
|
||||
ldflags := append(ldflags, "-o", executable, objfile, "-L", root)
|
||||
ldflags = append(ldflags, "-o", executable, objfile, "-L", root)
|
||||
if spec.RTLib == "compiler-rt" {
|
||||
ldflags = append(ldflags, librt)
|
||||
}
|
||||
if spec.GOARCH == "wasm" {
|
||||
// Round heap size to next multiple of 65536 (the WebAssembly page
|
||||
// size).
|
||||
heapSize := (config.heapSize + (65536 - 1)) &^ (65536 - 1)
|
||||
ldflags = append(ldflags, "--initial-memory="+strconv.FormatInt(heapSize, 10))
|
||||
}
|
||||
|
||||
// Compile extra files.
|
||||
for i, path := range spec.ExtraFiles {
|
||||
|
@ -540,6 +547,30 @@ func Run(pkgName, target string, config *BuildConfig) error {
|
|||
})
|
||||
}
|
||||
|
||||
// parseSize converts a human-readable size (with k/m/g suffix) into a plain
|
||||
// number.
|
||||
func parseSize(s string) (int64, error) {
|
||||
s = strings.ToLower(strings.TrimSpace(s))
|
||||
if len(s) == 0 {
|
||||
return 0, errors.New("no size provided")
|
||||
}
|
||||
multiply := int64(1)
|
||||
switch s[len(s)-1] {
|
||||
case 'k':
|
||||
multiply = 1 << 10
|
||||
case 'm':
|
||||
multiply = 1 << 20
|
||||
case 'g':
|
||||
multiply = 1 << 30
|
||||
}
|
||||
if multiply != 1 {
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
n, err := strconv.ParseInt(s, 0, 64)
|
||||
n *= multiply
|
||||
return n, err
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintln(os.Stderr, "TinyGo is a Go compiler for small places.")
|
||||
fmt.Fprintln(os.Stderr, "version:", version)
|
||||
|
@ -598,6 +629,7 @@ func main() {
|
|||
cFlags := flag.String("cflags", "", "additional cflags for compiler")
|
||||
ldFlags := flag.String("ldflags", "", "additional ldflags for linker")
|
||||
wasmAbi := flag.String("wasm-abi", "js", "WebAssembly ABI conventions: js (no i64 params) or generic")
|
||||
heapSize := flag.String("heap-size", "1M", "default heap size in bytes (only supported by WebAssembly)")
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintln(os.Stderr, "No command-line arguments supplied.")
|
||||
|
@ -633,6 +665,13 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
var err error
|
||||
if config.heapSize, err = parseSize(*heapSize); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Could not read heap size:", *heapSize)
|
||||
usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Setenv("CC", "clang -target="+*target)
|
||||
|
||||
switch command {
|
||||
|
|
|
@ -14,9 +14,12 @@ const TargetBits = 32
|
|||
//go:extern __heap_base
|
||||
var heapStartSymbol unsafe.Pointer
|
||||
|
||||
//go:export llvm.wasm.memory.size.i32
|
||||
func wasm_memory_size(index int32) int32
|
||||
|
||||
var (
|
||||
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
|
||||
heapEnd = (heapStart + wasmPageSize - 1) &^ (wasmPageSize - 1) // conservative guess: one page of heap memory
|
||||
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
|
||||
)
|
||||
|
||||
const wasmPageSize = 64 * 1024
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче