Changeset 245214 in webkit
- Timestamp:
- May 12, 2019, 3:50:21 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 33 edited
-
Source/JavaScriptCore/CMakeLists.txt (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (8 diffs)
-
Source/JavaScriptCore/Sources.txt (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/CodeOrigin.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/Watchpoint.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/Watchpoint.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h (modified) (2 diffs)
-
Source/JavaScriptCore/heap/PackedCellPtr.h (added)
-
Source/JavaScriptCore/runtime/FunctionRareData.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp (added)
-
Source/JavaScriptCore/runtime/ObjectToStringAdaptiveStructureWatchpoint.h (added)
-
Source/JavaScriptCore/runtime/StructureRareData.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/StructureRareData.h (modified) (1 diff)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/WTF.xcodeproj/project.pbxproj (modified) (2 diffs)
-
Source/WTF/wtf/Bag.h (modified) (6 diffs)
-
Source/WTF/wtf/CMakeLists.txt (modified) (1 diff)
-
Source/WTF/wtf/DumbPtrTraits.h (modified) (1 diff)
-
Source/WTF/wtf/DumbValueTraits.h (modified) (1 diff)
-
Source/WTF/wtf/MathExtras.h (modified) (5 diffs)
-
Source/WTF/wtf/Packed.h (added)
-
Source/WTF/wtf/Platform.h (modified) (1 diff)
-
Source/WTF/wtf/SentinelLinkedList.h (modified) (6 diffs)
-
Source/WTF/wtf/StdLibExtras.h (modified) (1 diff)
-
Source/WTF/wtf/UnalignedAccess.h (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/CMakeLists.txt (modified) (1 diff)
-
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WTF/Packed.cpp (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/CMakeLists.txt
r245213 r245214 607 607 heap/MarkingConstraint.h 608 608 heap/MutatorState.h 609 heap/PackedCellPtr.h 609 610 heap/RegisterState.h 610 611 heap/RunningScope.h -
trunk/Source/JavaScriptCore/ChangeLog
r245213 r245214 1 2019-05-12 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Compress Watchpoint size by using enum type and Packed<> data structure 4 https://bugs.webkit.org/show_bug.cgi?id=197730 5 6 Reviewed by Filip Pizlo. 7 8 Watchpoint takes 5~ MB memory in Gmail (total memory starts with 400 - 500 MB), so 1~%. Since it is allocated massively, 9 reducing each size of Watchpoint reduces memory footprint significantly. 10 11 As a first step, this patch uses Packed<> and enum to reduce the size of Watchpoint. 12 13 1. Watchpoint should have enum type and should not use vtable. vtable takes one pointer, and it is too costly for such a 14 memory sensitive objects. We perform downcast and dispatch the method of the derived classes based on this enum. Since 15 the # of derived Watchpoint classes are limited (Only 8), we can list up them easily. One unfortunate thing is that 16 we cannot do this for destructor so long as we use "delete" for deleting objects. If we dispatch the destructor of derived 17 class in the destructor of the base class, we call the destructor of the base class multiple times. delete operator override 18 does not help since custom delete operator is called after the destructor is called. While we can fix this issue by always 19 using custom deleter, currently we do not since all the watchpoints do not have members which have non trivial destructor. 20 Once it is strongly required, we can start using custom deleter, but for now, we do not need to do this. 21 22 2. We use Packed<> to compact pointers in Watchpoint. Since Watchpoint is a node of doubly linked list, each one has two 23 pointers for prev and next. This is also too costly. PackedPtr reduces the size and makes alignment 1.S 24 25 3. We use PackedCellPtr<> for JSCells in Watchpoint. This leverages alignment information and makes pointers smaller in 26 Darwin ARM64. One important thing to note here is that since this pointer is packed, it cannot be found by conservative 27 GC scan. It is OK for watchpoint since they are allocated in the heap anyway. 28 29 We applied this change to Watchpoint and get the following memory reduction. The highlight is that CodeBlockJettisoningWatchpoint in 30 ARM64 only takes 2 pointers size. 31 32 ORIGINAL X86_64 ARM64 33 WatchpointSet: 40 32 28 34 CodeBlockJettisoningWatchpoint: 32 19 15 35 StructureStubClearingWatchpoint: 56 48 40 36 AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint: 24 13 11 37 AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint: 24 13 11 38 FunctionRareData::AllocationProfileClearingWatchpoint: 32 19 15 39 ObjectToStringAdaptiveStructureWatchpoint: 56 48 40 40 LLIntPrototypeLoadAdaptiveStructureWatchpoint: 64 48 48 41 DFG::AdaptiveStructureWatchpoint: 56 48 40 42 43 While we will re-architect the mechanism of Watchpoint, anyway Packed<> mechanism and enum types will be used too. 44 45 * CMakeLists.txt: 46 * JavaScriptCore.xcodeproj/project.pbxproj: 47 * Sources.txt: 48 * bytecode/AdaptiveInferredPropertyValueWatchpointBase.h: 49 * bytecode/CodeBlockJettisoningWatchpoint.h: 50 * bytecode/CodeOrigin.h: 51 * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp: 52 (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint): 53 (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal): 54 * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h: 55 * bytecode/StructureStubClearingWatchpoint.cpp: 56 (JSC::StructureStubClearingWatchpoint::fireInternal): 57 * bytecode/StructureStubClearingWatchpoint.h: 58 * bytecode/Watchpoint.cpp: 59 (JSC::Watchpoint::fire): 60 * bytecode/Watchpoint.h: 61 (JSC::Watchpoint::Watchpoint): 62 * dfg/DFGAdaptiveStructureWatchpoint.cpp: 63 (JSC::DFG::AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint): 64 * dfg/DFGAdaptiveStructureWatchpoint.h: 65 * heap/PackedCellPtr.h: Added. 66 * runtime/FunctionRareData.h: 67 * runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp: Added. 68 (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint): 69 (JSC::ObjectToStringAdaptiveStructureWatchpoint::install): 70 (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal): 71 * runtime/ObjectToStringAdaptiveStructureWatchpoint.h: Added. 72 * runtime/StructureRareData.cpp: 73 (JSC::StructureRareData::clearObjectToStringValue): 74 (JSC::ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint): Deleted. 75 (JSC::ObjectToStringAdaptiveStructureWatchpoint::install): Deleted. 76 (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal): Deleted. 77 * runtime/StructureRareData.h: 78 1 79 2019-05-12 Yusuke Suzuki <ysuzuki@apple.com> 2 80 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r245213 r245214 1780 1780 E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterSnippet.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterSnippet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1781 1781 E355D38F22446877008F1AD6 /* GlobalExecutable.h in Headers */ = {isa = PBXBuildFile; fileRef = E355D38D2244686B008F1AD6 /* GlobalExecutable.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1782 E356987222841187008CDCCB /* PackedCellPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = E356987122841183008CDCCB /* PackedCellPtr.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1782 1783 E35A0B9D220AD87A00AC4474 /* ExecutableBaseInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1783 1784 E35CA1541DBC3A5C00F83516 /* DOMJITHeapRange.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA1521DBC3A5600F83516 /* DOMJITHeapRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1793 1794 E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1794 1795 E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1796 E39EEAF322812450008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */; }; 1795 1797 E3A0531A21342B680022EC14 /* WasmStreamingParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531621342B660022EC14 /* WasmStreamingParser.h */; }; 1796 1798 E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531821342B670022EC14 /* WasmSectionParser.h */; }; … … 4774 4776 E355D38D2244686B008F1AD6 /* GlobalExecutable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalExecutable.h; sourceTree = "<group>"; }; 4775 4777 E355D38E2244686C008F1AD6 /* GlobalExecutable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GlobalExecutable.cpp; sourceTree = "<group>"; }; 4778 E356987122841183008CDCCB /* PackedCellPtr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PackedCellPtr.h; sourceTree = "<group>"; }; 4776 4779 E35A0B9C220AD87A00AC4474 /* ExecutableBaseInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableBaseInlines.h; sourceTree = "<group>"; }; 4777 4780 E35CA14F1DBC3A5600F83516 /* DOMJITAbstractHeap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAbstractHeap.cpp; sourceTree = "<group>"; }; … … 4800 4803 E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = "<group>"; }; 4801 4804 E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; }; 4805 E39EEAF12281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectToStringAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; }; 4806 E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjectToStringAdaptiveStructureWatchpoint.h; sourceTree = "<group>"; }; 4802 4807 E3A0531621342B660022EC14 /* WasmStreamingParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmStreamingParser.h; sourceTree = "<group>"; }; 4803 4808 E3A0531721342B660022EC14 /* WasmSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSectionParser.cpp; sourceTree = "<group>"; }; … … 6026 6031 0FA762021DB9242300B7A2FD /* MutatorState.cpp */, 6027 6032 0FA762031DB9242300B7A2FD /* MutatorState.h */, 6033 E356987122841183008CDCCB /* PackedCellPtr.h */, 6028 6034 0F9DAA081FD1C3C80079C5B2 /* ParallelSourceAdapter.h */, 6029 6035 0FBB73B61DEF3AAC002C009E /* PreventCollectionScope.h */, … … 7175 7181 BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */, 7176 7182 BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */, 7183 E39EEAF12281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.cpp */, 7184 E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */, 7177 7185 F692A8770255597D01FF60F7 /* Operations.cpp */, 7178 7186 F692A8780255597D01FF60F7 /* Operations.h */, … … 9661 9669 0FD3E40C1B618B6600C80E1E /* ObjectPropertyConditionSet.h in Headers */, 9662 9670 BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */, 9671 E39EEAF322812450008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h in Headers */, 9663 9672 E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */, 9664 9673 14F79F70216EAFD200046D39 /* Opcode.h in Headers */, … … 9669 9678 BC18C4480E16F5CD00B34460 /* Operations.h in Headers */, 9670 9679 0FE228ED1436AB2700196C48 /* Options.h in Headers */, 9680 E356987222841187008CDCCB /* PackedCellPtr.h in Headers */, 9671 9681 0F9DAA0A1FD1C3D30079C5B2 /* ParallelSourceAdapter.h in Headers */, 9672 9682 E34E657520668EAA00FB81AC /* ParseHash.h in Headers */, -
trunk/Source/JavaScriptCore/Sources.txt
r244233 r245214 900 900 runtime/ObjectInitializationScope.cpp 901 901 runtime/ObjectPrototype.cpp 902 runtime/ObjectToStringAdaptiveStructureWatchpoint.cpp 902 903 runtime/Operations.cpp 903 904 runtime/Options.cpp -
trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h
r243560 r245214 46 46 virtual ~AdaptiveInferredPropertyValueWatchpointBase() = default; 47 47 48 class StructureWatchpoint final : public Watchpoint { 49 public: 50 StructureWatchpoint() 51 : Watchpoint(Watchpoint::Type::AdaptiveInferredPropertyValueStructure) 52 { } 53 54 void fireInternal(VM&, const FireDetail&); 55 }; 56 // Own destructor may not be called. Keep members trivially destructible. 57 static_assert(sizeof(StructureWatchpoint) == sizeof(Watchpoint), ""); 58 59 class PropertyWatchpoint final : public Watchpoint { 60 public: 61 PropertyWatchpoint() 62 : Watchpoint(Watchpoint::Type::AdaptiveInferredPropertyValueProperty) 63 { } 64 65 void fireInternal(VM&, const FireDetail&); 66 }; 67 // Own destructor may not be called. Keep members trivially destructible. 68 static_assert(sizeof(PropertyWatchpoint) == sizeof(Watchpoint), ""); 69 48 70 protected: 49 71 virtual bool isValid() const; … … 51 73 52 74 private: 53 class StructureWatchpoint final : public Watchpoint {54 public:55 StructureWatchpoint() { }56 protected:57 void fireInternal(VM&, const FireDetail&) override;58 };59 class PropertyWatchpoint final : public Watchpoint {60 public:61 PropertyWatchpoint() { }62 protected:63 void fireInternal(VM&, const FireDetail&) override;64 };65 66 75 void fire(VM&, const FireDetail&); 67 76 -
trunk/Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h
r243560 r245214 26 26 #pragma once 27 27 28 #include "PackedCellPtr.h" 28 29 #include "Watchpoint.h" 29 30 … … 35 36 public: 36 37 CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock) 37 : m_codeBlock(codeBlock) 38 : Watchpoint(Watchpoint::Type::CodeBlockJettisoning) 39 , m_codeBlock(codeBlock) 38 40 { 39 41 } 40 42 41 protected: 42 void fireInternal(VM&, const FireDetail&) override; 43 void fireInternal(VM&, const FireDetail&); 43 44 44 45 private: 45 CodeBlock* m_codeBlock;46 JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_codeBlock); 46 47 }; 47 48 -
trunk/Source/JavaScriptCore/bytecode/CodeOrigin.h
r243363 r245214 233 233 } 234 234 235 #if CPU(ARM64) && CPU(ADDRESS64) 236 static constexpr unsigned s_freeBitsAtTop = 28; 237 static constexpr uintptr_t s_maskCompositeValueForPointer = 0x0000000ffffffff8; 238 #elif CPU(ADDRESS64) 239 static constexpr unsigned s_freeBitsAtTop = 16; 240 static constexpr uintptr_t s_maskCompositeValueForPointer = 0x0000fffffffffff8; 241 #endif 242 #if CPU(ADDRESS64) 235 #if CPU(ADDRESS64) 236 static constexpr unsigned s_freeBitsAtTop = 64 - WTF_CPU_EFFECTIVE_ADDRESS_WIDTH; 237 static constexpr uintptr_t s_maskCompositeValueForPointer = ((1ULL << WTF_CPU_EFFECTIVE_ADDRESS_WIDTH) - 1) & ~(8ULL - 1); 243 238 static uintptr_t buildCompositeValue(InlineCallFrame* inlineCallFrame, unsigned bytecodeIndex) 244 239 { -
trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
r245050 r245214 34 34 35 35 LLIntPrototypeLoadAdaptiveStructureWatchpoint::LLIntPrototypeLoadAdaptiveStructureWatchpoint(CodeBlock* owner, const ObjectPropertyCondition& key, unsigned bytecodeOffset) 36 : m_owner(owner) 36 : Watchpoint(Watchpoint::Type::LLIntPrototypeLoadAdaptiveStructure) 37 , m_owner(owner) 38 , m_bytecodeOffset(bytecodeOffset) 37 39 , m_key(key) 38 , m_bytecodeOffset(bytecodeOffset)39 40 { 40 41 RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint()); … … 59 60 } 60 61 61 auto& instruction = m_owner->instructions().at(m_bytecodeOffset );62 clearLLIntGetByIdCache(instruction->as<OpGetById>().metadata(m_owner ));62 auto& instruction = m_owner->instructions().at(m_bytecodeOffset.get()); 63 clearLLIntGetByIdCache(instruction->as<OpGetById>().metadata(m_owner.get())); 63 64 } 64 65 -
trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h
r245050 r245214 28 28 #include "BytecodeStructs.h" 29 29 #include "ObjectPropertyCondition.h" 30 #include "PackedCellPtr.h" 30 31 #include "Watchpoint.h" 31 32 … … 42 43 const ObjectPropertyCondition& key() const { return m_key; } 43 44 44 protected: 45 void fireInternal(VM&, const FireDetail&) override; 45 void fireInternal(VM&, const FireDetail&); 46 46 47 47 private: 48 CodeBlock* m_owner; 49 ObjectPropertyCondition m_key; 50 unsigned m_bytecodeOffset; 48 // Own destructor may not be called. Keep members trivially destructible. 49 JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_owner); 50 JSC_WATCHPOINT_FIELD(Packed<unsigned>, m_bytecodeOffset); 51 JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key); 51 52 }; 52 53 -
trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.cpp
r243560 r245214 37 37 void StructureStubClearingWatchpoint::fireInternal(VM& vm, const FireDetail&) 38 38 { 39 if (!m_holder .isValid())39 if (!m_holder->isValid()) 40 40 return; 41 41 … … 44 44 // That works, because deleting a watchpoint removes it from the set's list, and 45 45 // the set's list traversal for firing is robust against the set changing. 46 ConcurrentJSLocker locker(m_holder .codeBlock()->m_lock);47 m_holder .stubInfo()->reset(m_holder.codeBlock());46 ConcurrentJSLocker locker(m_holder->codeBlock()->m_lock); 47 m_holder->stubInfo()->reset(m_holder->codeBlock()); 48 48 return; 49 49 } -
trunk/Source/JavaScriptCore/bytecode/StructureStubClearingWatchpoint.h
r243560 r245214 45 45 WTF_MAKE_FAST_ALLOCATED; 46 46 public: 47 StructureStubClearingWatchpoint( 48 const ObjectPropertyCondition& key, 49 WatchpointsOnStructureStubInfo& holder) 50 : m_key(key) 51 , m_holder(holder) 47 StructureStubClearingWatchpoint(const ObjectPropertyCondition& key, WatchpointsOnStructureStubInfo& holder) 48 : Watchpoint(Watchpoint::Type::StructureStubClearing) 49 , m_holder(&holder) 50 , m_key(key) 52 51 { 53 52 } 54 53 55 protected: 56 void fireInternal(VM&, const FireDetail&) override; 54 void fireInternal(VM&, const FireDetail&); 57 55 58 56 private: 59 ObjectPropertyCondition m_key; 60 WatchpointsOnStructureStubInfo& m_holder; 57 // Own destructor may not be called. Keep members trivially destructible. 58 JSC_WATCHPOINT_FIELD(PackedPtr<WatchpointsOnStructureStubInfo>, m_holder); 59 JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key); 61 60 }; 62 61 -
trunk/Source/JavaScriptCore/bytecode/Watchpoint.cpp
r234086 r245214 27 27 #include "Watchpoint.h" 28 28 29 #include "AdaptiveInferredPropertyValueWatchpointBase.h" 30 #include "CodeBlockJettisoningWatchpoint.h" 31 #include "DFGAdaptiveStructureWatchpoint.h" 32 #include "FunctionRareData.h" 29 33 #include "HeapInlines.h" 34 #include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h" 35 #include "ObjectToStringAdaptiveStructureWatchpoint.h" 36 #include "StructureStubClearingWatchpoint.h" 30 37 #include "VM.h" 31 38 #include <wtf/CompilationThread.h> … … 53 60 { 54 61 RELEASE_ASSERT(!isOnList()); 55 fireInternal(vm, detail); 62 switch (m_type) { 63 #define JSC_DEFINE_WATCHPOINT_DISPATCH(type, cast) \ 64 case Type::type: \ 65 static_cast<cast*>(this)->fireInternal(vm, detail); \ 66 break; 67 JSC_WATCHPOINT_TYPES(JSC_DEFINE_WATCHPOINT_DISPATCH) 68 #undef JSC_DEFINE_WATCHPOINT_DISPATCH 69 } 56 70 } 57 71 -
trunk/Source/JavaScriptCore/bytecode/Watchpoint.h
r245050 r245214 91 91 class WatchpointSet; 92 92 93 class Watchpoint : public BasicRawSentinelNode<Watchpoint> { 93 // Really unfortunately, we do not have the way to dispatch appropriate destructor in base class' destructor 94 // based on enum type. If we call destructor explicitly in the base class, it ends up calling the base destructor 95 // twice. C++20 allows this by using std::std::destroying_delete_t. But we are not using C++20 right now. 96 // 97 // Because we cannot dispatch destructors of derived classes in the destructor of the base class, what it means is, 98 // 1. Calling Watchpoint::~Watchpoint directly is illegal. 99 // 2. `delete watchpoint` where watchpoint is non-final derived class is illegal. If watchpoint is final derived class, it works. 100 // 3. If we really want to do (2), we need to call `watchpoint->destroy()` instead, and dispatch an appropriate destructor in Watchpoint::destroy. 101 // 102 // Luckily, none of our derived watchpoint classes have members which require destructors. So we do not dispatch 103 // the destructor call to the drived class in the base class. If it becomes really required, we can introduce 104 // a custom deleter for some classes which directly call "delete" to the allocated non-final Watchpoint class 105 // (e.g. std::unique_ptr<Watchpoint>, RefPtr<Watchpoint>), and call Watchpoint::destroy instead of "delete" 106 // operator. But since we do not require it for now, we are doing the simplest thing. 107 #define JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro) \ 108 macro(AdaptiveInferredPropertyValueStructure, AdaptiveInferredPropertyValueWatchpointBase::StructureWatchpoint) \ 109 macro(AdaptiveInferredPropertyValueProperty, AdaptiveInferredPropertyValueWatchpointBase::PropertyWatchpoint) \ 110 macro(CodeBlockJettisoning, CodeBlockJettisoningWatchpoint) \ 111 macro(LLIntPrototypeLoadAdaptiveStructure, LLIntPrototypeLoadAdaptiveStructureWatchpoint) \ 112 macro(FunctionRareDataAllocationProfileClearing, FunctionRareData::AllocationProfileClearingWatchpoint) \ 113 macro(ObjectToStringAdaptiveStructure, ObjectToStringAdaptiveStructureWatchpoint) 114 115 #if ENABLE(JIT) 116 #define JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro) \ 117 JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro) \ 118 macro(StructureStubClearing, StructureStubClearingWatchpoint) 119 120 #if ENABLE(DFG_JIT) 121 #define JSC_WATCHPOINT_TYPES(macro) \ 122 JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro) \ 123 macro(AdaptiveStructure, DFG::AdaptiveStructureWatchpoint) 124 #else 125 #define JSC_WATCHPOINT_TYPES(macro) \ 126 JSC_WATCHPOINT_TYPES_WITHOUT_DFG(macro) 127 #endif 128 129 #else 130 #define JSC_WATCHPOINT_TYPES(macro) \ 131 JSC_WATCHPOINT_TYPES_WITHOUT_JIT(macro) 132 #endif 133 134 #define JSC_WATCHPOINT_FIELD(type, member) \ 135 type member; \ 136 static_assert(std::is_trivially_destructible<type>::value, ""); \ 137 138 139 class Watchpoint : public PackedRawSentinelNode<Watchpoint> { 94 140 WTF_MAKE_NONCOPYABLE(Watchpoint); 95 141 WTF_MAKE_NONMOVABLE(Watchpoint); 96 142 WTF_MAKE_FAST_ALLOCATED; 97 143 public: 98 Watchpoint() = default; 99 100 virtual ~Watchpoint(); 144 #define JSC_DEFINE_WATCHPOINT_TYPES(type, _) type, 145 enum class Type : uint8_t { 146 JSC_WATCHPOINT_TYPES(JSC_DEFINE_WATCHPOINT_TYPES) 147 }; 148 #undef JSC_DEFINE_WATCHPOINT_TYPES 149 150 Watchpoint(Type type) 151 : m_type(type) 152 { } 101 153 102 154 protected: 103 virtual void fireInternal(VM&, const FireDetail&) = 0;155 ~Watchpoint(); 104 156 105 157 private: 106 158 friend class WatchpointSet; 107 159 void fire(VM&, const FireDetail&); 160 161 Type m_type; 108 162 }; 109 163 … … 240 294 int8_t m_setIsNotEmpty; 241 295 242 SentinelLinkedList<Watchpoint, BasicRawSentinelNode<Watchpoint>> m_set;296 SentinelLinkedList<Watchpoint, PackedRawSentinelNode<Watchpoint>> m_set; 243 297 }; 244 298 -
trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.cpp
r243560 r245214 34 34 namespace JSC { namespace DFG { 35 35 36 AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint( 37 const ObjectPropertyCondition& key, 38 CodeBlock* codeBlock) 39 : m_key(key) 36 AdaptiveStructureWatchpoint::AdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, CodeBlock* codeBlock) 37 : Watchpoint(Watchpoint::Type::AdaptiveStructure) 40 38 , m_codeBlock(codeBlock) 39 , m_key(key) 41 40 { 42 41 RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint()); -
trunk/Source/JavaScriptCore/dfg/DFGAdaptiveStructureWatchpoint.h
r243560 r245214 29 29 30 30 #include "ObjectPropertyCondition.h" 31 #include "PackedCellPtr.h" 31 32 #include "Watchpoint.h" 32 33 … … 41 42 void install(VM&); 42 43 43 protected: 44 void fireInternal(VM&, const FireDetail&) override; 44 void fireInternal(VM&, const FireDetail&); 45 45 46 46 private: 47 ObjectPropertyCondition m_key; 48 CodeBlock* m_codeBlock; 47 // Own destructor may not be called. Keep members trivially destructible. 48 JSC_WATCHPOINT_FIELD(PackedCellPtr<CodeBlock>, m_codeBlock); 49 JSC_WATCHPOINT_FIELD(ObjectPropertyCondition, m_key); 49 50 }; 50 51 -
trunk/Source/JavaScriptCore/runtime/FunctionRareData.h
r243560 r245214 29 29 #include "JSCast.h" 30 30 #include "ObjectAllocationProfile.h" 31 #include "PackedCellPtr.h" 31 32 #include "Watchpoint.h" 32 33 … … 111 112 } 112 113 114 class AllocationProfileClearingWatchpoint final : public Watchpoint { 115 public: 116 AllocationProfileClearingWatchpoint(FunctionRareData* rareData) 117 : Watchpoint(Watchpoint::Type::FunctionRareDataAllocationProfileClearing) 118 , m_rareData(rareData) 119 { } 120 121 void fireInternal(VM&, const FireDetail&); 122 123 private: 124 // Own destructor may not be called. Keep members trivially destructible. 125 JSC_WATCHPOINT_FIELD(PackedCellPtr<FunctionRareData>, m_rareData); 126 }; 127 113 128 protected: 114 129 FunctionRareData(VM&); … … 116 131 117 132 private: 118 119 class AllocationProfileClearingWatchpoint final : public Watchpoint {120 public:121 AllocationProfileClearingWatchpoint(FunctionRareData* rareData)122 : m_rareData(rareData)123 { }124 protected:125 void fireInternal(VM&, const FireDetail&) override;126 private:127 FunctionRareData* m_rareData;128 };129 130 133 friend class LLIntOffsetsExtractor; 131 134 -
trunk/Source/JavaScriptCore/runtime/StructureRareData.cpp
r243560 r245214 33 33 #include "JSCInlines.h" 34 34 #include "ObjectPropertyConditionSet.h" 35 #include "ObjectToStringAdaptiveStructureWatchpoint.h" 35 36 36 37 namespace JSC { … … 88 89 void handleFire(VM&, const FireDetail&) override; 89 90 90 StructureRareData* m_structureRareData;91 };92 93 class ObjectToStringAdaptiveStructureWatchpoint final : public Watchpoint {94 public:95 ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, StructureRareData*);96 97 void install(VM&);98 99 const ObjectPropertyCondition& key() const { return m_key; }100 101 protected:102 void fireInternal(VM&, const FireDetail&) override;103 104 private:105 ObjectPropertyCondition m_key;106 91 StructureRareData* m_structureRareData; 107 92 }; … … 165 150 } 166 151 167 inlinevoid StructureRareData::clearObjectToStringValue()152 void StructureRareData::clearObjectToStringValue() 168 153 { 169 154 m_objectToStringAdaptiveWatchpointSet.clear(); … … 190 175 // ------------- Methods for Object.prototype.toString() helper watchpoint classes -------------- 191 176 192 ObjectToStringAdaptiveStructureWatchpoint::ObjectToStringAdaptiveStructureWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData)193 : m_key(key)194 , m_structureRareData(structureRareData)195 {196 RELEASE_ASSERT(key.watchingRequiresStructureTransitionWatchpoint());197 RELEASE_ASSERT(!key.watchingRequiresReplacementWatchpoint());198 }199 200 void ObjectToStringAdaptiveStructureWatchpoint::install(VM& vm)201 {202 RELEASE_ASSERT(m_key.isWatchable());203 204 m_key.object()->structure(vm)->addTransitionWatchpoint(this);205 }206 207 void ObjectToStringAdaptiveStructureWatchpoint::fireInternal(VM& vm, const FireDetail&)208 {209 if (!m_structureRareData->isLive())210 return;211 212 if (m_key.isWatchable(PropertyCondition::EnsureWatchability)) {213 install(vm);214 return;215 }216 217 m_structureRareData->clearObjectToStringValue();218 }219 220 177 ObjectToStringAdaptiveInferredPropertyValueWatchpoint::ObjectToStringAdaptiveInferredPropertyValueWatchpoint(const ObjectPropertyCondition& key, StructureRareData* structureRareData) 221 178 : Base(key) -
trunk/Source/JavaScriptCore/runtime/StructureRareData.h
r243560 r245214 36 36 class JSPropertyNameEnumerator; 37 37 class Structure; 38 class ObjectToStringAdaptiveInferredPropertyValueWatchpoint; 38 39 class ObjectToStringAdaptiveStructureWatchpoint; 39 class ObjectToStringAdaptiveInferredPropertyValueWatchpoint;40 40 41 41 class StructureRareData final : public JSCell { -
trunk/Source/WTF/ChangeLog
r245202 r245214 1 2019-05-12 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Compress Watchpoint size by using enum type and Packed<> data structure 4 https://bugs.webkit.org/show_bug.cgi?id=197730 5 6 Reviewed by Filip Pizlo. 7 8 This patch introduces a new data structures, WTF::Packed, WTF::PackedPtr, and WTF::PackedAlignedPtr. 9 10 - WTF::Packed 11 12 WTF::Packed is data storage. We can read and write trivial (in C++ term [1]) data to this storage. The difference to 13 the usual storage is that the alignment of this storage is always 1. We access the underlying data by using unalignedLoad/unalignedStore. 14 This class offers alignment = 1 data structure instead of missing the following characteristics. 15 16 1. Load / Store are non atomic even if the data size is within a pointer width. We should not use this for a member which can be accessed 17 in a racy way. (e.g. fields accessed optimistically from the concurrent compilers). 18 19 2. We cannot take reference / pointer to the underlying storage since they are unaligned. 20 21 3. Access to this storage is unaligned access. The code is using memcpy, and the compiler will convert to an appropriate unaligned access 22 in certain architectures (x86_64 / ARM64). It could be slow. So use it for non performance sensitive & memory sensitive places. 23 24 - WTF::PackedPtr 25 26 WTF::PackedPtr is a specialization of WTF::Packed<T*>. And it is basically WTF::PackedAlignedPtr with alignment = 1. We further compact 27 the pointer by leveraging the platform specific knowledge. In 64bit architectures, the effective width of pointers are less than 64 bit. 28 In x86_64, it is 48 bits. And Darwin ARM64 is further smaller, 36 bits. This information allows us to compact the pointer to 6 bytes in 29 x86_64 and 5 bytes in Darwin ARM64. 30 31 - WTF::PackedAlignedPtr 32 33 WTF::PackedAlignedPtr is the WTF::PackedPtr with alignment information of the T. If we use this alignment information, we could reduce the 34 size of packed pointer further in some cases. For example, since we guarantee that JSCells are 16 byte aligned, low 4 bits are empty. Leveraging 35 this information in Darwin ARM64 platform allows us to make packed JSCell pointer 4 bytes (36 - 4 bits). We do not use passed alignment 36 information if it is not profitable. 37 38 We also have PackedPtrTraits. This is new PtrTraits and use it for various data structures such as Bag<>. 39 40 [1]: https://en.cppreference.com/w/cpp/types/is_trivial 41 42 * WTF.xcodeproj/project.pbxproj: 43 * wtf/Bag.h: 44 (WTF::Bag::clear): 45 (WTF::Bag::iterator::operator++): 46 * wtf/CMakeLists.txt: 47 * wtf/DumbPtrTraits.h: 48 * wtf/DumbValueTraits.h: 49 * wtf/MathExtras.h: 50 (WTF::clzConstexpr): 51 (WTF::clz): 52 (WTF::ctzConstexpr): 53 (WTF::ctz): 54 (WTF::getLSBSetConstexpr): 55 (WTF::getMSBSetConstexpr): 56 * wtf/Packed.h: Added. 57 (WTF::Packed::Packed): 58 (WTF::Packed::get const): 59 (WTF::Packed::set): 60 (WTF::Packed::operator=): 61 (WTF::Packed::exchange): 62 (WTF::Packed::swap): 63 (WTF::alignof): 64 (WTF::PackedPtrTraits::exchange): 65 (WTF::PackedPtrTraits::swap): 66 (WTF::PackedPtrTraits::unwrap): 67 * wtf/Platform.h: 68 * wtf/SentinelLinkedList.h: 69 (WTF::BasicRawSentinelNode::BasicRawSentinelNode): 70 (WTF::BasicRawSentinelNode::prev): 71 (WTF::BasicRawSentinelNode::next): 72 (WTF::PtrTraits>::remove): 73 (WTF::PtrTraits>::prepend): 74 (WTF::PtrTraits>::append): 75 (WTF::RawNode>::SentinelLinkedList): 76 (WTF::RawNode>::remove): 77 (WTF::BasicRawSentinelNode<T>::remove): Deleted. 78 (WTF::BasicRawSentinelNode<T>::prepend): Deleted. 79 (WTF::BasicRawSentinelNode<T>::append): Deleted. 80 * wtf/StdLibExtras.h: 81 (WTF::roundUpToMultipleOfImpl): 82 (WTF::roundUpToMultipleOfImpl0): Deleted. 83 * wtf/UnalignedAccess.h: 84 (WTF::unalignedLoad): 85 (WTF::unalignedStore): 86 1 87 2019-05-10 Saam barati <sbarati@apple.com> 2 88 -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r245064 r245214 659 659 E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRegisters.h; sourceTree = "<group>"; }; 660 660 E33D5F871FBED66700BF625E /* RecursableLambda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursableLambda.h; sourceTree = "<group>"; }; 661 E34CD0D022810A020020D299 /* Packed.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Packed.h; sourceTree = "<group>"; }; 661 662 E360C7642127B85B00C90F0E /* UnalignedAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnalignedAccess.h; sourceTree = "<group>"; }; 662 663 E360C7652127B85C00C90F0E /* Unexpected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unexpected.h; sourceTree = "<group>"; }; … … 1057 1058 A8A472DA151A825B004123FF /* OSRandomSource.cpp */, 1058 1059 A8A472DB151A825B004123FF /* OSRandomSource.h */, 1060 E34CD0D022810A020020D299 /* Packed.h */, 1059 1061 A8A472DF151A825B004123FF /* PackedIntVector.h */, 1060 1062 A8A472E0151A825B004123FF /* PageAllocation.h */, -
trunk/Source/WTF/wtf/Bag.h
r245202 r245214 29 29 #include <wtf/FastMalloc.h> 30 30 #include <wtf/Noncopyable.h> 31 #include <wtf/Packed.h> 31 32 32 33 namespace WTF { … … 34 35 namespace Private { 35 36 36 template<typename T >37 template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>> 37 38 class BagNode { 38 39 WTF_MAKE_FAST_ALLOCATED; 39 40 public: 41 using PtrTraits = typename PassedPtrTraits::template RebindTraits<BagNode>; 42 40 43 template<typename... Args> 41 44 BagNode(Args&&... args) … … 44 47 45 48 T m_item; 46 BagNode*m_next { nullptr };49 typename PtrTraits::StorageType m_next { nullptr }; 47 50 }; 48 51 49 52 } // namespace Private 50 53 51 template<typename T, typename P trTraits = DumbPtrTraits<Private::BagNode<T>>>54 template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>> 52 55 class Bag { 53 56 WTF_MAKE_NONCOPYABLE(Bag); 54 57 WTF_MAKE_FAST_ALLOCATED; 55 using Node = Private::BagNode<T>; 58 using Node = Private::BagNode<T, PassedPtrTraits>; 59 using PtrTraits = typename PassedPtrTraits::template RebindTraits<Node>; 56 60 57 61 public: … … 76 80 while (head) { 77 81 Node* current = head; 78 head = current->m_next;82 head = Node::PtrTraits::unwrap(current->m_next); 79 83 delete current; 80 84 } … … 105 109 iterator& operator++() 106 110 { 107 m_node = m_node->m_next;111 m_node = Node::PtrTraits::unwrap(m_node->m_next); 108 112 return *this; 109 113 } … … 149 153 }; 150 154 155 template<typename T> 156 using PackedBag = Bag<T, PackedPtrTraits<T>>; 157 151 158 } // namespace WTF 152 159 153 160 using WTF::Bag; 161 using WTF::PackedBag; -
trunk/Source/WTF/wtf/CMakeLists.txt
r245064 r245214 151 151 Optional.h 152 152 OrderMaker.h 153 Packed.h 153 154 PackedIntVector.h 154 155 PageAllocation.h -
trunk/Source/WTF/wtf/DumbPtrTraits.h
r227527 r245214 33 33 template<typename T> 34 34 struct DumbPtrTraits { 35 template<typename U> using RebindTraits = DumbPtrTraits<U>; 36 35 37 using StorageType = T*; 36 38 -
trunk/Source/WTF/wtf/DumbValueTraits.h
r227527 r245214 33 33 template<typename T> 34 34 struct DumbValueTraits { 35 template<typename U> using RebindTraits = DumbValueTraits<U>; 36 35 37 using StorageType = T; 36 38 -
trunk/Source/WTF/wtf/MathExtras.h
r243544 r245214 616 616 } 617 617 618 template <typename T> 619 constexpr unsigned clzConstexpr(T value) 620 { 621 constexpr unsigned bitSize = sizeof(T) * CHAR_BIT; 622 623 using UT = typename std::make_unsigned<T>::type; 624 UT uValue = value; 625 626 unsigned zeroCount = 0; 627 for (int i = bitSize - 1; i >= 0; i--) { 628 if (uValue >> i) 629 break; 630 zeroCount++; 631 } 632 return zeroCount; 633 } 634 618 635 template<typename T> 619 636 inline unsigned clz(T value) … … 638 655 return bitSize; 639 656 #else 657 UNUSED_PARAM(bitSize); 658 UNUSED_PARAM(uValue); 659 return clzConstexpr(value); 660 #endif 661 } 662 663 template <typename T> 664 constexpr unsigned ctzConstexpr(T value) 665 { 666 constexpr unsigned bitSize = sizeof(T) * CHAR_BIT; 667 668 using UT = typename std::make_unsigned<T>::type; 669 UT uValue = value; 670 640 671 unsigned zeroCount = 0; 641 for ( int i = bitSize - 1; i >= 0; i--) {642 if (uValue >> i)672 for (unsigned i = 0; i < bitSize; i++) { 673 if (uValue & 1) 643 674 break; 675 644 676 zeroCount++; 677 uValue >>= 1; 645 678 } 646 679 return zeroCount; 647 #endif648 680 } 649 681 … … 666 698 return bitSize; 667 699 #else 668 unsigned zeroCount = 0; 669 for (unsigned i = 0; i < bitSize; i++) { 670 if (uValue & 1) 671 break; 672 673 zeroCount++; 674 uValue >>= 1; 675 } 676 return zeroCount; 700 UNUSED_PARAM(bitSize); 701 UNUSED_PARAM(uValue); 702 return ctzConstexpr(value); 677 703 #endif 678 704 } … … 683 709 ASSERT(t); 684 710 return ctz(t); 711 } 712 713 template<typename T> 714 constexpr unsigned getLSBSetConstexpr(T t) 715 { 716 ASSERT_UNDER_CONSTEXPR_CONTEXT(t); 717 return ctzConstexpr(t); 685 718 } 686 719 … … 691 724 ASSERT(t); 692 725 return bitSize - 1 - clz(t); 726 } 727 728 template<typename T> 729 constexpr unsigned getMSBSetConstexpr(T t) 730 { 731 constexpr unsigned bitSize = sizeof(T) * CHAR_BIT; 732 ASSERT_UNDER_CONSTEXPR_CONTEXT(t); 733 return bitSize - 1 - clzConstexpr(t); 693 734 } 694 735 -
trunk/Source/WTF/wtf/Platform.h
r245075 r245214 748 748 #endif 749 749 750 #if CPU(ADDRESS64) 751 #if OS(DARWIN) && CPU(ARM64) 752 #define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 36 753 #else 754 /* We strongly assume that effective address width is <= 48 in 64bit architectures (e.g. NaN boxing). */ 755 #define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 48 756 #endif 757 #else 758 #define WTF_CPU_EFFECTIVE_ADDRESS_WIDTH 32 759 #endif 760 750 761 #if !defined(USE_JSVALUE64) && !defined(USE_JSVALUE32_64) 751 762 #if CPU(ADDRESS64) || CPU(ARM64) -
trunk/Source/WTF/wtf/SentinelLinkedList.h
r237099 r245214 37 37 #pragma once 38 38 39 #include <wtf/Packed.h> 40 39 41 namespace WTF { 40 42 41 43 enum SentinelTag { Sentinel }; 42 44 43 template<typename T >45 template<typename T, typename PassedPtrTraits = DumbPtrTraits<T>> 44 46 class BasicRawSentinelNode { 45 47 WTF_MAKE_FAST_ALLOCATED; 46 48 public: 49 using PtrTraits = typename PassedPtrTraits::template RebindTraits<BasicRawSentinelNode>; 50 47 51 BasicRawSentinelNode(SentinelTag) 48 : m_next(0)49 , m_prev(0)50 52 { 51 53 } 52 54 53 BasicRawSentinelNode() 54 : m_next(0) 55 , m_prev(0) 56 { 57 } 55 BasicRawSentinelNode() = default; 58 56 59 57 void setPrev(BasicRawSentinelNode* prev) { m_prev = prev; } 60 58 void setNext(BasicRawSentinelNode* next) { m_next = next; } 61 59 62 T* prev() { return static_cast<T*>( m_prev); }63 T* next() { return static_cast<T*>( m_next); }60 T* prev() { return static_cast<T*>(PtrTraits::unwrap(m_prev)); } 61 T* next() { return static_cast<T*>(PtrTraits::unwrap(m_next)); } 64 62 65 63 bool isOnList() const … … 75 73 76 74 private: 77 BasicRawSentinelNode* m_next;78 BasicRawSentinelNode* m_prev;75 typename PtrTraits::StorageType m_next { nullptr }; 76 typename PtrTraits::StorageType m_prev { nullptr }; 79 77 }; 80 78 … … 119 117 }; 120 118 121 template <typename T > void BasicRawSentinelNode<T>::remove()122 { 123 SentinelLinkedList<T, BasicRawSentinelNode <T>>::remove(static_cast<T*>(this));124 } 125 126 template <typename T > void BasicRawSentinelNode<T>::prepend(BasicRawSentinelNode* node)127 { 128 SentinelLinkedList<T, BasicRawSentinelNode <T>>::prepend(119 template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::remove() 120 { 121 SentinelLinkedList<T, BasicRawSentinelNode>::remove(static_cast<T*>(this)); 122 } 123 124 template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::prepend(BasicRawSentinelNode* node) 125 { 126 SentinelLinkedList<T, BasicRawSentinelNode>::prepend( 129 127 static_cast<T*>(this), static_cast<T*>(node)); 130 128 } 131 129 132 template <typename T > void BasicRawSentinelNode<T>::append(BasicRawSentinelNode* node)133 { 134 SentinelLinkedList<T, BasicRawSentinelNode <T>>::append(130 template <typename T, typename PtrTraits> void BasicRawSentinelNode<T, PtrTraits>::append(BasicRawSentinelNode* node) 131 { 132 SentinelLinkedList<T, BasicRawSentinelNode>::append( 135 133 static_cast<T*>(this), static_cast<T*>(node)); 136 134 } … … 141 139 { 142 140 m_headSentinel.setNext(&m_tailSentinel); 143 m_headSentinel.setPrev( 0);141 m_headSentinel.setPrev(nullptr); 144 142 145 143 m_tailSentinel.setPrev(&m_headSentinel); 146 m_tailSentinel.setNext( 0);144 m_tailSentinel.setNext(nullptr); 147 145 } 148 146 … … 201 199 next->setPrev(prev); 202 200 203 node->setPrev( 0);204 node->setNext( 0);201 node->setPrev(nullptr); 202 node->setNext(nullptr); 205 203 } 206 204 … … 272 270 } 273 271 272 template<typename T> 273 using PackedRawSentinelNode = BasicRawSentinelNode<T, PackedPtrTraits<T>>; 274 274 275 } 275 276 276 277 using WTF::BasicRawSentinelNode; 278 using WTF::PackedRawSentinelNode; 277 279 using WTF::SentinelLinkedList; -
trunk/Source/WTF/wtf/StdLibExtras.h
r244656 r245214 173 173 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) 174 174 175 ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl0(size_t remainderMask, size_t x) 176 { 175 ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl(size_t divisor, size_t x) 176 { 177 size_t remainderMask = divisor - 1; 177 178 return (x + remainderMask) & ~remainderMask; 178 }179 180 ALWAYS_INLINE constexpr size_t roundUpToMultipleOfImpl(size_t divisor, size_t x)181 {182 return roundUpToMultipleOfImpl0(divisor - 1, x);183 179 } 184 180 -
trunk/Source/WTF/wtf/UnalignedAccess.h
r235018 r245214 32 32 namespace WTF { 33 33 34 template<typename IntegralType>35 inline IntegralType unalignedLoad(const void* pointer)34 template<typename Type> 35 inline Type unalignedLoad(const void* pointer) 36 36 { 37 static_assert(std::is_ integral<IntegralType>::value || std::is_pointer<IntegralType>::value, "");38 IntegralType result { };39 memcpy(&result, pointer, sizeof( IntegralType));37 static_assert(std::is_trivial<Type>::value, ""); 38 Type result { }; 39 memcpy(&result, pointer, sizeof(Type)); 40 40 return result; 41 41 } 42 42 43 template<typename IntegralType>44 inline void unalignedStore(void* pointer, IntegralType value)43 template<typename Type> 44 inline void unalignedStore(void* pointer, Type value) 45 45 { 46 static_assert(std::is_ integral<IntegralType>::value || std::is_pointer<IntegralType>::value, "");47 memcpy(pointer, &value, sizeof( IntegralType));46 static_assert(std::is_trivial<Type>::value, ""); 47 memcpy(pointer, &value, sizeof(Type)); 48 48 } 49 49 -
trunk/Tools/ChangeLog
r245204 r245214 1 2019-05-12 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Compress Watchpoint size by using enum type and Packed<> data structure 4 https://bugs.webkit.org/show_bug.cgi?id=197730 5 6 Reviewed by Filip Pizlo. 7 8 * TestWebKitAPI/CMakeLists.txt: 9 * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj: 10 * TestWebKitAPI/Tests/WTF/MathExtras.cpp: 11 (TestWebKitAPI::TEST): 12 * TestWebKitAPI/Tests/WTF/Packed.cpp: Added. 13 (TestWebKitAPI::TEST): 14 1 15 2019-05-10 Chris Dumez <cdumez@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/CMakeLists.txt
r244857 r245214 61 61 Tests/WTF/OptionSet.cpp 62 62 Tests/WTF/Optional.cpp 63 Tests/WTF/Packed.cpp 63 64 Tests/WTF/ParkingLot.cpp 64 65 Tests/WTF/PriorityQueue.cpp -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r245039 r245214 861 861 E194E1BD177E53C7009C4D4E /* StopLoadingFromDidReceiveResponse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */; }; 862 862 E324A6F02041C82000A76593 /* UniqueArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E398BC0F2041C76300387136 /* UniqueArray.cpp */; }; 863 E32B549222810AC4008AD702 /* Packed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E32B549122810AC0008AD702 /* Packed.cpp */; }; 863 864 E373D7911F2CF35200C6FAAF /* Signals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3953F951F2CF32100A76A2E /* Signals.cpp */; }; 864 865 E38A0D351FD50CC300E98C8B /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38A0D341FD50CBC00E98C8B /* Threading.cpp */; }; … … 2232 2233 E194E1BC177E534A009C4D4E /* StopLoadingFromDidReceiveResponse.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = StopLoadingFromDidReceiveResponse.html; sourceTree = "<group>"; }; 2233 2234 E19DB9781B32137C00DB38D4 /* NavigatorLanguage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigatorLanguage.mm; sourceTree = "<group>"; }; 2235 E32B549122810AC0008AD702 /* Packed.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Packed.cpp; sourceTree = "<group>"; }; 2234 2236 E388887020C9098100E632BC /* WorkerPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerPool.cpp; sourceTree = "<group>"; }; 2235 2237 E38A0D341FD50CBC00E98C8B /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; }; … … 3350 3352 1AFDE6541953B2C000C48FFA /* Optional.cpp */, 3351 3353 CE50D8C81C8665CE0072EA5A /* OptionSet.cpp */, 3354 E32B549122810AC0008AD702 /* Packed.cpp */, 3352 3355 0FE447971B76F1E3009498EB /* ParkingLot.cpp */, 3353 3356 53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */, … … 3963 3966 1A77BAA31D9AFFFC005FC568 /* OptionSet.cpp in Sources */, 3964 3967 7C83DF021D0A590C00FEBCF3 /* OSObjectPtr.cpp in Sources */, 3968 E32B549222810AC4008AD702 /* Packed.cpp in Sources */, 3965 3969 7C83DF591D0A590C00FEBCF3 /* ParkingLot.cpp in Sources */, 3966 3970 53EC25411E96FD87000831B9 /* PriorityQueue.cpp in Sources */, -
trunk/Tools/TestWebKitAPI/Tests/WTF/MathExtras.cpp
r243418 r245214 508 508 } 509 509 510 TEST(WTF, clzConstexpr) 511 { 512 EXPECT_EQ(WTF::clzConstexpr<int32_t>(1), 31U); 513 EXPECT_EQ(WTF::clzConstexpr<int32_t>(42), 26U); 514 EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); 515 EXPECT_EQ(WTF::clzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 1U); 516 EXPECT_EQ(WTF::clzConstexpr<uint32_t>(0), 32U); 517 518 EXPECT_EQ(WTF::clzConstexpr<int8_t>(42), 2U); 519 EXPECT_EQ(WTF::clzConstexpr<int8_t>(3), 6U); 520 EXPECT_EQ(WTF::clzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); 521 EXPECT_EQ(WTF::clzConstexpr<uint8_t>(0), 8U); 522 523 EXPECT_EQ(WTF::clzConstexpr<int64_t>(-1), 0U); 524 EXPECT_EQ(WTF::clzConstexpr<int64_t>(1), 63U); 525 EXPECT_EQ(WTF::clzConstexpr<int64_t>(3), 62U); 526 EXPECT_EQ(WTF::clzConstexpr<uint64_t>(42), 58U); 527 EXPECT_EQ(WTF::clzConstexpr<uint64_t>(0), 64U); 528 } 529 530 TEST(WTF, ctzConstexpr) 531 { 532 EXPECT_EQ(WTF::ctzConstexpr<int32_t>(1), 0U); 533 EXPECT_EQ(WTF::ctzConstexpr<int32_t>(42), 1U); 534 EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); 535 EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); 536 EXPECT_EQ(WTF::ctzConstexpr<uint32_t>(0), 32U); 537 538 EXPECT_EQ(WTF::ctzConstexpr<int8_t>(42), 1U); 539 EXPECT_EQ(WTF::ctzConstexpr<int8_t>(3), 0U); 540 EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); 541 EXPECT_EQ(WTF::ctzConstexpr<uint8_t>(0), 8U); 542 543 EXPECT_EQ(WTF::ctzConstexpr<int64_t>(static_cast<uint32_t>(-1)), 0U); 544 EXPECT_EQ(WTF::ctzConstexpr<int64_t>(1), 0U); 545 EXPECT_EQ(WTF::ctzConstexpr<int64_t>(3), 0U); 546 EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(42), 1U); 547 EXPECT_EQ(WTF::ctzConstexpr<uint64_t>(0), 64U); 548 } 549 550 TEST(WTF, getLSBSetConstexpr) 551 { 552 EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(1), 0U); 553 EXPECT_EQ(WTF::getLSBSetConstexpr<int32_t>(42), 1U); 554 EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 0U); 555 EXPECT_EQ(WTF::getLSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); 556 557 EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(42), 1U); 558 EXPECT_EQ(WTF::getLSBSetConstexpr<int8_t>(3), 0U); 559 EXPECT_EQ(WTF::getLSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 0U); 560 561 EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(-1), 0U); 562 EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(1), 0U); 563 EXPECT_EQ(WTF::getLSBSetConstexpr<int64_t>(3), 0U); 564 EXPECT_EQ(WTF::getLSBSetConstexpr<uint64_t>(42), 1U); 565 } 566 567 TEST(WTF, getMSBSetConstexpr) 568 { 569 EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(1), 0U); 570 EXPECT_EQ(WTF::getMSBSetConstexpr<int32_t>(42), 5U); 571 EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(-1)), 31U); 572 EXPECT_EQ(WTF::getMSBSetConstexpr<uint32_t>(static_cast<uint32_t>(std::numeric_limits<int32_t>::min()) >> 1), 30U); 573 574 EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(42), 5U); 575 EXPECT_EQ(WTF::getMSBSetConstexpr<int8_t>(3), 1U); 576 EXPECT_EQ(WTF::getMSBSetConstexpr<uint8_t>(static_cast<uint8_t>(-1)), 7U); 577 578 EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(-1), 63U); 579 EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(1), 0U); 580 EXPECT_EQ(WTF::getMSBSetConstexpr<int64_t>(3), 1U); 581 EXPECT_EQ(WTF::getMSBSetConstexpr<uint64_t>(42), 5U); 582 } 583 510 584 } // namespace TestWebKitAPI
Note:
See TracChangeset
for help on using the changeset viewer.