Re: [MLton] Object allocation code path
Matthew Fluet <[email protected]> Fri, 4 Feb 2022 15:54:39 -0500
| Newsgroups | gmane.comp.lang.ml.mlton.devel |
|---|---|
| Message-ID | <CAMrhFL4uAOLE7rhf8GGxTozZN7t6MhPW5hVRWxVxiuTr0LHJ=Q@mail.gmail.com> |
--===============5234004293759209934== Content-Type: multipart/alternative; boundary="00000000000039f13f05d7377608" --00000000000039f13f05d7377608 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Feb 3, 2022 at 6:31 PM Jeffrey Murphy <[email protected]> wrote: > > > On Wed, Feb 2, 2022 at 1:20 PM Matthew Fluet <[email protected]> > wrote: > >> Hi Jeff, >> >> On Fri, Jan 28, 2022 at 12:54 AM Jeffrey Murphy <[email protected]> >> wrote: >> >>> I'm currently working on reading through the compiler code and >>> understanding how variables go from the AST layer through to the machin= e >>> layer. I would like to experiment with how objects are packed. I've bee= n >>> looking at, eg, packed-representation, and trying to understand how a >>> (normal) variable associated with a function is transformed into an >>> object/offset. Are there detailed descriptions of how MLton transforms = code >>> at each layer, other than what is on mlton.org >>> <https://nam12.safelinks.protection.outlook.com/?url=3Dhttp%3A%2F%2Fmlt= on.org%2F&data=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd21d84b40f8= 09ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C6377942282184= 34226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6I= k1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3DkC4NQgMKUHmj9Johv9iKfivGeq9QuBMuKEW7nM= Xwwos%3D&reserved=3D0> >>> or in "An LLVM back-end for MLton" (Leibig)? >>> >> >> The only documentation is what is at mlton.org >> <https://nam12.safelinks.protection.outlook.com/?url=3Dhttp%3A%2F%2Fmlto= n.org%2F&data=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd21d84b40f80= 9ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C63779422821843= 4226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik= 1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3DkC4NQgMKUHmj9Johv9iKfivGeq9QuBMuKEW7nMX= wwos%3D&reserved=3D0> >> and the code itself. >> >> It might help if you could describe a little more about what kinds of >> transformations you are trying to make. Object allocation and >> representation is pretty much entirely implicit from the front-end all t= he >> way to the RSSA IR. Any constructor application (e.g., `h :: t`), recor= d >> or tuple expression, or function expression is an implicit object >> allocation; there are also a few primitives that correspond to object >> allocation (creation of arrays, references, and weak pointers). But, >> because representations are not dictated by the language semantics, MLto= n >> is able to do a lot of transformations that may significantly alter what >> you thought of as source allocation. Components of tuples and construct= ors >> might be eliminated (because they are unused or they have constant value= s), >> tuples might be flattened into containing constructors/tuples/sequences, >> tuples might be eliminated entirely (turning a function that takes and >> returns a single tuple value to a function that takes and returns multip= le >> values), etc. >> >> >>> I'd like to understand how MLton tracks and transforms SML and the >>> associated functions so that I can influence how normals are allocated.= For >>> example, (this is contrived!), if I wanted to pack normals together tha= t >>> are allocated by functions that begin with the letter "t", how can I mo= re >>> easily learn which source files, or passes should I focus on with respe= ct >>> to how the code is parsed and transformed? I think after the coreml->= xml >>> transform, function names are discarded. Additional variables may be >>> introduced (for example I think LocalRef might convert refs in some >>> circumstances) and so if the function name is discarded by the time SSA= is >>> reached... >>> >> >> All of the source code information is discarded during elaboration (type >> checking). So, any names in the CoreML are just identifiers that may an >> initial "printName" associated with them from the source language, but t= hat >> carries no semantic information. If you really needed to capture some >> aspect of the source function at which an allocation happened, then you >> would probably need to tag that during elaboration. For example, here i= s >> where we type check an AST Record expression and create a CoreML record >> expression: >> >> https://github.com/MLton/mlton/blob/master/mlton/elaborate/elaborate-cor= e.fun#L3690-L3699 >> <https://nam12.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fgit= hub.com%2FMLton%2Fmlton%2Fblob%2Fmaster%2Fmlton%2Felaborate%2Felaborate-cor= e.fun%23L3690-L3699&data=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd= 21d84b40f809ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C637= 794228218434226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzI= iLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3D5UofmpD%2FS1ENWQdDcY8rm6q6BM= IRMMmHan1YK7amWQU%3D&reserved=3D0> >> In scope is `nest : Nest.t (* =3D string list *)` and `maybeName : strin= g >> option` which, to some degree, capture the nesting of module and functio= n >> names leading to this point. If you needed to track "where" an allocati= on >> came from, this is where you would obtain it and you would then need to = add >> that to the `Cexp.Record` constructor and carry that information through >> the subsequent IRs. You would also need to decide what to do when >> performing those transformations described above, as well as deciding wh= at >> to do when the compiler introduces an allocated object directly (without= a >> clear source location). Profiling is the closest thing that we have to >> tracking source location information through the compiler; see >> http://mlton.org/HowProfilingWorks >> <https://nam12.safelinks.protection.outlook.com/?url=3Dhttp%3A%2F%2Fmlto= n.org%2FHowProfilingWorks&data=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C= 07adfd21d84b40f809ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0= %7C637794228218434226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV= 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3DYBsl7Ll%2FkfI20fq7FGv5= utbIZobB5pQfGDV7Z1Npsas%3D&reserved=3D0> >> for some details on that. >> >> In your contrived example, I'm not sure what you mean by "pack normals >> together". Do you mean allocate them differently from other objects (e.= g., >> into a different heap)? Or do you mean pack them together into one larg= er >> object? >> > > By "normals" I mean not arrays or stacks. I think to make things simpler, > I would like to exclude refs also. > I was asking more about what you meant by "pack together". > To provide more context, we have a GC that is similar to a region based > GC. Each MLton Object[1] is encapsulated in a region. While we can merge > multiple Objects into a region, on a block by block basis, I am intereste= d > in a less obvious packing approach that involves merging Objects across > unrelated functions. In particular, I want the compiler to decide how to = do > this. I think doing the packing as late as possible, in RSSA, lets me > ignore what the Object contains, and only have to deal with the size. > However, and maybe I'm thinking about this the wrong way, I feel like I > need to know which two (or more) unrelated SML functions' Objects should = be > packed into the same region, and that bit of information is not available > in RSSA (easily at least). One thought is to just manually determine its > "x_100 and x_200" for now and leave the function name propagation (as you > propose below) for later. I haven't thought too much about that because t= he > actual merging of Objects is what I'm trying to do first. > Well, if the compiler is making the decision about which objects to pack together, then I would pursue some kind of analysis that you can do on the RSSA IR program to determine which objects to pack, rather than relying on some heuristic based on the source code. > At the moment, I have the packing algorithm implemented as an external > tool and I would like to do the following (I'm speculating a lot here). > Assume we have function A which calls B. We also have C and D which are > unrelated to each other or to A/B. Assume optimization passes do not > eliminate any of these. > > 1. save, as part of "-keep", the call tree and allocations. something lik= e > > "A vars x_1599 size 8, x_1601 size 12, ..." > "A calls B" > "B vars x_7777 size 8, x_8888, size 12, ..." > "C vars x_299 size 8, ..." > "D vars x_333 size 8, ..." > > 2. Produce 'packing' instructions (in the absence of which the compiler > will leave things as is -- in other words each object is encapsulated in = a > region by itself). Assuming the tool is told "pack functions A, B, C" the > 'packing' instructions might look like > > "region_0: x_1599, x_1601, x_7777, x_8888, x_299" > "region_1: x_333" > > and when I rerun the compilation, but with, say "-packing > instructions.txt", the compiler will take x_1599, wrap it in a region at > offset 0, then place X_1601 in the same but at offset 20, and so on. I > would include each Object header (and so the offsets into the region woul= d > need to account for that) as well so the machine output would (hopefully) > not need any substantial changes (I would need to adjust the Move operand > so it is aware of the region offset, I'm not sure what else may be > impacted?) My plan for "who allocates the region since you might not know > if A runs before C or vice versa" would be to (in this initial > implementation) to keep a runtime array of regions and if, at the start o= f > a block, an allocation were to occur, it would first see if there is a > memory address in the region slot the allocation was assigned to and then > use that, otherwise create a region and record it. > > Advice on whether I'm approaching this reasonably (by focusing on RSSA) i= s > welcome! > I'm still kind of confused by this. An object allocation in the program may be executed many times, each time allocating a different object. So, I don't understand what it would mean to place X_1601 at offset 20 of some region --- what happens when the `val x_1601 =3D ...` statement is executed again (e.g., in a loop)? Do you use a new region? In which case, trying to place allocations from different source functions into the same region seems very tricky. MLton's object allocation strategy is just "bump pointer" allocation. An object is always allocated at the frontier ( https://github.com/MLton/mlton/blob/master/mlton/backend/machine.fun#L456); there is no offset to determine where the object is allocated. I could see an approach where you have a (fixed) number of regions/frontiers, and each object allocation is (statically) directed at one of them. When to GC becomes more complicated. In a full region-based memory management system, you would have a dynamic number of regions and each object handle would (dynamically) use a region handle. -Matthew --00000000000039f13f05d7377608 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr"><div class=3D"gmail_default" style=3D"fon= t-family:arial,sans-serif;font-size:large"></div></div><br><div class=3D"gm= ail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Thu, Feb 3, 2022 at 6:3= 1 PM Jeffrey Murphy <<a href=3D"mailto:[email protected]">jcmurphy@bu= ffalo.edu</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style= =3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding= -left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><br></div><br><div class=3D"gm= ail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, Feb 2, 2022 at 1:2= 0 PM Matthew Fluet <<a href=3D"mailto:[email protected]" target=3D= "_blank">[email protected]</a>> wrote:<br></div><blockquote class= =3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg= b(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div dir=3D"ltr"><div sty= le=3D"font-family:arial,sans-serif;font-size:large">Hi Jeff,</div><div dir= =3D"ltr" class=3D"gmail_attr"><br></div><div dir=3D"ltr" class=3D"gmail_att= r">On Fri, Jan 28, 2022 at 12:54 AM Jeffrey Murphy <<a href=3D"mailto:jc= [email protected]" target=3D"_blank">[email protected]</a>> wrote:<b= r></div></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" = style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pa= dding-left:1ex"><div dir=3D"ltr">I'm currently working on reading throu= gh the compiler code and understanding how variables go from the AST layer = through to the machine layer. I would like to experiment with how objects a= re packed. I've been looking at, eg, packed-representation, and trying = to understand how a (normal) variable associated with a function is transfo= rmed into an object/offset. Are there detailed descriptions of how MLton tr= ansforms code at each layer, other than what is on <a href=3D"https://nam12= .safelinks.protection.outlook.com/?url=3Dhttp%3A%2F%2Fmlton.org%2F&data= =3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd21d84b40f809ec08d9e678ab= b5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C637794228218434226%7CUnknow= n%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI= 6Mn0%3D%7C3000&sdata=3DkC4NQgMKUHmj9Johv9iKfivGeq9QuBMuKEW7nMXwwos%3D&a= mp;reserved=3D0" target=3D"_blank">mlton.org</a> or in "An LLVM back-e= nd for MLton" (Leibig)? <br></div></blockquote><div><br></div><div><di= v style=3D"font-family:arial,sans-serif;font-size:large">The only documenta= tion is what is at <a href=3D"https://nam12.safelinks.protection.outlook.co= m/?url=3Dhttp%3A%2F%2Fmlton.org%2F&data=3D04%7C01%7Cjcmurphy%40g-mail.b= uffalo.edu%7C07adfd21d84b40f809ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a= 20250%7C0%7C0%7C637794228218434226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAw= MDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3DkC4NQ= gMKUHmj9Johv9iKfivGeq9QuBMuKEW7nMXwwos%3D&reserved=3D0" target=3D"_blan= k">mlton.org</a> and the code itself.</div><div style=3D"font-family:arial,= sans-serif;font-size:large"><br></div><div style=3D"font-family:arial,sans-= serif;font-size:large">It might help if you could describe a little more ab= out what kinds of transformations you are trying to make.=C2=A0 Object allo= cation and representation is pretty much entirely implicit from the front-e= nd all the way to the RSSA IR.=C2=A0 Any constructor application (e.g., `h = :: t`), record or tuple expression, or function expression is an implicit o= bject allocation; there are also a few primitives that correspond to object= allocation (creation of arrays, references, and weak pointers).=C2=A0 But,= because representations are not dictated by the language semantics, MLton = is able to do a lot of transformations that may significantly alter what yo= u thought of as source allocation.=C2=A0 Components of tuples and construct= ors might be eliminated (because they are unused or they have constant valu= es), tuples might be flattened into containing constructors/tuples/sequence= s, tuples might be eliminated entirely (turning a function that takes and r= eturns a single tuple value to a function that takes and returns multiple v= alues), etc.<br></div></div><div>=C2=A0</div><blockquote class=3D"gmail_quo= te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204= );padding-left:1ex"><div dir=3D"ltr"><div>I'd like to understand how ML= ton=C2=A0tracks and transforms SML and the associated functions so that=C2= =A0I can influence how normals are allocated. For example, (this is contriv= ed!), if I wanted to pack normals together that are allocated by functions = that begin with the letter "t", how can I more easily learn which= source files, or passes should I focus on with respect to how the code is = parsed and transformed?=C2=A0 =C2=A0I think after the coreml->xml transf= orm, function names are discarded. Additional variables may be introduced (= for example I think LocalRef might convert refs in some circumstances) and = so if the function name is discarded by the time SSA is reached...</div></d= iv></blockquote><div><br></div><div><div style=3D"font-family:arial,sans-se= rif;font-size:large">All of the source code information is discarded during= elaboration (type checking).=C2=A0 So, any names in the CoreML are just id= entifiers that may an initial "printName" associated with them fr= om the source language, but that carries no semantic information.=C2=A0 If = you really needed to capture some aspect of the source function at which an= allocation happened, then you would probably need to tag that during elabo= ration.=C2=A0 For example, here is where we type check an AST Record expres= sion and create a CoreML record expression:</div><div style=3D"font-family:= arial,sans-serif;font-size:large">=C2=A0 <a href=3D"https://nam12.safelinks= .protection.outlook.com/?url=3Dhttps%3A%2F%2Fgithub.com%2FMLton%2Fmlton%2Fb= lob%2Fmaster%2Fmlton%2Felaborate%2Felaborate-core.fun%23L3690-L3699&dat= a=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd21d84b40f809ec08d9e678a= bb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C637794228218434226%7CUnkno= wn%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVC= I6Mn0%3D%7C3000&sdata=3D5UofmpD%2FS1ENWQdDcY8rm6q6BMIRMMmHan1YK7amWQU%3= D&reserved=3D0" target=3D"_blank">https://github.com/MLton/mlton/blob/m= aster/mlton/elaborate/elaborate-core.fun#L3690-L3699</a></div><div style=3D= "font-family:arial,sans-serif;font-size:large">In scope is `nest : Nest.t (= * =3D string list *)` and `maybeName : string option` which, to some degree= , capture the nesting of module and function names leading to this point.= =C2=A0 If you needed to track "where" an allocation came from, th= is is where you would obtain it and you would then need to add that to the = `Cexp.Record` constructor and carry that information through the subsequent= IRs.=C2=A0 You would also need to decide what to do when performing those = transformations described above, as well as deciding what to do when the co= mpiler introduces an allocated object directly (without a clear source loca= tion).=C2=A0 Profiling is the closest thing that we have to tracking source= location information through the compiler; see <a href=3D"https://nam12.sa= felinks.protection.outlook.com/?url=3Dhttp%3A%2F%2Fmlton.org%2FHowProfiling= Works&data=3D04%7C01%7Cjcmurphy%40g-mail.buffalo.edu%7C07adfd21d84b40f8= 09ec08d9e678abb5%7C96464a8af8ed40b199e25f6b50a20250%7C0%7C0%7C6377942282184= 34226%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6I= k1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=3DYBsl7Ll%2FkfI20fq7FGv5utbIZobB5pQf= GDV7Z1Npsas%3D&reserved=3D0" target=3D"_blank">http://mlton.org/HowProf= ilingWorks</a> for some details on that.</div><div style=3D"font-family:ari= al,sans-serif;font-size:large"><br></div><div style=3D"font-family:arial,sa= ns-serif;font-size:large">In your contrived example, I'm not sure what = you mean by "pack normals together".=C2=A0 Do you mean allocate t= hem differently from other objects (e.g., into a different heap)?=C2=A0 Or = do you mean pack them together into one larger object?<br></div></div></div= ></div></blockquote><div><br></div><div>By "normals" I mean not a= rrays=C2=A0or stacks. I think to make things simpler, I would like to exclu= de refs also.<br></div></div></div></blockquote><div><br></div><div><div st= yle=3D"font-family:arial,sans-serif;font-size:large" class=3D"gmail_default= ">I was asking more about what you meant by "pack together".<br><= /div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg= in:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1e= x"><div dir=3D"ltr"><div class=3D"gmail_quote"><div></div><div>To provide m= ore context, we have a GC that is similar to a region based GC. Each MLton = Object[1] is encapsulated in a region. While we can merge multiple Objects = into a region, on a block by block basis,=C2=A0I am interested in a less ob= vious packing approach that involves merging Objects across unrelated funct= ions. In particular, I want the compiler to decide how to do this. I think = doing the packing as late as possible, in RSSA, lets me ignore what the Obj= ect contains, and only have to deal with the size. However, and maybe I'= ;m thinking about this the wrong way, I feel like I need to know which two = (or more) unrelated SML functions' Objects should be packed into the sa= me region, and that bit of information is not available in RSSA (easily at = least). One thought is to just manually determine its "x_100 and x_200= " for now and leave the function name propagation (as you propose belo= w) for later. I haven't thought too much about that because the actual = merging of Objects is what I'm trying to do first.<br></div></div></div= ></blockquote><div><br></div><div><div style=3D"font-family:arial,sans-seri= f;font-size:large" class=3D"gmail_default">Well, if the compiler is making = the decision about which objects to pack together, then I would pursue some= kind of analysis that you can do on the RSSA IR program to determine which= objects to pack, rather than relying on some heuristic based on the source= code.<br></div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st= yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd= ing-left:1ex"><div dir=3D"ltr"><div class=3D"gmail_quote"><div></div><div>A= t the moment, I have the packing algorithm implemented as an external tool = and I would like to do the following (I'm speculating a lot here). Assu= me we have function A which calls B. We also have C and D which are unrelat= ed to each other or to A/B. Assume optimization passes do not eliminate any= of these.=C2=A0</div><div><br></div><div>1. save, as part of "-keep&q= uot;, the call tree and allocations. something like=C2=A0</div><div><br></d= iv><div>"A vars x_1599 size 8, x_1601 size 12, ..."</div><div>&qu= ot;A calls B"</div><div>"B vars x_7777 size 8, x_8888, size 12, .= .."</div><div><div>"C vars x_299 size 8, ..."</div>"D v= ars x_333 size 8, ..."<br></div><div><br></div><div>2. Produce 'pa= cking' instructions (in the absence of which the compiler will leave th= ings as is -- in other words each object is encapsulated=C2=A0in a region b= y itself). Assuming the tool is told "pack functions A, B, C" the= 'packing' instructions might look like</div><div><br></div><div>&q= uot;region_0: x_1599, x_1601, x_7777, x_8888, x_299"</div><div>"r= egion_1: x_333"</div><div><br></div><div>and when I rerun the compilat= ion, but with, say "-packing instructions.txt", the compiler will= take x_1599, wrap it in a region at offset 0, then place X_1601 in the sam= e but at offset 20, and so on. I would include each Object header (and so t= he offsets into the region would need to account for that) as well so the m= achine output would (hopefully) not need any substantial changes (I=C2=A0wo= uld need to adjust the Move operand so it is aware of the region offset, I&= #39;m not sure what else may be impacted?) My plan for "who allocates = the region since you might not know if A runs before C or vice versa" = would be to (in this initial implementation) to keep a runtime array of reg= ions and if, at the start of a block, an allocation were to occur, it would= first see if there is a memory address in the region slot the allocation w= as assigned to and then use that, otherwise create a region and record it.= =C2=A0</div><div><br></div><div>Advice on whether I'm approaching this = reasonably (by focusing on RSSA) is welcome!</div></div></div></blockquote>= <div><br></div><div style=3D"font-family:arial,sans-serif;font-size:large" = class=3D"gmail_default">I'm still kind of confused by this.=C2=A0 An ob= ject allocation in the program may be executed many times, each time alloca= ting a different object.=C2=A0 So, I don't understand what it would mea= n to place X_1601 at offset 20 of some region --- what happens when the `va= l x_1601 =3D ...` statement is executed again (e.g., in a loop)?=C2=A0 Do y= ou use a new region?=C2=A0 In which case, trying to place allocations from = different source functions into the same region seems very tricky.</div><di= v style=3D"font-family:arial,sans-serif;font-size:large" class=3D"gmail_def= ault"><br></div><div style=3D"font-family:arial,sans-serif;font-size:large"= class=3D"gmail_default">MLton's object allocation strategy is just &qu= ot;bump pointer" allocation.=C2=A0 An object is always allocated at th= e frontier (<a href=3D"https://github.com/MLton/mlton/blob/master/mlton/bac= kend/machine.fun#L456">https://github.com/MLton/mlton/blob/master/mlton/bac= kend/machine.fun#L456</a>); there is no offset to determine where the objec= t is allocated.</div><div style=3D"font-family:arial,sans-serif;font-size:l= arge" class=3D"gmail_default"><br></div><div style=3D"font-family:arial,san= s-serif;font-size:large" class=3D"gmail_default">I could see an approach wh= ere you have a (fixed) number of regions/frontiers, and each object allocat= ion is (statically) directed at one of them.=C2=A0 When to GC becomes more = complicated.=C2=A0 In a full region-based memory management system, you wou= ld have a dynamic number of regions and each object handle would (dynamical= ly) use a region handle.</div><div style=3D"font-family:arial,sans-serif;fo= nt-size:large" class=3D"gmail_default"><br></div><div style=3D"font-family:= arial,sans-serif;font-size:large" class=3D"gmail_default">-Matthew<br></div= ><div style=3D"font-family:arial,sans-serif;font-size:large" class=3D"gmail= _default"><br></div></div></div> --00000000000039f13f05d7377608-- --===============5234004293759209934== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline --===============5234004293759209934== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ MLton-devel mailing list [email protected]; [email protected] https://lists.sourceforge.net/lists/listinfo/mlton-devel --===============5234004293759209934==--