]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.1] runtime: introduce cnewarray() to simplify allocation of typed...
authorAndrew Gerrand <adg@golang.org>
Tue, 4 Jun 2013 02:54:13 +0000 (12:54 +1000)
committerAndrew Gerrand <adg@golang.org>
Tue, 4 Jun 2013 02:54:13 +0000 (12:54 +1000)
««« CL 9648044 / 139919984600
runtime: introduce cnewarray() to simplify allocation of typed arrays

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/9648044
»»»

R=dsymonds, dvyukov, dave
CC=golang-dev
https://golang.org/cl/9780050

src/pkg/reflect/all_test.go
src/pkg/runtime/iface.c
src/pkg/runtime/malloc.goc
src/pkg/runtime/malloc.h
src/pkg/runtime/slice.c

index 56cb315ad6d08013cb8017b8432e901de9b777ae..a61f6630849d8a28f951eb9c458bb97081fd805d 100644 (file)
@@ -3032,6 +3032,25 @@ func TestSliceOf(t *testing.T) {
        checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
 }
 
+func TestSliceOverflow(t *testing.T) {
+       // check that MakeSlice panics when size of slice overflows uint
+       const S = 1e6
+       s := uint(S)
+       l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
+       if l*s >= s {
+               t.Fatal("slice size does not overflow")
+       }
+       var x [S]byte
+       st := SliceOf(TypeOf(x))
+       defer func() {
+               err := recover()
+               if err == nil {
+                       t.Fatal("slice overflow does not panic")
+               }
+       }()
+       MakeSlice(st, int(l), int(l))
+}
+
 func TestSliceOfGC(t *testing.T) {
        type T *uintptr
        tt := TypeOf(T(nil))
index 370edffb817e47085b02788c617323b35e66e74e..5973d6d03c5652bc6c42de4d817b55996ad20add 100644 (file)
@@ -687,42 +687,14 @@ reflect·unsafe_Typeof(Eface e, Eface ret)
 void
 reflect·unsafe_New(Type *t, void *ret)
 {
-       uint32 flag;
-
-       flag = t->kind&KindNoPointers ? FlagNoPointers : 0;
-       ret = runtime·mallocgc(t->size, flag, 1, 1);
-
-       if(UseSpanType && !flag) {
-               if(false) {
-                       runtime·printf("unsafe_New %S: %p\n", *t->string, ret);
-               }
-               runtime·settype(ret, (uintptr)t | TypeInfo_SingleObject);
-       }
-
+       ret = runtime·cnew(t);
        FLUSH(&ret);
 }
 
 void
 reflect·unsafe_NewArray(Type *t, intgo n, void *ret)
 {
-       uint64 size;
-
-       size = n*t->size;
-       if(size == 0)
-               ret = (byte*)&runtime·zerobase;
-       else if(t->kind&KindNoPointers)
-               ret = runtime·mallocgc(size, FlagNoPointers, 1, 1);
-       else {
-               ret = runtime·mallocgc(size, 0, 1, 1);
-
-               if(UseSpanType) {
-                       if(false) {
-                               runtime·printf("unsafe_NewArray [%D]%S: %p\n", (int64)n, *t->string, ret);
-                       }
-                       runtime·settype(ret, (uintptr)t | TypeInfo_Array);
-               }
-       }
-
+       ret = runtime·cnewarray(t, n);
        FLUSH(&ret);
 }
 
index f1d25a793f82b67f957a6cca34cbb345ae6276d3..ef755f25cf4b861a7f88d418e4fa2431252bfefc 100644 (file)
@@ -717,9 +717,8 @@ runtime·new(Type *typ, uint8 *ret)
                ret = runtime·mallocgc(typ->size, flag, 1, 1);
 
                if(UseSpanType && !flag) {
-                       if(false) {
+                       if(false)
                                runtime·printf("new %S: %p\n", *typ->string, ret);
-                       }
                        runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
                }
        }
@@ -727,36 +726,45 @@ runtime·new(Type *typ, uint8 *ret)
        FLUSH(&ret);
 }
 
-// same as runtime·new, but callable from C
-void*
-runtime·cnew(Type *typ)
+static void*
+cnew(Type *typ, intgo n, int32 objtyp)
 {
        uint32 flag;
        void *ret;
 
-       if(raceenabled)
-               m->racepc = runtime·getcallerpc(&typ);
-
-       if(typ->size == 0) {
+       if((objtyp&(PtrSize-1)) != objtyp)
+               runtime·throw("runtime: invalid objtyp");
+       if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
+               runtime·panicstring("runtime: allocation size out of range");
+       if(typ->size == 0 || n == 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);
-               }
+               return &runtime·zerobase;
+       }
+       flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
+       ret = runtime·mallocgc(typ->size*n, flag, 1, 1);
+       if(UseSpanType && !flag) {
+               if(false)
+                       runtime·printf("cnew [%D]%S: %p\n", (int64)n, *typ->string, ret);
+               runtime·settype(ret, (uintptr)typ | objtyp);
        }
-
        return ret;
 }
 
+// same as runtime·new, but callable from C
+void*
+runtime·cnew(Type *typ)
+{
+       return cnew(typ, 1, TypeInfo_SingleObject);
+}
+
+void*
+runtime·cnewarray(Type *typ, intgo n)
+{
+       return cnew(typ, n, TypeInfo_Array);
+}
+
 func GC() {
        runtime·gc(1);
 }
index 52b76d5574157309ece8f185043faa3b00b1b406..7bbc1b2b34d108bbb2e067a2bce4fd107d9e7bf7 100644 (file)
@@ -461,6 +461,7 @@ bool        runtime·blockspecial(void*);
 void   runtime·setblockspecial(void*, bool);
 void   runtime·purgecachedstats(MCache*);
 void*  runtime·cnew(Type*);
+void*  runtime·cnewarray(Type*, intgo);
 
 void   runtime·settype(void*, uintptr);
 void   runtime·settype_flush(M*, bool);
index 354c54c865fbe9c91c2419d92a8eecc1a48d3dcd..dd92a59a9d959ae8474c2ac90da7f9d2ca3b5310 100644 (file)
@@ -48,27 +48,9 @@ uintptr runtime·zerobase;
 static void
 makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
 {
-       uintptr size;
-
-       size = cap*t->elem->size;
-
        ret->len = len;
        ret->cap = cap;
-
-       if(size == 0)
-               ret->array = (byte*)&runtime·zerobase;
-       else if((t->elem->kind&KindNoPointers))
-               ret->array = runtime·mallocgc(size, FlagNoPointers, 1, 1);
-       else {
-               ret->array = runtime·mallocgc(size, 0, 1, 1);
-
-               if(UseSpanType) {
-                       if(false) {
-                               runtime·printf("new slice [%D]%S: %p\n", (int64)cap, *t->elem->string, ret->array);
-                       }
-                       runtime·settype(ret->array, (uintptr)t->elem | TypeInfo_Array);
-               }
-       }
+       ret->array = runtime·cnewarray(t->elem, cap);
 }
 
 // appendslice(type *Type, x, y, []T) []T