github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/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 // +build js,wasm 7 8 package runtime 9 10 import ( 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 *sysMemStat) 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 *sysMemStat) { 36 sysStat.add(-int64(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 // Round up the initial reserveEnd to 64 KiB so that 56 // reservations are always aligned to the page size. 57 initReserveEnd := alignUp(lastmoduledatap.end, physPageSize) 58 if reserveEnd < initReserveEnd { 59 reserveEnd = initReserveEnd 60 } 61 v = unsafe.Pointer(reserveEnd) 62 reserveEnd += alignUp(n, physPageSize) 63 64 current := currentMemory() 65 // reserveEnd is always at a page boundary. 66 needed := int32(reserveEnd / physPageSize) 67 if current < needed { 68 if growMemory(needed-current) == -1 { 69 return nil 70 } 71 resetMemoryDataView() 72 } 73 74 return v 75 } 76 77 func currentMemory() int32 78 func growMemory(pages int32) int32 79 80 // resetMemoryDataView signals the JS front-end that WebAssembly's memory.grow instruction has been used. 81 // This allows the front-end to replace the old DataView object with a new one. 82 func resetMemoryDataView() 83 84 func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) { 85 sysStat.add(int64(n)) 86 }