[JSC] Ensure PackedCellPtr only takes non-large-allocation pointers
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 22:51:28 +0000 (22:51 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jul 2019 22:51:28 +0000 (22:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200139

Reviewed by Mark Lam.

PackedCellPtr will compact a pointer by leveraging the fact that JSCell pointers are 16byte aligned.
But this fact only holds when the JSCell is not large allocation. Currently, we are using PackedCellPtr
only for the cell types which meets the above requirement. But we would like to ensure that statically.

In this patch, we add additional static/runtime assertions to ensure this invariant. We accept a cell
type of either (1) it is "final" annotated and sizeof(T) is <= MarkedSpace::largeCutoff or (2) it
is allocated from IsoSubspace.

This patch does not change any behaviors. It just adds extra static/runtime assertions.

* bytecode/CodeBlock.h:
(JSC::CodeBlock::subspaceFor):
* bytecode/CodeBlockJettisoningWatchpoint.h:
* bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
* dfg/DFGAdaptiveStructureWatchpoint.h:
* heap/IsoSubspace.h:
* heap/PackedCellPtr.h:
(JSC::PackedCellPtr::PackedCellPtr):
* runtime/FunctionRareData.h:
(JSC::FunctionRareData::createAllocationProfileClearingWatchpoint):
* runtime/ObjectToStringAdaptiveStructureWatchpoint.h:

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h
Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h
Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h
Source/JavaScriptCore/heap/IsoSubspace.h
Source/JavaScriptCore/heap/PackedCellPtr.h
Source/JavaScriptCore/runtime/FunctionRareData.h
Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h

index cdc9b74..cf626d0 100644 (file)
@@ -1,5 +1,34 @@
 2019-07-25  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] Ensure PackedCellPtr only takes non-large-allocation pointers
+        https://bugs.webkit.org/show_bug.cgi?id=200139
+
+        Reviewed by Mark Lam.
+
+        PackedCellPtr will compact a pointer by leveraging the fact that JSCell pointers are 16byte aligned.
+        But this fact only holds when the JSCell is not large allocation. Currently, we are using PackedCellPtr
+        only for the cell types which meets the above requirement. But we would like to ensure that statically.
+
+        In this patch, we add additional static/runtime assertions to ensure this invariant. We accept a cell
+        type of either (1) it is "final" annotated and sizeof(T) is <= MarkedSpace::largeCutoff or (2) it
+        is allocated from IsoSubspace.
+
+        This patch does not change any behaviors. It just adds extra static/runtime assertions.
+
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::subspaceFor):
+        * bytecode/CodeBlockJettisoningWatchpoint.h:
+        * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h:
+        * dfg/DFGAdaptiveStructureWatchpoint.h:
+        * heap/IsoSubspace.h:
+        * heap/PackedCellPtr.h:
+        (JSC::PackedCellPtr::PackedCellPtr):
+        * runtime/FunctionRareData.h:
+        (JSC::FunctionRareData::createAllocationProfileClearingWatchpoint):
+        * runtime/ObjectToStringAdaptiveStructureWatchpoint.h:
+
+2019-07-25  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [JSC] Make visitChildren implementation more idiomatic
         https://bugs.webkit.org/show_bug.cgi?id=200121
 
index 6648fc5..87068ba 100644 (file)
@@ -115,7 +115,7 @@ public:
     static const bool needsDestruction = true;
 
     template<typename, SubspaceAccess>
-    static void subspaceFor(VM&) { }
+    static IsoSubspace* subspaceFor(VM&) { return nullptr; }
 
     DECLARE_INFO;
 
index 35a4164..7e28b30 100644 (file)
 
 #pragma once
 
+#include "CodeBlock.h"
 #include "PackedCellPtr.h"
 #include "Watchpoint.h"
 
 namespace JSC {
 
-class CodeBlock;
-
 class CodeBlockJettisoningWatchpoint final : public Watchpoint {
 public:
     CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock)
index dd557cd..220fff3 100644 (file)
@@ -26,6 +26,7 @@
 #pragma once
 
 #include "BytecodeStructs.h"
+#include "CodeBlock.h"
 #include "ObjectPropertyCondition.h"
 #include "PackedCellPtr.h"
 #include "Watchpoint.h"
index 6ab07b4..b29f89f 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(DFG_JIT)
 
+#include "CodeBlock.h"
 #include "ObjectPropertyCondition.h"
 #include "PackedCellPtr.h"
 #include "Watchpoint.h"
index efd5cd3..f4d922b 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "BlockDirectory.h"
 #include "Subspace.h"
+#include "SubspaceAccess.h"
 #include <wtf/SinglyLinkedListWithTail.h>
 
 namespace JSC {
@@ -69,5 +70,10 @@ ALWAYS_INLINE Allocator IsoSubspace::allocatorForNonVirtual(size_t size, Allocat
 
 #define ISO_SUBSPACE_INIT(heap, heapCellType, type) ("Isolated " #type " Space", (heap), (heapCellType), sizeof(type))
 
+template<typename T>
+struct isAllocatedFromIsoSubspace {
+    static constexpr bool value = std::is_same<std::invoke_result_t<decltype(T::template subspaceFor<T, SubspaceAccess::OnMainThread>), VM&>, IsoSubspace*>::value;
+};
+
 } // namespace JSC
 
index fe04c0d..f249306 100644 (file)
 
 #pragma once
 
+#include "IsoSubspace.h"
 #include "MarkedBlock.h"
+#include "MarkedSpace.h"
 #include <wtf/Packed.h>
 
 namespace JSC {
 
 template<typename T>
-using PackedCellPtr = PackedAlignedPtr<T, MarkedBlock::atomSize>;
+class PackedCellPtr : public PackedAlignedPtr<T, MarkedBlock::atomSize> {
+public:
+    using Base = PackedAlignedPtr<T, MarkedBlock::atomSize>;
+    PackedCellPtr(T* pointer)
+        : Base(pointer)
+    {
+        static_assert((sizeof(T) <= MarkedSpace::largeCutoff && std::is_final<T>::value) || isAllocatedFromIsoSubspace<T>::value, "LargeAllocation does not have 16byte alignment");
+        ASSERT(!(bitwise_cast<uintptr_t>(pointer) & (16 - 1)));
+    }
+};
 
 } // namespace JSC
index c5d686c..4623641 100644 (file)
@@ -107,26 +107,8 @@ public:
     void setHasReifiedName() { m_hasReifiedName = true; }
 
     bool hasAllocationProfileClearingWatchpoint() const { return !!m_allocationProfileClearingWatchpoint; }
-    Watchpoint* createAllocationProfileClearingWatchpoint()
-    {
-        RELEASE_ASSERT(!hasAllocationProfileClearingWatchpoint());
-        m_allocationProfileClearingWatchpoint = std::make_unique<AllocationProfileClearingWatchpoint>(this);
-        return m_allocationProfileClearingWatchpoint.get();
-    }
-
-    class AllocationProfileClearingWatchpoint final : public Watchpoint {
-    public:
-        AllocationProfileClearingWatchpoint(FunctionRareData* rareData)
-            : Watchpoint(Watchpoint::Type::FunctionRareDataAllocationProfileClearing)
-            , m_rareData(rareData)
-        { }
-
-        void fireInternal(VM&, const FireDetail&);
-
-    private:
-        // Own destructor may not be called. Keep members trivially destructible.
-        JSC_WATCHPOINT_FIELD(PackedCellPtr<FunctionRareData>, m_rareData);
-    };
+    Watchpoint* createAllocationProfileClearingWatchpoint();
+    class AllocationProfileClearingWatchpoint;
 
 protected:
     FunctionRareData(VM&);
@@ -157,4 +139,25 @@ private:
     bool m_hasReifiedName { false };
 };
 
+class FunctionRareData::AllocationProfileClearingWatchpoint final : public Watchpoint {
+public:
+    AllocationProfileClearingWatchpoint(FunctionRareData* rareData)
+        : Watchpoint(Watchpoint::Type::FunctionRareDataAllocationProfileClearing)
+        , m_rareData(rareData)
+    { }
+
+    void fireInternal(VM&, const FireDetail&);
+
+private:
+    // Own destructor may not be called. Keep members trivially destructible.
+    JSC_WATCHPOINT_FIELD(PackedCellPtr<FunctionRareData>, m_rareData);
+};
+
+inline Watchpoint* FunctionRareData::createAllocationProfileClearingWatchpoint()
+{
+    RELEASE_ASSERT(!hasAllocationProfileClearingWatchpoint());
+    m_allocationProfileClearingWatchpoint = std::make_unique<AllocationProfileClearingWatchpoint>(this);
+    return m_allocationProfileClearingWatchpoint.get();
+}
+
 } // namespace JSC
index 60ee802..49f4f75 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ObjectPropertyCondition.h"
 #include "PackedCellPtr.h"
+#include "StructureRareData.h"
 #include "Watchpoint.h"
 
 namespace JSC {