// AUTO-GENERATED by autogen.sh; DO NOT EDIT

#include "runtime.h"
#include "arch.h"
#include "malloc.h"
#include "defs.h"
#include "go-type.h"
#include "go-string.h"

#line 17 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static Lock proflock; 
#line 22 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
enum { MProf , BProf } ; 
#line 26 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
struct Bucket 
{ 
Bucket *next; 
Bucket *allnext; 
int32 typ; 
#line 33 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
union 
{ 
struct 
{ 
#line 49 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
uintptr allocs; 
uintptr frees; 
uintptr alloc_bytes; 
uintptr free_bytes; 
#line 54 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
uintptr prev_allocs; 
uintptr prev_frees; 
uintptr prev_alloc_bytes; 
uintptr prev_free_bytes; 
#line 59 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
uintptr recent_allocs; 
uintptr recent_frees; 
uintptr recent_alloc_bytes; 
uintptr recent_free_bytes; 
#line 64 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
} ; 
struct 
{ 
int64 count; 
int64 cycles; 
} ; 
} ; 
uintptr hash; 
uintptr size; 
uintptr nstk; 
Location stk[1]; 
} ; 
enum { 
BuckHashSize = 179999 , 
} ; 
static Bucket **buckhash; 
static Bucket *mbuckets; 
static Bucket *bbuckets; 
static uintptr bucketmem; 
#line 85 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static Bucket* 
stkbucket ( int32 typ , uintptr size , Location *stk , int32 nstk , bool alloc ) 
{ 
int32 i , j; 
uintptr h; 
Bucket *b; 
#line 92 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
if ( buckhash == nil ) { 
buckhash = runtime_SysAlloc ( BuckHashSize*sizeof buckhash[0] , &mstats.buckhash_sys ) ; 
if ( buckhash == nil ) 
runtime_throw ( "runtime: cannot allocate memory" ) ; 
} 
#line 99 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
h = 0; 
for ( i=0; i<nstk; i++ ) { 
h += stk[i].pc; 
h += h<<10; 
h ^= h>>6; 
} 
#line 106 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
h += size; 
h += h<<10; 
h ^= h>>6; 
#line 110 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
h += h<<3; 
h ^= h>>11; 
#line 113 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
i = h%BuckHashSize; 
for ( b = buckhash[i]; b; b=b->next ) { 
if ( b->typ == typ && b->hash == h && b->size == size && b->nstk == ( uintptr ) nstk ) { 
for ( j = 0; j < nstk; j++ ) { 
if ( b->stk[j].pc != stk[j].pc || 
b->stk[j].lineno != stk[j].lineno || 
!__go_strings_equal ( b->stk[j].filename , stk[j].filename ) ) 
break; 
} 
if ( j == nstk ) 
return b; 
} 
} 
#line 127 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
if ( !alloc ) 
return nil; 
#line 130 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
b = runtime_persistentalloc ( sizeof *b + nstk*sizeof stk[0] , 0 , &mstats.buckhash_sys ) ; 
bucketmem += sizeof *b + nstk*sizeof stk[0]; 
runtime_memmove ( b->stk , stk , nstk*sizeof stk[0] ) ; 
b->typ = typ; 
b->hash = h; 
b->size = size; 
b->nstk = nstk; 
b->next = buckhash[i]; 
buckhash[i] = b; 
if ( typ == MProf ) { 
b->allnext = mbuckets; 
mbuckets = b; 
} else { 
b->allnext = bbuckets; 
bbuckets = b; 
} 
return b; 
} 
#line 149 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static void 
MProf_GC ( void ) 
{ 
Bucket *b; 
#line 154 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
for ( b=mbuckets; b; b=b->allnext ) { 
b->allocs += b->prev_allocs; 
b->frees += b->prev_frees; 
b->alloc_bytes += b->prev_alloc_bytes; 
b->free_bytes += b->prev_free_bytes; 
#line 160 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
b->prev_allocs = b->recent_allocs; 
b->prev_frees = b->recent_frees; 
b->prev_alloc_bytes = b->recent_alloc_bytes; 
b->prev_free_bytes = b->recent_free_bytes; 
#line 165 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
b->recent_allocs = 0; 
b->recent_frees = 0; 
b->recent_alloc_bytes = 0; 
b->recent_free_bytes = 0; 
} 
} 
#line 173 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_MProf_GC ( void ) 
{ 
runtime_lock ( &proflock ) ; 
MProf_GC ( ) ; 
runtime_unlock ( &proflock ) ; 
} 
#line 182 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_MProf_Malloc ( void *p , uintptr size ) 
{ 
Location stk[32]; 
Bucket *b; 
int32 nstk; 
#line 189 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
nstk = runtime_callers ( 1 , stk , nelem ( stk ) , false ) ; 
runtime_lock ( &proflock ) ; 
b = stkbucket ( MProf , size , stk , nstk , true ) ; 
b->recent_allocs++; 
b->recent_alloc_bytes += size; 
runtime_unlock ( &proflock ) ; 
#line 200 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
runtime_setprofilebucket ( p , b ) ; 
} 
#line 204 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_MProf_Free ( Bucket *b , uintptr size , bool freed ) 
{ 
runtime_lock ( &proflock ) ; 
if ( freed ) { 
b->recent_frees++; 
b->recent_free_bytes += size; 
} else { 
b->prev_frees++; 
b->prev_free_bytes += size; 
} 
runtime_unlock ( &proflock ) ; 
} 
#line 218 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
int64 runtime_blockprofilerate; 
#line 220 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void runtime_SetBlockProfileRate ( intgo ) __asm__ ( GOSYM_PREFIX "runtime.SetBlockProfileRate" ) ; 
#line 222 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_SetBlockProfileRate ( intgo rate ) 
{ 
int64 r; 
#line 227 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
if ( rate <= 0 ) 
r = 0; 
else { 
#line 231 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
r = ( float64 ) rate*runtime_tickspersecond ( ) / ( 1000*1000*1000 ) ; 
if ( r == 0 ) 
r = 1; 
} 
runtime_atomicstore64 ( ( uint64* ) &runtime_blockprofilerate , r ) ; 
} 
#line 238 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_blockevent ( int64 cycles , int32 skip ) 
{ 
int32 nstk; 
int64 rate; 
Location stk[32]; 
Bucket *b; 
#line 246 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
if ( cycles <= 0 ) 
return; 
rate = runtime_atomicload64 ( ( uint64* ) &runtime_blockprofilerate ) ; 
if ( rate <= 0 || ( rate > cycles && runtime_fastrand1 ( ) %rate > cycles ) ) 
return; 
#line 252 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
nstk = runtime_callers ( skip , stk , nelem ( stk ) , false ) ; 
runtime_lock ( &proflock ) ; 
b = stkbucket ( BProf , 0 , stk , nstk , true ) ; 
b->count++; 
b->cycles += cycles; 
runtime_unlock ( &proflock ) ; 
} 
#line 263 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
typedef struct Record Record; 
struct Record { 
int64 alloc_bytes , free_bytes; 
int64 alloc_objects , free_objects; 
uintptr stk[32]; 
} ; 
#line 271 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static void 
record ( Record *r , Bucket *b ) 
{ 
uint32 i; 
#line 276 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
r->alloc_bytes = b->alloc_bytes; 
r->free_bytes = b->free_bytes; 
r->alloc_objects = b->allocs; 
r->free_objects = b->frees; 
for ( i=0; i<b->nstk && i<nelem ( r->stk ) ; i++ ) 
r->stk[i] = b->stk[i].pc; 
for ( ; i<nelem ( r->stk ) ; i++ ) 
r->stk[i] = 0; 
} 
struct runtime_MemProfile_ret {
  intgo n;
  bool ok;
};
struct runtime_MemProfile_ret runtime_MemProfile(Slice p, bool include_inuse_zero) __asm__ (GOSYM_PREFIX "runtime.MemProfile");
struct runtime_MemProfile_ret runtime_MemProfile(Slice p, bool include_inuse_zero)
{
  intgo n;
  bool ok;
#line 286 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"

	Bucket *b;
	Record *r;
	bool clear;

	runtime_lock(&proflock);
	n = 0;
	clear = true;
	for(b=mbuckets; b; b=b->allnext) {
		if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
			n++;
		if(b->allocs != 0 || b->frees != 0)
			clear = false;
	}
	if(clear) {
		// Absolutely no data, suggesting that a garbage collection
		// has not yet happened. In order to allow profiling when
		// garbage collection is disabled from the beginning of execution,
		// accumulate stats as if a GC just happened, and recount buckets.
		MProf_GC();
		MProf_GC();
		n = 0;
		for(b=mbuckets; b; b=b->allnext)
			if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
				n++;
	}
	ok = false;
	if(n <= p.__count) {
		ok = true;
		r = (Record*)p.__values;
		for(b=mbuckets; b; b=b->allnext)
			if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
				record(r++, b);
	}
	runtime_unlock(&proflock);
  {
    struct runtime_MemProfile_ret __ret;
    __ret.n = n;
    __ret.ok = ok;
    return __ret;
  }
}

#line 323 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_MProf_Mark ( struct Workbuf **wbufp , void ( *enqueue1 ) ( struct Workbuf** , Obj ) ) 
{ 
#line 327 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
enqueue1 ( wbufp , ( Obj ) { ( byte* ) &mbuckets , sizeof mbuckets , 0 } ) ; 
enqueue1 ( wbufp , ( Obj ) { ( byte* ) &bbuckets , sizeof bbuckets , 0 } ) ; 
} 
#line 331 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_iterate_memprof ( void ( *callback ) ( Bucket* , uintptr , Location* , uintptr , uintptr , uintptr ) ) 
{ 
Bucket *b; 
#line 336 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
runtime_lock ( &proflock ) ; 
for ( b=mbuckets; b; b=b->allnext ) { 
callback ( b , b->nstk , b->stk , b->size , b->allocs , b->frees ) ; 
} 
runtime_unlock ( &proflock ) ; 
} 
#line 344 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
typedef struct BRecord BRecord; 
struct BRecord { 
int64 count; 
int64 cycles; 
uintptr stk[32]; 
} ; 
struct runtime_BlockProfile_ret {
  intgo n;
  bool ok;
};
struct runtime_BlockProfile_ret runtime_BlockProfile(Slice p) __asm__ (GOSYM_PREFIX "runtime.BlockProfile");
struct runtime_BlockProfile_ret runtime_BlockProfile(Slice p)
{
  intgo n;
  bool ok;
#line 351 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"

	Bucket *b;
	BRecord *r;
	int32 i;

	runtime_lock(&proflock);
	n = 0;
	for(b=bbuckets; b; b=b->allnext)
		n++;
	ok = false;
	if(n <= p.__count) {
		ok = true;
		r = (BRecord*)p.__values;
		for(b=bbuckets; b; b=b->allnext, r++) {
			r->count = b->count;
			r->cycles = b->cycles;
			for(i=0; (uintptr)i<b->nstk && (uintptr)i<nelem(r->stk); i++)
				r->stk[i] = b->stk[i].pc;
			for(; (uintptr)i<nelem(r->stk); i++)
				r->stk[i] = 0;			
		}
	}
	runtime_unlock(&proflock);
  {
    struct runtime_BlockProfile_ret __ret;
    __ret.n = n;
    __ret.ok = ok;
    return __ret;
  }
}

#line 377 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
typedef struct TRecord TRecord; 
struct TRecord { 
uintptr stk[32]; 
} ; 
struct runtime_ThreadCreateProfile_ret {
  intgo n;
  bool ok;
};
struct runtime_ThreadCreateProfile_ret runtime_ThreadCreateProfile(Slice p) __asm__ (GOSYM_PREFIX "runtime.ThreadCreateProfile");
struct runtime_ThreadCreateProfile_ret runtime_ThreadCreateProfile(Slice p)
{
  intgo n;
  bool ok;
#line 382 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"

	TRecord *r;
	M *first, *mp;
	int32 i;
	
	first = runtime_atomicloadp(&runtime_allm);
	n = 0;
	for(mp=first; mp; mp=mp->alllink)
		n++;
	ok = false;
	if(n <= p.__count) {
		ok = true;
		r = (TRecord*)p.__values;
		for(mp=first; mp; mp=mp->alllink) {
			for(i = 0; (uintptr)i < nelem(r->stk); i++) {
				r->stk[i] = mp->createstack[i].pc;
			}
			r++;
		}
	}
  {
    struct runtime_ThreadCreateProfile_ret __ret;
    __ret.n = n;
    __ret.ok = ok;
    return __ret;
  }
}
intgo runtime_Stack(Slice b, bool all) __asm__ (GOSYM_PREFIX "runtime.Stack");
intgo runtime_Stack(Slice b, bool all)
{
  intgo n;
#line 404 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"

	byte *pc, *sp;
	bool enablegc;
	
	sp = runtime_getcallersp(&b);
	pc = (byte*)(uintptr)runtime_getcallerpc(&b);

	if(all) {
		runtime_semacquire(&runtime_worldsema, false);
		runtime_m()->gcing = 1;
		runtime_stoptheworld();
		enablegc = mstats.enablegc;
		mstats.enablegc = false;
	}

	if(b.__count == 0)
		n = 0;
	else{
		G* g = runtime_g();
		g->writebuf = (byte*)b.__values;
		g->writenbuf = b.__count;
		USED(pc);
		USED(sp);
		runtime_goroutineheader(g);
		runtime_traceback();
		runtime_printcreatedby(g);
		if(all)
			runtime_tracebackothers(g);
		n = b.__count - g->writenbuf;
		g->writebuf = nil;
		g->writenbuf = 0;
	}
	
	if(all) {
		runtime_m()->gcing = 0;
		mstats.enablegc = enablegc;
		runtime_semrelease(&runtime_worldsema);
		runtime_starttheworld();
	}
return n;
}

#line 445 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static void 
saveg ( G *gp , TRecord *r ) 
{ 
int32 n , i; 
Location locstk[nelem ( r->stk ) ]; 
#line 451 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
if ( gp == runtime_g ( ) ) { 
n = runtime_callers ( 0 , locstk , nelem ( r->stk ) , false ) ; 
for ( i = 0; i < n; i++ ) 
r->stk[i] = locstk[i].pc; 
} 
else { 
#line 458 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
n = 0; 
} 
if ( ( size_t ) n < nelem ( r->stk ) ) 
r->stk[n] = 0; 
} 
struct runtime_GoroutineProfile_ret {
  intgo n;
  bool ok;
};
struct runtime_GoroutineProfile_ret runtime_GoroutineProfile(Slice b) __asm__ (GOSYM_PREFIX "runtime.GoroutineProfile");
struct runtime_GoroutineProfile_ret runtime_GoroutineProfile(Slice b)
{
  intgo n;
  bool ok;
#line 464 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"

	uintptr i;
	TRecord *r;
	G *gp;
	
	ok = false;
	n = runtime_gcount();
	if(n <= b.__count) {
		runtime_semacquire(&runtime_worldsema, false);
		runtime_m()->gcing = 1;
		runtime_stoptheworld();

		n = runtime_gcount();
		if(n <= b.__count) {
			G* g = runtime_g();
			ok = true;
			r = (TRecord*)b.__values;
			saveg(g, r++);
			for(i = 0; i < runtime_allglen; i++) {
				gp = runtime_allg[i];
				if(gp == g || gp->status == Gdead)
					continue;
				saveg(gp, r++);
			}
		}
	
		runtime_m()->gcing = 0;
		runtime_semrelease(&runtime_worldsema);
		runtime_starttheworld();
	}
  {
    struct runtime_GoroutineProfile_ret __ret;
    __ret.n = n;
    __ret.ok = ok;
    return __ret;
  }
}

#line 498 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static Lock tracelock; 
#line 500 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
static const char* 
typeinfoname ( int32 typeinfo ) 
{ 
if ( typeinfo == TypeInfo_SingleObject ) 
return "single object" ; 
else if ( typeinfo == TypeInfo_Array ) 
return "array" ; 
else if ( typeinfo == TypeInfo_Chan ) 
return "channel" ; 
runtime_throw ( "typinfoname: unknown type info" ) ; 
return nil; 
} 
#line 513 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_tracealloc ( void *p , uintptr size , uintptr typ ) 
{ 
const char *name; 
Type *type; 
#line 519 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
runtime_lock ( &tracelock ) ; 
runtime_m ( ) ->traceback = 2; 
type = ( Type* ) ( typ & ~3 ) ; 
name = typeinfoname ( typ & 3 ) ; 
if ( type == nil ) 
runtime_printf ( "tracealloc(%p, %p, %s)\n" , p , size , name ) ; 
else 
runtime_printf ( "tracealloc(%p, %p, %s of %S)\n" , p , size , name , *type->__reflection ) ; 
if ( runtime_m ( ) ->curg == nil || runtime_g ( ) == runtime_m ( ) ->curg ) { 
runtime_goroutineheader ( runtime_g ( ) ) ; 
runtime_traceback ( ) ; 
} else { 
runtime_goroutineheader ( runtime_m ( ) ->curg ) ; 
runtime_traceback ( ) ; 
} 
runtime_printf ( "\n" ) ; 
runtime_m ( ) ->traceback = 0; 
runtime_unlock ( &tracelock ) ; 
} 
#line 539 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_tracefree ( void *p , uintptr size ) 
{ 
runtime_lock ( &tracelock ) ; 
runtime_m ( ) ->traceback = 2; 
runtime_printf ( "tracefree(%p, %p)\n" , p , size ) ; 
runtime_goroutineheader ( runtime_g ( ) ) ; 
runtime_traceback ( ) ; 
runtime_printf ( "\n" ) ; 
runtime_m ( ) ->traceback = 0; 
runtime_unlock ( &tracelock ) ; 
} 
#line 552 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
void 
runtime_tracegc ( void ) 
{ 
runtime_lock ( &tracelock ) ; 
runtime_m ( ) ->traceback = 2; 
runtime_printf ( "tracegc()\n" ) ; 
#line 559 "../../../gcc-5.1.0/libgo/runtime/mprof.goc"
runtime_tracebackothers ( runtime_g ( ) ) ; 
runtime_printf ( "end tracegc\n" ) ; 
runtime_printf ( "\n" ) ; 
runtime_m ( ) ->traceback = 0; 
runtime_unlock ( &tracelock ) ; 
} 