Bug 136055 - DFG::freezeFragile should register the frozen value's structure
Summary: DFG::freezeFragile should register the frozen value's structure
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Filip Pizlo
URL:
Keywords:
Depends on: 133426 135750
Blocks:
  Show dependency treegraph
 
Reported: 2014-08-18 17:53 PDT by Filip Pizlo
Modified: 2015-07-01 18:31 PDT (History)
8 users (show)

See Also:


Attachments
the patch (4.12 KB, patch)
2015-06-30 16:36 PDT, Filip Pizlo
ggaren: review+
Details | Formatted Diff | Diff
the patch (5.46 KB, patch)
2015-07-01 18:09 PDT, Filip Pizlo
mark.lam: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Filip Pizlo 2014-08-18 17:53:18 PDT
...
Comment 1 Filip Pizlo 2015-06-30 16:33:13 PDT
I believe that we previously did not do this because of the suspicion that it might be worthwhile to sometimes track a value without tracking its structure.  But right now all users of freeze() will eventually register the value's structure, except in cases where they obviously should but they obviously don't.  That causes bugs.  It would be easier to just make freeze() always register the structure and then not have any doubts about whose responsibility it is.
Comment 2 Filip Pizlo 2015-06-30 16:36:54 PDT
Created attachment 255873 [details]
the patch
Comment 3 Geoffrey Garen 2015-07-01 10:51:24 PDT
Comment on attachment 255873 [details]
the patch

r=me
Comment 4 Mark Lam 2015-07-01 11:11:02 PDT
Comment on attachment 255873 [details]
the patch

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

> Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp:55
>          for (FrozenValue* value : m_graph.m_frozenValues)
> -            registerStructure(value->structure());
> +            m_graph.assertIsRegistered(value->structure());

According to Graph::freezeFragile() and FrozenValue::freeze(), we can freeze non-cell values.  In those cases, value->structure() is a nullptr.  Is this assertion valid without a nullcheck on value->structure() first?  In Graph::assertIsRegistered(), it looks like it will deref the passed in structure without any checks.
Comment 5 Filip Pizlo 2015-07-01 11:21:40 PDT
(In reply to comment #4)
> Comment on attachment 255873 [details]
> the patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=255873&action=review
> 
> > Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp:55
> >          for (FrozenValue* value : m_graph.m_frozenValues)
> > -            registerStructure(value->structure());
> > +            m_graph.assertIsRegistered(value->structure());
> 
> According to Graph::freezeFragile() and FrozenValue::freeze(), we can freeze
> non-cell values.  In those cases, value->structure() is a nullptr.  Is this
> assertion valid without a nullcheck on value->structure() first?  In
> Graph::assertIsRegistered(), it looks like it will deref the passed in
> structure without any checks.

Wow, good catch!  It turns out that this works because assertIsRegistered() returns early before the end of the structure registration phase.  So this is just a broken no-op!  I'll fix and post a new patch.
Comment 6 Filip Pizlo 2015-07-01 18:08:43 PDT
(In reply to comment #5)
> (In reply to comment #4)
> > Comment on attachment 255873 [details]
> > the patch
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=255873&action=review
> > 
> > > Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp:55
> > >          for (FrozenValue* value : m_graph.m_frozenValues)
> > > -            registerStructure(value->structure());
> > > +            m_graph.assertIsRegistered(value->structure());
> > 
> > According to Graph::freezeFragile() and FrozenValue::freeze(), we can freeze
> > non-cell values.  In those cases, value->structure() is a nullptr.  Is this
> > assertion valid without a nullcheck on value->structure() first?  In
> > Graph::assertIsRegistered(), it looks like it will deref the passed in
> > structure without any checks.
> 
> Wow, good catch!  It turns out that this works because assertIsRegistered()
> returns early before the end of the structure registration phase.  So this
> is just a broken no-op!  I'll fix and post a new patch.

And this revealed a bug.  freezeFragile() was loading the structure and registering it, but then the act of freezing would load the structure a second time.  That was racy.  The fix is to load the structure only once.

Posting new patch now...
Comment 7 Filip Pizlo 2015-07-01 18:09:06 PDT
Created attachment 255979 [details]
the patch
Comment 8 Mark Lam 2015-07-01 18:23:42 PDT
Comment on attachment 255979 [details]
the patch

r=me
Comment 9 Filip Pizlo 2015-07-01 18:31:56 PDT
Landed in http://trac.webkit.org/changeset/186215