Ignore:
Timestamp:
Apr 4, 2018, 5:30:48 PM (7 years ago)
Author:
[email protected]
Message:

REGRESSION(r222563): removed DoubleReal type check causes tons of crashes because CSE has never known how to handle SaneChain
https://bugs.webkit.org/show_bug.cgi?id=184319

Reviewed by Saam Barati.

JSTests:

  • stress/array-push-nan-to-double-array-cse-sane-and-insane-chain.js: Added.

(foo):
(bar):

  • stress/array-push-nan-to-double-array.js: Added.

(foo):
(bar):

Source/JavaScriptCore:

In r222581, we replaced type checks about DoubleReal in ArrayPush in the DFG/FTL backends with
assertions. That's correct because FixupPhase was emitting those checks as Check(DoubleRealRep:) before
the ArrayPush.

But this revealed a longstanding CSE bug: CSE will happily match a SaneChain GetByVal with a InBounds
GetByVal. SaneChain can return NaN while InBounds cannot. This means that if we first use AI to
eliminate the Check(DoubleRealRep:) based on the input being a GetByVal(InBounds) but then replace that
with a GetByVal(SaneChain), then we will hit the assertion.

This teaches CSE to not replace GetByVal(InBounds) with GetByVal(SaneChain) and vice versa. That gets
tricky because PutByVal can match either. So, we use the fact that it's legal for a store to def() more
than once: PutByVal now defs() a HeapLocation for InBounds and a HeapLocation for SaneChain.

  • dfg/DFGCSEPhase.cpp:
  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGHeapLocation.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArrayPush):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r228411 r230287  
    11/*
    2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    470470                            if (!mode.isInBounds())
    471471                                break;
    472                             heap = HeapLocation(
    473                                 indexedPropertyLoc, IndexedInt32Properties, base, index);
     472                            heap = HeapLocation(indexedPropertyLoc, IndexedInt32Properties, base, index);
    474473                            break;
    475474                           
    476                         case Array::Double:
     475                        case Array::Double: {
    477476                            if (!mode.isInBounds())
    478477                                break;
    479                             heap = HeapLocation(
    480                                 indexedPropertyLoc, IndexedDoubleProperties, base, index);
     478                            LocationKind kind = mode.isSaneChain() ? IndexedPropertyDoubleSaneChainLoc : IndexedPropertyDoubleLoc;
     479                            heap = HeapLocation(kind, IndexedDoubleProperties, base, index);
    481480                            break;
     481                        }
    482482                           
    483483                        case Array::Contiguous:
    484484                            if (!mode.isInBounds())
    485485                                break;
    486                             heap = HeapLocation(
    487                                 indexedPropertyLoc, IndexedContiguousProperties, base, index);
     486                            heap = HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, base, index);
    488487                            break;
    489488                           
Note: See TracChangeset for help on using the changeset viewer.