github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/mem_js.go (about) 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 //go:build js && wasm 6 7 package runtime 8 9 import ( 10 "unsafe" 11 ) 12 13 // Don't split the stack as this function may be invoked without a valid G, 14 // which prevents us from allocating more stack. 15 //go:nosplit 16 func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer { 17 p := sysReserve(nil, n) 18 sysMap(p, n, sysStat) 19 return p 20 } 21 22 func sysUnused(v unsafe.Pointer, n uintptr) { 23 } 24 25 func sysUsed(v unsafe.Pointer, n uintptr) { 26 } 27 28 func sysHugePage(v unsafe.Pointer, n uintptr) { 29 } 30 31 // Don't split the stack as this function may be invoked without a valid G, 32 // which prevents us from allocating more stack. 33 //go:nosplit 34 func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) { 35 sysStat.add(-int64(n)) 36 } 37 38 func sysFault(v unsafe.Pointer, n uintptr) { 39 } 40 41 var reserveEnd uintptr 42 43 func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer { 44 // 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 45 46 if v != nil { 47 // The address space of WebAssembly's linear memory is contiguous, 48 // so requesting specific addresses is not supported. We could use 49 // a different address, but then mheap.sysAlloc discards the result 50 // right away and we don't reuse chunks passed to sysFree. 51 return nil 52 } 53 54 // Round up the initial reserveEnd to 64 KiB so that 55 // reservations are always aligned to the page size. 56 initReserveEnd := alignUp(lastmoduledatap.end, physPageSize) 57 if reserveEnd < initReserveEnd { 58 reserveEnd = initReserveEnd 59 } 60 v = unsafe.Pointer(reserveEnd) 61 reserveEnd += alignUp(n, physPageSize) 62 63 current := currentMemory() 64 // reserveEnd is always at a page boundary. 65 needed := int32(reserveEnd / physPageSize) 66 if current < needed { 67 if growMemory(needed-current) == -1 { 68 return nil 69 } 70 resetMemoryDataView() 71 } 72 73 return v 74 } 75 76 func currentMemory() int32 77 func growMemory(pages int32) int32 78 79 // resetMemoryDataView signals the JS front-end that WebAssembly's memory.grow instruction has been used. 80 // This allows the front-end to replace the old DataView object with a new one. 81 func resetMemoryDataView() 82 83 func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) { 84 sysStat.add(int64(n)) 85 }