]> Cypherpunks repositories - gostls13.git/commitdiff
gc/runtime: pass type structure to makeslice.
authorRuss Cox <rsc@golang.org>
Sat, 5 Dec 2009 05:44:05 +0000 (21:44 -0800)
committerRuss Cox <rsc@golang.org>
Sat, 5 Dec 2009 05:44:05 +0000 (21:44 -0800)
  * inform garbage collector about memory with no pointers in it

1.9s gcc reverse-complement.c

reverse-complement.go
4.5s / 3.5s original, with/without bounds checks
3.5s / 3.3s bounds check reduction
3.3s / 2.8s smarter garbage collector
2.6s / 2.3s assembler bytes.IndexByte
2.5s / 2.1s even smarter garbage collector (this CL)

R=r
https://golang.org/cl/165064

src/cmd/gc/builtin.c.boot
src/cmd/gc/reflect.c
src/cmd/gc/runtime.go
src/cmd/gc/walk.c
src/pkg/runtime/slice.c
src/pkg/runtime/type.go
src/pkg/runtime/type.h

index d2ff0ff90e41c66e4c72e0818dd742ad1b96215c..98c2b8a7ba634376eaa3dabdb50a0ae49a8faac6 100644 (file)
@@ -64,7 +64,7 @@ char *runtimeimport =
        "func runtime.selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
        "func runtime.selectdefault (sel *uint8) (selected bool)\n"
        "func runtime.selectgo (sel *uint8)\n"
-       "func runtime.makeslice (nel int, cap int, width int) (ary []any)\n"
+       "func runtime.makeslice (typ *uint8, nel int, cap int) (ary []any)\n"
        "func runtime.sliceslice1 (old []any, lb int, width int) (ary []any)\n"
        "func runtime.sliceslice (old []any, lb int, hb int, width int) (ary []any)\n"
        "func runtime.slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
index 79065c5de5be411353787badd9c13c1219f65e81..50506b955104c2f196def20af58e5f84ce975690 100644 (file)
@@ -325,6 +325,67 @@ dextratype(Type *t)
        return s;
 }
 
+enum {
+       KindBool = 1,
+       KindInt,
+       KindInt8,
+       KindInt16,
+       KindInt32,
+       KindInt64,
+       KindUint,
+       KindUint8,
+       KindUint16,
+       KindUint32,
+       KindUint64,
+       KindUintptr,
+       KindFloat,
+       KindFloat32,
+       KindFloat64,
+       KindArray,
+       KindChan,
+       KindDotDotDot,
+       KindFunc,
+       KindInterface,
+       KindMap,
+       KindPtr,
+       KindSlice,
+       KindString,
+       KindStruct,
+       KindUnsafePointer,
+       
+       KindNoPointers = 1<<7,
+};
+
+static int
+kinds[] =
+{
+       [TINT]          = KindInt,
+       [TUINT]         = KindUint,
+       [TINT8]         = KindInt8,
+       [TUINT8]        = KindUint8,
+       [TINT16]        = KindInt16,
+       [TUINT16]       = KindUint16,
+       [TINT32]        = KindInt32,
+       [TUINT32]       = KindUint32,
+       [TINT64]        = KindInt64,
+       [TUINT64]       = KindUint64,
+       [TUINTPTR]      = KindUintptr,
+       [TFLOAT]        = KindFloat,
+       [TFLOAT32]      = KindFloat32,
+       [TFLOAT64]      = KindFloat64,
+       [TBOOL]         = KindBool,
+       [TSTRING]               = KindString,
+       [TDDD]          = KindDotDotDot,
+       [TPTR32]                = KindPtr,
+       [TPTR64]                = KindPtr,
+       [TSTRUCT]       = KindStruct,
+       [TINTER]                = KindInterface,
+       [TCHAN]         = KindChan,
+       [TMAP]          = KindMap,
+       [TARRAY]                = KindArray,
+       [TFUNC]         = KindFunc,
+};
+
 static char*
 structnames[] =
 {
@@ -377,6 +438,50 @@ typestruct(Type *t)
        return pkglookup(name, "type");
 }
 
+static int
+haspointers(Type *t)
+{
+       Type *t1;
+
+       switch(t->etype) {
+       case TINT:
+       case TUINT:
+       case TINT8:
+       case TUINT8:
+       case TINT16:
+       case TUINT16:
+       case TINT32:
+       case TUINT32:
+       case TINT64:
+       case TUINT64:
+       case TUINTPTR:
+       case TFLOAT:
+       case TFLOAT32:
+       case TFLOAT64:
+       case TBOOL:
+               return 0;
+       case TARRAY:
+               if(t->bound < 0)        // slice
+                       return 1;
+               return haspointers(t->type);
+       case TSTRUCT:
+               for(t1=t->type; t1!=T; t1=t1->down)
+                       if(haspointers(t1->type))
+                               return 1;
+               return 0;
+       case TSTRING:
+       case TDDD:
+       case TPTR32:
+       case TPTR64:
+       case TINTER:
+       case TCHAN:
+       case TMAP:
+       case TFUNC:
+       default:
+               return 1;
+       }
+}
+
 /*
  * commonType
  * ../../pkg/runtime/type.go:/commonType
@@ -421,6 +526,12 @@ dcommontype(Sym *s, int ot, Type *t)
                i = maxround;
        ot = duint8(s, ot, i);  // align
        ot = duint8(s, ot, i);  // fieldAlign
+       i = kinds[t->etype];
+       if(t->etype == TARRAY && t->bound < 0)
+               i = KindSlice;
+       if(!haspointers(t))
+               i |= KindNoPointers;
+       ot = duint8(s, ot, i);
        p = smprint("%#-T", t);
        ot = dgostringptr(s, ot, p);    // string
        free(p);
index 6413db5e2177c508fcf93df0e319c203b90cd575..baca93c8c6b9520d7060e813239790f94c33b97c 100644 (file)
@@ -79,7 +79,7 @@ func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
 func selectdefault(sel *byte) (selected bool)
 func selectgo(sel *byte)
 
-func makeslice(nel int, cap int, width int) (ary []any)
+func makeslice(typ *byte, nel int, cap int) (ary []any)
 func sliceslice1(old []any, lb int, width int) (ary []any)
 func sliceslice(old []any, lb int, hb int, width int) (ary []any)
 func slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
index 771c258d0cafaaf87f837fce9a9667843495ba58..1d52d05cc4a3b300cb35fc1258b7d29f74c882cd 100644 (file)
@@ -994,9 +994,9 @@ walkexpr(Node **np, NodeList **init)
                fn = syslook("makeslice", 1);
                argtype(fn, t->type);                   // any-1
                n = mkcall1(fn, n->type, nil,
+                       typename(n->type),
                        conv(n->left, types[TINT]),
-                       conv(n->right, types[TINT]),
-                       nodintconst(t->type->width));
+                       conv(n->right, types[TINT]));
                goto ret;
 
        case ORUNESTR:
index 17762ae269901d1cb339b9d8342c3564a2420985..d5e524e8a456be583665cb11fcf6a04544548b53 100644 (file)
@@ -3,35 +3,35 @@
 // license that can be found in the LICENSE file.
 
 #include "runtime.h"
+#include "type.h"
+#include "malloc.h"
 
 static int32   debug   = 0;
 
-// makeslice(nel int, cap int, width int) (ary []any);
+// makeslice(typ *Type, nel int, cap int) (ary []any);
 void
-runtime·makeslice(uint32 nel, uint32 cap, uint32 width, Slice ret)
+runtime·makeslice(SliceType *t, uint32 nel, uint32 cap, Slice ret)
 {
        uint64 size;
 
        if(cap < nel)
                cap = nel;
-       size = cap*width;
+       size = cap*t->elem->size;
 
        ret.len = nel;
        ret.cap = cap;
-       ret.array = mal(size);
+
+       if(t->elem->kind&KindNoPointers)
+               ret.array = mallocgc(size, RefNoPointers, 1);
+       else
+               ret.array = mal(size);
 
        FLUSH(&ret);
 
        if(debug) {
-               prints("makeslice: nel=");
-               runtime·printint(nel);
-               prints("; cap=");
-               runtime·printint(cap);
-               prints("; width=");
-               runtime·printint(width);
-               prints("; ret=");
-               runtime·printslice(ret);
-               prints("\n");
+               printf("makeslice(%S, %d, %d); ret=", 
+                       *t->string, nel, cap);
+               runtime·printslice(ret);
        }
 }
 
index a8b70be8762011499ed66a6c1b927e2e1fa1900a..e91544483f66e18f7e5780c82c3321b0ccfa77ca 100644 (file)
@@ -31,10 +31,43 @@ type commonType struct {
        alg             uint8;          // algorithm for copy+hash+cmp (../runtime/runtime.h:/AMEM)
        align           uint8;          // alignment of variable with this type
        fieldAlign      uint8;          // alignment of struct field with this type
+       kind            uint8;          // enumeration for C
        string          *string;        // string form; unnecessary  but undeniably useful
        *uncommonType;                  // (relatively) uncommon fields
 }
 
+// Values for commonType.kind.
+const (
+       kindBool        = 1 + iota;
+       kindInt;
+       kindInt8;
+       kindInt16;
+       kindInt32;
+       kindInt64;
+       kindUint;
+       kindUint8;
+       kindUint16;
+       kindUint32;
+       kindUint64;
+       kindUintptr;
+       kindFloat;
+       kindFloat32;
+       kindFloat64;
+       kindArray;
+       kindChan;
+       kindDotDotDot;
+       kindFunc;
+       kindInterface;
+       kindMap;
+       kindPtr;
+       kindSlice;
+       kindString;
+       kindStruct;
+       kindUnsafePointer;
+
+       kindNoPointers  = 1 << 7;       // OR'ed into kind
+)
+
 // Method on non-interface type
 type method struct {
        hash    uint32;         // hash of name + pkg + typ
index 86e31ba2aea66d1a215fb3c340001398c5084ae0..f81c98635292394607666555ec018a3a5412366f 100644 (file)
@@ -13,6 +13,7 @@ typedef struct Method Method;
 typedef struct IMethod IMethod;
 typedef struct MapType MapType;
 typedef struct ChanType ChanType;
+typedef struct SliceType SliceType;
 
 struct CommonType
 {
@@ -21,10 +22,42 @@ struct CommonType
        uint8 alg;
        uint8 align;
        uint8 fieldAlign;
+       uint8 kind;
        String *string;
        UncommonType *x;
 };
 
+enum {
+       KindBool = 1,
+       KindInt,
+       KindInt8,
+       KindInt16,
+       KindInt32,
+       KindInt64,
+       KindUint,
+       KindUint8,
+       KindUint16,
+       KindUint32,
+       KindUint64,
+       KindUintptr,
+       KindFloat,
+       KindFloat32,
+       KindFloat64,
+       KindArray,
+       KindChan,
+       KindDotDotDot,
+       KindFunc,
+       KindInterface,
+       KindMap,
+       KindPtr,
+       KindSlice,
+       KindString,
+       KindStruct,
+       KindUnsafePointer,
+       
+       KindNoPointers = 1<<7,
+};
+
 struct Method
 {
        uint32 hash;
@@ -79,3 +112,10 @@ struct ChanType
        Type *elem;
        uintptr dir;
 };
+
+struct SliceType
+{
+       Type;
+       Type *elem;
+};
+