summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/malloc.go')
-rw-r--r--src/pkg/runtime/malloc.go56
1 files changed, 54 insertions, 2 deletions
diff --git a/src/pkg/runtime/malloc.go b/src/pkg/runtime/malloc.go
index dbe37c810..883ca0cef 100644
--- a/src/pkg/runtime/malloc.go
+++ b/src/pkg/runtime/malloc.go
@@ -431,7 +431,7 @@ func gogc(force int32) {
mp = acquirem()
mp.gcing = 1
releasem(mp)
- stoptheworld()
+ onM(stoptheworld)
if mp != acquirem() {
gothrow("gogc: rescheduled")
}
@@ -465,7 +465,7 @@ func gogc(force int32) {
// all done
mp.gcing = 0
semrelease(&worldsema)
- starttheworld()
+ onM(starttheworld)
releasem(mp)
mp = nil
@@ -760,3 +760,55 @@ func runfinq() {
}
}
}
+
+var persistent struct {
+ lock mutex
+ pos unsafe.Pointer
+ end unsafe.Pointer
+}
+
+// Wrapper around sysAlloc that can allocate small chunks.
+// There is no associated free operation.
+// Intended for things like function/type/debug-related persistent data.
+// If align is 0, uses default align (currently 8).
+func persistentalloc(size, align uintptr, stat *uint64) unsafe.Pointer {
+ const (
+ chunk = 256 << 10
+ maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
+ )
+
+ if align != 0 {
+ if align&(align-1) != 0 {
+ gothrow("persistentalloc: align is not a power of 2")
+ }
+ if align > _PageSize {
+ gothrow("persistentalloc: align is too large")
+ }
+ } else {
+ align = 8
+ }
+
+ if size >= maxBlock {
+ return sysAlloc(size, stat)
+ }
+
+ lock(&persistent.lock)
+ persistent.pos = roundup(persistent.pos, align)
+ if uintptr(persistent.pos)+size > uintptr(persistent.end) {
+ persistent.pos = sysAlloc(chunk, &memstats.other_sys)
+ if persistent.pos == nil {
+ unlock(&persistent.lock)
+ gothrow("runtime: cannot allocate memory")
+ }
+ persistent.end = add(persistent.pos, chunk)
+ }
+ p := persistent.pos
+ persistent.pos = add(persistent.pos, size)
+ unlock(&persistent.lock)
+
+ if stat != &memstats.other_sys {
+ xadd64(stat, int64(size))
+ xadd64(&memstats.other_sys, -int64(size))
+ }
+ return p
+}