diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-07-24 22:30:25 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-07-24 22:30:25 +0000 |
commit | b0c5dc1655bc88f34ecd1bf93ff297871b650392 (patch) | |
tree | 6c5565907afcb57540cfa85b6b3702a3d51074b4 /libgo/runtime/malloc.goc | |
parent | ce4a94223ea08c13ba644b2f8c2dde8a2b1511fb (diff) | |
download | gcc-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.goc | 21 |
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; } |