<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>121519</bug_id>
          
          <creation_ts>2013-09-17 14:20:49 -0700</creation_ts>
          <short_desc>DFG doesn&apos;t properly keep scope alive for op_put_to_scope</short_desc>
          <delta_ts>2014-04-29 15:32:28 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>REOPENED</bug_status>
          <resolution></resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Mark Hahnenberg">mhahnenberg</reporter>
          <assigned_to name="Mark Hahnenberg">mhahnenberg</assigned_to>
          <cc>commit-queue</cc>
    
    <cc>fpizlo</cc>
    
    <cc>ggaren</cc>
    
    <cc>msaboff</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>930390</commentid>
    <comment_count>0</comment_count>
    <who name="Mark Hahnenberg">mhahnenberg</who>
    <bug_when>2013-09-17 14:20:49 -0700</bug_when>
    <thetext>This was a latent bug that can&apos;t actually occur in ToT. It was uncovered by causing slow path calls in the baseline JIT for op_put_to_scope in places where we couldn&apos;t before (but which were necessary for gen GC).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930393</commentid>
    <comment_count>1</comment_count>
      <attachid>211940</attachid>
    <who name="Mark Hahnenberg">mhahnenberg</who>
    <bug_when>2013-09-17 14:22:26 -0700</bug_when>
    <thetext>Created attachment 211940
Patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930416</commentid>
    <comment_count>2</comment_count>
      <attachid>211940</attachid>
    <who name="WebKit Commit Bot">commit-queue</who>
    <bug_when>2013-09-17 14:56:23 -0700</bug_when>
    <thetext>Comment on attachment 211940
Patch

Clearing flags on attachment: 211940

Committed r156003: &lt;http://trac.webkit.org/changeset/156003&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930417</commentid>
    <comment_count>3</comment_count>
    <who name="WebKit Commit Bot">commit-queue</who>
    <bug_when>2013-09-17 14:56:24 -0700</bug_when>
    <thetext>All reviewed patches have been landed.  Closing bug.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930486</commentid>
    <comment_count>4</comment_count>
      <attachid>211940</attachid>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2013-09-17 19:05:16 -0700</bug_when>
    <thetext>Comment on attachment 211940
Patch

Thanks for the fix. 

I think we need to go even further. I think we need a Phantom after op_get_from_scope and op_put_to_scope, and we need it regardless of the get/put kind. The bytecode implies that the output scope from op_resolve_scope is live until after op_get_from_scope / op_put_to_scope.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930487</commentid>
    <comment_count>5</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2013-09-17 19:05:39 -0700</bug_when>
    <thetext>Reopening to track a more complete fix.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930489</commentid>
    <comment_count>6</comment_count>
      <attachid>211940</attachid>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2013-09-17 19:39:13 -0700</bug_when>
    <thetext>Comment on attachment 211940
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=211940&amp;action=review

&gt; Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:3125
&gt;                  addToGraph(PutGlobalVar, OpInfo(operand), get(value));
&gt; +                // Keep scope alive until after put.
&gt; +                addToGraph(Phantom, get(scope));

PutGlobalVar doesn&apos;t exit, right?  So you could have had the Phantom before the PutGlobalVar, probably.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930490</commentid>
    <comment_count>7</comment_count>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2013-09-17 19:41:53 -0700</bug_when>
    <thetext>(In reply to comment #4)
&gt; (From update of attachment 211940 [details])
&gt; Thanks for the fix. 
&gt; 
&gt; I think we need to go even further. I think we need a Phantom after op_get_from_scope and op_put_to_scope, and we need it regardless of the get/put kind. The bytecode implies that the output scope from op_resolve_scope is live until after op_get_from_scope / op_put_to_scope.

Some put/get kinds already keep the scope alive by virtue of using it.  I think PutClosureVar is an example.  

GetClosureVar doesn&apos;t need to keep anything alive because there is no way to exit between GetClosureRegisters and GetClosureVar.  If CSE kills the GetClosureRegisters, it will already correctly replace it with a Phantom.

Mark&apos;s fix may very well be the only place where we need this, and since handlePutByOffset may exit and there were no other uses of the scope; PutGlobalVar won&apos;t exit but that case also otherwise has no Phantoms on the scope.

There is some small benefit to not adding Phantoms for those that already keep things alive appropriately, because each Phantom puts a constraint on the register allocator.  It won&apos;t matter in the FTL but it will matter in the DFG.  So, it wouldn&apos;t be wrong to take a conservative approach and sprinkle Phantom&apos;s everywhere.  But I would resist the temptation if there is a way to reason through this and have fewer Phantoms.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930508</commentid>
    <comment_count>8</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2013-09-17 21:31:34 -0700</bug_when>
    <thetext>These remaining cases can exit unsafely:

op_get_from_scope+GlobalProperty -- structure check failure
op_get_from_scope+GlobalPropertyWithVarInjectionChecks -- structure check failure
op_get_from_scope+GlobalVar -- global var watchpoint
op_get_from_scope+GlobalVarWithVarInjectionChecks -- global var watchpoint

FWIW, I found it difficult to reason through the side-effects and guarantee that other Phantoms were not necessary.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930518</commentid>
    <comment_count>9</comment_count>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2013-09-17 22:05:16 -0700</bug_when>
    <thetext>(In reply to comment #8)
&gt; These remaining cases can exit unsafely:
&gt; 
&gt; op_get_from_scope+GlobalProperty -- structure check failure
&gt; op_get_from_scope+GlobalPropertyWithVarInjectionChecks -- structure check failure
&gt; op_get_from_scope+GlobalVar -- global var watchpoint
&gt; op_get_from_scope+GlobalVarWithVarInjectionChecks -- global var watchpoint

Interesting.  FWIW, I find these investigations useful.  In addition to having to reason about liveness during an exit, it&apos;s worthwhile to reason about these things to ensure that you don&apos;t emit nodes for a bytecode instruction that do the following:

1: Foo(..., bc#42) // performs an observable side-effect
2: Bar(..., bc#42) // exits backwards



&gt; 
&gt; FWIW, I found it difficult to reason through the side-effects and guarantee that other Phantoms were not necessary.

I guess I don&apos;t find it as difficult.  But I have to think about it a lot.

We could definitely fix this by introducing the following rules:

- Bytecode parser *always* inserts phantoms at the points where bytecode kills operands.  The best way to do this is to run Mark&apos;s liveness analysis and whenever that analysis says something is killed, we put a Phantom.  This minimizes the Phantoms and means that we don&apos;t need any more Phantoms inserted anywhere in the DFG.

- Have a DFG phase that hoists Phantoms.  This will run very late in the pipeline and never in FTL mode.  It will run just before virtual register allocation.  It will just take each Phantom and put it just below the last node that exited.  We could even go further and annotate nodes that exit with the set of nodes that must be alive right before them.  This will mean that a Phantom will indicate that the last node prior to the Phantom, that exits, also kills the thing that the Phantom is trying to keep alive.

Something like would definitely make our IR easier to reason about.  But, as with all things we&apos;ve ever done to make our IR easier to think about, it will probably be a compile-time regression. :-)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>930690</commentid>
    <comment_count>10</comment_count>
    <who name="Geoffrey Garen">ggaren</who>
    <bug_when>2013-09-18 11:41:04 -0700</bug_when>
    <thetext>&gt; - Bytecode parser *always* inserts phantoms at the points where bytecode kills operands.  

I like this idea, actually. Nice and automatic.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>211940</attachid>
            <date>2013-09-17 14:22:26 -0700</date>
            <delta_ts>2013-09-17 19:39:13 -0700</delta_ts>
            <desc>Patch</desc>
            <filename>bug-121519-20130917142132.patch</filename>
            <type>text/plain</type>
            <size>2092</size>
            <attacher name="Mark Hahnenberg">mhahnenberg</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTU1OTk3KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDE3IEBA
CisyMDEzLTA5LTE3ICBNYXJrIEhhaG5lbmJlcmcgIDxtaGFobmVuYmVyZ0BhcHBsZS5jb20+CisK
KyAgICAgICAgREZHIGRvZXNuJ3QgcHJvcGVybHkga2VlcCBzY29wZSBhbGl2ZSBmb3Igb3BfcHV0
X3RvX3Njb3BlCisgICAgICAgIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9p
ZD0xMjE1MTkKKworICAgICAgICBSZXZpZXdlZCBieSBOT0JPRFkgKE9PUFMhKS4KKworICAgICAg
ICBUaGlzIHdhcyBhIGxhdGVudCBidWcgdGhhdCBjYW4ndCBhY3R1YWxseSBvY2N1ciBpbiBUb1Qu
IEl0IHdhcyB1bmNvdmVyZWQgYnkgY2F1c2luZyBzbG93IAorICAgICAgICBwYXRoIGNhbGxzIGlu
IHRoZSBiYXNlbGluZSBKSVQgZm9yIG9wX3B1dF90b19zY29wZSBpbiBwbGFjZXMgd2hlcmUgd2Ug
Y291bGRuJ3QgYmVmb3JlIChidXQgCisgICAgICAgIHdoaWNoIHdlcmUgbmVjZXNzYXJ5IGZvciBn
ZW4gR0MpLgorCisgICAgICAgICogZGZnL0RGR0J5dGVDb2RlUGFyc2VyLmNwcDoKKyAgICAgICAg
KEpTQzo6REZHOjpCeXRlQ29kZVBhcnNlcjo6cGFyc2VCbG9jayk6CisKIDIwMTMtMDktMTcgIEZp
bGlwIFBpemxvICA8ZnBpemxvQGFwcGxlLmNvbT4KIAogICAgICAgICBEb24ndCBHQyB3aGlsZSBP
U1IgY29tcGlsaW5nCkluZGV4OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR0J5dGVDb2Rl
UGFyc2VyLmNwcAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR0J5
dGVDb2RlUGFyc2VyLmNwcAkocmV2aXNpb24gMTU1ODk1KQorKysgU291cmNlL0phdmFTY3JpcHRD
b3JlL2RmZy9ERkdCeXRlQ29kZVBhcnNlci5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTMxMTIsNiAr
MzExMiw4IEBAIGJvb2wgQnl0ZUNvZGVQYXJzZXI6OnBhcnNlQmxvY2sodW5zaWduZWQKICAgICAg
ICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgTm9kZSogYmFzZSA9IGNlbGxDb25zdGFudFdp
dGhTdHJ1Y3R1cmVDaGVjayhnbG9iYWxPYmplY3QsIHN0YXR1cy5vbGRTdHJ1Y3R1cmUoKSk7CiAg
ICAgICAgICAgICAgICAgaGFuZGxlUHV0QnlPZmZzZXQoYmFzZSwgaWRlbnRpZmllck51bWJlciwg
c3RhdGljX2Nhc3Q8UHJvcGVydHlPZmZzZXQ+KG9wZXJhbmQpLCBnZXQodmFsdWUpKTsKKyAgICAg
ICAgICAgICAgICAvLyBLZWVwIHNjb3BlIGFsaXZlIHVudGlsIGFmdGVyIHB1dC4KKyAgICAgICAg
ICAgICAgICBhZGRUb0dyYXBoKFBoYW50b20sIGdldChzY29wZSkpOwogICAgICAgICAgICAgICAg
IGJyZWFrOwogICAgICAgICAgICAgfQogICAgICAgICAgICAgY2FzZSBHbG9iYWxWYXI6CkBAIC0z
MTE5LDYgKzMxMjEsOCBAQCBib29sIEJ5dGVDb2RlUGFyc2VyOjpwYXJzZUJsb2NrKHVuc2lnbmVk
CiAgICAgICAgICAgICAgICAgU3ltYm9sVGFibGVFbnRyeSBlbnRyeSA9IGdsb2JhbE9iamVjdC0+
c3ltYm9sVGFibGUoKS0+Z2V0KHVpZCk7CiAgICAgICAgICAgICAgICAgQVNTRVJUKCFlbnRyeS5j
b3VsZEJlV2F0Y2hlZCgpIHx8ICFtX2dyYXBoLndhdGNocG9pbnRzKCkuaXNTdGlsbFZhbGlkKGVu
dHJ5LndhdGNocG9pbnRTZXQoKSkpOwogICAgICAgICAgICAgICAgIGFkZFRvR3JhcGgoUHV0R2xv
YmFsVmFyLCBPcEluZm8ob3BlcmFuZCksIGdldCh2YWx1ZSkpOworICAgICAgICAgICAgICAgIC8v
IEtlZXAgc2NvcGUgYWxpdmUgdW50aWwgYWZ0ZXIgcHV0LgorICAgICAgICAgICAgICAgIGFkZFRv
R3JhcGgoUGhhbnRvbSwgZ2V0KHNjb3BlKSk7CiAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAg
ICAgICAgICB9CiAgICAgICAgICAgICBjYXNlIENsb3N1cmVWYXI6Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>