[JSC] Compress JIT related data more by using Packed<>
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 May 2019 02:34:28 +0000 (02:34 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 May 2019 02:34:28 +0000 (02:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197866

Reviewed by Saam Barati.

This patch leverages Packed<> more to reduce JIT related data size. When we measure memory usage on Gmail, we found that a lot of memory is
consumed in DFG data. This patch attempts to reduce that size by using Packed<> to make various data structure's alignment 1.

* dfg/DFGCommonData.cpp:
(JSC::DFG::CommonData::shrinkToFit): Add more shrinkToFit.
* dfg/DFGMinifiedID.h: Make alignment = 1.
(JSC::DFG::MinifiedID::operator! const):
(JSC::DFG::MinifiedID::operator== const):
(JSC::DFG::MinifiedID::operator!= const):
(JSC::DFG::MinifiedID::operator< const):
(JSC::DFG::MinifiedID::operator> const):
(JSC::DFG::MinifiedID::operator<= const):
(JSC::DFG::MinifiedID::operator>= const):
(JSC::DFG::MinifiedID::hash const):
(JSC::DFG::MinifiedID::dump const):
(JSC::DFG::MinifiedID::isHashTableDeletedValue const):
(JSC::DFG::MinifiedID::bits const):
* dfg/DFGMinifiedIDInlines.h:
(JSC::DFG::MinifiedID::MinifiedID):
* dfg/DFGMinifiedNode.cpp:
(JSC::DFG::MinifiedNode::fromNode): Make sizeof(MinifiedNode) from 16 to 13 with alignment = 1.
* dfg/DFGMinifiedNode.h:
(JSC::DFG::MinifiedNode::id const):
(JSC::DFG::MinifiedNode::hasConstant const):
(JSC::DFG::MinifiedNode::constant const):
(JSC::DFG::MinifiedNode::isPhantomDirectArguments const):
(JSC::DFG::MinifiedNode::isPhantomClonedArguments const):
(JSC::DFG::MinifiedNode::hasInlineCallFrame const):
(JSC::DFG::MinifiedNode::inlineCallFrame const):
(JSC::DFG::MinifiedNode::op const): Deleted.
(JSC::DFG::MinifiedNode::hasInlineCallFrame): Deleted.
* dfg/DFGVariableEvent.h: Make sizeof(VariableEvent) from 12 to 10 with alignment = 1.
(JSC::DFG::VariableEvent::fillGPR):
(JSC::DFG::VariableEvent::fillPair):
(JSC::DFG::VariableEvent::fillFPR):
(JSC::DFG::VariableEvent::birth):
(JSC::DFG::VariableEvent::spill):
(JSC::DFG::VariableEvent::death):
(JSC::DFG::VariableEvent::setLocal):
(JSC::DFG::VariableEvent::movHint):
(JSC::DFG::VariableEvent::id const):
(JSC::DFG::VariableEvent::gpr const):
(JSC::DFG::VariableEvent::tagGPR const):
(JSC::DFG::VariableEvent::payloadGPR const):
(JSC::DFG::VariableEvent::fpr const):
(JSC::DFG::VariableEvent::spillRegister const):
(JSC::DFG::VariableEvent::bytecodeRegister const):
(JSC::DFG::VariableEvent::machineRegister const):
(JSC::DFG::VariableEvent::variableRepresentation const):
* dfg/DFGVariableEventStream.cpp:
(JSC::DFG::tryToSetConstantRecovery):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGCommonData.cpp
Source/JavaScriptCore/dfg/DFGMinifiedID.h
Source/JavaScriptCore/dfg/DFGMinifiedIDInlines.h
Source/JavaScriptCore/dfg/DFGMinifiedNode.cpp
Source/JavaScriptCore/dfg/DFGMinifiedNode.h
Source/JavaScriptCore/dfg/DFGVariableEvent.h
Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp

index f075585..c20f93b 100644 (file)
@@ -1,5 +1,64 @@
 2019-05-13  Yusuke Suzuki  <ysuzuki@apple.com>
 
+        [JSC] Compress JIT related data more by using Packed<>
+        https://bugs.webkit.org/show_bug.cgi?id=197866
+
+        Reviewed by Saam Barati.
+
+        This patch leverages Packed<> more to reduce JIT related data size. When we measure memory usage on Gmail, we found that a lot of memory is
+        consumed in DFG data. This patch attempts to reduce that size by using Packed<> to make various data structure's alignment 1.
+
+        * dfg/DFGCommonData.cpp:
+        (JSC::DFG::CommonData::shrinkToFit): Add more shrinkToFit.
+        * dfg/DFGMinifiedID.h: Make alignment = 1.
+        (JSC::DFG::MinifiedID::operator! const):
+        (JSC::DFG::MinifiedID::operator== const):
+        (JSC::DFG::MinifiedID::operator!= const):
+        (JSC::DFG::MinifiedID::operator< const):
+        (JSC::DFG::MinifiedID::operator> const):
+        (JSC::DFG::MinifiedID::operator<= const):
+        (JSC::DFG::MinifiedID::operator>= const):
+        (JSC::DFG::MinifiedID::hash const):
+        (JSC::DFG::MinifiedID::dump const):
+        (JSC::DFG::MinifiedID::isHashTableDeletedValue const):
+        (JSC::DFG::MinifiedID::bits const):
+        * dfg/DFGMinifiedIDInlines.h:
+        (JSC::DFG::MinifiedID::MinifiedID):
+        * dfg/DFGMinifiedNode.cpp:
+        (JSC::DFG::MinifiedNode::fromNode): Make sizeof(MinifiedNode) from 16 to 13 with alignment = 1.
+        * dfg/DFGMinifiedNode.h:
+        (JSC::DFG::MinifiedNode::id const):
+        (JSC::DFG::MinifiedNode::hasConstant const):
+        (JSC::DFG::MinifiedNode::constant const):
+        (JSC::DFG::MinifiedNode::isPhantomDirectArguments const):
+        (JSC::DFG::MinifiedNode::isPhantomClonedArguments const):
+        (JSC::DFG::MinifiedNode::hasInlineCallFrame const):
+        (JSC::DFG::MinifiedNode::inlineCallFrame const):
+        (JSC::DFG::MinifiedNode::op const): Deleted.
+        (JSC::DFG::MinifiedNode::hasInlineCallFrame): Deleted.
+        * dfg/DFGVariableEvent.h: Make sizeof(VariableEvent) from 12 to 10 with alignment = 1.
+        (JSC::DFG::VariableEvent::fillGPR):
+        (JSC::DFG::VariableEvent::fillPair):
+        (JSC::DFG::VariableEvent::fillFPR):
+        (JSC::DFG::VariableEvent::birth):
+        (JSC::DFG::VariableEvent::spill):
+        (JSC::DFG::VariableEvent::death):
+        (JSC::DFG::VariableEvent::setLocal):
+        (JSC::DFG::VariableEvent::movHint):
+        (JSC::DFG::VariableEvent::id const):
+        (JSC::DFG::VariableEvent::gpr const):
+        (JSC::DFG::VariableEvent::tagGPR const):
+        (JSC::DFG::VariableEvent::payloadGPR const):
+        (JSC::DFG::VariableEvent::fpr const):
+        (JSC::DFG::VariableEvent::spillRegister const):
+        (JSC::DFG::VariableEvent::bytecodeRegister const):
+        (JSC::DFG::VariableEvent::machineRegister const):
+        (JSC::DFG::VariableEvent::variableRepresentation const):
+        * dfg/DFGVariableEventStream.cpp:
+        (JSC::DFG::tryToSetConstantRecovery):
+
+2019-05-13  Yusuke Suzuki  <ysuzuki@apple.com>
+
         [WTF] Simplify GCThread and CompilationThread flags by adding them to WTF::Thread
         https://bugs.webkit.org/show_bug.cgi?id=197146
 
index 73554bc..5b6cf5c 100644 (file)
@@ -85,9 +85,12 @@ void CommonData::removeCallSiteIndex(CallSiteIndex callSite)
 void CommonData::shrinkToFit()
 {
     codeOrigins.shrinkToFit();
+    dfgIdentifiers.shrinkToFit();
     weakReferences.shrinkToFit();
+    weakStructureReferences.shrinkToFit();
     transitions.shrinkToFit();
     catchEntrypoints.shrinkToFit();
+    jumpReplacements.shrinkToFit();
 }
 
 static Lock pcCodeBlockMapLock;
index a645cfa..8cdcfc7 100644 (file)
@@ -42,20 +42,20 @@ public:
     MinifiedID(WTF::HashTableDeletedValueType) : m_index(otherInvalidIndex()) { }
     explicit MinifiedID(Node* node);
     
-    bool operator!() const { return m_index == invalidIndex(); }
+    bool operator!() const { return m_index.get() == invalidIndex(); }
     
-    bool operator==(const MinifiedID& other) const { return m_index == other.m_index; }
-    bool operator!=(const MinifiedID& other) const { return m_index != other.m_index; }
-    bool operator<(const MinifiedID& other) const { return m_index < other.m_index; }
-    bool operator>(const MinifiedID& other) const { return m_index > other.m_index; }
-    bool operator<=(const MinifiedID& other) const { return m_index <= other.m_index; }
-    bool operator>=(const MinifiedID& other) const { return m_index >= other.m_index; }
+    bool operator==(const MinifiedID& other) const { return m_index.get() == other.m_index.get(); }
+    bool operator!=(const MinifiedID& other) const { return m_index.get() != other.m_index.get(); }
+    bool operator<(const MinifiedID& other) const { return m_index.get() < other.m_index.get(); }
+    bool operator>(const MinifiedID& other) const { return m_index.get() > other.m_index.get(); }
+    bool operator<=(const MinifiedID& other) const { return m_index.get() <= other.m_index.get(); }
+    bool operator>=(const MinifiedID& other) const { return m_index.get() >= other.m_index.get(); }
     
-    unsigned hash() const { return WTF::IntHash<unsigned>::hash(m_index); }
+    unsigned hash() const { return WTF::IntHash<unsigned>::hash(m_index.get()); }
     
-    void dump(PrintStream& out) const { out.print(m_index); }
+    void dump(PrintStream& out) const { out.print(m_index.get()); }
     
-    bool isHashTableDeletedValue() const { return m_index == otherInvalidIndex(); }
+    bool isHashTableDeletedValue() const { return m_index.get() == otherInvalidIndex(); }
     
     static MinifiedID fromBits(unsigned value)
     {
@@ -64,7 +64,7 @@ public:
         return result;
     }
     
-    unsigned bits() const { return m_index; }
+    unsigned bits() const { return m_index.get(); }
 
 private:
     friend class MinifiedNode;
@@ -72,7 +72,7 @@ private:
     static constexpr unsigned invalidIndex() { return static_cast<unsigned>(-1); }
     static constexpr unsigned otherInvalidIndex() { return static_cast<unsigned>(-2); }
     
-    unsigned m_index { invalidIndex() };
+    Packed<unsigned> m_index { invalidIndex() };
 };
 
 struct MinifiedIDHash {
index 3869cf7..5ea8137 100644 (file)
@@ -35,7 +35,7 @@ namespace DFG {
 inline MinifiedID::MinifiedID(Node* node)
     : m_index(node->index())
 {
-    RELEASE_ASSERT(m_index != invalidIndex() && m_index != otherInvalidIndex());
+    RELEASE_ASSERT(m_index.get() != invalidIndex() && m_index.get() != otherInvalidIndex());
 }
 
 } } // namespace JSC::DFG
index 9a2ff99..90324c9 100644 (file)
@@ -39,7 +39,9 @@ MinifiedNode MinifiedNode::fromNode(Node* node)
     ASSERT(belongsInMinifiedGraph(node->op()));
     MinifiedNode result;
     result.m_id = MinifiedID(node);
-    result.m_op = node->op();
+    result.m_hasConstant = hasConstant(node->op());
+    result.m_isPhantomDirectArguments = node->op() == PhantomDirectArguments;
+    result.m_isPhantomClonedArguments = node->op() == PhantomClonedArguments;
     if (hasConstant(node->op()))
         result.m_info = JSValue::encode(node->asJSValue());
     else {
index de6cd4c..ae5f9d0 100644 (file)
@@ -57,20 +57,21 @@ public:
     static MinifiedNode fromNode(Node*);
     
     MinifiedID id() const { return m_id; }
-    NodeType op() const { return m_op; }
     
-    bool hasConstant() const { return hasConstant(m_op); }
+    bool hasConstant() const { return m_hasConstant; }
     
     JSValue constant() const
     {
-        return JSValue::decode(bitwise_cast<EncodedJSValue>(m_info));
+        return JSValue::decode(bitwise_cast<EncodedJSValue>(m_info.get()));
     }
     
-    bool hasInlineCallFrame() const { return hasInlineCallFrame(m_op); }
+    bool isPhantomDirectArguments() const { return m_isPhantomDirectArguments; }
+    bool isPhantomClonedArguments() const { return m_isPhantomClonedArguments; }
+    bool hasInlineCallFrame() const { return m_isPhantomDirectArguments || m_isPhantomClonedArguments; }
     
     InlineCallFrame* inlineCallFrame() const
     {
-        return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(m_info));
+        return bitwise_cast<InlineCallFrame*>(static_cast<uintptr_t>(m_info.get()));
     }
     
     static MinifiedID getID(MinifiedNode* node) { return node->id(); }
@@ -85,14 +86,11 @@ private:
         return type == JSConstant || type == Int52Constant || type == DoubleConstant;
     }
     
-    static bool hasInlineCallFrame(NodeType type)
-    {
-        return type == PhantomDirectArguments || type == PhantomClonedArguments;
-    }
-    
-    uint64_t m_info;
+    Packed<uint64_t> m_info;
     MinifiedID m_id;
-    NodeType m_op;
+    bool m_hasConstant : 1;
+    bool m_isPhantomDirectArguments : 1;
+    bool m_isPhantomClonedArguments : 1;
 };
 
 } } // namespace JSC::DFG
index ac25327..2060d4a 100644 (file)
@@ -35,7 +35,7 @@
 
 namespace JSC { namespace DFG {
 
-enum VariableEventKind {
+enum VariableEventKind : uint8_t {
     // Marks the beginning of a checkpoint. If you interpret the variable
     // events starting at a Reset point then you'll get everything you need.
     Reset,
@@ -101,10 +101,14 @@ public:
         ASSERT(!(dataFormat & DataFormatJS));
 #endif
         VariableEvent event;
-        event.m_which.id = id.bits();
-        event.m_representation.gpr = gpr;
+        WhichType which;
+        which.id = id.bits();
+        VariableRepresentation representation;
+        representation.gpr = gpr;
         event.m_kind = kind;
         event.m_dataFormat = dataFormat;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
     
@@ -113,11 +117,15 @@ public:
     {
         ASSERT(kind == BirthToFill || kind == Fill);
         VariableEvent event;
-        event.m_which.id = id.bits();
-        event.m_representation.pair.tagGPR = tagGPR;
-        event.m_representation.pair.payloadGPR = payloadGPR;
+        WhichType which;
+        which.id = id.bits();
+        VariableRepresentation representation;
+        representation.pair.tagGPR = tagGPR;
+        representation.pair.payloadGPR = payloadGPR;
         event.m_kind = kind;
         event.m_dataFormat = DataFormatJS;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
 #endif // USE(JSVALUE32_64)
@@ -126,18 +134,24 @@ public:
     {
         ASSERT(kind == BirthToFill || kind == Fill);
         VariableEvent event;
-        event.m_which.id = id.bits();
-        event.m_representation.fpr = fpr;
+        WhichType which;
+        which.id = id.bits();
+        VariableRepresentation representation;
+        representation.fpr = fpr;
         event.m_kind = kind;
         event.m_dataFormat = DataFormatDouble;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
     
     static VariableEvent birth(MinifiedID id)
     {
         VariableEvent event;
-        event.m_which.id = id.bits();
+        WhichType which;
+        which.id = id.bits();
         event.m_kind = Birth;
+        event.m_which = WTFMove(which);
         return event;
     }
     
@@ -145,18 +159,24 @@ public:
     {
         ASSERT(kind == BirthToSpill || kind == Spill);
         VariableEvent event;
-        event.m_which.id = id.bits();
-        event.m_representation.virtualReg = virtualRegister.offset();
+        WhichType which;
+        which.id = id.bits();
+        VariableRepresentation representation;
+        representation.virtualReg = virtualRegister.offset();
         event.m_kind = kind;
         event.m_dataFormat = format;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
     
     static VariableEvent death(MinifiedID id)
     {
         VariableEvent event;
-        event.m_which.id = id.bits();
+        WhichType which;
+        which.id = id.bits();
         event.m_kind = Death;
+        event.m_which = WTFMove(which);
         return event;
     }
     
@@ -164,19 +184,27 @@ public:
         VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
     {
         VariableEvent event;
-        event.m_which.virtualReg = machineReg.offset();
-        event.m_representation.virtualReg = bytecodeReg.offset();
+        WhichType which;
+        which.virtualReg = machineReg.offset();
+        VariableRepresentation representation;
+        representation.virtualReg = bytecodeReg.offset();
         event.m_kind = SetLocalEvent;
         event.m_dataFormat = format;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
     
     static VariableEvent movHint(MinifiedID id, VirtualRegister bytecodeReg)
     {
         VariableEvent event;
-        event.m_which.id = id.bits();
-        event.m_representation.virtualReg = bytecodeReg.offset();
+        WhichType which;
+        which.id = id.bits();
+        VariableRepresentation representation;
+        representation.virtualReg = bytecodeReg.offset();
         event.m_kind = MovHintEvent;
+        event.m_which = WTFMove(which);
+        event.m_representation = WTFMove(representation);
         return event;
     }
     
@@ -190,7 +218,7 @@ public:
         ASSERT(
             m_kind == BirthToFill || m_kind == Fill || m_kind == BirthToSpill || m_kind == Spill
             || m_kind == Death || m_kind == MovHintEvent || m_kind == Birth);
-        return MinifiedID::fromBits(m_which.id);
+        return MinifiedID::fromBits(m_which.get().id);
     }
     
     DataFormat dataFormat() const
@@ -209,7 +237,7 @@ public:
 #if USE(JSVALUE32_64)
         ASSERT(!(m_dataFormat & DataFormatJS));
 #endif
-        return m_representation.gpr;
+        return m_representation.get().gpr;
     }
     
 #if USE(JSVALUE32_64)
@@ -217,13 +245,13 @@ public:
     {
         ASSERT(m_kind == BirthToFill || m_kind == Fill);
         ASSERT(m_dataFormat & DataFormatJS);
-        return m_representation.pair.tagGPR;
+        return m_representation.get().pair.tagGPR;
     }
     MacroAssembler::RegisterID payloadGPR() const
     {
         ASSERT(m_kind == BirthToFill || m_kind == Fill);
         ASSERT(m_dataFormat & DataFormatJS);
-        return m_representation.pair.payloadGPR;
+        return m_representation.get().pair.payloadGPR;
     }
 #endif // USE(JSVALUE32_64)
     
@@ -231,28 +259,28 @@ public:
     {
         ASSERT(m_kind == BirthToFill || m_kind == Fill);
         ASSERT(m_dataFormat == DataFormatDouble);
-        return m_representation.fpr;
+        return m_representation.get().fpr;
     }
     
     VirtualRegister spillRegister() const
     {
         ASSERT(m_kind == BirthToSpill || m_kind == Spill);
-        return VirtualRegister(m_representation.virtualReg);
+        return VirtualRegister(m_representation.get().virtualReg);
     }
     
     VirtualRegister bytecodeRegister() const
     {
         ASSERT(m_kind == SetLocalEvent || m_kind == MovHintEvent);
-        return VirtualRegister(m_representation.virtualReg);
+        return VirtualRegister(m_representation.get().virtualReg);
     }
     
     VirtualRegister machineRegister() const
     {
         ASSERT(m_kind == SetLocalEvent);
-        return VirtualRegister(m_which.virtualReg);
+        return VirtualRegister(m_which.get().virtualReg);
     }
     
-    const VariableRepresentation& variableRepresentation() const { return m_representation; }
+    VariableRepresentation variableRepresentation() const { return m_representation.get(); }
     
     void dump(PrintStream&) const;
     
@@ -260,10 +288,11 @@ private:
     void dumpFillInfo(const char* name, PrintStream&) const;
     void dumpSpillInfo(const char* name, PrintStream&) const;
     
-    union {
+    union WhichType {
         int virtualReg;
         unsigned id;
-    } m_which;
+    };
+    Packed<WhichType> m_which;
     
     // For BirthToFill, Fill:
     //   - The GPR or FPR, or a GPR pair.
@@ -273,9 +302,9 @@ private:
     //   - The bytecode operand.
     // For Death:
     //   - Unused.
-    VariableRepresentation m_representation;
+    Packed<VariableRepresentation> m_representation;
     
-    int8_t m_kind;
+    VariableEventKind m_kind;
     DataFormat m_dataFormat { DataFormatNone };
 };
 
index 4de11b4..6f8af42 100644 (file)
@@ -101,12 +101,12 @@ static bool tryToSetConstantRecovery(ValueRecovery& recovery, MinifiedNode* node
         return true;
     }
     
-    if (node->op() == PhantomDirectArguments) {
+    if (node->isPhantomDirectArguments()) {
         recovery = ValueRecovery::directArgumentsThatWereNotCreated(node->id());
         return true;
     }
     
-    if (node->op() == PhantomClonedArguments) {
+    if (node->isPhantomClonedArguments()) {
         recovery = ValueRecovery::clonedArgumentsThatWereNotCreated(node->id());
         return true;
     }