⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 245071 in webkit


Ignore:
Timestamp:
May 8, 2019, 3:19:26 PM (7 years ago)
Author:
ysuzuki@apple.com
Message:

Invalid DFG JIT genereation in high CPU usage state
https://bugs.webkit.org/show_bug.cgi?id=197453

Reviewed by Saam Barati.

JSTests:

  • stress/string-ident-use-clears-abstract-value-if-rope-string-constant-is-held.js: Added.

(trigger):
(main):

Source/JavaScriptCore:

We have a DFG graph like this.

a: JSConstant(rope JSString)
b: CheckStringIdent(Check:StringUse:@a)
... AI think this is unreachable ...

When executing StringUse edge filter onto @a, AbstractValue::filterValueByType clears AbstractValue and makes it None.
This is because @a constant produces SpecString (SpecStringVar | SpecStringIdent) while StringUse edge filter requires
SpecStringIdent. AbstractValue::filterValueByType has an assumption that the JS constant always produces the same
SpeculatedType. So it clears AbstractValue completely.
But this assumption is wrong. JSString can produce SpecStringIdent later if the string is resolved to AtomicStringImpl.
AI think that we always fail. But once the string is resolved to AtomicStringImpl, we pass this check. So we execute
the breakpoint emitted by DFG since DFG think this is unreachable.

In this patch, we just clear the m_value if AbstractValue type filter fails with the held constant, since the constant
may produce a narrower type which can meet the type filter later.

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::filterValueByType):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r245068 r245071  
     12019-05-08  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Invalid DFG JIT genereation in high CPU usage state
     4        https://bugs.webkit.org/show_bug.cgi?id=197453
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/string-ident-use-clears-abstract-value-if-rope-string-constant-is-held.js: Added.
     9        (trigger):
     10        (main):
     11
    1122019-05-08  Robin Morisset  <rmorisset@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r245068 r245071  
     12019-05-08  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        Invalid DFG JIT genereation in high CPU usage state
     4        https://bugs.webkit.org/show_bug.cgi?id=197453
     5
     6        Reviewed by Saam Barati.
     7
     8        We have a DFG graph like this.
     9
     10            a: JSConstant(rope JSString)
     11            b: CheckStringIdent(Check:StringUse:@a)
     12            ... AI think this is unreachable ...
     13
     14        When executing StringUse edge filter onto @a, AbstractValue::filterValueByType clears AbstractValue and makes it None.
     15        This is because @a constant produces SpecString (SpecStringVar | SpecStringIdent) while StringUse edge filter requires
     16        SpecStringIdent. AbstractValue::filterValueByType has an assumption that the JS constant always produces the same
     17        SpeculatedType. So it clears AbstractValue completely.
     18        But this assumption is wrong. JSString can produce SpecStringIdent later if the string is resolved to AtomicStringImpl.
     19        AI think that we always fail. But once the string is resolved to AtomicStringImpl, we pass this check. So we execute
     20        the breakpoint emitted by DFG since DFG think this is unreachable.
     21
     22        In this patch, we just clear the `m_value` if AbstractValue type filter fails with the held constant, since the constant
     23        may produce a narrower type which can meet the type filter later.
     24
     25        * dfg/DFGAbstractValue.cpp:
     26        (JSC::DFG::AbstractValue::filterValueByType):
     27
    1282019-05-08  Robin Morisset  <rmorisset@apple.com>
    229
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp

    r244480 r245071  
    372372    // in any realistic scenario, so we don't do it. Simpler is better.
    373373
    374     if (!!m_type) {
    375         // The type is still non-empty. It may be that the new type renders
    376         // the value empty because it contravenes the constant value we had.
    377         if (m_value && !validateTypeAcceptingBoxedInt52(m_value))
    378             clear();
     374    if (!m_value)
    379375        return;
    380     }
    381    
    382     // The type has been rendered empty. That means that the value must now be invalid,
    383     // as well.
    384     ASSERT(!m_value || !validateTypeAcceptingBoxedInt52(m_value));
     376
     377    if (validateTypeAcceptingBoxedInt52(m_value))
     378        return;
     379
     380    // We assume that the constant value can produce a narrower type at
     381    // some point. For example, rope JSString produces SpecString, but
     382    // it produces SpecStringIdent once it is resolved to AtomicStringImpl.
     383    // We do not make this AbstractValue cleared, but clear the constant
     384    // value if validation fails currently.
    385385    m_value = JSValue();
    386386}
Note: See TracChangeset for help on using the changeset viewer.