<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Hi Stef,<br></div><div><br>On Nov 24, 2015, at 12:00 PM, stepharo &lt;<a href="mailto:stepharo@free.fr">stepharo@free.fr</a>&gt; wrote:<br><br></div><blockquote type="cite"><div>
  
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  
  
    Thanks for this great explanation and yes I know about this cache
    but I do not why<br>
    I was wondering that we did not need to update it from the image. <br>
    Now I would like to add such comment inside the system because I
    like self explanation. <br>
    <br>
    "See Object documentation whatIsAPrimitive." gets frustrates me. <br></div></blockquote><div><br></div>It's still appropriate to explain to newbies what primitives are and how they are invoked. &nbsp;Interesting to consider what the minimum knowledge programmers have when first using the system. &nbsp;Do they know, for example, that methods contain bytecode for a stack machine, or that underneath the system is a virtual machine containing a bytecode execution engine, a set of primitives and (a) garbage collector(s)?<div><br><blockquote type="cite"><div>So I imagine that is Behavior flushCache flushing for the class in
    the class,selector pair.<br></div></blockquote><div><br></div>Again because of inheritance the VM can't just flush entries for a specific class, so the VM responds to Behavior&gt;&gt;flushCache flushes the entire cache.</div><div><br><blockquote type="cite"><div>
    What would be a good place to add such comment? MethodDictionary. It
    sounds reasonable to me but tell me.<br></div></blockquote><div><br></div>If the comments in the various flushCache implementations are correct and reference each other then I think that's enough.</div><div><br><blockquote type="cite"><div>TBehavior &gt;&gt; flushCache<br>
    &nbsp;&nbsp;&nbsp; "Tell the interpreter to remove the contents of its method
    lookup cache, if it has <br>
    &nbsp;&nbsp;&nbsp; one.&nbsp; Essential.&nbsp; See Object documentation whatIsAPrimitive."<br>
    <br>
    &nbsp;&nbsp;&nbsp; &lt;primitive: 89&gt;<br>
    &nbsp;&nbsp;&nbsp; self primitiveFailed<br></div></blockquote><div><br></div>I would rewrite this to say</div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">"Tell the virtual machine to remove the contents of its method lookup caches, if it has&nbsp;</span><span style="background-color: rgba(255, 255, 255, 0);">any. &nbsp;This must be done when the system modifies the class hierarchy so that message lookups reflect the revised organization. &nbsp;c.f. Symbol&gt;&gt;flushCache &amp; CompiledMethod&gt;&gt;flushCache. &nbsp;Essential.&nbsp; See Object documentation whatIsAPrimitive."</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><blockquote type="cite"><div>Symbol &gt;&gt; flushCache<br>
    &nbsp;&nbsp;&nbsp; "Tell the interpreter to remove all entries with this symbol as
    a selector from its method lookup cache, if it has one.&nbsp; This
    primitive must be called whenever a method is redefined or removed.<br>
    &nbsp;&nbsp;&nbsp; NOTE:&nbsp; Only one of the two selective flush methods (Symbol or
    CompiledMethod) needs to be used."<br>
    <br>
    &nbsp;&nbsp;&nbsp; &lt;primitive: 119&gt;<br></div></blockquote><div><br></div><div><span style="background-color: rgba(255, 255, 255, 0);">I would rewrite this to say</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><span style="background-color: rgba(255, 255, 255, 0);">"Tell the virtual machine to remove&nbsp;all entries with this symbol as a selector from its&nbsp;method lookup caches, if it has&nbsp;any. &nbsp;This must be done&nbsp;whenever a method is added, redefined or removed, so that message lookups reflect the revised organization. &nbsp;c.f. Behavior&gt;&gt;flushCache &amp; CompiledMethod&gt;&gt;flushCache. &nbsp;Essential.&nbsp; See Object documentation whatIsAPrimitive."</span><br><br><br><blockquote type="cite"><div>CompiledMethod &gt;&gt; flushCache<br>
    &nbsp;&nbsp;&nbsp; "Tell the interpreter to remove all references to this method
    from its method lookup cache, if it has one. This primitive must be
    called whenever a method is redefined or removed.<br>
    &nbsp;&nbsp;&nbsp; NOTE:&nbsp; Only one of two selective flush methods (Symbol or
    CompiledMethod) needs to be used."<br>
    <br>
    &nbsp;&nbsp;&nbsp; &lt;primitive: 116&gt;<br></div></blockquote><div><br></div><div><div><span style="background-color: rgba(255, 255, 255, 0);">I would rewrite this to say</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><span style="background-color: rgba(255, 255, 255, 0);">"Tell the virtual machine to remove&nbsp;all references to this method from&nbsp;its&nbsp;method lookup caches, and to discard any optimized version of the method, if it has&nbsp;any of these. &nbsp;This must be done&nbsp;whenever a method is modified in place, such as modifying its literals or machine code, to reflect the revised code. &nbsp;c.f. Behavior&gt;&gt;flushCache &amp; Symbol&gt;&gt;flushCache. &nbsp;Essential.&nbsp; See Object documentation whatIsAPrimitive."</span><span style="background-color: rgba(255, 255, 255, 0);">&nbsp;</span></div><div><br></div><br><blockquote type="cite"><div><div class="moz-cite-prefix">Le 24/11/15 19:10, Eliot Miranda a
      écrit&nbsp;:<br>
    </div>
    <blockquote cite="mid:CAC20JE0yTDwd93yBSbX2Z_Larx_g7oAvG5X93kTf0_Axj1xarQ@mail.gmail.com" type="cite">
      <div dir="ltr">Hi Stephane,
        <div><br>
        </div>
        <div>&nbsp; &nbsp; the VM caches method lookups in a lookup cache from
          class,selector pairs to method,primitive pairs, where
          primitive may be null.&nbsp; This is called the first-level method
          lookup cache.&nbsp; The JIT VM caches message lookups in machine
          code, so that a particular piece of machine code exists in a
          state that invokes a method for a specific class very fast by
          embedding the class reference in a register load and the
          target method in a call instruction, and having the target
          method verify this "cache probe" (this is an "in-line cache).&nbsp;
          The JIT also caches the translation of a byte coded method to
          machine code, by hiding a reference to a machine code method
          in a byte coded method.</div>
        <div><br>
        </div>
        <div>These caches can be invalidated in several circumstances:</div>
        <div><br>
        </div>
        <div>1a. if one adds or removes a method from a class's method
          dictionary it may change the correct results of a lookup not
          merely of the class whose dictionary was updated but also
          subclasses of the class.</div>
        <div>1b. if one replaces a method in a method dictionary this
          changes the target method for a lookup of the selector for the
          class and subclasses</div>
        <div><br>
        </div>
        <div>2. if one wants to rewrite the byte code or literals of a
          method, for example because a Slot definition has changed,
          then if the method has been compiled to machine code, the
          machine code must be discarded before the new code may be
          executed</div>
        <div><br>
        </div>
        <div>1a &amp; 1b are done via Symbol&gt;&gt;flushCache.&nbsp; In
          response the normal VM flushes its first-level method lookup
          cache, and the JIT also scans all of machine code looking for
          inline caches with that selector, and voiding them, reverting
          each send site for that selector to the "unlinked" state.</div>
        <div><br>
        </div>
        <div>There used to be confusion in Squeak, which Pharo
          inherited, that using CompiledMethod&gt;&gt;flushCache was
          somehow the right way to void caches when updating method
          dictionaries, flushing the old method in the dictionary, if
          any, and the new method.&nbsp; It isn't, precisely because adding
          or removing methods affects the visibility of inherited
          methods with the same selector.&nbsp; So MethodDictionary code
          should use Symbol&gt;&gt;flushCache, and only once, on each
          update of a method dictionary.&nbsp; As a result, the VM will
          ensure that the necessary send caches are flushed for that
          selector.<br>
        </div>
        <div><br>
        </div>
        <div>2. is done via CompiledMethod&gt;&gt;flushCache.&nbsp; In
          response the VM searches the first-level method lookup cache
          and removes all entries whose target is the method.&nbsp; In
          addition the JIT discards the machine code for the method, and
          searches for all send sites with that method's machine code as
          the target and voids them, reverting them to the unlinked
          state.</div>
        <div><br>
        </div>
        <div>The VM must be told to flush the cached state for a
          compiled method via CompiledMethod&gt;&gt;flushCache and will
          /try/ and void the state for that method.&nbsp; But it can't always
          deal with existing activations of that method, because if
          there are activations running the machine code, that machine
          code can't merely be thrown away, and can't be replaced
          because its length may change, depending on literals or byte
          codes.&nbsp; So this kind of byte coded method manipulation needs
          to be done with case and some understanding of the total
          system state.</div>
        <div><br>
        </div>
        <div>HTH</div>
        <div><br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Tue, Nov 24, 2015 at 9:37 AM,
          stepharo <span dir="ltr">&lt;<a moz-do-not-send="true" href="mailto:stepharo@free.fr" target="_blank">stepharo@free.fr</a>&gt;</span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Clement<br>
            <br>
            do you know what is flushCache and why we need to invoke it?<br>
            <br>
            Stef</blockquote></div>
        <div class="gmail_signature">
          <div dir="ltr">
            <div><span style="font-size:small;border-collapse:separate">
                <div>_,,,^..^,,,_<br>
                </div>
                <div>best,&nbsp;Eliot</div></span></div></div></div></div></blockquote></div></blockquote><div><span style="background-color: rgba(255, 255, 255, 0);"><br>_,,,^..^,,,_ (phone)</span></div></div></body></html>