Bug 143999

Summary: Remove AllocationProfileWatchpoint node
Product: WebKit Reporter: Basile Clement <basile_clement>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Enhancement CC: commit-queue, fpizlo, ggaren, msaboff
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 144000    
Attachments:
Description Flags
Tentative patch, non thread-safe
none
Patch w/ GC safety
none
Rebased patch none

Description Basile Clement 2015-04-21 10:52:56 PDT
Patch forthcoming.
Comment 1 Basile Clement 2015-04-21 11:18:14 PDT
Created attachment 251246 [details]
Tentative patch, non thread-safe
Comment 2 Basile Clement 2015-04-21 11:22:38 PDT
Comment on attachment 251246 [details]
Tentative patch, non thread-safe

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

> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:2643
>                  if (Structure* structure = function->allocationStructure()) {

We probably need to freeze the rare data here, in case it is removed by the JS thread and then the GC runs at that point.
Not sure how to do this, I first need to investigate more deeply how freeze() & the GC works.
Comment 3 Filip Pizlo 2015-04-21 11:31:30 PDT
Comment on attachment 251246 [details]
Tentative patch, non thread-safe

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

>> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:2643
>>                  if (Structure* structure = function->allocationStructure()) {
> 
> We probably need to freeze the rare data here, in case it is removed by the JS thread and then the GC runs at that point.
> Not sure how to do this, I first need to investigate more deeply how freeze() & the GC works.

It seems that you're using JSFunction's helpers to get things from the rare data.  I would make this explicit here, so instead of function->allocationStructure() you'd do something like rareData->allocationStructure().  And instead of function->allocationProfileWatchpointSet() you'd do rareData->allocationProfileWatchpointSet().

Then you'd do:

FunctionRareData* rareData = function->rareData();
if (rareData) {
    if (Structure* structure = rareData->structure()) {
        m_graph.freeze(rareData);
        m_graph.watchpoints().addLazily(rareData->allocationProfileWatchpointSet()); // note that here you don't have to do any null checking - you know that rareData has the InlineWatchpointSet in place rather than via pointer.
        ... the rest
    }
}
Comment 4 Basile Clement 2015-04-21 11:45:31 PDT
(In reply to comment #3)
> Comment on attachment 251246 [details]
> Tentative patch, non thread-safe
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=251246&action=review
> 
> >> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:2643
> >>                  if (Structure* structure = function->allocationStructure()) {
> > 
> > We probably need to freeze the rare data here, in case it is removed by the JS thread and then the GC runs at that point.
> > Not sure how to do this, I first need to investigate more deeply how freeze() & the GC works.
> 
> It seems that you're using JSFunction's helpers to get things from the rare
> data.  I would make this explicit here, so instead of
> function->allocationStructure() you'd do something like
> rareData->allocationStructure().  And instead of
> function->allocationProfileWatchpointSet() you'd do
> rareData->allocationProfileWatchpointSet().

I had this discussion with Michael yesterday who told me keeping the accessors would be better, but that is indeed problematic here. I will change that.

> 
> Then you'd do:
> 
> FunctionRareData* rareData = function->rareData();
> if (rareData) {
>     if (Structure* structure = rareData->structure()) {
>         m_graph.freeze(rareData);

Right, the m_graph.freeze(rareData) was the thing I was not sure would be sufficient (thought I needed to store it somewhere).
Shouldn't it rather be:

if (rareData) {
    m_graph.freeze(rareData);
    if (Structure* structure = rareData->structure()) {
      ...
    }
}

in case the rare data is deallocated in between the two ifs (this shouldn't matter after https://bugs.webkit.org/show_bug.cgi?id=144000 is taken care of)?

Thanks!
Comment 5 Filip Pizlo 2015-04-21 11:48:00 PDT
(In reply to comment #4)
> (In reply to comment #3)
> > Comment on attachment 251246 [details]
> > Tentative patch, non thread-safe
> > 
> > View in context:
> > https://bugs.webkit.org/attachment.cgi?id=251246&action=review
> > 
> > >> Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:2643
> > >>                  if (Structure* structure = function->allocationStructure()) {
> > > 
> > > We probably need to freeze the rare data here, in case it is removed by the JS thread and then the GC runs at that point.
> > > Not sure how to do this, I first need to investigate more deeply how freeze() & the GC works.
> > 
> > It seems that you're using JSFunction's helpers to get things from the rare
> > data.  I would make this explicit here, so instead of
> > function->allocationStructure() you'd do something like
> > rareData->allocationStructure().  And instead of
> > function->allocationProfileWatchpointSet() you'd do
> > rareData->allocationProfileWatchpointSet().
> 
> I had this discussion with Michael yesterday who told me keeping the
> accessors would be better, but that is indeed problematic here. I will
> change that.
> 
> > 
> > Then you'd do:
> > 
> > FunctionRareData* rareData = function->rareData();
> > if (rareData) {
> >     if (Structure* structure = rareData->structure()) {
> >         m_graph.freeze(rareData);
> 
> Right, the m_graph.freeze(rareData) was the thing I was not sure would be
> sufficient (thought I needed to store it somewhere).
> Shouldn't it rather be:
> 
> if (rareData) {
>     m_graph.freeze(rareData);
>     if (Structure* structure = rareData->structure()) {
>       ...
>     }
> }
> 
> in case the rare data is deallocated in between the two ifs (this shouldn't
> matter after https://bugs.webkit.org/show_bug.cgi?id=144000 is taken care
> of)?

It's safe to assume that a GC cannot happen during a DFG phase.  The parser counts as a phase.  Hence, you only need to freeze it if you decide that you'll be using it after parsing completes - i.e. exactly if/when you addLazily().

> 
> Thanks!
Comment 6 Basile Clement 2015-04-21 12:23:58 PDT
Created attachment 251254 [details]
Patch w/ GC safety
Comment 7 Filip Pizlo 2015-04-21 12:28:02 PDT
You should rebase your patch.  svn up and all.
Comment 8 Basile Clement 2015-04-21 12:35:25 PDT
Created attachment 251256 [details]
Rebased patch
Comment 9 WebKit Commit Bot 2015-04-21 13:24:58 PDT
Comment on attachment 251256 [details]
Rebased patch

Clearing flags on attachment: 251256

Committed r183073: <http://trac.webkit.org/changeset/183073>
Comment 10 WebKit Commit Bot 2015-04-21 13:25:02 PDT
All reviewed patches have been landed.  Closing bug.