]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: coalesce 0-size allocations
authorRuss Cox <rsc@golang.org>
Sat, 22 Dec 2012 21:42:22 +0000 (16:42 -0500)
committerRuss Cox <rsc@golang.org>
Sat, 22 Dec 2012 21:42:22 +0000 (16:42 -0500)
Fixes #3996.

R=ken2
CC=golang-dev
https://golang.org/cl/7001052

src/pkg/runtime/malloc.goc

index f58045e63e9c63c86225657205be06cd4b60e780..e37f8927ba8ff7c5dcc84ec2ae7fa4447c522117 100644 (file)
@@ -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;
 }