2011-12-05 07:40:22 -07:00
|
|
|
// 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.
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
package runtime
|
2011-12-05 07:40:22 -07:00
|
|
|
#include "runtime.h"
|
2011-12-12 20:22:09 -07:00
|
|
|
#include "type.h"
|
2013-08-12 14:47:18 -06:00
|
|
|
#include "../../cmd/ld/textflag.h"
|
2011-12-05 07:40:22 -07:00
|
|
|
|
2012-06-13 13:52:32 -06:00
|
|
|
#define M0 (sizeof(uintptr)==4 ? 2860486313UL : 33054211828000289ULL)
|
|
|
|
#define M1 (sizeof(uintptr)==4 ? 3267000013UL : 23344194077549503ULL)
|
|
|
|
|
2013-03-15 11:46:34 -06:00
|
|
|
static bool use_aeshash;
|
|
|
|
|
2011-12-05 07:40:22 -07:00
|
|
|
/*
|
|
|
|
* map and chan helpers for
|
|
|
|
* dealing with unknown types
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
runtime·memhash(uintptr *h, uintptr s, void *a)
|
|
|
|
{
|
|
|
|
byte *b;
|
|
|
|
uintptr hash;
|
2014-03-14 14:33:55 -06:00
|
|
|
if(!NaCl && use_aeshash) {
|
2013-03-15 11:46:34 -06:00
|
|
|
runtime·aeshash(h, s, a);
|
|
|
|
return;
|
|
|
|
}
|
2011-12-05 07:40:22 -07:00
|
|
|
|
|
|
|
b = a;
|
2013-01-04 08:53:42 -07:00
|
|
|
hash = M0 ^ *h;
|
2011-12-05 07:40:22 -07:00
|
|
|
while(s > 0) {
|
2012-06-13 13:52:32 -06:00
|
|
|
hash = (hash ^ *b) * M1;
|
2011-12-05 07:40:22 -07:00
|
|
|
b++;
|
|
|
|
s--;
|
|
|
|
}
|
2013-01-04 08:53:42 -07:00
|
|
|
*h = hash;
|
2011-12-05 07:40:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·memequal(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
if(a == b) {
|
|
|
|
*eq = 1;
|
|
|
|
return;
|
|
|
|
}
|
2013-04-02 17:26:15 -06:00
|
|
|
*eq = runtime·memeq(a, b, s);
|
2011-12-05 07:40:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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:
|
2011-12-12 20:22:09 -07:00
|
|
|
v = *(uint32*)a;
|
2011-12-05 07:40:22 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2012-01-19 23:32:55 -07:00
|
|
|
void
|
|
|
|
runtime·memequal0(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
USED(a);
|
|
|
|
USED(b);
|
|
|
|
*eq = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·memcopy0(uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
USED(a);
|
|
|
|
USED(b);
|
|
|
|
}
|
|
|
|
|
2011-12-05 07:40:22 -07:00
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
2012-01-26 14:25:07 -07:00
|
|
|
void
|
|
|
|
runtime·f32equal(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
*eq = *(float32*)a == *(float32*)b;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·f64equal(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
*eq = *(float64*)a == *(float64*)b;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·c64equal(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
Complex64 *ca, *cb;
|
|
|
|
|
|
|
|
USED(s);
|
|
|
|
ca = a;
|
|
|
|
cb = b;
|
|
|
|
*eq = ca->real == cb->real && ca->imag == cb->imag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·c128equal(bool *eq, uintptr s, void *a, void *b)
|
|
|
|
{
|
|
|
|
Complex128 *ca, *cb;
|
|
|
|
|
|
|
|
USED(s);
|
|
|
|
ca = a;
|
|
|
|
cb = b;
|
|
|
|
*eq = ca->real == cb->real && ca->imag == cb->imag;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Because NaN != NaN, a map can contain any
|
|
|
|
// number of (mostly useless) entries keyed with NaNs.
|
|
|
|
// To avoid long hash chains, we assign a random number
|
|
|
|
// as the hash value for a NaN.
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·f32hash(uintptr *h, uintptr s, void *a)
|
|
|
|
{
|
|
|
|
uintptr hash;
|
|
|
|
float32 f;
|
|
|
|
|
|
|
|
USED(s);
|
|
|
|
f = *(float32*)a;
|
|
|
|
if(f == 0)
|
|
|
|
hash = 0; // +0, -0
|
|
|
|
else if(f != f)
|
|
|
|
hash = runtime·fastrand1(); // any kind of NaN
|
|
|
|
else
|
|
|
|
hash = *(uint32*)a;
|
2012-06-13 13:52:32 -06:00
|
|
|
*h = (*h ^ hash ^ M0) * M1;
|
2012-01-26 14:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·f64hash(uintptr *h, uintptr s, void *a)
|
|
|
|
{
|
|
|
|
uintptr hash;
|
|
|
|
float64 f;
|
|
|
|
uint64 u;
|
|
|
|
|
|
|
|
USED(s);
|
2012-01-30 09:10:59 -07:00
|
|
|
f = *(float64*)a;
|
2012-01-26 14:25:07 -07:00
|
|
|
if(f == 0)
|
|
|
|
hash = 0; // +0, -0
|
|
|
|
else if(f != f)
|
|
|
|
hash = runtime·fastrand1(); // any kind of NaN
|
|
|
|
else {
|
|
|
|
u = *(uint64*)a;
|
|
|
|
if(sizeof(uintptr) == 4)
|
2012-06-13 13:52:32 -06:00
|
|
|
hash = ((uint32)(u>>32) * M1) ^ (uint32)u;
|
2012-01-26 14:25:07 -07:00
|
|
|
else
|
|
|
|
hash = u;
|
|
|
|
}
|
2012-06-13 13:52:32 -06:00
|
|
|
*h = (*h ^ hash ^ M0) * M1;
|
2012-01-26 14:25:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·c64hash(uintptr *h, uintptr s, void *a)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
runtime·f32hash(h, 0, a);
|
|
|
|
runtime·f32hash(h, 0, (float32*)a+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·c128hash(uintptr *h, uintptr s, void *a)
|
|
|
|
{
|
|
|
|
USED(s);
|
|
|
|
runtime·f64hash(h, 0, a);
|
|
|
|
runtime·f64hash(h, 0, (float64*)a+1);
|
|
|
|
}
|
|
|
|
|
2011-12-05 07:40:22 -07:00
|
|
|
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)
|
|
|
|
{
|
2012-09-24 12:58:34 -06:00
|
|
|
intgo alen;
|
2013-04-02 17:26:15 -06:00
|
|
|
byte *s1, *s2;
|
2011-12-05 07:40:22 -07:00
|
|
|
|
|
|
|
USED(s);
|
|
|
|
alen = ((String*)a)->len;
|
|
|
|
if(alen != ((String*)b)->len) {
|
|
|
|
*eq = false;
|
|
|
|
return;
|
|
|
|
}
|
2013-04-02 17:26:15 -06:00
|
|
|
s1 = ((String*)a)->str;
|
|
|
|
s2 = ((String*)b)->str;
|
|
|
|
if(s1 == s2) {
|
2012-08-05 13:35:41 -06:00
|
|
|
*eq = true;
|
|
|
|
return;
|
|
|
|
}
|
2013-04-02 17:26:15 -06:00
|
|
|
*eq = runtime·memeq(s1, s2, alen);
|
2011-12-05 07:40:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2013-01-04 08:53:42 -07:00
|
|
|
*h = runtime·ifacehash(*(Iface*)a, *h ^ M0) * M1;
|
2011-12-05 07:40:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2013-01-04 08:53:42 -07:00
|
|
|
*h = runtime·efacehash(*(Eface*)a, *h ^ M0) * M1;
|
2011-12-05 07:40:22 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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 },
|
2012-01-26 14:25:07 -07:00
|
|
|
[AFLOAT32] { runtime·f32hash, runtime·f32equal, runtime·memprint, runtime·memcopy },
|
|
|
|
[AFLOAT64] { runtime·f64hash, runtime·f64equal, runtime·memprint, runtime·memcopy },
|
|
|
|
[ACPLX64] { runtime·c64hash, runtime·c64equal, runtime·memprint, runtime·memcopy },
|
|
|
|
[ACPLX128] { runtime·c128hash, runtime·c128equal, runtime·memprint, runtime·memcopy },
|
2012-01-19 23:32:55 -07:00
|
|
|
[AMEM0] { runtime·memhash, runtime·memequal0, runtime·memprint, runtime·memcopy0 },
|
2011-12-05 07:40:22 -07:00
|
|
|
[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 },
|
2012-01-19 23:32:55 -07:00
|
|
|
[ANOEQ0] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy0 },
|
2011-12-05 07:40:22 -07:00
|
|
|
[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 },
|
|
|
|
};
|
|
|
|
|
2011-12-12 20:22:09 -07:00
|
|
|
// Runtime helpers.
|
|
|
|
|
2013-03-12 11:47:44 -06:00
|
|
|
// used in asm_{386,amd64}.s
|
|
|
|
byte runtime·aeskeysched[HashRandomBytes];
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·hashinit(void)
|
|
|
|
{
|
2014-03-14 14:33:55 -06:00
|
|
|
if(NaCl)
|
|
|
|
return;
|
|
|
|
|
2013-03-12 11:47:44 -06:00
|
|
|
// 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;
|
2013-03-15 11:46:34 -06:00
|
|
|
use_aeshash = true;
|
2013-03-12 11:47:44 -06:00
|
|
|
runtime·algarray[AMEM].hash = runtime·aeshash;
|
|
|
|
runtime·algarray[AMEM8].hash = runtime·aeshash;
|
|
|
|
runtime·algarray[AMEM16].hash = runtime·aeshash;
|
|
|
|
runtime·algarray[AMEM32].hash = runtime·aeshash32;
|
|
|
|
runtime·algarray[AMEM64].hash = runtime·aeshash64;
|
|
|
|
runtime·algarray[AMEM128].hash = runtime·aeshash;
|
|
|
|
runtime·algarray[ASTRING].hash = runtime·aeshashstr;
|
|
|
|
|
|
|
|
// 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)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-12 20:22:09 -07:00
|
|
|
// func equal(t *Type, x T, y T) (ret bool)
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
2011-12-12 20:22:09 -07:00
|
|
|
void
|
|
|
|
runtime·equal(Type *t, ...)
|
|
|
|
{
|
|
|
|
byte *x, *y;
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
bool *ret;
|
2011-12-12 20:22:09 -07:00
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
x = (byte*)ROUND((uintptr)(&t+1), t->align);
|
2012-08-06 19:49:56 -06:00
|
|
|
y = x + t->size;
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
ret = (bool*)ROUND((uintptr)(y+t->size), Structrnd);
|
2014-02-26 09:28:26 -07:00
|
|
|
t->alg->equal(ret, t->size, x, y);
|
2011-12-12 20:22:09 -07:00
|
|
|
}
|
2013-09-06 17:23:46 -06:00
|
|
|
|
2014-02-06 18:43:22 -07:00
|
|
|
// Testing adapter for memclr
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func memclrBytes(s Slice) {
|
2014-02-06 18:43:22 -07:00
|
|
|
runtime·memclr(s.array, s.len);
|
|
|
|
}
|
|
|
|
|
2013-09-06 17:23:46 -06:00
|
|
|
// Testing adapters for hash quality tests (see hash_test.go)
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func haveGoodHash() (res bool) {
|
2013-09-06 17:23:46 -06:00
|
|
|
res = use_aeshash;
|
|
|
|
}
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
|
|
|
|
func stringHash(s String, seed uintptr) (res uintptr) {
|
2013-09-06 17:23:46 -06:00
|
|
|
runtime·algarray[ASTRING].hash(&seed, sizeof(String), &s);
|
|
|
|
res = seed;
|
|
|
|
}
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
|
|
|
|
func bytesHash(s Slice, seed uintptr) (res uintptr) {
|
2013-09-06 17:23:46 -06:00
|
|
|
runtime·algarray[AMEM].hash(&seed, s.len, s.array);
|
|
|
|
res = seed;
|
|
|
|
}
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
|
|
|
|
func int32Hash(i uint32, seed uintptr) (res uintptr) {
|
2013-09-06 17:23:46 -06:00
|
|
|
runtime·algarray[AMEM32].hash(&seed, sizeof(uint32), &i);
|
|
|
|
res = seed;
|
|
|
|
}
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
|
|
|
|
func int64Hash(i uint64, seed uintptr) (res uintptr) {
|
2013-09-06 17:23:46 -06:00
|
|
|
runtime·algarray[AMEM64].hash(&seed, sizeof(uint64), &i);
|
|
|
|
res = seed;
|
|
|
|
}
|