dumpspan(spanidx);
}
}
+
void
runtime·gchelper(void)
{
mstats.stacks_sys = stacks_sys;
}
+// Structure of arguments passed to function gc().
+// This allows the arguments to be passed via reflect·call.
+struct gc_args
+{
+ int32 force;
+};
+
+static void gc(struct gc_args *args);
+
void
runtime·gc(int32 force)
{
- int64 t0, t1, t2, t3;
- uint64 heap0, heap1, obj0, obj1;
byte *p;
- GCStats stats;
- M *m1;
- uint32 i;
+ struct gc_args a, *ap;
// The atomic operations are not atomic if the uint64s
// are not aligned on uint64 boundaries. This has been
if(gcpercent < 0)
return;
+ // Run gc on a bigger stack to eliminate
+ // a potentially large number of calls to runtime·morestack.
+ a.force = force;
+ ap = &a;
+ m->moreframesize_minalloc = StackBig;
+ reflect·call((byte*)gc, (byte*)&ap, sizeof(ap));
+
+ if(gctrace > 1 && !force) {
+ a.force = 1;
+ gc(&a);
+ }
+}
+
+static void
+gc(struct gc_args *args)
+{
+ int64 t0, t1, t2, t3;
+ uint64 heap0, heap1, obj0, obj1;
+ GCStats stats;
+ M *m1;
+ uint32 i;
+
runtime·semacquire(&runtime·worldsema);
- if(!force && mstats.heap_alloc < mstats.next_gc) {
+ if(!args->force && mstats.heap_alloc < mstats.next_gc) {
runtime·semrelease(&runtime·worldsema);
return;
}
// give the queued finalizers, if any, a chance to run
if(finq != nil)
runtime·gosched();
-
- if(gctrace > 1 && !force)
- runtime·gc(1);
}
void
void
runtime·newstack(void)
{
- int32 framesize, argsize;
+ int32 framesize, minalloc, argsize;
Stktop *top;
byte *stk, *sp;
G *g1;
uintptr free;
framesize = m->moreframesize;
+ minalloc = m->moreframesize_minalloc;
argsize = m->moreargsize;
g1 = m->curg;
+ m->moreframesize_minalloc = 0;
+
if(m->morebuf.sp < g1->stackguard - StackGuard) {
runtime·printf("runtime: split stack overflow: %p < %p\n", m->morebuf.sp, g1->stackguard - StackGuard);
runtime·throw("runtime: split stack overflow");
if(reflectcall)
framesize = 0;
- if(reflectcall && m->morebuf.sp - sizeof(Stktop) - argsize - 32 > g1->stackguard) {
+ if(framesize < minalloc)
+ framesize = minalloc;
+
+ if(reflectcall && minalloc == 0 && m->morebuf.sp - sizeof(Stktop) - argsize - 32 > g1->stackguard) {
// special case: called from reflect.call (framesize==1)
// to call code with an arbitrary argument size,
// and we have enough space on the current stack.
free = framesize;
}
-//runtime·printf("newstack framesize=%d argsize=%d morepc=%p moreargp=%p gobuf=%p, %p top=%p old=%p\n",
-//framesize, argsize, m->morepc, m->moreargp, m->morebuf.pc, m->morebuf.sp, top, g1->stackbase);
+ if(0) {
+ runtime·printf("newstack framesize=%d argsize=%d morepc=%p moreargp=%p gobuf=%p, %p top=%p old=%p\n",
+ framesize, argsize, m->morepc, m->moreargp, m->morebuf.pc, m->morebuf.sp, top, g1->stackbase);
+ }
top->stackbase = (byte*)g1->stackbase;
top->stackguard = (byte*)g1->stackguard;