From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 34CCB7FACB for ; Sat, 6 Sep 2014 09:47:48 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of frederic.bour@lakaban.net) identity=pra; client-ip=213.251.185.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="frederic.bour@lakaban.net"; x-sender="frederic.bour@lakaban.net"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of frederic.bour@lakaban.net designates 213.251.185.180 as permitted sender) identity=mailfrom; client-ip=213.251.185.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="frederic.bour@lakaban.net"; x-sender="frederic.bour@lakaban.net"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail.lakaban.net) identity=helo; client-ip=213.251.185.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="frederic.bour@lakaban.net"; x-sender="postmaster@mail.lakaban.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqwEAA67ClTV+7m0/2dsb2JhbABAGoNgV4J8sAyENJFyh0wBgRl3hAQBBSMECwEFCAEBLAoCDwsYAgIFBBILAgIJAwIBAgEzEhMGAgEBDogcAxUJNqhYeIUCAQWJPAOGZAERBoEsjiiCeYFThQ8Fhh+HEYMvgjuGH4VgjWqDZmcBgk4BAQE X-IPAS-Result: AqwEAA67ClTV+7m0/2dsb2JhbABAGoNgV4J8sAyENJFyh0wBgRl3hAQBBSMECwEFCAEBLAoCDwsYAgIFBBILAgIJAwIBAgEzEhMGAgEBDogcAxUJNqhYeIUCAQWJPAOGZAERBoEsjiiCeYFThQ8Fhh+HEYMvgjuGH4VgjWqDZmcBgk4BAQE X-IronPort-AV: E=Sophos;i="5.04,478,1406584800"; d="scan'208";a="93292305" Received: from pepper.lakaban.net (HELO mail.lakaban.net) ([213.251.185.180]) by mail2-smtp-roc.national.inria.fr with ESMTP; 06 Sep 2014 09:47:47 +0200 Received: from [192.168.1.33] (broadband-46-188-125-94.2com.net [46.188.125.94]) (Authenticated sender: defre@ygg-drasil.fr) by mail.lakaban.net (Postfix) with ESMTPSA id A894327A8C0 for ; Sat, 6 Sep 2014 07:34:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=lakaban.net; s=default; t=1409988871; bh=CC2YuPLwr7aSHJ81JEi96m7rCwsX07r6Qfm20rSPZVQ=; h=Date:From:To:Subject:References:In-Reply-To:From; b=yPIWr3A1PQwdM8HTCLDKIX+/Dmt0S2p3UVb+lMjmVu7bxnr+G6SPHWZNdIrkXZ98m Fr9nX+zhG/4SDBBwNrII+v9sgbzLu2bFngVnPjKEQqp05o166pQPW8KggIDJ+M1WvX I7Cz3t7xp+K+6M7ypfhnDj+0HkIrLVHlD+8nrIPw= Message-ID: <540ABBED.8080307@lakaban.net> Date: Sat, 06 Sep 2014 11:46:53 +0400 From: =?UTF-8?B?RnLDqWTDqXJpYyBCb3Vy?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: caml-list@inria.fr References: <20140905215626.GB3416@annexia.org> <20140905221302.GE3099@annexia.org> <20140905221813.GC3416@annexia.org> <540A3B85.6010609@ens-lyon.org> <540AA0DB.1040202@ens-lyon.org> In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [Caml-list] segfault in simple program with 4.02 native Since it is generated code and offsets of the fields are already known, Obj.new_block / Obj.set_field / Obj.repr could do it too. The Obj.repr will be the only point were the typed version is introduced and it won't receive any mutation after that, this should be enough to make it works. Of course, this might not be robust against future changes. On 06/09/2014 10:00, Milan Stanojević wrote: > Could you do a dirty trick where you define a record that is the same > as the one you have now except that is has mutable fields, then you do > your parsing like now and then at the end return a record with > immutable fields (using (Obj.magic mutable : immutable)? You just need > to make sure that your mutable record doesn't escape your code. > > On Sat, Sep 6, 2014 at 1:51 AM, Martin Jambon > wrote: >> On Fri 05 Sep 2014 05:12:44 PM PDT, Jeremy Yallop wrote: >>> On 6 September 2014 00:39, Martin Jambon >>> wrote: >>>> That code is generated by atdgen. What happens is that we have to either >>>> create an empty record when starting to parse a list of unordered JSON >>>> fields, or use a bunch `let = ref None in` for each field >>>> and >>>> create the record in the end. While the latter approach is not much more >>>> work to implement, the resulting code was found to be significantly >>>> slower. >>>> >>>> The reason why it's using `Obj.magic 0.0` is that it worked in all cases >>>> (and has been for the past 4 years). Obtaining a well-formed constant >>>> value >>>> for any type is not trivial, so this what we have. >>>> >>>> It's very possible that it's now broken with OCaml 4.02. First try a >>>> 'make >>>> test' from atdgen's source directory (https://github.com/mjambon/atdgen) >>>> and >>>> see if it passes. >>> >>> It does seem to be broken, and the change in behaviour with 4.0.2 is >>> apparently due to improved constant propagation >>> (http://caml.inria.fr/mantis/view.php?id=5779). >>> >>> The compiler now takes more advantage of immutability to improve the >>> memory usage and performance of programs. It's safe (or ought to be >>> safe) to assume that immutable record fields are never updated, so the >>> values used to initialize the fields can be propagated to other parts >>> of the program. Here's a small example that shows the change in >>> behaviour between 4.01 and 4.02. >>> >>> type t = { s : string } >>> let x = { s = "one" } >>> let () = Obj.(set_field (repr x) 0 (repr "two")) >>> let () = print_endline x.s >>> >>> Using OCaml 4.01 the third line overwrites the field 's' and the >>> fourth line reads the updated field and prints "two". Using OCaml >>> 4.02 the initial value of the field is propagated past the write to >>> the code in the fourth line, so the program prints "one". >>> >>> The code currently generated by atdgen assumes that it's safe to treat >>> fields as if they were mutable -- that is, it assumes that it's safe >>> to initialize a field with a value of the wrong type, so long as the >>> value is overwritten before the field is first read. I don't think >>> such tricks were ever explicitly guaranteed to work, but they're now >>> much more likely to fail, leading to the dummy initial value being >>> accessed at an inappropriate type. >> >> Thanks for the explanation, Jeremy. I guess atdgen will have to use "option >> refs" after all unless someone has a better idea. >> >> ATD definition: >> >> type t = { >> ?field0: foo option; >> ~field1: string; >> field2: int; >> } >> >> Generated OCaml code: >> >> let field0 = ref None in >> let field1 = ref "" in >> let field2 = ref None in >> ... >> (* parse json fields coming in an unknown order *) >> ... >> { >> field0 = !field0; >> field1 = !field1; >> field2 = (match !field2 with None -> error ... | Some x - >x); >> >> } >> >> >> -- >> Caml-list mailing list. Subscription management and archives: >> https://sympa.inria.fr/sympa/arc/caml-list >> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners >> Bug reports: http://caml.inria.fr/bin/caml-bugs