// slicearray(old *any, nel int, lb int, hb int, width int) (ary []any); void runtime·slicearray(byte* old, uint32 nel, uint32 lb, uint32 hb, uint32 width, Slice ret) { if(nel > 0 && old == nil) { // crash if old == nil. // could give a better message // but this is consistent with all the in-line checks // that the compiler inserts for other uses. *old = 0; } if(hb > nel || lb > hb) { if(debug) { prints("runtime·slicearray: old="); runtime·printpointer(old); prints("; nel="); runtime·printint(nel); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·printint(width); prints("\n"); } throwslice(lb, hb, nel); } // new array is inside old array ret.len = hb-lb; ret.cap = nel-lb; ret.array = old + lb*width; FLUSH(&ret); if(debug) { prints("runtime·slicearray: old="); runtime·printpointer(old); prints("; nel="); runtime·printint(nel); prints("; lb="); runtime·printint(lb); prints("; hb="); runtime·printint(hb); prints("; width="); runtime·printint(width); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
// arraytoslice(old *any, nel int) (ary []any) void runtime·arraytoslice(byte* old, uint32 nel, Slice ret) { if(nel > 0 && old == nil) { // crash if old == nil. // could give a better message // but this is consistent with all the in-line checks // that the compiler inserts for other uses. *old = 0; } // new dope to old array ret.len = nel; ret.cap = nel; ret.array = old; FLUSH(&ret); if(debug) { prints("runtime·slicearrayp: old="); runtime·printpointer(old); prints("; ret="); runtime·printslice(ret); prints("\n"); } }
void runtime·printslice(Slice a) { runtime·prints("["); runtime·printint(a.len); runtime·prints("/"); runtime·printint(a.cap); runtime·prints("]"); runtime·printpointer(a.array); }
void runtime·printslice(Slice a) { #line 197 "C:\Users\ADMINI~1\AppData\Local\Temp\2\makerelease686069423\go\src\pkg\runtime\slice.goc" runtime·prints("["); runtime·printint(a.len); runtime·prints("/"); runtime·printint(a.cap); runtime·prints("]"); runtime·printpointer(a.array); }
void runtime·printslice(Slice a) { #line 201 "/home/pi/go_build/hg/go/src/pkg/runtime/slice.goc" runtime·prints("["); runtime·printint(a.len); runtime·prints("/"); runtime·printint(a.cap); runtime·prints("]"); runtime·printpointer(a.array); }
void runtime·printslice(Slice a) { #line 197 "C:\Users\gopher\AppData\Local\Temp\1\makerelease745458658\go\src\pkg\runtime\slice.goc" runtime·prints("["); runtime·printint(a.len); runtime·prints("/"); runtime·printint(a.cap); runtime·prints("]"); runtime·printpointer(a.array); }
void runtime·printslice(Slice a) { #line 201 "/home/14/ren/source/golang/go/src/pkg/runtime/slice.goc" runtime·prints("["); runtime·printint(a.len); runtime·prints("/"); runtime·printint(a.cap); runtime·prints("]"); runtime·printpointer(a.array); }
void runtime·dump(byte *p, int32 n) { int32 i; for(i=0; i<n; i++) { runtime·printpointer((byte*)(p[i]>>4)); runtime·printpointer((byte*)(p[i]&0xf)); if((i&15) == 15) runtime·prints("\n"); else runtime·prints(" "); } if(n & 15) runtime·prints("\n"); }
void dump(byte *p, int32 n) { int32 i; for(i=0; i<n; i++) { ·printpointer((byte*)(p[i]>>4)); ·printpointer((byte*)(p[i]&0xf)); if((i&15) == 15) prints("\n"); else prints(" "); } if(n & 15) prints("\n"); }
// Atomically, // if(*addr == val) sleep // Might be woken up spuriously; that's allowed. static void futexsleep(uint32 *addr, uint32 val) { int32 ret; ret = futex(addr, FUTEX_WAIT, val, &longtime, nil, 0); if(ret >= 0 || ret == -EAGAIN || ret == -EINTR) return; prints("futexsleep addr="); ·printpointer(addr); prints(" val="); ·printint(val); prints(" returned "); ·printint(ret); prints("\n"); *(int32*)0x1005 = 0x1005; }
// If any procs are sleeping on addr, wake up at least one. static void futexwakeup(uint32 *addr) { int64 ret; ret = futex(addr, FUTEX_WAKE, 1, nil, nil, 0); if(ret >= 0) return; // I don't know that futex wakeup can return // EAGAIN or EINTR, but if it does, it would be // safe to loop and call futex again. prints("futexwakeup addr="); ·printpointer(addr); prints(" returned "); ·printint(ret); prints("\n"); *(int32*)0x1006 = 0x1006; }
// Very simple printf. Only for debugging prints. // Do not add to this without checking with Rob. static void vprintf(int8 *s, byte *base) { int8 *p, *lp; uintptr arg, narg; byte *v; // lock(&debuglock); lp = p = s; arg = 0; for(; *p; p++) { if(*p != '%') continue; if(p > lp) runtime·write(2, lp, p-lp); p++; narg = 0; switch(*p) { case 't': narg = arg + 1; break; case 'd': // 32-bit case 'x': arg = runtime·rnd(arg, 4); narg = arg + 4; break; case 'D': // 64-bit case 'U': case 'X': case 'f': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + 8; break; case 'C': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + 16; break; case 'p': // pointer-sized case 's': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(uintptr); break; case 'S': // pointer-aligned but bigger arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(String); break; case 'a': // pointer-aligned but bigger arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(Slice); break; case 'i': // pointer-aligned but bigger case 'e': arg = runtime·rnd(arg, sizeof(uintptr)); narg = arg + sizeof(Eface); break; } v = base+arg; switch(*p) { case 'a': runtime·printslice(*(Slice*)v); break; case 'd': runtime·printint(*(int32*)v); break; case 'D': runtime·printint(*(int64*)v); break; case 'e': runtime·printeface(*(Eface*)v); break; case 'f': runtime·printfloat(*(float64*)v); break; case 'C': runtime·printcomplex(*(Complex128*)v); break; case 'i': runtime·printiface(*(Iface*)v); break; case 'p': runtime·printpointer(*(void**)v); break; case 's': runtime·prints(*(int8**)v); break; case 'S': runtime·printstring(*(String*)v); break; case 't': runtime·printbool(*(bool*)v); break; case 'U': runtime·printuint(*(uint64*)v); break; case 'x': runtime·printhex(*(uint32*)v); break; case 'X': runtime·printhex(*(uint64*)v); break; } arg = narg; lp = p+1; } if(p > lp) runtime·write(2, lp, p-lp); // unlock(&debuglock); }
static int32 machcall(MachHeader *h, int32 maxsize, int32 rxsize) { uint32 *p; int32 i, ret, id; uint32 port; CodeMsg *c; if((port = m->machport) == 0){ port = runtime·mach_reply_port(); m->machport = port; } h->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); h->msgh_local_port = port; h->msgh_reserved = 0; id = h->msgh_id; if(DebugMach){ p = (uint32*)h; runtime·prints("send:\t"); for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ runtime·prints(" "); runtime·printpointer((void*)p[i]); if(i%8 == 7) runtime·prints("\n\t"); } if(i%8) runtime·prints("\n"); } ret = mach_msg(h, MACH_SEND_MSG|MACH_RCV_MSG, h->msgh_size, maxsize, port, 0, 0); if(ret != 0){ if(DebugMach){ runtime·prints("mach_msg error "); runtime·printint(ret); runtime·prints("\n"); } return ret; } if(DebugMach){ p = (uint32*)h; runtime·prints("recv:\t"); for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ runtime·prints(" "); runtime·printpointer((void*)p[i]); if(i%8 == 7) runtime·prints("\n\t"); } if(i%8) runtime·prints("\n"); } if(h->msgh_id != id+Reply){ if(DebugMach){ runtime·prints("mach_msg reply id mismatch "); runtime·printint(h->msgh_id); runtime·prints(" != "); runtime·printint(id+Reply); runtime·prints("\n"); } return -303; // MIG_REPLY_MISMATCH } // Look for a response giving the return value. // Any call can send this back with an error, // and some calls only have return values so they // send it back on success too. I don't quite see how // you know it's one of these and not the full response // format, so just look if the message is right. c = (CodeMsg*)h; if(h->msgh_size == sizeof(CodeMsg) && !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){ if(DebugMach){ runtime·prints("mig result "); runtime·printint(c->code); runtime·prints("\n"); } return c->code; } if(h->msgh_size != rxsize){ if(DebugMach){ runtime·prints("mach_msg reply size mismatch "); runtime·printint(h->msgh_size); runtime·prints(" != "); runtime·printint(rxsize); runtime·prints("\n"); } return -307; // MIG_ARRAY_TOO_LARGE } return 0; }
void HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, GoOutput base, ...) { uintptr bucket, i; Bucket *b; KEYTYPE *k; byte *v, **valueptr; uint8 top; int8 keymaybe; valueptr = (byte**)&base; if(debug) { runtime·prints("runtime.mapaccess1_fastXXX: map="); runtime·printpointer(h); runtime·prints("; key="); t->key->alg->print(t->key->size, &key); runtime·prints("\n"); } if(h == nil || h->count == 0) { *valueptr = t->elem->zero; return; } if(raceenabled) runtime·racereadpc(h, runtime·getcallerpc(&t), HASH_LOOKUP1); if(docheck) check(t, h); if(h->B == 0) { // One-bucket table. Don't hash, just check each bucket entry. b = (Bucket*)h->buckets; if(FASTKEY(key)) { for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { if(b->tophash[i] == Empty) continue; if(QUICK_NE(key, *k)) continue; if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) { *valueptr = v; return; } } } else { keymaybe = -1; for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { if(b->tophash[i] == Empty) continue; if(QUICK_NE(key, *k)) continue; if(QUICK_EQ(key, *k)) { *valueptr = v; return; } if(MAYBE_EQ(key, *k)) { if(keymaybe >= 0) { // Two same-length strings in this bucket. // use slow path. // TODO: keep track of more than just 1. We could // afford about 3 equals calls before it would be more // expensive than 1 hash + 1 equals. goto dohash; } keymaybe = i; } } if(keymaybe >= 0) { k = (KEYTYPE*)b->data + keymaybe; if(SLOW_EQ(key, *k)) { *valueptr = (byte*)((KEYTYPE*)b->data + BUCKETSIZE) + keymaybe * h->valuesize; return; } } } } else { dohash: bucket = h->hash0; HASHFUNC(&bucket, sizeof(KEYTYPE), &key); top = bucket >> (sizeof(uintptr)*8 - 8); if(top < MinTopHash) top += MinTopHash; bucket &= (((uintptr)1 << h->B) - 1); if(h->oldbuckets != nil) { i = bucket & (((uintptr)1 << (h->B - 1)) - 1); b = (Bucket*)(h->oldbuckets + i * h->bucketsize); if(evacuated(b)) { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } } else { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } do { for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { if(b->tophash[i] != top) continue; if(QUICK_NE(key, *k)) continue; if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) { *valueptr = v; return; } } b = b->overflow; } while(b != nil); } *valueptr = t->elem->zero; }
// Very simple printf. Only for debugging prints. // Do not add to this without checking with Rob. static void vprintf(int8 *s, byte *arg) { int8 *p, *lp; byte *narg; // lock(&debuglock); lp = p = s; for(; *p; p++) { if(*p != '%') continue; if(p > lp) write(fd, lp, p-lp); p++; narg = nil; switch(*p) { case 't': narg = arg + 1; break; case 'd': // 32-bit case 'x': arg = vrnd(arg, 4); narg = arg + 4; break; case 'D': // 64-bit case 'U': case 'X': case 'f': arg = vrnd(arg, sizeof(uintptr)); narg = arg + 8; break; case 'p': // pointer-sized case 's': arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(uintptr); break; case 'S': // pointer-aligned but bigger arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(String); break; case 'a': // pointer-aligned but bigger arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(Slice); break; case 'i': // pointer-aligned but bigger case 'e': arg = vrnd(arg, sizeof(uintptr)); narg = arg + sizeof(Eface); break; } switch(*p) { case 'a': ·printslice(*(Slice*)arg); break; case 'd': ·printint(*(int32*)arg); break; case 'D': ·printint(*(int64*)arg); break; case 'e': ·printeface(*(Eface*)arg); break; case 'f': ·printfloat(*(float64*)arg); break; case 'i': ·printiface(*(Iface*)arg); break; case 'p': ·printpointer(*(void**)arg); break; case 's': prints(*(int8**)arg); break; case 'S': ·printstring(*(String*)arg); break; case 't': ·printbool(*(bool*)arg); break; case 'U': ·printuint(*(uint64*)arg); break; case 'x': ·printhex(*(uint32*)arg); break; case 'X': ·printhex(*(uint64*)arg); break; case '!': ·panicl(-1); } arg = narg; lp = p+1; } if(p > lp) write(fd, lp, p-lp); // unlock(&debuglock); }