aboutsummaryrefslogtreecommitdiff
path: root/src/pkg
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2012-12-22 16:42:22 -0500
committerRuss Cox <rsc@golang.org>2012-12-22 16:42:22 -0500
commitec59b840f93fff4631b60323e28a44967c704e7d (patch)
tree50868a2cf17c483f8fa7f68d01a70e699bfcd91f /src/pkg
parent295a4d8e6433e8a8b6df25375fb780b0f75ff4e6 (diff)
downloadgo-ec59b840f93fff4631b60323e28a44967c704e7d.tar.xz
runtime: coalesce 0-size allocations
Fixes #3996. R=ken2 CC=golang-dev https://golang.org/cl/7001052
Diffstat (limited to 'src/pkg')
-rw-r--r--src/pkg/runtime/malloc.goc41
1 files changed, 29 insertions, 12 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
index f58045e63e..e37f8927ba 100644
--- a/src/pkg/runtime/malloc.goc
+++ b/src/pkg/runtime/malloc.goc
@@ -697,14 +697,22 @@ runtime·new(Type *typ, uint8 *ret)
if(raceenabled)
m->racepc = runtime·getcallerpc(&typ);
- flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
- ret = runtime·mallocgc(typ->size, flag, 1, 1);
- if(UseSpanType && !flag) {
- if(false) {
- runtime·printf("new %S: %p\n", *typ->string, ret);
+ if(typ->size == 0) {
+ // All 0-length allocations use this pointer.
+ // The language does not require the allocations to
+ // have distinct values.
+ ret = (uint8*)&runtime·zerobase;
+ } else {
+ flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
+ ret = runtime·mallocgc(typ->size, flag, 1, 1);
+
+ if(UseSpanType && !flag) {
+ if(false) {
+ runtime·printf("new %S: %p\n", *typ->string, ret);
+ }
+ runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
}
- runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
}
FLUSH(&ret);
@@ -719,15 +727,24 @@ runtime·cnew(Type *typ)
if(raceenabled)
m->racepc = runtime·getcallerpc(&typ);
- flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
- ret = runtime·mallocgc(typ->size, flag, 1, 1);
- if(UseSpanType && !flag) {
- if(false) {
- runtime·printf("new %S: %p\n", *typ->string, ret);
+ if(typ->size == 0) {
+ // All 0-length allocations use this pointer.
+ // The language does not require the allocations to
+ // have distinct values.
+ ret = (uint8*)&runtime·zerobase;
+ } else {
+ flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
+ ret = runtime·mallocgc(typ->size, flag, 1, 1);
+
+ if(UseSpanType && !flag) {
+ if(false) {
+ runtime·printf("new %S: %p\n", *typ->string, ret);
+ }
+ runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
}
- runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
}
+
return ret;
}