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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 086EC7FACB for ; Sat, 6 Sep 2014 21:08:22 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of martin.jambon@ens-lyon.org) identity=pra; client-ip=66.111.4.25; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="martin.jambon@ens-lyon.org"; x-sender="martin.jambon@ens-lyon.org"; x-conformance=sidf_compatible Received-SPF: Neutral (mail3-smtp-sop.national.inria.fr: domain of martin.jambon@ens-lyon.org does not assert whether or not 66.111.4.25 is permitted sender) identity=mailfrom; client-ip=66.111.4.25; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="martin.jambon@ens-lyon.org"; x-sender="martin.jambon@ens-lyon.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@out1-smtp.messagingengine.com) identity=helo; client-ip=66.111.4.25; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="martin.jambon@ens-lyon.org"; x-sender="postmaster@out1-smtp.messagingengine.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aq0BAG1aC1RCbwQZnGdsb2JhbAA/GoNgV4J8sDGENJFzh0wBgQAWEAEBAQEBBg0JCRQphAMBAQQBIwQLAQUILgoBAQQLCxgCAgUEEgsCAgkDAgECATMSBg0BBQIBAQ4JiBMDCQgNNqcheIUIiRYDhmQBEQaBLI4hB4J5gVOFDwWGJocMgy+CPIYlhUgakWxMAYJOAQEB X-IPAS-Result: Aq0BAG1aC1RCbwQZnGdsb2JhbAA/GoNgV4J8sDGENJFzh0wBgQAWEAEBAQEBBg0JCRQphAMBAQQBIwQLAQUILgoBAQQLCxgCAgUEEgsCAgkDAgECATMSBg0BBQIBAQ4JiBMDCQgNNqcheIUIiRYDhmQBEQaBLI4hB4J5gVOFDwWGJocMgy+CPIYlhUgakWxMAYJOAQEB X-IronPort-AV: E=Sophos;i="5.04,479,1406584800"; d="scan'208";a="77996755" Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 06 Sep 2014 21:08:20 +0200 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by gateway2.nyi.internal (Postfix) with ESMTP id 678002009C for ; Sat, 6 Sep 2014 15:08:13 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute2.internal (MEProxy); Sat, 06 Sep 2014 15:08:13 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=message-id:date:from:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; s=smtpout; bh=NQifS8B2AQ62/8rmTe58Ym lTWOo=; b=Ww/w3KTYKyD71EtpHnHdMqM5poqerZoRLFqnSAKJ5jjSKZ5mDp41MY pJUK0wnz+LA8dFraHfHfWiDDkKlTE1U8FrQZHPCma6FVfZKY6WpTXHuTwfk3anP7 TkVDw7u7TzBnlVYm5fR4sVbNiPqXkgESA0ObBNbiHPV5vjJYv1rQA= X-Sasl-enc: R2h4KxdkClyJSX5CSUm7OtPy6EhRad6a2Ej5AD1mah3P 1410030493 Received: from [192.168.2.7] (unknown [67.180.86.2]) by mail.messagingengine.com (Postfix) with ESMTPA id D2E646800DC; Sat, 6 Sep 2014 15:08:12 -0400 (EDT) Message-ID: <540B5B9A.9040207@ens-lyon.org> Date: Sat, 06 Sep 2014 12:08:10 -0700 From: Martin Jambon User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0 MIME-Version: 1.0 To: =?UTF-8?B?TWlsYW4gU3Rhbm9qZXZpxIc=?= CC: Jeremy Yallop , Caml List 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 On 09/05/2014 11:00 PM, 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. I remember considering this solution in the past. It seems it would work. I must say there's a strange feeling about creating more type definitions while breaking the type system. > 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