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 7B5C77F7B4 for ; Sat, 1 Feb 2014 16:40:46 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of goswin-v-b@web.de) identity=pra; client-ip=212.227.15.3; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="goswin-v-b@web.de"; x-sender="goswin-v-b@web.de"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of goswin-v-b@web.de) identity=mailfrom; client-ip=212.227.15.3; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="goswin-v-b@web.de"; x-sender="goswin-v-b@web.de"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mout.web.de) identity=helo; client-ip=212.227.15.3; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="goswin-v-b@web.de"; x-sender="postmaster@mout.web.de"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aj0CAEkV7VLU4w8DnGdsb2JhbABZvCqFUoEHFg4BAQEBAQYNCQkUKIIlAQEEAScTPwULCxgJJQ8FKCGIAwEMDMJ/H4lrF44xWAeDJIEUBJgphjISjwyBZw X-IPAS-Result: Aj0CAEkV7VLU4w8DnGdsb2JhbABZvCqFUoEHFg4BAQEBAQYNCQkUKIIlAQEEAScTPwULCxgJJQ8FKCGIAwEMDMJ/H4lrF44xWAeDJIEUBJgphjISjwyBZw X-IronPort-AV: E=Sophos;i="4.95,760,1384297200"; d="scan'208";a="56430223" Received: from mout.web.de ([212.227.15.3]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 01 Feb 2014 16:40:46 +0100 Received: from frosties.localnet ([37.49.32.119]) by smtp.web.de (mrweb102) with ESMTPSA (Nemesis) id 0MTyDl-1Vj3F61oJ7-00Qj44 for ; Sat, 01 Feb 2014 16:40:45 +0100 Received: from mrvn by frosties.localnet with local (Exim 4.80) (envelope-from ) id 1W9cgW-0000en-OJ; Sat, 01 Feb 2014 16:40:44 +0100 Date: Sat, 1 Feb 2014 16:40:44 +0100 From: Goswin von Brederlow To: Yotam Barnoy Cc: Ocaml Mailing List Message-ID: <20140201154044.GE1783@frosties> References: <20140120101654.GI26447@frosties> <08bc01cf17b8$9263d070$b72b7150$@ffconsultancy.com> <20140123092925.GB20624@frosties> <01c401cf1891$b1fb1360$15f13a20$@ffconsultancy.com> <026101cf18dd$756c13d0$60443b70$@ffconsultancy.com> <030501cf1925$45380fa0$cfa82ee0$@ffconsultancy.com> <20140127152944.GA29326@frosties> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Provags-ID: V03:K0:94hHO1IKNdqCrB9+cRcOi+AX7xtZT+AdSy07zBJel3pc+AnNCxb fOxTnnfbxA7ctRGOLVm8+FCL9Jxqe8czsGLVJzpFJZhaFxJmUpueDCkHQ+qVWizlVcQdCgg agFT34JipOnxGVW9OE8cYtmT1rD4cZe+c9gL1yptQDiqLT4Kj2hoQ1thljnGm4I5RLbL1Mw 1m+HkHBQOXQrA/TFLZhqw== Subject: Re: [Caml-list] How much optimized is the 'a option type ? On Mon, Jan 27, 2014 at 11:18:23AM -0500, Yotam Barnoy wrote: > > > > But you can't just put a float 42.0 on the heap or even stack when the > > GC might get called. That needs to be boxed in some way to avoid it > > getting misread as pointer. > > > > > It wouldn't be too hard to add a word of metadata to the stack to tell the > GC what's a pointer and what isn't. Haskell does this for function calls > (in fact, if the metadata doesn't fit in a word, it allocates a separate > metadata structure), and F# has this from the .NET runtime which has full > type metadata for everything. You can do that. It's called BOXING. Even if you create just a single box for the whole stackframe of the function it is still a box. See the other thread about changing the in memory represenation of ocaml for how to improve having boxed with mixed content so int32/int64/float don't need extra boxing on their own. > Problem is that a value is a fixed size and fits in a register. A > > tuple does not. (int * float) even takes the space of 3 values on > > 32bit. You can unbox that in the optimizer for local use but in memory > > and in function calls you need to pass this as box. Otherwise > > polymorphic functions break. > > > > Putting larger structures into an array without boxing also only works > > for immutable objects and by copying them every time they are passed > > around. You can't copy a mutable and you can't pass a pointer to the > > middle of an array to another function or the GC might freak out. > > > > Leaving it to the optimizer is problematic because it might cause a lot of > unneeded boxing and unboxing. > Haskell has the {- #UNPACK -} pragma to unbox types. You have to be really > careful in haskell with this, because you're also changing the evaluation > semantics to be strict. This makes for really ugly optimized haskell code, > but maybe we can do something similar (but not as ugly). F# inherits .NET's > struct types, which are similarly limited, but also useful. Of course, once > you unbox, all parametric polymorphism is lost, but because you have > control over it, you can decide where it's worthwhile. > > An example of unpack usage in haskell: > > data T = T {-# UNPACK #-} !(Int,Int) > > which would be equivalent to something like > type t = (int * int) [@u] > > Note that the whole tuple is unboxed. > > In haskell, you can now do > > f :: T -> Int > f (T(i1,i2)) = i1 + i2 > > and in ocaml you'd do > > let f : t -> int = fun (i1,i2) = i1 + i2 > > Of course, this would require more metadata for the stack. For the heap, > you'd probably want to just use a new tag or the custom tag. For ocaml > you'd also probably have to stipulate that polymorphic marshalling cannot > be performed on this type, and neither can polymorphic comparison -- you'd > have to have specific marshalling/comparison functions, which aren't too > difficult to generate automatically. > > -Yotam Consider this: type ['a] tt = ('a * 'a) [@u] let ff : 'a tt -> ('a -> int) -> int = fun (t1, t2) f = f t2 let x = ff ((1, 2), (3, 4)) f The ff function is tail recursive so f is called with the arguments of ff no longer registered with the GC. And f is passed a pointer to the middle of the tt type. Now lets assume the GC will run inside f. *BOOM* The tt type is no longer reachable so it would be freed. f has a pointer pointing to the middle of a block causing the GC to parse the t1 part of tt type as metadata. Overall verry bad. Boxed and UNPACKed types would have to be incompatible in ocaml. MfG Goswin