8000 [release-branch.go1.1] runtime: introduce cnewarray() to simplify all… · golang/go@0987916 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0987916

Browse files
committed
[release-branch.go1.1] runtime: introduce cnewarray() to simplify allocation of typed arrays
««« 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
1 parent ea3b4c9 commit 0987916

File tree

5 files changed

+52
-70
lines changed

5 files changed

+52
-70
lines changed

src/pkg/reflect/all_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,25 @@ func TestSliceOf(t *testing.T) {
30323032
checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
30333033
}
30343034

3035+
func TestSliceOverflow(t *testing.T) {
3036+
// check that MakeSlice panics when size of slice overflows uint
3037+
const S = 1e6
3038+
s := uint(S)
3039+
l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
3040+
if l*s >= s {
3041+
t.Fatal("slice size does not overflow")
3042+
}
3043+
var x [S]byte
3044+
st := SliceOf(TypeOf(x))
3045+
defer func() {
3046+
err := recover()
3047+
if err == nil {
3048+
t.Fatal("slice overflow does not panic")
3049+
}
3050+
}()
3051+
MakeSlice(st, int(l), int(l))
3052+
}
3053+
30353054
func TestSliceOfGC(t *testing.T) {
30363055
type T *uintptr
30373056
tt := TypeOf(T(nil))

src/pkg/runtime/iface.c

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -687,42 +687,14 @@ reflect·unsafe_Typeof(Eface e, Eface ret)
687687
void
688688
reflect·unsafe_New(Type *t, void *ret)
689689
{
690-
uint32 flag;
691-
692-
flag = t->kind&KindNoPointers ? FlagNoPointers : 0;
693-
ret = runtime·mallocgc(t->size, flag, 1, 1);
694-
695-
if(UseSpanType && !flag) {
696-
if(false) {
697-
runtime·printf("unsafe_New %S: %p\n", *t->string, ret);
698-
}
699-
runtime·settype(ret, (uintptr)t | TypeInfo_SingleObject);
700-
}
701-
690+
ret = runtime·cnew(t);
702691
FLUSH(&ret);
703692
}
704693

705694
void
706695
reflect·unsafe_NewArray(Type *t, intgo n, void *ret)
707696
{
708-
uint64 size;
709-
710-
size = n*t->size;
711-
if(size == 0)
712-
ret = (byte*)&runtime·zerobase;
713-
else if(t->kind&KindNoPointers)
714-
ret = runtime·mallocgc(size, FlagNoPointers, 1, 1);
715-
else {
716-
ret = runtime·mallocgc(size, 0, 1, 1);
717-
718-
if(UseSpanType) {
719-
if(false) {
720-
runtime·printf("unsafe_NewArray [%D]%S: %p\n", (int64)n, *t->string, ret);
721-
}
722-
runtime·settype(ret, (uintptr)t | TypeInfo_Array);
723-
}
724-
}
725-
697+
ret = runtime·cnewarray(t, n);
726698
FLUSH(&ret);
727699
}
728700

src/pkg/runtime/malloc.goc

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -717,46 +717,54 @@ runtime·new(Type *typ, uint8 *ret)
717717
ret = runtime·mallocgc(typ->size, flag, 1, 1);
718718

719719
if(UseSpanType && !flag) {
720-
if(false) {
720+
if(false)
721721
runtime·printf("new %S: %p\n", *typ->string, ret);
722-
}
723722
runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
724723
}
725724
}
726725

727726
FLUSH(&ret);
728727
}
729728

730-
// same as runtime·new, but callable from C
731-
void*
732-
runtime·cnew(Type *typ)
729+
static void*
730+
cnew(Type *typ, intgo n, int32 objtyp)
733731
{
734732
uint32 flag;
735733
void *ret;
736734

737-
if(raceenabled)
738-
m->racepc = runtime·getcallerpc(&typ);
739-
740-
if(typ->size == 0) {
735+
if((objtyp&(PtrSize-1)) != objtyp)
736+
runtime·throw("runtime: invalid objtyp");
737+
if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
738+
runtime·panicstring("runtime: allocation size out of range");
739+
if(typ->size == 0 || n == 0) {
741740
// All 0-length allocations use this pointer.
742741
// The language does not require the allocations to
743742
// have distinct values.
744-
ret = (uint8*)&runtime·zerobase;
745-
} else {
746-
flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
747-
ret = runtime·mallocgc(typ->size, flag, 1, 1);
748-
749-
if(UseSpanType && !flag) {
750-
if(false) {
751-
runtime·printf("new %S: %p\n", *typ->string, ret);
752-
}
753-
runtime·settype(ret, (uintptr)typ | TypeInfo_SingleObject);
754-
}
743+
return &runtime·zerobase;
744+
}
745+
flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
746+
ret = runtime·mallocgc(typ->size*n, flag, 1, 1);
747+
if(UseSpanType && !flag) {
748+
if(false)
749+
runtime·printf("cnew [%D]%S: %p\n", (int64)n, *typ->string, ret);
750+
runtime·settype(ret, (uintptr)typ | objtyp);
755751
}
756-
757752
return ret;
758753
}
759754

755+
// same as runtime·new, but callable from C
756+
void*
757+
runtime·cnew(Type *typ)
758+
{
759+
return cnew(typ, 1, TypeInfo_SingleObject);
760+
}
761+
762+
void*
763+
runtime·cnewarray(Type *typ, intgo n)
764+
{
765+
return cnew(typ, n, TypeInfo_Array);
766+
}
767+
760768
func GC() {
761769
runtime·gc(1);
762770
}

src/pkg/runtime/malloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ bool runtime·blockspecial(void*);
461461
void runtime·setblockspecial(void*, bool);
462462
void runtime·purgecachedstats(MCache*);
463463
void* runtime·cnew(Type*);
464+
void* runtime·cnewarray(Type*, intgo);
464465

465466
void runtime·settype(void*, uintptr);
466467
void runtime·settype_flush(M*, bool);

src/pkg/runtime/slice.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,9 @@ uintptr runtime·zerobase;
4848
static void
4949
makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
5050
{
51-
uintptr size;
52-
53-
size = cap*t->elem->size;
54-
5551
ret->len = len;
5652
ret->cap = cap;
57-
58-
if(size == 0)
59-
ret->array = (byte*)&runtime·zerobase;
60-
else if((t->elem->kind&KindNoPointers))
61-
ret->array = runtime·mallocgc(size, FlagNoPointers, 1, 1);
62-
else {
63-
ret->array = runtime·mallocgc(size, 0, 1, 1);
64-
65-
if(UseSpanType) {
66-
if(false) {
67-
runtime·printf("new slice [%D]%S: %p\n", (int64)cap, *t->elem->string, ret->array);
68-
}
69-
runtime·settype(ret->array, (uintptr)t->elem | TypeInfo_Array);
70-
}
71-
}
53+
ret->array = runtime·cnewarray(t->elem, cap);
7254
}
7355

7456
// appendslice(type *Type, x, y, []T) []T

0 commit comments

Comments
 (0)
0