[JSC] Delete IC creation should check mayNeedToCheckCell/canCacheDeleteIC regardless...
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Mar 2020 20:37:09 +0000 (20:37 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 13 Mar 2020 20:37:09 +0000 (20:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=209027

Reviewed by Saam Barati.

Delete IC code generation assumes that mayNeedToCheckCell (it is replaced with canCacheDeleteIC) is false
while we are looking into this status only if Structure::outOfLineCapacity meets a certain condition. We should avoid
create Delete IC when mayNeedToCheckCell/canCacheDeleteIC is true regardless of Structure::outOfLineCapacity

* bytecode/AccessCase.cpp:
(JSC::AccessCase::createDelete):
(JSC::AccessCase::generateImpl):
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::mayHaveIndexingHeader const):
(JSC::Structure::canCacheDeleteIC const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@258427 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/AccessCase.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureInlines.h

index 9012701..bca8a34 100644 (file)
@@ -1,3 +1,22 @@
+2020-03-12  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Delete IC creation should check mayNeedToCheckCell/canCacheDeleteIC regardless of Structure::outOfLineCapacity
+        https://bugs.webkit.org/show_bug.cgi?id=209027
+
+        Reviewed by Saam Barati.
+
+        Delete IC code generation assumes that mayNeedToCheckCell (it is replaced with canCacheDeleteIC) is false
+        while we are looking into this status only if Structure::outOfLineCapacity meets a certain condition. We should avoid
+        create Delete IC when mayNeedToCheckCell/canCacheDeleteIC is true regardless of Structure::outOfLineCapacity
+
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::createDelete):
+        (JSC::AccessCase::generateImpl):
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::mayHaveIndexingHeader const):
+        (JSC::Structure::canCacheDeleteIC const):
+
 2020-03-13  Alexey Shvayka  <shvaikalesh@gmail.com>
 
         Bound functions should pass correct NewTarget value
index a923353..bfc159e 100644 (file)
@@ -129,15 +129,10 @@ std::unique_ptr<AccessCase> AccessCase::createDelete(
     VM& vm, JSCell* owner, CacheableIdentifier identifier, PropertyOffset offset, Structure* oldStructure, Structure* newStructure)
 {
     RELEASE_ASSERT(oldStructure == newStructure->previousID(vm));
-    if (!newStructure->outOfLineCapacity() && oldStructure->outOfLineCapacity()) {
-        // We do not cache this case so that we do not need to check the jscell.
-        // See the Delete code below.
-        bool mayNeedToCheckCell;
-        newStructure->mayHaveIndexingHeader(mayNeedToCheckCell);
-
-        if (mayNeedToCheckCell)
-            return nullptr;
-    }
+    // We do not cache this case so that we do not need to check the jscell, e.g. TypedArray cells require a check for neutering status.
+    // See the Delete code below.
+    if (!newStructure->canCacheDeleteIC())
+        return nullptr;
     return std::unique_ptr<AccessCase>(new AccessCase(vm, owner, Delete, identifier, offset, newStructure, { }, { }));
 }
 
@@ -1950,11 +1945,10 @@ void AccessCase::generateImpl(AccessGenerationState& state)
         ScratchRegisterAllocator::PreservedState preservedState =
             allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);
 
-        bool mayNeedToCheckCell;
-        bool hasIndexingHeader = newStructure()->mayHaveIndexingHeader(mayNeedToCheckCell);
+        bool hasIndexingHeader = newStructure()->mayHaveIndexingHeader();
         // We do not cache this case yet so that we do not need to check the jscell.
         // See Structure::hasIndexingHeader and JSObject::deleteProperty.
-        ASSERT(!mayNeedToCheckCell);
+        ASSERT(newStructure()->canCacheDeleteIC());
         // Clear the butterfly if we have no properties, since our put code expects this.
         bool shouldNukeStructureAndClearButterfly = !newStructure()->outOfLineCapacity() && structure()->outOfLineCapacity() && !hasIndexingHeader;
 
index 320a47a..d02879f 100644 (file)
@@ -532,7 +532,8 @@ public:
     }
     
     bool hasIndexingHeader(const JSCell*) const;
-    bool mayHaveIndexingHeader(bool& mustCheckCell) const;
+    bool mayHaveIndexingHeader() const;
+    bool canCacheDeleteIC() const;
     
     bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
 
index 3dc17b7..fb276d8 100644 (file)
@@ -256,19 +256,22 @@ inline bool Structure::hasIndexingHeader(const JSCell* cell) const
     return jsCast<const JSArrayBufferView*>(cell)->mode() == WastefulTypedArray;
 }
 
-inline bool Structure::mayHaveIndexingHeader(bool& mustCheckCell) const
+inline bool Structure::mayHaveIndexingHeader() const
 {
-    mustCheckCell = false;
     if (hasIndexedProperties(indexingType()))
         return true;
 
     if (!isTypedView(typedArrayTypeForType(m_blob.type())))
         return false;
 
-    mustCheckCell = true;
     return true;
 }
 
+inline bool Structure::canCacheDeleteIC() const
+{
+    return !isTypedView(typedArrayTypeForType(m_blob.type()));
+}
+
 inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
 {
     return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;