summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.goc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
-rw-r--r--src/pkg/runtime/malloc.goc50
1 files changed, 32 insertions, 18 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
index 84e0ac479..f1509cd9d 100644
--- a/src/pkg/runtime/malloc.goc
+++ b/src/pkg/runtime/malloc.goc
@@ -8,9 +8,10 @@
package runtime
#include "runtime.h"
+#include "arch_GOARCH.h"
#include "stack.h"
#include "malloc.h"
-#include "defs.h"
+#include "defs_GOOS_GOARCH.h"
#include "type.h"
MHeap runtime·mheap;
@@ -80,11 +81,12 @@ runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
m->mcache->next_sample -= size;
else {
// pick next profile time
+ // If you change this, also change allocmcache.
if(rate > 0x3fffffff) // make 2*rate not overflow
rate = 0x3fffffff;
m->mcache->next_sample = runtime·fastrand1() % (2*rate);
profile:
- runtime·setblockspecial(v);
+ runtime·setblockspecial(v, true);
runtime·MProf_Malloc(v, size);
}
}
@@ -113,7 +115,7 @@ runtime·free(void *v)
if(v == nil)
return;
- // If you change this also change mgc0.c:/^sweepspan,
+ // If you change this also change mgc0.c:/^sweep,
// which has a copy of the guts of free.
if(m->mallocing)
@@ -205,6 +207,7 @@ runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
MCache*
runtime·allocmcache(void)
{
+ int32 rate;
MCache *c;
runtime·lock(&runtime·mheap);
@@ -212,6 +215,14 @@ runtime·allocmcache(void)
mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
mstats.mcache_sys = runtime·mheap.cachealloc.sys;
runtime·unlock(&runtime·mheap);
+
+ // Set first allocation sample size.
+ rate = runtime·MemProfileRate;
+ if(rate > 0x3fffffff) // make 2*rate not overflow
+ rate = 0x3fffffff;
+ if(rate != 0)
+ c->next_sample = runtime·fastrand1() % (2*rate);
+
return c;
}
@@ -383,8 +394,10 @@ runtime·mal(uintptr n)
return runtime·mallocgc(n, 0, 1, 1);
}
-func new(n uint32) (ret *uint8) {
- ret = runtime·mal(n);
+func new(typ *Type) (ret *uint8) {
+ uint32 flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
+ ret = runtime·mallocgc(typ->size, flag, 1, 1);
+ FLUSH(&ret);
}
void*
@@ -448,8 +461,7 @@ func SetFinalizer(obj Eface, finalizer Eface) {
if(obj.type == nil) {
runtime·printf("runtime.SetFinalizer: first argument is nil interface\n");
- throw:
- runtime·throw("runtime.SetFinalizer");
+ goto throw;
}
if(obj.type->kind != KindPtr) {
runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
@@ -461,11 +473,8 @@ func SetFinalizer(obj Eface, finalizer Eface) {
}
nret = 0;
if(finalizer.type != nil) {
- if(finalizer.type->kind != KindFunc) {
- badfunc:
- runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.type->string, *obj.type->string);
- goto throw;
- }
+ if(finalizer.type->kind != KindFunc)
+ goto badfunc;
ft = (FuncType*)finalizer.type;
if(ft->dotdotdot || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
goto badfunc;
@@ -477,11 +486,16 @@ func SetFinalizer(obj Eface, finalizer Eface) {
nret += t->size;
}
nret = (nret + sizeof(void*)-1) & ~(sizeof(void*)-1);
-
- if(runtime·getfinalizer(obj.data, 0)) {
- runtime·printf("runtime.SetFinalizer: finalizer already set\n");
- goto throw;
- }
}
- runtime·addfinalizer(obj.data, finalizer.data, nret);
+
+ if(!runtime·addfinalizer(obj.data, finalizer.data, nret)) {
+ runtime·printf("runtime.SetFinalizer: finalizer already set\n");
+ goto throw;
+ }
+ return;
+
+badfunc:
+ runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.type->string, *obj.type->string);
+throw:
+ runtime·throw("runtime.SetFinalizer");
}