// allocator, assuming that inside malloc all the stack
// frames are small, so that all the stack allocations
// will be a single size, the minimum (right now, 5k).
- if(m->mallocing || m->gcing || n == FixedStack) {
+ if(n == FixedStack || m->mallocing || m->gcing) {
if(n != FixedStack) {
runtime·printf("stackalloc: in malloc, size=%d want %d", FixedStack, n);
runtime·throw("stackalloc");
{
uint32 pos;
- if(m->mallocing || m->gcing || n == FixedStack) {
+ if(n == FixedStack || m->mallocing || m->gcing) {
if(m->stackcachecnt == StackCacheSize)
stackcacherelease();
pos = m->stackcachepos;
void
runtime·oldstack(void)
{
- Stktop *top, old;
+ Stktop *top;
+ Gobuf label;
uint32 argsize;
uintptr cret;
- byte *sp;
+ byte *sp, *old;
+ uintptr *src, *dst, *dstend;
G *gp;
int64 goid;
gp = m->curg;
top = (Stktop*)gp->stackbase;
+ old = (byte*)gp->stackguard - StackGuard;
sp = (byte*)top;
- old = *top;
- argsize = old.argsize;
+ argsize = top->argsize;
if(argsize > 0) {
sp -= argsize;
- runtime·memmove(top->argp, sp, argsize);
+ dst = (uintptr*)top->argp;
+ dstend = dst + argsize/sizeof(*dst);
+ src = (uintptr*)sp;
+ while(dst < dstend)
+ *dst++ = *src++;
}
- goid = old.gobuf.g->goid; // fault if g is bad, before gogo
+ goid = top->gobuf.g->goid; // fault if g is bad, before gogo
USED(goid);
- if(old.free != 0)
- runtime·stackfree((byte*)gp->stackguard - StackGuard, old.free);
- gp->stackbase = (uintptr)old.stackbase;
- gp->stackguard = (uintptr)old.stackguard;
+ label = top->gobuf;
+ gp->stackbase = (uintptr)top->stackbase;
+ gp->stackguard = (uintptr)top->stackguard;
+ if(top->free != 0)
+ runtime·stackfree(old, top->free);
cret = m->cret;
m->cret = 0; // drop reference
- runtime·gogo(&old.gobuf, cret);
+ runtime·gogo(&label, cret);
}
// Called from reflect·call or from runtime·morestack when a new
int32 framesize, minalloc, argsize;
Stktop *top;
byte *stk, *sp;
+ uintptr *src, *dst, *dstend;
G *gp;
Gobuf label;
bool reflectcall;
uintptr free;
framesize = m->moreframesize;
- minalloc = m->moreframesize_minalloc;
argsize = m->moreargsize;
gp = m->curg;
- m->moreframesize_minalloc = 0;
-
if(m->morebuf.sp < gp->stackguard - StackGuard) {
runtime·printf("runtime: split stack overflow: %p < %p\n", m->morebuf.sp, gp->stackguard - StackGuard);
runtime·throw("runtime: split stack overflow");
runtime·throw("runtime: stack split argsize");
}
+ minalloc = 0;
reflectcall = framesize==1;
- if(reflectcall)
+ if(reflectcall) {
framesize = 0;
-
- if(framesize < minalloc)
- framesize = minalloc;
+ // moreframesize_minalloc is only set in runtime·gc(),
+ // that calls newstack via reflect·call().
+ minalloc = m->moreframesize_minalloc;
+ m->moreframesize_minalloc = 0;
+ if(framesize < minalloc)
+ framesize = minalloc;
+ }
if(reflectcall && minalloc == 0 && m->morebuf.sp - sizeof(Stktop) - argsize - 32 > gp->stackguard) {
// special case: called from reflect.call (framesize==1)
sp = (byte*)top;
if(argsize > 0) {
sp -= argsize;
- runtime·memmove(sp, top->argp, argsize);
+ dst = (uintptr*)sp;
+ dstend = dst + argsize/sizeof(*dst);
+ src = (uintptr*)top->argp;
+ while(dst < dstend)
+ *dst++ = *src++;
}
if(thechar == '5') {
// caller would have saved its LR below args.