Commit b9ccd077 authored by Russ Cox's avatar Russ Cox

runtime: prep for type-specific algorithms

Equality on structs will require arbitrary code for type equality,
so change algorithm in type data from uint8 to table pointer.
In the process, trim top-level map structure from
104/80 bytes (64-bit/32-bit) to 24/12.

Equality on structs will require being able to call code generated
by the Go compiler, and C code has no way to access Go return
values, so change the hash and equal algorithm functions to take
a pointer to a result instead of returning the result.

R=ken
CC=golang-dev
https://golang.org/cl/5453043
parent 263c955f
This diff is collapsed.
......@@ -72,35 +72,6 @@ struct Strlit
char s[3]; // variable
};
/*
* note this is the runtime representation
* of hashmap iterator. it is probably
* insafe to use it this way, but it puts
* all the changes in one place.
* only flag is referenced from go.
* actual placement does not matter as long
* as the size is >= actual size.
*/
typedef struct Hiter Hiter;
struct Hiter
{
uchar data[8]; // return val from next
int32 elemsize; // size of elements in table
int32 changes; // number of changes observed last time
int32 i; // stack pointer in subtable_state
int32 cycled; // actually a bool but pad for next field, a pointer
uchar last[8]; // last hash value returned
uchar cycle[8]; // the value where we started and will stop
uchar h[8]; // the hash table
struct
{
uchar sub[8]; // pointer into subtable
uchar start[8]; // pointer into start of subtable
uchar end[8]; // pointer into end of subtable
uchar pad[8];
} sub[4];
};
enum
{
Mpscale = 29, // safely smaller than bits in a long
......
......@@ -167,7 +167,9 @@ walkrange(Node *n)
case TMAP:
th = typ(TARRAY);
th->type = ptrto(types[TUINT8]);
th->bound = (sizeof(struct Hiter) + widthptr - 1) / widthptr;
// see ../../pkg/runtime/hashmap.h:/hash_iter
// Size in words.
th->bound = 5 + 4*3 + 4*4/widthptr;
hit = temp(th);
fn = syslook("mapiterinit", 1);
......
......@@ -553,10 +553,15 @@ haspointers(Type *t)
static int
dcommontype(Sym *s, int ot, Type *t)
{
int i;
int i, sizeofAlg;
Sym *sptr;
static Sym *algarray;
char *p;
sizeofAlg = 4*widthptr;
if(algarray == nil)
algarray = pkglookup("algarray", runtimepkg);
dowidth(t);
if(t->sym != nil && !isptr[t->etype])
......@@ -586,7 +591,7 @@ dcommontype(Sym *s, int ot, Type *t)
// }
ot = duintptr(s, ot, t->width);
ot = duint32(s, ot, typehash(t));
ot = duint8(s, ot, algtype(t));
ot = duint8(s, ot, 0); // unused
ot = duint8(s, ot, t->align); // align
ot = duint8(s, ot, t->align); // fieldAlign
i = kinds[t->etype];
......@@ -595,6 +600,7 @@ dcommontype(Sym *s, int ot, Type *t)
if(!haspointers(t))
i |= KindNoPointers;
ot = duint8(s, ot, i); // kind
ot = dsymptr(s, ot, algarray, algtype(t)*sizeofAlg);
p = smprint("%-uT", t);
//print("dcommontype: %s\n", p);
ot = dgostringptr(s, ot, p); // string
......
......@@ -52,7 +52,7 @@ func stringtoslicebyte(string) []byte
func stringtoslicerune(string) []rune
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv rune)
func slicecopy(to any, fr any, wid uint32) int
func copy(to any, fr any, wid uint32) int
func slicestringcopy(to any, fr any) int
// interface conversions
......
......@@ -1078,7 +1078,7 @@ walkexpr(Node **np, NodeList **init)
if(n->right->type->etype == TSTRING)
fn = syslook("slicestringcopy", 1);
else
fn = syslook("slicecopy", 1);
fn = syslook("copy", 1);
argtype(fn, n->left->type);
argtype(fn, n->right->type);
n = mkcall1(fn, n->type, init,
......
......@@ -775,7 +775,7 @@ enum {
KindNoPointers = 1<<7,
// size of Type interface header + CommonType structure.
CommonSize = 2*PtrSize+ 4*PtrSize + 8,
CommonSize = 2*PtrSize+ 5*PtrSize + 8,
};
static Reloc*
......
......@@ -241,10 +241,11 @@ const (
type commonType struct {
size uintptr
hash uint32
alg uint8
_ uint8
align uint8
fieldAlign uint8
kind uint8
alg *uintptr
string *string
*uncommonType
ptrToThis *runtime.Type
......
......@@ -63,6 +63,7 @@ OFILES_arm=\
vlrt.$O\
OFILES=\
alg.$O\
asm.$O\
atomic.$O\
cgocall.$O\
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "runtime.h"
/*
* map and chan helpers for
* dealing with unknown types
*/
void
runtime·memhash(uintptr *h, uintptr s, void *a)
{
byte *b;
uintptr hash;
b = a;
if(sizeof(hash) == 4)
hash = 2860486313U;
else
hash = 33054211828000289ULL;
while(s > 0) {
if(sizeof(hash) == 4)
hash = (hash ^ *b) * 3267000013UL;
else
hash = (hash ^ *b) * 23344194077549503ULL;
b++;
s--;
}
*h ^= hash;
}
void
runtime·memequal(bool *eq, uintptr s, void *a, void *b)
{
byte *ba, *bb, *aend;
if(a == b) {
*eq = 1;
return;
}
ba = a;
bb = b;
aend = ba+s;
while(ba != aend) {
if(*ba != *bb) {
*eq = 0;
return;
}
ba++;
bb++;
}
*eq = 1;
return;
}
void
runtime·memprint(uintptr s, void *a)
{
uint64 v;
v = 0xbadb00b;
switch(s) {
case 1:
v = *(uint8*)a;
break;
case 2:
v = *(uint16*)a;
break;
case 4:
v = *(uintptr*)a;
break;
case 8:
v = *(uint64*)a;
break;
}
runtime·printint(v);
}
void
runtime·memcopy(uintptr s, void *a, void *b)
{
if(b == nil) {
runtime·memclr(a, s);
return;
}
runtime·memmove(a, b, s);
}
void
runtime·memequal8(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = *(uint8*)a == *(uint8*)b;
}
void
runtime·memcopy8(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint8*)a = 0;
return;
}
*(uint8*)a = *(uint8*)b;
}
void
runtime·memequal16(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = *(uint16*)a == *(uint16*)b;
}
void
runtime·memcopy16(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint16*)a = 0;
return;
}
*(uint16*)a = *(uint16*)b;
}
void
runtime·memequal32(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = *(uint32*)a == *(uint32*)b;
}
void
runtime·memcopy32(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint32*)a = 0;
return;
}
*(uint32*)a = *(uint32*)b;
}
void
runtime·memequal64(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = *(uint64*)a == *(uint64*)b;
}
void
runtime·memcopy64(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
*(uint64*)a = 0;
return;
}
*(uint64*)a = *(uint64*)b;
}
void
runtime·memequal128(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = ((uint64*)a)[0] == ((uint64*)b)[0] && ((uint64*)a)[1] == ((uint64*)b)[1];
}
void
runtime·memcopy128(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((uint64*)a)[0] = 0;
((uint64*)a)[1] = 0;
return;
}
((uint64*)a)[0] = ((uint64*)b)[0];
((uint64*)a)[1] = ((uint64*)b)[1];
}
void
runtime·slicecopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Slice*)a)->array = 0;
((Slice*)a)->len = 0;
((Slice*)a)->cap = 0;
return;
}
((Slice*)a)->array = ((Slice*)b)->array;
((Slice*)a)->len = ((Slice*)b)->len;
((Slice*)a)->cap = ((Slice*)b)->cap;
}
void
runtime·strhash(uintptr *h, uintptr s, void *a)
{
USED(s);
runtime·memhash(h, ((String*)a)->len, ((String*)a)->str);
}
void
runtime·strequal(bool *eq, uintptr s, void *a, void *b)
{
int32 alen;
USED(s);
alen = ((String*)a)->len;
if(alen != ((String*)b)->len) {
*eq = false;
return;
}
runtime·memequal(eq, alen, ((String*)a)->str, ((String*)b)->str);
}
void
runtime·strprint(uintptr s, void *a)
{
USED(s);
runtime·printstring(*(String*)a);
}
void
runtime·strcopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((String*)a)->str = 0;
((String*)a)->len = 0;
return;
}
((String*)a)->str = ((String*)b)->str;
((String*)a)->len = ((String*)b)->len;
}
void
runtime·interhash(uintptr *h, uintptr s, void *a)
{
USED(s);
*h ^= runtime·ifacehash(*(Iface*)a);
}
void
runtime·interprint(uintptr s, void *a)
{
USED(s);
runtime·printiface(*(Iface*)a);
}
void
runtime·interequal(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = runtime·ifaceeq_c(*(Iface*)a, *(Iface*)b);
}
void
runtime·intercopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Iface*)a)->tab = 0;
((Iface*)a)->data = 0;
return;
}
((Iface*)a)->tab = ((Iface*)b)->tab;
((Iface*)a)->data = ((Iface*)b)->data;
}
void
runtime·nilinterhash(uintptr *h, uintptr s, void *a)
{
USED(s);
*h ^= runtime·efacehash(*(Eface*)a);
}
void
runtime·nilinterprint(uintptr s, void *a)
{
USED(s);
runtime·printeface(*(Eface*)a);
}
void
runtime·nilinterequal(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
*eq = runtime·efaceeq_c(*(Eface*)a, *(Eface*)b);
}
void
runtime·nilintercopy(uintptr s, void *a, void *b)
{
USED(s);
if(b == nil) {
((Eface*)a)->type = 0;
((Eface*)a)->data = 0;
return;
}
((Eface*)a)->type = ((Eface*)b)->type;
((Eface*)a)->data = ((Eface*)b)->data;
}
void
runtime·nohash(uintptr *h, uintptr s, void *a)
{
USED(s);
USED(a);
USED(h);
runtime·panicstring("hash of unhashable type");
}
void
runtime·noequal(bool *eq, uintptr s, void *a, void *b)
{
USED(s);
USED(a);
USED(b);
USED(eq);
runtime·panicstring("comparing uncomparable types");
}
Alg
runtime·algarray[] =
{
[AMEM] { runtime·memhash, runtime·memequal, runtime·memprint, runtime·memcopy },
[ANOEQ] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy },
[ASTRING] { runtime·strhash, runtime·strequal, runtime·strprint, runtime·strcopy },
[AINTER] { runtime·interhash, runtime·interequal, runtime·interprint, runtime·intercopy },
[ANILINTER] { runtime·nilinterhash, runtime·nilinterequal, runtime·nilinterprint, runtime·nilintercopy },
[ASLICE] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·slicecopy },
[AMEM8] { runtime·memhash, runtime·memequal8, runtime·memprint, runtime·memcopy8 },
[AMEM16] { runtime·memhash, runtime·memequal16, runtime·memprint, runtime·memcopy16 },
[AMEM32] { runtime·memhash, runtime·memequal32, runtime·memprint, runtime·memcopy32 },
[AMEM64] { runtime·memhash, runtime·memequal64, runtime·memprint, runtime·memcopy64 },
[AMEM128] { runtime·memhash, runtime·memequal128, runtime·memprint, runtime·memcopy128 },
[ANOEQ8] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy8 },
[ANOEQ16] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy16 },
[ANOEQ32] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy32 },
[ANOEQ64] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy64 },
[ANOEQ128] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy128 },
};
......@@ -92,11 +92,6 @@ runtime·makechan_c(ChanType *t, int64 hint)
if(hint < 0 || (int32)hint != hint || (elem->size > 0 && hint > ((uintptr)-1) / elem->size))
runtime·panicstring("makechan: size out of range");
if(elem->alg >= nelem(runtime·algarray)) {
runtime·printf("chan(alg=%d)\n", elem->alg);
runtime·throw("runtime.makechan: unsupported elem type");
}
// calculate rounded size of Hchan
n = sizeof(*c);
while(n & MAXALIGN)
......@@ -105,12 +100,12 @@ runtime·makechan_c(ChanType *t, int64 hint)
// allocate memory in one call
c = (Hchan*)runtime·mal(n + hint*elem->size);
c->elemsize = elem->size;
c->elemalg = &runtime·algarray[elem->alg];
c->elemalg = elem->alg;
c->elemalign = elem->align;
c->dataqsiz = hint;
if(debug)
runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%d; elemalign=%d; dataqsiz=%d\n",
runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; elemalign=%d; dataqsiz=%d\n",
c, (int64)elem->size, elem->alg, elem->align, c->dataqsiz);
return c;
......
This diff is collapsed.
......@@ -86,6 +86,7 @@ struct hash_iter {
hash_hash_t last_hash; /* last hash value returned */
hash_hash_t cycle; /* hash value where we started */
struct Hmap *h; /* the hash table */
MapType *t; /* the map type */
struct hash_iter_sub {
struct hash_entry *e; /* pointer into subtable */
struct hash_entry *start; /* start of subtable */
......
......@@ -159,17 +159,18 @@ out:
static void
copyin(Type *t, void *src, void **dst)
{
int32 wid, alg;
uintptr size;
void *p;
Alg *alg;
wid = t->size;
size = t->size;
alg = t->alg;
if(wid <= sizeof(*dst))
runtime·algarray[alg].copy(wid, dst, src);
if(size <= sizeof(*dst))
alg->copy(size, dst, src);
else {
p = runtime·mal(wid);
runtime·algarray[alg].copy(wid, p, src);
p = runtime·mal(size);
alg->copy(size, p, src);
*dst = p;
}
}
......@@ -177,15 +178,16 @@ copyin(Type *t, void *src, void **dst)
static void
copyout(Type *t, void **src, void *dst)
{
int32 wid, alg;
uintptr size;
Alg *alg;
wid = t->size;
size = t->size;
alg = t->alg;
if(wid <= sizeof(*src))
runtime·algarray[alg].copy(wid, dst, src);
if(size <= sizeof(*src))
alg->copy(size, dst, src);
else
runtime·algarray[alg].copy(wid, dst, *src);
alg->copy(size, dst, *src);
}
// func convT2I(typ *byte, typ2 *byte, elem any) (ret any)
......@@ -548,23 +550,27 @@ runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok)
static uintptr
ifacehash1(void *data, Type *t)
{
int32 alg, wid;
Alg *alg;
uintptr size, h;
Eface err;
if(t == nil)
return 0;
alg = t->alg;
wid = t->size;
if(runtime·algarray[alg].hash == runtime·nohash) {
size = t->size;
if(alg->hash == runtime·nohash) {
// calling nohash will panic too,
// but we can print a better error.
runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
runtime·panic(err);
}
if(wid <= sizeof(data))
return runtime·algarray[alg].hash(wid, &data);
return runtime·algarray[alg].hash(wid, data);
h = 0;
if(size <= sizeof(data))
alg->hash(&h, size, &data);
else
alg->hash(&h, size, data);
return h;
}
uintptr
......@@ -584,22 +590,27 @@ runtime·efacehash(Eface a)
static bool
ifaceeq1(void *data1, void *data2, Type *t)
{
int32 alg, wid;
uintptr size;
Alg *alg;
Eface err;
bool eq;
alg = t->alg;
wid = t->size;
size = t->size;
if(runtime·algarray[alg].equal == runtime·noequal) {
if(alg->equal == runtime·noequal) {
// calling noequal will panic too,
// but we can print a better error.
runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"comparing uncomparable type "), *t->string), &err);
runtime·panic(err);
}
if(wid <= sizeof(data1))
return runtime·algarray[alg].equal(wid, &data1, &data2);
return runtime·algarray[alg].equal(wid, data1, data2);
eq = 0;
if(size <= sizeof(data1))
alg->equal(&eq, size, &data1, &data2);
else
alg->equal(&eq, size, data1, data2);
return eq;
}
bool
......@@ -701,7 +712,7 @@ unsafe·Reflect(Eface e, Eface rettype, void *retaddr)
if(e.type->size <= sizeof(uintptr)) {
// Copy data into x ...
x = 0;
runtime·algarray[e.type->alg].copy(e.type->size, &x, &e.data);
e.type->alg->copy(e.type->size, &x, &e.data);
// but then build pointer to x so that Reflect
// always returns pointer to data.
......@@ -711,7 +722,7 @@ unsafe·Reflect(Eface e, Eface rettype, void *retaddr)
// Already a pointer, but still make a copy,
// to preserve value semantics for interface data.
p = runtime·mal(e.type->size);
runtime·algarray[e.type->alg].copy(e.type->size, p, e.data);
e.type->alg->copy(e.type->size, p, e.data);
}
retaddr = p;
}
......@@ -734,7 +745,7 @@ unsafe·Unreflect(Eface typ, void *addr, Eface e)
// Interface holds either pointer to data
// or copy of original data.
if(e.type->size <= sizeof(uintptr))
runtime·algarray[e.type->alg].copy(e.type->size, &e.data, addr);
e.type->alg->copy(e.type->size, &e.data, addr);
else {
// Easier: already a pointer to data.
// TODO(rsc): Should this make a copy?
......
......@@ -322,338 +322,6 @@ runtime·check(void)
runtime·initsig(0);
}
/*
* map and chan helpers for
* dealing with unknown types
*/
static uintptr
memhash(uint32 s, void *a)
{
byte *b;
uintptr hash;
b = a;
if(sizeof(hash) == 4)
hash = 2860486313U;
else
hash = 33054211828000289ULL;
while(s > 0) {
if(sizeof(hash) == 4)
hash = (hash ^ *b) * 3267000013UL;
else
hash = (hash ^ *b) * 23344194077549503ULL;
b++;
s--;
}
return hash;
}
static uint32
memequal(uint32 s, void *a, void *b)
{
byte *ba, *bb, *aend;
if(a == b)
return 1;
ba = a;
bb = b;
aend = ba+s;
while(ba != aend) {
if(*ba != *bb)
return 0;
ba++;
bb++;
}
return 1;
}
static void
memprint(uint32 s, void *a)
{
uint64 v;
v = 0xbadb00b;
switch(s) {
case 1:
v = *(uint8*)a;
break;
case 2:
v = *(uint16*)a;
break;
case 4:
v = *(uint32*)a;
break;
case 8:
v = *(uint64*)a;
break;
}
runtime·printint(v);
}
static void
memcopy(uint32 s, void *a, void *b)
{
if(b == nil) {
runtime·memclr(a,s);
return;
}
runtime·memmove(a,b,s);
}
static uint32
memequal8(uint32 s, uint8 *a, uint8 *b)
{
USED(s);
return *a == *b;
}
static void
memcopy8(uint32 s, uint8 *a, uint8 *b)
{
USED(s);
if(b == nil) {
*a = 0;
return;
}
*a = *b;
}
static uint32
memequal16(uint32 s, uint16 *a, uint16 *b)
{
USED(s);
return *a == *b;
}
static void
memcopy16(uint32 s, uint16 *a, uint16 *b)
{
USED(s);
if(b == nil) {
*a = 0;
return;
}
*a = *b;
}
static uint32
memequal32(uint32 s, uint32 *a, uint32 *b)
{
USED(s);
return *a == *b;
}
static void
memcopy32(uint32 s, uint32 *a, uint32 *b)
{
USED(s);
if(b == nil) {
*a = 0;
return;
}
*a = *b;
}
static uint32
memequal64(uint32 s, uint64 *a, uint64 *b)
{
USED(s);
return *a == *b;
}
static void
memcopy64(uint32 s, uint64 *a, uint64 *b)
{
USED(s);
if(b == nil) {
*a = 0;
return;
}
*a = *b;
}
static uint32
memequal128(uint32 s, uint64 *a, uint64 *b)
{
USED(s);
return a[0] == b[0] && a[1] == b[1];
}
static void
memcopy128(uint32 s, uint64 *a, uint64 *b)
{
USED(s);
if(b == nil) {
a[0] = 0;
a[1] = 0;
return;
}
a[0] = b[0];
a[1] = b[1];
}
static void
slicecopy(uint32 s, Slice *a, Slice *b)
{
USED(s);
if(b == nil) {
a->array = 0;
a->len = 0;
a->cap = 0;
return;
}
a->array = b->array;
a->len = b->len;
a->cap = b->cap;
}
static uintptr
strhash(uint32 s, String *a)
{
USED(s);
return memhash((*a).len, (*a).str);
}
static uint32
strequal(uint32 s, String *a, String *b)
{
int32 alen;
USED(s);
alen = a->len;
if(alen != b->len)
return false;
return memequal(alen, a->str, b->str);
}
static void
strprint(uint32 s, String *a)
{
USED(s);
runtime·printstring(*a);
}
static void
strcopy(uint32 s, String *a, String *b)
{
USED(s);
if(b == nil) {
a->str = 0;
a->len = 0;
return;
}
a->str = b->str;
a->len = b->len;
}
static uintptr
interhash(uint32 s, Iface *a)
{
USED(s);
return runtime·ifacehash(*a);
}
static void
interprint(uint32 s, Iface *a)
{
USED(s);
runtime·printiface(*a);
}
static uint32
interequal(uint32 s, Iface *a, Iface *b)
{
USED(s);
return runtime·ifaceeq_c(*a, *b);
}
static void
intercopy(uint32 s, Iface *a, Iface *b)
{
USED(s);
if(b == nil) {
a->tab = 0;
a->data = 0;
return;
}
a->tab = b->tab;
a->data = b->data;
}
static uintptr
nilinterhash(uint32 s, Eface *a)
{
USED(s);
return runtime·efacehash(*a);
}
static void
nilinterprint(uint32 s, Eface *a)
{
USED(s);
runtime·printeface(*a);
}
static uint32
nilinterequal(uint32 s, Eface *a, Eface *b)
{
USED(s);
return runtime·efaceeq_c(*a, *b);
}
static void
nilintercopy(uint32 s, Eface *a, Eface *b)
{
USED(s);
if(b == nil) {
a->type = 0;
a->data = 0;
return;
}
a->type = b->type;
a->data = b->data;
}
uintptr
runtime·nohash(uint32 s, void *a)
{
USED(s);
USED(a);
runtime·panicstring("hash of unhashable type");
return 0;
}
uint32
runtime·noequal(uint32 s, void *a, void *b)
{
USED(s);
USED(a);
USED(b);
runtime·panicstring("comparing uncomparable types");
return 0;
}
Alg
runtime·algarray[] =
{
[AMEM] { memhash, memequal, memprint, memcopy },
[ANOEQ] { runtime·nohash, runtime·noequal, memprint, memcopy },
[ASTRING] { (void*)strhash, (void*)strequal, (void*)strprint, (void*)strcopy },
[AINTER] { (void*)interhash, (void*)interequal, (void*)interprint, (void*)intercopy },
[ANILINTER] { (void*)nilinterhash, (void*)nilinterequal, (void*)nilinterprint, (void*)nilintercopy },
[ASLICE] { (void*)runtime·nohash, (void*)runtime·noequal, (void*)memprint, (void*)slicecopy },
[AMEM8] { memhash, (void*)memequal8, memprint, (void*)memcopy8 },
[AMEM16] { memhash, (void*)memequal16, memprint, (void*)memcopy16 },
[AMEM32] { memhash, (void*)memequal32, memprint, (void*)memcopy32 },
[AMEM64] { memhash, (void*)memequal64, memprint, (void*)memcopy64 },
[AMEM128] { memhash, (void*)memequal128, memprint, (void*)memcopy128 },
[ANOEQ8] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy8 },
[ANOEQ16] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy16 },
[ANOEQ32] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy32 },
[ANOEQ64] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy64 },
[ANOEQ128] { runtime·nohash, runtime·noequal, memprint, (void*)memcopy128 },
};
void
runtime·Caller(int32 skip, uintptr retpc, String retfile, int32 retline, bool retbool)
{
......
......@@ -43,7 +43,6 @@ typedef int32 intptr;
*/
typedef uint8 bool;
typedef uint8 byte;
typedef struct Alg Alg;
typedef struct Func Func;
typedef struct G G;
typedef struct Gobuf Gobuf;
......@@ -260,13 +259,6 @@ struct Stktop
uintptr free; // if free>0, call stackfree using free as size
bool panic; // is this frame the top of a panic?
};
struct Alg
{
uintptr (*hash)(uint32, void*);
uint32 (*equal)(uint32, void*, void*);
void (*print)(uint32, void*);
void (*copy)(uint32, void*, void*);
};
struct SigTab
{
int32 flags;
......@@ -356,6 +348,13 @@ struct Timer
/*
* known to compiler
*/
enum {
Structrnd = sizeof(uintptr)
};
/*
* type algorithms - known to compiler
*/
enum
{
AMEM,
......@@ -376,11 +375,45 @@ enum
ANOEQ128,
Amax
};
typedef struct Alg Alg;
struct Alg
{
void (*hash)(uintptr*, uintptr, void*);
void (*equal)(bool*, uintptr, void*, void*);
void (*print)(uintptr, void*);
void (*copy)(uintptr, void*, void*);
};
extern Alg runtime·algarray[Amax];
enum {
Structrnd = sizeof(uintptr)
};
void runtime·memhash(uintptr*, uintptr, void*);
void runtime·nohash(uintptr*, uintptr, void*);
void runtime·strhash(uintptr*, uintptr, void*);
void runtime·interhash(uintptr*, uintptr, void*);
void runtime·nilinterhash(uintptr*, uintptr, void*);
void runtime·memequal(bool*, uintptr, void*, void*);
void runtime·noequal(bool*, uintptr, void*, void*);
void runtime·strequal(bool*, uintptr, void*, void*);
void runtime·interequal(bool*, uintptr, void*, void*);
void runtime·nilinterequal(bool*, uintptr, void*, void*);
void runtime·memprint(uintptr, void*);
void runtime·strprint(uintptr, void*);
void runtime·interprint(uintptr, void*);
void runtime·nilinterprint(uintptr, void*);
void runtime·memcopy(uintptr, void*, void*);
void runtime·memcopy8(uintptr, void*, void*);
void runtime·memcopy16(uintptr, void*, void*);
void runtime·memcopy32(uintptr, void*, void*);
void runtime·memcopy64(uintptr, void*, void*);
void runtime·memcopy128(uintptr, void*, void*);
void runtime·memcopy(uintptr, void*, void*);
void runtime·strcopy(uintptr, void*, void*);
void runtime·algslicecopy(uintptr, void*, void*);
void runtime·intercopy(uintptr, void*, void*);
void runtime·nilintercopy(uintptr, void*, void*);
/*
* deferred subroutine calls
......@@ -410,7 +443,6 @@ struct Panic
/*
* external data
*/
extern Alg runtime·algarray[Amax];
extern String runtime·emptystring;
G* runtime·allg;
G* runtime·lastg;
......@@ -498,8 +530,6 @@ bool runtime·ifaceeq_c(Iface, Iface);
bool runtime·efaceeq_c(Eface, Eface);
uintptr runtime·ifacehash(Iface);
uintptr runtime·efacehash(Eface);
uintptr runtime·nohash(uint32, void*);
uint32 runtime·noequal(uint32, void*, void*);
void* runtime·malloc(uintptr size);
void runtime·free(void *v);
bool runtime·addfinalizer(void*, void(*fn)(void*), int32);
......
......@@ -11,7 +11,7 @@ static int32 debug = 0;
static void makeslice1(SliceType*, int32, int32, Slice*);
static void growslice1(SliceType*, Slice, int32, Slice *);
void runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret);
void runtime·copy(Slice to, Slice fm, uintptr width, int32 ret);
// see also unsafe·NewArray
// makeslice(typ *Type, len, cap int64) (ary []any);
......@@ -290,9 +290,9 @@ runtime·slicearray(byte* old, uint64 nel, uint64 lb, uint64 hb, uint64 width, S
}
}
// slicecopy(to any, fr any, wid uint32) int
// copy(to any, fr any, wid uint32) int
void
runtime·slicecopy(Slice to, Slice fm, uintptr width, int32 ret)
runtime·copy(Slice to, Slice fm, uintptr width, int32 ret)
{
if(fm.len == 0 || to.len == 0 || width == 0) {
ret = 0;
......
......@@ -27,15 +27,16 @@ type Type interface{}
// All types begin with a few common fields needed for
// the interface runtime.
type commonType struct {
size uintptr // size in bytes
hash uint32 // hash of type; avoids computation in hash tables
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
ptrToThis *Type // pointer to this type, if used in binary or has methods
size uintptr // size in bytes
hash uint32 // hash of type; avoids computation in hash tables
_ uint8 // unused
align uint8 // alignment of variable with this type
fieldAlign uint8 // alignment of struct field with this type
kind uint8 // enumeration for C
alg *uintptr // algorithm table (../runtime/runtime.h:/Alg)
string *string // string form; unnecessary but undeniably useful
*uncommonType // (relatively) uncommon fields
ptrToThis *Type // pointer to this type, if used in binary or has methods
}
// Values for commonType.kind.
......
......@@ -23,10 +23,11 @@ struct CommonType
{
uintptr size;
uint32 hash;
uint8 alg;
uint8 _unused;
uint8 align;
uint8 fieldAlign;
uint8 kind;
Alg *alg;
String *string;
UncommonType *x;
Type *ptrto;
......
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