// auto generated by go tool dist
// goos=openbsd goarch=amd64

#include "runtime.h"
#include "arch_GOARCH.h"
#include "malloc.h"
#include "type.h"
#include "typekind.h"
#include "race.h"
#include "stack.h"
#include "../../cmd/ld/textflag.h"
#pragma dataflag NOPTR

#line 21 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
MHeap runtime·mheap; 
#line 23 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
int32 runtime·checking; 
#line 25 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
extern MStats mstats; 
#line 27 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
extern volatile intgo runtime·MemProfileRate; 
#line 33 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·mallocgc ( uintptr size , uintptr typ , uint32 flag ) 
{ 
int32 sizeclass; 
intgo rate; 
MCache *c; 
MCacheList *l; 
uintptr npages; 
MSpan *s; 
MLink *v; 
#line 44 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( size == 0 ) { 
#line 48 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
return &runtime·zerobase; 
} 
if ( m->mallocing ) 
runtime·throw ( "malloc/free - deadlock" ) ; 
#line 54 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
m->locks++; 
m->mallocing = 1; 
#line 57 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( DebugTypeAtBlockEnd ) 
size += sizeof ( uintptr ) ; 
#line 60 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
c = m->mcache; 
if ( size <= MaxSmallSize ) { 
#line 64 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( size <= 1024-8 ) 
sizeclass = runtime·size_to_class8[ ( size+7 ) >>3]; 
else 
sizeclass = runtime·size_to_class128[ ( size-1024+127 ) >> 7]; 
size = runtime·class_to_size[sizeclass]; 
l = &c->list[sizeclass]; 
if ( l->list == nil ) 
runtime·MCache_Refill ( c , sizeclass ) ; 
v = l->list; 
l->list = v->next; 
l->nlist--; 
if ( ! ( flag & FlagNoZero ) ) { 
v->next = nil; 
#line 78 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( size > sizeof ( uintptr ) && ( ( uintptr* ) v ) [1] != 0 ) 
runtime·memclr ( ( byte* ) v , size ) ; 
} 
c->local_cachealloc += size; 
} else { 
#line 86 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
npages = size >> PageShift; 
if ( ( size & PageMask ) != 0 ) 
npages++; 
s = runtime·MHeap_Alloc ( &runtime·mheap , npages , 0 , 1 , ! ( flag & FlagNoZero ) ) ; 
if ( s == nil ) 
runtime·throw ( "out of memory" ) ; 
s->limit = ( byte* ) ( s->start<<PageShift ) + size; 
size = npages<<PageShift; 
v = ( void* ) ( s->start << PageShift ) ; 
#line 97 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·markspan ( v , 0 , 0 , true ) ; 
} 
#line 100 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( ! ( flag & FlagNoGC ) ) 
runtime·markallocated ( v , size , ( flag&FlagNoScan ) != 0 ) ; 
#line 103 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( DebugTypeAtBlockEnd ) 
* ( uintptr* ) ( ( uintptr ) v+size-sizeof ( uintptr ) ) = typ; 
#line 108 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( UseSpanType && ! ( flag & FlagNoScan ) && typ != 0 ) { 
uintptr *buf , i; 
#line 111 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
buf = m->settype_buf; 
i = m->settype_bufsize; 
buf[i++] = ( uintptr ) v; 
buf[i++] = typ; 
m->settype_bufsize = i; 
} 
#line 118 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
m->mallocing = 0; 
if ( UseSpanType && ! ( flag & FlagNoScan ) && typ != 0 && m->settype_bufsize == nelem ( m->settype_buf ) ) 
runtime·settype_flush ( m ) ; 
m->locks--; 
if ( m->locks == 0 && g->preempt ) 
g->stackguard0 = StackPreempt; 
#line 125 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( ! ( flag & FlagNoProfiling ) && ( rate = runtime·MemProfileRate ) > 0 ) { 
if ( size >= rate ) 
goto profile; 
if ( m->mcache->next_sample > size ) 
m->mcache->next_sample -= size; 
else { 
#line 133 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( rate > 0x3fffffff ) 
rate = 0x3fffffff; 
m->mcache->next_sample = runtime·fastrand1 ( ) % ( 2*rate ) ; 
profile: 
runtime·setblockspecial ( v , true ) ; 
runtime·MProf_Malloc ( v , size ) ; 
} 
} 
#line 142 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( ! ( flag & FlagNoInvokeGC ) && mstats.heap_alloc >= mstats.next_gc ) 
runtime·gc ( 0 ) ; 
#line 145 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( raceenabled ) 
runtime·racemalloc ( v , size ) ; 
return v; 
} 
#line 150 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·malloc ( uintptr size ) 
{ 
return runtime·mallocgc ( size , 0 , FlagNoInvokeGC ) ; 
} 
#line 157 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void 
runtime·free ( void *v ) 
{ 
int32 sizeclass; 
MSpan *s; 
MCache *c; 
uint32 prof; 
uintptr size; 
#line 166 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( v == nil ) 
return; 
#line 172 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( m->mallocing ) 
runtime·throw ( "malloc/free - deadlock" ) ; 
m->mallocing = 1; 
#line 176 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( !runtime·mlookup ( v , nil , nil , &s ) ) { 
runtime·printf ( "free %p: not an allocated block\n" , v ) ; 
runtime·throw ( "free runtime·mlookup" ) ; 
} 
prof = runtime·blockspecial ( v ) ; 
#line 182 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( raceenabled ) 
runtime·racefree ( v ) ; 
#line 186 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
sizeclass = s->sizeclass; 
c = m->mcache; 
if ( sizeclass == 0 ) { 
#line 190 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
size = s->npages<<PageShift; 
* ( uintptr* ) ( s->start<<PageShift ) = ( uintptr ) 0xfeedfeedfeedfeedll; 
#line 194 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·markfreed ( v , size ) ; 
runtime·unmarkspan ( v , 1<<PageShift ) ; 
runtime·MHeap_Free ( &runtime·mheap , s , 1 ) ; 
c->local_nlargefree++; 
c->local_largefree += size; 
} else { 
#line 201 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
size = runtime·class_to_size[sizeclass]; 
if ( size > sizeof ( uintptr ) ) 
( ( uintptr* ) v ) [1] = ( uintptr ) 0xfeedfeedfeedfeedll; 
#line 207 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·markfreed ( v , size ) ; 
c->local_nsmallfree[sizeclass]++; 
runtime·MCache_Free ( c , v , sizeclass , size ) ; 
} 
if ( prof ) 
runtime·MProf_Free ( v , size ) ; 
m->mallocing = 0; 
} 
#line 216 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
int32 
runtime·mlookup ( void *v , byte **base , uintptr *size , MSpan **sp ) 
{ 
uintptr n , i; 
byte *p; 
MSpan *s; 
#line 223 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
m->mcache->local_nlookup++; 
if ( sizeof ( void* ) == 4 && m->mcache->local_nlookup >= ( 1<<30 ) ) { 
#line 226 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·lock ( &runtime·mheap ) ; 
runtime·purgecachedstats ( m->mcache ) ; 
runtime·unlock ( &runtime·mheap ) ; 
} 
#line 231 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
s = runtime·MHeap_LookupMaybe ( &runtime·mheap , v ) ; 
if ( sp ) 
*sp = s; 
if ( s == nil ) { 
runtime·checkfreed ( v , 1 ) ; 
if ( base ) 
*base = nil; 
if ( size ) 
*size = 0; 
return 0; 
} 
#line 243 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
p = ( byte* ) ( ( uintptr ) s->start<<PageShift ) ; 
if ( s->sizeclass == 0 ) { 
#line 246 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( base ) 
*base = p; 
if ( size ) 
*size = s->npages<<PageShift; 
return 1; 
} 
#line 253 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
n = s->elemsize; 
if ( base ) { 
i = ( ( byte* ) v - p ) /n; 
*base = p + i*n; 
} 
if ( size ) 
*size = n; 
#line 261 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
return 1; 
} 
#line 264 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
MCache* 
runtime·allocmcache ( void ) 
{ 
intgo rate; 
MCache *c; 
#line 270 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·lock ( &runtime·mheap ) ; 
c = runtime·FixAlloc_Alloc ( &runtime·mheap.cachealloc ) ; 
runtime·unlock ( &runtime·mheap ) ; 
runtime·memclr ( ( byte* ) c , sizeof ( *c ) ) ; 
#line 276 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
rate = runtime·MemProfileRate; 
if ( rate > 0x3fffffff ) 
rate = 0x3fffffff; 
if ( rate != 0 ) 
c->next_sample = runtime·fastrand1 ( ) % ( 2*rate ) ; 
#line 282 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
return c; 
} 
#line 285 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void 
runtime·freemcache ( MCache *c ) 
{ 
runtime·MCache_ReleaseAll ( c ) ; 
runtime·lock ( &runtime·mheap ) ; 
runtime·purgecachedstats ( c ) ; 
runtime·FixAlloc_Free ( &runtime·mheap.cachealloc , c ) ; 
runtime·unlock ( &runtime·mheap ) ; 
} 
#line 295 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void 
runtime·purgecachedstats ( MCache *c ) 
{ 
MHeap *h; 
int32 i; 
#line 302 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
h = &runtime·mheap; 
mstats.heap_alloc += c->local_cachealloc; 
c->local_cachealloc = 0; 
mstats.nlookup += c->local_nlookup; 
c->local_nlookup = 0; 
h->largefree += c->local_largefree; 
c->local_largefree = 0; 
h->nlargefree += c->local_nlargefree; 
c->local_nlargefree = 0; 
for ( i=0; i<nelem ( c->local_nsmallfree ) ; i++ ) { 
h->nsmallfree[i] += c->local_nsmallfree[i]; 
c->local_nsmallfree[i] = 0; 
} 
} 
#line 317 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
uintptr runtime·sizeof_C_MStats = sizeof ( MStats ) ; 
#line 319 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
#define MaxArena32 ( 2U<<30 ) 
#line 321 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void 
runtime·mallocinit ( void ) 
{ 
byte *p; 
uintptr arena_size , bitmap_size , spans_size; 
extern byte end[]; 
byte *want; 
uintptr limit; 
uint64 i; 
#line 331 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
p = nil; 
arena_size = 0; 
bitmap_size = 0; 
spans_size = 0; 
#line 337 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
USED ( p ) ; 
USED ( arena_size ) ; 
USED ( bitmap_size ) ; 
USED ( spans_size ) ; 
#line 342 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·InitSizes ( ) ; 
#line 347 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
limit = 0; 
#line 352 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( sizeof ( void* ) == 8 && ( limit == 0 || limit > ( 1<<30 ) ) ) { 
#line 377 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
arena_size = MaxMem; 
bitmap_size = arena_size / ( sizeof ( void* ) *8/4 ) ; 
spans_size = arena_size / PageSize * sizeof ( runtime·mheap.spans[0] ) ; 
spans_size = ROUND ( spans_size , PageSize ) ; 
for ( i = 0; i <= 0x7f; i++ ) { 
p = ( void* ) ( i<<40 | 0x00c0ULL<<32 ) ; 
p = runtime·SysReserve ( p , bitmap_size + spans_size + arena_size ) ; 
if ( p != nil ) 
break; 
} 
} 
if ( p == nil ) { 
#line 406 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
bitmap_size = MaxArena32 / ( sizeof ( void* ) *8/4 ) ; 
arena_size = 512<<20; 
spans_size = MaxArena32 / PageSize * sizeof ( runtime·mheap.spans[0] ) ; 
if ( limit > 0 && arena_size+bitmap_size+spans_size > limit ) { 
bitmap_size = ( limit / 9 ) & ~ ( ( 1<<PageShift ) - 1 ) ; 
arena_size = bitmap_size * 8; 
spans_size = arena_size / PageSize * sizeof ( runtime·mheap.spans[0] ) ; 
} 
spans_size = ROUND ( spans_size , PageSize ) ; 
#line 425 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
want = ( byte* ) ROUND ( ( uintptr ) end + ( 1<<18 ) , 1<<20 ) ; 
p = runtime·SysReserve ( want , bitmap_size + spans_size + arena_size ) ; 
if ( p == nil ) 
runtime·throw ( "runtime: cannot reserve arena virtual address space" ) ; 
if ( ( uintptr ) p & ( ( ( uintptr ) 1<<PageShift ) -1 ) ) 
runtime·printf ( "runtime: SysReserve returned unaligned address %p; asked for %p" , p , 
bitmap_size+spans_size+arena_size ) ; 
} 
if ( ( uintptr ) p & ( ( ( uintptr ) 1<<PageShift ) -1 ) ) 
runtime·throw ( "runtime: SysReserve returned unaligned address" ) ; 
#line 436 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·mheap.spans = ( MSpan** ) p; 
runtime·mheap.bitmap = p + spans_size; 
runtime·mheap.arena_start = p + spans_size + bitmap_size; 
runtime·mheap.arena_used = runtime·mheap.arena_start; 
runtime·mheap.arena_end = runtime·mheap.arena_start + arena_size; 
#line 443 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·MHeap_Init ( &runtime·mheap ) ; 
m->mcache = runtime·allocmcache ( ) ; 
#line 447 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·free ( runtime·malloc ( 1 ) ) ; 
} 
#line 450 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·MHeap_SysAlloc ( MHeap *h , uintptr n ) 
{ 
byte *p; 
#line 455 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( n > h->arena_end - h->arena_used ) { 
#line 458 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
byte *new_end; 
uintptr needed; 
#line 461 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
needed = ( uintptr ) h->arena_used + n - ( uintptr ) h->arena_end; 
needed = ROUND ( needed , 256<<20 ) ; 
new_end = h->arena_end + needed; 
if ( new_end <= h->arena_start + MaxArena32 ) { 
p = runtime·SysReserve ( h->arena_end , new_end - h->arena_end ) ; 
if ( p == h->arena_end ) 
h->arena_end = new_end; 
} 
} 
if ( n <= h->arena_end - h->arena_used ) { 
#line 472 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
p = h->arena_used; 
runtime·SysMap ( p , n , &mstats.heap_sys ) ; 
h->arena_used += n; 
runtime·MHeap_MapBits ( h ) ; 
runtime·MHeap_MapSpans ( h ) ; 
if ( raceenabled ) 
runtime·racemapshadow ( p , n ) ; 
return p; 
} 
#line 483 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( sizeof ( void* ) == 8 && ( uintptr ) h->bitmap >= 0xffffffffU ) 
return nil; 
#line 489 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
p = runtime·SysAlloc ( n , &mstats.heap_sys ) ; 
if ( p == nil ) 
return nil; 
#line 493 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( p < h->arena_start || p+n - h->arena_start >= MaxArena32 ) { 
runtime·printf ( "runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n" , 
p , h->arena_start , h->arena_start+MaxArena32 ) ; 
runtime·SysFree ( p , n , &mstats.heap_sys ) ; 
return nil; 
} 
#line 500 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( p+n > h->arena_used ) { 
h->arena_used = p+n; 
if ( h->arena_used > h->arena_end ) 
h->arena_end = h->arena_used; 
runtime·MHeap_MapBits ( h ) ; 
runtime·MHeap_MapSpans ( h ) ; 
if ( raceenabled ) 
runtime·racemapshadow ( p , n ) ; 
} 
#line 510 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
return p; 
} 
#line 513 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
static struct 
{ 
Lock; 
byte* pos; 
byte* end; 
} persistent; 
#line 520 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
enum 
{ 
PersistentAllocChunk = 256<<10 , 
PersistentAllocMaxBlock = 64<<10 , 
} ; 
#line 530 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·persistentalloc ( uintptr size , uintptr align , uint64 *stat ) 
{ 
byte *p; 
#line 535 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( align != 0 ) { 
if ( align& ( align-1 ) ) 
runtime·throw ( "persistentalloc: align is now a power of 2" ) ; 
if ( align > PageSize ) 
runtime·throw ( "persistentalloc: align is too large" ) ; 
} else 
align = 8; 
if ( size >= PersistentAllocMaxBlock ) 
return runtime·SysAlloc ( size , stat ) ; 
runtime·lock ( &persistent ) ; 
persistent.pos = ( byte* ) ROUND ( ( uintptr ) persistent.pos , align ) ; 
if ( persistent.pos + size > persistent.end ) { 
persistent.pos = runtime·SysAlloc ( PersistentAllocChunk , &mstats.other_sys ) ; 
if ( persistent.pos == nil ) { 
runtime·unlock ( &persistent ) ; 
runtime·throw ( "runtime: cannot allocate memory" ) ; 
} 
persistent.end = persistent.pos + PersistentAllocChunk; 
} 
p = persistent.pos; 
persistent.pos += size; 
runtime·unlock ( &persistent ) ; 
if ( stat != &mstats.other_sys ) { 
#line 559 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·xadd64 ( stat , size ) ; 
runtime·xadd64 ( &mstats.other_sys , - ( uint64 ) size ) ; 
} 
return p; 
} 
#line 565 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
static Lock settype_lock; 
#line 567 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void 
runtime·settype_flush ( M *mp ) 
{ 
uintptr *buf , *endbuf; 
uintptr size , ofs , j , t; 
uintptr ntypes , nbytes2 , nbytes3; 
uintptr *data2; 
byte *data3; 
void *v; 
uintptr typ , p; 
MSpan *s; 
#line 579 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
buf = mp->settype_buf; 
endbuf = buf + mp->settype_bufsize; 
#line 582 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
runtime·lock ( &settype_lock ) ; 
while ( buf < endbuf ) { 
v = ( void* ) *buf; 
*buf = 0; 
buf++; 
typ = *buf; 
buf++; 
#line 591 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
p = ( uintptr ) v>>PageShift; 
if ( sizeof ( void* ) == 8 ) 
p -= ( uintptr ) runtime·mheap.arena_start >> PageShift; 
s = runtime·mheap.spans[p]; 
#line 596 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
if ( s->sizeclass == 0 ) { 
s->types.compression = MTypes_Single; 
s->types.data = typ; 
continue; 
} 
#line 602 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
size = s->elemsize; 
ofs = ( ( uintptr ) v - ( s->start<<PageShift ) ) / size; 
#line 605 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
switch ( s->types.compression ) { 
case MTypes_Empty: 
ntypes = ( s->npages << PageShift ) / size; 
nbytes3 = 8*sizeof ( uintptr ) + 1*ntypes; 
data3 = runtime·mallocgc ( nbytes3 , 0 , FlagNoProfiling|FlagNoScan|FlagNoInvokeGC ) ; 
s->types.compression = MTypes_Bytes; 
s->types.data = ( uintptr ) data3; 
( ( uintptr* ) data3 ) [1] = typ; 
data3[8*sizeof ( uintptr ) + ofs] = 1; 
break; 
#line 616 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
case MTypes_Words: 
( ( uintptr* ) s->types.data ) [ofs] = typ; 
break; 
#line 620 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
case MTypes_Bytes: 
data3 = ( byte* ) s->types.data; 
for ( j=1; j<8; j++ ) { 
if ( ( ( uintptr* ) data3 ) [j] == typ ) { 
break; 
} 
if ( ( ( uintptr* ) data3 ) [j] == 0 ) { 
( ( uintptr* ) data3 ) [j] = typ; 
break; 
} 
} 
if ( j < 8 ) { 
data3[8*sizeof ( uintptr ) + ofs] = j; 
} else { 
ntypes = ( s->npages << PageShift ) / size; 
nbytes2 = ntypes * sizeof ( uintptr ) ; 
data2 = runtime·mallocgc ( nbytes2 , 0 , FlagNoProfiling|FlagNoScan|FlagNoInvokeGC ) ; 
s->types.compression = MTypes_Words; 
s->types.data = ( uintptr ) data2; 
#line 641 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
for ( j=0; j<ntypes; j++ ) { 
t = data3[8*sizeof ( uintptr ) + j]; 
t = ( ( uintptr* ) data3 ) [t]; 
data2[j] = t; 
} 
data2[ofs] = typ; 
} 
break; 
} 
} 
runtime·unlock ( &settype_lock ) ; 
#line 653 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
mp->settype_bufsize = 0; 
} 
#line 656 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
uintptr 
runtime·gettype ( void *v ) 
{ 
MSpan *s; 
uintptr t , ofs; 
byte *data; 
#line 663 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
s = runtime·MHeap_LookupMaybe ( &runtime·mheap , v ) ; 
if ( s != nil ) { 
t = 0; 
switch ( s->types.compression ) { 
case MTypes_Empty: 
break; 
case MTypes_Single: 
t = s->types.data; 
break; 
case MTypes_Words: 
ofs = ( uintptr ) v - ( s->start<<PageShift ) ; 
t = ( ( uintptr* ) s->types.data ) [ofs/s->elemsize]; 
break; 
case MTypes_Bytes: 
ofs = ( uintptr ) v - ( s->start<<PageShift ) ; 
data = ( byte* ) s->types.data; 
t = data[8*sizeof ( uintptr ) + ofs/s->elemsize]; 
t = ( ( uintptr* ) data ) [t]; 
break; 
default: 
runtime·throw ( "runtime·gettype: invalid compression kind" ) ; 
} 
if ( 0 ) { 
runtime·lock ( &settype_lock ) ; 
runtime·printf ( "%p -> %d,%X\n" , v , ( int32 ) s->types.compression , ( int64 ) t ) ; 
runtime·unlock ( &settype_lock ) ; 
} 
return t; 
} 
return 0; 
} 
#line 697 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·mal ( uintptr n ) 
{ 
return runtime·mallocgc ( n , 0 , 0 ) ; 
} 
#line 703 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
#pragma textflag NOSPLIT 
void 
runtime·new ( Type *typ , uint8 *ret ) 
{ 
ret = runtime·mallocgc ( typ->size , ( uintptr ) typ | TypeInfo_SingleObject , typ->kind&KindNoPointers ? FlagNoScan : 0 ) ; 
FLUSH ( &ret ) ; 
} 
#line 711 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
static void* 
cnew ( Type *typ , intgo n , int32 objtyp ) 
{ 
if ( ( objtyp& ( PtrSize-1 ) ) != objtyp ) 
runtime·throw ( "runtime: invalid objtyp" ) ; 
if ( n < 0 || ( typ->size > 0 && n > MaxMem/typ->size ) ) 
runtime·panicstring ( "runtime: allocation size out of range" ) ; 
return runtime·mallocgc ( typ->size*n , ( uintptr ) typ | objtyp , typ->kind&KindNoPointers ? FlagNoScan : 0 ) ; 
} 
#line 722 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·cnew ( Type *typ ) 
{ 
return cnew ( typ , 1 , TypeInfo_SingleObject ) ; 
} 
#line 728 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"
void* 
runtime·cnewarray ( Type *typ , intgo n ) 
{ 
return cnew ( typ , n , TypeInfo_Array ) ; 
} 
void
runtime·GC()
{
#line 734 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"

	runtime·gc(1);
}
void
runtime·SetFinalizer(Eface obj, Eface finalizer)
{
#line 738 "/usr/obj/go-1.2/go/src/pkg/runtime/malloc.goc"

	byte *base;
	uintptr size;
	FuncType *ft;
	int32 i;
	uintptr nret;
	Type *t;
	Type *fint;
	PtrType *ot;
	Iface iface;

	if(obj.type == nil) {
		runtime·printf("runtime.SetFinalizer: first argument is nil interface\n");
		goto throw;
	}
	if(obj.type->kind != KindPtr) {
		runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
		goto throw;
	}
	if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
		runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
		goto throw;
	}
	nret = 0;
	ot = (PtrType*)obj.type;
	fint = nil;
	if(finalizer.type != nil) {
		if(finalizer.type->kind != KindFunc)
			goto badfunc;
		ft = (FuncType*)finalizer.type;
		if(ft->dotdotdot || ft->in.len != 1)
			goto badfunc;
		fint = *(Type**)ft->in.array;
		if(fint == obj.type) {
			// ok - same type
		} else if(fint->kind == KindPtr && (fint->x == nil || fint->x->name == nil || obj.type->x == nil || obj.type->x->name == nil) && ((PtrType*)fint)->elem == ((PtrType*)obj.type)->elem) {
			// ok - not same type, but both pointers,
			// one or the other is unnamed, and same element type, so assignable.
		} else if(fint->kind == KindInterface && ((InterfaceType*)fint)->mhdr.len == 0) {
			// ok - satisfies empty interface
		} else if(fint->kind == KindInterface && runtime·ifaceE2I2((InterfaceType*)fint, obj, &iface)) {
			// ok - satisfies non-empty interface
		} else
			goto badfunc;

		// compute size needed for return parameters
		for(i=0; i<ft->out.len; i++) {
			t = ((Type**)ft->out.array)[i];
			nret = ROUND(nret, t->align) + t->size;
		}
		nret = ROUND(nret, sizeof(void*));
	}
	
	if(!runtime·addfinalizer(obj.data, finalizer.data, nret, fint, ot)) {
		runtime·printf("runtime.SetFinalizer: finalizer already set\n");
		goto throw;
	}
	return;

badfunc:
	runtime·printf("runtime.SetFinalizer: cannot pass %S to finalizer %S\n", *obj.type->string, *finalizer.type->string);
throw:
	runtime·throw("runtime.SetFinalizer");
}
