diff options
Diffstat (limited to 'src/pkg/runtime/mem.c')
-rw-r--r-- | src/pkg/runtime/mem.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/pkg/runtime/mem.c b/src/pkg/runtime/mem.c new file mode 100644 index 000000000..7ed299eb0 --- /dev/null +++ b/src/pkg/runtime/mem.c @@ -0,0 +1,75 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "defs.h" + +// Stubs for memory management. +// In a separate file so they can be overridden during testing of gc. + +enum +{ + NHUNK = 20<<20, +}; + +// Convenient wrapper around mmap. +static void* +brk(uint32 n) +{ + byte *v; + + v = sys_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + m->mem.nmmap += n; + return v; +} + +// Allocate n bytes of memory. Note that this gets used +// to allocate new stack segments, so at each call to a function +// you have to ask yourself "would it be okay to call mal recursively +// right here?" The answer is yes unless we're in the middle of +// editing the malloc state in m->mem. +void* +oldmal(uint32 n) +{ + byte* v; + + // round to keep everything 64-bit aligned + n = rnd(n, 8); + + // be careful. calling any function might invoke + // mal to allocate more stack. + if(n > NHUNK) { + v = brk(n); + } else { + // allocate a new hunk if this one is too small + if(n > m->mem.nhunk) { + // here we're in the middle of editing m->mem + // (we're about to overwrite m->mem.hunk), + // so we can't call brk - it might call mal to grow the + // stack, and the recursive call would allocate a new + // hunk, and then once brk returned we'd immediately + // overwrite that hunk with our own. + // (the net result would be a memory leak, not a crash.) + // so we have to call sys_mmap directly - it is written + // in assembly and tagged not to grow the stack. + m->mem.hunk = + sys_mmap(nil, NHUNK, PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_ANON|MAP_PRIVATE, 0, 0); + m->mem.nhunk = NHUNK; + m->mem.nmmap += NHUNK; + } + v = m->mem.hunk; + m->mem.hunk += n; + m->mem.nhunk -= n; + } + m->mem.nmal += n; + return v; +} + +void +sys_mal(uint32 n, uint8 *ret) +{ + ret = mal(n); + FLUSH(&ret); +} |