aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/malloc.goc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2013-07-24 22:30:25 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-07-24 22:30:25 +0000
commitb0c5dc1655bc88f34ecd1bf93ff297871b650392 (patch)
tree6c5565907afcb57540cfa85b6b3702a3d51074b4 /libgo/runtime/malloc.goc
parentce4a94223ea08c13ba644b2f8c2dde8a2b1511fb (diff)
downloadgcc-b0c5dc1655bc88f34ecd1bf93ff297871b650392.zip
gcc-b0c5dc1655bc88f34ecd1bf93ff297871b650392.tar.gz
gcc-b0c5dc1655bc88f34ecd1bf93ff297871b650392.tar.bz2
runtime: Handle allocating memory in cgo/SWIG function.
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
Diffstat (limited to 'libgo/runtime/malloc.goc')
-rw-r--r--libgo/runtime/malloc.goc21
1 files changed, 19 insertions, 2 deletions
diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc
index 4b93e97..8ccaa6b 100644
--- a/libgo/runtime/malloc.goc
+++ b/libgo/runtime/malloc.goc
@@ -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;
}