...

Source file src/pkg/runtime/mem_js.go

     1	// Copyright 2018 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	// +build js,wasm
     6	
     7	package runtime
     8	
     9	import (
    10		"runtime/internal/sys"
    11		"unsafe"
    12	)
    13	
    14	// Don't split the stack as this function may be invoked without a valid G,
    15	// which prevents us from allocating more stack.
    16	//go:nosplit
    17	func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
    18		p := sysReserve(nil, n)
    19		sysMap(p, n, sysStat)
    20		return p
    21	}
    22	
    23	func sysUnused(v unsafe.Pointer, n uintptr) {
    24	}
    25	
    26	func sysUsed(v unsafe.Pointer, n uintptr) {
    27	}
    28	
    29	func sysHugePage(v unsafe.Pointer, n uintptr) {
    30	}
    31	
    32	// Don't split the stack as this function may be invoked without a valid G,
    33	// which prevents us from allocating more stack.
    34	//go:nosplit
    35	func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) {
    36		mSysStatDec(sysStat, n)
    37	}
    38	
    39	func sysFault(v unsafe.Pointer, n uintptr) {
    40	}
    41	
    42	var reserveEnd uintptr
    43	
    44	func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
    45		// TODO(neelance): maybe unify with mem_plan9.go, depending on how https://github.com/WebAssembly/design/blob/master/FutureFeatures.md#finer-grained-control-over-memory turns out
    46	
    47		if v != nil {
    48			// The address space of WebAssembly's linear memory is contiguous,
    49			// so requesting specific addresses is not supported. We could use
    50			// a different address, but then mheap.sysAlloc discards the result
    51			// right away and we don't reuse chunks passed to sysFree.
    52			return nil
    53		}
    54	
    55		if reserveEnd < lastmoduledatap.end {
    56			reserveEnd = lastmoduledatap.end
    57		}
    58		v = unsafe.Pointer(reserveEnd)
    59		reserveEnd += n
    60	
    61		current := currentMemory()
    62		needed := int32(reserveEnd/sys.DefaultPhysPageSize + 1)
    63		if current < needed {
    64			if growMemory(needed-current) == -1 {
    65				return nil
    66			}
    67		}
    68	
    69		return v
    70	}
    71	
    72	func currentMemory() int32
    73	func growMemory(pages int32) int32
    74	
    75	func sysMap(v unsafe.Pointer, n uintptr, sysStat *uint64) {
    76		mSysStatInc(sysStat, n)
    77	}
    78	

View as plain text