mirror of
https://github.com/golang/go
synced 2024-11-19 13:14:42 -07:00
runtime: generate type info for chans
LGTM=khr R=golang-codereviews, khr CC=golang-codereviews, khr https://golang.org/cl/115280043
This commit is contained in:
parent
fe3ee5741d
commit
dfa5a99ebb
@ -9,16 +9,40 @@ package runtime
|
|||||||
#include "race.h"
|
#include "race.h"
|
||||||
#include "malloc.h"
|
#include "malloc.h"
|
||||||
#include "chan.h"
|
#include "chan.h"
|
||||||
|
#include "mgc0.h"
|
||||||
|
#include "typekind.h"
|
||||||
#include "../../cmd/ld/textflag.h"
|
#include "../../cmd/ld/textflag.h"
|
||||||
|
|
||||||
uint32 runtime·Hchansize = sizeof(Hchan);
|
|
||||||
|
|
||||||
static void dequeueg(WaitQ*);
|
static void dequeueg(WaitQ*);
|
||||||
static SudoG* dequeue(WaitQ*);
|
static SudoG* dequeue(WaitQ*);
|
||||||
static void enqueue(WaitQ*, SudoG*);
|
static void enqueue(WaitQ*, SudoG*);
|
||||||
static void destroychan(Hchan*);
|
|
||||||
static void racesync(Hchan*, SudoG*);
|
static void racesync(Hchan*, SudoG*);
|
||||||
|
|
||||||
|
static Type hchanType;
|
||||||
|
static String hchanStr;
|
||||||
|
|
||||||
|
void
|
||||||
|
runtime·chaninit(void)
|
||||||
|
{
|
||||||
|
int32 i, off;
|
||||||
|
byte *mask;
|
||||||
|
|
||||||
|
// Generate (bare minimum) type descriptor for Hchan.
|
||||||
|
hchanType.size = sizeof(Hchan);
|
||||||
|
hchanStr = runtime·gostringnocopy((byte*)"chan");
|
||||||
|
hchanType.string = &hchanStr;
|
||||||
|
// Hchan has only one interesting pointer -- buf.
|
||||||
|
off = offsetof(Hchan, buf)/PtrSize*gcBits;
|
||||||
|
if(off%8)
|
||||||
|
runtime·throw("makechan: unaligned buffer");
|
||||||
|
if(off+8 >= sizeof(hchanType.gc)*8)
|
||||||
|
runtime·throw("makechan: gc mask does not fit");
|
||||||
|
mask = (byte*)hchanType.gc;
|
||||||
|
for(i = 0; i < off/8; i++)
|
||||||
|
mask[i] = (BitsScalar<<2) | (BitsScalar<<6);
|
||||||
|
mask[off/8] = (BitsPointer<<2) | (BitsDead<<6);
|
||||||
|
}
|
||||||
|
|
||||||
static Hchan*
|
static Hchan*
|
||||||
makechan(ChanType *t, int64 hint)
|
makechan(ChanType *t, int64 hint)
|
||||||
{
|
{
|
||||||
@ -36,8 +60,17 @@ makechan(ChanType *t, int64 hint)
|
|||||||
if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem - sizeof(*c)) / elem->size))
|
if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem - sizeof(*c)) / elem->size))
|
||||||
runtime·panicstring("makechan: size out of range");
|
runtime·panicstring("makechan: size out of range");
|
||||||
|
|
||||||
|
if((elem->kind&KindNoPointers) || hint == 0) {
|
||||||
// allocate memory in one call
|
// allocate memory in one call
|
||||||
c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, nil, 0);
|
c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, nil, FlagNoScan);
|
||||||
|
if(hint > 0 && elem->size != 0)
|
||||||
|
c->buf = (byte*)(c+1);
|
||||||
|
else
|
||||||
|
c->buf = (byte*)c; // race detector uses this location for synchronization
|
||||||
|
} else {
|
||||||
|
c = (Hchan*)runtime·cnew(&hchanType);
|
||||||
|
c->buf = runtime·cnewarray(elem, hint);
|
||||||
|
}
|
||||||
c->elemsize = elem->size;
|
c->elemsize = elem->size;
|
||||||
c->elemtype = elem;
|
c->elemtype = elem;
|
||||||
c->dataqsiz = hint;
|
c->dataqsiz = hint;
|
||||||
|
@ -26,14 +26,12 @@ struct WaitQ
|
|||||||
SudoG* last;
|
SudoG* last;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The garbage collector is assuming that Hchan can only contain pointers into the stack
|
|
||||||
// and cannot contain pointers into the heap.
|
|
||||||
struct Hchan
|
struct Hchan
|
||||||
{
|
{
|
||||||
uintgo qcount; // total data in the q
|
uintgo qcount; // total data in the q
|
||||||
uintgo dataqsiz; // size of the circular q
|
uintgo dataqsiz; // size of the circular q
|
||||||
|
byte* buf;
|
||||||
uint16 elemsize;
|
uint16 elemsize;
|
||||||
uint16 pad; // ensures proper alignment of the buffer that follows Hchan in memory
|
|
||||||
bool closed;
|
bool closed;
|
||||||
Type* elemtype; // element type
|
Type* elemtype; // element type
|
||||||
uintgo sendx; // send index
|
uintgo sendx; // send index
|
||||||
@ -45,7 +43,7 @@ struct Hchan
|
|||||||
|
|
||||||
// Buffer follows Hchan immediately in memory.
|
// Buffer follows Hchan immediately in memory.
|
||||||
// chanbuf(c, i) is pointer to the i'th slot in the buffer.
|
// chanbuf(c, i) is pointer to the i'th slot in the buffer.
|
||||||
#define chanbuf(c, i) ((byte*)((c)+1)+(uintptr)(c)->elemsize*(i))
|
#define chanbuf(c, i) ((byte*)((c)->buf)+(uintptr)(c)->elemsize*(i))
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -158,6 +158,7 @@ runtime·schedinit(void)
|
|||||||
runtime·symtabinit();
|
runtime·symtabinit();
|
||||||
runtime·stackinit();
|
runtime·stackinit();
|
||||||
runtime·mallocinit();
|
runtime·mallocinit();
|
||||||
|
runtime·chaninit();
|
||||||
mcommoninit(g->m);
|
mcommoninit(g->m);
|
||||||
|
|
||||||
// Initialize the itable value for newErrorCString,
|
// Initialize the itable value for newErrorCString,
|
||||||
|
@ -862,6 +862,7 @@ void runtime·shrinkstack(G*);
|
|||||||
MCache* runtime·allocmcache(void);
|
MCache* runtime·allocmcache(void);
|
||||||
void runtime·freemcache(MCache*);
|
void runtime·freemcache(MCache*);
|
||||||
void runtime·mallocinit(void);
|
void runtime·mallocinit(void);
|
||||||
|
void runtime·chaninit(void);
|
||||||
bool runtime·ifaceeq_c(Iface, Iface);
|
bool runtime·ifaceeq_c(Iface, Iface);
|
||||||
bool runtime·efaceeq_c(Eface, Eface);
|
bool runtime·efaceeq_c(Eface, Eface);
|
||||||
uintptr runtime·ifacehash(Iface, uintptr);
|
uintptr runtime·ifacehash(Iface, uintptr);
|
||||||
|
Loading…
Reference in New Issue
Block a user