mirror of
https://github.com/golang/go
synced 2024-11-23 07:40:04 -07:00
runtime: delete cgo_allocate
This memory is untyped and can't be used anymore. The next version of SWIG won't need it. Change-Id: I592b287c5f5186975ee09a9b28d8efe3b57134e7 Reviewed-on: https://go-review.googlesource.com/8956 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
89b7c66d0d
commit
6a2b0c0b6d
@ -9,7 +9,6 @@ void callback(void *f);
|
||||
void callGoFoo(void);
|
||||
void callGoStackCheck(void);
|
||||
void callPanic(void);
|
||||
void callCgoAllocate(void);
|
||||
int callGoReturnVal(void);
|
||||
int returnAfterGrow(void);
|
||||
int returnAfterGrowFromGo(void);
|
||||
@ -17,7 +16,6 @@ int returnAfterGrowFromGo(void);
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"strings"
|
||||
@ -211,23 +209,6 @@ func testPanicFromC(t *testing.T) {
|
||||
C.callPanic()
|
||||
}
|
||||
|
||||
func testAllocateFromC(t *testing.T) {
|
||||
if strings.Contains(os.Getenv("GODEBUG"), "wbshadow=") {
|
||||
// This test is writing pointers to Go heap objects from C.
|
||||
// As such, those writes have no write barriers, and
|
||||
// wbshadow=2 mode correctly discovers that and crashes.
|
||||
// Disable test if any wbshadow mode is enabled.
|
||||
// TODO(rsc): I am not sure whether the test is fundamentally
|
||||
// incompatible with concurrent collection and should be
|
||||
// turned off or rewritten entirely. The test is attempting to
|
||||
// mimic some SWIG behavior, so it is important to work
|
||||
// through what we expect before trying SWIG and C++
|
||||
// with the concurrent collector.
|
||||
t.Skip("test is incompatible with wbshadow=")
|
||||
}
|
||||
C.callCgoAllocate() // crashes or exits on failure
|
||||
}
|
||||
|
||||
// Test that C code can return a value if it calls a Go function that
|
||||
// causes a stack copy.
|
||||
func testReturnAfterGrow(t *testing.T) {
|
||||
|
@ -23,58 +23,3 @@ callPanic(void)
|
||||
crosscall2(_cgo_panic, &a, sizeof a);
|
||||
*(int*)1 = 1;
|
||||
}
|
||||
|
||||
/* Test calling cgo_allocate from C. This is what SWIG does. */
|
||||
|
||||
typedef struct List List;
|
||||
struct List
|
||||
{
|
||||
List *next;
|
||||
int x;
|
||||
};
|
||||
|
||||
void
|
||||
callCgoAllocate(void)
|
||||
{
|
||||
int i;
|
||||
struct { size_t n; void *ret; } a;
|
||||
List *l, *head, **tail;
|
||||
|
||||
// Make sure this doesn't crash.
|
||||
// And make sure it returns non-nil.
|
||||
a.n = 0;
|
||||
a.ret = 0;
|
||||
crosscall2(_cgo_allocate, &a, sizeof a);
|
||||
if(a.ret == 0) {
|
||||
fprintf(stderr, "callCgoAllocate: alloc 0 returned nil\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
head = 0;
|
||||
tail = &head;
|
||||
for(i=0; i<100; i++) {
|
||||
a.n = sizeof *l;
|
||||
crosscall2(_cgo_allocate, &a, sizeof a);
|
||||
l = a.ret;
|
||||
l->x = i;
|
||||
l->next = 0;
|
||||
*tail = l;
|
||||
tail = &l->next;
|
||||
}
|
||||
|
||||
gc();
|
||||
|
||||
l = head;
|
||||
for(i=0; i<100; i++) {
|
||||
if(l->x != i) {
|
||||
fprintf(stderr, "callCgoAllocate: lost memory\n");
|
||||
exit(2);
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
if(l != 0) {
|
||||
fprintf(stderr, "callCgoAllocate: lost memory\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,52 +19,3 @@ callPanic(void)
|
||||
{
|
||||
_cgo_panic("panic from C");
|
||||
}
|
||||
|
||||
/* Test calling cgo_allocate from C. This is what SWIG does. */
|
||||
|
||||
typedef struct List List;
|
||||
struct List
|
||||
{
|
||||
List *next;
|
||||
int x;
|
||||
};
|
||||
|
||||
void
|
||||
callCgoAllocate(void)
|
||||
{
|
||||
int i;
|
||||
List *l, *head, **tail;
|
||||
|
||||
// Make sure this doesn't crash.
|
||||
// And make sure it returns non-nil.
|
||||
if(_cgo_allocate(0) == 0) {
|
||||
fprintf(stderr, "callCgoAllocate: alloc 0 returned nil\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
head = 0;
|
||||
tail = &head;
|
||||
for(i=0; i<100; i++) {
|
||||
l = _cgo_allocate(sizeof *l);
|
||||
l->x = i;
|
||||
l->next = 0;
|
||||
*tail = l;
|
||||
tail = &l->next;
|
||||
}
|
||||
|
||||
gc();
|
||||
|
||||
l = head;
|
||||
for(i=0; i<100; i++) {
|
||||
if(l->x != i) {
|
||||
fprintf(stderr, "callCgoAllocate: lost memory\n");
|
||||
exit(2);
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
if(l != 0) {
|
||||
fprintf(stderr, "callCgoAllocate: lost memory\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) }
|
||||
func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) }
|
||||
func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) }
|
||||
func TestPanicFromC(t *testing.T) { testPanicFromC(t) }
|
||||
func TestAllocateFromC(t *testing.T) { testAllocateFromC(t) }
|
||||
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
|
||||
func TestBlocking(t *testing.T) { testBlocking(t) }
|
||||
func Test1328(t *testing.T) { test1328(t) }
|
||||
|
@ -22,32 +22,6 @@ func _runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr)
|
||||
//go:cgo_export_static crosscall2
|
||||
//go:cgo_export_dynamic crosscall2
|
||||
|
||||
// Allocate memory. This allocates the requested number of bytes in
|
||||
// memory controlled by the Go runtime. The allocated memory will be
|
||||
// zeroed. You are responsible for ensuring that the Go garbage
|
||||
// collector can see a pointer to the allocated memory for as long as
|
||||
// it is valid, e.g., by storing a pointer in a local variable in your
|
||||
// C function, or in memory allocated by the Go runtime. If the only
|
||||
// pointers are in a C global variable or in memory allocated via
|
||||
// malloc, then the Go garbage collector may collect the memory.
|
||||
|
||||
// Call like this in code compiled with gcc:
|
||||
// struct { size_t len; void *ret; } a;
|
||||
// a.len = /* number of bytes to allocate */;
|
||||
// crosscall2(_cgo_allocate, &a, sizeof a);
|
||||
// /* Here a.ret is a pointer to the allocated memory. */
|
||||
|
||||
//go:linkname _runtime_cgo_allocate_internal runtime._cgo_allocate_internal
|
||||
var _runtime_cgo_allocate_internal byte
|
||||
|
||||
//go:linkname _cgo_allocate _cgo_allocate
|
||||
//go:cgo_export_static _cgo_allocate
|
||||
//go:cgo_export_dynamic _cgo_allocate
|
||||
//go:nosplit
|
||||
func _cgo_allocate(a unsafe.Pointer, n int32) {
|
||||
_runtime_cgocallback(unsafe.Pointer(&_runtime_cgo_allocate_internal), a, uintptr(n))
|
||||
}
|
||||
|
||||
// Panic. The argument is converted into a Go string.
|
||||
|
||||
// Call like this in code compiled with gcc:
|
||||
|
@ -132,12 +132,6 @@ func cgocall_errno(fn, arg unsafe.Pointer) int32 {
|
||||
//go:nosplit
|
||||
func endcgo(mp *m) {
|
||||
mp.ncgo--
|
||||
if mp.ncgo == 0 {
|
||||
// We are going back to Go and are not in a recursive
|
||||
// call. Let the GC collect any memory allocated via
|
||||
// _cgo_allocate that is no longer referenced.
|
||||
mp.cgomal = nil
|
||||
}
|
||||
|
||||
if raceenabled {
|
||||
raceacquire(unsafe.Pointer(&racecgosync))
|
||||
|
@ -4,35 +4,8 @@
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// These functions are called from C code via cgo/callbacks.go.
|
||||
|
||||
// Allocate memory. This allocates the requested number of bytes in
|
||||
// memory controlled by the Go runtime. The allocated memory will be
|
||||
// zeroed. You are responsible for ensuring that the Go garbage
|
||||
// collector can see a pointer to the allocated memory for as long as
|
||||
// it is valid, e.g., by storing a pointer in a local variable in your
|
||||
// C function, or in memory allocated by the Go runtime. If the only
|
||||
// pointers are in a C global variable or in memory allocated via
|
||||
// malloc, then the Go garbage collector may collect the memory.
|
||||
//
|
||||
// TODO(rsc,iant): This memory is untyped.
|
||||
// Either we need to add types or we need to stop using it.
|
||||
|
||||
func _cgo_allocate_internal(len uintptr) unsafe.Pointer {
|
||||
if len == 0 {
|
||||
len = 1
|
||||
}
|
||||
ret := unsafe.Pointer(&make([]unsafe.Pointer, (len+ptrSize-1)/ptrSize)[0])
|
||||
c := new(cgomal)
|
||||
c.alloc = ret
|
||||
gp := getg()
|
||||
c.next = gp.m.cgomal
|
||||
gp.m.cgomal = c
|
||||
return ret
|
||||
}
|
||||
|
||||
// Panic.
|
||||
|
||||
func _cgo_panic_internal(p *byte) {
|
||||
|
@ -127,15 +127,6 @@ const (
|
||||
_RootCount = 5
|
||||
)
|
||||
|
||||
//go:linkname weak_cgo_allocate go.weak.runtime._cgo_allocate_internal
|
||||
var weak_cgo_allocate byte
|
||||
|
||||
// Is _cgo_allocate linked into the binary?
|
||||
//go:nowritebarrier
|
||||
func have_cgo_allocate() bool {
|
||||
return &weak_cgo_allocate != nil
|
||||
}
|
||||
|
||||
// heapminimum is the minimum number of bytes in the heap.
|
||||
// This cleans up the corner case of where we have a very small live set but a lot
|
||||
// of allocations and collecting every GOGC * live set is expensive.
|
||||
|
@ -283,7 +283,6 @@ type m struct {
|
||||
fastrand uint32
|
||||
ncgocall uint64 // number of cgo calls in total
|
||||
ncgo int32 // number of cgo calls currently in progress
|
||||
cgomal *cgomal
|
||||
park note
|
||||
alllink *m // on allm
|
||||
schedlink *m
|
||||
@ -485,13 +484,6 @@ type lfnode struct {
|
||||
pushcnt uintptr
|
||||
}
|
||||
|
||||
// Track memory allocated by code not written in Go during a cgo call,
|
||||
// so that the garbage collector can see them.
|
||||
type cgomal struct {
|
||||
next *cgomal
|
||||
alloc unsafe.Pointer
|
||||
}
|
||||
|
||||
// Indicates to write barrier and sychronization task to preform.
|
||||
const (
|
||||
_GCoff = iota // GC not running, write barrier disabled
|
||||
|
Loading…
Reference in New Issue
Block a user