From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: =?utf-8?Q?Ludovic_Court=C3=A8s?= Newsgroups: gmane.lisp.guile.devel Subject: Re: For a cheaper =?utf-8?Q?=E2=80=98bytevector-=3Epointer?= =?utf-8?Q?=E2=80=99?= Date: Mon, 25 Nov 2019 23:03:59 +0100 Message-ID: <87o8wzvcj4.fsf@gnu.org> References: <87zhglzgue.fsf@gnu.org> <875zj81g3b.fsf@igalia.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="6329"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cc: Guile Devel To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Nov 25 23:04:50 2019 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iZMTR-0001WF-90 for guile-devel@m.gmane.org; Mon, 25 Nov 2019 23:04:49 +0100 Original-Received: from localhost ([::1]:48652 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iZMTQ-0004HT-1K for guile-devel@m.gmane.org; Mon, 25 Nov 2019 17:04:48 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:37436) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iZMSk-0004Go-6h for guile-devel@gnu.org; Mon, 25 Nov 2019 17:04:07 -0500 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:46034) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iZMSi-00085B-FM; Mon, 25 Nov 2019 17:04:04 -0500 Original-Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=45970 helo=ribbon) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1iZMSf-00021X-Jn; Mon, 25 Nov 2019 17:04:02 -0500 X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 5 Frimaire an 228 de la =?utf-8?Q?R=C3=A9volution?= X-PGP-Key-ID: 0x090B11993D9AEBB5 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu In-Reply-To: <875zj81g3b.fsf@igalia.com> (Andy Wingo's message of "Mon, 25 Nov 2019 10:05:12 +0100") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.org gmane.lisp.guile.devel:20168 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello! Andy Wingo skribis: > Honestly I would prefer not to do this. If I understand correctly, the > problem is in FFI calls -- you have a bytevector and you want to pass it > as a pointer. In that case the "right" optimization is to avoid the > scm_tc7_pointer altogether and instead having an unboxed raw pointer. > The idioms used in FFI are local enough that a compiler can do this. I agree! I have a patch from the 2.0 era (attached), but it doesn=E2=80=99t work because all the tc3s are already taken. I don=E2=80=99t think this has changed but I could well be missing something about the tag space. WDYT? > More broadly -- the current FFI is an interpreter but it should be a > compiler. When a call happens, the code interprets the description of > the ABI. Instead, pointer->function should ideally *compile* a > trampoline. In an ideal world this compilation can happen > ahead-of-time, when the .go file is compiled. Yes, agreed. > In the short term, what about allowing bytevectors as arguments > whereever a pointer is allowed? Perhaps it's bad to expand the domain > of these functions but it may be the right trade-off. So in practice, every time there=E2=80=99s '* in the FFI, it=E2=80=99d acce= pt a bytevector, right? I would prefer immediate pointers if that=E2=80=99s possible, and then one = of the two other solutions. Thanks! Ludo=E2=80=99. --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable commit c705f743031b305051549928cd91e5cfdfef7ec7 Author: Ludovic Court=C3=A8s Date: Sun Jan 30 23:28:13 2011 +0100 Attempt to support "immediate pointers". =20=20=20=20 Problem is, 3 is not a valid "immediate tag", because that would prevent using an immediate number as the car of a pair. diff --git a/libguile/evalext.c b/libguile/evalext.c index ff2ff0ec0..c9dcf8b96 100644 --- a/libguile/evalext.c +++ b/libguile/evalext.c @@ -1,5 +1,6 @@ -/* Copyright (C) 1998,1999,2000,2001,2002,2003, 2006, 2008, 2009, 2010 Fre= e Software Foundation, Inc. - *=20 +/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2008, + * 2009, 2010, 2011 Free Software Foundation, Inc. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 3 of @@ -72,6 +73,8 @@ SCM_DEFINE (scm_self_evaluating_p, "self-evaluating?", 1,= 0, 0, case scm_tc3_imm24: /* characters, booleans, other immediates */ return scm_from_bool (!scm_is_null_and_not_nil (obj)); + case scm_tc3_aligned_pointer: + return SCM_BOOL_T; case scm_tc3_cons: switch (SCM_TYP7 (obj)) { diff --git a/libguile/foreign.c b/libguile/foreign.c index 52da23f6e..d00d4a975 100644 --- a/libguile/foreign.c +++ b/libguile/foreign.c @@ -60,7 +60,7 @@ SCM_SYMBOL (sym_null, "%null-pointer"); SCM_SYMBOL (sym_null_pointer_error, "null-pointer-error"); =20 /* The cell representing the null pointer. */ -static SCM null_pointer; +static SCM null_pointer =3D SCM_PACK (scm_tc3_aligned_pointer); =20 #if SIZEOF_VOID_P =3D=3D 4 # define scm_to_uintptr scm_to_uint32 @@ -139,8 +139,9 @@ scm_from_pointer (void *ptr, scm_t_pointer_finalizer fi= nalizer) { SCM ret; =20 - if (ptr =3D=3D NULL && finalizer =3D=3D NULL) - ret =3D null_pointer; + if (SCM_LIKELY (((scm_t_uintptr) ptr & 3) =3D=3D 0 && finalizer =3D=3D N= ULL)) + /* Return an immediate pointer. */ + ret =3D SCM_PACK ((scm_t_bits) ptr | scm_tc3_aligned_pointer); else { ret =3D scm_cell (scm_tc7_pointer, (scm_t_bits) ptr); @@ -1125,7 +1126,6 @@ scm_init_foreign (void) #endif ); =20 - null_pointer =3D scm_cell (scm_tc7_pointer, 0); scm_define (sym_null, null_pointer); } =20 diff --git a/libguile/foreign.h b/libguile/foreign.h index b29001962..bf16126e5 100644 --- a/libguile/foreign.h +++ b/libguile/foreign.h @@ -49,12 +49,18 @@ typedef enum scm_t_foreign_type scm_t_foreign_type; =20 typedef void (*scm_t_pointer_finalizer) (void *); =20 -#define SCM_POINTER_P(x) \ - (!SCM_IMP (x) && SCM_TYP7(x) =3D=3D scm_tc7_pointer) +#define SCM_POINTER_P(x) \ + (SCM_IMP (x) \ + ? SCM_ITAG3 (x) =3D=3D scm_tc3_aligned_pointer \ + : SCM_TYP7 (x) =3D=3D scm_tc7_pointer) + #define SCM_VALIDATE_POINTER(pos, x) \ SCM_MAKE_VALIDATE (pos, x, POINTER_P) + #define SCM_POINTER_VALUE(x) \ - ((void *) SCM_CELL_WORD_1 (x)) + (SCM_IMP (x) \ + ? (void *) ((scm_t_uintptr) (x) & ~3UL) \ + : (void *) SCM_CELL_WORD_1 (x)) =20 SCM_API SCM scm_from_pointer (void *, scm_t_pointer_finalizer); =20 diff --git a/libguile/gc.c b/libguile/gc.c index 91250ba57..1754f6b1d 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 200= 8, 2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + * 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -746,8 +747,9 @@ scm_i_tag_name (scm_t_bits tag) return "cons (immediate car)"; case scm_tcs_cons_nimcar: return "cons (non-immediate car)"; + case scm_tc3_aligned_pointer: case scm_tc7_pointer: - return "foreign"; + return "pointer"; case scm_tc7_hashtable: return "hashtable"; case scm_tc7_fluid: diff --git a/libguile/goops.c b/libguile/goops.c index c597044f5..feb61ff22 100644 --- a/libguile/goops.c +++ b/libguile/goops.c @@ -211,6 +211,9 @@ SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0, else return scm_class_unknown; =20 + case scm_tc3_aligned_pointer: + return class_foreign; + case scm_tc3_cons: switch (SCM_TYP7 (x)) { diff --git a/libguile/hash.c b/libguile/hash.c index 0dcd1c29e..7ceea43e0 100644 --- a/libguile/hash.c +++ b/libguile/hash.c @@ -143,6 +143,18 @@ scm_i_utf8_string_hash (const char *str, size_t len) return h; } =20 +static unsigned long +pointer_hash (SCM obj) +{ + /* Pointer objects are typically used to store addresses of heap + objects. On most platforms, these are at least 3-byte + aligned (on x86_64-*-gnu, `malloc' returns 4-byte aligned + addresses), so get rid of the least significant bits. */ + scm_t_uintptr significant_bits; + + significant_bits =3D (scm_t_uintptr) SCM_POINTER_VALUE (obj) >> 4UL; + return (size_t) significant_bits; +} =20 /* Dirk:FIXME:: why downcase for characters? (2x: scm_hasher, scm_ihashv) = */ /* Dirk:FIXME:: scm_hasher could be made static. */ @@ -155,6 +167,8 @@ scm_hasher(SCM obj, unsigned long n, size_t d) case scm_tc3_int_1:=20 case scm_tc3_int_2: return SCM_I_INUM(obj) % n; /* SCM_INUMP(obj) */ + case scm_tc3_aligned_pointer: + return pointer_hash (obj) % n; case scm_tc3_imm24: if (SCM_CHARP(obj)) return (unsigned)(scm_c_downcase(SCM_CHAR(obj))) % n; @@ -214,16 +228,7 @@ scm_hasher(SCM obj, unsigned long n, size_t d) case scm_tc7_symbol: return scm_i_symbol_hash (obj) % n; case scm_tc7_pointer: - { - /* Pointer objects are typically used to store addresses of heap - objects. On most platforms, these are at least 3-byte - aligned (on x86_64-*-gnu, `malloc' returns 4-byte aligned - addresses), so get rid of the least significant bits. */ - scm_t_uintptr significant_bits; - - significant_bits =3D (scm_t_uintptr) SCM_POINTER_VALUE (obj) >> 4UL; - return (size_t) significant_bits % n; - } + return pointer_hash (obj) % n; case scm_tc7_wvect: case scm_tc7_vector: { diff --git a/libguile/print.c b/libguile/print.c index 679327a8a..f5af19131 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -499,6 +499,9 @@ iprin1 (SCM exp, SCM port, scm_print_state *pstate) scm_ipruk ("immediate", exp, port); } break; + case scm_tc3_aligned_pointer: + scm_i_pointer_print (exp, port, pstate); + break; case scm_tc3_cons: switch (SCM_TYP7 (exp)) { diff --git a/libguile/tags.h b/libguile/tags.h index 9e0e3059d..913064d9f 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -3,8 +3,8 @@ #ifndef SCM_TAGS_H #define SCM_TAGS_H =20 -/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2008,20= 09,2010 - * Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, + * 2003, 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -386,7 +386,7 @@ typedef scm_t_uintptr scm_t_bits; #define scm_tc3_cons 0 #define scm_tc3_struct 1 #define scm_tc3_int_1 (scm_tc2_int + 0) -#define scm_tc3_unused 3 +#define scm_tc3_aligned_pointer 3 #define scm_tc3_imm24 4 #define scm_tc3_tc7_1 5 #define scm_tc3_int_2 (scm_tc2_int + 4) --=-=-=--