Commit 864c757a authored by Russ Cox's avatar Russ Cox

gc/runtime: pass type structure to makeslice.

  * 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
parent 6f14cada
...@@ -64,7 +64,7 @@ char *runtimeimport = ...@@ -64,7 +64,7 @@ char *runtimeimport =
"func runtime.selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n" "func runtime.selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
"func runtime.selectdefault (sel *uint8) (selected bool)\n" "func runtime.selectdefault (sel *uint8) (selected bool)\n"
"func runtime.selectgo (sel *uint8)\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.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.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" "func runtime.slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
......
...@@ -325,6 +325,67 @@ dextratype(Type *t) ...@@ -325,6 +325,67 @@ dextratype(Type *t)
return s; 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* static char*
structnames[] = structnames[] =
{ {
...@@ -377,6 +438,50 @@ typestruct(Type *t) ...@@ -377,6 +438,50 @@ typestruct(Type *t)
return pkglookup(name, "type"); 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 * commonType
* ../../pkg/runtime/type.go:/commonType * ../../pkg/runtime/type.go:/commonType
...@@ -421,6 +526,12 @@ dcommontype(Sym *s, int ot, Type *t) ...@@ -421,6 +526,12 @@ dcommontype(Sym *s, int ot, Type *t)
i = maxround; i = maxround;
ot = duint8(s, ot, i); // align ot = duint8(s, ot, i); // align
ot = duint8(s, ot, i); // fieldAlign 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); p = smprint("%#-T", t);
ot = dgostringptr(s, ot, p); // string ot = dgostringptr(s, ot, p); // string
free(p); free(p);
......
...@@ -79,7 +79,7 @@ func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool) ...@@ -79,7 +79,7 @@ func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
func selectdefault(sel *byte) (selected bool) func selectdefault(sel *byte) (selected bool)
func selectgo(sel *byte) 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 sliceslice1(old []any, lb int, width int) (ary []any)
func sliceslice(old []any, lb int, hb 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) func slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
......
...@@ -994,9 +994,9 @@ walkexpr(Node **np, NodeList **init) ...@@ -994,9 +994,9 @@ walkexpr(Node **np, NodeList **init)
fn = syslook("makeslice", 1); fn = syslook("makeslice", 1);
argtype(fn, t->type); // any-1 argtype(fn, t->type); // any-1
n = mkcall1(fn, n->type, nil, n = mkcall1(fn, n->type, nil,
typename(n->type),
conv(n->left, types[TINT]), conv(n->left, types[TINT]),
conv(n->right, types[TINT]), conv(n->right, types[TINT]));
nodintconst(t->type->width));
goto ret; goto ret;
case ORUNESTR: case ORUNESTR:
......
...@@ -3,35 +3,35 @@ ...@@ -3,35 +3,35 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "runtime.h" #include "runtime.h"
#include "type.h"
#include "malloc.h"
static int32 debug = 0; static int32 debug = 0;
// makeslice(nel int, cap int, width int) (ary []any); // makeslice(typ *Type, nel int, cap int) (ary []any);
void void
runtime·makeslice(uint32 nel, uint32 cap, uint32 width, Slice ret) runtime·makeslice(SliceType *t, uint32 nel, uint32 cap, Slice ret)
{ {
uint64 size; uint64 size;
if(cap < nel) if(cap < nel)
cap = nel; cap = nel;
size = cap*width; size = cap*t->elem->size;
ret.len = nel; ret.len = nel;
ret.cap = cap; ret.cap = cap;
if(t->elem->kind&KindNoPointers)
ret.array = mallocgc(size, RefNoPointers, 1);
else
ret.array = mal(size); ret.array = mal(size);
FLUSH(&ret); FLUSH(&ret);
if(debug) { if(debug) {
prints("makeslice: nel="); printf("makeslice(%S, %d, %d); ret=",
runtime·printint(nel); *t->string, nel, cap);
prints("; cap=");
runtime·printint(cap);
prints("; width=");
runtime·printint(width);
prints("; ret=");
runtime·printslice(ret); runtime·printslice(ret);
prints("\n");
} }
} }
......
...@@ -31,10 +31,43 @@ type commonType struct { ...@@ -31,10 +31,43 @@ type commonType struct {
alg uint8; // algorithm for copy+hash+cmp (../runtime/runtime.h:/AMEM) alg uint8; // algorithm for copy+hash+cmp (../runtime/runtime.h:/AMEM)
align uint8; // alignment of variable with this type align uint8; // alignment of variable with this type
fieldAlign uint8; // alignment of struct field 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 string *string; // string form; unnecessary but undeniably useful
*uncommonType; // (relatively) uncommon fields *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 // Method on non-interface type
type method struct { type method struct {
hash uint32; // hash of name + pkg + typ hash uint32; // hash of name + pkg + typ
......
...@@ -13,6 +13,7 @@ typedef struct Method Method; ...@@ -13,6 +13,7 @@ typedef struct Method Method;
typedef struct IMethod IMethod; typedef struct IMethod IMethod;
typedef struct MapType MapType; typedef struct MapType MapType;
typedef struct ChanType ChanType; typedef struct ChanType ChanType;
typedef struct SliceType SliceType;
struct CommonType struct CommonType
{ {
...@@ -21,10 +22,42 @@ struct CommonType ...@@ -21,10 +22,42 @@ struct CommonType
uint8 alg; uint8 alg;
uint8 align; uint8 align;
uint8 fieldAlign; uint8 fieldAlign;
uint8 kind;
String *string; String *string;
UncommonType *x; 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 struct Method
{ {
uint32 hash; uint32 hash;
...@@ -79,3 +112,10 @@ struct ChanType ...@@ -79,3 +112,10 @@ struct ChanType
Type *elem; Type *elem;
uintptr dir; uintptr dir;
}; };
struct SliceType
{
Type;
Type *elem;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment