{"id":18,"date":"2009-01-14T12:51:37","date_gmt":"2009-01-14T20:51:37","guid":{"rendered":"http:\/\/www.mirandabanda.org\/cogblog\/?p=18"},"modified":"2018-12-10T11:41:58","modified_gmt":"2018-12-10T19:41:58","slug":"under-cover-contexts-and-the-big-frame-up","status":"publish","type":"post","link":"http:\/\/www.mirandabanda.org\/cogblog\/2009\/01\/14\/under-cover-contexts-and-the-big-frame-up\/","title":{"rendered":"Under Cover Contexts and the Big Frame-Up"},"content":{"rendered":"<p>Nobody expects the Smalltalk language system. Our chief weapon is polymorphism&#8230; polymorphism and objects&#8230;objects and polymorphism. Our two weapons are objects and polymorphism&#8230; and inheritance&#8230; Our three weapons are objects, and polymorphism and inheritance&#8230; and an almost fanatical devotion to contexts&#8230;<br \/>\nOur four&#8230;no&#8230;<br \/>\nAmongst our weapons&#8230; Amongst our weaponry&#8230; are such elements as objects, po&#8230;<br \/>\n<a href=\"http:\/\/www.youtube.com\/watch?v=uprjmoSMJ-o\">I&#8217;ll come in again<\/a>.<\/p>\n<p>Contexts are Smalltalk&#8217;s first-class activation records. thisContext is the &#8220;reserved word&#8221; (technically, pseudo-variable) for the current activation record. Try &#8220;thisContext inspect&#8221; and see what you get. Then try &#8220;thisContext inspect. self halt&#8221; and see what you get.<\/p>\n<p>Contexts are fabulous weapons, even better programming building blocks, and <em>horribly<\/em> expensive. How do I love contexts? Let me count the ways&#8230;<\/p>\n<p>Contexts mean Smalltalk has had edit-and-continue debugging since the 1970&#8217;s.<br \/>\nContexts allow the implemention of an exception system with no additional support from the virtual machine.<br \/>\nContexts allow the implemention of dynamic binding, co-routines, tail-recursion-elimination and <a href=\"http:\/\/portal.acm.org\/citation.cfm?id=62094\">backtracking<\/a> with no additional support from the virtual machine.<br \/>\nContexts enable process persistence and migration.<br \/>\nContexts allow implementation of continuations (full, <a href=\"http:\/\/www.cs.rutgers.edu\/~ccshan\/zipper\/context2007.pdf\">delimited<\/a>\/partial or otherwise) without additional VM support (and hence the <a href=\"http:\/\/www.seaside.st\/\">Seaside<\/a> web framework).<br \/>\nContexts are <a href=\"https:\/\/www.youtube.com\/watch?v=JmvA7oWGb40\">consistent<\/a> <a href=\"http:\/\/www.lyricsfreak.com\/k\/king+crimson\/indiscipline_20078583.html\">(consistent)<\/a> with the rest of the &#8220;objects all the way down&#8221; system, providing activations as first-class objects.<br \/>\nBecause they&#8217;re there.<\/p>\n<p>What does a context look like?<br \/>\n<img src=\"http:\/\/www.mirandabanda.org\/images\/bluebook\/figure27_5.gif\" alt=\"\" \/><br \/>\nThe method is the code to execute. The stack is of finite size, guaranteed by the bytecode compiler. The sender is the caller context, providing a simple and flexible <a href=\"http:\/\/en.wikipedia.org\/wiki\/Spaghetti_stack\">&#8220;spaghetti stack&#8221;<\/a> scheme.<\/p>\n<p>But a naive implementation has to allocate a context on each send, move the receiver and arguments from the stack of the caller context to that of the callee, and assign the callee&#8217;s sender with the caller. For essentially every return the garbage collector eventually has to reclaim, and every return has to nil the sender and instruction pointer fields of, the context being returned from. Here&#8217;s the <a href=\"http:\/\/www.mirandabanda.org\/bluebook\/bluebook_chapter28.html#SendBytecodes28\">blue book<\/a> code for method activation:<\/p>\n<p><strong>activateNewMethod<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">contextSize<\/span> <span style=\"color: #404040;\">newContext<\/span> <span style=\"color: #404040;\">newReceiver<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #0e0e8e;\">largeContextFlagOf:<\/span><span style=\"color: #000000;\"> newMethod) <\/span><span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\">contextSize<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">32<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>TempFrameStart<\/strong><\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\">contextSize<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">12<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>TempFrameStart<\/strong><\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">newContext<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> memory<br \/>\n<\/span><span style=\"color: #0e0e8e;\">instantiateClass:<\/span> <strong><span style=\"color: #424242;\">ClassMethodContextPointer<\/span><\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #020282;\">withPointers:<\/span> <span style=\"color: #404040;\">contextSize<\/span><span style=\"color: #000000;\">.<br \/>\nmemory <\/span><span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">newContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> activeContext.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storeInstructionPointerValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #0e0e8e;\">initialInstructionPointerOfMethod:<\/span><span style=\"color: #000000;\"> newMethod)<br \/>\n<\/span><span style=\"color: #000080;\">inContext:<\/span> <span style=\"color: #404040;\">newContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storeStackPointerValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #0e0e8e;\">temporaryCountof:<\/span><span style=\"color: #000000;\"> newMethod)<br \/>\n<\/span><span style=\"color: #000080;\">inContext:<\/span> <span style=\"color: #404040;\">newContext<\/span><span style=\"color: #000000;\">.<br \/>\nmemory <\/span><span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">newContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">transfer:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">fromIndex:<\/span><span style=\"color: #000000;\"> stackPointer <\/span><span style=\"color: #000080;\">&#8211;<\/span><span style=\"color: #000000;\"> argumentCount<br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext<br \/>\n<\/span><span style=\"color: #000080;\">toIndex:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">newContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pop:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">newActiveContext:<\/span> <span style=\"color: #404040;\">newContext<\/span><\/p>\n<p>If you want to stay with this scheme but make it faster then you could do worse than the current Squeak implementation:<\/p>\n<p><strong>activateNewMethod<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">newContext<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #404040;\">initialIP<\/span> <span style=\"color: #404040;\">tempCount<\/span> <span style=\"color: #404040;\">nilOop<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #808080;\">|<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">methodHeader<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">headerOf:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #404040;\">newContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">allocateOrRecycleContext:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #404040;\"><strong>LargeContextBit<\/strong><\/span><span style=\"color: #000000;\">).<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">initialIP<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> (<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #404040;\"><strong>LiteralStart<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">literalCountOfHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">*<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">tempCount<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">temporaryCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Assume: newContext will be recorded as a root if necessary by the<br \/>\ncall to newActiveContext: below, so we can use unchecked stores.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">where<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">newContext<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>BaseHeaderSize<\/strong><\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> activeContext.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">integerObjectOf:<\/span> <span style=\"color: #404040;\">initialIP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\"><strong>StackPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">integerObjectOf:<\/span> <span style=\"color: #404040;\">tempCount<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\"><strong>ClosureIndex<\/strong><\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> nilObj.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Copy the reciever and arguments&#8230;&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">to:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span><span style=\"color: #000080;\">+i<\/span><span style=\"color: #800080;\">)<\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackValue:<\/span><span style=\"color: #000000;\"> argumentCount<\/span><span style=\"color: #000080;\">-i<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;clear remaining temps to nil in case it has been recycled&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">nilOop<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> nilObj.<br \/>\nargumentCount<\/span><span style=\"color: #000080;\">+<\/span><span style=\"color: #800000;\">1<\/span><span style=\"color: #000080;\">+<\/span><span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #404040;\">tempCount<\/span><span style=\"color: #000080;\">+<\/span><span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">where<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">&lt;&lt;<\/span> <span style=\"color: #404040;\"><strong>ShiftForWord<\/strong><\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #404040;\">nilOop<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pop:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\nreclaimableContextCount <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> reclaimableContextCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">newActiveContext:<\/span> <span style=\"color: #404040;\">newContext<\/span><\/p>\n<p>The variable <span style=\"color: #000000;\">reclaimableContextCount<\/span> counts how many contexts have been allocated that are not referenced by other objects and so may eagerly be reclaimed on return. Whenever thisContext is referenced or a block created <span style=\"color: #000000;\">reclaimableContextCount<\/span> gets set to zero. On return if <span style=\"color: #000000;\">reclaimableContextCount<\/span> is non-zero the returning context is reclaimed and <span style=\"color: #000000;\">reclaimableContextCount is decremented.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Again in a naive implementation p<\/span>ushing an object on the stack involves a store check. David Ungar&#8217;s Berkeley Smalltalk nilled out the stack slot when popping off an entry so that a push would only have to increase the reference count of the object pushed instead of also decrementing the count of the object overwritten. The Squeak VM uses a generational collector so there is no reference counting but it does need to make the context a root if it is old (in <span style=\"color: #000080;\">newActiveContext:<\/span>) to avoid the store-check on every push. It also carefully protects against access beyond the stack pointer through checks in the at: and at:put: primitives so that <span style=\"color: #000080;\">allocateOrRecycleContext:<\/span><span style=\"color: #000000;\"> does not have to initialize the stack with nils.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">But these are all desperate attempts at mitigating the cost of a structure which for the most part is used in last-in, first-out (LIFO) order and only occasionally used to do the cool stuff we love it for. So here&#8217;s my evolution of <\/span><a href=\"http:\/\/portal.acm.org\/citation.cfm?id=800017.800542\">Peter Deutsch&#8217;s and Allan Schiffman&#8217;s original scheme<\/a><span style=\"color: #000000;\"> for having one&#8217;s cake and eating it too, for providing the illusion of ever-present contexts while only creating them when necessary. This is the fourth variant I&#8217;ve come up with, a hybrid of my earlier schemes and Peter and Allan&#8217;s, and like any hybrid it is vigourous and healthy \ud83d\ude42<\/span> What&#8217;s really different about my scheme, unlike Peter and Allan&#8217;s, is that contexts don&#8217;t get divorced when you send them a message, a cryptic comment I&#8217;ll explain presently.<\/p>\n<h2>Stack Organization<\/h2>\n<p><span style=\"color: #000000;\">The basic idea is to organize method activations using a stack discipline and to allow these to be accessed through contexts. The stack discipline is no different to that in conventonal language implementations. Outgoing arguments get pushed on the stack and on activation a frame is built immediately following the arguments which it references via the stack or frame pointer. On return the frame is popped off the stack and the stack pointer and frame pointer revert to referencing the caller frame; no different to stack management in e.g. Pascal or C. The wrinkle is in allowing context objects to be created and manipulated as if they were conventional contexts even though they are stand-ins for underlying stack frames.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Let&#8217;s look at some activation\/return sequences to understand it properly. Here&#8217;s a stack which has some arguments for a send pushed on it by some already active method, it is about to send + in DateAndTime <\/span><span style=\"color: #000080;\">today<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (Duration <\/span><span style=\"color: #000080;\">weeks:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">).<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig1.jpg\" alt=\"\" \/><span style=\"color: #000000;\"><br \/>\nHere&#8217;s the DateAndTime&gt;&gt;+ method:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>DateAndTime<\/em><\/span><span style=\"color: #000000;\"><em> methods for ansi protocol<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>+<\/strong> <span style=\"color: #000080;\">operand<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;operand conforms to protocol Duration&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">ticks<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">ticks<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ticks<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #000080;\">operand<\/span> <span style=\"color: #000080;\">asDuration<\/span> <span style=\"color: #000080;\">ticks<\/span><span style=\"color: #000000;\">) .<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">^<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">class<\/span> <span style=\"color: #000080;\">basicNew<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ticks:<\/span> <span style=\"color: #404040;\">ticks<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">offset:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">offset<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">yourself<\/span><\/p>\n<p><span style=\"color: #000000;\">When the message is sent the intetpreter looks up #+ in dateAndTime and finds the method. To build the frame for the method the interpreter pushes its current instruction pointer and frame pointer, saving them for the eventual return, then pushes the method, a flag word and a slot to hold the frame&#8217;s context if it ever needs one. Finally it pushes the receiver (again) and initializes temporaries (in this case just &#8220;ticks&#8221;) to nil.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig2.jpg\" alt=\"\" \/><\/p>\n<p>all of which is done by the following method<\/p>\n<p><em>StackInterpreter methods for message sending<\/em><br \/>\n<strong>internalActivateNewMethod<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #404040;\">numTemps<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #404040;\">errorCode<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">methodHeader<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">headerOf:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #404040;\">numTemps<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">tempCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">rcvr<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackValue:<\/span><span style=\"color: #000000;\"> argumentCount. <\/span><span style=\"color: #008080;\">&#8220;could new rcvr be set at point of send?&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> localIP.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalFP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localSP.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\nmethod <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">encodeFrameFieldHasContext:<\/span> <span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">isBlock:<\/span> <span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">numArgs:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">argumentCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> nilObj. <\/span><span style=\"color: #008080;\">&#8220;FxThisContext field&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Initialize temps&#8230;&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nargumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #404040;\">numTemps<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> nilObj].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;-1 to account for pre-increment in fetchNextBytecode&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nlocalIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pointerForOop:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">initialPCForHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #000080;\">method:<\/span><span style=\"color: #000000;\"> newMethod) <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><br \/>\nThe flag word, tells the interpreter three things, how many arguments the method has, whether the context field is valid or not and whether the frame is a method or block activation.<\/p>\n<p>Each of these fields is a single byte. The interpreter uses the args field to decide where to find a temporary variable. The bytecode set uses push\/Store\/StorePopTemporary bytecodes to access both arguments and temporaries since in a context the arguments and temporaries are adjacent. But in this stack organization the arguments are at the top of the frame and the temporaries below, so the argument count determines where to find temporaries and hence having fast access to the argument count is essential to access arguments and temporaries with acceptable speed:<br \/>\n<span style=\"color: #800000;\"><br \/>\n<\/span><em>StackInterpreter methods for frame access<\/em><br \/>\n<strong>frameNumArgs:<\/strong> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See encodeFrameFieldHasContext:numArgs:&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">byteAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxFrameFlags<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><em>StackInterpreter methods for internal interpreter access<\/em><br \/>\n<strong>temporary:<\/strong> <span style=\"color: #000080;\">offset<\/span> <strong>in:<\/strong> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See StackInterpreter class&gt;&gt;initializeFrameIndices&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">frameNumArgs<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">&lt;<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\">frameNumArgs<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameNumArgs:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxCallerSavedIP<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #404040;\">frameNumArgs<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #000080;\">offset<\/span><span style=\"color: #800080;\">)<\/span> <span style=\"color: #000080;\">*<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxReceiver<\/strong><\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #404040;\">frameNumArgs<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #000080;\">offset<\/span><span style=\"color: #800080;\">)<\/span> <span style=\"color: #000080;\">*<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">]<\/span><span style=\"color: #404040;\"><strong><br \/>\n<\/strong><\/span><span style=\"color: #800000;\"><br \/>\n<\/span><strong>internalPush:<\/strong> <span style=\"color: #000080;\">object<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;In the StackInterpreter stacks grow down.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAtPointer:<\/span><span style=\"color: #000000;\"> (localSP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localSP <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">put:<\/span> <span style=\"color: #000080;\">object<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><em>StackInterpreter methods for stack bytecodes<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>pushTemporaryVariable:<\/strong> <span style=\"color: #000080;\">temporaryIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">temporary:<\/span> <span style=\"color: #000080;\">temporaryIndex<\/span> <span style=\"color: #000080;\">in:<\/span><span style=\"color: #000000;\"> localFP)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>pushTemporaryVariableBytecode<\/strong><span style=\"color: #000000;\"><br \/>\n&lt;expandCases&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;this bytecode will be expanded so that refs to currentBytecode below will be constant&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushTemporaryVariable:<\/span><span style=\"color: #000000;\"> (currentBytecode <\/span><span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #800000;\">16rF<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000000;\"><br \/>\nThe receiver is pushed also, partly for reasons of efficiency and, as we&#8217;ll see later, to support blocks. Pushing the receiver after the context field allows the interpreter to find the receiver at a known offset relative to the frame pointer, avoiding having to fetch frameNumArgs for instance variable access:<\/span><br \/>\n<span style=\"color: #800000;\"><br \/>\n<\/span><em>StackInterpreter methods for frame access<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>frameReceiver:<\/strong> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxReceiver<br \/>\n<\/strong><\/span><span style=\"color: #800000;\"><br \/>\n<\/span><em>StackInterpreter methods for stack bytecodes<br \/>\n<\/em><strong>pushReceiverVariable:<\/strong> <span style=\"color: #000080;\">fieldIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">receiver<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #404040;\"><strong><br \/>\n<\/strong><\/span><strong>pushReceiverVariableBytecode<\/strong><span style=\"color: #000000;\"><br \/>\n&lt;expandCases&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;this bytecode will be expanded so that refs to currentBytecode below will be constant&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushReceiverVariable:<\/span><span style=\"color: #000000;\"> (currentBytecode <\/span><span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #800000;\">16rF<\/span><span style=\"color: #000000;\">)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">We arrange that stacks grow down because in the JIT they definitely will. Call, return, push and pop instructions on CISC processors (notably x86\/IA32) define that stacks grow downwards, and the JIT will reuse much of the StackInterpreter&#8217;s machinery. Whenever I talk about a frame being above another one I mean it is later, actually at a lower address, but logically above, towards the head frame and away from the base frame; the &#8220;hottest&#8221; element on the stack is still called the top of stack.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Continuing with the execution once DateAndTime&gt;&gt;+ has pushed self (12 January 2009) it is ready to send ticks:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig3.jpg\" alt=\"\" \/><\/p>\n<p>The pushed 12 January 2009 becomes the receiver of the new activation of DateAndTime&gt;&gt;#ticks. The saved instruction pointer is the pointer to the bytecode following the send of ticks. The saved frame pointer is the frame pointer for the DateAndTime&gt;&gt;#+ frame, then comes the DateAndTime&gt;&gt;#ticks method, a flag word indicating no arguments, an invalid context field and the 12 January 2009 receiver:<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig4.jpg\" alt=\"\" \/><\/p>\n<p>The ticks method will eventually compute <span style=\"color: #000000;\">#(2454844 0 0)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>DateAndTime<\/em><\/span><span style=\"color: #000000;\"><em> methods for private<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>ticks<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Private &#8211; answer an array with our instance variables. Assumed to be UTC &#8220;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000000;\"> Array <\/span><span style=\"color: #000080;\">with:<\/span><span style=\"color: #000000;\"> jdn <\/span><span style=\"color: #000080;\">with:<\/span><span style=\"color: #000000;\"> seconds <\/span><span style=\"color: #000080;\">with:<\/span><span style=\"color: #000000;\"> nanos<\/span><\/p>\n<p><span style=\"color: #000000;\">Its return bytecode dismantles the frame, assigning the frame pointer to the stack pointer, popping off the saved frame pointer into the frame pointer, the caller&#8217;s saved ip into the instruction pointer, removing the arguments, and pushing the result:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig5.jpg\" alt=\"\" \/><\/p>\n<p>which is done by the following method:<br \/>\n<strong>commonCallerReturn<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Return to the previous context\/frame (sender for method activations, caller for block activations).&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000000;\">&lt;sharedCodeNamed: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;commonCallerReturn&#8217;<\/span><\/span><span style=\"color: #000000;\"> inCase: <\/span><span style=\"color: #800000;\">125<\/span><span style=\"color: #000000;\">&gt; <\/span><span style=\"color: #008080;\">&#8220;returnTopFromBlock&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0localIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSavedIP:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalSP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localFP <\/span><span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameStackedReceiverOffset:<\/span><span style=\"color: #000000;\"> localFP).<br \/>\nlocalFP <\/span><strong>:=\u00c2\u00a0<\/strong><span style=\"color: #000000;\">\u00c2\u00a0<\/span><span style=\"color: #000000;\"><span style=\"color: #800000;\">self<\/span>\u00c2\u00a0<span style=\"color: #000080;\">frameCallerFP:<\/span>\u00c2\u00a0localFP.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span><span style=\"color: #000000;\"> localSP <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> localReturnValue.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\nmethod <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span><span style=\"color: #000000;\"> localFP<\/span><\/p>\n<p>and the bytecode after the send of #ticks in DateAndTime&gt;&gt;#+ pops and stores the result into the ticks temporary, leaving us where we started but with ticks holding <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ticks<\/span>. Look ma, no contexts.<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/DateAndTimePlus-fig6.jpg\" alt=\"\" \/><\/p>\n<h2>Context to Stack Mapping<\/h2>\n<p>Let&#8217;s add closures to the mix so we can see contexts related to stack frames. A closure has an explicit reference to its enclosing context, which in our new scheme has to be mapped to a stack frame. Let&#8217;s evaluate<\/p>\n<p>&#8216;Hi!&#8217; detect: [:char| &#8216;!?&#8217; includes: char] ifNone: [^#unemphatic]<\/p>\n<p>Here&#8217;s Collection&gt;&gt;#detect:ifNone:<\/p>\n<p><em>Collection methods for enumerating<\/em><br \/>\n<strong>detect:<\/strong> <span style=\"color: #000080;\">aBlock<\/span> <strong>ifNone:<\/strong> <span style=\"color: #000080;\">exceptionBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Evaluate aBlock with each of the receiver&#8217;s elements as the argument.<br \/>\nAnswer the first element for which aBlock evaluates to true. If none<br \/>\nevaluate to true, then evaluate the argument, exceptionBlock.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"> [:<\/span><span style=\"color: #000080;\">each<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000080;\">aBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #000080;\">each<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^<\/span> <span style=\"color: #000080;\">each<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span> <span style=\"color: #000080;\">exceptionBlock<\/span> <span style=\"color: #000080;\">value<\/span><\/p>\n<p>On activation of Collection&gt;&gt;#detect:ifNone: the top frame on the stack looks like this<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/detectifnone-fig1.jpg\" alt=\"\" \/><\/p>\n<p><span style=\"color: #000000;\">The <\/span><span style=\"color: #000000;\">[:<\/span><span style=\"color: #000080;\">each<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000080;\">aBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #000080;\">each<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^<\/span> <span style=\"color: #000080;\">each<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">] needs an <\/span><span style=\"color: #000000;\">outerContext but it is executing within the frame activation of Collection&gt;&gt;#<\/span>detect:ifNone:<span style=\"color: #000000;\">. So when the block is created we also create a context that is a <\/span><a href=\"http:\/\/en.wikipedia.org\/wiki\/Proxy_pattern\">proxy<\/a><span style=\"color: #000000;\"> for the frame (a better reference is <\/span><a href=\"http:\/\/portal.acm.org\/citation.cfm?id=38765.38837\">here<\/a><span style=\"color: #000000;\">). If the block refers to self or an instance variable it needs to get at the receiver of the outerContext and if it executes the uparrow-return it must return from the Collection&gt;&gt;#<\/span>detect:ifNone:<span style=\"color: #000000;\"> frame.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/detectifnone-fig2.jpg\" alt=\"\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">To avoid chaos we need a one-to-one relationship between frames and contexts; hence the flag in the frame which ensures we only create one context for a frame. In this implementation we say that a frame is married to a context, and there&#8217;s no polygamy allowed. Given that a context could be referenced long after its frame exits we also have to detect if a context has been <\/span><a href=\"http:\/\/en.wiktionary.org\/wiki\/widow\">widowed<\/a><span style=\"color: #000000;\">, and convert it into a stable, but returned-from context. As we&#8217;ll see frames and contexts can get divorced (although that&#8217;s fatal for the frame) and contexts can re-marry, but frames only marry once if at all; clearly contexts are female, and frames are rather frail males; no <\/span><a href=\"http:\/\/en.wiktionary.org\/wiki\/widower\">widowers<\/a><span style=\"color: #000000;\"> here.<\/span><\/p>\n<p><span style=\"color: #000000;\">To implement non-local return correctly we must be able to determine if a context is single (a normal heap context, not associated with a frame), married or widowed, and, if married, to locate its spouse frame.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">At the least we need a pointer from the context to its spouse. For this we use the sender field. The sender field of a context is always either another context or nil (ignoring wilful and inevitably fatal abuse by the programmer; you <\/span><span style=\"color: #000000;\"><em>can<\/em><\/span><span style=\"color: #000000;\"> assign a Point, or any other object, to the sender of thisContext but it&#8217;ll end your session). So we mark married contexts by storing the frame pointer of their spouse frame with the SmallInteger tag bit set in the sender field. Frames are always word-aligned so frame pointer least significant bits are always zero. <\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for frame access<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>isMarriedOrWidowedContext:<\/strong> <span style=\"color: #000080;\">aContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">isIntegerObject:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">aContext<\/span><span style=\"color: #000000;\">)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>ensureFrameIsMarried:<\/strong> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">frameContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">marryFrame:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>marryFrame:<\/strong> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Marry an unmarried frame. This means creating a spouse context<br \/>\ninitialized with a subset of the frame&#8217;s state (state through the last argument)<br \/>\nthat references the frame.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #404040;\">byteSize<\/span> <span style=\"color: #404040;\">tempCount<\/span> <span style=\"color: #404040;\">closureOrNil<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">methodHeader<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">headerOf:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;This phrase is merely determining how much of the stack to initialize the context with.<br \/>\nIt is a lot of work for dubious benefit. Perhaps blocks could encode their num temps in frame flags.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameIsBlockActivation:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">numBlockArgs<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">numBlockArgs<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameNumArgs:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">closureOrNil<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushedReceiverOrClosureOfFrame:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">tempCount<\/span> <strong>:=<\/strong> <span style=\"color: #808080;\">numBlockArgs<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchWordLengthOf:<\/span> <span style=\"color: #404040;\">closureOrNil<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>ClosureFirstCopiedValueIndex<\/strong><\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\">closureOrNil<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> nilObj.<br \/>\n<\/span><span style=\"color: #404040;\">tempCount<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">tempCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">byteSize<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> (<\/span><span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #404040;\"><strong>LargeContextBit<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\"><strong>LargeContextSize<\/strong><\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\"><strong>SmallContextSize<\/strong><\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">eeInstantiateContext:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">splObj:<\/span> <span style=\"color: #404040;\"><strong>ClassMethodContext<\/strong><\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">sizeInBytes:<\/span> <span style=\"color: #404040;\">byteSize<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Mark context as married by setting its sender to the frame pointer plus SmallInteger<br \/>\ntags and the InstructionPointer to the saved fp (which ensures correct alignment<br \/>\nw.r.t. the frame when we check for validity)&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withSmallIntegerTags:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withSmallIntegerTags:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>StackPointerIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">integerObjectOf:<\/span> <span style=\"color: #404040;\">tempCount<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>ClosureIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">closureOrNil<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameReceiver:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #404040;\">tempCount<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span><span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #000080;\">i<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">temporary:<\/span> <span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">in:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxThisContext<\/strong><\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">byteAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxFrameFlags<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">2<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">==<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000000;\"><br \/>\nI think marryFrame: contains a bug in that it copies all temporaries into the spouse context but it needs only to copy the receiver and arguments. But that&#8217;s how the code stands today. Mea culpa.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Before we delve into the details of divorce and widowhood, and how we hide all this matrimonial activity from Smalltalk let&#8217;s finish activating the block within Collection&gt;&gt;#<\/span>detect:ifNone:<span style=\"color: #000000;\">. Collection&gt;&gt;#<\/span>detect:ifNone:<span style=\"color: #000000;\"> sends do: and in this case SequenceableCollection&gt;&gt;#do: will activate the block:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>SequenceableCollection methods for enumerating<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>do:<\/strong> <span style=\"color: #000080;\">aBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Refer to the comment in Collection&gt;&gt;do:.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">size<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">index<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #000080;\">aBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">index<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><span style=\"color: #000000;\">The BlockClosure&gt;&gt;value[:value:&#8230;] primitives create a frame for the block, setting the &#8220;is block&#8221; flag, push the method and receiver in the outerContext and push any copied values.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/detectifnone-fig3.jpg\" alt=\"\" \/><br \/>\n<span style=\"color: #000000;\"><br \/>\nIn the block activation the receiver of the value: message, the [] in <\/span>detect:ifNone:<span style=\"color: #000000;\"> that do: pushed on the stack, is not the receiver (&#8216;Hi&#8217;) of <\/span>detect:ifNone:<span style=\"color: #000000;\">. If we need to marry a block activation then we can find its closureOrNil on the stack in the same position as the receiver for normal sends. But as far as accessing self and its instance variables blocks and methods are the same; the field following the context field is always the receiver of the home method activation.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for control primitives<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>activateNewClosureMethod:<\/strong> <span style=\"color: #000080;\">blockClosure<\/span> <strong>numArgs:<\/strong> <span style=\"color: #000080;\">numArgs<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Similar to activateNewMethod but for Closure and newMethod.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">numCopied<\/span> <span style=\"color: #404040;\">outerContext<\/span> <span style=\"color: #404040;\">theMethod<\/span> <span style=\"color: #404040;\">closureIP<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #404040;\">outerContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>ClosureOuterContextIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">blockClosure<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">numCopied<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchWordLengthOf:<\/span> <span style=\"color: #000080;\">blockClosure<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>ClosureFirstCopiedValueIndex<\/strong><\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">theMethod<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">outerContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> instructionPointer.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> framePointer.<br \/>\nframePointer <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPointer.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span> <span style=\"color: #404040;\">theMethod<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">encodeFrameFieldHasContext:<\/span> <span style=\"color: #800000;\">false<\/span> <span style=\"color: #000080;\">isBlock:<\/span> <span style=\"color: #800000;\">true<\/span> <span style=\"color: #000080;\">numArgs:<\/span> <span style=\"color: #000080;\">numArgs<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> nilObj. <\/span><span style=\"color: #008080;\">&#8220;FxThisContext field&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">outerContext<\/span><span style=\"color: #000000;\">).<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Copy the copied values&#8230;&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #404040;\">numCopied<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span><span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>ClosureFirstCopiedValueIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">blockClosure<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameIsBlockActivation:<\/span><span style=\"color: #000000;\"> framePointer).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span><span style=\"color: #000000;\"> framePointer) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;The initial instructions in the block nil-out remaining temps.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;the instruction pointer is a pointer variable equal to<br \/>\nmethod oop + ip + BaseHeaderSize<br \/>\n-1 for 0-based addressing of fetchByte<br \/>\n-1 because it gets incremented BEFORE fetching currentByte&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">closureIP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">quickFetchInteger:<\/span> <span style=\"color: #404040;\"><strong>ClosureStartPCIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">blockClosure<\/span><span style=\"color: #000000;\">.<br \/>\ninstructionPointer <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">theMethod<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">closureIP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>BaseHeaderSize<\/strong><\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">2<\/span><span style=\"color: #000000;\">.<br \/>\nmethod <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">theMethod<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Stack Pages<\/h2>\n<p><span style=\"color: #000000;\">So far I&#8217;ve left out how the stack is shared amongst Smalltalk&#8217;s light-weight processes, and how we maintain Smalltalk&#8217;s immunity from stack overflow. In a context-based Smalltalk the only limit to the depth of a call chain is available heap memory in which to store contexts. In a blue-book Smalltalk implementation infinite recursion manifests itself as a low-space condition. Smalltalk provides light-weight processes, which are simply chains of contexts, and applications like Croquet can create thousands a second and have hundreds active at any one time. Creating a new process involves creating a process object and a context or two. In using a stack we need to both share it effectively between processes and keep process creation cheap.<\/span><\/p>\n<p>Pater Deutsch&#8217;s solution is to divide up the stack into pages, each page capable of holding enough contexts so that we&#8217;re not switching stack pages all the time and few enough such that moving all the frames on the page into the heap in the form of contexts so the page can be reused doesn&#8217;t take too long. As we&#8217;ll see with the JIT this does introduce some complications calling run-time routines on the C stack, but on balance it&#8217;s an excellent solution and I&#8217;m sticking with it. So the stack is in fact composed of pages of a fixed size determined statically and quantity determined at start-up. I&#8217;m currently using 1024 byte stack pages, which have room for about 20 &#8220;average&#8221; activations, which is a little tight and so will probably move to 2048 byte pages when I tune the JIT. Current;y inside Qwaq we&#8217;re using 192 stack pages.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Running on a stack page of a small size introduces three complications, stack page overflow, stack page underflow, and linking stack pages together. We handle overflow by checking a stackLimit on every frame build. So in full detail internalActivateNewMethod is as follows, with the added complications of passing any primitive error code and of checking for stack overflow, which is right at the end of the method:<br \/>\n<\/span><br \/>\n<em>StackInterpreter methods for message sending<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>internalActivateNewMethod<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #404040;\">numTemps<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #404040;\">errorCode<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">methodHeader<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">headerOf:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #404040;\">numTemps<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">tempCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">rcvr<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackValue:<\/span><span style=\"color: #000000;\"> argumentCount. <\/span><span style=\"color: #008080;\">&#8220;could new rcvr be set at point of send?&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> localIP.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalFP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localSP.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> newMethod.<br \/>\nmethod <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> newMethod.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">encodeFrameFieldHasContext:<\/span> <span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">isBlock:<\/span> <span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">numArgs:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">argumentCountOfMethodHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> nilObj. <\/span><span style=\"color: #008080;\">&#8220;FxThisContext field&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Initialize temps&#8230;&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nargumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #404040;\">numTemps<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span><span style=\"color: #000000;\"> nilObj].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;-1 to account for pre-increment in fetchNextBytecode&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nlocalIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pointerForOop:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">initialPCForHeader:<\/span> <span style=\"color: #404040;\">methodHeader<\/span> <span style=\"color: #000080;\">method:<\/span><span style=\"color: #000000;\"> newMethod) <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Pass primitive error code to last temp if method receives it (indicated<br \/>\nby an initial long store temp bytecode). Protect against obsolete values<br \/>\nin primFailCode by checking that newMethod actually has a primitive?&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nprimFailCode <\/span><span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">methodHeaderHasPrimitive:<\/span> <span style=\"color: #404040;\">methodHeader<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">(self<\/span> <span style=\"color: #000080;\">byteAtPointer:<\/span><span style=\"color: #000000;\"> localIP <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1)<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">129<\/span> <span style=\"color: #008080;\">&#8220;long store temp&#8221;<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">errorCode<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">getErrorObjectFromPrimFailCode<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">longAt:<\/span><span style=\"color: #000000;\"> localSP <\/span><span style=\"color: #000080;\">put:<\/span> <span style=\"color: #404040;\">errorCode<\/span> <span style=\"color: #008080;\">&#8220;nil if primFailCode == 1, or primFailCode&#8221;<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\nprimFailCode <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameNumArgs:<\/span><span style=\"color: #000000;\"> localFP) <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> argumentCount.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameIsBlockActivation:<\/span><span style=\"color: #000000;\"> localFP) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span><span style=\"color: #000000;\"> localFP) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Now check for stack overflow or an event (interrupt, must scavenge, etc)&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nlocalSP <\/span><span style=\"color: #000080;\">&lt;<\/span><span style=\"color: #000000;\"> stackLimit <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalizeIPandSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackOverflowOrEvent:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">mayContextSwitch:<\/span> <span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalizeIPandSP<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><span style=\"color: #000000;\">On overflow we must allocate a new stack page and continue execution there, linking the new bottom-most frame (its base frame) to the current frame. Likewise, return must deal with returning from a base frame and return from one stack frame to the next. We have a mechanism for referring to stack frames, married contexts, so to link a stack page&#8217;s base frame to the stack page beneath it we marry the top frame of the stack we&#8217;re leaving and store this in the base frame of the stack page we&#8217;re entering. We mark the new stack page&#8217;s base frame as such by giving it a null caller saved fp and use the caller saved ip field to hold the caller context, the spouse of the stack page beneath&#8217;s top frame:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/baseframe-fig1.jpg\" alt=\"\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">We have a linked list of StackPage objects, one for each page, that we use to keep stack pages in order of usage, along with free pages, referenced by a variable called the mostRecentlyUsedPage. Each StackPage keeps track of whether a stack page is in use (baseFP is non-null) and what part of the page is in use (from the first slot through to the headSP) and what the frames are in the page (the list from headFP chained through caller saved fp to the baseFP). The interpreter&#8217;s current stack page is called stackPage. On stack switch we load stackLimit from stackPage&#8217;s stackLimit. Peter cleverly realised that one can use the stackLimit check to cause the VM to break out of execution to process input events. The VM is set up to respond to potential input with an interrupt handler that sets the stackLimit to all ones (the highest possible address) so that the next stack overflow check will fail. We also check for stack overflow on backward branch so that we can break out of infinite loops:<br \/>\n<\/span><br \/>\n<em>StackInterpreter methods for jump bytecodes<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>longUnconditionalJump<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">offset<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">offset<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> (<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #000000;\">currentBytecode <\/span><span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #800000;\">7<\/span><span style=\"color: #800080;\">)<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">4<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">*<\/span> <span style=\"color: #800000;\">256<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchByte<\/span><span style=\"color: #000000;\">.<br \/>\nlocalIP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localIP <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">offset<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #404040;\">offset<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #008080;\">&#8220;backward jump means we&#8217;re in a loop; check for possible interrupts&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">localSP <\/span><span style=\"color: #000080;\">&lt;<\/span><span style=\"color: #000000;\"> stackLimit<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalizeIPandSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">checkForEventsMayContextSwitch:<\/span> <span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">browserPluginReturnIfNeeded<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalizeIPandSP<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><\/p>\n<p><span style=\"color: #000000;\">So stackOverflowOrEvent:mayContextSwitch: checks whether stackLimit differs from stackPage&#8217;s stack limit to see whether it should check for input and only switches to a new page if the stack pointer is below stackPage&#8217;s real stack limit.<\/span><\/p>\n<p>Of course on stack overflow we may find that there are no free stack pages, in which case the VM simply flushes all the frames<br \/>\non the least-recently used page to the heap in the form of contexts. First it ensures all frames on the page are married and then divorces them all, linking them through their sender fields just as if they were created by a context-only VM, and then reuses the page, mercilessly killing the frames there-on. If any other stack page had the freed stack page beneath it then that stack page&#8217;s base frame will find its saved caller context is single.<\/p>\n<p>So as execution proceeeds the stack zone holds the top frames of a number of recently executed processes, overflowing the contents of older stack pages to the heap as contexts. The only possible references into that page are from contexts which have all been divorced, so all references remain valid, except now they&#8217;re to single contexts instead of married ones.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">When the system snapshots the image all stack frames are divorced and so the image file contains only single contexts, allowing the image file to be run by a context-only VM or started up on a VM with a different number of stack pages at different addresses. Here&#8217;s the divorce code:<br \/>\n<\/span><br \/>\n<em>StackInterpreter methods for image save\/restore<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>snapshot:<\/strong> <span style=\"color: #000080;\">embedded<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;update state of active context&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">activeContext<\/span> <span style=\"color: #404040;\">activeProc<\/span> <span style=\"color: #404040;\">dataSize<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #404040;\">setMacType<\/span> <span style=\"color: #404040;\">stackIndex<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#setMacType<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;void *&#8217;<\/span><\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Need to convert all frames into contexts since the snapshot file only holds objects.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">push:<\/span><span style=\"color: #000000;\"> instructionPointer.<br \/>\n<\/span><span style=\"color: #404040;\">activeContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">divorceAllFrames<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushRemappableOop:<\/span> <span style=\"color: #404040;\">activeContext<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;update state of active process&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n&#8230;etc&#8230;<br \/>\n<\/span><br \/>\n<em>StackInterpreter methods for frame access<\/em><span style=\"color: #000000;\"><br \/>\n<\/span><strong>divorceAllFrames<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">activeContext<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#aPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalWriteBackHeadFramePointers<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">activeContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span><span style=\"color: #000000;\"> framePointer.<br \/>\n<\/span><span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">to:<\/span><span style=\"color: #000000;\"> numStackPages <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">aPage<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">aPage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageAt:<\/span> <span style=\"color: #000080;\">i<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">isFree:<\/span> <span style=\"color: #808080;\">aPage<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">divorceFramesIn:<\/span> <span style=\"color: #808080;\">aPage<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\nstackPage <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">activeContext<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>divorceFramesIn:<\/strong> <span style=\"color: #000080;\">aStackPage<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">calleeFP<\/span> <span style=\"color: #404040;\">theSP<\/span> <span style=\"color: #404040;\">theIP<\/span> <span style=\"color: #404040;\">calleeContext<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#aStackPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#calleeFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theSP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0statStackPageDivorce <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> statStackPageDivorce <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">aStackPage<\/span> <span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theSP<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">aStackPage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theIP<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">theSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theSP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">theSP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">. <\/span><span style=\"color: #008080;\">&#8220;theSP points at hottest item on frame&#8217;s stack&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">calleeContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">nil<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0[<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">updateStateOfSpouseContextForFrame:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">WithSP:<\/span> <span style=\"color: #404040;\">theSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">contextInstructionPointerForFrame:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">IP:<\/span> <span style=\"color: #404040;\">theIP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameReceiver:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">==<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">calleeContext<\/span> <span style=\"color: #000080;\">~~<\/span> <span style=\"color: #800000;\">nil<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">calleeContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">calleeContext<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">calleeFP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theIP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">. <\/span><span style=\"color: #008080;\">&#8220;a.k.a. frameCallerIP:&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">] <\/span><span style=\"color: #000080;\">whileTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008080;\">&#8220;theSP points at stacked hottest item on frame&#8217;s stack&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">theSP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSP:<\/span> <span style=\"color: #404040;\">calleeFP<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">theIP<\/span><span style=\"color: #000000;\">. <\/span><span style=\"color: #008080;\">&#8220;The ip of the base frame is the caller context&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;The page is now free; mark it so.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">aStackPage<\/span> <span style=\"color: #000080;\">baseFP:<\/span> <span style=\"color: #800000;\">0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>updateStateOfSpouseContextForFrame:<\/strong> <span style=\"color: #000080;\">theFP<\/span> <strong>WithSP:<\/strong> <span style=\"color: #000080;\">theSP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Update the frame&#8217;s spouse context with the frame&#8217;s current state except for the<br \/>\nsender and instruction pointer, which are used to mark the context as married.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #404040;\">tempIndex<\/span> <span style=\"color: #404040;\">pointer<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theSP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#pointer<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameContext:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">tempIndex<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameNumArgs:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">pointer<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxReceiver<\/strong><\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">.<br \/>\n[<\/span><span style=\"color: #404040;\">pointer<\/span> <span style=\"color: #000080;\">&gt;=<\/span> <span style=\"color: #000080;\">theSP<\/span><span style=\"color: #000000;\">] <\/span><span style=\"color: #000080;\">whileTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">tempIndex<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">tempIndex<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">tempIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">pointer<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">pointer<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">pointer<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>StackPointerIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">integerObjectOf:<\/span> <span style=\"color: #404040;\">tempIndex<\/span><span style=\"color: #000000;\">)<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Widowhood<\/h2>\n<p>Given that contexts are objects they have indefinite extent; they can be stored in instance variables, typically indirectly from blocks that are stored in various places) and so outlive being returned from. For example here&#8217;s one way to create a widowed context for a block activation:<\/p>\n<p>| container |<br \/>\ncontainer := Array new: 1.<br \/>\n#(foo) do: [:ignored| container at: 1 put: thisContext].<br \/>\ncontainer<\/p>\n<p>Even simpler would be<br \/>\n<em>Object methods for examples<\/em><br \/>\n<strong>widowedContext<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^thisContext<\/span><\/p>\n<p>At various times, for example whenever accessing the instance variables of contexts, or on return, we need to check whether a context is single, married or widowed and act accordingly. A single context will have a sender that is not a SmallInteger (recall isMarriedOrWidowedContext: above). A married or widowed context however may or or may not have outlived its spouse. Since the system starts up and snapshots with only single contexts we know that all encoded frame pointers in sender fields point into stack pages. We can easily derive the StackPage object for a stack page because each stack page is a power-of-two in size and all stack pages are contiguous. Once we have the StackPage we can find out if it is in use or not, and if the context&#8217;s spouse frame is in the live portion of the stack (between baseFP and headFP). If so, we can follow the frame pointer and examine the frame&#8217;s flags and context fields. But there is no guarantee that we&#8217;re looking at the actual frame. It may have been exited and overwritten by some other frame. So we must assume that the spouse frame pointer is potentially pointing at an arbitrary position in the stack.<\/p>\n<p>Note that we have to keep the current stackPage&#8217;s headFP and headSP up-to-date because the interpreter of course uses its own localFP and localSP (and, sigh, framePointer and stackPointer, the former being a clever performance hack that tediously causes lots of code duplication, one that the JIT can hopefully do without). writeBackHeadFramePointers and externalWriteBackHeadFramePointers assign stackPage headFP and headSP from localFP &amp; localSP or framePointer and stackPointer respectively (see e.g. divorceAllFrames above).<\/p>\n<p>Because the stack and the heap are disjoint there is no overlap of caller saved fp and other fields on the stack (saved instruction pointers are also pointers but into method bytecodes). So by storing the spouse&#8217;s caller saved fp in the married context, a match implies the spouse frame pointer is to a frame at that position. If the frame has a context context matches then we know the two are married. If they&#8217;re not, the frame must have exited, and so we widow the context by converting it into a context that has been returned from, .e. we nil its sender and instruction pointer fields. Now you can see the bug in marryFrame above. The widowed context will have a valid method, receiver and arguments (arguments being read-only in Smalltalk) but shouldn&#8217;t hold onto the temporaries that existed at the time of its creation because they could be out-of-date. Alas Qwaq is too close to a release right now for me to dare fixing this; I&#8217;m going to wait a week or two. That a widowed context doesn&#8217;t hold onyto non-argument temporaries is, I believe (and fervently hope) the only visible difference between a pure context VM and a stack VM. I think its fair to expect that volatile state does disappear on return, and not holding onto volatile state is good for garbage collection. This change in semantics has never been complained about by the VisualWorks community when I introduced this scheme to VisualWorks in 1999. The only code I&#8217;ve ever seen affected by this was an exception report generator that used to generate its report after the exception handler had squirreled away the context and returned. The fix is either to generate the report in the exception handler or copy the context chain there-in.<br \/>\n<span style=\"color: #000000;\"><br \/>\nWith widowhood explained we can have a look at the full glory of return.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Return<\/h2>\n<p><span style=\"color: #000000;\">As we&#8217;ve seen, most of the time send and return are considerably less complicated than in the context VM. Send is somewhat more complicated when there&#8217;s a stack overflow. Return is somewhat more complicated when there is a base return:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for return bytecodes<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>commonReturn<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Note: Assumed to be inlined into the dispatch loop.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">closure<\/span> <span style=\"color: #404040;\">home<\/span> <span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span> <span style=\"color: #404040;\">frameToReturnTo<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">callerFP<\/span> <span style=\"color: #404040;\">newPage<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#frameToReturnTo<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#callerFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#thePage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;sharedCodeNamed: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;commonReturn&#8217;<\/span><\/span><span style=\"color: #000000;\"> inCase: <\/span><span style=\"color: #800000;\">120<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;If this is a method simply return to the sender\/caller.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameIsBlockActivation:<\/span><span style=\"color: #000000;\"> localFP) <\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">commonCallerReturn<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p><span style=\"color: #000000;\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0&#8230; non-local return code; here be beasties &#8230;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>commonCallerReturn<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Return to the previous context\/frame (sender for method activations, caller for block activations).&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">callersFPOrNull<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#callersFPOrNull<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;sharedCodeNamed: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;commonCallerReturn&#8217;<\/span><\/span><span style=\"color: #000000;\"> inCase: <\/span><span style=\"color: #800000;\">125<\/span><span style=\"color: #000000;\">&gt; <\/span><span style=\"color: #008080;\">&#8220;returnTopFromBlock&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">callersFPOrNull<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\n<\/span><span style=\"color: #404040;\">callersFPOrNull<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #008080;\">&#8220;baseFrame&#8221;<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> localFP <\/span><span style=\"color: #000080;\">=<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">baseFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">baseReturn<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0localIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSavedIP:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalSP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> localFP <\/span><span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameStackedReceiverOffset:<\/span><span style=\"color: #000000;\"> localFP).<br \/>\nlocalFP <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">callersFPOrNull<\/span><span style=\"color: #000000;\">.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span><span style=\"color: #000000;\"> localSP <\/span><span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> localReturnValue.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\nmethod <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span><span style=\"color: #000000;\"> localFP<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>baseReturn<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #404040;\">isContext<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">theSP<\/span> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theSP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#thePage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\n<\/span><span style=\"color: #404040;\">isContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #404040;\">isContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isStillMarriedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">thePage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theSP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #404040;\">isContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isIntegerObject:<\/span> <span style=\"color: #800000;\">(self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #800000;\">)<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">internalCannotReturn:<\/span><span style=\"color: #000000;\"> localReturnValue<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">thePage<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">makeBaseFrameFor:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theSP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">].<br \/>\nstackPages <\/span><span style=\"color: #000080;\">freeStackPageNoAssert:<\/span><span style=\"color: #000000;\"> stackPage. <\/span><span style=\"color: #008080;\">&#8220;for a short time invariant is violated; assert follows&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">setStackPageAndLimit:<\/span> <span style=\"color: #404040;\">thePage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPage.<br \/>\nlocalSP <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">theSP<\/span><span style=\"color: #000000;\">.<br \/>\nlocalFP <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\nmethod <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pointerForOop:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackTop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackTopPut:<\/span><span style=\"color: #000000;\"> localReturnValue.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">checkIsStillMarriedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #000080;\">currentFP:<\/span><span style=\"color: #000000;\"> localFP)<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">But non-local return is <\/span><span style=\"color: #000000;\"><em>much<\/em><\/span><span style=\"color: #000000;\"> more complicated. What does non-local return do in a pure context VM? It walks the context chain from a block context until it finds the block context&#8217;s home context, checking for unwnd protect contexts along the way. If it doesn&#8217;t find the home context it sends cannotReturn: and if it finds an unwnd protect it sends aboutToReturn:through: and allows the image to run unwind-protect blocks itself, otherwise it simply returns from the home context. Using the stack, things are seriously more complicated.<\/span><\/p>\n<p><span style=\"color: #000000;\">In the StackInterpreter non-local return occurs in some block activation (a frame) and returns from the block activation&#8217;s home context, which is some distance along the block activation&#8217;s closure&#8217;s outerContext chain (its lexical chain). The home context could be single, widowed or married. If married it could be a base frame whose caller could be single, widowed or married. If single we need to marry it to have a frame to resume execution in. If the home&#8217;s caller is married its spouse frame could be the head frame on its page or some interior frame. So we could be returning within a stack page or across stack pages or across stack pages and single contexts. First we have to walk this chain looking for unwind protects and the home context, then we have to do the return, freeing intervening stack pages. Complicated.<\/span><\/p>\n<p>So here it is. Read the comments and hopefully it&#8217;ll make sense.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for return bytecodes<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>commonReturn<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Note: Assumed to be inlined into the dispatch loop.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">closure<\/span> <span style=\"color: #404040;\">home<\/span> <span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span> <span style=\"color: #404040;\">frameToReturnTo<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">callerFP<\/span> <span style=\"color: #404040;\">newPage<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#frameToReturnTo<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#callerFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#thePage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;sharedCodeNamed: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;commonReturn&#8217;<\/span><\/span><span style=\"color: #000000;\"> inCase: <\/span><span style=\"color: #800000;\">120<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;If this is a method simply return to the sender\/caller.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameIsBlockActivation:<\/span><span style=\"color: #000000;\"> localFP) <\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">commonCallerReturn<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Since this is a block activation the closure is on the stack above any args and the frame.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">closure<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushedReceiverOrClosureOfFrame:<\/span><span style=\"color: #000000;\"> localFP.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">home<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">nil<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Walk the closure&#8217;s lexical chain to find the context or frame to return from (home).&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">closure<\/span> <span style=\"color: #000080;\">~~<\/span><span style=\"color: #000000;\"> nilObj] <\/span><span style=\"color: #000080;\">whileTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">home<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>ClosureOuterContextIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">closure<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">closure<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>ClosureIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">home<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;home is to be returned from provided there is no unwind-protect activation between<br \/>\nthis frame and home&#8217;s sender. Search for an unwind. findUnwindThroughContext:<br \/>\nwill answer either the context for an unwind-protect activation or nilObj if the sender<br \/>\ncannot be found or 0 if no unwind is found but the sender is. We must update the<br \/>\ncurrent page&#8217;s headFrame pointers to enable the search to identify widowed contexts<br \/>\ncorrectly.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">writeBackHeadFramePointers<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">findUnwindThroughContext:<\/span> <span style=\"color: #404040;\">home<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span> <span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> nilObj <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008080;\">&#8220;error: can&#8217;t find home on chain; cannot return&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">internalCannotReturn:<\/span><span style=\"color: #000000;\"> localReturnValue].<br \/>\n<\/span><span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span> <span style=\"color: #000080;\">~~<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">internalAboutToReturn:<\/span><span style=\"color: #000000;\"> localReturnValue <\/span><span style=\"color: #000080;\">through:<\/span> <span style=\"color: #404040;\">unwindContextOrNilOrZero<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Now we know home is on the sender chain.<br \/>\nWe could be returning to either a context or a frame. Find out which.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">nil<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #404040;\">home<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">checkIsStillMarriedContext:<\/span> <span style=\"color: #404040;\">home<\/span> <span style=\"color: #000080;\">currentFP:<\/span><span style=\"color: #000000;\"> localFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #404040;\">home<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">frameToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">home<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">checkIsStillMarriedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #000080;\">currentFP:<\/span><span style=\"color: #000000;\"> localFP<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">frameToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">nil<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;If returning to a context we must make a frame for it unless it is dead.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">contextToReturnTo<\/span> <span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">nil<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">frameToReturnTo<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">establishFrameForContextToReturnTo:<\/span> <span style=\"color: #404040;\">contextToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">frameToReturnTo<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #008080;\">&#8220;error: home&#8217;s sender is dead; cannot return&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">internalCannotReturn:<\/span><span style=\"color: #000000;\"> localReturnValue<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Now we have a frame to return to. If it is on a different page we must<br \/>\nfree intervening pages and nil out intervening contexts. We must free<br \/>\nintervening stack pages because if we leave the pages to be divorced<br \/>\nthen their contexts will be divorced with intact senders and instruction<br \/>\npointers. This code is similar to primitiveTerminateTo.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">newPage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">frameToReturnTo<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">newPage<\/span> <span style=\"color: #000080;\">~~<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">currentCtx<\/span> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #808080;\">nextCntx<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">currentCtx<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">baseFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isContext:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">freeStackPage:<\/span><span style=\"color: #000000;\"> stackPage.<br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">(<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #00eb00;\">(<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #00eb00;\">)<\/span><span style=\"color: #800000;\">)<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">]<\/span> <span style=\"color: #000080;\">whileFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800080;\">[<\/span><span style=\"color: #808080;\">thePage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #808080;\">currentCtx<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #000080;\">baseFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">freeStackPage:<\/span> <span style=\"color: #808080;\">thePage<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #800000;\">(self<\/span> <span style=\"color: #000080;\">isContext:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #800000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #808080;\">nextCntx<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #808080;\">currentCtx<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #808080;\">currentCtx<\/span> <span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> nilObj.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #808080;\">currentCtx<\/span> <span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> nilObj.<br \/>\n<\/span><span style=\"color: #808080;\">currentCtx<\/span> <strong>:=<\/strong> <span style=\"color: #808080;\">nextCntx<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">setStackPageAndLimit:<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #000000;\">.<br \/>\nlocalSP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">.<br \/>\nlocalFP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Two cases. Returning to the top frame or an interior frame.<br \/>\nThe top frame has its instruction pointer on top of stack.<br \/>\nAn interior frame has its instruction pointer in the caller frame.<br \/>\nWe need to peel back any frames on the page until we get to the correct frame.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0localFP <\/span><span style=\"color: #000080;\">==<\/span> <span style=\"color: #404040;\">frameToReturnTo<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008080;\">&#8220;pop the saved IP, push the return value and continue.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n[localIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pointerForOop:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackTop<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">callerFP<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> localFP.<br \/>\nlocalFP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\nlocalFP <\/span><span style=\"color: #000080;\">~~<\/span> <span style=\"color: #404040;\">frameToReturnTo<\/span><span style=\"color: #008000;\">]<\/span> <span style=\"color: #000080;\">whileTrue<\/span><span style=\"color: #000000;\">.<br \/>\nlocalIP <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSavedIP:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #000000;\">.<br \/>\nlocalSP <\/span><strong>:=<\/strong> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSP:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackTopPut:<\/span><span style=\"color: #000000;\"> localReturnValue.<br \/>\nmethod <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span><span style=\"color: #000000;\"> localFP.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><br \/>\n<strong>findUnwindThroughContext:<\/strong> <span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Search for either an unwind-protect (activation of method with primitive 198)<br \/>\nor homeContext along the sender chain, which ever is found first. If homeContext<br \/>\nis not found answer nilObj, indicating cannotReturn:. If homeContext is found<br \/>\nanswer 0. If homeContext is itself an unwind-protect answer the context, not 0.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">ctxtOrNilOrZero<\/span> <span style=\"color: #404040;\">theMethod<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalizeIPandSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Since nothing changes we don&#8217;t need to internalize.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">ctxtOrNilOrZero<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">findMethodWithPrimitive:<\/span> <span style=\"color: #800000;\">198<\/span> <span style=\"color: #000080;\">FromFP:<\/span><span style=\"color: #000000;\"> localFP <\/span><span style=\"color: #000080;\">UpToContext:<\/span> <span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">ctxtOrNilOrZero<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">theMethod<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">primitiveIndexOf:<\/span> <span style=\"color: #404040;\">theMethod<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #800000;\">198<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">ctxtOrNilOrZero<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>findMethodWithPrimitive:<\/strong> <span style=\"color: #000080;\">primitive<\/span> <strong>FromFP:<\/strong> <span style=\"color: #000080;\">startFP<\/span> <strong>UpToContext:<\/strong> <span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See findUnwindThroughContext:. Alas this is mutually recursive with<br \/>\nfindMethodWithPrimitive:FromContext:ThroughContext: instead of iterative.<br \/>\nWe&#8217;re doing the simplest thing that could possibly work. Niceties can wait.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">theFPAbove<\/span> <span style=\"color: #404040;\">theMethod<\/span> <span style=\"color: #404040;\">senderContext<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#startFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFPAbove<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">startFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFPAbove<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">startFP<\/span><span style=\"color: #000000;\">.<br \/>\n[<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #000080;\">homeContext<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #800000;\">(self<\/span> <span style=\"color: #000080;\">frameContext:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #800000;\">)<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^0<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theMethod<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameMethod:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">primitiveIndexOf:<\/span> <span style=\"color: #404040;\">theMethod<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #000080;\">primitive<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFPAbove<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">] <\/span><span style=\"color: #000080;\">whileTrue<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">senderContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span> <span style=\"color: #404040;\">theFPAbove<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isContext:<\/span> <span style=\"color: #404040;\">senderContext<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000000;\">nilObj].<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">findMethodWithPrimitive:<\/span> <span style=\"color: #000080;\">primitive<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">FromContext:<\/span> <span style=\"color: #404040;\">senderContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">UpToContext:<\/span> <span style=\"color: #000080;\">homeContext<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>findMethodWithPrimitive:<\/strong> <span style=\"color: #000080;\">primitive<\/span> <strong>FromContext:<\/strong> <span style=\"color: #000080;\">senderContext<\/span> <strong>UpToContext:<\/strong> <span style=\"color: #000080;\">homeContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See findUnwindThroughContext:. Alas this is mutually recursive with<br \/>\nfindMethodWithPrimitive:FromFP:SP:ThroughContext: instead of iterative.<br \/>\nWe&#8217;re doing the simplest thing that could possibly work. Niceties can wait.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #404040;\">theMethod<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">senderContext<\/span><span style=\"color: #000000;\">.<br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">] <\/span><span style=\"color: #000080;\">whileFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #000080;\">homeContext<\/span> <span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^0<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theMethod<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">primitiveIndexOf:<\/span> <span style=\"color: #404040;\">theMethod<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #000080;\">primitive<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">theContext<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #000080;\">=<\/span><span style=\"color: #000000;\"> nilObj <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">theContext<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isWidowedContext:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000000;\">nilObj].<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">findMethodWithPrimitive:<\/span> <span style=\"color: #000080;\">primitive<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">FromFP:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">UpToContext:<\/span> <span style=\"color: #000080;\">homeContext<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Ouch. That <\/span><span style=\"color: #000000;\"><em>is<\/em><\/span><span style=\"color: #000000;\"> complicated, but at least it is the <\/span><span style=\"color: #000000;\"><em>most<\/em><\/span><span style=\"color: #000000;\"> complicated thing in the StackInterpreter. It is not finished yet. The mutual recursion between findMethodWithPrimitive:FromFP:UpToContext: and findMethodWithPrimitive:FromContext:UpToContext: could conceivably cause the runtime C stack to overflow and should be flattened into a set of loops. But when I wrote this I found it much easier to understand because I was riting it in Smalltalk. I&#8217;m not at all convinced that the code inside the VisualWorks VMs correct because, being written in C, it is not nearly as comprehensible.<\/span><\/p>\n<p><span style=\"color: #000000;\">Those of you who know the Squeak VM well will know there&#8217;s a primitive terminateTo: that does something similar to the context nilling in non-local return. It is a little simpler than non-local return (although not much) but it is just a variation on the same theme so I&#8217;ll spare you.<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Hiding Stack Frames<\/h2>\n<p>Still reading? Good. Now we&#8217;re ready for some fun. While we&#8217;ve organized the system around stack pages and improved performance markedly (measurements to follow) and prepared the ground for the JIT, we still have to hide these stack pages from the Smalltalk programmer. We need to arrange that whever he or she accesses a context it hides its spose and always pretends to be single, whether we read or write it. We&#8217;ve seen how return copes with this, but what about methods on context such as<\/p>\n<p><em>ContextPart methods for debugger access<\/em><br \/>\n<strong>swapSender:<\/strong> <span style=\"color: #000080;\">coroutine<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Replace the receiver&#8217;s sender with coroutine and answer the receiver&#8217;s<br \/>\nprevious sender. For use in coroutining.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">oldSender<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">oldSender<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> sender.<br \/>\nsender <\/span><strong>:=<\/strong> <span style=\"color: #000080;\">coroutine<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">oldSender<\/span><\/p>\n<p>The problem here is that the current valid state of the context lives in the frame and changing that state needs to either affect the frame or update the context after it has been divorced. One apparently straight-forward way to handle this is to divorce contexts whenever they are sent messages and whenever the system attempts to access a context instance variable. This is the way the VisualWorks VM handled things until I changed the scheme in 5i in 1999. Married contexts (hybrid contexts in the VisualWorks terminology) had special classes that would cause teh send machinery to trap and &#8220;stabilize&#8221; (divorce) the receiver context. The bytecode compiler marked methods that accessed instance variables which could be run by contexts and the JIT generated special code that would stabilize the receiver context before accessing an instance variable.<\/p>\n<p>The main problem with this approach is that any kind of state access ends up divorcing a context which hurts performance and encourages a proliferation of complex primitives in the VM which try and avoid divorce replicating code that could be written in the image. The other problem is that it is slow. Sends to contexts trap and divorce even for read access. Wen I introduced the scheme I&#8217;m using here exception handling code and non-local return roughly doubled in speed. The key in this scheme is to intercept all access to context instace variables and forward the access to the spouse if married.<\/p>\n<p>In the VM the only places the state of a context are accessed outside of the frame management code for send and return and stack page management are the instance variable access bytecodes and the at: at:put: instVarAt: and instVarAt:put: primitives. Instance variable access is very frequent so having to test for accessing a context on every instance variable access bytecode would hurt performance noticeably. Unlike a JIT we can&#8217;t perform the text for contextness at compile time based on the class of the method being compiled; we have to test on execution of the relevant bytecocde. But as I alluded to in <a href=\"http:\/\/www.mirandabanda.org\/cogblog\/2008\/07\/24\/closures-part-iii-the-compiler\/\">Closures Part III<\/a> I added a horrible hack to the bytecode compiler to avoid testing on most instace variable accesses.<\/p>\n<p>The compiler allows a class to specify special node classes for handling instance variables. This is used by Tweak to access properties and by InstructionStream, the first superclass of ContextPart to introduce state, to handle context instance variables.<\/p>\n<p><em>Encoder methods for initialize-release<\/em><br \/>\n<strong>init:<\/strong> <span style=\"color: #000080;\">aClass<\/span> <strong>context:<\/strong> <span style=\"color: #000080;\">aContext<\/span> <strong>notifying:<\/strong> <span style=\"color: #000080;\">req<\/span><span style=\"color: #000000;\"><br \/>\nrequestor <\/span><strong>:=<\/strong> <span style=\"color: #000080;\">req<\/span><span style=\"color: #000000;\">.<br \/>\nclass <\/span><strong>:=<\/strong> <span style=\"color: #000080;\">aClass<\/span><span style=\"color: #000000;\">.<br \/>\nnTemps <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">.<br \/>\nsupered <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">initScopeAndLiteralTables<\/span><span style=\"color: #000000;\">.<br \/>\nclass <\/span><span style=\"color: #000080;\">variablesAndOffsetsDo:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">variable<\/span> <span style=\"color: #008080;\">&#8220;&lt;String|CFieldDefinition&gt;&#8221;<\/span><span style=\"color: #000000;\"> :<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #008080;\">&#8220;&lt;Integer|nil&gt;&#8221;<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">isNil<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">scopeTable <\/span><span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">variable<\/span> <span style=\"color: #000080;\">name<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #000000;\">FieldNode <\/span><span style=\"color: #000080;\">new<\/span> <span style=\"color: #000080;\">fieldDefinition:<\/span> <span style=\"color: #000080;\">variable<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">scopeTable<br \/>\n<\/span><span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">variable<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">put:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">&gt;=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #800000;\">[<\/span><span style=\"color: #000000;\">InstanceVariableNode <\/span><span style=\"color: #000080;\">new<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">name:<\/span> <span style=\"color: #000080;\">variable<\/span> <span style=\"color: #000080;\">index:<\/span> <span style=\"color: #000080;\">offset<\/span><span style=\"color: #800000;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span> <span style=\"color: #800000;\">[<\/span><span style=\"color: #000000;\">MaybeContextInstanceVariableNode <\/span><span style=\"color: #000080;\">new<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">name:<\/span> <span style=\"color: #000080;\">variable<\/span> <span style=\"color: #000080;\">index:<\/span> <span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">negated<\/span><span style=\"color: #800000;\">]<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #000080;\">aContext<\/span> <span style=\"color: #000080;\">~~<\/span> <span style=\"color: #800000;\">nil<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">homeNode<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">homeNode<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">bindTemp:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">doItInContextName<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;0th temp = aContext passed as arg&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">aContext<\/span> <span style=\"color: #000080;\">tempNames<\/span> <span style=\"color: #000080;\">withIndexDo:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #000080;\">variable<\/span><span style=\"color: #000000;\"> :<\/span><span style=\"color: #000080;\">index<\/span><span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\nscopeTable<br \/>\n<\/span><span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">variable<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">put:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #000000;\">MessageAsTempNode <\/span><span style=\"color: #000080;\">new<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">receiver:<\/span> <span style=\"color: #808080;\">homeNode<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">selector:<\/span> <span style=\"color: #000080;\">#namedTempAt:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">arguments:<\/span> <span style=\"color: #800000;\">(<\/span><span style=\"color: #000000;\">Array <\/span><span style=\"color: #000080;\">with:<\/span> <span style=\"color: #00eb00;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">encodeLiteral:<\/span> <span style=\"color: #000080;\">index<\/span><span style=\"color: #00eb00;\">)<\/span><span style=\"color: #800000;\">)<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">precedence:<\/span> <span style=\"color: #800000;\">3<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">from:<\/span> <span style=\"color: #800000;\">self<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">].<br \/>\nsourceRanges <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> Dictionary <\/span><span style=\"color: #000080;\">new:<\/span> <span style=\"color: #800000;\">32<\/span><span style=\"color: #000000;\">.<br \/>\nglobalSourceRanges <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> OrderedCollection <\/span><span style=\"color: #000080;\">new:<\/span> <span style=\"color: #800000;\">32<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>CProtoObject class methods for compiling<\/em><\/span><span style=\"color: #000080;\"><br \/>\n<\/span><strong>variablesAndOffsetsDo:<\/strong> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;This is the interface between the compiler and a class&#8217;s instance or field names. The<br \/>\nclass should enumerate aBinaryBlock with the field definitions (with nil offsets) followed<br \/>\nby the instance variable name strings and their integer offsets (1-relative). The order is<br \/>\nimportant; names evaluated later will override the same names occurring earlier.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">allFieldsReverseDo:<\/span><span style=\"color: #000000;\"> [:<\/span><span style=\"color: #000080;\">field<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #000080;\">field<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #800000;\">nil<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instVarNamesAndOffsetsDo:<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span><\/p>\n<p><em>Behavior methods for compiling<\/em><br \/>\n<strong>variablesAndOffsetsDo:<\/strong> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;This is the interface between the compiler and a class&#8217;s instance or field names. The<br \/>\nclass should enumerate aBinaryBlock with the field definitions (with nil offsets) followed<br \/>\nby the instance variable name strings and their integer offsets (1-relative). The order is<br \/>\nimportant; names evaluated later will override the same names occurring earlier.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Only need to do instance variables here. CProtoObject introduces field definitions.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instVarNamesAndOffsetsDo:<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>instVarNamesAndOffsetsDo:<\/strong> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;This is part of the interface between the compiler and a class&#8217;s instance or field names.<br \/>\nThe class should enumerate aBinaryBlock with the instance variable name strings and<br \/>\ntheir integer offsets. The order is important. Names evaluated later will override the<br \/>\nsame names occurring earlier.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Nothing to do here; ClassDescription introduces named instance variables&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><\/p>\n<p><em>ClassDescription methods for compiling<\/em><br \/>\n<strong>instVarNamesAndOffsetsDo:<\/strong> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;This is part of the interface between the compiler and a class&#8217;s instance or field names.<br \/>\nThe class should enumerate aBinaryBlock with the instance variable name strings and<br \/>\ntheir integer offsets. The order is important. Names evaluated later will override the<br \/>\nsame names occurring earlier.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">superInstSize<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #404040;\">superInstSize<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> superclass <\/span><span style=\"color: #000080;\">notNil<\/span> <span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">superclass <\/span><span style=\"color: #000080;\">instSize<\/span><span style=\"color: #008000;\">]<\/span> <span style=\"color: #000080;\">ifFalse:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">0<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">&gt;<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[superclass <\/span><span style=\"color: #000080;\">instVarNamesAndOffsetsDo:<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instSize<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\">superInstSize<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000000;\">instanceVariables <\/span><span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">i<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">superInstSize<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><em>InstructionStream class methods for compiling<br \/>\n<\/em><strong>instVarNamesAndOffsetsDo:<\/strong> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;This is part of the interface between the compiler and a class&#8217;s instance or field names.<br \/>\nWe override here to arrange that the compiler will use MaybeContextInstanceVariableNodes<br \/>\nfor instances variables of ContextPart or any of its superclasses and subclasses. The<br \/>\nconvention to make the compiler use the special nodes is to use negative indices&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">superInstSize<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withAllSubclasses<\/span> <span style=\"color: #000080;\">noneSatisfy:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #000080;\">class<\/span><span style=\"color: #808080;\">|<\/span><span style=\"color: #000080;\">class<\/span> <span style=\"color: #000080;\">isContextClass<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^super<\/span> <span style=\"color: #000080;\">instVarNamesAndOffsetsDo:<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\">].<br \/>\n(<\/span><span style=\"color: #404040;\">superInstSize<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> superclass <\/span><span style=\"color: #000080;\">notNil<\/span> <span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">superclass <\/span><span style=\"color: #000080;\">instSize<\/span><span style=\"color: #008000;\">]<\/span> <span style=\"color: #000080;\">ifFalse:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">0<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">&gt;<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[superclass <\/span><span style=\"color: #000080;\">instVarNamesAndOffsetsDo:<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instSize<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\">superInstSize<\/span> <span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"><br \/>\n[:<\/span><span style=\"color: #000080;\">i<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #000080;\">aBinaryBlock<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000000;\">instanceVariables <\/span><span style=\"color: #000080;\">at:<\/span> <span style=\"color: #000080;\">i<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">value:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">superInstSize<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">negated<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><span style=\"color: #000000;\">MaybeContextInstanceVariableNode simply forces the use of the long-form instance variable bytecodes:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>MaybeContextInstanceVariableNode methods for code generation (new scheme)<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>emitCodeForValue:<\/strong> <span style=\"color: #000080;\">stack<\/span> <strong>encoder:<\/strong> <span style=\"color: #000080;\">encoder<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">stack<\/span> <span style=\"color: #000080;\">push:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000080;\">encoder<\/span> <span style=\"color: #000080;\">genPushInstVarLong:<\/span><span style=\"color: #000000;\"> index<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>emitCodeForStorePop:<\/strong> <span style=\"color: #000080;\">stack<\/span> <strong>encoder:<\/strong> <span style=\"color: #000080;\">encoder<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">encoder<\/span> <span style=\"color: #000080;\">genStorePopInstVarLong:<\/span><span style=\"color: #000000;\"> index.<br \/>\n<\/span><span style=\"color: #000080;\">stack<\/span> <span style=\"color: #000080;\">pop:<\/span> <span style=\"color: #800000;\">1<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">EncoderForV3 methods for bytecode generation<br \/>\n<\/span><strong>genPushInstVarLong:<\/strong> <span style=\"color: #000080;\">instVarIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See BlueBook page 596&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See also MaybeContextInstanceVariableNode&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">&gt;=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #800000;\">256<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008080;\">&#8220;132 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a010000100 iiijjjjj kkkkkkkk \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstream<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #800000;\">132<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #800000;\">64<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #000080;\">instVarIndex<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">outOfRangeError:<\/span> <span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;index&#8217;<\/span><\/span> <span style=\"color: #000080;\">index:<\/span> <span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">range:<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #800000;\">255<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>genStorePopInstVarLong:<\/strong> <span style=\"color: #000080;\">instVarIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See BlueBook page 596&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;See also MaybeContextInstanceVariableNode&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">&gt;=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #800000;\">256<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008080;\">&#8220;132 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a010000100 iiijjjjj kkkkkkkk \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(Send, Send Super, Push Receiver Variable, Push Literal Constant, Push Literal Variable, Store Receiver Variable, Store-Pop Receiver Variable, Store Literal Variable)[iii] #kkkkkkkk jjjjj&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstream<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #800000;\">132<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #800000;\">192<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">nextPut:<\/span> <span style=\"color: #000080;\">instVarIndex<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">outOfRangeError:<\/span> <span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;index&#8217;<\/span><\/span> <span style=\"color: #000080;\">index:<\/span> <span style=\"color: #000080;\">instVarIndex<\/span> <span style=\"color: #000080;\">range:<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">to:<\/span> <span style=\"color: #800000;\">255<\/span><\/p>\n<p><span style=\"color: #000000;\">The doubleExtendedDoAnythingBytecode (I&#8217;m not making this up) only needs to be used for instance variables with an offset greater than 63, which is rare. Since MethodContext only has 6 instance variables we only have to check for the receiver being a contex if we&#8217;re using the doubleExtendedDoAnythingBytecode to access instance variables 0 through 5. Since the doubleExtendedDoAnythingBytecode has to do a lot of decoding before it computes the instance variable offset and the test is ony a compare of the computed index against the constant 6 the test is essentally free for all but use on actual contexts.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for send bytecodes<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>doubleExtendedDoAnythingBytecode<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Replaces the Blue Book double-extended send [132], in which the first byte was wasted on 8 bits of argument count.<br \/>\nHere we use 3 bits for the operation sub-type (opType), and the remaining 5 bits for argument count where needed.<br \/>\nThe last byte give access to 256 instVars or literals.<br \/>\nSee also secondExtendedSendBytecode&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">byte2<\/span> <span style=\"color: #404040;\">byte3<\/span> <span style=\"color: #404040;\">opType<\/span> <span style=\"color: #404040;\">top<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">byte2<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchByte<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">byte3<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchByte<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">byte2<\/span> <span style=\"color: #000080;\">&gt;&gt;<\/span> <span style=\"color: #800000;\">5<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[messageSelector <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">literal:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #000000;\">.<br \/>\nargumentCount <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">byte2<\/span> <span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #800000;\">31<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">normalSend<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[messageSelector <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">literal:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #000000;\">.<br \/>\nargumentCount <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">byte2<\/span> <span style=\"color: #000080;\">bitAnd:<\/span> <span style=\"color: #800000;\">31<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">superclassSend<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchNextBytecode<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">2<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">pushMaybeContextReceiverVariable:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">3<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">pushLiteralConstant:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">4<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">pushLiteralVariable:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">top<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalStackTop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">5<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">storeMaybeContextReceiverVariable:<\/span> <span style=\"color: #404040;\">byte3<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">top<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">6<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPop:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">storeMaybeContextReceiverVariable:<\/span> <span style=\"color: #404040;\">byte3<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">top<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">opType<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #800000;\">7<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\"><strong>ValueIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">literal:<\/span> <span style=\"color: #404040;\">byte3<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #404040;\">top<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for stack bytecodes<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>pushMaybeContextReceiverVariable:<\/strong> <span style=\"color: #000080;\">fieldIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Must trap accesses to married and widowed contexts.<br \/>\nBut don&#8217;t want to check on all inst var accesses. This<br \/>\nmethod is only used by the long-form bytecodes, evading<br \/>\nthe cost. Note that the method, closure and receiver fields<br \/>\nof married contexts are correctly initialized so they don&#8217;t<br \/>\nneed special treatment on read. Only sender, instruction<br \/>\npointer and stack pointer need to be intercepted on reads.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #404040;\">rcvr<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">receiver<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instVar:<\/span> <span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">ofContext:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalPush:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>storeMaybeContextReceiverVariable:<\/strong> <span style=\"color: #000080;\">fieldIndex<\/span> <strong>withValue:<\/strong> <span style=\"color: #000080;\">anObject<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Must trap accesses to married and widowed contexts.<br \/>\nBut don&#8217;t want to check on all inst var accesses. This<br \/>\nmethod is only used by the long-form bytecodes, evading the cost.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">rcvr<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">receiver<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">&lt;=<\/span> <span style=\"color: #404040;\"><strong>ReceiverIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #404040;\">rcvr<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">instVar:<\/span> <span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">ofContext:<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #000080;\">anObject<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #000080;\">fieldIndex<\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">rcvr<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #000080;\">anObject<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><span style=\"color: #000000;\">Reading is easy. Simply compute the relevant value, sender, pc or stackp from the spouse frame.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for frame access<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>instVar:<\/strong> <span style=\"color: #000080;\">offset<\/span> <strong>ofContext:<\/strong> <span style=\"color: #000080;\">aOnceMarriedContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Fetch an instance avriable from a maybe married context.<br \/>\nIf the context is still married compute the value of the<br \/>\nrelevant inst var from the spouse frame&#8217;s state.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">spouseFP<\/span> <span style=\"color: #404040;\">senderFP<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#spouseFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#senderFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#thePage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFPAbove<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span> <span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #404040;\"><strong>MethodIndex<\/strong><\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #000080;\">aOnceMarriedContext<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">writeBackHeadFramePointers<\/span><span style=\"color: #000000;\">.<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isWidowedContext:<\/span> <span style=\"color: #000080;\">aOnceMarriedContext<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">aOnceMarriedContext<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #404040;\">spouseFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withoutSmallIntegerTags:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">aOnceMarriedContext<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #404040;\">spouseFP<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">frameCallerContext:<\/span> <span style=\"color: #404040;\">spouseFP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">senderFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">spouseFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span> <span style=\"color: #404040;\">senderFP<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #404040;\"><strong>StackPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">integerObjectOf:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackPointerIndexForFrame:<\/span> <span style=\"color: #404040;\">spouseFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #000080;\">offset<\/span> <span style=\"color: #000080;\">=<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">theIP<\/span> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #808080;\">theFPAbove<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">spouseFP<\/span> <span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> localFP<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #808080;\">theIP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">oopForPointer:<\/span><span style=\"color: #000000;\"> localIP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #808080;\">thePage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">spouseFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #808080;\">theFPAbove<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">findFrameAbove:<\/span> <span style=\"color: #404040;\">spouseFP<\/span> <span style=\"color: #000080;\">inPage:<\/span> <span style=\"color: #808080;\">thePage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #808080;\">theIP<\/span> <strong>:=<\/strong> <span style=\"color: #808080;\">theFPAbove<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">oopForPointer:<\/span> <span style=\"color: #800000;\">(self<\/span> <span style=\"color: #000080;\">frameCallerSavedIP:<\/span> <span style=\"color: #808080;\">theFPAbove<\/span><span style=\"color: #800000;\">)<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span> <span style=\"color: #000080;\">contextInstructionPointerForFrame:<\/span> <span style=\"color: #404040;\">spouseFP<\/span> <span style=\"color: #000080;\">IP:<\/span> <span style=\"color: #808080;\">theIP<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">error:<\/span> <span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;bad index&#8217;<\/span><\/span><\/p>\n<p><span style=\"color: #000000;\">Writing is a different matter. The one case that&#8217;s really important for performance is assigning the sender because it is used in e.g. co-routining but also in stack unwinding and termination. It is trivial to assign the sender of a base frame as it already refers to a context, but to assign to the sender of any other frame requires ingenuity something that Peter Deutsch and Allan Schiffman have in abundance and their solution is to split the stack into two.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><img src=\"http:\/\/www.mirandabanda.org\/images\/stackmapping\/splitstack-fig1.jpg\" alt=\"\" \/><br \/>\n<span style=\"color: #000000;\"><br \/>\nThe assignee and all frames above it are moved to another stack, making the assignee the base frame, rendering assigning the sender trivial. Likewise handlng other assignment cases is done by moving all frames above the assignee to another stack, divorcing the assignee frame and assigning to the resulting single context. Once the assignee frame is a base frame we no longer have to split its stack if its sender is assigned again. So contexts that have their sender assigned often migrate to the bottom of stack pages, allowing the StackInterpreter to keep up with a context interpreter when co-routining.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for frame access<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>instVar:<\/strong> <span style=\"color: #000080;\">index<\/span> <strong>ofContext:<\/strong> <span style=\"color: #000080;\">aMarriedContext<\/span> <strong>put:<\/strong> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Assign the field of a married context. The important case to optimize is<br \/>\nassigning the sender. We could also consider optimizing assiging the IP but<br \/>\ntypically that is followed by an assignment to the stack pointer and we can&#8217;t<br \/>\nefficiently assign the stack pointer because it involves moving frames around.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isMarriedOrWidowedContext:<\/span> <span style=\"color: #000080;\">aMarriedContext<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameOfMarriedContext:<\/span> <span style=\"color: #000080;\">aMarriedContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #000080;\">index<\/span> <span style=\"color: #000080;\">==<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #808080;\">onCurrentPage<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">thePage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">mostRecentlyUsedPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #808080;\">onCurrentPage<\/span> <strong>:=<\/strong> <span style=\"color: #808080;\">thePage<\/span> <span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPage<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">writeBackHeadFramePointers<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storeSenderOfFrame:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #808080;\">onCurrentPage<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">localFP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\nlocalSP <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headSP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^self<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalizeIPandSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalDivorceFrame:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">andContext:<\/span> <span style=\"color: #000080;\">aMarriedContext<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #000080;\">index<\/span> <span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #000080;\">aMarriedContext<\/span> <span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">internalizeIPandSP<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>storeSenderOfFrame:<\/strong> <span style=\"color: #000080;\">theFP<\/span> <strong>withValue:<\/strong> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Set the sender of a frame. If the frame is a base frame then this is trivial;<br \/>\nmerely store into the FoxCallerSavedIP field. If not, then split the stack at<br \/>\nthe frame, moving the frame and those hotter than it to a new stack page.<br \/>\nIn the new stack page the frame will be the base frame and storing trivial.<br \/>\nAnswer the possibly changed location of theFP.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #404040;\">onCurrentPage<\/span> <span style=\"color: #404040;\">newPage<\/span> <span style=\"color: #404040;\">theMovedFP<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#thePage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theMovedFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;returnTypeC: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;char *&#8217;<\/span><\/span><span style=\"color: #000000;\">&gt;<br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxCallerSavedIP<\/strong><\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #404040;\">thePage<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">stackPageFor:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">mostRecentlyUsedPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">onCurrentPage<\/span> := <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPage.<br \/>\n<\/span><span style=\"color: #404040;\">onCurrentPage<\/span> <span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #008080;\">&#8220;Make sure the frame&#8217;s page isn&#8217;t divorced when a new page is allocated.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstackPages <\/span><span style=\"color: #000080;\">markStackPageNextMostRecentlyUsed:<\/span> <span style=\"color: #404040;\">thePage<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">newPage<\/span> := <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">newStackPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">theMovedFP<\/span> := <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">moveFramesIn:<\/span> <span style=\"color: #404040;\">thePage<\/span> <span style=\"color: #000080;\">through:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">toPage:<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">onCurrentPage<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">setStackPageAndLimit:<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #404040;\">theMovedFP<\/span><span style=\"color: #000000;\">).<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">theMovedFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">FoxCallerSavedIP<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #000080;\">anOop<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">theMovedFP<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><strong>moveFramesIn:<\/strong> <span style=\"color: #000080;\">oldPage<\/span> <strong>through:<\/strong> <span style=\"color: #000080;\">theFP<\/span> <strong>toPage:<\/strong> <span style=\"color: #000080;\">newPage<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Move frames from the hot end of oldPage through to theFP to newPage.<br \/>\nThis has the effect of making theFP a base frame which can be stored into.<br \/>\nAnswer theFP&#8217;s new location.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">newSP<\/span> <span style=\"color: #404040;\">newFP<\/span> <span style=\"color: #404040;\">stackedReceiverOffset<\/span> <span style=\"color: #404040;\">delta<\/span> <span style=\"color: #404040;\">callerFP<\/span> <span style=\"color: #404040;\">callerIP<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span> <span style=\"color: #404040;\">offsetCallerFP<\/span> <span style=\"color: #404040;\">theContext<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">false<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#oldPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newSP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#callerFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#fpInNewPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#offsetCallerFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#source<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;returnTypeC: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;char *&#8217;<\/span><\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #404040;\">newSP<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">newPage<\/span> <span style=\"color: #000080;\">baseAddress<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">stackedReceiverOffset<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameStackedReceiverOffset:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;First move the data. We will fix up frame pointers later.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">stackedReceiverOffset<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">to:<\/span> <span style=\"color: #000080;\">oldPage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">by:<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span> <span style=\"color: #000080;\">negated<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">do:<\/span><span style=\"color: #000000;\"> [:<\/span><span style=\"color: #000080;\">source<\/span><span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">newSP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">newSP<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">newSP<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #000000;\">stackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">source<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;newSP = oldSP + delta =&gt; delta = newSP &#8211; oldSP&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">delta<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">newSP<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #000080;\">oldPage<\/span> <span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">newFP<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">newPage<\/span> <span style=\"color: #000080;\">baseAddress<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #404040;\">stackedReceiverOffset<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">setHeadFP:<\/span> <span style=\"color: #000080;\">oldPage<\/span> <span style=\"color: #000080;\">headFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">delta<\/span> <span style=\"color: #000080;\">andSP:<\/span> <span style=\"color: #404040;\">newSP<\/span> <span style=\"color: #000080;\">inPage:<\/span> <span style=\"color: #000080;\">newPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #000080;\">newPage<\/span> <span style=\"color: #000080;\">baseFP:<\/span> <span style=\"color: #404040;\">newFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">callerFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #404040;\">callerIP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">oopForPointer:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerSavedIP:<\/span> <span style=\"color: #000080;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">stackedReceiverOffset<\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #404040;\">callerIP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #000080;\">oldPage<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">headFP:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #000000;\">;<br \/>\n<\/span><span style=\"color: #000080;\">headSP:<\/span> <span style=\"color: #000080;\">theFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">stackedReceiverOffset<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Mark the new base frame in the new page&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">newFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxCallerSavedIP<\/strong><\/span> <span style=\"color: #000080;\">put:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameContext:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #000000;\">).<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">newFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxSavedFP<\/strong><\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Now relocate frame pointers, updating married contexts to refer to their moved spouse frames.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">fpInNewPage<\/span> <strong>:=<\/strong> <span style=\"color: #000080;\">newPage<\/span> <span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\n[<\/span><span style=\"color: #404040;\">offsetCallerFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">offsetCallerFP<\/span> <span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">offsetCallerFP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">offsetCallerFP<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">delta<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\nstackPages <\/span><span style=\"color: #000080;\">longAt:<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\"><strong>FoxSavedFP<\/strong><\/span> <span style=\"color: #000080;\">put:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">oopForPointer:<\/span> <span style=\"color: #404040;\">offsetCallerFP<\/span><span style=\"color: #008000;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">theContext<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameContext:<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>SenderIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withSmallIntegerTags:<\/span> <span style=\"color: #404040;\">fpInNewPage<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointerUnchecked:<\/span> <span style=\"color: #404040;\"><strong>InstructionPointerIndex<\/strong><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span> <span style=\"color: #404040;\">theContext<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">withSmallIntegerTags:<\/span> <span style=\"color: #404040;\">offsetCallerFP<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">fpInNewPage<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">offsetCallerFP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">fpInNewPage<\/span> <span style=\"color: #000080;\">~=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">] <\/span><span style=\"color: #000080;\">whileTrue<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">^<\/span><span style=\"color: #404040;\">newFP<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">It turns out that <\/span><span style=\"color: #000080;\">moveFramesIn:through:toPage:<\/span><span style=\"color: #000000;\"> is useful for one more function that really helps performance, stack overflow. Consider what happens in the execution of benchFib:<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>Integer methods for benchmarks<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>benchFib<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">^<\/span> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #800000;\">2<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000080;\">&#8211;<\/span><span style=\"color: #800000;\">1<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">benchFib<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000080;\">&#8211;<\/span><span style=\"color: #800000;\">2<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">benchFib<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p><span style=\"color: #000000;\">If the initial argument is larger than the number of activations of nfib that can fit on the remaining room in the stack page a stack overflow will occur, and probably soon thereafter a base return back to the original stack. At some point the system will thrash doing overflowing sends and underflowing returns. When we first started using the StackInterpreter inside Qwaq benchFib for large N would do well but benchFib for small N would do badly and the problem was overflow\/underflow thrashing.<\/span><\/p>\n<p>The simple fix is to increase the number of frames moved on each successive overflow from the same page. On the first overflow we move one frame, on the second two and so on. Soon the thrashing is taken care of because the active frames end up located on the same page. So here&#8217;s stack overflow. It turns out we only need two variables to remember which page last overflowed and a count of frames to move.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>StackInterpreter methods for frame access<\/em><\/span><span style=\"color: #000000;\"><br \/>\n<\/span><strong>stackOverflowOrEvent:<\/strong> <span style=\"color: #000080;\">numArgs<\/span> <strong>mayContextSwitch:<\/strong> <span style=\"color: #000080;\">mayContextSwitch<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;The stackPointer is below the stackLimit. This is either because of a<br \/>\nstack overflow or the setting of stackLimit to indicate a possible interrupt.<br \/>\nCheck for interrupts and stackOverflow and deal with each appropriately.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">newPage<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #404040;\">callerFP<\/span> <span style=\"color: #404040;\">overflowLimitAddress<\/span> <span style=\"color: #404040;\">overflowCount<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#newPage<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;StackPage *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#theFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#callerFP<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#overflowLimitAddress<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #000080;\">#&#8217;char *&#8217;<\/span><span style=\"color: #000000;\">&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;If the stackLimit differs from the realStackLimit then the stackLimit<br \/>\nhas been set to indicate an event or interrupt that needs servicing.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstackLimit <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">realStackLimit<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">externalWriteBackHeadFramePointers<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">checkForEventsMayContextSwitch:<\/span> <span style=\"color: #000080;\">mayContextSwitch<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;After checkForInterrupts another event check may have been forced, setting both<br \/>\nstackLimit and stackPage stackLimit to all ones. So here we must check against<br \/>\nthe real stackLimit, not the effective stackLimit.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nstackPointer <\/span><span style=\"color: #000080;\">&lt;<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">realStackLimit<\/span> <span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #800000;\">^nil<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0statStackOverflow <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> statStackOverflow <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;The stack has overflowed this page. If the system is executing some recursive algorithm,<br \/>\ne.g. fibonacci, then the system could thrash overflowing the stack if the call soon returns<br \/>\nback to the current page. To avoid thrashing, since overflow is quite slow, we can move<br \/>\nmore than one frame. The idea is to record which page has overflowed, and the first<br \/>\ntime it overflows move one frame, the second time two frames, and so on. We move no<br \/>\nmore frames than would leave the page half occupied.&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> framePointer.<br \/>\nstackPage <\/span><span style=\"color: #000080;\">==<\/span><span style=\"color: #000000;\"> overflowedPage<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"><br \/>\n[<\/span><span style=\"color: #404040;\">overflowLimitAddress<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">baseAddress<\/span> <span style=\"color: #000080;\">&#8211;<\/span><span style=\"color: #000000;\"> stackPages <\/span><span style=\"color: #000080;\">overflowLimit<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">overflowCount<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> extraFramesToMoveOnOverflow <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> extraFramesToMoveOnOverflow <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #800080;\">(<\/span><span style=\"color: #404040;\">overflowCount<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">overflowCount<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #800080;\">)<\/span> <span style=\"color: #000080;\">&gt;=<\/span> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800080;\">[<\/span><span style=\"color: #800000;\">(<\/span><span style=\"color: #404040;\">callerFP<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #800000;\">)<\/span> <span style=\"color: #000080;\">&lt;<\/span> <span style=\"color: #404040;\">overflowLimitAddress<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">and:<\/span> <span style=\"color: #800000;\">[<\/span><span style=\"color: #00eb00;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isBaseFrame:<\/span> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #00eb00;\">)<\/span> <span style=\"color: #000080;\">not<\/span><span style=\"color: #800000;\">]<\/span><span style=\"color: #800080;\">]<\/span><span style=\"color: #008000;\">]<\/span> <span style=\"color: #000080;\">whileTrue:<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008000;\">[<\/span><span style=\"color: #404040;\">theFP<\/span> <strong>:=<\/strong> <span style=\"color: #404040;\">callerFP<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"><br \/>\n[overflowedPage <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage.<br \/>\nextraFramesToMoveOnOverflow <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">0<\/span><span style=\"color: #000000;\">].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">ensureFrameIsMarried:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameCallerFP:<\/span> <span style=\"color: #404040;\">theFP<\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #404040;\">newPage<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">newStackPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">moveFramesIn:<\/span><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">through:<\/span> <span style=\"color: #404040;\">theFP<\/span> <span style=\"color: #000080;\">toPage:<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">setStackPageAndLimit:<\/span> <span style=\"color: #404040;\">newPage<\/span><span style=\"color: #000000;\">.<br \/>\nframePointer <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headFP<\/span><span style=\"color: #000000;\">.<br \/>\nstackPointer <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> stackPage <\/span><span style=\"color: #000080;\">headSP<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;To overflow the stack this must be a new frame&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">frameHasContext:<\/span><span style=\"color: #000000;\"> framePointer) <\/span><span style=\"color: #000080;\">not<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">assert:<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">validInstructionPointer:<\/span><span style=\"color: #000000;\"> instructionPointer <\/span><span style=\"color: #000080;\">inMethod:<\/span><span style=\"color: #000000;\"> method)<\/span><\/p>\n<p>&nbsp;<\/p>\n<h2>Garbage Collection<\/h2>\n<p>Before we can have a look at measurements I need to discuss garbage collection. There&#8217;s not much difficulty grabae collecitng references frm stack pages. The garbage collector simply has to traverse the frames on in-use pages. There is a need to void stack pages that are not reachable to stop them holding onto garbage, but this also is easy. The major problem is the Squeak VM&#8217;s habit of running the garbage collector inside an allocation when memory runs out. This is a feature it shares with a number of other garbage collectors in VMs and it is difficult to be emphatic enough when saying how horrible this is. It is incredibly difficult to live with and a huge source of bugs. Because the garbage collector can run, and hence move objects, on any allocation the VM must hold onto all unreferenced intermediate results it is using while allocating. For example, look at the start of the basic allocation routine in the standard Squeak VM:<\/p>\n<p><em>ObjectMemory methods for allocation<\/em><br \/>\n<strong>allocate:<\/strong> <span style=\"color: #000080;\">byteSize<\/span> <strong>headerSize:<\/strong> <span style=\"color: #000080;\">hdrSize<\/span> <strong>h1:<\/strong> <span style=\"color: #000080;\">baseHeader<\/span> <strong>h2:<\/strong> <span style=\"color: #000080;\">classOop<\/span> <strong>h3:<\/strong> <span style=\"color: #000080;\">extendedSize<\/span> <strong>doFill:<\/strong> <span style=\"color: #000080;\">doFill<\/span> <strong>with:<\/strong> <span style=\"color: #000080;\">fillWord<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Allocate a new object of the given size and number of header words. (Note: byteSize already includes space for the base header word.) Initialize the header fields of the new object and fill the remainder of the object with the given value.<br \/>\nMay cause a GC&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">newObj<\/span> <span style=\"color: #404040;\">remappedClassOop<\/span> <span style=\"color: #404040;\">end<\/span> <span style=\"color: #404040;\">i<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n&lt;inline: <\/span><span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#i<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;usqInt&#8217;<\/span><\/span><span style=\"color: #000000;\">&gt;<br \/>\n&lt;var: <\/span><span style=\"color: #000080;\">#end<\/span><span style=\"color: #000000;\"> type: <\/span><span style=\"color: #800080;\"><span style=\"font-family: Accuny;\">&#8216;usqInt&#8217;<\/span><\/span><span style=\"color: #000000;\">&gt;<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;remap classOop in case GC happens during allocation&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">hdrSize<\/span> <span style=\"color: #000080;\">&gt;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pushRemappableOop:<\/span> <span style=\"color: #000080;\">classOop<\/span><span style=\"color: #000000;\">].<br \/>\n<\/span><span style=\"color: #404040;\">newObj<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">allocateChunk:<\/span> <span style=\"color: #000080;\">byteSize<\/span> <span style=\"color: #000080;\">+<\/span><span style=\"color: #000000;\"> (<\/span><span style=\"color: #000080;\">hdrSize<\/span> <span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">*<\/span> <span style=\"color: #404040;\"><strong>BytesPerWord<\/strong><\/span><span style=\"color: #000000;\">).<br \/>\n<\/span><span style=\"color: #000080;\">hdrSize<\/span> <span style=\"color: #000080;\">&gt;<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #404040;\">remappedClassOop<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">popRemappableOop<\/span><span style=\"color: #000000;\">].<br \/>\n&#8230; etc &#8230;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\">Because allocateChunk might cause the GC to run the classOop might move and hence the &#8220;solution&#8221; (read &#8220;slow inconvenient hack&#8221;) is to provide a stack to hold intermediate results (<\/span><span style=\"color: #000080;\">pushRemappableOop:\/popRemappableOop<\/span><span style=\"color: #000000;\">) whose contents the GC updates when it runs. So where is the latent bug in the standard perform primitive?<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"><em>Interpreter methods for control primitives<\/em><\/span><br \/>\n<strong>primitivePerform<\/strong><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #808080;\">|<\/span> <span style=\"color: #404040;\">performSelector<\/span> <span style=\"color: #404040;\">newReceiver<\/span> <span style=\"color: #404040;\">selectorIndex<\/span> <span style=\"color: #404040;\">lookupClass<\/span> <span style=\"color: #404040;\">performMethod<\/span> <span style=\"color: #808080;\">|<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #404040;\">performSelector<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> messageSelector.<br \/>\n<\/span><span style=\"color: #404040;\">performMethod<\/span> <strong>:=<\/strong><span style=\"color: #000000;\"> newMethod.<br \/>\nmessageSelector <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackValue:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">newReceiver<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackValue:<\/span><span style=\"color: #000000;\"> argumentCount.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;NOTE: the following lookup may fail and be converted to #doesNotUnderstand:, so we must adjust argumentCount and slide args now, so that would work.&#8221;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Slide arguments down over selector&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nargumentCount <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">selectorIndex<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">stackPointerIndex<\/span> <span style=\"color: #000080;\">&#8211;<\/span><span style=\"color: #000000;\"> argumentCount.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">transfer:<\/span><span style=\"color: #000000;\"> argumentCount<br \/>\n<\/span><span style=\"color: #000080;\">fromIndex:<\/span> <span style=\"color: #404040;\">selectorIndex<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext<br \/>\n<\/span><span style=\"color: #000080;\">toIndex:<\/span> <span style=\"color: #404040;\">selectorIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">pop:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #404040;\">lookupClass<\/span> <strong>:=<\/strong> <span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchClassOf:<\/span> <span style=\"color: #404040;\">newReceiver<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">findNewMethodInClass:<\/span> <span style=\"color: #404040;\">lookupClass<\/span><span style=\"color: #000000;\">.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/span><span style=\"color: #008080;\">&#8220;Only test CompiledMethods for argument count &#8211; other objects will have to take their chances&#8221;<\/span><span style=\"color: #000000;\"><br \/>\n(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">isCompiledMethod:<\/span><span style=\"color: #000000;\"> newMethod)<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">success:<\/span> <span style=\"color: #008000;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">argumentCountOf:<\/span><span style=\"color: #000000;\"> newMethod<\/span><span style=\"color: #008000;\">)<\/span> <span style=\"color: #000080;\">=<\/span><span style=\"color: #000000;\"> argumentCount].<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #000000;\"> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0successFlag<br \/>\n<\/span><span style=\"color: #000080;\">ifTrue:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">executeNewMethodFromCache<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #008080;\">&#8220;Recursive xeq affects successFlag&#8221;<\/span><span style=\"color: #000000;\"><br \/>\nsuccessFlag <\/span><strong>:=<\/strong> <span style=\"color: #800000;\">true<\/span><span style=\"color: #000000;\">]<br \/>\n<\/span><span style=\"color: #000080;\">ifFalse:<\/span><span style=\"color: #000000;\"> [<\/span><span style=\"color: #008080;\">&#8220;Slide the args back up (sigh) and re-insert the selector. &#8220;<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">to:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">do:<\/span> <span style=\"color: #008000;\">[<\/span><span style=\"color: #000000;\">:<\/span><span style=\"color: #000080;\">i<\/span> <span style=\"color: #808080;\">|<\/span> <span style=\"color: #800000;\">self<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">storePointer:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">selectorIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext<br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span> <span style=\"color: #800080;\">(<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">fetchPointer:<\/span><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">&#8211;<\/span> <span style=\"color: #000080;\">i<\/span> <span style=\"color: #000080;\">+<\/span> <span style=\"color: #404040;\">selectorIndex<\/span> <span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext<\/span><span style=\"color: #800080;\">)<\/span><span style=\"color: #008000;\">]<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">unPop:<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\n<\/span><span style=\"color: #800000;\">self<\/span> <span style=\"color: #000080;\">storePointer:<\/span> <span style=\"color: #404040;\">selectorIndex<\/span><span style=\"color: #000000;\"><br \/>\n<\/span><span style=\"color: #000080;\">ofObject:<\/span><span style=\"color: #000000;\"> activeContext<br \/>\n<\/span><span style=\"color: #000080;\">withValue:<\/span><span style=\"color: #000000;\"> messageSelector.<br \/>\nargumentCount <\/span><strong>:=<\/strong><span style=\"color: #000000;\"> argumentCount <\/span><span style=\"color: #000080;\">+<\/span> <span style=\"color: #800000;\">1<\/span><span style=\"color: #000000;\">.<br \/>\nnewMethod <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">performMethod<\/span><span style=\"color: #000000;\">.<br \/>\nmessageSelector <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">performSelector<\/span><span style=\"color: #000000;\">]<\/span><\/p>\n<p>Well if the perform is not understood there will be an allocation of a Message within <span style=\"color: #000080;\">findNewMethodInClass:<\/span>, which may cause a GC, and if the new method doesn&#8217;t have the right number of arguments the statements<br \/>\n<span style=\"color: #000000;\"><br \/>\nnewMethod <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">performMethod<\/span><span style=\"color: #000000;\">.<br \/>\nmessageSelector <\/span><strong>:=<\/strong> <span style=\"color: #404040;\">performSelector<\/span><\/p>\n<p>may assign invalid pointers to newMethod and messageSelector. It might bite only once in a blue moon but those are the worst kind.<\/p>\n<p>Things are far worse in the StackInterpreter since any send, or assignment to a context instance variable, may cause an entire stack pages worth of contexts to be allocated as a stack page&#8217;s frames are divorced so that the page can be reused. It is simply intolerable to live with <span style=\"color: #000080;\">pushRemappableOop:\/popRemappableOop<\/span> scheme. It has to go, or at least only rear its ugly head occasionally.<\/p>\n<p>The change is to maintain sufficient free space such that we can at least allocate a page worth of contexts, scheduling a GC as soon as we&#8217;ve started eating into this reserve, but deferring the garbage collection until a safe point. I won&#8217;t bore you wth the details, but there&#8217;s a subclass of ObjectMemory called NewObjectMemory that coordinates this providing a set of <span style=\"color: #0e0e8e;\">eeInstantiate<\/span>* methods (for execution engine) that the VM uses for objects allocated in the course of execution (contexts, closures and messages for <span style=\"color: #1a1a92;\">doesNotUnderstand:<\/span>). It then only runs the garbage collector in <span style=\"color: #000080;\">checkForEventsMayContextSwitch:<\/span>. The standard allocation primitives <span style=\"color: #000080;\">primitiveNew<\/span> and <span style=\"color: #000080;\">primitiveNewWithArg<\/span> still use the old scheme which is also provided for plugins so that they don&#8217;t have to be rewritten, but inside the interpreter the remapBuffer is shunned entirely.<\/p>\n<h2>Proportions, Profiles and Prospects<\/h2>\n<p><span style=\"color: #000000;\">This stack organization does make a difference all by itself. The StackInterpreter is substantially faster for activation\/return benchmarks and insubstantially slower for process switch benchmarks. Here are the results of four benchmarks comparing the StackInterpreter against the standard context Interpreter. Both are compiled using the Intel C compiler and run on my 2.16GHz Intel Core Duo MacBook Pro.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><code>{[self nbody: 200000 to: t1]}<br \/>\ntook 5.289 seconds<br \/>\nratio: 0.69 % change: -30.95%<\/code><\/p>\n<p><code>{[self binarytrees: 15 to: t1]}<br \/>\ntook 7.583 seconds<br \/>\nratio: 0.526 % change: -47.4%<\/code><\/p>\n<p>{[self chameneosredux: 260000 to: t1]}<br \/>\ntook 7.095 seconds<br \/>\nratio: 0.837 % change: -16.31%<\/p>\n<p>&nbsp;<\/p>\n<p><code>{[self threadring: 10000000]}<br \/>\ntook 8.263 seconds<br \/>\nratio: 0.948 % change: -5.22%<br \/>\ngeometric mean 0.733 average speedup -26.74%<\/code><\/p>\n<p>These benchmarks are taken directly from the Squeak versions on the <a href=\"http:\/\/shootout.alioth.debian.org\">computer language shootout<\/a> site (thanks Isaac!!).<\/p>\n<p>nbody is a floating-point intensive N-body simulation of the Sun, Jupiter, Saturn, Uranus and Neptune. Some of the speedup (about a third) is due to improvements in the primitive floating point code (the use of compact class indices if you must know).<\/p>\n<p>binarytrees is an allocation heavy binary tree creation and traversal benchmark. It benefits both from the stack organization and the GC changes.<\/p>\n<p>Chameneos is a symbolic computation that compares many pairs of objects in one of three states, the colours red, blue and yellow.<\/p>\n<p>threadring is a thread benchmark that passes a token between 503 Smalltalk processes.<\/p>\n<p>As you can see we get worth-while speedups for everything except threadring, and that threading is not any slower.<\/p>\n<p>Running <a href=\"http:\/\/www.qwaq.com\/\">Qwaq Forums<\/a>, Qwaq&#8217;s business communications solution written in Croquet, we see about a 15% improvement both in loading times and in frame rate. And we&#8217;re getting ready to release this VM to the public as I write. I&#8217;ll be putting a version for general consumption in a Monticello repository near you real soon now\u00e2\u201e\u00a2.<\/p>\n<p>If we compare the profiles of benchFib for the context Interpreter<br \/>\n<span style=\"color: #000000;\"><br \/>\n<\/span><code> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\/Users\/eliot\/Qwaq\/QFCI1.2.28.app\/Contents\/MacOS\/Qwaq VM eem 12\/30\/2008 18:31<\/code><\/p>\n<p><code>\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a039 benchFib<\/code><\/p>\n<p>gc prior. clear prior.<br \/>\n25.496 seconds; sampling frequency 1465 hz<br \/>\n37317 samples in the Interpreter \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(37347 samples in the entire program) 99.92% of total<\/p>\n<p>&nbsp;<\/p>\n<p><code> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0% of interpret (% of total) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(samples) (cumulative)<br \/>\n13.46% (13.45%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalActivateNewMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(5023) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(13.46%)<br \/>\n12.90% (12.89%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodeDispatch \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(4815) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(26.36%)<br \/>\n6.40% ( 6.39%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalStoreContextRegisters \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2387) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(32.76%)<br \/>\n5.99% ( 5.99%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0commonReturn \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2237) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(38.75%)<br \/>\n5.54% ( 5.53%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0lookupInMethodCacheSelclass \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2067) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(44.29%)<br \/>\n5.53% ( 5.53%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimAdd \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2065) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(49.83%)<br \/>\n5.38% ( 5.37%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0normalSend \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2007) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(55.21%)<br \/>\n4.95% ( 4.95%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimSubtract \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1847) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(60.15%)<br \/>\n4.62% ( 4.61%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushReceiverBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1723) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(64.77%)<br \/>\n4.21% ( 4.20%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalFetchContextRegisters \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1570) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(68.98%)<br \/>\n3.94% ( 3.94%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushConstantOneBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1471) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(72.92%)<br \/>\n3.93% ( 3.92%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0recycleContextIfPossible \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1465) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(76.85%)<br \/>\n3.08% ( 3.08%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L1internalFetchContextRegisters \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1151) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(79.93%)<br \/>\n2.86% ( 2.86%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalQuickCheckForInterrupts \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1068) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(82.79%)<br \/>\n2.81% ( 2.81%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushConstantTwoBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1049) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(85.60%)<br \/>\n2.63% ( 2.63%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0sendLiteralSelectorBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(981) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(88.23%)<br \/>\n2.33% ( 2.33%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0returnTopFromMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(869) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(90.56%)<br \/>\n2.22% ( 2.21%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalExecuteNewMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(827) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(92.78%)<br \/>\n2.07% ( 2.07%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0booleanCheat \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(774) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(94.85%)<br \/>\n1.68% ( 1.68%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushReceiverVariableBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(626) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(96.53%)<br \/>\n1.46% ( 1.46%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0longUnconditionalJump \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(546) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(97.99%)<br \/>\n1.17% ( 1.17%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimLessThan \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(436) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(99.16%)<br \/>\n0.84% ( 0.84%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0storePointerofObjectwithValue \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(312) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(100.0%)<br \/>\n0.00% ( 0.00%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0...others... \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(100.0%)<\/code><\/p>\n<p>to that of the StackInterpreter<\/p>\n<p><code>\/Users\/eliot\/Qwaq\/QFSI1.2.28.app\/Contents\/MacOS\/Qwaq VM eem 1\/14\/2009 12:23<br \/>\neden size: 262,144 stack pages: 8<\/code><\/p>\n<p><code>\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a039 benchFib<\/code><\/p>\n<p>gc prior. clear prior.<br \/>\n18.282 seconds; sampling frequency 1467 hz<br \/>\n26575 samples in the Interpreter \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(26824 samples in the entire program) 99.07% of total<\/p>\n<p>&nbsp;<\/p>\n<p><code> \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0% of interpret (% of total) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(samples) (cumulative)<br \/>\n20.17% (19.99%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodeDispatch \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(5361) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(20.17%)<br \/>\n9.13% ( 9.05%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalActivateNewMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2427) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(29.31%)<br \/>\n8.87% ( 8.79%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalFindNewMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2357) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(38.17%)<br \/>\n8.58% ( 8.50%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimAdd \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(2279) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(46.75%)<br \/>\n7.41% ( 7.34%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0commonCallerReturn \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1968) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(54.16%)<br \/>\n7.35% ( 7.28%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimSubtract \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1952) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(61.50%)<br \/>\n6.20% ( 6.14%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0sendLiteralSelector0ArgsBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1647) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(67.70%)<br \/>\n5.98% ( 5.92%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushReceiverBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1588) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(73.67%)<br \/>\n4.77% ( 4.72%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushConstantOneBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1267) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(78.44%)<br \/>\n4.24% ( 4.20%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushConstantTwoBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1126) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(82.68%)<br \/>\n4.04% ( 4.00%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0booleanCheat \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1074) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(86.72%)<br \/>\n3.71% ( 3.68%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0bytecodePrimLessThan \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(987) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(90.43%)<br \/>\n2.40% ( 2.38%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0pushReceiverVariableBytecode \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(638) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(92.84%)<br \/>\n2.29% ( 2.27%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0internalExecuteNewMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(608) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(95.12%)<br \/>\n1.86% ( 1.84%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0longUnconditionalJump \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(493) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(96.98%)<br \/>\n1.77% ( 1.76%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0commonReturn \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(471) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(98.75%)<br \/>\n0.66% ( 0.66%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0slowPrimitiveResponse \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(176) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(99.41%)<br \/>\n0.56% ( 0.56%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0returnTopFromMethod \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(149) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(99.97%)<br \/>\n0.02% ( 0.02%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0L0baseReturn \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(6) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(100.0%)<br \/>\n0.00% ( 0.00%) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0...others... \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0 \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(1) \u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0(100.0%)<\/code><\/p>\n<p>we can see where this speedup comes. All of the context management on send and return is substantially cheaper and we see a noticeable increase in the cost of bytecode dispatch, showing that the VM has more time to do real work.<\/p>\n<p>But 15% improvement is nothing for a system that, at least for activation\/return benchmarks like benchFib, is some 20 times slower than VisualWorks. The overhead of bytyecode dispatch shows where we have to go next. We need to execute machine code rather than interpret bytecode. We need a JIT.<\/p>\n<p>The StackInterpreter is an intermediate step after closures and before the JIT to ensure steady progress and on-time delivery of a substantially faster VM. The essential point, of course, is that a stack organization suits the use of native call and return instructions whose use, along with in-line cacheing techniques, substantially improve send and return performance. As you can see in my <a href=\"http:\/\/www.mirandabanda.org\/cogblog\/2008\/12\/12\/simulate-out-of-the-bochs\/\">Simulate Out Of The Bochs<\/a> post I&#8217;ve already started work on the JIT and I hope to be far more current in my blog posts about it than I&#8217;ve been on the StackInterpreter. Apologies.<\/p>\n<p>I&#8217;m already enjoying this year immensely. The JIT, the first I&#8217;ve ever written in Smalltalk, is a delight. I hope to blog about it soon.<\/p>\n<p>Thanks for reading.<\/p>\n<div class=\"pdf24Plugin-cp\"> \t<form name=\"pdf24Form0\" method=\"post\" action=\"https:\/\/doc2pdf.pdf24.org\/wordpress.php\" target=\"pdf24PopWin\" onsubmit=\"var pdf24Win = window.open('about:blank', 'pdf24PopWin', 'resizable=yes,scrollbars=yes,width=600,height=250,left='+(screen.width\/2-300)+',top='+(screen.height\/3-125)+''); pdf24Win.focus(); if(typeof pdf24OnCreatePDF === 'function'){void(pdf24OnCreatePDF(this,pdf24Win));}\"> \t\t<input type=\"hidden\" name=\"blogCharset\" value=\"Cw1x07UAAA==\" \/><input type=\"hidden\" name=\"blogPosts\" value=\"MwQA\" \/><input type=\"hidden\" name=\"blogUrl\" value=\"yygpKbDS1y8vL9fLzSxKzEtJTAIRevlF6frJ+elJOfnpAA==\" \/><input type=\"hidden\" name=\"blogName\" value=\"c85PV3DKyU8HAA==\" \/><input type=\"hidden\" name=\"blogValueEncoding\" value=\"gzdeflate base64\" \/><input type=\"hidden\" name=\"postId_0\" value=\"M7QAAA==\" \/><input type=\"hidden\" name=\"postTitle_0\" value=\"C81LSS1ScM4vA5N5JakVJcUKiXkpCiUZqQpOmekKbkWJuam6oQUA\" \/><input type=\"hidden\" name=\"postLink_0\" value=\"HctJDoAgDADAF5WC8aK\/YamVRJZgEZ\/vcpnb7CJ1RRxjqBSbzcG6D1Uaoy\/sjsI4ab2gNmhm7DlQA1+u3yx0ywlvANkJXGTYmk0EveID\" \/><input type=\"hidden\" name=\"postAuthor_0\" value=\"S0zJzcwDAA==\" \/><input type=\"hidden\" name=\"postDateTime_0\" value=\"MzIwsNQ1MNQ1NFEwNLIyMLQyNgcA\" \/><input type=\"hidden\" name=\"postContent_0\" value=\"7b3rcttIti74f54id3X0DqmLom6WLMvl6pBVrW51lC3tkqscMRXuHSCQJFECkSxcRLOnZ8fEeYv5M3NiHuWcN5knmEeYdcnEhaTEBAiIlK3du2xLBBOZK1euXNdvfTf+\/r3qKW8q5OexdJNYJEMpbkZOECROcCsCJxykzkCKeBonctQVV2kk3KEv+2IinbEKhR+LsQqmIxWNh348+vc\/nBwc7r0u\/U44oSdU7zccX3+uf6JPio\/yC5KJ0sPDE5EU9z1tXoa\/98OhjPzECV1pfk1DDSMpFw3WmRvtvmHw104onGCk4kT0ndBJfNcJhCfvVOIDCRIlXBUm8nO2vO96kdj9\/n\/BCfRVGunfhqr88dlIhQMYEp4wMzTvnP8ommbzgUXEqTsUMpAjGSJd4nxV45mXfOcIIEH\/zTfDJBmf7u5OJpPuVKVJ2pNdV412J07iDv989yYdR7+N1M27v++ob76\/xDH2X74OAljZSAJVhDNw\/PC7Xef77ne7Yxh2\/P25XjNNKGMZ\/c1Y9P0oTnbcwInhCTfx7xwiViRdFXlxF3bGj\/UQyETId\/jdg73XkYxldCc9MYEn6Xf7r8VWIt1hiIQPprDKWKae2rlzIt\/pBXIbyBzREG4aRUCT+Td2xYdoat5QencYI+eb9+Bux8gyQycRQCgxkAl8dyhhnx8coAtfC\/pi6AQPj7WQfH2nlwYqjQ0fdIS8gzf2ZJLISIwjNYic0cgPB6KX+oFH\/wiUe6vZ+Ds5+n6oosjvBdPvduEHOs5h7N\/JrvibmghPiUsRqDuZceqfxY8yESP8RQr0QtpNnGnGwLOTHEk4ArlcGALLDR1PSM9PdmAGOzisH6YSTkUvHQxwgrEPh4gG3n\/1cs\/wRVfzZb78IIAJ4mP+aMwcjbum+njo5GdXjulnFkBi4idDESrhePBm+D2cwzgdj1UEJzNSIxrnzo+SFD4YOSCpQlnhjd40dEa+K3p+iDTuAHF2IjgsMApQOnH8YAe4KY1ieH5HBj7sCPMYbcLMScNJOUHXcUddFQ12XZAq+GzX7Y\/+7Htvjg\/2Xr345vue494mEfwB78Pj1cgKZYinAvnGlXD8xhJmDOTD\/cCZjnxgJ5rLYtJkZHEMYfT20s+x2OqnQdARi0SLG3ejNBnAC7vSS3f\/y3XjoRPu\/tMfwyR2NfMd7O297I69\/jffe0TERHq49N2xEyU+LAvOsoJlRhM\/hqONBIE9KBLkl3cZTbZwQUNpWG3RnGLpxL4nu3Gy+833N\/wDk1r2gKbOSIKgud2eJ0Y0M178gPz8++ju7KX6+Nfei71vvod1MsETes+iSQXTyHfjfiSdWxrndhc54Fs38kexCneRAWPXHwewvf+J9Do5OjnsDpNR8M33W\/nw2znL4OpBcia4XQVhmt2dIMv1IQdpMAmNjOJz1UFeufNJsOSik26WohzXgxlKvZWuk8ZE+Kk+3xH9FMlMzH1E2ecpCWMZ2QOCSIFq4d\/KP5tLyh+BvIjcEoVGfgR76\/TwDzpB\/gg0kXi3F6SyByPs9v1BGsmDl\/951B34\/W9gicmbb76B8fSoILRBbgHzeOaCcZUn8bqWn+EUJ5LkuogTOH34BBCu74fAjSC6\/ik7AjQfmEEi4SbqTen7vSncQjgG7NjYD2SkR5ChB2LavARIDT\/pxZYoCwPj0aJD2A\/kZx9P6Sx3yLA78W\/9MchWXjf+tHszdgZDuA78\/6T5fvO93t\/Y\/J7XobeV2CJ2h3CKs514i2dIhA5cCrMnHMU5kAVPv+vA+vOtgg8lCBlaYkeM8AZhRnMljBOxchQNUlZEMgHFNNWcWCYIvihBpih+KvkeAx7zB2Hh15k2oUmccTqP2RUXICtAxKEIR80Ar024pSOZpBGPM3CiHiqwroIvuAk+DjcrSk94Wq8bVhM4\/ojnUBpBPxD6fHj0LFhRjJModYl8Y+WHeE\/3fRl4yEcdzW284J7EzecRgZeQSHArwyHJVnef5Jo7Ahnvm3\/8pzt0xvDugxMSDn+4gRm+1VwaH5zA\/QIPCnySWIKYF3UlfS7ys35q2OQ7WBcon9\/rj+R7OXlHD3+3qz\/5DngOLuRkGsg33wBdVXQq\/rBH\/\/f6G3P44Gl4avGzJ3v4P3j2X\/opsfCxF3v4v9ckTpGQN3Aq7b4QyomW4tbP\/6Q5+sEvzE3cihRbD9NCP4za44Mv35N78kTCkwEcOKnXdxE4g6v+qdV0RGi2clss+wKt8s0SYuhx96sQw+rFfv9DlErLVf360GMP8xDz8+mbjLWXrPTw4OEdMvP\/1o7tzAQ+yNH4AvWQmwQ0oPyc2Sz\/UzW6XjhBvIGE3d9AwnYtKPugxJkjwhJ6j+RIRVOb\/TSSAC8hB6++RJ6jgnY6+\/LFkz7A\/8HX6TssEfTkr\/kmMy9vTOLvHewdnOAr8QLXLynOthqDPTwds29MTjtJF4NiIPW8Tqvx2A3pBJfwx+dqDFbl4Kr+FanepzXvv+Zmghv4ixNYS2dSI8xt1bVSDqwvxNLuXeYKmd7IKtNs+o5GOwI00vlJXfX5wFW+sivJ+VATvB1+aXMbb9By2IANBKN4rCInmp6jf0z1v4T9eiSJyAR4lojLWKSlY5SAzRj3811bJqC19U58bscb367LLkDTmfjKcm1xQZjYLY1McvSfVCbdKsxb5Q6t8p5ElahleX6NKfykT3BLh2usxk\/kXLVEANiGsyI71t497W667FNkbOKE5BmEEzs1Xj4\/1i5M0UsTMXJupfAxABvjaU4wIoffdFUaeBjgmqiIfNFOWIoE3vyeSud2xuO5yd6uqs4rduX9TTreEu9V9g2jnF7bPY6qEIs4u\/n7wZUa2z07wVhBRZeb3rl\/D3vx+HW+jw8exv\/53\/7Hf3\/oPysbfzGhq7o67I\/akN5U3bvXvOOisSWZCMNVBJfM1A1mpcgqSn71A5FNq+cnZ6FX8Zr8seCGfetX9C5td9fOzgukQFWP1dbDaz3hx+x2LSOrD+LdCRZ67MSq9+fJ0vnUYOqAZ0wi8qrPfHdaW3Y\/PPdtK4pv2038T9UYHuNK8bWMPqrIq8jtG6r\/PHTFtScEy64F4xBqhW8K1FiTuNkz97eOV5\/FMajFpyK\/d0DdCwLRkzpRS2IYWDgiUioRfh8exBwWoJYOwuttdSmhQYk5fRRGCtSkI2LMIRQuzAhTFNIQNEn3FgYnx0bczQLla5bCMxqQJddVVRbrBlDeOrFkLtPu9wqHviUDJIAJnNmaHcv1yznKNKKCWAQHlkzn34PkNf5XMRgx9PvJhWpPRI\/TZIMc\/0+KF+ZjAV8lXzStfSElB2AmkS8pN5YqmsBLtfVn\/i1GZp45d22cO6uqPnPuKgGpL51n2w42PSk+OA9UnGKmwNfICH4AgmZjzMBzNZ6aTGJfzmUS6zKUGSNtdU+8fnbP0lBX7cV6PMux9bJ+PbVLJKjmSxdPRQyIFTyMdn6\/hqKgPGu\/ki9vU0RPNedhQfSsujuV84RAEa2Ug1aK09vs4I5fiVRLM0k3ROq6gXQiELkjB+yfcCBQl8wKHPxQuE5MMVYse+hJSbWTGKXxGhbE98YKqwYgzK3Gr6y+z99aseb+6mNVEy\/W91JTtsIjL+D58nusy8+SOE\/+slksUTZVLn8ViUe6qg4rkbUXeGZGVYX90gGfc6vK\/Iy1qQYiQTy8ontoayZAIAGxGKqJGDnhNEMRAE3hTrKqYFI7PK7uxOLpUCWwaX0QeKHLRbRU1l3C84gVjDgV0hnIKJjqMCBOBb5A4A1YNdkVH4cyJDNxBjaiMLwCG5JREYQbSZrJSmseyATrTikt7Z8yUl1xZeaDccmVxoaZhyrcwWG1FYzDokrmFtdmCEHwAnXeh8N4EsiBAkF6qwi8MwQAISSQxTXERuam8ZBqnUO9zbiLeUmwH96p4I6qwSkQKygs2xU\/OHe+J34OB06UVcW+ldGtDOS0gDsB0j3ArU6TwphxAHw2wXxAEJJjfLnqM3pEiJAdsa43dsQY5iYmlC+oQir\/vaNycD9EholNabPmKI2MocuU9WJwCMnVv9LxCKUigBdkNCaterj4uwr4dxL5SSJDrhvXqYm\/vMMQNZJkAEzOyAxOUKhYphXApJhtZmfIqCAJ6u1UZx9iwXqiOGGyWIecx9R9YgwFdNiCDa0nlLapYvxO+Z7eCtjNHdpNKhqnKmqkVldcJkwkF2QCIkdMsSQ+YQmATBUjXAsBVfTkVIVeYWtNZXUyjFQ6GDK3xMiF+IyTnLLbKDlFBQGGRTAJH9nLbHqr6WhMbpUUGImiSv4\/ZWENDOjhB\/Eqp+8tczzwKApWzH3wZDxGZkEyoJ6P1EwErn\/gFNiQASHwtGHsMY0QjcZ3hxlgDoEaIfAGcgSwIfK2CJw42fHDjgZ\/wOO29ePlxdW2wAQN9tXRCVIumIzErvADfRuo4Cn9bhXAa9M+YkUx+Aym76qoK26UGBbr30dYuK+C1MCNGEJVQ1TBG3f\/ZRf+Onpx8M331xI55weZJrE7zF6FUz8LAkSzcUFr7cN1ln2mIn\/gE+AKpR1jxfwSDkAqwuaTzAnz9bh49AhMgLfCx0tEdejxHA6CEGiCII31qvHM7IwR\/QhER3bDwnbB7U3UpmtNf3PEEi\/LjkGJAjuoMSgQdQq4ji5\/GMzgORH+z0iKdExc2QG+GE57kU+CDDfBiQIfiMbrZ2IxGTOymTUyWAKCeAhUCPQwLFju\/AG8H+GMGJzFCZLhVPx\/\/\/f\/+d\/M\/YeoIBm1YFXIPh7shmTwph5yHMyH59ERaUgvuncqtGqnQDRPmU8TvMdh7DsVoZIwMWnjCOXAdHTECEk4QAwKIPF0nPgukgnFuSggYcnP4wCvQL1DwVQjawwPODQqrqKBE\/r\/JJ78bhd+vfxY4y3QgxPkCt+TDq1DARvSOHIepAFPqAYSoTfmGDFEFQ3hMdGSAn4EdYpFK6llWoZqIhXRTwoD8R2Tb4aB60D3kAoRO4NupwwZrqwGxIjglgwUzTLDBcEt0DdnSRtgOVIE63IYkAdngUhX8FrYBw8LnIFD+gpXZ45OPjxLNL+gbCIPOkUkkkiPqy+Uoi5H58W8FDUInGW\/PzPN+TuJQFyKg8KAcIITRhThiWRymCFQ6PHXc\/TlcUESAT2J64DWsjvoimsndhkP6Zx3C9SH8Dagmfqsck+KSqNRrHnnjRZMkE\/AUeM04J9j1AEQtAcEcyTNthqtw2BIIQAZIi8Nhvws4c4lCPYFVzaJshSTm4IpgX3REmh9K91zP8pcLhBMEHBejCIr55FdvW+xBPWJ9hqWS1Oh2SEfgIwd48xmYFbMsWF+QScnD53j15ANQaIhZ1cYrzfVTwZAUm+qc5v0+exoqcdSC7cTv\/8tbtAPQO+z0PsASrywLNjynGmzEdIfUtYo7SYwkfJ2SWF+RVt5WaZ7Fegn2r6RQ0r+boG413CJ7vT9wX73t\/GgCARl412cQ+IpDPzvg+Q1\/vet3uvTFVgbQfoKQxNOn50XFAH9+P2aRcPYJx1awbMVxplxWrDT5dslqaZ5vR6qm6HXXB1gOTahh0cBBGsc0ak2axSGidectVu1lAs0idu4BUQhu5z28stbzGdfuspG0zruYchlpl5seKj6opalaqzfj\/yPpmMahPdnWTyF+ut7OWm8QJi24LT6SWuyRLkfy+S0aeLysFazfV1lumDXRIVZ2DHgR4K2JahEsoJQlSELlMxTUAYTMHhQu0V1LEbT8Q+k23gF3YZUYT\/0Yj0QJZyJD4rRagsaduZ1YMvGvCLSryClC7RTUMVM+e4inL05zbsjYjbCyaAzLzFAf1rR73DNsH5HPgs0+\/qBMyC4YfYnsUsRLqChKk4\/t++Nk5ZcaeSXRq9bjE6Arrjw2R\/iJ8WXZZCJW+T02tYogsZhFAtTFuTDv7fIw+XHHJH\/LY2TDHkYGV1fg9s6dP+IGtbBrIalX4IeKdU3lhgZ4NKgZuZm20iXVuuJgeJClvNlgQWKeo7hSFSoCR4XNR19HvQlRtsP5D7bnPrt6vXYYTpCpLLY7unIvbMcV0aRis6VJ1tQQTBI7IfoMTgVVlcUnGI7\/C7Ut59rvVup9Z7js3aLHL+G+sZ7jmV7hDUS72alLLiuqJQ3RjEzYDqBq0TfEsZFnYTvXxT8KKL\/vHbrrDYxr+GetiQjRoyCy+uWUgDqTugim5D+sX6aBQ1ws0ELnBN2WnusvcK2iyJqrLFyjmxzRo4MERWaYFIvEMD6b05slX+SzaqPmLLNYwDHbzGXY61zgAvzLBrEa8pzLgnslq\/RSgnN2xskGzgBuNJtdvH5QyGJiEDb2yo0WW3t9obAEwF\/uCzkR6AiWr\/Mp\/0kx6ZysK2Muy80M7r2gd6ckomdfQqru5zQxQkccocyxkyoti8Td\/geUaB044Ua\/Ky1ygd0GtFcJjFty4WKrqxzipsvfSZBcH0Os1j1RlvyqlE9uOU6cKFt4KHmrWwyH2UHhGcQxHPeU+51l2D6ZdzJc3Xz8HbB8zp04JHJUFI+bjFJkK5DSuIBOU1JtZjghr7K4tNZvoRjBoQHOfc2D9RnnWf+gh1kOBcylqZLCn0Zs1kC7qvDCQ7F9VBSpM70iPXEEsq19D1MY8PcBfgZHc8wVIaqlKU884hZzx40WWlIdMru3mC+Iv95rcYfsi+bx2N97CktUSXDAhkpHaTgrOVGZ5QZm\/W4KeWnzH6BUvi83xxXoiGOqX3G3WuyVfJEotmh8Ks8fqLGJsGUt8OkqRRflYMhFcfR6akeknmEzc1mqFmabNZfSye6IQCnoUyycFxYSNaTp0DG+wlCKZL41DihXPV4LCUcWePqfehQzRyXZS5lTSma0CJ\/Mn3+Plf7rSLjQIKL67bi4jdwph8w0YyJUuPOadmFm78EDuSpnTz9gz0pRTIdS9thdeTGHTqR+JP+oepKKgViHx6Vcakx4GI3fxRKZ0vLbRdwY7NoYBfqM\/Mg3ERx49iM5Ttysd637HgbhbN0j9x\/2rM7w\/qol0K3Io9CbY6smKMPhfJNIlMecKSdvAw9H4jTuPlbLWJWFLpPL1T1LOesT8uyytMmQV8WM1V7ZtWs5lBRUi\/xuLXXPa3qXWRT7fw4d9E5JVXfOHfSIxy35q6jVoBFrKVcJeuyQlJRVeCR9uGBq8FotNjp7ukegkLfykp4VhasVWmHn8\/bl3feqsCB5Idz+UROHs5In\/Ua2ynmVPrSlmJ9yX6YOd2a5EYsBpGaUFftbg1Nup7smWnNtUxl0kH9lbMCmnOLPj68vAVi1UJmqmeKsisvcyey+VmjPgO9lZl78hft2rQ3N803DUzPJsU3HznoULL2qzxfpN3SZVbL2tleEud6gAdMtKlapiuaWfIzPOidO7GMq9p9Feyh2ahYY8gqs8KZPOeZm990E+BFSi+DAohknxzWOrPcTItd5NnXXMU9ddefEXDvwbc5OrOLtHMzWrTByT11x9FFo7ZrkZQfignzfmyqMRFGokNoBVQNjBW3Toxl0Vg93+\/7ri9Dd4rhhQ5WuU5kXr0dSymw\/DXqUIlmOkYwAQ5ZxV1xrVFLSon6Tj9ZGByjstsF4TcTPCmNgbAbtyGoBoIVRvgIpuEzXkQeu8kKGQhRA6eioy04Kp4kUVRnta8TGdUtQPywo\/O0HDpsOXxS40ajQYzd0p7j9Nnt91TCGxtoTTdgzVRVEM236VTl976ZUmXVj4TVs9rHiohVJ+P7SSeaaGVaY+5R7t1p5qK1t9vv58BnxfPLVzwXSZ0np3fWTyH8iDktkRMOJG\/hrJ8HNsx1sK+YRiL7++UHBknxZB9DrIhWgxvbFRik6GQVqIRAh9kvYzUulrZi5ag4v7w5R8gDVK5UFIutUGE6zFR8PjnevTw7PNjm4e+Z08SJPA3LZKZEvBVJnOgozXKw5txYOQ6X44IaLBFNKgNcvBSEvMfoJgaepycJ4KeHoF5OqFEdYWKXcMM5oQZE0eq242IRLiyDdGFgeVSLPS+CVXYIuC5QA9\/lJ3BAVNBpLTRXLIwr5Dc5Ewc0\/0iN6MMeVsdqUB38WZ\/LoUoSGZuTJCTjE80AEWKyFZKHoHm8YkYVPbBKAirm5vhhiiTSrYxRKkhX45uhzr4QYwQRabSlg6dVbO0fiL87YYp5aQd7e6+2NWEZhMYgzZTK5B+hBPjwnhJgtNn07GfmjadFjWbroDUzYlVZAQAKfruANn+gRWrEKgz4LawL1+BnGWggG1iZgC7DRxHtcA6zI5cxnQygWumXpsJ80Uy\/5Wd1tXm+7ntXtbAM3cfEDAZ7C1WeOYfHGzE0KTdzxirV536W9lFuaLXADC8eYIbi6lgUmYp8xLJTo3GaLIOl\/cPWwYujFycvXog9sbe9EeA744gKzVeF3TGAFQ0Vqc+qJtc8S6E98QgZRHI3pHtNt1hX6QIvApwF7tHpaRixnz+cG8G6MTgnS951Rmu0A7wCQlgqN795YeNjxiCaEDej6XFDuJXjSjggl0lsEPEyien58QhU0kAWhCB61mJ\/EBo5WpaMWuaWkPI6JVze5D5BGy52iOXweZmaom+Acf6dBbcBKl0jdTeHFsga0rjk8IvTIHnEG\/ToHqFphZ5xOpPDiEiVKuRcmJ9o\/9qTKj9pxEQmOiiPdz6ifOqLaJd3biumpqcawWMWwbKTYSEuqBiIt7sNmz+5pwvMz3joRNJDQIz3MFFvuVvwhC3lwqd9WOpO3xn5wfRUnLluGk5NvPP49fxWzPjirI6uH6KBbOmz3D84snb0VSqSZFHwQY0vQNmmStxHqO5\/xCoo4tVSBtkK5fYrB9YvrsXqLVpadKEhschqlJ7xDFyVsLEso51LQQq0JmBDueWVfEZM2FKBRrTlmouMYTLOzbliNQ94k6kY9h0CaVgWWwQr0t1E99xS6IdmBcS7KsWDmgdmBKSxyzKlKg8rGhNU24FlwNiCQQnqk26WQb3rC0pLrgHxEFnKQkcEkgOIqSnumpBaFiECMHpd2DNB30KUM3y0DUDIrvgRYXxHTgcN2Qx7uhW96nihXjU8+N7U+gOtGKr7HQ+SoXQXYYcdD0xr7hSaFbiN\/M\/ozp2gKhpSLDnDSaZ4LhtLJRBkcWZGIb8OtqP4PA58twhTTT0DEGs5xEcLSM4dg6QWkpGGPhLGQqex2C5DQvB7neKbgeCFxcg7OMpkrurrmjWVv\/n\/ph+hIkA3ORW\/nmL48F9CP\/FvfzYP+DC51JPxqcAHPgm\/\/15hTPXXf\/whDYHfhqC6uZ\/MC0pouufcwgKBWw0369fpQYrZVPnDJXtbhqC3R+QKWVTCo8ezDYo5pMrM1e+Y2dgNIj9jpSJMtDhY48r2X\/TWCZ4zH1iZl9Jmnp18s9nRGWPuQ9HmMcLzjJ0AZFVgY4fMM4p0ZobT7zJswwcggstAXPaxZY3UQ5kHzOfa3ZX\/uvD6jigTrLv+EIctzIKwBFjAbWkCY6FiU7dZbn7o2bsiVJiwXk4j7dvKFSlLlv5rA4i31VfyybZlXI1siTrixGY3ZzSNq3DGkb5U\/GZRD7bcSwEShnulvhsY51z9wuZX+32UIgvB2q1sSHQsW23V88l9PrnFk6sRep3Qjn1UClq60Rt1ey3ENeAwno7s+cXuIUvPnn7vjAb0sNmDrZImBqGZ3WWICqw7e0yk7qxFP5fwJxzuSXFfKyUZdif+rT\/G3ip0YvGn3etIfZ7+5xgbSkUh2I74o2UXpJwOWw5opwn3QzF6rh\/X7Ol0ePLy+Kh7eHJy+BJBUiOLpkzbpKvk9KJZxBwuDfrUJjBckDwJ+8scAg8OGN1yUbiyxBcE4cwY0MQX2jZLx04UqcmOaRaYiBEiOOsfs+h1Myyitf6WvNezQvs+\/OcqbsAPpm8c2BMKs3S5ZZ2DGQQ7idpB5zdnyaowHvpjZKcJtphky0roLhFkfr3W2CSJAcgpHUnWaWXIttyk2EZLUr5CFkKlxi\/afrrUYCwzDQ7RfnamppdghoAzgr32jR2WmW\/a6i\/YQmD9jlUwHTijKWcQS68r\/upzlx0a0kyG0VZ7stjcEh1E2nOABiO\/XX7GfxshYJrQ8ZYhX+ZDZg29HxQH1AIomubyYOJ7aoJxJw+nu\/zodczeUB8kX7snyDyFI8bZHnwKpLdD50BPEGOOc+naC7abzO9SQ68tbC6mmxQVeor1HZAqZcG0PT9SJHdw+6Y8M\/0+4hH6NadqICGxg2HwWlD\/9KDQ\/hThePpy5ODiMlR6\/jWYrENu+eQHAp+IqfFTjQ2QkdmCKLaQxsh13UqhPziQGa9TX1LyZBl55aoIhCBm3E8kCzLsKoYiUzMbQQiV+c2PDbQT3AahimD9mMkzzg8IoUrFsXJ9vskIAUhvVCc7VGiXMvN1OKsf3qI\/ozx+bt9IRyIeq9RkA63U55TlPuw0rDSXTVnqh5Hebu5Tyl\/fFReKe9TiV1PdUtQExDBPQ2eaFH7D\/RkLlHOCiTMFVcMnBjLpVVmPrwgx8sSWPwC6siIS9NNAtxOQdz7njPEBcHo4Bx1JhOt8ANQZyeg1tcCzzn+Ao2Kf7qDDw7Akyrnt8IVbbv3byeLETAe6W3NITla3Cp33YGnY2wIej7FZ4jarRegCi24zXskOJXbrSpg28wFqvsb9qMQveZoWtZrF1LgBOkrgPumBFMOyDX2vlLfyIj\/uetMweWfHCYAAnABafjkzFUXP+76LnRl7flL6PjcaXjHRpWIJR\/0kFj9+x8S\/ij7yMS0gB9v542Y6VzfmC\/pHhRz1WG94OYl7Y9PU53K4b4gpTb56lbJ8u8T1ertlV9rIyhmDERlueq4J2pCaoFbiyLb44nVgckTjADkGaLdpocOR5Jbo8GkDOpLZk4J0bZIAjROiRunpzBVXntz6Id7ekWECz6WhUXy02Ur9nzH9Ps4bRTtGzdHKkX5hjgKXad5x2kM1pwgomufbJahkb\/Ffpo0wKckEBarDPKb8yNS8mE682XjdNcPMwUTK91fjjZwwxn8DVLWcj2mRY\/e4jiZfRe\/9YBNQ8uxbLny99bIVmj3EsYzWpntuxr0Mlu4Tafa04e3BWuGPci5Uc7yxMVD\/dIGOhxEWldFVGmEZn\/FwESYDYqoXCuk4UooeoEJji4JvCO9WEzG+1AEZ7CyJnRJVdEv2uJf2KIm6J0PZ95OuuJbR0BnHGptCe4MZAVq7LsJ0xP0zqPsAN9ZESN46F2wrrHLJvXvOsojYUwLEbEDlyB6DnWJKtINsazXVxXN4okColfodLtaYWuysQdWPWYJ0dK7f32\/HuKlEiwXKpjUhqjKzbbp6S32zyJOGKHI\/ynCQDPNbs7qC3UgORS00PM07F5ind67GYOdRUvZCJ9\/6cFObPIZ2nb4ei+c3veHpp\/UrwfPWbtU93VpB2V4VUGLuxP3oRAPjIHjrJ61AUP7XGzuQi73m2yk2pgM9SDjND09JPGVRFAz91V9GNcm0wBXVnmiScG0QtgzG2mds\/Ee2JOMxSvHTqnehE8csVHOqNX84Y9j0y5BgaE9r+fuaRxh6hwFuY006ebIRhrhlQi5eSj7gqPSiAmoxDsC4LIa1jZsWDMYMNOIyr5++nqnk5lLtsdgqJ1PprBBBsW50\/+phJ92oC0ZsMQdLUu6UO5QuW7yEXuEn0+311wHE3P+LVvxzSFOUXnPR1+bEt12g9n750txM0KdRpe140xIE319k5w9OG\/02upvLb\/Nn9Zn3Npj32jJyF1Uir87\/G9EHuhGpTBXYz+fjkdu6FvKorP0us2b602U61lGf2e3LCEttLJtp32B7CX9VUybu54jGXK4VjKg17Yrx+z8f\/8c8\/kUc+TUKgH3L16vTJnODKtezm2xGu9pYv1Io9Kna7w+e2xXbmtkQ8kuTAo9sCFXt6uM3F7Srevr9cE2GWrvBoqfb7uFDXnRU8eAv7SVW9+jVRRD7elqEHzS0Q\/M9xzcz6fA5mfRxLLP1E+2qrwugrEhXV8JYRsPevGk+X2mj4aNbVpaKz15iuWvIpau6uISifI4fYopoL9U4Bg4V0buY\/oNlwUGG74c\/Z9B\/5RIPA1bCYBZUzI69R9R4OtOZDLspGFDkrnibJuUKesx15VxWjxJdQ4LG8JxpV7yTjnDTYOyssqNvZV8xKqEngzuZL8eTQIeAerrpKn+aK9WBD5XiSnCaHnx36COiIlKGql+cJPJHKvSx9BmTT\/1Ed4sgrz01sggK6HjYqwMbcug8VV0w3Mvg1mATmsJxaQjsAyO9iA99quu9ed0upizfyN9TrLjB0vxFyE\/wHQLh16uV+VpPV603Xvjmh1H86ldksa1bHe2vBTTsfh4nR+xnhE9YyDIw5dZA7xryPNQxvpdVOrXtnljaoMsau6stVK6WbF7HVqvyl7d\/q9cT3BqrjSiqHdbmOBDpfj1lCuK5ONx7\/Qkba4x87IwZ53hWurhBw7iQsOpkmS+Fjj++LpcwLX+wHEJ3WyL4Vg1DDyIz7yoaLsZz0i2apnzteoJmGT8WvtJcc50HmnjOaRVFlLACGtkiGCumPRAmjmFS3GXh109IlDq3EmkqeMHo\/j9FIMEOlr0g2ktpGlsZEK2+jLdxZrVu1st+BtMCspiBe5yFVAgNgC\/1acXEqWL8YaY\/lP6BU6lin8ZwZloYIWNqdBu6mFmNchB+KMK\/GGUDeZWgxxz91vmeK6bYB58w1yaigpgpvNagrQgXU25jVG4ClKPHLNr0oRrJ+ZYM3TbRRnB6kQoKh3vV69+oL+\/lRIuVPAJopRT0ChJpNvsyzMtWrMbSz7elYdwA0QKHdIzCsnm9DFkFJNZLId4JzafrrrUGwnDVgt3jRSlsbfTySisFGi+vN6Fyug6oiJXlupiMLZZ61cesMbVRhRk\/AoDNgrPfYI3VAqZvtCKi\/Vqo+oSy9CqtuRZq\/UUzC+TWRp7PB1KZmk0xWSCz1pICMrbvUO3PZeCuf05kKc3Mpvi7+g2K4kIm5SOss+K9v+m80rRAZyAAjrGhym8baFkI27IUGO9t0T0orLUaO635tNLTa40NVdhwXadaqdnaRTESzabcZrQBf3pYiKtk87R9c20O1Mm5CQeVnFzaFdcW6+01nCNnZ2O2mtHztebdLb+w6\/u+m0tNsxcjVbPDvl2XAdN8jmANk2+Dcs++uByQe6GTKuj\/X26GzLy2W4UsXwgK3TxumTQAZEXTNDYxDA6FgF66o6j\/wshhNDOCEOs+QlvfKou5p5s3Y6eZH7KmLfL3FBadqHJ3UKXG4lvsD\/6teOvEkpFDqE6fH9vZJ8f53k4PPvWw4WOkwzSqL+jSQBCA\/OGedB3MsPET7D2BdHUjapYAX377l4urn\/7C36IGjmkUwSc4QMN61EO+7PZcSL+nvnt7gavTNa\/1\/Lw32Hn0+nyTXbzzXp3KbWYrRieqqhN2QYy6SsrMUam2SZWU64PHaPl7v8dogYgbHnAYU1DGddYW9uEJ3iiK817qCPYdNg3pJ5hRkCXP6VhyLLj1vHBGMOE4ydPRslS0wB8Mk52JxL+wUwcGjmVcynVDuY0pggu+7Y9GaZglu\/FbFVjB\/UBNqKFR1mBEy7w8H46SIDBLMMAIrciS8MbJUHcmwfQ6d4gvRiF85\/gByV7q5zKSIxVN8aZheBDqgot5fVmnX357D9TdnR52As7fPNNfyQ8xHS+hsHUaxZRB5oR+X8YochOOoDOC5mQHNsall3gUme8WhgXi3fmevJ+kutMpTDLGKUx5cZRwaGbNdHfG2LCX+1BxJ8TzSP2eyoSSCHSSCnYfiik70hGxxBnxnmE3pmEawtWCH6E6J6mPELZCCbFfM2J2n+dA3djjV08SSHGngiwRhj83n3EHFZ5fsSlMMlFE6zTWwN\/EBIXMiJ6CHSU+pIZl\/b6kScH6TX+tjEY0+q2U4+ytPBHYEhe3fVb1uXZQWv4g0yR2hzlsuApS3llqqub5uC0iHZeyLOCDMZ65Dre2xX8DdcfEYbAhpjW1DAl0POvxEitOOsl6RsGqMMkknvj6IuYX0Ng6QZSJzn2agNh6yBjxXGmskaKG2ebhrB0UN8\/BiWU5qsT7ptWYikZF3uG5SbOUkDt5pXjqPCXjUE8YjpqDvTWVouZeCztgZW1p\/n75gTM9cQScRqS8FA5AjBkdrhoV+BSPKy4jSsMdWm+ksGFhvpJzk5eDCQTwu54TUDKKX2iBHVLL3iDAjMZsG5FwRtihkAHFwDRCFAhce6PKMg\/BaYHxaX4Klw9E4v0gudL3P2OPHMTMzbpIeYQ17+MapvQ+0O\/CBAVb4RHYKmpkvpOOu4UJac0LvshHYH\/v4AV1XS+ygjn9dDwjBcKSWr\/1UGgf7Jl0MvgwgqdNNlmeK5N9n6F8\/STBNlgkYKg\/u+IUWzg1PerCBCxFbbIO9l6c8FyYAASKdCmSNJRmf0EY8AJeoziN8aj8x8T5vcThemGvDopL6tbR2X9KQ7IBcFsLg\/HOxChLeWcyVsOMokjOMFun9FV935R+mSI2Ev8WCQSceTt7OBMFSvVQRl3xEdubh16Qj4VAV1TVWZBpP9I9pbDZtIymOkWwl\/rYkOlGEdelMH1OIxekyIVOcDaXP+NTn2zOpsJ9NWcNzAHqJlU8VMS5bCKgAM+ymYSMIspy8liuoBgw00XGKt\/EBeaJmGc4K07yN\/NMxdMZc0D\/tCzZSmfzUS5almhdp63TfTSzDBm2kE9UvRdDmI4+oIFr93Tk3lmOSzt+Dhv+9DKJnlHzH47cZclzFZN+Zvjsi8GYXX+2TPlYtkdYI\/FIvFbBtDAVVLQr1YK+DOyPaj+uErXEmNsOk5cLLwSU439es39uBWJe2weQqeHo5XVLfuu6E7rIJqR\/rJ9EQwPcbNAC54TdUjdLk9Lzcda4xtBjo2k6DaJAV8roaWcOltk\/bZVOFQV2y9foRoAp1pENX0oK06K12xsCTyT8d1noPYSKaP0sntLZsAuWfttoOk2V1J\/lxt0jZemI1ToFPd6B\/rQxLLuzzyVNLjEaui7GkdzJwqrkw8GQ43tsxTBNJN6lNfhZa5WVQ0d1EqI4Ynihois1Xhv6KgmC63OYxao32rKWrSXQTVvNsMEakacC3jPL+ddOHC92H8KBoHaqKMOF3zd1mrqGEyNgYssPPXRJSk8zeI86wZrcDwwj6OgbDdLTJ2e7K64jlVDUaICRLjAue7EKZKLrgOMsAk5Tu3D8AB1cJecrRUiynUSXeEpO+iGF5LIV\/bnGMS29s5U2KuJx+0HbK68nbai4xeMMdse12ZuG9dts\/tuNmwjOsuY92bvt+nJv2ROPcdRmkkbtvBfNakyWzcUsT8L+waul9lZRTs3IEotTnW3JpyZ7p9U4mlavt2sNtMDX354KMZDJX\/B9nO10EanRdUEwrrPcqQzYaOfpsjsM9jCKdmGXWTYOMQLYL99qb96I\/Y4gnTP\/rdW1dTIDgmK1F4tvt6pstPeca918NvFMk1I7l3BV+LxKAYQvNW+7blZ7NZrbZ24\/p8e3S98Nsbbeq0mh71g5GQNvAIeSSEKyrEDdi9Jx0hGjFAyk2HXgA0RGkom7Xdf3YHsNYtzfbsMKGTCNt320MW3qVCx\/Zn8Vdte7Bs3+5nq9nR6AgFeaB66iv+D214n12pF\/5ExNR0lKTKxeSr0WIhkXY8Utq4YOdxXmZxGzm\/HYOQGeG4J+w8B4IZEMs6sww9IPUynkZ+mmBtUrgkNq8sowhQq\/2FNJokY7IwVjcoLYFgJvYe4z\/7yd4TZy0h3\/tit+9G\/lxI9hyEgmaRTytDzpBJwgxr+l9C7MtHYKQ2p4OfoWfYhpvrwC\/ly\/MQRu0LlumBIsRtIdOqEfcypihKCSEa1FFb8dd7Lmj3mSMmaaKlp8KYsvy+MsTC4pJmcSRXsylA6lbnJyOeKmUZKsGuvv6Jw0k0mc5yEG0uFUWcx5ZCNx6Of1RvlbSyPQW4vDYAUNLpWoMcJWl2b\/Hl6LE3PWbm8qBv4dN8FEjsG0P5daouVtK3GKWLtDe138zB9rzDSgDGYZF5\/QFO4U4XXnl6IJmM0wI9xpS2CBSAJ6ASIF7s8iBda4bHMmRB6SmJ8ZU+bJjUGf1+nmwGvIzYTkatK0OyYDm+mrOGG8mNkJ\/KAij\/HnUsYZdMixQEepj+mkOimXuB4hZKm1qZMXeNGG8N7gYcbqfkzx\/TmWHk6vK\/6C08mni3OAnYjopu9jni1KiHKOK3MqTnoLKXpxzQiF4Q4y0DaDDePKxk6UmG2f\/SIdcMbki1BdCAjgMKKM8jxHHARnYbxCUjkl4RcSy7fwX0R8Ghi\/CtOiugRaPQ88y9v6RbyI7a7gQsAsNzRjTCPjyjTQpM0aDXTFVagf4Sx63NpAOV5R6cjrS66LhzN\/oiuuKS\/VDTA9N5jC1sI9EtMqnIS4CHPizZEsDM2KGmJVO+bTX95R4QIMcUtlNbAZBdGvCvUSY\/iUVLmYyQDfxKobmVC9gYJZwDEO6bCPVSJDXSyJXyNmJDe6VgF1EnLEM46x4m9mqhi8ChAwEraStm7oD4YyxtStOPaRb3VN4XZWqGAk\/6wWyqumrPG+4wckCp0AvnW\/3oop++7txIngsIDUgI3KqyG44KBIsKysJlBqHNfMLP4tLcQT4tqJxXj4fw6zqh0n+DuMu76kYtXvw+62kMdrB9Y38\/ZGoeKaDEFkryzUtrrWsZqen5zZuPPpDS8rBRyarEl80aTX+k+WdZBHx01i633bdKZBXgpdxRZZHnV\/vHDK4sNmt46tWqfY0sxfMXBZdnNk1wGJ6ZF0wrikZ\/shVU2q8evCrZJdVdm9FzecsGUfzrMLy2Tvbt230mAYYPvZT1NrNsSoF4odNPG7p+lH6UVqEsvoOkgHfvgTuQYu+++l9KT3FN07LU1nLtWrkhvpRrtJZn16c643ln1xZhMW9HnP74P9GT9o3eT18VSZqweB38RDKuTIJSubFVQOiHX1bExRoaMp8yYLrORPyFFOehKV\/PlJoB1VnMmsk\/0KK5DTCD0V4azJQP6dKcPeG2sEEcOpaJoN8VKNbFbOT41ltCWmi+X7AWL8xzNl0pozdIlxIJ042Ym0sS6o9pkWbVE+3RUEk0U16iHCXfCrFlRj4\/SNT8yhlcnQtAwik22E3yw5B0e5kT6UfkQVNojjj46gGK7PmND7eWumQDYEMqAyf+2XMCAKtLG\/vOvk76UK7zibXAeu4cj1A7AB4clbn2uyCx4A2oEdRC647DMoQM6UvLyh4+kvSGOmzznu6NVspj7oMWP70nQ9YAdC2ddF5jLMMZBZPTGcLCBGbnCTtU1dpXLG\/Sca9Og+i8u+Q13jHaajHvt\/Mmbg8ZAhckQGw6ilpgYg9vGLMHaJLnGJiWCCOeN8MFAWmW6T+ZWydlnk19HMQ8c9K9svFIYjw\/Vkzk0euVrxt4UBGUgJM+h8+Bzr5ccJHCcC\/pjmyhcKDKJr\/iZMwZMO1fwa\/kVXQq1C7o\/MAbAfUxgUpFfojEEiaZ8FeRFp4kVXMi3eLM0UrueP9309WUbFIBlWXkGHHPXZdhW+hu4aidgDC8+LYG9GhNufjrn4HH7LHhgthdFRlbNNCcUhKTyiHSxANfE3+E3uhB1mS6O8ypoOD14SHpRdeA26uGs7PcyOWDeVkLB4z1ZFqNFVIh17DqMiJFzwz+Akeq\/W3DiCJ1OpFQR\/5RrEid3zsHrnZlnvqhqV4WAHvnPcD9Ox5cgxM2DlJlbWpeR3TnRqZ378YW7uyzr+wJPLa9RPGF+q8GkfNnan74z8YHoqzlw3DafGU3P8+k75nviTPsqZerPh1e1zOQcabgeOE9xqSVF5oSsoh4nxEXWFRLeWECxCSVbylaqDL90nBQZdDx1\/mQBoL+9S3xZnQXDBquyageV\/khjvw+hXoZSkhtR8Ijk699xGWjuswfm6\/g2MSv2vehqADjVTB6\/ad\/8C3lpTrMP+Xn0k6BL74uJCF6SKt5qDFnRTF1o+rL6h8qjz7J3VRFOnFTx4HyM\/kW9hcljEcVFAwI2b73n06OKanQIXnFWq+2Wv0COlHeT6ZRVx6ShjnrjForgngF4vGnmseNDFo8HmL355vf469pyQPX+WVAS1X\/3Y24WVsyGrLs2PLyIpT6vveUO1Rhd4Jz1ysVF9jZVVisuwcXp9qhYOyHa57fKWSjL7H7Wvr\/tU4pJKVyS+XS\/yTOKvy7UCpubFtSXSNPqGrZ+GgW\/sH72sNIeqTUG\/Ng23GletR82tuKYinza\/HHfoRI+1kplj9LQXUzzlG7OSFp0Y6JHIeP8HHVJYpYviA6M1CLHzBBqgXlTvXHH\/NWqBAXpx3bzdO3PnPcYybtpZxoN9RBq2XcqV5BXUirXvXAVlp3YDjmki42sZYbvmim2NRcUWOzfXnHJCQdWhShJJGRcSi5bYTVJOfmmtlc1iHa+q+RD6wfql36+23LchzrIK1sJaYiEcGLjBuMBV\/4aKsDTlLlR0UayzWtnuyd750U+GN9drkU+1allVZPyZP4eUgGa9vYbrLueidRvRlfD+89LcTDDtpIT1\/MhQpDoSPL8D7fH3ZQXevrxuEN30USAXHnn\/6J40\/Yabk6qV6FqF39+8WROdnkQ3Z1tB0zjb13B45UB4\/2VnHOYK0ibiba149VXkqRvK+d2sW27R1j\/6RVf3KHx6tKNQw1arlhNTeYoXq1mSF2sw6UWj9985ZZFbYdvXWXglw9bp3nadrijMC\/SdtkzXen6s1ch8cb0W462OplkVonVJrNHOvTQZ+oFsHsv1IecJuUekt04nSj2H1mqcaG0kVwqBPCn8wi9MBVm\/oV3F+Kx1PxA+ythAuhTKo\/x4AfrPhjVG\/1BAocEqIywLe82oSViEqLqtVW9XDFUwHM1pRfH\/YM6FnSvQKvCy8NrO3X62Y1g6\/mpU5\/zM+dBZqWB+hzAOlanXy\/pVlp8qYP0k0lSlYT4zPGrydbjoEeu+Crn6pga12B+ZCjcTlWNzmZc7salc6665Xsgy5SN\/Xo7Gy2tussc1Ub6WdJIvJ\/ViI7MVaq2kzIIbtpavAEK3woXSQIevNQUKWbVvaeHV1j0voFte9nu7hnTtLnvuoqmaUVLBNq+Yl3ChPhs\/fEUXvE3RQpNpEDYGfaWrPV8JiLw31gxiC6iyNq9GA6etokbVVjpb64H1R4xYfVtPhX2OzbdVj1IpXc1KT2svelj3AqkpDx9Xsn\/a4Awado987bkzj97rMJEDqXslXfVP25Cc2w\/4poYH33\/0PTUZKgWsDD\/hA38Fwa\/hmDKUB3SjaBgHBpUigCEfJqFhebFoN0xe84eE3isZUx29M+SgcRAnwiBixx208XyXmu9hP8AIhkZYLsQy6mGTlZhngC\/Ox8GvqzQW48BxZbxtQH9UmgRYbd+TiOXD4PWILQ2DdcUFon1\/dkbjAMGWChg7iPk0caaEckHoWMIRE6RGDk5PLieHJ8Ql\/abtC9PyXwZgSEbiX5rx8t+cvhFnUQRvCOXkVOybw\/+Hrb5S28JTp+LXU38Q4uKKAzkJPCywpxTh0Wvez2RH9qCZBALFMawZfHlCKG49WcAHYO4qoQJoemhEAP2oPu6aBPmRa6zU35S0FVY1w5tnSbbFiU\/dAgqzRbS6EOG4NZxBhts0x1xFIDbqkaVCzRUdBJELDbYJg1Zn4OpzGGJ5swIYw7AG8pyDTShdFy4AfG7aFWcz2FIMVaZR6bWnkviZ3N4I838zAt6\/5PMvtoD9EWHFN9mtV9HH0jacCqen7rAH5tmiOZm3DuEnJBDC5OGy+V\/4QpqKPicaPo0csV1xkwO4aOwthLaKEdmKjleGxEWu2kU4WkjTW4YMcxgphvvGezouoa9kgp0vQ9XRJwwoU4DIIvRwlCHSiX14HXwBTzdOcRbRXx\/QEqwcA68TwH8ZKt6B901ktKP6O8lE0Wyw3TRtaIYtpkG6Il6eP0iBSogp72LTByZjeSIarZxg6RCs3O9jJCMH2YcJwgYwxp5GSyyEZoo+8SyKozEFSaaNVUR+7VLjhq2eTCaI7KaR\/3FsLhHZJiS+WHWyeSnEOMtd7BlII34HTxaIkgUO+H7gDOKsXUnWDB1I8TY1wIvEy2KQOpEDj0gD3l5osKEUQRZq4Hjutmp6lFwmxJxEUUKpk5\/9RJ8vRNKbRH6SSEJgixU24aBTqr98o\/JmK3GcjmQOT18iZgGRMgPMJ2Q9H3uw0MyARk7U85PIiQhyjzDdzRYQuTNEu\/cqyVapWUH3iyj2YJkHvdSNEMwu3VzD4dpJ1A6FSAzDJuW2ByzDCAmTIBnxyKpJaHpd0WAGQXgLfugAMw+GnRI6hO5skit2nQyrEj7k29LRPQ7EWEb4AUnSITIZU1R6KI6DKfcziOGdiZavnhReOg6wlS9QjFtrZLvw98sPxH5DNZb9FGnuKZIgcESARyf3YntovlwGAYLbDndnTuwFRCZlwtDr3+EOeZ1RzCDj3Eco6rQgqaoapr6FWKmyO+iKWSQcI5YNh7wtbCYfVQ2tqXEeCbEw\/o3EXvEQIcMHDgV1F7V+0bzPQlOFRUmg28DMR8BYiFEThuw3vVRLW92WOeuFsE1HCo8a6FrmYuWTlMfkZiamj8hMP58O9gJysO8GaiS+BhO971ASmKzGKEo0rqU+giTIcrHFHZqNMDJ\/05v4HWHhGoINAAFfQFY1gxUQLUko5+OTLKEzzXKoY5TLieRrthQ5xJ7SjIym+\/YQVfP50UpwyiTZShppR3RBgKEagl098SJ+MJCZyV3sAjdVKZ2qWDKL9dIBbgN1PbpgKiI\/MoborHJQVEkI7lNzQcd05+Y5mP5gMYiV7J9Gs3Y8BsGEl5ICkzjB7TaxFeMHh5q+CTcjUqFGOUWTRYGEZX4A2gCRY5L2LC5Q26M2H\/AuUsaRAgXJiORmxRbvWLzBUXaCNhQAjf9j4vzOzAQ6XaC4jY8Ds0UAXykikIsMaYrKAjeR8gg41f\/MrO7Hr8WlnvlIDJTuWzVxqCETXLS3KDCApZCwTrLATvCUjOfWPoUxsCGPIWOJCj5oppcIk+yD9CUJLvoyumN0WZSa20QYovadzziwBjfUxVuDFQDQadIo58tf3vEeaunwyztgfFxgeEuk7Tt+hCuTn1G48U7cqQDIHRjsMlwJyihnPJZOSXPGgUmVhNUhhWhzZ74NuzAAW5IoPYBrFQUzGACBdPlIf8AGW9gobCBZG4T7JvHdmM4KK\/d0YlwFwoPbBgFHp3TgCMDZj0GF+KiiW0TMHY1SMD6nZBjAOuG8RMpLXerSg0o8iAbe7uLX4LX7r169KuDs0lVm9h8FAE4jJuoCvV0Nm0xDTlAKhTohwSfioIImBmCZRE6itJZvMg70ryURXz\/q9BMyBmRhFNOqB8GS499TP0LehaWTeVpMWMh6s6FI+0CNmz4j0aVPN0Txlfg9\/UotqeffpzBNaFx+B7Vr0sDOfph5rGzMP0xA4aOBDgXkMr2HWhc1XbpALTQHH3UDMYDhpgyvjGvrPuyxYAT6zF3x8MzOCj0k4OW4qx3qwWUUapI8KIKLje+0+h\/7IJjBopwKRMBmpkR1h9tAZUpifvjgFsWRkPdAZaV2WSNFY+XfnGio44InwplBOu8KXqPtQGzcUCYYL+B0hXSvpZCCmkYzfZTquObYs4DnWIVmV5tyN8w3UU3kqTgjY8HTAM+cuOIZUG3Szcaku2Cbke6aU+eq5hDh1ZdGlqi9Q2AruyfTcAKmrfZDXEXv\/eAq+l9lpOy+TcrVB8W7+8HyS\/pAVf1aVWSgyPbpUE5aQmarmESzmJpPPsXpS8LJib6QxZR5\/svAY3oCC4phi9Hr68n3cNS9xsHJi5dtDYhyuCrPQc2wzPXcP9h7csDn5CdAH2xMTY3JTaJ7xmjFx\/QgJrN9lw99nfzhVhL\/LuO3GKw6K8aqbPZVu8ms+3xVx5i0q539RxXgAWRlLuTJtMca1TkPP76MtzQ6Nxn6RETDJqgbv6aII6qaPewlhHa\/QfO2KRhYuMKW9OOfSswNav8dheG0Krar24+b8I0yJkEhKhp3jIsQP56Nmcbb686x58nFF9egxILVuX5tbvGENlBteJxLqcjnj3A1HVlTolJ1VqR18\/FFpEYki9dsRi7n\/0cu+rW7iapXsVsebVsgkdpdTGNGqipvu9j4xpmVihZMVM0OsaVC49IyAPPyAr0WEJcrNMaEKayieTQqA5Y3LG6lghqjgZc1z\/ZcB9xaPZYvKvZYXkc9zg3X15u06itqt1xRNS9R7aL6Ri+RlnZHaLXcY5uV2nZExgS5CsPyOaVkz8duAGtFWK1OP9bpfUevq8aBVjZLSSauqUtQTf\/xbFZic+7matDym+Frfi6i3ciVPOFeUDbncx04Ty0YJAtESXsr8+NqwFX3kd\/uotqqRYAGgTxCz7KaqmkLyY9vEj8IdIp2qzSvhEm3XYV8TVuaa0ISu+o\/xjbURBdbUyetCxU9FVRsG8TbOnhtS3w6lbSsDW2+UH8NtvXc1cRJw5Egu1rYTbhnMkd38\/fMZbEu0BKDautRoIwtgdabBTWuJLVP5gofH9y8T19Q771\/VKs8xQqLcycMVfJTOWuwmjtlXei6yy\/axlSOkXMr3xrHvv01+zjaxsVj3iFf0z1Y1+eJmIaZJf1enVUJrGTvqoYJqcsgh5jtTRnNfkjVsCFVIt75mKUvvdeC9S5dFBg3HpCvjlwg83ZiZ6H3oz\/yK2iF1r6Q7ibgfG2UXm+Z6POmauzOPrTTeFualeMi1a2iJ+C0L1HnccKD46z\/y5UaW2qv1TUXkhsf1HidAmB2LtdfVkzqS4JFJLCHyxY8eMvey1XhVdNftldIFcAK\/bl0RH\/5rZOV\/4xSd2hf1TNXmdQVH7FgiSoJ5+bhEfDCXNninxEPYOIEt\/GCYjQq5DYwLOajNEyogJaQF\/hbpQfy6ntED8iqk4kPsHwRVaY0nISeGEcqwXLIHO0Go9Y04sSZUumwP1viSXAPVNddGJ0grCXOxi2aVQb6IZsrELP85ux7VOxoWOw0GUYqHQxPDUQFqGwMEzDCEE2iRJTSSDDojhlKg+f4CR6NDleOT\/xY0juKecwxk3V2DV3xc4asQrd6h+pHB1xODgdYwwHMbXqlrNrLMEfRKNaZzbGLcuEAMXIITnI2q1Rs6fLx7UL5XmFls8\/fwxSMFa2r7bAKjAFlcj64dxxddJWDCqVJFl\/S3LuFxZ+B\/IxoR\/yrba7dLLFOVt9soGdMiTGBuORF7Kbc3i98xSmiwE+GWAGdgcDbjaoRXQrgOFRTjm+Bf+u6TR4f2U4S5Ib8LN1Uo2Vk1fq4qFnIAD8uTHsG7iSboQZJMKAxOCo8S9gtMFnaGLpufTWDApKNwLuPzItAEyRlCgAwaCG5kYrjEtDL4t9S6X8Z5KYrLvwoLiF\/oLjiYgHeaAN3oiWLnx\/wOIeBKPGdgS0wI3pKl+1yxTUakoQvgOu+k7S0Ek7O+f3nD2jDpaFoAWJBqeNpyTrikn4CysjQOXwjL4NAoLcD5VEsu88FpM8FpM8FpM8FpM8FpM8FpM8FpM8FpM8FpM8FpM8FpJvCaga603DbnHVMCj9rdfhECTmOkMLACpgi4lduoLBp1VaTvzkVs0UvdBoPCxUX0Tm\/+qpfakpu60Rfd\/FeWd2uSrW8cfLqjt9ZJvzIVrCcc4WUXB4o9DKfmfF5GEuefQokG8lzs4WrrVUv\/Gs9LrRqTr1km4HGV73fNqAZxmqs8ihZROYsFpxlj5FGVNr2JpsoP55UW53oj0DoAgc20BBhVuCQC42xQzOnn8bWRH\/bne8RPlsOrjrjIS\/cjxpFUU+CLlINRkrOsWLbQlLWEN\/Nidwhw04b33uXJNvP9O8P7LLPQks8MkFvOmE8kVEG1VeQg6XRFs0TMaRJvBgEaZ6OQYSnYAMSo6\/SkHy7e\/hgtnSkA3\/US5PC98kz+FFjn6ZZx0YzrMYzHs9BGZdRvRFPMkTcdT0yEQh+CfsQJn5\/OguWGWdA9hGj\/nfXn4dyPx5x89JiuT+sRfFxL6M2e7AbJkgTKSr6AK2lSGJWhMkowt\/DwS0HFEm0wXknlem1jiJqEdfWIVlP0uinR+SQTINbEeihbayGGjtxVooX19sKuyNhYtGN+PyfioGNmNsGVdyoHcaI5huUTqrh5Y8Lg5F4P\/ozLUYoXVNHMS9M5wiKQrdnejdXdFnVnGy8bdK9bVIavsbWWlnXUlmVXYHNOjKsloYUV02qWldTuydRGtmobtcak\/lxVofRXE50pZ1vWSSsXg60qWX2je3Tpxb2aR11W8tzHB4Zme2Rd2i9haZrPib1\/Xg3pHlukhtvzTfCaspgPWSG7dZsxQbrQZtVHLNkga88Nd8qoaIFLXJdt8TmQm08pklb7WarE9e47JedBrm3wLQ6pMRck4eNQQMfyyCoNw23nPSk463DgfCg980SZjXfAbEmBJs1HDAZJ04v8OOhqSw\/nyXy5py2Kpm4jYPsrvM+vcd7vyA+aM7gF+26b1ZObpand77SRWfsmSowdgA7WSs+Do8aCa03D+s2SkUbeVUJNn1U3IUz+zQvMTGxWBxAj3VP7UfWHNHv48sDaRoT86ccG9fdSr0svs0Nw\/yo0LoZI9OFR7nLM7wUW1wzU8ezrSn1cCYAbLr6YRc9ap098gOHetGNI6zn9+\/kBxmN\/NBJQHy0dj3N5dhvIO5WnfT77kpEaCKzqSIwd\/N+cKsyluwxrdafJ5\/tnq+EuBrCqTkPbYf+V+O9LhYtbgMxMzcEy\/2JRE4sATzvZ4ImIxorod2c1oQLacbpcbJB\/qWKm1XRcbBOILstqxm2d5vu7cleBYTATQ6+VT7ReuXblQDwGsLMtCjoqoiq98kyOQ+TpdcFrPcsUx7BDreVQPdpbF8BxO6G6X8N6NQbpP0t1GEqLXElcbgBEevWwGxtI0tVMWzb0ZntwGPrHd150\/GrDC9X1nnaPfpxoiKT7P9zSKFI6T0Zki3TnPxkSD7b0yo58htM6ceEn95IqjehBiyWR00q9Os5yfWxZKtgVTTWvK6ij6wCcrE9ImrzU7y4fmKRnw8TJVzQQAkkqxB+x2BKosYGjowq9GYAyDSZP5SeHDqEvlcMmJhaOaodgAdVnylrBjibHfnBQXxd1697LRdn8jHHbxtLGYgeFfqHU34qq12gkBXjJ06kGMjErFeX5C0GAWitaaV1H9E37UVZ6hu\/dm1hx7DtVDaC\/TLF5XVHID5BAe1N3FEtDobaMDjnh2ktFIZfv26c3w3pXfJrha7FDzona2A8Xzx2C9iLVbq\/2p79JTV89c5+DTcknvzqd\/C62\/JWA7NrSv955ChacfnNrrxazi\/lBC1p\/D1n2CA+d3wto48q8matmQZyDTcC2\/wJoeVvBAz7zFz0T5pWD1XyP3z8jLKu4LQ03TtrBp8qB8swFbBzKBdbRZiLvgFMoyykLH1I7L86MaWYMFZh5gWI5mJBrkF0lneck8fgF30E8KVEruLadZoVIoUk+kGN1MF2eQcUbg8xdilVq5g+NztU9iY9ph5mb9FzjM+9CPWDv1SAB+nQzPaaR8moiA6b1EBvhWXwMXz0fJnqqbifWd75\/5SX16CG31y3BpnFuG2wq0PiqaETYiQKTDFP5YAQxpAzchjm1V5qd7IWJBJmjY9w1q\/NUbc0I0Ag2L3mIlKjqgqqnUb68\/iDsgpB1Ja43Ua28EGLeqOBMR6SIhsZOuFJtueRbpWTWtPLs2ucCHPVP613dTSim9uWI1jLl\/UW+P3Dzi1ryy3N1zjZzXSJELvP85grwvdcJFZ6cMaes8IlvzqsxokTJ0rmnTkz18TmqObyftS6rjgLnDgDlh2lSeoEhF+MzVhQIUf93BQ73EN\/JJ8ZcGZ8cmtjQwqFNRUycvALuQ9bq0AR6kNZKxpEUJZxws1o4E\/H9D8Zqzj2ezC7iYpuu+K978rEl9SCR0wcP1m33lyhqQA9eoa4vE1q19njbCGVGWuNvQjKB+a5B8EGraTIgxu2nBZzfu8R5U0DAc0c8MeY3K\/NKH4nrblt\/+bEDaPFbH5C\/QPXfUNa7FZV53nzW7C+Tuxr1cv31tgU\/RFN5Xk3+6NmRT+brA\/bMRt8QCr4ZUNELb\/g3iS6bGJNgFWPdde3dFzWVBLVPMpYA2tuArHErjdR1Y4QzS\/9HrtvUzEA7Y2P9vBlq017EYGXAMuuvU2S1ZC6p0m3LihJczp3rXDRvXdjc\/MqernaYpYq82kkKrU+f2tVT+mDou2rdr3CfXtz\/bU7Xm2s6rXnKjw44creocrSpdsSFvmquJxz1GhOzWoLSdaS4yzD7\/X9Q7YJ6s8ejScU\/K97MJ4dKV+0I6WeYFrHKX5MA\/QJoGu3cIxXvojW20LryzgWn9rzSjyGHrUt1tvs5tkx0ZxjwjrxtZWYbk3c8Kr8uinekYcmeZW6Q4RJBdvZbqPlCI77d7vwl90GugqsdCxSkF6HmnzCmwLpgNnOmLVoyVu\/eaTipN67tZNAVyhT5dAl3sHjSCbYPfUyEabQwg997M8tpjJBykjt6jCOjrw5q1ji5SjuKZXP2iSklb7E7gxXhdgq3EGPBkPrUnEulkmPpDjX4LuJEupORv1ATehl8dA0fOsHTpJI7EQLageit8cyQT9LoNQ47oq31OANlnMpJljqwS6eS11xArs0SrFgxYl9Sdi5KUHvJvgOA\/UL33RiEflUiYL7GoqbkRMEiRPcAm2192ZE9HWwNCbARd1hsYHHjhuuKkGc3jD2PV7hL34MdP+oottY\/PIuzmrA9VuBnSS+DzukwvLwpecdzVX4olA6EVDMiYkPIglLRK+QnK3vf5iJPgwVLBCoNVUpkElxyz1iot9T6dzCzMREwoIIr9h8WGg27hSqhZIcbfiU1+0pGYtYYXER4SjnEMXFNrxwqQSafUMV7lA1gK7ONqzriADIEBi3GNbpOPNPiy0nAP5LB0MiEe7sNp1KJttvCPHsiDsn8nXdk24pSKDTQwl\/xirbT1gvkC6SSJqHQBOGB9\/\/zfdw\/nTuBEVMQYbA7\/FR6q4B83PwkT+LvyrldQWjXuduP\/x4SvVaSCzRT2HhH9Fjkj91h1gIAyf0\/8ldlkU8jRM5Ek5EjFyEqCbY6BG2ZIZHx3BoVDRysPJl5ES30gOu2RoBw6cRrDhMCLS6rwI4Wdv0VWAmXDe\/ZcDD49Twx79ffuhgwUxMqyLUbvj2UPN0LEvzoM7QxEvmtGCf6AHQZ4RCqQCaAPcV1uIw08BpxfKxIYE\/gKwSjuvKOMaFZSwDG4ovZbCGeIxMjFN3gokzjQWJvdAzcNwxUD6QWJsmqRhuwgTH4an\/MAyCs8kJHaP4G8IeabZy1RjrhLA2DqUHS\/oJztXBPqC6eI5gHswEY5QqTpydQpDqWu5dO1H+DaSrJ3vpYIBFerROvgHKRYfxxBmzgWTtUAdxAlPzQ9mWO\/0nOQ4cV0triSJcRrOw\/ESybCa8RXmd3ey3DL55JO98lea9vy+ASAS5HmZjwY4+BkxGk25xFXi8hetycy+YQGVcGt4Rg1jMm1y9EL0Wi7ZQ9jBLEcM1qBaBpILbdCRMP\/v8Htft2e+cwCe5m9AFWrzQAuDq2GhjeWN7KjjMgjn8TZSAcbFVbb+PSkD+ReT9rEN89ganT4g0CQHW9FBcmUYCXXGFJ22MIjxMQNbDXjj+YJjsgKyZOJEHysyUhDZMKZBZxAt+o4coNCkApYJkMbwaVI2Iin1ReMVxdtEUn8nuJNBYRmO+WVioFUV3iNoVvIbuYdRYuI+B1pZpdnPqkZ6tVnRjDaJzqWs49YXo0hUOZD\/y8c\/9V69edYW2hfJFbQ2nvcgv\/ELvU\/GFrMkAuwym2\/Bq2OaxdH3QM9zAoZuILyrWX1lnlUM6HXDHujBFGRGNgfRjopKWmdh1xseKUi27xJam+XZJIJq5sYLe07XrpOj5qPzwPZ5dIjQZfUl68\/SNdVF23iI5BSV\/mhMAJ6gvdzGA3YzIpMiWrDxZXG+2hoVThvGBz8ydjcxO8E2zW148aSMHdsAct+ySRRaOFBAzO3yIp3RLPZv7+vBo3qKrPh1r\/qV35i2caOnDNIJ1FlUhXLMMgSQRczJOIPD7FJrlingyr+TnXL\/NOeWdHjaBXaY77U4BQ5njA+pTkNWtZ8TLqF9Q6HEwf4Rw7LTRiiSAoYRZNuuuMahnXXFjtJps7zIOM2+HsxiSWkEqDlMItRs0gMBAipSXuuUDkxswKW0YSTz52ZVjIgWdvGwt1EtlVu2mWDeIGk+lvYBYELkHZREu6xZkBy0Wl6HPaJxVWONryGTSm5kvjtmmxMgOq6IkxpJMMzT2BOiBujPLiA99xmaX2cbhXyqEuZLywiInk+E52zgZC0vqEU5Wm5byLJeBjWDjUIFmwpDyLknB8QxdnJJiXvwKjk+7P3syzJLMoc9Pp4NmdnI6TnU6wS9OdKYt7\/xH+jTnWDCf7nsBbMEdSql+JMHSgynFeCXcGRA2zDzAJRXOcd5EPSSAh+ny2WuRgcevdPrAOvNdiSZ\/V\/wcBj61V0PxM0F8tbwWX3+HMeHw1TglPY2QrpXESEVB7gKENPaMXUfC2uyaBrhgo1p\/x3ud9R4ya8a1fZZuaqQAy7hA3jlAIl6W60l2KzjoRwDWTT2DGCC+c8Qwkv033wyTZHy6uzuZTLojH4wbz+nhH12w4XZdNejB1bJ7AHrQ7t7L3YMXu26g0B6Ld+DaTnZ839+BF+8Ygb\/7zffn+gFB5sPl5eV3u873+HoPXw5vVcDxuAND7S1JFt4ceCGTsMLFIiVgleh2mjtrmdFVEtXZOA6ai3SrE41hWLou+tPs2gjpvfq6xG3L5Mj8BZVrACluH9xNHybofMjVBxCKwAuU5kKemakoIJLeJCDrRh0+nIg1AtYXPJ1tf9HwYrHDUpAPfqegDN2ro+RkQEvuLyFSNSpZcWCTJD6hRewgvwAfLjLk8ClrE845xxXMautuxcwq5574H57B\/hQ2xHokkBRVjBISLAg+W99CsH2jsQ14y2u\/rkRwuzeGH0DTjetjK+1V6xGDfC1XgHLqYwbOOsFi8QDcoD+FkGIxFS74QAdslX1+6IXZCYYXXvX7sUziH1S1+NlppRdVgqfEIlEQX3AK\/3V+4cvA+0H2SZKoEGsvq2TyCbtpKqJB5UliOGEgo3+FfjA\/scdyZVRbRBa+fb+sx2yLWKR7VuWIfIjwWNBhsONsxzaWZsmZ+unQGVk+OU4b6VydEYAOwHvUG6zWH8qJLeRR6WDVo9pKxa6VEhlWgFJtmA8rFecmDdK1Fi0aZMfKQgZlYqPVS03Louz1djxgzMZf9GbVOZXNLRBFUiuyzsd0s1PbNLMCOzxM4zWd84p7\/M6Z9kyOxfN+r3T8QzlAn+nqzNHKhfKpW0mQV8pgXIIPvf4u81W72GLi0fscKfbRG83Ov7+9dN0e1kGB\/do4hrynLkGkaEZ6nyuUzUN67mG4AJYg3gjDuGLskNvWiYUTDRouhqp5THCK7zkvxLaTDaVCVzRVV8\/kzUasZfQ2YqH6Ogfc\/khb0eZZrdXXPkdvz2I8+eu9503w8LSWaG5uHiDYpJss739r8LRQPyHBeZacNi9YokFKeVm2vfusZnAWRc7UslQPhE8TnYDrYEGTY137BU8r6HQtdO9t8AQjn3uwNlv9\/bD5bPlIjarf8mtQUWOVRq78iZG5a\/fP+sGnwJATTa2Fm+3WHFRSZQaB6jnBTSOLuoo8dP6fqwClFcYnW1tbjVw6ynC8jlSiuBpLRwaLITKOHvrhwCrJ\/WQRjzOh7vXp20V53vrIGW8D5d62lRxZzGiiNIc+BldNZn1SCqVizgBTK0ufzOKP2JgMvZcCrxyKk8pSCESnwcsQroyIUmIKizPJNFKP4WUu0Fhs0WdglQm2c+NtnQMsTReF3vSeDAWcCmaVUSKWzk7wI1omZrHq8cTWPgZCCelgW+e3IAMDVUzrh9FYRTB28ppXJyS24qLcI\/gaZY8GAWX9RyZnnjK1+WHlYiIexpMxEd6X0frzQav36A0C8nnHP2E+RSxttX1hGZKibW\/AOH7o6CxVi4PU1pdTnO7qwy5wPayroQ9l55D5tygIWUNcFXIR3krM2lHRQ5K2nIPwLD2fpefGSc9ZFrjCHD1THuKpRVmtmKfYFSWdI0vtiec3rXlYnA2SBIshox5638Yddsx8Mxl3DR76Qq\/YSod++cnVIy88v+UjK7LD2hXv7Q6rMYee0JF9r\/sq8YHF0\/laUELVDzJ2I5+ziQsnlLwoCw52W+e0VIderMuanaP1Tfp8vp7P1+YUmFFyIAZyb\/x\/thG+2rIDPV08i8qVZnkGr52XQyXv64UYm8mZqThdv0ygRvrkNpgLZJusUsnHZ4lwQj0n1t0erc5+NqzZNWir7lsGKVULzcQtxFG9Dr724q4Qlm4j8dd\/Ah6WkyqxIn8mGShuOB\/VbxJdroqDybd77Nv6DLjk1C7QPufqWB50nJtDj7rosxI6q4R+lLmOR1WMs9ASpReQTogFg8sS4YzLhct8+PO44IiYKTHCqrlwylC\/cUGR0bVLcdrTP5YcUiq8kyGZHzDpkXMry5M1uDjF8ipTt42fUQYagrBQ0+Q5I+pZd23Wk4NmzFkQ3GR7aZknqEJ5A\/sU96eNqp92F5W7rLrJnrZz49ki+1tUWLWhVLYHm0ecuzb3XwOIiM+W27Pl9my5PVtuz5bbs+W2eZab7fLXa99VW7hFtcj9JuNqJT0En0hIgwb8JI0zYJMAbvcdwtuYd85neCSnK+aILZ1i2fCFX2hIIjSNtkI50Rgy2\/ZIqYuTyOTIT85h\/AsV\/WI40bYRbPGE69EYEsJ6EP1886nM5ck9nFgeDy2vjf1HRmi7h0xLFgSMcg1ruuQb\/UfF0BYW6VSlFOIHI+oFprlJVCSv1fjL4JuqhDarr0nsbls8rcZVWbqGHNP4Lyg5DkvyKgPcyWXWYuGzmFWtOEArrJfL095Xa5X1FmTiW6U0dtXRq+PGK6nm3wlWkFrqjqsxj60qpkCRss2XfYsVe1zbm7d11xTYWnEHR8dP35Mzy4b7hwdLPZ\/7OD78IXzf\/w3\/T9zq\/1v61S2E8OsQkJ+4QQWzI1AQiJ8MjqLhdP17XQuDDmY8CcnMr\/OnSSAvGoY+2AFRfe+Hc6Nt\/woL+yT+kK2KFlnj3MUU0ahU+o1edJuKNxbiluUYr9ubwvGLNc2g\/oXQUveO+l1BllXip8lVn6pn\/hJFKrKshix92ofrZKfvjPxgeirOXDcNp8ZrcfyaNBIdY8q0gqbhBKoLYopbnTZ6u1j7iQ6Ojqz04fs1wWdd5lmXedZlnnWZZ13m6egy+68OnpWZZ2Xmy1dmljVFkhrK\/C+fsY+M9H5QZ+GUqhveGg\/PVrnv08i55c4OCGI83maM8ay5Q08ysnExg6iIz49J8U6ok9vFAARNYnocHR92NNo8jBw5WPJ0g52lBLfaOs8wueF92AzieOELpHmAoa7doXRvs6Y+GYY\/g2MboG8EUi82KWJ0+MSGODlw84LJ7MEYhBgvjsxarAbF1XFtiSMCRWlkHn6Cs9JdB3yGA08TGd9TZKBJbEDVCfPbx849U1r3iDo+Ze08aCiPXZbCGTg4nunDQVcYkLs4DCJmhwk1ju9HkkHhEdse+wVRoCUEulC7NQPg310xnDLb663kjiQ8+ixys2rAZNkGWSaI1G81xHuKurwgZZ4ntCP1jHi5v8I9+qmDWOy6R0MGCo6EoE5u8F\/CKPEnooc5egj9r1FXsE9DmBjh\/zdMIpxwkOyQnzWHBvHIOSgVp72dZDoGkaDGH+Dv7U7GXpHE5hbIoEf5t8uvwgYqEfeBwYYFeTVN4Jg5DzCvL291AKqqQfyPMdkwYI0ny4LMjI8YtiX0zIahmma2qvESq2rZfriqA\/tHDy0bLBH1LZtdqvG62jDNLL7lZsy44833OZ7ZlSe5hll2sVxEBSYumdb2yVFH7a\/Vpif1+lK4dH+pG43KVR\/t3p7PAhvIqYXsb7dLRuafk8ivuqA6PAfXzdky\/0uO\/LPfrq21NC06GjkBXlDN2WZt8v7+M+8\/835DvJ\/nqzbL\/3Uv2\/egThc0+s2\/iA6aP4zi16Z3GXOtirEA4740XsrGD9\/aZeThU9kW7TA2TukvbydePLGd2JAzUTIR27t9qQoyBO0HHTkfsndutsw9WheWe437FaNCDYtei+LAX5Ynty\/gtA2XJMdr3vbqp+q6ej7oerTAZy5tjEtfPjHhdK2IWy23wdxFtHUmAKf97pZ9TRgsr4nKm02wNqvV3rTG9a3GcaiHcGOBHBtjxCp9iyAYWk3eepdiwI16XOt+tAyPwD3dqf+87yHsZiGgxm\/BBr2eylsJTzBal4U+MRAXBBRGwdhg3u2WOtHqIXTLYAoPBtOsN225VCrblQ6Cjnk5SAeHCWOEJFNJAX+CR+0I3fJX94vWEViiqHm\/yhpZF3q1RzhqBF9Igmmh6ayH\/Zth+Glx0aZHqSy0c8csloTCT0AD7BHeFYS1icEzzODxczwS\/fUxy6diN2v9G4PP2ZN5L28OrOHALSBuVgszRe5d1EKUB5PK\/DDwQ3kqrIQj0NPOlUIxggqXZ3mB7dkohj0rqUhb9hDVTWb0zV2UnCex8KZssGlHM6mOdTTd+B3LiKvoI4vC87xBdLVD0kjmY\/3Ghes1FJYWQ7amEelYfhWQ9AoHRvVb4odtS72ofpfDr5UhyA9vZRWswBU2RkB7TGFTW2BlE9fTU7PbsmQO2KGlhUy5Z40313hFput+mRrfszJ2vzL2ppo2Zs7wsz72rI89KWVIrNilsd4F8uTUJ3uP5hp0l2Z8g3V3skoJwk+SL1bMKXfiKebJE3CPTknXycUB3L8hXucw507mwRm7wvgMxwIb\/2ngUIVZzP3IGclWk87pDVq9WNVTWZAGVsrZbM9u\/lLp1NspeVehK7UcL\/f5bVzfu0BlH4s\/sloF507XKtDeOaD7gQo86wk0F\/ulKVXgMhDglzhBXNv88ZxhiE90cYP+esZDmV64kGEyAF6YYiLXreXxzC6uLZ+mY7Hk6Q32BOJLYGNO7UpK\/zBDnCV5HFi3YDuyZgJ3CFzyp5kKs7YWU967p70YOFTXzkC2thaSyviGR1zQxfVZT93Jzdyfprs1grkc2Wp5szfRhvi0u49BmiVssLUZFtfKl\/12S8ScRH4i38JZ\/hsogRd4\/Wp9Om7O5K9F5sel7tqBvdv011YRD7YJGysS\/FN3Xc0CHlDs2nOjobGn0uRm5ATBJTcX++AM4jXJMHsWmrsLbkhHajMT6DHkZK2T8eaxKNUGUEs7scT4rQMnCC+N01rGVCNJVjXIZfX65iU3EuocJICMqjkGK1HtU\/M53fNGbYs1uDmRLq4bpU\/LSbUyxAQrOgyXRkc8reU0aCDj9VEEHFmAfItsgpirs2m60SffTFf9NYXg41lKXqiodan6RLis0LFso3jNyomYPZYM5eW19aMFx83yh8tOkUcPRFu5R\/PNf2On8QbKdQIYtHY4cbU47OJda+\/SU2oMR35GI7ch0WWTOkHb0b8mtK77DknlvlHGfWnZtCR7\/kJF69NKHjj1LWpkfsiOIXrjaYNRk8I1jKQ9rSMgmyVrreNeTRbPy0KxUm+tWod3uajMwAAtG5tVPE+Y4HWWnDZ3JWYjD6Xj3Vwv09BO1icW7Sjb1C2yhLm2allmN86d9C6vT2sqKQ9PabuJvWvcGK5jXbg5FHNZhV1Nv1\/y1ir7cnm9VgwQ2Qooac\/RIIoLgUntXMwfIz\/RKTGO8Px+X0ZYxTRyEtg+aqUrVCiF68RcbJXlLESSABn90VhFhNmIWSpjGWEyKyVc4Ihx7A9Ck8rK1r\/oSdfBFAif8iooGdYPhewOusJVO5FKE8b2Q3RHAtzzQ10glYYT7MOLYJqIBCijkR8SWGBXXNJgSeTfUTWW0q8uvhfhCEXPMckX8AROwQmwqGoKy4GVU1KwAepMOjSFwlhqdjjsRwy\/Mtk5kfw99SNsIBwOZJj6yVTECpN4mAJOIq4pr+cHmSYxpad44iwIYHdu3CGQHujGWKKwYqeXhh4nrjDqoR\/BYEFK2IjcoDgeBz4XvzF54MTBDCdqScTBHw1EHLlvvhkmyfh0d3cymXRHfgSvcXr4R1dFg11\/hFfcLg08csZjWMEuvY9+s9P3B\/vd38aDb4B+yZtvvoEjYw6OzRWDXMVElbw+zKEmGgLPoPyknYmkGMG\/qRbOCZnQ9PpOjgtbGAd\/yLe3A7uB+0TcsogNNa90xY\/+rZz4MSKhhl4AD\/Gb+EuMKOnE3BXaw6PQm+K0aNzZWZfnMzdrz79TkTs3cc2OSIZ8okono8VpQOcTUWKDLCMJqwtduWgYOscFLp9IESpKM4d5GKBa5hzqo82co5tqM2Wyg4uZ8YjO2hU3Kq+VJEbmkZgr+VvZV1Q\/kaEY+YPISaRZSE8liRrhodG1jsheHaSgmhiCzOW\/wXdvpRyLdKyxfPOErMJTkyG8rig5vtg8PH9RrUWNNLyF0SaR1zEnVco2LCu5W0hYI3Xrkd1Bs3mGZ\/k1Qwm3fMvMZhXSNZrflHyZKqHGiT\/y\/4mH1oC6LZBUXfERz30aeHwdIkiyTzcQfz2TcOZrl9d4cZl66enYd+mmpnPrIxfjoeMSFFhgQc6ZC65UjUy1MagAzNY\/y37fd334HoxdvG1L3y5e9uGdCu5AVmrpaSQnnNvQq5P8uPaK4a8upaetMPV9R7rl6NtVv7ygFslQKcrg22ftv3mywfoakQX7cIEKz9MIDRn7r\/yr8WvsKfhuiwdu83McswXa0cM2CFOVziMVU9UsXn0\/g\/3aqJfWNvj6MKfX8Onaex4r0\/XLyYJpP9+0PYdexXIzviqu+lUceMtV8lXKwhqEcaxxU6yXA7MRdcT4AcTnZoUohhkqXhE0xZvHneLN9Sb4ydfkXf7M4BpgSl5eg712s9Yb3czmB\/J2yZbEByxzM7T2x6nm9Zsu5F3uDdpk4V0bf2b+iCwHS5m7CK1cYwtN2VrAKM152OYbqiZzERIuZRa6AnaxUzlBlys1ZcuDLq8zsJNIIvAdtY3kkASMc6E+lyKq7C2j14Qq6fCIswENJymA\/mmvvnYe5XPj8IhC\/71Ksv5uPgduRCgnBY9zVt7Lrqryh4UxJ1jr25sNKWioPkUxBRM+0COehfFEcgursYpjv4dV5UPszudRAhOFbbhG+OJ63ZW+Nsp+DiVrrSBlXwG62j8Mk3mHUZ7WSomrll4+V8VuYlVsmae+jDLfMt9vIMNFMkmjEKGkz5e72CsmLyycXMU5rq3OZ+Etv7bKyzZy0u7TYx569NtqvuhZnaCiQ7oSNlAb2uc\/rIhtzyGtmYcPFOw8dkGmfdFTnSNWNda0qe75Gmt\/ds8\/jnv+Yb349E0Dqnd9Aq2+gEeGQpuD6XRuwfhD\/PbMGMsSDslG8+MciZPTqcDAogwgtvX0Q5RYBFaXrJVYUJnhnOg20x+x09u7GQ48rWOXNdkPZMYiu49NawgIGPnGLsxT55DNG4cNTh2TC+lWjC\/D0+Ys54Lwpn7szetZiVpeRXLP1rctADceCTOWScavZ6H3oz\/ykxYo+enLhASqCoNQ0cjNFLg2LJqqHqeqZs0Cc+bJWzEPbOSDfvNZ0WoHMxl4ixTyghit73jPRabVGFWOeh00ckwW1\/mPGTLkUCVChpRBqikh9NJ1YubFNf5DT62bpdKDtjN0YhpC9vvSTQR1uDEJ8vCtckL40HeHmM6JDm7y0nvkpp\/3ZF9cZ7oXqlbGjb1u7zVqHNfWj1rjWaLEkZ4B0r5aXuiffdWTQeLYPepq07fK05eWT\/fHl+H7Kp53BjM4rzQlYAubQOEjAX\/20Rpp2U9blkpfCr7kFxHk+OJiAkXR9uS35gthshmR\/bQXM39HPO31LLzCnjg4s0ojVz7HBOvGBG39YTfV60zuMQ+WPIy695nnRVQw2EIY7e00kfG1jD6qyGsetthWQW65VOdm0dvXEkSZ6zTgR3FChcpkgnlO4lDFHuUQ9f3PWL3KlpeuiYtF4GBtfcNmVIsB24e2vsF5K1uU31k\/waq5wTUm25ueNndKl0qbAUYyGl+Dpyz9iL+e2sU3l95cLcKz1ZPoFZwKOa48Xk\/7rx9bSLfqEq2wfAuHpU0BU6uAShVYsh24yPIVQdQVb9CtB39\/K8hhJN6g0mL+LfgZzVv8ZMMXxH3+qjUfldbFetVA6cXGKoaVJE\/9S7utqgeZUCncdVvXfMNaz3K3brEY5ea6eVFrgxZYK2RRqRq9Mk9fVCDFRQtneN7JvhEo3k80qesLzLENVfLVkp8Y9m9OXA2Yv5ITdLvGad1c+OEWU2Ct0CVXyYN9Yonh1WOw9lbJffzW4EVZJVJYZdyhhdZU76S+rjqNm+uNZI7mvXrvnOg2qxEsZE\/4eeUgppo+QnJpVTt+44s11iJvH+G2e7obS1t60Xj9TUVg7zrH9L2aYMNmSvWe8bJ3RDr2HMLOnIHjI\/BUwnvViVV+pIFGi815425b\/peFiTqtehpqYHj8apcDfE8K0Wa1Taoa9a6WBm2fRZUt4r8qIuJvIiBNUzywEiFruHKaxIdpVeTb5vNtnuBvrX9UBeD\/h9mqiVBAk2Buj2TGWwvCJwDJ9mBKatv3TztUfzzUoZ9DdyjRnGquK2pz9q4dgNH9+9\/cTCxhjrJMp6ZPOb7\/vla6zTBdNvXtp86alv3zntl0o9jU\/na25dT2usOuYrfVUkcam2STtsiS\/Ag7RXgy9AP5wRaOvYV6tlLosUafiMtEYBpsLBS2iEFkfUtogkJdnClsK5fzLnGPccucfhpQNwrsRzJCoLV+GpLo47no3jxDGYzjYk+ejoY7g1lE\/UBNuuLcNBOYcFeP8ViGsfFyys\/STQ1yWU+CYL7we6crdtfQMqLUVIPGxir6lVtqmFlaYnjUYazGVEnMprYb86DlznjL8v+s6LNvJyBaa74pWuoNXyUnZyUKVTO6Cpy+sm9gE4hzsKnEqczgVdqvaZhNP\/QTbFzmRIOUWrH4mCUeDQycJcWc0lFPg3SCqL+jWtwYfwz7fo\/lPlb19v1EqFB3jxo53EstUmpkpHoB8dKZuQ84aV25bhp1CO1yHKmeg1iWseIx4WbpU1cYDopxMQj8GwbRSJ8qwk40sBYauivOEmqCxn55nsA0TuSI3wV3oBMPhadwlmYa1O8KLM2Y5pCiyWl+zS+Mu+IjYr5MsOsOpt\/Du6JEwrPxvc2kfLroxH9MnN+zu4wuH6KzeC8m1GLHUzAqon\/CvV56LEYFt\/hYz\/Gw8w13ZyNKBbgqJ87WsZtNXa9zQXMq7AwU+6NxIKlYgDu7+aELhI7lzL7rinGOVcB+SMcdijilXlT+ncy3MaspjykiguXi4sp0KUJ65RvOPdZIkdAIq8p0zXMVrm2iGPdUCUWNwPTH2YJoys4t9uDCjm2kKXDPH+pOhqya1bpjeXs6FhqaJ3tTPskbJZDHsrrzWXWlpHZNcNqwBaGUPM87J\/KBW6UO8IwkEY4L3onfA6ewduxuhj3XsLdSmBToC19GmnQ3vn8YUedKL+cq+ssdSA57iIN0dBYN4llLZuRMtZl6A2adaw+7MPvFtrATPhgRpq185L+e5DOmPyFQF2y6xQDF0qcmfIYtUYAW\/ff5YVCR5vyEwoamWR0Nx8fS8ynS6BiQX8md6KJ0nBgj5Ry9F7TV2UexRg4u7Bb9xgM1nTvb0UkG5TtSY2DhRAbTDUBZqIThWw3TwPZpszW0BTa50nPfPMfDvX5k4S8Rvva5wHsDC6LvPzAbs7D6\/gPxP\/\/b\/\/jvD\/1X5SLRqndBxHP74wIkD\/pRbgpXAMPeF7+jdwkBeHoSIezlzE0BWhpey6J4H7CyjmoL9lyN7nzsCVsbqJDn1g7ipt2wZTI9BV9F9W4mH2u2c1qz26PGiin8cqFYnYzfLdAHbbAV62iDn7qbIhvOyMg1lLgsKnLc0ZkPNT0gYK3cD5kkQJ8wSTuZFtmDL8wf10whpFNWVjPRzgR7LM7MIbLS0ti8j3oyx8XeGHgAC4N0sKdGARAMLbCCYlw7aVUr3Haun9y5+QjC5rFxa3OncOgHG8DbQEOGtczsi1V6b9031KP50DZGDmTGJkHsFTwH1PyGfRZGj2CvFtqbHDZBJxY6viL4KSL\/jBMMFFwjw1HHtFDuDrqi7\/dU6Liu3ykoGDwYd33WPrKidyz34\/n8dlRi2UmnPWT6DUXPnMtwrXraH0DQ3Cnfyz05HWwy7xbcSLCW31O49kQMP3V0F2jyjZheP4qQmuGXmf9I97oG01b7smD5KvKKXpgyKTuZC41cU0aq+SNqGm2ei+fcVEUfFT6MDiB24HSKDquP2sEVquKcjacHp84OvUDqjvZmjkGfHKFjvx6GdCPtjpdwer+ghsylJDarEeb7RWZsS9pbtdzjB30DLbccXLF2u2HE+xIpWkhxXuxLqUpiUAYjh6PfHxRCoF6Fq19XVoM+4sXVZMfZ5ck6lbeoMa9ZJVACOyrOZfgse\/Mged1o8koVsQZXjGW2lZ0iufWUS9vt24ln89huKEfC5jp45F23aeYre62khVdHaLfzfurpWm7akvr6k7lQ+YPn51OlfD9hmXi2xmz1VYpk3Cp1DJ\/W7Joy6lxZeWygLbS5ZutpFM0kOq7NRv1qOoDZ3yo1oSfCmsm8m9Imp6GeN81aRlZdb+p0\/F5r15vN7TRjZl90BjQgYkUFaIoaNZNrmOdNexiwH1TuNMtdc+QjJL99T+r2ZFlHs0YzO74IBKIKvq5nmKelL79zAt+bL4myLTKY+6Jl89rwHaW6Wb6G8+K2H1Ckhgff\/9WJenjOzxXoDDSl73bh1\/jkW9lXHB1DvzSF4BwRKIWd42FwB5UezKaNxaVOElTC82M3jWMx0MO62bDkuS7kHmIMbZS6Q0oL8N00SKZiEDk9x3zJTyghtQ9fCl3q5DMqJNfG7AmfeQ8mkmK255R79igBCixIjrjQ8DDGvEg\/3MFctXygiNsaZusg133hbZxTgBmYOO8IE8owFRIfjRM1xuFHYqgCjzLbQvi1nlmHUl1JVoFmryiA4cRTnv3I+Q1mbHJbfe4ydPN7Kp1b8cu7jFTwKp8yKKM0DE18Yn7lOgUX9kq3Z8TSEmreOJIjFU3x65TamefuOaIvnQQbQsIL4iGsL+aMOaeQF8sh2bn3UR3LL+84+86nnOpsK5EuIJXlaAxk810hQ2q0RJOJnSmuYQjCfKhAVyYy8nwoAxX\/hQm6no+Z0aUhAwzz8PwotXSYYnSXQGgpMzYdwBBvC\/mx80RCVgY6cBBjiJylQx9UbBhTfq4TToskxIF+ecdXDW4x7y9GhNIw40+P809GMG1MTAFCwpxjTRfOmybjOBs4HHTFBUxIfnYwPbmTnSx9w0W04\/hDz4mBhIUJgQYI35eFjPPQcyIv55zTzE6So++5jPIds0AxVzYfkTNltZjWGoJp8WmdodqbJvLG\/+ecvo\/KgYzwE+uhhl60cKR9+8k4sfwbvXhukAPrQdwALpm8K1w+xKH1EJjfEnrSW7QcT134QWA9FD8+OwieBush+jCAhshuJXn4TPOMVsf4TBk2HsDhhRGAEHT2cvnCDCImMDE4vlvvFTCdMNwEXArS1puiTAhSD+QTTAQObV9nE1OdRGGE7ra45GoP\/DI1fuMP+74MvNhMpjA9nEyfiyVMTYfHE6N6C36IhE6+ijssBzaKzTtnKljkOOKv5zPq5+O7LyonIoOAsHsWiTMeS+987lw89C3gf7sH\/U3oeZbYVs3WTyL1m8oYrdECJo1\/vwyT1VrAVFxuvv9PdcFVRCCdEWFuDryiXZRQfz3Pqn+9NEJtIL992+pUMneLLov2VQsyig1OKx2n8fAnklaopcNGWOZVztz4DfcILwna9pyhRnM7H6bhreXC55U3m6D+KlZ3TTatEw5fMuafHqvXyHb3azy+FupDe2dhrMYlOVDtYCO3He69FjJxhf73CnqdMUxL51OM\/MEwEbnJCjcFpvWlbNtlFwk\/RqZqbrniE\/reiVWQFi4TsYVac\/YhpRuGrgpBefUxSXHouLf60W2dSTiO1B35D4x\/VbG1u9CutTva82J4t9aGbIPtrGLJCKPocNKEIghSdFmgXwFMbXRwUFr3xHh08EHsBwZL7qWDOYtZg3fA2jF8AKr9nxuA31hUl4ozj1SQv6hcnVo2vbOHrnl6TaJtVLMONH1uJHtPrE0KAyNtiT2thzeIUhZfQWdJOiZJUmkl7EBtwdCwkoD3krNqfGYk49gZSDNQt8YkZilRdQqwyzyEefnMnOpnCFQBNgNBVYLmWjJpAwBBCXiiBsjGo6UxPnyaNpWkG1NZ8P7qw19O2emvAp3VzzKD6on6jh\/QPdqjSwVom7Df\/w+ekvF7lfyMPiC6Jk47mOtuSoQc7zf6q8RHlA8f0N0ZDTCyMaHvUMiA098nKrrtrtkzNEuiGzPjlIM4npqEFGcVRh7XMEzvOWBVhcsTPKf3XGItn9QZLMamM+VnDne9QG6DPUwjJ4z71nHW0uyrvAcrlImkp00rMO3kxa+Cq7mMhlTfaKA1K\/WbXZWCm7HmltIXxst8Um3KqoXac4up7mA\/D9nq75\/WtSHWkmTS90PvvVF0L0Naw2ldC+WJFGVeIegTWNWJOFejsR9I710xaGwg1BjWKeuoSjkCOojO2GOUMIIpGM6t1G1A3CHCZMY19IrmM\/nLi7OUDJnRs\/1kEBY0gNmaWgqUruD89NuSuUnQwjc1lIaWy8p5ay4CZ\/CEADuw+lpmQvECVKVzxx3K1rI\/f8oKvD\/L34VDkAuxKNCuDuBC\/u36fgrrUPE6QVnnLT7CDUQ7lYrXwSDeiv3BcJus2Eju+CHmVer6b+1eMn7kxnNq921z09vz73jKUjT+ajWFU7tNruaBFGuwtYpNA9brXbOkWl3TqqH+iRtrwDylVgdkKXyBTLeKp2Clvd\/Ejg81+CINr9dgL6\/YauX0q5Yc9SJY6\/MftwJUkRkylbXMB8N1di9fNSC3JGxZDaf9I6J+azQlE3X3uQok5ViLUh5DoLP7oDdbyYDAwuIdr4nycf1wBe9NR0MmjUrJu1wW4Oc5whzDFxgVCnUSYaI9G5gtTEkZBeT4LJiiswwSLpDJ4vsWp\/qLZhnNDEh02At\/gJU4VEuV9ZVFj1FOAtyNWUmBNSKcDdND8CzCKFeYDQP84IgeiCAxQqQurrvBtBEn4u2aKARnvwWu6Ob48H4IphA+0XcogzzO6irmgMYZvwurQxA+v4Ogo7wKcohhTYjpgUslXujrykDTO0VOCwV8wY9kqcII3p0MkYuKfXR7eboQUCPOknNMd2yqD9J1TbgIz78jgMQs\/phBbmHhSw8TeGAGnim00cVSQHoVyMhUNOVlNk2l94jYHUpEL7tMTGXWQDEBE8QGQ9x43MdIwib4sPR0QA12HA9RwpwYzj+23OkWYf3RmTiQOnkJs\/YT+E\/EKdYLUY5TP5JSVwvEWGjG8VimRPZaJy9ZIDLN7UKH5u6lASXtYtYRzJ+g4ODvidmEO5k1SZDcFRlpynVNkUQUWl0J5mHBUHRPEReKObiwMDYtYqevuzoA1WBaufjpYVXeVKViomsSPAlLD2JTalassoNx0h4lkeGaSqVAhHXhifeUl5r\/mjtdKBV5fkjJVYzFR8lhTAIE4YXBFvOG3JMnEv1E8pKOQIJpY5oL\/pSlRG31qfLJ9D+S4cAP5XbOsb+8wzZM7HE2TuX8HOjz6ao0YsD5fKStfNvcQGGFYlwUIjziwpnvO\/vOqwNyCMxmAOjpb3ODBMw1Y2bFcrr7SvEaQYHlKsEsW61wGeZ5ZMvOqHkQ9tkcRiSI\/bc+giA4iwbZSU7wdjbZipggyGdb36emzlFnE3pE8HGQwgbHRaE0hTt19kZVLKAmkZ8kMmR21kWN3MUlF8WmVmf8NkVQaZJlwzQM8fyRaM2ExfDg++tIjeFYY0OXjoAf+n6g2QJ+iMfIXVnR68P3JNVN6rYG0cAJ\/X\/ydiDPgAy6RTHCMNeUn4k1gr0pCjQwIHgz5xunoC+zp48KthXrg1jCeiUUjlknml3TCiZr5cWaSlj+LiZ66u\/CBqCLU8TEUYUvdsXfUMkyl6LJ6MQGHXCgim9w1WjsRPe2fNFAueWMSnMBFh7sircKSzYjSSNi0KXQSQYfDMS5+ShiP2SKZ0yMpuKgu3\/817\/90zyGou+HVIl3jvsW6yVhA5e46F3lye\/\/t19xB0TYU970VBzQdgK\/nYpk\/9P\/bjAxcbyj7sHJKw18adS2CHfgVOx1j1+JP+pr51TsHO51Xx398btdesHC1\/VAgkbTBK6h+FTsHy184cvu0cnhfS88OjguvvHFy+6L2RfqV8EzoIRIFUdwVX2GJR7fu8SX3b1XR\/e98eTwZfGN+8fdw\/0\/WlA2GWK+MfIKrJSPy175tSfdg+N7F\/rqxUnxtbALB3\/Uzwykglsj8l0sOQ\/h2ZeHhwKLugnZeSxhvWOxc3DcfTlHGzhvsSwdGeR5aqbjgYhwEzxtBoxeF89itTh3fuJL5jtHwNL6b74ZJgnoN7vxUKkEa6hBawWu7nqy5zthF6QBCHVg4RRPRgDrSGl++unvdh2QnKiubiEoKkzlMnYc99\/+bTtTaYg3dU12oEiH2OGmTij3QgqAvN+hh0BrS4PMKKLJY0Xz39MxvCHqiBss6YZf\/Bw5YcqC4r0cJ2lILYBG0nzLUG\/L6WHDHwev+sijfHAvJXkM6iHIcV3lr6\/d7G7I5qmbTyHtcX1S6D4wJD\/chJPYGbQfxCRYV6i8UDrdbagmOQkK54UIUTL\/QBm8m+ojJfAZgU2c6CNCuOVCfyfI95uua\/hJ9lGjRKDwQuemeRlucHJBw2NGjLOJnZvTxfsTT0c9FQBH8oY7eWdIlph0F4CVMHb8iASrUWF8RvJVfF60hRh3tDYToD4D8hgsC7JicEJTidmL2UTyY8Yz4Z\/zJfMsxoiNQR8r5PWeTCYInX60dyioj2ziBLfmfiis8iymjUH1OJaE+zCQCSvEO1y7rhmGtSgJ9J4m1KNKfnYl9V0wszOow475pZ4xmvtkP9E9lb35J41rMHvYJpNJ9\/eJ83sX6Lr7zffUXAyUpnQU44HqULexTNXt4Z2CNx48PEpD39Ut3ExlhNB6Be7CeaTguCcEuoxrNQdg\/+iPRZ5npoHngdFpCQiFbG5e3WsKZBgcqzP4VWYMRES5hBuqYe0y4TQHuuUYkAHUWw0aPU57yEgOYmjg\/NBE0qOwDwT4K2G1W0smov0AuDECXgdhGqejMS2PzN93cP3CKQOmgTeOFYgc1OlDNKtwbxnJHo0XOHj\/8\/\/5f\/+P\/+t\/\/D\/ZLlz2yTpiFjZd11hXKjQozSqvF9z0Vfwc5tYmib00VL77M9hQ8a5EobuL2777Hxfnl\/vdA7ivu2Bu7p7r0pBd0AyubugRJLOUI7F\/sHu4twuX\/onYPzk93F94ZS+bwOErkXc9LH1\/4KJIRMeEGyCd+Qe9yoOj7otXx+bae43N2MZkSYJxChwYulOx\/+L4SAz\/qb9w+PJw\/yU\/JjORW9S6lk10C0Z4MTeC9jfAhg6Aa7fFq1fdVwd\/JEmkQBw8dMMvfSMNkynnYisfdnvpd7+SB7b0dmyDgZry5X0nTQ7R\/mH3xfEfxRb+ffTH5TT7cY+IHTrBGdsHeTbGYyzlaO\/gcPkkt3hV2RoPuq\/2cI0H3ZNXVmvEilTkvx98kBNowXwZjPDiZP\/Ignqgzx7m1DvuvkDiCfjlq0oMcoPhKO1a+EkO\/JhcrI+wzIPDk5cWyzw86L7Ml3nUffUKl0l\/2ywTb3oV\/sSm8ZfBHwcHh1aEO+m+PCoQ7ugFE+7o0IpwnJx6qfHEKH\/rRgaspz\/GIveObRb54kX34FVxkYeVFmkkyDUYLGee96UwyN6xjQB58Qps+QLtDk+YdocvrWgXYkv74AY7yn4lNzTohzY8eXTUPdjP6PoCXUBAV\/q7Kk\/epD2wWsE+fhL02T95YUOf473u\/lGBPscHTJ\/jfSv6cEiJE\/\/falo9Efq8tFKLjl90X74s0AeYiehzsFfpYr+gkoo1XOz7Ry\/3bJZ50n11ki3zsPuK7if625YNYHXk2b4K5SZxwtb+i5f7FhR4eYAWVoECh5oCB1YUiKQ7BXtSb\/Fl\/9p0RN4MEljdQS+PuydHBRLsnTAJ4G8LEuyvn9f3j6x2+hVurlkmGDhozAn6u8qR\/o\/Ud2\/P53siNrCOveMTi3WcgDL+qriOfb2O\/cpn9sNEbdaZ3XvxyoYCR93jvQIFjg+ZAsd2CidmhfyILnjUnDgS\/IhU2Hp1YsOtJyfdgyK3Huo1Hh5ayiU0tj6oMRZ+PJrToQHqnBzbcMCrve7RcYE6BwdMnYP9Smf5LzNVMo+ywAMb\/ewVHPKTwgL3XvIC9+zsgp5SgXRCEFNO8rVYBi9fvrAh7IviZbffPabLjv6uqvj+onPGHlN4HB8c2yzymIzvbJHktxT0t53bIRz8jDBUnp9QStff09H4aTDB0Qsr+rwk11VGn\/2XTJ\/9l5Wtwx9lHH\/ABpob4bU8tFr9q+5+Ljz3uiek9NPfVtdnIXfepK1naeWPscrD\/QMbx\/beXnevsMq9PV7lno0F1+12qVQ6hn88B0cMRStQvRx7S3RCmUmDmElRKgeyFsUQb2xjiLv7LzCE+ErsH5weHJoGWZ5GtMaEm4PO\/osXxYzeU3HymKHGfVDsTg6WhRpf5qHGg+Ojl0crhRoPjk8OXliEGlHJeA41bkCo8WCPr6T9V7Yhli80DHd0eGwjdZhehnpwvZGxBAz9BOK0By+sDIKDV5jiZ5Z40j0hleWEXAFVHJLFWpvNcOgfHllG0gpbfNI9OuH1H+19zUGmg5c21vKL42IU8mX3BXmMXnYPX1QI33K3wicUxAXpaeVPO3pRVIeBKkdMnYOTLz1U9OrIRpE+3qdDluU4HOgch\/0Xdb1te2fRIG7Oat7aP7aLeb3svtwrZjHoWKulq\/8Jx7yOTmwOwsvD7nEx5vXyJce8Xh48\/WDQgVUmw8uT7osXxajfi0pRv412re9beY5ODsgTllFgT1Ngb+\/Z73ivyWvleDw5poOURdle7nOU7fjkafucXlllkL3a674ohjM4Ue4A812ehNv18MTOaX\/yohiVeKWjEi83PipxvGe1wKPu\/kHBb3qi\/cqWnsMn7Fd+8erQzu9eSKfY1zfoPiVPfp15knZJGK9KaZJ73eNj9tUe29ENy1SuTbnTTzIewx38ZNKRLD32L\/YL9DnS9Dk6\/rKDwftW6QBYJPGy6Ok\/0J5+O70VWxN+SWfOQtg\/h0+eVPhEg2FQtR8h71B1mikLhVsDuyOfBYGJr5iSr5ETOgOukFMhgaFo9Ehi9rmKdhe09rGu7DYFd1gK6LuSIEeo3a+TA6+4KqaQjlFNsas0OZ87WFA74crxHCkCAUVGWBiO1XnUhFpxoRt1XTBrfZsmc+V9XJFIJYxUbi\/iaZzIEY3eyTFClpbiB\/6tzGI2HSIAltke7OmCQV2Wj6W\/4hc\/Th3swnqrW1hjywVGOqEVT8tLphXHenuAeAYpYYAwOZ+Trvgos6bVGpsVtscdYn9gGihyCJqZ3p1HTgxp8+874u+XH0oAK4ugCswgph8UkGssnD5+WsLb6HHvcNwhGJYmF+Kn+AWsiKToEBZr4sMq3KGt8yQiz0RThnpaiIrwyzsmGlau0kdce9zhcmPEA+lw2yfs1r2oyjdOfQ3PpIuUQwqQEBpKiYnzHu2x7j6V4uAO6poMjuOHOwGRGcsniCmlOwz931Ms6S3PXjPd3FHRMEmIFAQHrVx\/6xP+waKS2JEfIdpCD\/\/AynM41INeoAZU47i7f4D\/r2vE5Y5Kkx3V34EV7\/SUO4x3v\/n+Rn8mruBMXPWJoG\/xMypTH+Ppu8xxbUwDXoNvg6fKVMfj3uJyLsVQjQ2CBwIp0Xl00yiiY0YrwRnS4LEut\/UT5srCu3qSwFUWBnOBQGMFY\/iFkmXz1VE2Sxn+pqYsIYAPpoQnNILDHiMiCK0U5swV130\/Kq8UK5qLVcJZsXSHq62RPwdDwuPJlouLypaDlbWFI0SF\/ig8dAU0f\/T\/Aw==\" \/> \t\t<a href=\"https:\/\/www.pdf24.org\" target=\"_blank\" title=\"www.pdf24.org\" rel=\"nofollow\"><img src=\"http:\/\/www.mirandabanda.org\/cogblog\/wp-content\/plugins\/pdf24-post-to-pdf\/img\/pdf_32x32.png\" alt=\"\" border=\"0\" height=\"32\" \/><\/a> \t\t<span class=\"pdf24Plugin-cp-space\">&nbsp;&nbsp;<\/span> \t\t<span class=\"pdf24Plugin-cp-text\">Send article as PDF<\/span> \t\t<span class=\"pdf24Plugin-cp-space\">&nbsp;&nbsp;<\/span> \t\t<input class=\"pdf24Plugin-cp-input\" style=\"margin: 0px;\" type=\"text\" name=\"sendEmailTo\" placeholder=\"Enter email address\" \/> \t\t<input class=\"pdf24Plugin-cp-submit\" style=\"margin: 0px;\" type=\"submit\" value=\"Send\" \/> \t<\/form> <\/div>","protected":false},"excerpt":{"rendered":"<p>Nobody expects the Smalltalk language system. Our chief weapon is polymorphism&#8230; polymorphism and objects&#8230;objects and polymorphism. Our two weapons are objects and polymorphism&#8230; and inheritance&#8230; Our three weapons are objects, and polymorphism and inheritance&#8230; and an almost fanatical devotion to contexts&#8230; Our four&#8230;no&#8230; Amongst our weapons&#8230; Amongst our weaponry&#8230; are such elements as objects, po&#8230; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/18"}],"collection":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":12,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"predecessor-version":[{"id":389,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/posts\/18\/revisions\/389"}],"wp:attachment":[{"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.mirandabanda.org\/cogblog\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}