Title: [229270] releases/WebKitGTK/webkit-2.20
Revision
229270
Author
[email protected]
Date
2018-03-05 05:16:46 -0800 (Mon, 05 Mar 2018)

Log Message

We need to clear cached structures when having a bad time
https://bugs.webkit.org/show_bug.cgi?id=183256
<rdar://problem/36245022>

Reviewed by Mark Lam.

JSTests:

* stress/having-a-bad-time-with-derived-arrays.js: Added.
(assert):
(defineSetter):
(iterate):
(doSlice):

Source/_javascript_Core:

This patch makes both InternalFunctionAllocationProfile and the VM's
structure cache having-a-bad-time aware. For InternalFunctionAllocationProfile,
we clear them when they'd produce an object with a bad indexing type.
For the VM's Structure cache, we conservatively clear the entire cache
since it may be housing Structures with bad indexing types.

* runtime/FunctionRareData.h:
(JSC::FunctionRareData::clearInternalFunctionAllocationProfile):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::haveABadTime):
* runtime/StructureCache.h:
(JSC::StructureCache::clear):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog (229269 => 229270)


--- releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog	2018-03-05 13:16:40 UTC (rev 229269)
+++ releases/WebKitGTK/webkit-2.20/JSTests/ChangeLog	2018-03-05 13:16:46 UTC (rev 229270)
@@ -1,3 +1,17 @@
+2018-03-01  Saam Barati  <[email protected]>
+
+        We need to clear cached structures when having a bad time
+        https://bugs.webkit.org/show_bug.cgi?id=183256
+        <rdar://problem/36245022>
+
+        Reviewed by Mark Lam.
+
+        * stress/having-a-bad-time-with-derived-arrays.js: Added.
+        (assert):
+        (defineSetter):
+        (iterate):
+        (doSlice):
+
 2018-02-28  Yusuke Suzuki  <[email protected]>
 
         JSC crash with `import("")`

Added: releases/WebKitGTK/webkit-2.20/JSTests/stress/having-a-bad-time-with-derived-arrays.js (0 => 229270)


--- releases/WebKitGTK/webkit-2.20/JSTests/stress/having-a-bad-time-with-derived-arrays.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.20/JSTests/stress/having-a-bad-time-with-derived-arrays.js	2018-03-05 13:16:46 UTC (rev 229270)
@@ -0,0 +1,48 @@
+function assert(b) {
+    if (!b)
+        throw new Error;
+}
+
+let called = false;
+function defineSetter() {
+    Array.prototype.__defineSetter__(0, function (x) {
+        assert(x === 42);
+        called = true;
+    });
+}
+
+class DerivedArray extends Array {
+    constructor(...args) {
+        super()
+    }
+}
+
+function iterate(a) {
+    for (let i = 0; i < a.length; i++) { }
+}
+
+let arr = [[[1, 2, 3, 4, 5], [ 2], 5], [[1, 2, 3], [ -4]]];
+let d = new DerivedArray();
+d[1] = 20;
+d[2] = 40;
+arr.push([d, [2]  -9]);
+
+function doSlice(a) {
+    let r = a.slice();
+    defineSetter();
+    return r;
+}
+
+for (let i = 0; i < 10000; i++) {
+    for (let [a, b, ...c] of arr) {
+        let s = doSlice(a);
+        iterate(s);
+        delete s[0];
+        called = false;
+        s[0] = 42;
+        if (a === d) {
+            assert(called);
+            called = false;
+        }
+    }
+}

Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog (229269 => 229270)


--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog	2018-03-05 13:16:40 UTC (rev 229269)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/ChangeLog	2018-03-05 13:16:46 UTC (rev 229270)
@@ -1,3 +1,24 @@
+2018-03-01  Saam Barati  <[email protected]>
+
+        We need to clear cached structures when having a bad time
+        https://bugs.webkit.org/show_bug.cgi?id=183256
+        <rdar://problem/36245022>
+
+        Reviewed by Mark Lam.
+
+        This patch makes both InternalFunctionAllocationProfile and the VM's
+        structure cache having-a-bad-time aware. For InternalFunctionAllocationProfile,
+        we clear them when they'd produce an object with a bad indexing type.
+        For the VM's Structure cache, we conservatively clear the entire cache 
+        since it may be housing Structures with bad indexing types.
+
+        * runtime/FunctionRareData.h:
+        (JSC::FunctionRareData::clearInternalFunctionAllocationProfile):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::haveABadTime):
+        * runtime/StructureCache.h:
+        (JSC::StructureCache::clear):
+
 2018-03-01  Yusuke Suzuki  <[email protected]>
 
         Unreviewed, fix exception check for ExceptionScope

Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/FunctionRareData.h (229269 => 229270)


--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/FunctionRareData.h	2018-03-05 13:16:40 UTC (rev 229269)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/FunctionRareData.h	2018-03-05 13:16:46 UTC (rev 229270)
@@ -88,6 +88,10 @@
     {
         return m_internalFunctionAllocationProfile.createAllocationStructureFromBase(vm, globalObject, this, prototype, baseStructure);
     }
+    void clearInternalFunctionAllocationProfile()
+    {
+        m_internalFunctionAllocationProfile.clear();
+    }
 
     Structure* getBoundFunctionStructure() { return m_boundFunctionStructure.get(); }
     void setBoundFunctionStructure(VM& vm, Structure* structure) { m_boundFunctionStructure.set(vm, this, structure); }

Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/JSGlobalObject.cpp (229269 => 229270)


--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2018-03-05 13:16:40 UTC (rev 229269)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2018-03-05 13:16:46 UTC (rev 229270)
@@ -1170,10 +1170,15 @@
 {
 }
 
+inline bool hasBrokenIndexing(IndexingType type)
+{
+    return type && !hasSlowPutArrayStorage(type);
+}
+
 inline bool hasBrokenIndexing(JSObject* object)
 {
     IndexingType type = object->indexingType();
-    return type && !hasSlowPutArrayStorage(type);
+    return hasBrokenIndexing(type);
 }
 
 inline void ObjectsWithBrokenIndexingFinder::visit(JSCell* cell)
@@ -1181,32 +1186,48 @@
     if (!cell->isObject())
         return;
     
-    JSObject* object = asObject(cell);
+    VM& vm = m_globalObject->vm();
 
-    // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
-    if (!hasBrokenIndexing(object))
-        return;
-    
     // We only want to have a bad time in the affected global object, not in the entire
     // VM. But we have to be careful, since there may be objects that claim to belong to
     // a different global object that have prototypes from our global object.
-    bool foundGlobalObject = false;
-    VM& vm = m_globalObject->vm();
-    for (JSObject* current = object; ;) {
-        if (current->globalObject() == m_globalObject) {
-            foundGlobalObject = true;
-            break;
+    auto isInEffectedGlobalObject = [&] (JSObject* object) {
+        for (JSObject* current = object; ;) {
+            if (current->globalObject() == m_globalObject)
+                return true;
+            
+            JSValue prototypeValue = current->getPrototypeDirect(vm);
+            if (prototypeValue.isNull())
+                return false;
+            current = asObject(prototypeValue);
         }
-        
-        JSValue prototypeValue = current->getPrototypeDirect(vm);
-        if (prototypeValue.isNull())
-            break;
-        current = asObject(prototypeValue);
+        RELEASE_ASSERT_NOT_REACHED();
+    };
+
+    JSObject* object = asObject(cell);
+
+    if (JSFunction* function = jsDynamicCast<JSFunction*>(vm, object)) {
+        if (FunctionRareData* rareData = function->rareData()) {
+            // We only use this to cache JSFinalObjects. They do not start off with a broken indexing type.
+            ASSERT(!(rareData->objectAllocationStructure() && hasBrokenIndexing(rareData->objectAllocationStructure()->indexingType())));
+
+            if (Structure* structure = rareData->internalFunctionAllocationStructure()) {
+                if (hasBrokenIndexing(structure->indexingType())) {
+                    bool isRelevantGlobalObject = (structure->globalObject() == m_globalObject)
+                        || (structure->hasMonoProto() && !structure->storedPrototype().isNull() && isInEffectedGlobalObject(asObject(structure->storedPrototype())));
+                    if (isRelevantGlobalObject)
+                        rareData->clearInternalFunctionAllocationProfile();
+                }
+            }
+        }
     }
-    if (!foundGlobalObject)
+
+    // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
+    if (!hasBrokenIndexing(object))
         return;
     
-    m_foundObjects.append(object);
+    if (isInEffectedGlobalObject(object))
+        m_foundObjects.append(object);
 }
 
 IterationStatus ObjectsWithBrokenIndexingFinder::operator()(HeapCell* cell, HeapCell::Kind kind) const
@@ -1227,7 +1248,9 @@
     
     if (isHavingABadTime())
         return;
-    
+
+    vm.structureCache.clear(); // We may be caching array structures in here.
+
     // Make sure that all allocations or indexed storage transitions that are inlining
     // the assumption that it's safe to transition to a non-SlowPut array storage don't
     // do so anymore.

Modified: releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/StructureCache.h (229269 => 229270)


--- releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/StructureCache.h	2018-03-05 13:16:40 UTC (rev 229269)
+++ releases/WebKitGTK/webkit-2.20/Source/_javascript_Core/runtime/StructureCache.h	2018-03-05 13:16:46 UTC (rev 229270)
@@ -47,6 +47,8 @@
     {
     }
 
+    void clear() { m_structures.clear(); }
+
     JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false, FunctionExecutable* = nullptr);
     JS_EXPORT_PRIVATE Structure* emptyStructureForPrototypeFromBaseStructure(JSGlobalObject*, JSObject*, Structure*);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to