runtime: Handle allocating memory in cgo/SWIG function.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 24 Jul 2013 22:30:25 +0000 (22:30 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 24 Jul 2013 22:30:25 +0000 (22:30 +0000)
A function that returns an interface type and returns a value
that requires memory allocation will try to allocate while
appearing to be in a syscall.  This patch lets that work.

From-SVN: r201226

libgo/runtime/malloc.goc

index 4b93e9707691faff2ff136a49bb5846bc6fc2883..8ccaa6b888cdd6935102181888cf4763921f5239 100644 (file)
@@ -41,11 +41,24 @@ runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
        uintptr npages;
        MSpan *s;
        void *v;
+       bool incallback;
 
        m = runtime_m();
        g = runtime_g();
-       if(g->status == Gsyscall)
-               dogc = 0;
+
+       incallback = false;
+       if(m->mcache == nil && g->ncgo > 0) {
+               // For gccgo this case can occur when a cgo or SWIG function
+               // has an interface return type and the function
+               // returns a non-pointer, so memory allocation occurs
+               // after syscall.Cgocall but before syscall.CgocallDone.
+               // We treat it as a callback.
+               runtime_exitsyscall();
+               m = runtime_m();
+               incallback = true;
+               dogc = false;
+       }
+
        if(runtime_gcwaiting && g != m->g0 && m->locks == 0 && dogc) {
                runtime_gosched();
                m = runtime_m();
@@ -129,6 +142,10 @@ runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
                runtime_racemalloc(v, size, m->racepc);
                m->racepc = nil;
        }
+
+       if(incallback)
+               runtime_entersyscall();
+
        return v;
 }