]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert type algorithms to Go
authorDmitriy Vyukov <dvyukov@google.com>
Sat, 30 Aug 2014 04:40:56 +0000 (08:40 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Sat, 30 Aug 2014 04:40:56 +0000 (08:40 +0400)
Actually it mostly deletes code -- alg.print and alg.copy go away.
There was only one usage of alg.print for debug purposes.
Alg.copy is used in chan.goc, but Keith replaces them with
memcopy during conversion, so alg.copy is not needed as well.
Converting them would be significant amount of work
for no visible benefit.

LGTM=crawshaw, rsc, khr
R=golang-codereviews, crawshaw, khr
CC=golang-codereviews, rsc
https://golang.org/cl/139930044

12 files changed:
src/cmd/gc/reflect.c
src/pkg/runtime/alg.go
src/pkg/runtime/alg.goc [deleted file]
src/pkg/runtime/asm_386.s
src/pkg/runtime/asm_amd64.s
src/pkg/runtime/asm_amd64p32.s
src/pkg/runtime/asm_arm.s
src/pkg/runtime/chan.goc
src/pkg/runtime/hashmap.go
src/pkg/runtime/runtime.h
src/pkg/runtime/stubs.go
src/pkg/runtime/type.h

index 05bf2d6521d2456ed17a5797d6e4a4d9af9db4f6..f227054cafe2efcec80f0fe1a37c772ecaf51bba 100644 (file)
@@ -724,7 +724,7 @@ dcommontype(Sym *s, int ot, Type *t)
        if(ot != 0)
                fatal("dcommontype %d", ot);
 
-       sizeofAlg = 4*widthptr;
+       sizeofAlg = 2*widthptr;
        if(algarray == nil)
                algarray = pkglookup("algarray", runtimepkg);
        alg = algtype(t);
@@ -1242,7 +1242,6 @@ dalgsym(Type *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).
@@ -1261,24 +1260,10 @@ dalgsym(Type *t)
        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;
index 909612454d599d3a44a6e76897de915f21457baa..01fbc931e57a0a8d009e0a41e900682cf55ab5ba 100644 (file)
@@ -11,6 +11,7 @@ const (
        c1 = uintptr((8-ptrSize)/4*3267000013 + (ptrSize-4)/4*23344194077549503)
 )
 
+// type algorithms - known to compiler
 const (
        alg_MEM = iota
        alg_MEM0
@@ -37,9 +38,43 @@ const (
        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
@@ -48,7 +83,7 @@ func aeshash64(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)
        }
 
@@ -61,8 +96,8 @@ func memhash(p unsafe.Pointer, s, h uintptr) uintptr {
        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
@@ -70,54 +105,49 @@ func strhash(a *string, s, h uintptr) uintptr {
 // 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) {
@@ -127,15 +157,14 @@ func interhash(a *iface, s, h uintptr) uintptr {
        }
 }
 
-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) {
@@ -206,9 +235,7 @@ func efaceeq(p, q interface{}) bool {
                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) {
@@ -230,9 +257,7 @@ func ifaceeq(p, q interface {
        }
        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) {
@@ -241,40 +266,36 @@ func ifaceeq(p, q interface {
        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
@@ -282,3 +303,50 @@ func memclrBytes(b []byte) {
        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)))
+                       }
+               }
+       }
+}
diff --git a/src/pkg/runtime/alg.goc b/src/pkg/runtime/alg.goc
deleted file mode 100644 (file)
index 0c3b3cd..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-// 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)));
-                       }
-               }
-       }
-}
index b40b75521a1b5b5cda2865ad479a9d2aec5c2c33..d80020ccd650a6c7f06e02dccb83267705cf1aae 100644 (file)
@@ -92,7 +92,6 @@ ok:
        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
index 01ec391153071409f0e9e0f0953c807888d1f4ae..bc17c68f3d3bbbd463d46acc9f05484c7f3105e9 100644 (file)
@@ -88,7 +88,6 @@ ok:
        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
index 9073144cffd86f83b362d160a39a2df0717121de..82c0d77cdd4afa1f56473288a6827c7bf3ec754f 100644 (file)
@@ -68,7 +68,6 @@ ok:
        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
index 702eda61bd1c10f1dc61de4688176060df72d8b9..f8447d7940dd3001e2f9b52a881e676e73bf14ad 100644 (file)
@@ -64,7 +64,6 @@ nocgo:
        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
index a4a0d1d9baec7efb6f4429250538a8f0f0a2faf5..383351179d7f5f1149b5d2e3fa23f4a72a8b61a0 100644 (file)
@@ -51,12 +51,6 @@ chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
                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);
 
@@ -101,7 +95,7 @@ chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
                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);
@@ -156,7 +150,7 @@ asynch:
                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++;
@@ -240,7 +234,7 @@ chanrecv(ChanType *t, Hchan* c, byte *ep, bool block, bool *received)
                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)
@@ -304,8 +298,8 @@ asynch:
        }
 
        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--;
@@ -328,7 +322,7 @@ asynch:
 
 closed:
        if(ep != nil)
-               c->elemtype->alg->copy(c->elemsize, ep, nil);
+               runtime·memclr(ep, c->elemsize);
        if(received != nil)
                *received = false;
        if(raceenabled)
@@ -842,8 +836,8 @@ asyncrecv:
        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--;
@@ -866,7 +860,7 @@ asyncsend:
                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++;
@@ -895,7 +889,7 @@ syncrecv:
        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)
@@ -909,7 +903,7 @@ rclose:
        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;
@@ -924,7 +918,7 @@ syncsend:
        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)
index 1d1e70848728ea816a278798a7649937e2d27100..309e26db96f11b1ab8828a0dc7653ee5d64e741e 100644 (file)
@@ -896,7 +896,7 @@ func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
 }
 
 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
index 3f03a4da0668c9eb3364f2d63b4585467b44e624..80366a549dce4b2fc6283aaf8c5bdb242d8f4054 100644 (file)
@@ -606,101 +606,13 @@ enum {
        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);
index 90d43ea713340ca900ad0f44196d4581912bbc0f..9ad400639d75afed4c623de43ed25d8a8059993a 100644 (file)
@@ -131,23 +131,6 @@ var noequalcode uintptr
 // 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
index 1da37323eba6480a4a535f11ba9955a8735bbb71..de82e886f29be96658effe9ab2c41d8b15702d3e 100644 (file)
@@ -21,7 +21,7 @@ struct Type
        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.