commit f1d42e628ed611297731b2a78bbee69d2f45f8e1 Author: Richard Henderson Date: Thu Sep 25 20:14:37 2014 -0700 Always use libffi for libgo * Makefile.am (LIBFFI, LIBFFIINCS): Define directly (go_reflect_makefunc_file, go_reflect_makefunc_s_file): Remove. (reflect/makefunc.lo): Remove. * configure.ac (--with-libffi): Remove option. (LIBFFI, LIBFFIINCS): Remove subst. * Makefile.in, configure: Rebuild. * go/reflect/makefunc.go (MakeFunc): Don't check runtime.GOARCH. (makeValueMethod): Likewise. * go/reflect/makefunc_ffi_c.c: Don't check USE_LIBFFI. * runtime/go-ffi.c: Likewise. * runtime/go-ffi.h: Likewise. * runtime/go-reflect-call.c: Likewise. * go/reflect/value.go (makeFuncStubFn, makeFuncStubCode): Remove. (Value.call): Don't compare against makeFuncStubCode. (Value.Pointer): Return a dummy value for methods. * go/reflect/makefunc_386.S: Remove file. * go/reflect/makefunc_amd64.S: Remove file. * go/reflect/makefunc_dummy.c: Remove file. * go/reflect/makefuncgo_386.go: Remove file. * go/reflect/makefuncgo_amd64.go: Remove file. diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 6d00bcc..06ce555 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -27,8 +27,8 @@ toolexecdir = $(glibgo_toolexecdir) toolexeclibdir = $(glibgo_toolexeclibdir) toolexeclibgodir = $(nover_glibgo_toolexeclibdir)/go/$(gcc_version)/$(target_alias) -LIBFFI = @LIBFFI@ -LIBFFIINCS = @LIBFFIINCS@ +LIBFFI = ../libffi/libffi_convenience.la +LIBFFIINCS = -I$(top_srcdir)/../libffi/include -I../libffi/include LIBATOMIC = @LIBATOMIC@ @@ -931,29 +931,10 @@ go_path_files = \ go/path/match.go \ go/path/path.go -if LIBGO_IS_X86_64 -go_reflect_makefunc_file = \ - go/reflect/makefuncgo_amd64.go -go_reflect_makefunc_s_file = \ - go/reflect/makefunc_amd64.S -else -if LIBGO_IS_386 -go_reflect_makefunc_file = \ - go/reflect/makefuncgo_386.go -go_reflect_makefunc_s_file = \ - go/reflect/makefunc_386.S -else -go_reflect_makefunc_file = -go_reflect_makefunc_s_file = \ - go/reflect/makefunc_dummy.c -endif -endif - go_reflect_files = \ go/reflect/deepequal.go \ go/reflect/makefunc.go \ go/reflect/makefunc_ffi.go \ - $(go_reflect_makefunc_file) \ go/reflect/type.go \ go/reflect/value.go go_reflect_makefunc_c_file = \ @@ -1852,7 +1833,6 @@ libgo_go_objs = \ os.lo \ path.lo \ reflect-go.lo \ - reflect/makefunc.lo \ reflect/makefunc_ffi_c.lo \ regexp.lo \ runtime-go.lo \ @@ -2254,9 +2234,6 @@ reflect-go.lo: $(go_reflect_files) $(BUILDPACKAGE) reflect/check: $(CHECK_DEPS) @$(CHECK) -reflect/makefunc.lo: $(go_reflect_makefunc_s_file) - @$(MKDIR_P) reflect - $(LTCOMPILE) -c -o $@ $< reflect/makefunc_ffi_c.lo: $(go_reflect_makefunc_c_file) @$(MKDIR_P) reflect $(LTCOMPILE) -c -o $@ $< diff --git a/libgo/config.h.in b/libgo/config.h.in index 9e622c6..e243e11 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -374,9 +374,6 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Define if we're to use libffi. */ -#undef USE_LIBFFI - /* Define if the compiler supports -fsplit-stack */ #undef USING_SPLIT_STACK diff --git a/libgo/configure.ac b/libgo/configure.ac index 5e1e4d9..568188d 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -103,25 +103,6 @@ AC_SUBST(glibgo_toolexecdir) AC_SUBST(glibgo_toolexeclibdir) AC_SUBST(nover_glibgo_toolexeclibdir) -# See if the user wants to configure without libffi. Some -# architectures don't support it. FIXME: We should set a default -# based on the host. -AC_ARG_WITH(libffi, - AS_HELP_STRING([--without-libffi], - [don't use libffi]), - [:], - [with_libffi=${with_libffi_default-yes}]) - -LIBFFI= -LIBFFIINCS= -if test "$with_libffi" != no; then - AC_DEFINE(USE_LIBFFI, 1, [Define if we're to use libffi.]) - LIBFFI=../libffi/libffi_convenience.la - LIBFFIINCS='-I$(top_srcdir)/../libffi/include -I../libffi/include' -fi -AC_SUBST(LIBFFI) -AC_SUBST(LIBFFIINCS) - # See if the user wants to configure without libatomic. This is useful if we are # on an architecture for which libgo does not need an atomic support library and # libatomic does not support our C compiler. diff --git a/libgo/go/reflect/makefunc.go b/libgo/go/reflect/makefunc.go index 736ac36..6549f33 100644 --- a/libgo/go/reflect/makefunc.go +++ b/libgo/go/reflect/makefunc.go @@ -7,7 +7,6 @@ package reflect import ( - "runtime" "unsafe" ) @@ -58,18 +57,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { t := typ.common() ftyp := (*funcType)(unsafe.Pointer(t)) - var code uintptr - var ffi *ffiData - switch runtime.GOARCH { - case "amd64", "386": - // Indirect Go func value (dummy) to obtain actual - // code address. (A Go func value is a pointer to a C - // function pointer. http://golang.org/s/go11func.) - dummy := makeFuncStub - code = **(**uintptr)(unsafe.Pointer(&dummy)) - default: - code, ffi = makeFuncFFI(ftyp, fn) - } + code, ffi := makeFuncFFI(ftyp, fn) impl := &makeFuncImpl{ code: code, @@ -117,22 +105,11 @@ func makeMethodValue(op string, v Value) Value { ftyp := (*funcType)(unsafe.Pointer(t)) method := int(v.flag) >> flagMethodShift - var code uintptr - var ffi *ffiData - switch runtime.GOARCH { - case "amd64", "386": - // Indirect Go func value (dummy) to obtain actual - // code address. (A Go func value is a pointer to a C - // function pointer. http://golang.org/s/go11func.) - dummy := makeFuncStub - code = **(**uintptr)(unsafe.Pointer(&dummy)) - default: - code, ffi = makeFuncFFI(ftyp, - func(in []Value) []Value { - m := rcvr.Method(method) - return m.Call(in) - }) - } + code, ffi := makeFuncFFI(ftyp, + func(in []Value) []Value { + m := rcvr.Method(method) + return m.Call(in) + }) fv := &makeFuncImpl{ code: code, @@ -160,21 +137,10 @@ func makeValueMethod(v Value) Value { t := typ.common() ftyp := (*funcType)(unsafe.Pointer(t)) - var code uintptr - var ffi *ffiData - switch runtime.GOARCH { - case "amd64", "386": - // Indirect Go func value (dummy) to obtain actual - // code address. (A Go func value is a pointer to a C - // function pointer. http://golang.org/s/go11func.) - dummy := makeFuncStub - code = **(**uintptr)(unsafe.Pointer(&dummy)) - default: - code, ffi = makeFuncFFI(ftyp, - func(in []Value) []Value { - return v.Call(in) - }) - } + code, ffi := makeFuncFFI(ftyp, + func(in []Value) []Value { + return v.Call(in) + }) impl := &makeFuncImpl{ code: code, diff --git a/libgo/go/reflect/makefunc_ffi_c.c b/libgo/go/reflect/makefunc_ffi_c.c index fba269d..d05f82b 100644 --- a/libgo/go/reflect/makefunc_ffi_c.c +++ b/libgo/go/reflect/makefunc_ffi_c.c @@ -5,17 +5,8 @@ #include "runtime.h" #include "go-type.h" #include "go-panic.h" - -#ifdef USE_LIBFFI - #include "go-ffi.h" -#if FFI_CLOSURES -#define USE_LIBFFI_CLOSURES -#endif - -#endif /* defined(USE_LIBFFI) */ - /* Declare C functions with the names used to call from Go. */ struct ffi_ret { @@ -30,8 +21,6 @@ struct ffi_ret ffi(const struct __go_func_type *ftyp, FuncVal *callback) void ffiFree(void *data) __asm__ (GOSYM_PREFIX "reflect.ffiFree"); -#ifdef USE_LIBFFI_CLOSURES - /* The function that we pass to ffi_prep_closure_loc. This calls the Go callback function (passed in user_data) with the pointer to the arguments and the results area. */ @@ -116,20 +105,3 @@ ffiFree (void *data) { ffi_closure_free (data); } - -#else /* !defined(USE_LIBFFI_CLOSURES) */ - -struct ffi_ret -ffi(const struct __go_func_type *ftyp, FuncVal *callback) -{ - runtime_panicstring ("libgo built without FFI does not support " - "reflect.MakeFunc"); -} - -void ffiFree(void *data) -{ - runtime_panicstring ("libgo built without FFI does not support " - "reflect.MakeFunc"); -} - -#endif diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go index c390b8e..0a4c5e1 100644 --- a/libgo/go/reflect/value.go +++ b/libgo/go/reflect/value.go @@ -427,9 +427,6 @@ func (v Value) CallSlice(in []Value) []Value { var callGC bool // for testing; see TestCallMethodJump -var makeFuncStubFn = makeFuncStub -var makeFuncStubCode = **(**uintptr)(unsafe.Pointer(&makeFuncStubFn)) - func (v Value) call(op string, in []Value) []Value { // Get function pointer, type. t := v.typ @@ -507,17 +504,6 @@ func (v Value) call(op string, in []Value) []Value { } nout := t.NumOut() - // If target is makeFuncStub, short circuit the unpack onto stack / - // pack back into []Value for the args and return values. Just do the - // call directly. - // We need to do this here because otherwise we have a situation where - // reflect.callXX calls makeFuncStub, neither of which knows the - // layout of the args. That's bad for precise gc & stack copying. - x := (*makeFuncImpl)(fn) - if x.code == makeFuncStubCode { - return x.call(in) - } - if v.flag&flagMethod != 0 { nin++ } @@ -1313,12 +1299,14 @@ func (v Value) Pointer() uintptr { if v.flag&flagMethod != 0 { // As the doc comment says, the returned pointer is an // underlying code pointer but not necessarily enough to - // identify a single function uniquely. All method expressions - // created via reflect have the same underlying code pointer, - // so their Pointers are equal. The function used here must - // match the one used in makeMethodValue. - f := makeFuncStub - return **(**uintptr)(unsafe.Pointer(&f)) + // identify a single function uniquely. + // ??? Prior to the use of libffi, all method expressions + // created via reflect had the same underlying code pointer, + // so their Pointers were equal. Since we now create ffi + // thunks, we have no way to remember the thunk value for + // any method, so we have no way at all to generate pointer + // equality. The best we can do is some non-zero quantity. + return 0xdeadbeef } p := v.pointer() // Non-nil func value points at data block. diff --git a/libgo/runtime/go-ffi.c b/libgo/runtime/go-ffi.c index 21879b9..42f8134 100644 --- a/libgo/runtime/go-ffi.c +++ b/libgo/runtime/go-ffi.c @@ -12,9 +12,6 @@ #include "go-alloc.h" #include "go-assert.h" #include "go-type.h" - -#ifdef USE_LIBFFI - #include "ffi.h" /* The functions in this file are only called from reflect_call and @@ -334,5 +331,3 @@ __go_func_to_cif (const struct __go_func_type *func, _Bool is_interface, status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args); __go_assert (status == FFI_OK); } - -#endif /* defined(USE_LIBFFI) */ diff --git a/libgo/runtime/go-ffi.h b/libgo/runtime/go-ffi.h index afae4b6..1b4f523 100644 --- a/libgo/runtime/go-ffi.h +++ b/libgo/runtime/go-ffi.h @@ -6,11 +6,6 @@ #include "config.h" #include "go-type.h" - -#ifdef USE_LIBFFI - #include "ffi.h" void __go_func_to_cif (const struct __go_func_type *, _Bool, _Bool, ffi_cif *); - -#endif diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c index dfc703e..8018183 100644 --- a/libgo/runtime/go-reflect-call.c +++ b/libgo/runtime/go-reflect-call.c @@ -12,9 +12,6 @@ #include "go-alloc.h" #include "go-assert.h" #include "go-type.h" - -#ifdef USE_LIBFFI - #include "go-ffi.h" /* The functions in this file are only called from reflect_call. As @@ -232,20 +229,3 @@ reflect_call (const struct __go_func_type *func_type, FuncVal *func_val, free (call_result); } - -#else /* !defined(USE_LIBFFI) */ - -void -reflect_call (const struct __go_func_type *func_type __attribute__ ((unused)), - FuncVal *func_val __attribute__ ((unused)), - _Bool is_interface __attribute__ ((unused)), - _Bool is_method __attribute__ ((unused)), - void **params __attribute__ ((unused)), - void **results __attribute__ ((unused))) -{ - /* Without FFI there is nothing we can do. */ - runtime_throw("libgo built without FFI does not support " - "reflect.Call or runtime.SetFinalizer"); -} - -#endif /* !defined(USE_LIBFFI) */