if(ot != 0)
fatal("dcommontype %d", ot);
- sizeofAlg = 4*widthptr;
+ sizeofAlg = 2*widthptr;
if(algarray == nil)
algarray = pkglookup("algarray", runtimepkg);
alg = algtype(t);
{
int ot;
Sym *s, *hash, *hashfunc, *eq, *eqfunc;
- char buf[100];
// dalgsym is only called for a type that needs an algorithm table,
// which implies that the type is comparable (or else it would use ANOEQ).
dsymptr(eqfunc, 0, eq, 0);
ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
- // ../../pkg/runtime/runtime.h:/Alg
+ // ../../pkg/runtime/alg.go:/typeAlg
ot = 0;
ot = dsymptr(s, ot, hashfunc, 0);
ot = dsymptr(s, ot, eqfunc, 0);
- ot = dsymptr(s, ot, pkglookup("memprint", runtimepkg), 0);
- switch(t->width) {
- default:
- ot = dsymptr(s, ot, pkglookup("memcopy", runtimepkg), 0);
- break;
- case 1:
- case 2:
- case 4:
- case 8:
- case 16:
- snprint(buf, sizeof buf, "memcopy%d", (int)t->width*8);
- ot = dsymptr(s, ot, pkglookup(buf, runtimepkg), 0);
- break;
- }
ggloblsym(s, ot, DUPOK|RODATA);
return s;
c1 = uintptr((8-ptrSize)/4*3267000013 + (ptrSize-4)/4*23344194077549503)
)
+// type algorithms - known to compiler
const (
alg_MEM = iota
alg_MEM0
alg_max
)
+type typeAlg struct {
+ // function for hashing objects of this type
+ // (ptr to object, size, seed) -> hash
+ hash func(unsafe.Pointer, uintptr, uintptr) uintptr
+ // function for comparing objects of this type
+ // (ptr to object A, ptr to object B, size) -> ==?
+ equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
+}
+
+var algarray = [alg_max]typeAlg{
+ alg_MEM: {memhash, memequal},
+ alg_MEM0: {memhash, memequal0},
+ alg_MEM8: {memhash, memequal8},
+ alg_MEM16: {memhash, memequal16},
+ alg_MEM32: {memhash, memequal32},
+ alg_MEM64: {memhash, memequal64},
+ alg_MEM128: {memhash, memequal128},
+ alg_NOEQ: {nil, nil},
+ alg_NOEQ0: {nil, nil},
+ alg_NOEQ8: {nil, nil},
+ alg_NOEQ16: {nil, nil},
+ alg_NOEQ32: {nil, nil},
+ alg_NOEQ64: {nil, nil},
+ alg_NOEQ128: {nil, nil},
+ alg_STRING: {strhash, strequal},
+ alg_INTER: {interhash, interequal},
+ alg_NILINTER: {nilinterhash, nilinterequal},
+ alg_SLICE: {nil, nil},
+ alg_FLOAT32: {f32hash, f32equal},
+ alg_FLOAT64: {f64hash, f64equal},
+ alg_CPLX64: {c64hash, c64equal},
+ alg_CPLX128: {c128hash, c128equal},
+}
+
const nacl = GOOS == "nacl"
-var use_aeshash bool
+var useAeshash bool
// in asm_*.s
func aeshash(p unsafe.Pointer, s, h uintptr) uintptr
func aeshashstr(p unsafe.Pointer, s, h uintptr) uintptr
func memhash(p unsafe.Pointer, s, h uintptr) uintptr {
- if !nacl && use_aeshash {
+ if !nacl && useAeshash {
return aeshash(p, s, h)
}
return h
}
-func strhash(a *string, s, h uintptr) uintptr {
- return memhash((*stringStruct)(unsafe.Pointer(a)).str, uintptr(len(*a)), h)
+func strhash(a unsafe.Pointer, s, h uintptr) uintptr {
+ return memhash((*stringStruct)(a).str, uintptr(len(*(*string)(a))), h)
}
// NOTE: Because NaN != NaN, a map can contain any
// To avoid long hash chains, we assign a random number
// as the hash value for a NaN.
-func f32hash(a *float32, s, h uintptr) uintptr {
- f := *a
+func f32hash(p unsafe.Pointer, s, h uintptr) uintptr {
+ f := *(*float32)(p)
switch {
case f == 0:
return c1 * (c0 ^ h) // +0, -0
case f != f:
return c1 * (c0 ^ h ^ uintptr(fastrand2())) // any kind of NaN
default:
- return memhash(unsafe.Pointer(a), 4, h)
+ return memhash(p, 4, h)
}
}
-func f64hash(a *float64, s, h uintptr) uintptr {
- f := *a
+func f64hash(p unsafe.Pointer, s, h uintptr) uintptr {
+ f := *(*float64)(p)
switch {
case f == 0:
return c1 * (c0 ^ h) // +0, -0
case f != f:
return c1 * (c0 ^ h ^ uintptr(fastrand2())) // any kind of NaN
default:
- return memhash(unsafe.Pointer(a), 8, h)
+ return memhash(p, 8, h)
}
}
-func c64hash(a *complex64, s, h uintptr) uintptr {
- x := (*[2]float32)(unsafe.Pointer(a))
- return f32hash(&x[1], 4, f32hash(&x[0], 4, h))
-}
-
-func c128hash(a *complex128, s, h uintptr) uintptr {
- x := (*[2]float64)(unsafe.Pointer(a))
- return f64hash(&x[1], 4, f64hash(&x[0], 4, h))
+func c64hash(p unsafe.Pointer, s, h uintptr) uintptr {
+ x := (*[2]float32)(p)
+ return f32hash(unsafe.Pointer(&x[1]), 4, f32hash(unsafe.Pointer(&x[0]), 4, h))
}
-func nohash(a unsafe.Pointer, s, h uintptr) uintptr {
- panic(errorString("hash of unhashable type"))
+func c128hash(p unsafe.Pointer, s, h uintptr) uintptr {
+ x := (*[2]float64)(p)
+ return f64hash(unsafe.Pointer(&x[1]), 8, f64hash(unsafe.Pointer(&x[0]), 8, h))
}
-func interhash(a *iface, s, h uintptr) uintptr {
+func interhash(p unsafe.Pointer, s, h uintptr) uintptr {
+ a := (*iface)(p)
tab := a.tab
if tab == nil {
return h
}
t := tab._type
fn := goalg(t.alg).hash
- if **(**uintptr)(unsafe.Pointer(&fn)) == nohashcode {
- // calling nohash will panic too,
- // but we can print a better error.
+ if fn == nil {
panic(errorString("hash of unhashable type " + *t._string))
}
if isDirectIface(t) {
}
}
-func nilinterhash(a *eface, s, h uintptr) uintptr {
+func nilinterhash(p unsafe.Pointer, s, h uintptr) uintptr {
+ a := (*eface)(p)
t := a._type
if t == nil {
return h
}
fn := goalg(t.alg).hash
- if **(**uintptr)(unsafe.Pointer(&fn)) == nohashcode {
- // calling nohash will panic too,
- // but we can print a better error.
+ if fn == nil {
panic(errorString("hash of unhashable type " + *t._string))
}
if isDirectIface(t) {
return true
}
eq := goalg(t.alg).equal
- if **(**uintptr)(unsafe.Pointer(&eq)) == noequalcode {
- // calling noequal will panic too,
- // but we can print a better error.
+ if eq == nil {
panic(errorString("comparing uncomparable type " + *t._string))
}
if isDirectIface(t) {
}
t := xtab._type
eq := goalg(t.alg).equal
- if **(**uintptr)(unsafe.Pointer(&eq)) == noequalcode {
- // calling noequal will panic too,
- // but we can print a better error.
+ if eq == nil {
panic(errorString("comparing uncomparable type " + *t._string))
}
if isDirectIface(t) {
return eq(x.data, y.data, uintptr(t.size))
}
-func noequal(p, q unsafe.Pointer, size uintptr) bool {
- panic(errorString("comparing uncomparable types"))
-}
-
// Testing adapters for hash quality tests (see hash_test.go)
func haveGoodHash() bool {
- return use_aeshash
+ return useAeshash
}
func stringHash(s string, seed uintptr) uintptr {
- return goalg(&algarray[alg_STRING]).hash(noescape(unsafe.Pointer(&s)), unsafe.Sizeof(s), seed)
+ return algarray[alg_STRING].hash(noescape(unsafe.Pointer(&s)), unsafe.Sizeof(s), seed)
}
func bytesHash(b []byte, seed uintptr) uintptr {
- // TODO: use sliceStruct
- return goalg(&algarray[alg_MEM]).hash(*(*unsafe.Pointer)(unsafe.Pointer(&b)), uintptr(len(b)), seed)
+ s := (*sliceStruct)(unsafe.Pointer(&b))
+ return algarray[alg_MEM].hash(s.array, uintptr(s.len), seed)
}
func int32Hash(i uint32, seed uintptr) uintptr {
- return goalg(&algarray[alg_MEM32]).hash(noescape(unsafe.Pointer(&i)), 4, seed)
+ return algarray[alg_MEM32].hash(noescape(unsafe.Pointer(&i)), 4, seed)
}
func int64Hash(i uint64, seed uintptr) uintptr {
- return goalg(&algarray[alg_MEM64]).hash(noescape(unsafe.Pointer(&i)), 8, seed)
+ return algarray[alg_MEM64].hash(noescape(unsafe.Pointer(&i)), 8, seed)
}
func efaceHash(i interface{}, seed uintptr) uintptr {
- return goalg(&algarray[alg_NILINTER]).hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
+ return algarray[alg_NILINTER].hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
}
func ifaceHash(i interface {
F()
}, seed uintptr) uintptr {
- return goalg(&algarray[alg_INTER]).hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
+ return algarray[alg_INTER].hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
}
// Testing adapter for memclr
s := (*sliceStruct)(unsafe.Pointer(&b))
memclr(s.array, uintptr(s.len))
}
+
+// TODO(dvyukov): remove when Type is converted to Go and contains *typeAlg.
+func goalg(a unsafe.Pointer) *typeAlg {
+ return (*typeAlg)(a)
+}
+
+// used in asm_{386,amd64}.s
+const hashRandomBytes = 32
+
+var aeskeysched [hashRandomBytes]byte
+
+//go:noescape
+func get_random_data(rnd *unsafe.Pointer, n *int32)
+
+func init() {
+ if theGoos == "nacl" {
+ return
+ }
+
+ // Install aes hash algorithm if we have the instructions we need
+ if (cpuid_ecx&(1<<25)) != 0 && // aes (aesenc)
+ (cpuid_ecx&(1<<9)) != 0 && // sse3 (pshufb)
+ (cpuid_ecx&(1<<19)) != 0 { // sse4.1 (pinsr{d,q})
+ useAeshash = true
+ algarray[alg_MEM].hash = aeshash
+ algarray[alg_MEM8].hash = aeshash
+ algarray[alg_MEM16].hash = aeshash
+ algarray[alg_MEM32].hash = aeshash32
+ algarray[alg_MEM64].hash = aeshash64
+ algarray[alg_MEM128].hash = aeshash
+ algarray[alg_STRING].hash = aeshashstr
+ // Initialize with random data so hash collisions will be hard to engineer.
+ var rnd unsafe.Pointer
+ var n int32
+ get_random_data(&rnd, &n)
+ if n > hashRandomBytes {
+ n = hashRandomBytes
+ }
+ memmove(unsafe.Pointer(&aeskeysched[0]), rnd, uintptr(n))
+ if n < hashRandomBytes {
+ // Not very random, but better than nothing.
+ for t := nanotime(); n < hashRandomBytes; n++ {
+ aeskeysched[n] = byte(t >> uint(8*(n%8)))
+ }
+ }
+ }
+}
+++ /dev/null
-// 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.
-
-package runtime
-#include "runtime.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-bool runtime·use_aeshash;
-
-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 = *(uint32*)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·memcopy0(uintptr s, void *a, void *b)
-{
- USED(s);
- USED(a);
- USED(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·memcopy16(uintptr s, void *a, void *b)
-{
- USED(s);
- if(b == nil) {
- *(uint16*)a = 0;
- return;
- }
- *(uint16*)a = *(uint16*)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·memcopy64(uintptr s, void *a, void *b)
-{
- USED(s);
- if(b == nil) {
- *(uint64*)a = 0;
- return;
- }
- *(uint64*)a = *(uint64*)b;
-}
-
-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·algslicecopy(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·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·interprint(uintptr s, void *a)
-{
- USED(s);
- runtime·printiface(*(Iface*)a);
-}
-
-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·nilinterprint(uintptr s, void *a)
-{
- USED(s);
- runtime·printeface(*(Eface*)a);
-}
-
-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;
-}
-
-extern uintptr runtime·nohashcode;
-extern uintptr runtime·noequalcode;
-
-static FuncVal memhashfunc = {(void*)runtime·memhash};
-static FuncVal nohashfunc = {(void*)runtime·nohash};
-static FuncVal strhashfunc = {(void*)runtime·strhash};
-static FuncVal interhashfunc = {(void*)runtime·interhash};
-static FuncVal nilinterhashfunc = {(void*)runtime·nilinterhash};
-static FuncVal f32hashfunc = {(void*)runtime·f32hash};
-static FuncVal f64hashfunc = {(void*)runtime·f64hash};
-static FuncVal c64hashfunc = {(void*)runtime·c64hash};
-static FuncVal c128hashfunc = {(void*)runtime·c128hash};
-
-static FuncVal aeshashfunc = {(void*)runtime·aeshash};
-static FuncVal aeshash32func = {(void*)runtime·aeshash32};
-static FuncVal aeshash64func = {(void*)runtime·aeshash64};
-static FuncVal aeshashstrfunc = {(void*)runtime·aeshashstr};
-
-static FuncVal memequalfunc = {(void*)runtime·memequal};
-static FuncVal noequalfunc = {(void*)runtime·noequal};
-static FuncVal strequalfunc = {(void*)runtime·strequal};
-static FuncVal interequalfunc = {(void*)runtime·interequal};
-static FuncVal nilinterequalfunc = {(void*)runtime·nilinterequal};
-static FuncVal f32equalfunc = {(void*)runtime·f32equal};
-static FuncVal f64equalfunc = {(void*)runtime·f64equal};
-static FuncVal c64equalfunc = {(void*)runtime·c64equal};
-static FuncVal c128equalfunc = {(void*)runtime·c128equal};
-static FuncVal memequal0func = {(void*)runtime·memequal0};
-static FuncVal memequal8func = {(void*)runtime·memequal8};
-static FuncVal memequal16func = {(void*)runtime·memequal16};
-static FuncVal memequal32func = {(void*)runtime·memequal32};
-static FuncVal memequal64func = {(void*)runtime·memequal64};
-static FuncVal memequal128func = {(void*)runtime·memequal128};
-
-
-Alg
-runtime·algarray[] =
-{
-[AMEM] { &memhashfunc, &memequalfunc, runtime·memprint, runtime·memcopy },
-[ANOEQ] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy },
-[ASTRING] { &strhashfunc, &strequalfunc, runtime·strprint, runtime·strcopy },
-[AINTER] { &interhashfunc, &interequalfunc, runtime·interprint, runtime·intercopy },
-[ANILINTER] { &nilinterhashfunc, &nilinterequalfunc, runtime·nilinterprint, runtime·nilintercopy },
-[ASLICE] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·algslicecopy },
-[AFLOAT32] { &f32hashfunc, &f32equalfunc, runtime·memprint, runtime·memcopy },
-[AFLOAT64] { &f64hashfunc, &f64equalfunc, runtime·memprint, runtime·memcopy },
-[ACPLX64] { &c64hashfunc, &c64equalfunc, runtime·memprint, runtime·memcopy },
-[ACPLX128] { &c128hashfunc, &c128equalfunc, runtime·memprint, runtime·memcopy },
-[AMEM0] { &memhashfunc, &memequal0func, runtime·memprint, runtime·memcopy0 },
-[AMEM8] { &memhashfunc, &memequal8func, runtime·memprint, runtime·memcopy8 },
-[AMEM16] { &memhashfunc, &memequal16func, runtime·memprint, runtime·memcopy16 },
-[AMEM32] { &memhashfunc, &memequal32func, runtime·memprint, runtime·memcopy32 },
-[AMEM64] { &memhashfunc, &memequal64func, runtime·memprint, runtime·memcopy64 },
-[AMEM128] { &memhashfunc, &memequal128func, runtime·memprint, runtime·memcopy128 },
-[ANOEQ0] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy0 },
-[ANOEQ8] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy8 },
-[ANOEQ16] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy16 },
-[ANOEQ32] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy32 },
-[ANOEQ64] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy64 },
-[ANOEQ128] { &nohashfunc, &noequalfunc, runtime·memprint, runtime·memcopy128 },
-};
-
-// Runtime helpers.
-
-// used in asm_{386,amd64}.s
-#pragma dataflag NOPTR
-byte runtime·aeskeysched[HashRandomBytes];
-
-void
-runtime·hashinit(void)
-{
- runtime·nohashcode = (uintptr)runtime·nohash;
- runtime·noequalcode = (uintptr)runtime·noequal;
-
- if(NaCl)
- return;
-
- // Install aes hash algorithm if we have the instructions we need
- if((runtime·cpuid_ecx & (1 << 25)) != 0 && // aes (aesenc)
- (runtime·cpuid_ecx & (1 << 9)) != 0 && // sse3 (pshufb)
- (runtime·cpuid_ecx & (1 << 19)) != 0) { // sse4.1 (pinsr{d,q})
- byte *rnd;
- int32 n;
- runtime·use_aeshash = true;
- runtime·algarray[AMEM].hash = &aeshashfunc;
- runtime·algarray[AMEM8].hash = &aeshashfunc;
- runtime·algarray[AMEM16].hash = &aeshashfunc;
- runtime·algarray[AMEM32].hash = &aeshash32func;
- runtime·algarray[AMEM64].hash = &aeshash64func;
- runtime·algarray[AMEM128].hash = &aeshashfunc;
- runtime·algarray[ASTRING].hash = &aeshashstrfunc;
- // Initialize with random data so hash collisions will be hard to engineer.
- runtime·get_random_data(&rnd, &n);
- if(n > HashRandomBytes)
- n = HashRandomBytes;
- runtime·memmove(runtime·aeskeysched, rnd, n);
- if(n < HashRandomBytes) {
- // Not very random, but better than nothing.
- int64 t = runtime·nanotime();
- while (n < HashRandomBytes) {
- runtime·aeskeysched[n++] = (int8)(t >> (8 * (n % 8)));
- }
- }
- }
-}
MOVL AX, 4(SP)
CALL runtime·args(SB)
CALL runtime·osinit(SB)
- CALL runtime·hashinit(SB)
CALL runtime·schedinit(SB)
// create a new goroutine to start program
MOVQ AX, 8(SP)
CALL runtime·args(SB)
CALL runtime·osinit(SB)
- CALL runtime·hashinit(SB)
CALL runtime·schedinit(SB)
// create a new goroutine to start program
MOVL AX, 4(SP)
CALL runtime·args(SB)
CALL runtime·osinit(SB)
- CALL runtime·hashinit(SB)
CALL runtime·schedinit(SB)
// create a new goroutine to start program
MOVW R1, 8(R13)
BL runtime·args(SB)
BL runtime·osinit(SB)
- BL runtime·hashinit(SB)
BL runtime·schedinit(SB)
// create a new goroutine to start program
return false; // not reached
}
- if(debug) {
- runtime·printf("chansend: chan=%p; elem=", c);
- c->elemtype->alg->print(c->elemsize, ep);
- runtime·prints("\n");
- }
-
if(raceenabled)
runtime·racereadpc(c, pc, chansend);
gp = sg->g;
gp->param = sg;
if(sg->elem != nil)
- c->elemtype->alg->copy(c->elemsize, sg->elem, ep);
+ runtime·memmove(sg->elem, ep, c->elemsize);
if(sg->releasetime)
sg->releasetime = runtime·cputicks();
runtime·ready(gp);
runtime·racerelease(chanbuf(c, c->sendx));
}
- c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), ep);
+ runtime·memmove(chanbuf(c, c->sendx), ep, c->elemsize);
if(++c->sendx == c->dataqsiz)
c->sendx = 0;
c->qcount++;
runtime·unlock(&c->lock);
if(ep != nil)
- c->elemtype->alg->copy(c->elemsize, ep, sg->elem);
+ runtime·memmove(ep, sg->elem, c->elemsize);
gp = sg->g;
gp->param = sg;
if(sg->releasetime)
}
if(ep != nil)
- c->elemtype->alg->copy(c->elemsize, ep, chanbuf(c, c->recvx));
- c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
+ runtime·memmove(ep, chanbuf(c, c->recvx), c->elemsize);
+ runtime·memclr(chanbuf(c, c->recvx), c->elemsize);
if(++c->recvx == c->dataqsiz)
c->recvx = 0;
c->qcount--;
closed:
if(ep != nil)
- c->elemtype->alg->copy(c->elemsize, ep, nil);
+ runtime·memclr(ep, c->elemsize);
if(received != nil)
*received = false;
if(raceenabled)
if(cas->receivedp != nil)
*cas->receivedp = true;
if(cas->sg.elem != nil)
- c->elemtype->alg->copy(c->elemsize, cas->sg.elem, chanbuf(c, c->recvx));
- c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
+ runtime·memmove(cas->sg.elem, chanbuf(c, c->recvx), c->elemsize);
+ runtime·memclr(chanbuf(c, c->recvx), c->elemsize);
if(++c->recvx == c->dataqsiz)
c->recvx = 0;
c->qcount--;
runtime·racerelease(chanbuf(c, c->sendx));
runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
}
- c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), cas->sg.elem);
+ runtime·memmove(chanbuf(c, c->sendx), cas->sg.elem, c->elemsize);
if(++c->sendx == c->dataqsiz)
c->sendx = 0;
c->qcount++;
if(cas->receivedp != nil)
*cas->receivedp = true;
if(cas->sg.elem != nil)
- c->elemtype->alg->copy(c->elemsize, cas->sg.elem, sg->elem);
+ runtime·memmove(cas->sg.elem, sg->elem, c->elemsize);
gp = sg->g;
gp->param = sg;
if(sg->releasetime)
if(cas->receivedp != nil)
*cas->receivedp = false;
if(cas->sg.elem != nil)
- c->elemtype->alg->copy(c->elemsize, cas->sg.elem, nil);
+ runtime·memclr(cas->sg.elem, c->elemsize);
if(raceenabled)
runtime·raceacquire(c);
goto retc;
if(debug)
runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
if(sg->elem != nil)
- c->elemtype->alg->copy(c->elemsize, sg->elem, cas->sg.elem);
+ runtime·memmove(sg->elem, cas->sg.elem, c->elemsize);
gp = sg->g;
gp->param = sg;
if(sg->releasetime)
}
func ismapkey(t *_type) bool {
- return **(**uintptr)(unsafe.Pointer(&t.alg.hash)) != nohashcode
+ return goalg(t.alg).hash != nil
}
// Reflect stubs. Called from ../reflect/asm_*.s
Structrnd = sizeof(uintreg),
};
-/*
- * type algorithms - known to compiler
- */
-enum
-{
- AMEM,
- AMEM0,
- AMEM8,
- AMEM16,
- AMEM32,
- AMEM64,
- AMEM128,
- ANOEQ,
- ANOEQ0,
- ANOEQ8,
- ANOEQ16,
- ANOEQ32,
- ANOEQ64,
- ANOEQ128,
- ASTRING,
- AINTER,
- ANILINTER,
- ASLICE,
- AFLOAT32,
- AFLOAT64,
- ACPLX64,
- ACPLX128,
- Amax
-};
-typedef struct Alg Alg;
-struct Alg
-{
- FuncVal* hash;
- FuncVal* equal;
- void (*print)(uintptr, void*);
- void (*copy)(uintptr, void*, void*);
-};
-
-extern Alg runtime·algarray[Amax];
-
byte* runtime·startup_random_data;
uint32 runtime·startup_random_data_len;
-void runtime·get_random_data(byte**, int32*);
enum {
// hashinit wants this many random bytes
HashRandomBytes = 32
};
-void runtime·hashinit(void);
-
-void runtime·memhash(void*, uintptr, uintptr, uintptr);
-void runtime·nohash(void*, uintptr, uintptr, uintptr);
-void runtime·strhash(void*, uintptr, uintptr, uintptr);
-void runtime·interhash(void*, uintptr, uintptr, uintptr);
-void runtime·nilinterhash(void*, uintptr, uintptr, uintptr);
-void runtime·f32hash(void*, uintptr, uintptr, uintptr);
-void runtime·f64hash(void*, uintptr, uintptr, uintptr);
-void runtime·c64hash(void*, uintptr, uintptr, uintptr);
-void runtime·c128hash(void*, uintptr, uintptr, uintptr);
-void runtime·aeshash(void*, uintptr, uintptr, uintptr);
-void runtime·aeshash32(void*, uintptr, uintptr, uintptr);
-void runtime·aeshash64(void*, uintptr, uintptr, uintptr);
-void runtime·aeshashstr(void*, uintptr, uintptr, uintptr);
-
-void runtime·memequal(void*, void*, uintptr, bool);
-void runtime·noequal(void*, void*, uintptr, bool);
-void runtime·strequal(void*, void*, uintptr, bool);
-void runtime·interequal(void*, void*, uintptr, bool);
-void runtime·nilinterequal(void*, void*, uintptr, bool);
-void runtime·f32equal(void*, void*, uintptr, bool);
-void runtime·f64equal(void*, void*, uintptr, bool);
-void runtime·c64equal(void*, void*, uintptr, bool);
-void runtime·c128equal(void*, void*, uintptr, bool);
-void runtime·memequal0(void*, void*, uintptr, bool);
-void runtime·memequal8(void*, void*, uintptr, bool);
-void runtime·memequal16(void*, void*, uintptr, bool);
-void runtime·memequal32(void*, void*, uintptr, bool);
-void runtime·memequal64(void*, void*, uintptr, bool);
-void runtime·memequal128(void*, void*, uintptr, bool);
-
-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·strcopy(uintptr, void*, void*);
-void runtime·algslicecopy(uintptr, void*, void*);
-void runtime·intercopy(uintptr, void*, void*);
-void runtime·nilintercopy(uintptr, void*, void*);
uint32 runtime·readgstatus(G *gp);
void runtime·casgstatus(G*, uint32, uint32);
// in panic.c
func gothrow(s string)
-// Return the Go equivalent of the C Alg structure.
-// TODO: at some point Go will hold the truth for the layout
-// of runtime structures and C will be derived from it (if
-// needed at all). At that point this function can go away.
-type goalgtype struct {
- // function for hashing objects of this type
- // (ptr to object, size, seed) -> hash
- hash func(unsafe.Pointer, uintptr, uintptr) uintptr
- // function for comparing objects of this type
- // (ptr to object A, ptr to object B, size) -> ==?
- equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
-}
-
-func goalg(a *alg) *goalgtype {
- return (*goalgtype)(unsafe.Pointer(a))
-}
-
// noescape hides a pointer from escape analysis. noescape is
// the identity function but escape analysis doesn't think the
// output depends on the input. noescape is inlined and currently
uint8 align;
uint8 fieldAlign;
uint8 kind;
- Alg *alg;
+ void* alg;
// gc stores type info required for garbage collector.
// If (kind&KindGCProg)==0, then gc directly contains sparse GC bitmap
// (no indirection), 4 bits per word.