From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4639 invoked by alias); 22 Jun 2016 11:54:29 -0000 Mailing-List: contact java-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: java-patches-owner@gcc.gnu.org Received: (qmail 4628 invoked by uid 89); 22 Jun 2016 11:54:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=cif, H*Ad:U*aurelien, HTo:U*java-patches X-HELO: mailapp01.imgtec.com Received: from mailapp01.imgtec.com (HELO mailapp01.imgtec.com) (195.59.15.196) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Jun 2016 11:54:18 +0000 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Forcepoint Email with ESMTPS id EB9B68CD62B50; Wed, 22 Jun 2016 12:54:12 +0100 (IST) Received: from HHMAIL01.hh.imgtec.org ([fe80::710b:f219:72bc:e0b3]) by hhmail02.hh.imgtec.org ([fe80::5400:d33e:81a4:f775%25]) with mapi id 14.03.0294.000; Wed, 22 Jun 2016 12:54:15 +0100 From: Matthew Fortune To: "java-patches@gcc.gnu.org" CC: "aurelien@aurel32.net" , Yunqiang Su Subject: [RFC] interpreter use of closures and return types Date: Wed, 22 Jun 2016 11:54:00 -0000 Message-ID: <6D39441BF12EF246A7ABCE6654B023537E45723C@HHMAIL01.hh.imgtec.org> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-SW-Source: 2016-q2/txt/msg00020.txt.bz2 Hi, While working on getting mips64el support in place for Debian we found a bug relating to libgcj/libffi and closures for MIPS n32 and n64. The bug is essentially that return types <=3D 32bit do not end up correctly sign extended in registers when a function is called via a closure. A test case showing what I think the problem boils down to is at the end of this email. Switch between the two lines in foo_binding to see the difference. Note that this will not fail on x86 but I believe it will fail on any big endian architecture. The root of the problem seems to be in a oddity of FFI that integer return values less than word (or rather register) size are returned as an ffi_arg. The java interpreter does not appear to adhere to this and the patch below seems to fix the issue. Can anyone comment if this looks like the right approach? I think there may be a similar issue in the lang/reflect/natVMProxy.cc code (unbox function) by code inspection alone but haven't investigated further. If this looks OK I'll do some full testsuite runs. Thanks, Matthew libjava/ * interpret-run.cc: Return integers as ffi_arg instead of jint. diff --git a/libjava/interpret-run.cc b/libjava/interpret-run.cc index a4c2d4d..6be354e 100644 --- a/libjava/interpret-run.cc +++ b/libjava/interpret-run.cc @@ -1838,7 +1838,7 @@ details. */ return; =20 insn_ireturn: - *(jint *) retp =3D POPI (); + *(ffi_arg *) retp =3D POPI (); return; =20 insn_return: Here is the test case to show the effect of getting int vs ffi_arg wrong on n32/n64. It will say that the result is negative only when using ffi_arg as the return type. #include #include __attribute__((noinline)) int foo(void) { return -1; } /* Acts like puts with the file given at time of enclosure. */ void foo_binding(ffi_cif *cif, void *ret, void* args[], void* none) { *(int *)ret =3D foo(); // *(ffi_arg *)ret =3D foo(); } typedef int (*foo_t)(); int main() { ffi_cif cif; ffi_closure *closure; void *bound_foo; int rc; closure =3D ffi_closure_alloc(sizeof(ffi_closure), &bound_foo); if (closure) { /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint32, NULL) =3D=3D FFI_OK) { if (ffi_prep_closure_loc(closure, &cif, foo_binding, NULL, bound_foo) =3D=3D FFI_OK) { rc =3D ((foo_t)bound_foo)(); fprintf(stderr, "is result negative: %s\n", (rc < 0)? "yes":"= no"); } } } ffi_closure_free(closure); return 0; }