<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Hi Christoph, <br>
</p>
<p>yes this optimization is possible - <br>
</p>
<p>IMO Pharo/Squeal has a CleanBlockClosure -</p>
<p> I used the term red & green BlockClosure ( demonstrated at a
customer in 2010 )</p>
<p>- implemented in LSWGVM since more than a decade.</p>
Frank
<div class="moz-cite-prefix">On 1/6/2021 01:16, Thiede, Christoph
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:d89f5d40a0644868a5888a61399fd9f9@student.hpi.uni-potsdam.de">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;}</style>
<div id="divtagdefaultwrapper"
style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;"
dir="ltr">
<p>Hi Eliot,</p>
<p><br>
</p>
<p>thanks for the feedback! This is an exciting task and I'll
put it onto my list, I'm looking forward to tackling it
... :-)</p>
<p><br>
</p>
<p>> <span style="font-size: 12pt;">We can, but remember that
passing a block is in fact hiding an allocation, maybe two.
Mentioning a block in code causes it to be allocated and if
not already done so, causes allocation of the lexically
enclosing context.</span></p>
<div><br>
</div>
<div id="Signature">
<div id="divtagdefaultwrapper" dir="ltr" style="font-size:
12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica,
sans-serif, EmojiFont, "Apple Color Emoji",
"Segoe UI Emoji", NotoColorEmoji, "Segoe UI
Symbol", "Android Emoji", EmojiSymbols;">
<div name="divtagdefaultwrapper"
style="font-family:Calibri,Arial,Helvetica,sans-serif;
font-size:; margin:0">
<div>
<div class="_rp_T4" id="Item.MessagePartBody">
<div class="_rp_U4 ms-font-weight-regular
ms-font-color-neutralDark rpHighlightAllClass
rpHighlightBodyClass" id="Item.MessageUniqueBody"
style="font-family:wf_segoe-ui_normal,"Segoe
UI","Segoe
WP",Tahoma,Arial,sans-serif,serif,EmojiFont">
<div dir="ltr">
<div id="divtagdefaultwrapper"><font
face="Calibri,Helvetica,sans-serif,EmojiFont,Apple
Color Emoji,Segoe UI
Emoji,NotoColorEmoji,Segoe UI Symbol,Android
Emoji,EmojiSymbols">
<div id="Signature">
<div style="margin:0px"><font
style="font-family:Calibri,Arial,Helvetica,sans-serif,serif,EmojiFont">
<div><font size="3" color="black"><span
style="font-size:12pt"><a
href="http://www.hpi.de/"
target="_blank" rel="noopener
noreferrer" id="LPNoLP"
moz-do-not-send="true"><font
size="2"><span
id="LPlnk909538"></span></font></a></span></font></div>
</font></div>
</div>
</font></div>
</div>
</div>
</div>
<div class="_rp_T4" id="Item.MessagePartBody">That's
correct, but I believe that it could be possible to
waive any closure variables but only use block
arguments, block returns, and method returns. This
should be relatively fast, shouldn't it?</div>
<div class="_rp_T4" id="Item.MessagePartBody"><br>
</div>
<div class="_rp_T4" id="Item.MessagePartBody">Best,</div>
<div class="_rp_T4" id="Item.MessagePartBody">Christoph</div>
</div>
</div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font style="font-size:11pt"
face="Calibri, sans-serif" color="#000000"><b>Von:</b>
Squeak-dev
<a class="moz-txt-link-rfc2396E" href="mailto:squeak-dev-bounces@lists.squeakfoundation.org"><squeak-dev-bounces@lists.squeakfoundation.org></a> im
Auftrag von Eliot Miranda <a class="moz-txt-link-rfc2396E" href="mailto:eliot.miranda@gmail.com"><eliot.miranda@gmail.com></a><br>
<b>Gesendet:</b> Samstag, 2. Januar 2021 02:45:53<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] Two new curious
Context/primitive questions :-)</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div dir="ltr">
<div class="gmail_default"><font size="4">Hi Christoph,</font><br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Fri, Jan 1, 2021 at
4:18 PM Thiede, Christoph <<a
href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de"
moz-do-not-send="true">Christoph.Thiede@student.hpi.uni-potsdam.de</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"
dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<p>Hi Eliot,</p>
<p><br>
</p>
<p>once again I am very pleasantly surprised by your
professional and detailed answer which was a joy
to read!</p>
<div id="gmail-m_-2979770936573098614Signature">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody">
<div
id="gmail-m_-2979770936573098614Item.MessageUniqueBody"
style="font-family:wf_segoe-ui_normal,"Segoe UI","Segoe
WP",Tahoma,Arial,sans-serif,serif,EmojiFont">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"><font
face="Calibri,Helvetica,sans-serif,EmojiFont,Apple Color Emoji,Segoe UI
Emoji,NotoColorEmoji,Segoe UI
Symbol,Android Emoji,EmojiSymbols">
<div
id="gmail-m_-2979770936573098614Signature">
<div style="margin:0px"><font
style="font-family:Calibri,Arial,Helvetica,sans-serif,serif,EmojiFont">
<div><font size="3"
color="black"><span
style="font-size:12pt"><a
href="http://www.hpi.de/" rel="noopener noreferrer"
id="gmail-m_-2979770936573098614LPNoLP"
target="_blank"
moz-do-not-send="true"><font
size="2"><span
id="gmail-m_-2979770936573098614LPlnk909538"></span></font></a></span></font></div>
</font></div>
</div>
</font></div>
</div>
</div>
</div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><br>
</div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody">> <span
style="font-size:12pt">'Nuff said</span>
<div><br>
</div>
</div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody">No
further questions. This was very
interesting!</div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody">It
also gives me a possible explanation for
why one cannot execute a context
subinstance without any
problems. That's because the marriage
between stack frame and context objects is
hard-coded based on the Context class
(specialObjects at: 11), isn't it?</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><font size="4"><br>
</font></div>
<div class="gmail_default"><font size="4">Indeed. One may be
able to go the other way, create a stack of contexts
whose class is different. These should retain their
class because the associated stack frames will be
married to them. But going the other way is not
supported.</font></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"
dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<div id="gmail-m_-2979770936573098614Signature">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span
style="font-size:12pt">> </span><span
style="font-size:12pt">But beware,
because if one was debugging the
debugger one mustn't confuse a
PrimFailToken created in the simulation
for a PrimFailToken created by the
simulation.</span><br>
</div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><br>
</span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span>Hm, aren't we already in a very
similar situation? I had planned to
write a separate message for this issue,
but here is my case:</span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><br>
</span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span>
<div>{Context primitiveFailTokenFor:
nil} at: 1. "{an Object . nil}"</div>
<div>Context runSimulated: [{Context
primitiveFailTokenFor: nil} at: 1].
"⚡ Error: subscript is out of bounds:
1"</div>
<br>
</span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span>Now one could argue that this is not
a very likely situation to occur ever in
"production", but the same could be said
for a hypothetical #<span>isPrimFailToken
selector, and above all, it precludes
an ideal, i.e. completely transparent
simulation machinery ...<span></span></span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span>So I would like to suggest to
find a different solution for this
problem anyway, provided that you
support this idea in general.</span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span><br>
</span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span>An alternative I could imagine
would be the SetElement pattern from
Collections which is completely
transparent. But this would probably
be too expensive for simulation
purposes (because we would need to
instantiate one object per
simulated primitive call), right?</span></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><font size="4"><br>
</font></div>
<div class="gmail_default"><font size="4">Not sure. If
instantiation can be deferred until failure then things
should be OK.</font></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"
dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<div id="gmail-m_-2979770936573098614Signature">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span>Why not encode a failing
primitive via a changed control
flow? Couldn't we pass an additional
failBlock argument to #<span>doPrimitive:method:receiver:args:, #<span>tryPrimitive:withArgs:/</span>#<span>tryNamedPrimitiveIn:for:withArgs:,
and #<span>simulateValueWithArguments:caller:</span> (and
analogously to ExternalFunction
>> #<span>tryInvokeWithArguments:
and the critsect primitive
methods on Mutex)?</span></span></span></span></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><font size="4"><br>
</font></div>
<div class="gmail_default"><font size="4">We can, but
remember that passing a block is in fact hiding an
allocation, maybe two. Mentioning a block in code
causes it to be allocated and if not already done so,
causes allocation of the lexically enclosing context.</font></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"
dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<div id="gmail-m_-2979770936573098614Signature">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
Then we could rewrite #<span
style="font-size:12pt">send:to:with:lookupIn:
like this (pseudo):</span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span></span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span><br>
</span></span></div>
</div>
</div>
</div>
</div>
</div>
<blockquote style="margin:0px 0px 0px
40px;border:none;padding:0px">
<div dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div>
<div dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span
style="font-family:"Times New
Roman"">send: selector to: rcvr
with: arguments lookupIn: lookupClass</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> "Simulate the action
of sending a message with selector and
arguments to rcvr. The argument,
lookupClass, is the class in which to
lookup the message. This is the
receiver's class for normal messages,
but for super messages it will be some
specific class related to the source
method."</span><br
style="font-family:"Times New
Roman"">
<br style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> | meth <span
style="color:rgb(189,19,152)">
prim</span><span
style="color:rgb(189,19,152)">FailCode</span><span
style="color:rgb(189,19,152)">
</span><span style="color:rgb(0,0,0)">val
</span>ctxt |</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> (meth := lookupClass
lookupSelector: selector) ifNil:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> [selector ==
#doesNotUnderstand: ifTrue:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> [self error:
'Recursive message not understood!'
translated].</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> ^self send:
#doesNotUnderstand:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> to: rcvr</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> with:
{(Message selector: selector
arguments: arguments) lookupClass:
lookupClass}</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> lookupIn:
lookupClass].</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> </span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> meth isCompiledMethod
ifFalse:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> ["Object as
Methods (OaM) protocol: 'The contract
is that, when the VM encounters an
ordinary object (rather than a
compiled method) in the method
dictionary during lookup, it sends it
the special selector #run:with:in:
providing the original selector,
arguments, and receiver.'. DOI:
10.1145/2991041.2991062."</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> ^self send:
#run:with:in:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> to: meth</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> with:
{selector. arguments. rcvr}].</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> </span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> meth numArgs =
arguments size ifFalse:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> [^ self error:
('Wrong number of arguments in
simulated message {1}' translated
format: {selector})].</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> (primIndex := meth
primitive) > 0 ifTrue:</span><br
style="font-family:"Times New
Roman"">
<s style="font-family:"Times New
Roman""><font color="#0000FF">-
[val := self doPrimitive:
primIndex method: meth receiver:
rcvr args: arguments.<br>
- (self isPrimFailToken:
val) ifFalse:<br>
- [^val]].<br>
</font></s><font
style="font-family:"Times New
Roman"" color="#FF0000">+
[val := self doPrimitive:
primIndex method: meth receiver: rcvr
args: arguments ifFail:<br>
+ [:code | primFailCode :=
code].</font></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><font
style="font-family:"Times New
Roman"" color="#FF0000">+
primFailCode ifNil: [^ val]].<br>
</font><span
style="font-family:"Times New
Roman""> </span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> (selector ==
#doesNotUnderstand: and: [lookupClass
== ProtoObject]) ifTrue:</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> [^self error:
('Simulated message {1} not
understood' translated format:
{arguments first selector})].</span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> </span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> ctxt := Context
sender: self receiver: rcvr method:
meth arguments: arguments.</span><br
style="font-family:"Times New
Roman"">
<s style="font-family:"Times New
Roman""><font color="#0000FF">-
(primIndex isInteger and:
[primIndex > 0]) ifTrue:<br>
- [ctxt failPrimitiveWith:
val].<br>
</font></s><font
style="font-family:"Times New
Roman"" color="#FF0000">+
primFailCode ifNotNil:<br>
+ [ctxt failPrimitiveWith:
primFailCode].<br>
</font><span
style="font-family:"Times New
Roman""> </span><br
style="font-family:"Times New
Roman"">
<span style="font-family:"Times New
Roman""> ^ctxt</span><br>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div dir="ltr"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<div>
<div dir="ltr"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span><span><br>
</span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span><span>Current
senders of #<span>primitiveFailTokenFor:
could then evaluate the failBlock if
the primitive fails.</span></span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span><span>Do
you think this approach would be worth
a try? :-)</span></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div><font size="4"><br>
</font></div>
<div class="gmail_default"><font size="4">Definitely. It
might eliminate multiple tests. I think you should
definitely try it. It looks nice to me. Thank you!</font></div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div
id="gmail-m_-2979770936573098614divtagdefaultwrapper"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif"
dir="ltr">
<div dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android Emoji",EmojiSymbols">
<div>
<div dir="ltr"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI
Symbol","Android
Emoji",EmojiSymbols">
<div name="divtagdefaultwrapper">
<div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"><span><span><br>
</span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span>Best,</span></span></div>
<div
id="gmail-m_-2979770936573098614Item.MessagePartBody"
style="font-size:12pt">
<span><span>Christoph</span></span></div>
</div>
</div>
</div>
</div>
</div>
<hr
style="font-size:12pt;display:inline-block;width:98%">
<div id="gmail-m_-2979770936573098614divRplyFwdMsg"
dir="ltr" style="font-size:12pt">
<font style="font-size:11pt" face="Calibri,
sans-serif" color="#000000"><b>Von:</b> Squeak-dev
<<a
href="mailto:squeak-dev-bounces@lists.squeakfoundation.org"
target="_blank" moz-do-not-send="true">squeak-dev-bounces@lists.squeakfoundation.org</a>>
im Auftrag von Eliot Miranda <<a
href="mailto:eliot.miranda@gmail.com"
target="_blank" moz-do-not-send="true">eliot.miranda@gmail.com</a>><br>
<b>Gesendet:</b> Freitag, 1. Januar 2021 22:34:28<br>
<b>An:</b> The general-purpose Squeak developers
list<br>
<b>Betreff:</b> Re: [squeak-dev] Two new curious
Context/primitive questions :-)</font>
<div> </div>
</div>
<div style="font-size:12pt">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div style="font-size:small">errata:<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div class="gmail_attr">On Fri, Jan 1, 2021 at
1:22 PM Eliot Miranda <<a
href="mailto:eliot.miranda@gmail.com"
target="_blank" moz-do-not-send="true">eliot.miranda@gmail.com</a>>
wrote:<br>
</div>
<span style="font-size:large">Hi Christoph,</span><br>
<font size="4"><br>
</font><span style="font-size:large"> happy
new year!!</span><br>
<font size="4"><br>
</font><span style="font-size:large">On Fri,
Jan 1, 2021 at 11:28 AM Thiede, Christoph
<</span><a
href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de"
target="_blank" moz-do-not-send="true">Christoph.Thiede@student.hpi.uni-potsdam.de</a><span
style="font-size:large">> wrote:</span><br>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div>
<div>
<div>
<div class="gmail_quote"><span
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">Hi
all, hi Eliot,</span><br>
<font size="3" face="Calibri,
Helvetica, sans-serif"
color="#000000"><span><br>
</span></font><span
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">new
year, new simulation fun, and I
have collected two new questions
about the Context implementation
which I'd love to get answered
here:</span><br>
<font size="3" face="Calibri,
Helvetica, sans-serif"
color="#000000"><span><br>
</span></font><span
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">First,
I was confused by the following:</span><br>
<span
style="font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe
UI Symbol","Android
Emoji",EmojiSymbols;font-size:16px;color:rgb(0,0,0)">(BlockClosure
>> #numArgs) primitive.
"266"</span><br>
<span
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">(Context
>> #pc) primitive. "0"</span><br>
<div>
<div
id="gmail-m_-2979770936573098614gmail-m_5689234217555540956gmail-m_5405583940077301585divtagdefaultwrapper"
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI Symbol","Android
Emoji",EmojiSymbols">
<div style="font-size:12pt">What
makes Context so special that
it cannot be compiled with
quick accessor methods?</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<font size="4"><br>
</font><span style="font-size:large">The gory
details are here: </span><a
href="http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/"
target="_blank" moz-do-not-send="true">http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/</a><br>
<font size="4"><br>
</font><span style="font-size:large">But
that's full of implementation detail. Let
me try and explain at a higher level.</span><br>
<font size="4"><br>
</font><span style="font-size:large">Contexts
are wonderful but very expensive. Any VM
that actually creates contexts for every
method or block activation will inevitably
run slowly. There are two overheads here.
One is the basic overhead of allocating and
reclaiming the contexts that are created.
The other is the cost of moving the outgoing
receiver and arguments from the sending
context to the new context. A fast VM must
avoid these overheads, and the key solution
is to use a stack frame organization as is
used in conventional language
implementations. The key here is that with
stack frames the receiver and incoming
arguments do not have to be moved; they stay
where they are and a new frame is built
underneath them which includes them as the
incoming receiver and arguments; stack
frames overlap outgoing and incoming
arguments.</span><br>
<font size="4"><br>
</font><span style="font-size:large">But
crucially, in addition the VM must still
create contexts if and when they are
needed. If not, this would no longer be a
Smalltalk-80 implementation. Now one could
imagine a VM which converted stack frames to
contexts whenever a method or block
activation was accessed using thisContext
(or thisContext sender etc which access
contexts by following the sender field).
But that would be very slow. Instead, the
fastest approach is to try and keep stack
frames as stack frames for as long as
possible. For this to work contexts have to
be able to function as "proxy objects" for
stack frames. The VM does indeed create
contexts when one uses thisContext, or even
when one creates a block, but internally the
context is in a very special state, a state
in which it points at a stack frame.</span><br>
<font size="4"><br>
</font><span style="font-size:large">Some
terminology is useful. Peter Deutsch used
"volatile", "hybrid" and "stable". I like
"single", "married", "widowed" and
"divorced" (Peter's scheme didn't have
"widowed" which is the key to why my scheme
is faster, and why the closure
implementation is as it is).</span><br>
<font size="4"><br>
</font><span style="font-size:large">When a
stack frame is created it is "single". It
has a slot within it to refer to a context
object if it is needed, but the slot is nil.</span><br>
<span style="font-size:large">When a
stack frame needs a context object one is
created and the two are "married".</span><br>
<span style="font-size:large">When a method or
block returns its stack frame is discarded;
the stack frame has died and if it was
married its context becomes "widowed". (*)</span><br>
<span style="font-size:large">When space is
needed for new stack frames all reclaimed
stack frames are "divorced" from their
contexts. The stack frame state is written
to the context object and the context object
no longer acts as a proxy; it is a fully
fledged normal stack object. (*)</span><br>
<font size="4"><br>
</font><span style="font-size:large">(*) Stack
frames exist in a small memory zone
organized as stack pages, the stack zone.
The size of the stack zone is set at
startup, and its size is either the VM's
defau<span class="gmail_default"
style="font-size:small">l</span>t or set
by a value that persists in the image header
(see vmParameterAt: 43). Since the system
may run out of stack pages (a deep call
stack, many active processes), the VM makes
new pages available by purging the least
recently used pages to the heap in the form
of context objects. All the frames in the
least recently used stack page are divorced
at the same time. A context must be created
for each frame that is not ye</span><font
size="4">t marrie<span class="gmail_default">d</span><span
class="gmail_default"></span><span
class="gmail_default"></span>.<span
class="gmail_default"></span><span
class="gmail_default"> A page is big
enough to hold on average about 40 method
activations; since activations are of
different sizes and change size as
execution proceeds, the number of
activations per full page varies.</span></font><br>
<font size="4"><br>
(*) The reason why Peter's original scheme
is slower is that <span
class="gmail_default">
in HPS </span>at return time the VM has
to check for <span class="gmail_default">
a frame </span>being <span
class="gmail_default">hybrid</span> and
copy state to the hybrid context, making it
stable. This has to be done because a
closure's outer temporary variables are
stored in the lexically enclosing
stack frame, and so have to be made to
persist in the stable context or their
values will be stale. In my (lisp-derived)
closure implementation there are no such
references to outer temporary variables;
values are either copied if they do not
change, or stored in an Array (the
"indirection vector"), which can then be
copied.<br>
<br>
Note that divorce is a process. Once
divorced a context is single and free to
function as a context does. Indeed when the
system starts up it loads an image which
only contains single contexts. All contexts
are divorced on snapshot.<span
class="gmail_default"> Divorced
contexts are amnesiacs.</span><span
class="gmail_default"></span><br>
<br>
<br>
</font><span style="font-size:large">So now,
finally, we can answer your question. Why
is (Context>>#pc), a method that
simply answers an instance variable, not
compiled as a quick method with a primitive
that answers that variable? "married" and
"widowed" contexts are proxies for stack
frames. Only the instance variables they
contain which do not change can be fetched
from the context object itself; these are
the receiver, arguments, closureOrNil, and
method. sender, pc, stackp and other stack
contents may change as execution proceeds.
These mutable values must be fetched from
the stack frame itself, if it still exists.</span><br>
<font size="4"><br>
</font><span style="font-size:large">All
accesses to sender, pc, stackp, and stack
contents (Context>>at:[put:]) must be
mediated. A married or widowed context has
its sender field set to the frame pointer of
its stack frame, encoded as a SmallInteger.
You can never see this from the image
(except via a special xRay primitive). By
following the frame pointer encoded in the
sender field the VM can detect if the frame
is still live. If so, the relevant
values are synthesized or fetched from the
stack frame itself. If not, the context is
widowed and "mourns"; it is changed into a
context with a nil sender field, a nil pc,
and a stackp that points at the last
argument.</span><br>
<font size="4"><br>
</font><span style="font-size:large">How is
this mediation done? One design could be to
require that all image level accesses to
Context inst vars are through primitives.
This feels contrived to me. Instead, inst
var access is via inst var access bytcodes.
But if we do this naively we would have to
check in all inst var access bytecodes whose
index is the same as sender (0), pc (1)
& stackp (2). This would slow down inst
var access enormously. Instead we observe
that inst var access bytecodes
pushReceiverVariable:,
popIntoReceiverVariable: have short forms
for the most frequently used (indexes 0 to
15 for push, indexes 0 to 7 for popInto).
By arranging that we only use the long forms
for accessing inst vars in Context, and
superclasses and subclasses, we only have to
check in the long forms and the check is
cheap. We check that the index is <= 2,
because all other inst var accesses with
these indices will use the short-form
bytecodes.</span><br>
<font size="4"><br>
</font><span style="font-size:large">By
arranging that Context's inst vars are *not*
accessed by quick primitives we do not have
to duplicate this machinery in quick
primitive dispatch, which would also slow
things down. Hence Context>>pc is
compiled as a vanilla method and its inst
var access bytecode is the long form:</span><br>
<font size="4"><br>
</font><span style="font-size:large">25 <E2
01> pushRcvr: 1</span><br>
<span style="font-size:large">27 <5C>
returnTop</span><br>
<br>
<span style="font-size:large">'Nuff said</span></div>
<div class="gmail_quote"><font size="4"><br>
</font>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div>
<div>
<div>
<div class="gmail_quote">
<span
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif;font-size:12pt">Second,
Context >> #</span><span
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif;font-size:12pt">isPrimFailToken:
attracted my attention multiple
times when looking at different
#timeProfile results of simulation
sessions. In the expression
[100000 factorial] it takes up
more than 44% of the whole
execution time!</span><br>
<span
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif;font-size:12pt">I
have no idea why it could be so
slow, but this message is sent
really often, which is at least 2
times per simulation of a special
message send.</span><br>
<span
style="color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif;font-size:12pt">Would
there be an easy change to resolve
this bottleneck and speed
up the simulation by 40% or more?</span><br>
<div>
<div
id="gmail-m_-2979770936573098614gmail-m_5689234217555540956gmail-m_5405583940077301585divtagdefaultwrapper"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI Symbol","Android
Emoji",EmojiSymbols">
<div><span><span>Would it be
possible to provide a
primitive for this method?
Or do you see any other
way to optimize it?</span></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<font size="4"><br>
It's not slow so much as <span
class="gmail_default">that </span>it has
to be used all the time to check whether a
send has invoked a primitive which has
failed. Its function is to support
primitive error codes.
<span class="gmail_default">Before primitive
error codes</span> <span
class="gmail_default">(IIRC)
</span>we simply check<span
class="gmail_default">ed</span> for nil.
But with <span class="gmail_default"
style="color:rgb(0,0,0)">primitive error
codes</span><span
style="color:rgb(0,0,0);font-family:-webkit-standard"> </span> we
need a container that both reliably
distinguishes a primitive failure result
from all other objects in the system, and
holds onto the primitive failure code. It
may indeed be able to reduce the overhead by
only testing when absolutely necessary. It
may be that reimplementing the scheme is
faster.</font><br>
<font size="4"><br>
</font><span style="font-size:large">For
example, one could imagine a class whose
instances are the only objects to answer
#isPrimFailToken, which would be faster than
a one argument message send. But beware,
because if one was debugging the debugger
one mustn't confuse a PrimFailToken created
in the simulation for a PrimFailToken
created by the simulation.</span><br>
<span style="font-size:large">Remember to
distinguish between price and value.
Implementing the context-to-stack mapping
scheme outlined above was very costly, but
its value is very high. It allows us to
have contexts, with all their utility, while
reducing their costs significantly.
Similarly, and closely related, being able
to simulate execution is costly but hugely
valuable. If the price is 40% of simulated
execution then it is a price worth paying.</span><br>
<font size="4"><br>
</font>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div>
<div>
<div>
<div class="gmail_quote">
<span
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif">Best,</span><br>
<div>
<div
id="gmail-m_-2979770936573098614gmail-m_5689234217555540956gmail-m_5405583940077301585divtagdefaultwrapper"
style="font-size:12pt;color:rgb(0,0,0);font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple
Color Emoji","Segoe UI
Emoji",NotoColorEmoji,"Segoe UI Symbol","Android
Emoji",EmojiSymbols">
<div><span><span>Christoph</span></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<font size="4"><br>
</font><span style="font-size:large">Happy New
Year!</span><br>
<font size="4"><br>
</font><span style="font-size:large">_,,,^..^,,,_</span><br>
<div>
<div>
<div>
<div>
<div>
<div><span
style="border-collapse:separate"><font
size="4">
<div>best, Eliot</div>
</font></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
</blockquote>
</div>
<br clear="all">
<div><br>
</div>
-- <br>
<div dir="ltr" class="gmail_signature">
<div dir="ltr">
<div><span
style="font-size:small;border-collapse:separate">
<div>_,,,^..^,,,_<br>
</div>
<div>best, Eliot</div>
</span></div>
</div>
</div>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<pre class="moz-quote-pre" wrap="">
</pre>
</blockquote>
</body>
</html>