[JSC] Compress miscelaneous JIT related data structures with Packed<>
https://bugs.webkit.org/show_bug.cgi?id=197830

Reviewed by Saam Barati.

Source/JavaScriptCore:

This patch leverages Packed<> to compress miscelaneous data structures related to JIT.

1. JIT IC data structures

2. ValueRecovery

    We use Packed<> for EncodedJSValue in ValueRecovery. This means that conservative GC cannot find
    these values. But this is OK anyway since ValueRecovery's constant should be already registered
    in DFG graph. From 16 (alignment 8) to 9 (alignment 1).

3. FTL::ExitValue

    We use Packed<> for EncodedJSValue in FTL::ExitValue. This is also OK since this constant should
    be already registered by DFG/FTL graph. From 16 (alignment 8) to 9 (alignment 1).

* assembler/CodeLocation.h:
* bytecode/ByValInfo.h:
* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::CallLinkInfo):
(JSC::CallLinkInfo::callReturnLocation):
* bytecode/CallLinkInfo.h:
(JSC::CallLinkInfo::nearCallMode const):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::addJITAddIC):
(JSC::CodeBlock::addJITMulIC):
(JSC::CodeBlock::addJITSubIC):
(JSC::CodeBlock::addJITNegIC):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::addMathIC):
* bytecode/InlineCallFrame.h:
(JSC::InlineCallFrame::InlineCallFrame):
* bytecode/ValueRecovery.h:
(JSC::ValueRecovery::inGPR):
(JSC::ValueRecovery::inPair):
(JSC::ValueRecovery::inFPR):
(JSC::ValueRecovery::displacedInJSStack):
(JSC::ValueRecovery::constant):
(JSC::ValueRecovery::directArgumentsThatWereNotCreated):
(JSC::ValueRecovery::clonedArgumentsThatWereNotCreated):
(JSC::ValueRecovery::gpr const):
(JSC::ValueRecovery::tagGPR const):
(JSC::ValueRecovery::payloadGPR const):
(JSC::ValueRecovery::fpr const):
(JSC::ValueRecovery::virtualRegister const):
(JSC::ValueRecovery::withLocalsOffset const):
(JSC::ValueRecovery::constant const):
(JSC::ValueRecovery::nodeID const):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileValueAdd):
(JSC::DFG::SpeculativeJIT::compileValueSub):
(JSC::DFG::SpeculativeJIT::compileValueNegate):
(JSC::DFG::SpeculativeJIT::compileValueMul):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::materializeNewObject):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::inJSStack):
(JSC::FTL::ExitValue::inJSStackAsInt32):
(JSC::FTL::ExitValue::inJSStackAsInt52):
(JSC::FTL::ExitValue::inJSStackAsDouble):
(JSC::FTL::ExitValue::constant):
(JSC::FTL::ExitValue::exitArgument):
(JSC::FTL::ExitValue::exitArgument const):
(JSC::FTL::ExitValue::adjustStackmapLocationsIndexByOffset):
(JSC::FTL::ExitValue::constant const):
(JSC::FTL::ExitValue::virtualRegister const):
(JSC::FTL::ExitValue::objectMaterialization const):
(JSC::FTL::ExitValue::withVirtualRegister const):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileValueAdd):
(JSC::FTL::DFG::LowerDFGToB3::compileValueSub):
(JSC::FTL::DFG::LowerDFGToB3::compileValueMul):
(JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
(JSC::FTL::DFG::LowerDFGToB3::compileValueNegate):
* jit/CachedRecovery.h:
* jit/CallFrameShuffleData.h:
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_negate):
(JSC::JIT::emit_op_add):
(JSC::JIT::emit_op_mul):
(JSC::JIT::emit_op_sub):
* jit/JITMathIC.h:
(JSC::isProfileEmpty):
(JSC::JITBinaryMathIC::JITBinaryMathIC):
(JSC::JITUnaryMathIC::JITUnaryMathIC):
* jit/PolymorphicCallStubRoutine.h:
(JSC::PolymorphicCallNode::hasCallLinkInfo):
* jit/SnippetOperand.h:
(JSC::SnippetOperand::asRawBits const):
(JSC::SnippetOperand::asConstInt32 const):
(JSC::SnippetOperand::asConstDouble const):
(JSC::SnippetOperand::setConstInt32):
(JSC::SnippetOperand::setConstDouble):

Source/WTF:

* wtf/Packed.h:
(WTF::alignof):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245239 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index eeb5b5c..56fb367 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,105 @@
+2019-05-13  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Compress miscelaneous JIT related data structures with Packed<>
+        https://bugs.webkit.org/show_bug.cgi?id=197830
+
+        Reviewed by Saam Barati.
+
+        This patch leverages Packed<> to compress miscelaneous data structures related to JIT.
+
+        1. JIT IC data structures
+
+        2. ValueRecovery
+
+            We use Packed<> for EncodedJSValue in ValueRecovery. This means that conservative GC cannot find
+            these values. But this is OK anyway since ValueRecovery's constant should be already registered
+            in DFG graph. From 16 (alignment 8) to 9 (alignment 1).
+
+        3. FTL::ExitValue
+
+            We use Packed<> for EncodedJSValue in FTL::ExitValue. This is also OK since this constant should
+            be already registered by DFG/FTL graph. From 16 (alignment 8) to 9 (alignment 1).
+
+        * assembler/CodeLocation.h:
+        * bytecode/ByValInfo.h:
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::CallLinkInfo):
+        (JSC::CallLinkInfo::callReturnLocation):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::nearCallMode const):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::addJITAddIC):
+        (JSC::CodeBlock::addJITMulIC):
+        (JSC::CodeBlock::addJITSubIC):
+        (JSC::CodeBlock::addJITNegIC):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::addMathIC):
+        * bytecode/InlineCallFrame.h:
+        (JSC::InlineCallFrame::InlineCallFrame):
+        * bytecode/ValueRecovery.h:
+        (JSC::ValueRecovery::inGPR):
+        (JSC::ValueRecovery::inPair):
+        (JSC::ValueRecovery::inFPR):
+        (JSC::ValueRecovery::displacedInJSStack):
+        (JSC::ValueRecovery::constant):
+        (JSC::ValueRecovery::directArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::clonedArgumentsThatWereNotCreated):
+        (JSC::ValueRecovery::gpr const):
+        (JSC::ValueRecovery::tagGPR const):
+        (JSC::ValueRecovery::payloadGPR const):
+        (JSC::ValueRecovery::fpr const):
+        (JSC::ValueRecovery::virtualRegister const):
+        (JSC::ValueRecovery::withLocalsOffset const):
+        (JSC::ValueRecovery::constant const):
+        (JSC::ValueRecovery::nodeID const):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileValueAdd):
+        (JSC::DFG::SpeculativeJIT::compileValueSub):
+        (JSC::DFG::SpeculativeJIT::compileValueNegate):
+        (JSC::DFG::SpeculativeJIT::compileValueMul):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::materializeNewObject):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::inJSStack):
+        (JSC::FTL::ExitValue::inJSStackAsInt32):
+        (JSC::FTL::ExitValue::inJSStackAsInt52):
+        (JSC::FTL::ExitValue::inJSStackAsDouble):
+        (JSC::FTL::ExitValue::constant):
+        (JSC::FTL::ExitValue::exitArgument):
+        (JSC::FTL::ExitValue::exitArgument const):
+        (JSC::FTL::ExitValue::adjustStackmapLocationsIndexByOffset):
+        (JSC::FTL::ExitValue::constant const):
+        (JSC::FTL::ExitValue::virtualRegister const):
+        (JSC::FTL::ExitValue::objectMaterialization const):
+        (JSC::FTL::ExitValue::withVirtualRegister const):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileValueAdd):
+        (JSC::FTL::DFG::LowerDFGToB3::compileValueSub):
+        (JSC::FTL::DFG::LowerDFGToB3::compileValueMul):
+        (JSC::FTL::DFG::LowerDFGToB3::compileUnaryMathIC):
+        (JSC::FTL::DFG::LowerDFGToB3::compileBinaryMathIC):
+        (JSC::FTL::DFG::LowerDFGToB3::compileArithAddOrSub):
+        (JSC::FTL::DFG::LowerDFGToB3::compileValueNegate):
+        * jit/CachedRecovery.h:
+        * jit/CallFrameShuffleData.h:
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emit_op_negate):
+        (JSC::JIT::emit_op_add):
+        (JSC::JIT::emit_op_mul):
+        (JSC::JIT::emit_op_sub):
+        * jit/JITMathIC.h:
+        (JSC::isProfileEmpty):
+        (JSC::JITBinaryMathIC::JITBinaryMathIC):
+        (JSC::JITUnaryMathIC::JITUnaryMathIC):
+        * jit/PolymorphicCallStubRoutine.h:
+        (JSC::PolymorphicCallNode::hasCallLinkInfo):
+        * jit/SnippetOperand.h:
+        (JSC::SnippetOperand::asRawBits const):
+        (JSC::SnippetOperand::asConstInt32 const):
+        (JSC::SnippetOperand::asConstDouble const):
+        (JSC::SnippetOperand::setConstInt32):
+        (JSC::SnippetOperand::setConstDouble):
+
 2019-05-12  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Compress Watchpoint size by using enum type and Packed<> data structure
diff --git a/Source/JavaScriptCore/assembler/CodeLocation.h b/Source/JavaScriptCore/assembler/CodeLocation.h
index 41d251e..a6ca5c8 100644
--- a/Source/JavaScriptCore/assembler/CodeLocation.h
+++ b/Source/JavaScriptCore/assembler/CodeLocation.h
@@ -31,7 +31,7 @@
 
 namespace JSC {
 
-enum NearCallMode { Regular, Tail };
+enum class NearCallMode : uint8_t { Regular, Tail };
 
 template<PtrTag> class CodeLocationInstruction;
 template<PtrTag> class CodeLocationLabel;
@@ -153,7 +153,7 @@
         : CodeLocationCommon<tag>(MacroAssemblerCodePtr<tag>(location)), m_callMode(callMode) { }
     NearCallMode callMode() { return m_callMode; }
 private:
-    NearCallMode m_callMode = NearCallMode::Regular;
+    NearCallMode m_callMode { NearCallMode::Regular };
 };
 
 template<PtrTag tag>
diff --git a/Source/JavaScriptCore/bytecode/ByValInfo.h b/Source/JavaScriptCore/bytecode/ByValInfo.h
index 5df21ff..3399d58 100644
--- a/Source/JavaScriptCore/bytecode/ByValInfo.h
+++ b/Source/JavaScriptCore/bytecode/ByValInfo.h
@@ -39,7 +39,7 @@
 
 class StructureStubInfo;
 
-enum JITArrayMode {
+enum JITArrayMode : uint8_t {
     JITInt32,
     JITDouble,
     JITContiguous,
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp b/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
index b3b66c4..ced9d4d 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
@@ -63,8 +63,6 @@
     , m_clearedByJettison(false)
     , m_callType(None)
     , m_calleeGPR(255)
-    , m_maxNumArguments(0)
-    , m_slowPathCount(0)
 {
 }
 
@@ -100,7 +98,7 @@
 CodeLocationNearCall<JSInternalPtrTag> CallLinkInfo::callReturnLocation()
 {
     RELEASE_ASSERT(!isDirect());
-    return CodeLocationNearCall<JSInternalPtrTag>(m_callReturnLocationOrPatchableJump, Regular);
+    return CodeLocationNearCall<JSInternalPtrTag>(m_callReturnLocationOrPatchableJump, NearCallMode::Regular);
 }
 
 CodeLocationJump<JSInternalPtrTag> CallLinkInfo::patchableJump()
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.h b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
index a0b207f..fa0a115 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
@@ -41,7 +41,7 @@
 enum OpcodeID : unsigned;
 struct CallFrameShuffleData;
 
-class CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+class CallLinkInfo : public PackedRawSentinelNode<CallLinkInfo> {
 public:
     enum CallType {
         None,
@@ -146,7 +146,7 @@
     
     NearCallMode nearCallMode() const
     {
-        return isTailCall() ? Tail : Regular;
+        return isTailCall() ? NearCallMode::Tail : NearCallMode::Regular;
     }
 
     bool isVarargs() const
@@ -347,6 +347,7 @@
     }
 
 private:
+    uint32_t m_maxNumArguments { 0 }; // For varargs: the profiled maximum number of arguments. For direct: the number of stack slots allocated for arguments.
     CodeLocationLabel<JSInternalPtrTag> m_callReturnLocationOrPatchableJump;
     CodeLocationLabel<JSInternalPtrTag> m_hotPathBeginOrSlowPathStart;
     CodeLocationNearCall<JSInternalPtrTag> m_hotPathOther;
@@ -355,6 +356,7 @@
     RefPtr<PolymorphicCallStubRoutine> m_stub;
     RefPtr<JITStubRoutine> m_slowStub;
     std::unique_ptr<CallFrameShuffleData> m_frameShuffleData;
+    CodeOrigin m_codeOrigin;
     bool m_hasSeenShouldRepatch : 1;
     bool m_hasSeenClosure : 1;
     bool m_clearedByGC : 1;
@@ -363,9 +365,7 @@
     bool m_clearedByJettison : 1;
     unsigned m_callType : 4; // CallType
     unsigned m_calleeGPR : 8;
-    uint32_t m_maxNumArguments; // For varargs: the profiled maximum number of arguments. For direct: the number of stack slots allocated for arguments.
-    uint32_t m_slowPathCount;
-    CodeOrigin m_codeOrigin;
+    uint32_t m_slowPathCount { 0 };
 };
 
 inline CodeOrigin getCallLinkInfoCodeOrigin(CallLinkInfo& callLinkInfo)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index ecc1a95..bcb8a9d 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1427,28 +1427,28 @@
     return ensureJITData(locker).m_stubInfos.add(accessType);
 }
 
-JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile, const Instruction* instruction)
+JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
-    return ensureJITData(locker).m_addICs.add(arithProfile, instruction);
+    return ensureJITData(locker).m_addICs.add(arithProfile);
 }
 
-JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile, const Instruction* instruction)
+JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
-    return ensureJITData(locker).m_mulICs.add(arithProfile, instruction);
+    return ensureJITData(locker).m_mulICs.add(arithProfile);
 }
 
-JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile, const Instruction* instruction)
+JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
-    return ensureJITData(locker).m_subICs.add(arithProfile, instruction);
+    return ensureJITData(locker).m_subICs.add(arithProfile);
 }
 
-JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile, const Instruction* instruction)
+JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile)
 {
     ConcurrentJSLocker locker(m_lock);
-    return ensureJITData(locker).m_negICs.add(arithProfile, instruction);
+    return ensureJITData(locker).m_negICs.add(arithProfile);
 }
 
 StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index a4c23bf..a93c36f 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -261,8 +261,8 @@
         Bag<JITSubIC> m_subICs;
         Bag<ByValInfo> m_byValInfos;
         Bag<CallLinkInfo> m_callLinkInfos;
-        SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo>> m_incomingCalls;
-        SentinelLinkedList<PolymorphicCallNode, BasicRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
+        SentinelLinkedList<CallLinkInfo, PackedRawSentinelNode<CallLinkInfo>> m_incomingCalls;
+        SentinelLinkedList<PolymorphicCallNode, PackedRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
         SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles;
         std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
         std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
@@ -277,22 +277,22 @@
     }
     JITData& ensureJITDataSlow(const ConcurrentJSLocker&);
 
-    JITAddIC* addJITAddIC(ArithProfile*, const Instruction*);
-    JITMulIC* addJITMulIC(ArithProfile*, const Instruction*);
-    JITNegIC* addJITNegIC(ArithProfile*, const Instruction*);
-    JITSubIC* addJITSubIC(ArithProfile*, const Instruction*);
+    JITAddIC* addJITAddIC(ArithProfile*);
+    JITMulIC* addJITMulIC(ArithProfile*);
+    JITNegIC* addJITNegIC(ArithProfile*);
+    JITSubIC* addJITSubIC(ArithProfile*);
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITAddGenerator>::value>::type>
-    JITAddIC* addMathIC(ArithProfile* profile, const Instruction* instruction) { return addJITAddIC(profile, instruction); }
+    JITAddIC* addMathIC(ArithProfile* profile) { return addJITAddIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITMulGenerator>::value>::type>
-    JITMulIC* addMathIC(ArithProfile* profile, const Instruction* instruction) { return addJITMulIC(profile, instruction); }
+    JITMulIC* addMathIC(ArithProfile* profile) { return addJITMulIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITNegGenerator>::value>::type>
-    JITNegIC* addMathIC(ArithProfile* profile, const Instruction* instruction) { return addJITNegIC(profile, instruction); }
+    JITNegIC* addMathIC(ArithProfile* profile) { return addJITNegIC(profile); }
 
     template <typename Generator, typename = typename std::enable_if<std::is_same<Generator, JITSubGenerator>::value>::type>
-    JITSubIC* addMathIC(ArithProfile* profile, const Instruction* instruction) { return addJITSubIC(profile, instruction); }
+    JITSubIC* addMathIC(ArithProfile* profile) { return addJITSubIC(profile); }
 
     StructureStubInfo* addStubInfo(AccessType);
 
diff --git a/Source/JavaScriptCore/bytecode/InlineCallFrame.h b/Source/JavaScriptCore/bytecode/InlineCallFrame.h
index a6bf1c8..8defc26 100644
--- a/Source/JavaScriptCore/bytecode/InlineCallFrame.h
+++ b/Source/JavaScriptCore/bytecode/InlineCallFrame.h
@@ -177,21 +177,21 @@
     
     Vector<ValueRecovery> argumentsWithFixup; // Includes 'this' and arity fixups.
     WriteBarrier<CodeBlock> baselineCodeBlock;
-    ValueRecovery calleeRecovery;
     CodeOrigin directCaller;
 
-    unsigned argumentCountIncludingThis; // Do not include fixups.
+    unsigned argumentCountIncludingThis { 0 }; // Do not include fixups.
     signed stackOffset : 28;
     unsigned kind : 3; // real type is Kind
     bool isClosureCall : 1; // If false then we know that callee/scope are constants and the DFG won't treat them as variables, i.e. they have to be recovered manually.
     VirtualRegister argumentCountRegister; // Only set when we inline a varargs call.
+
+    ValueRecovery calleeRecovery;
     
     // There is really no good notion of a "default" set of values for
     // InlineCallFrame's fields. This constructor is here just to reduce confusion if
     // we forgot to initialize explicitly.
     InlineCallFrame()
-        : argumentCountIncludingThis(0)
-        , stackOffset(0)
+        : stackOffset(0)
         , kind(Call)
         , isClosureCall(false)
     {
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
index 4e99567..95e580d 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.h
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -43,7 +43,7 @@
 
 // Describes how to recover a given bytecode virtual register at a given
 // code point.
-enum ValueRecoveryTechnique {
+enum ValueRecoveryTechnique : uint8_t {
     // It's in a register.
     InGPR,
     UnboxedInt32InGPR,
@@ -116,7 +116,9 @@
             result.m_technique = UnboxedCellInGPR;
         else
             result.m_technique = InGPR;
-        result.m_source.gpr = gpr;
+        UnionType u;
+        u.gpr = gpr;
+        result.m_source = WTFMove(u);
         return result;
     }
     
@@ -125,8 +127,10 @@
     {
         ValueRecovery result;
         result.m_technique = InPair;
-        result.m_source.pair.tagGPR = tagGPR;
-        result.m_source.pair.payloadGPR = payloadGPR;
+        UnionType u;
+        u.pair.tagGPR = tagGPR;
+        u.pair.payloadGPR = payloadGPR;
+        result.m_source = WTFMove(u);
         return result;
     }
 #endif
@@ -139,7 +143,9 @@
             result.m_technique = UnboxedDoubleInFPR;
         else
             result.m_technique = InFPR;
-        result.m_source.fpr = fpr;
+        UnionType u;
+        u.fpr = fpr;
+        result.m_source = WTFMove(u);
         return result;
     }
     
@@ -176,7 +182,9 @@
             result.m_technique = DisplacedInJSStack;
             break;
         }
-        result.m_source.virtualReg = virtualReg.offset();
+        UnionType u;
+        u.virtualReg = virtualReg.offset();
+        result.m_source = WTFMove(u);
         return result;
     }
     
@@ -184,7 +192,9 @@
     {
         ValueRecovery result;
         result.m_technique = Constant;
-        result.m_source.constant = JSValue::encode(value);
+        UnionType u;
+        u.constant = JSValue::encode(value);
+        result.m_source = WTFMove(u);
         return result;
     }
     
@@ -192,7 +202,9 @@
     {
         ValueRecovery result;
         result.m_technique = DirectArgumentsThatWereNotCreated;
-        result.m_source.nodeID = id.bits();
+        UnionType u;
+        u.nodeID = id.bits();
+        result.m_source = WTFMove(u);
         return result;
     }
     
@@ -200,7 +212,9 @@
     {
         ValueRecovery result;
         result.m_technique = ClonedArgumentsThatWereNotCreated;
-        result.m_source.nodeID = id.bits();
+        UnionType u;
+        u.nodeID = id.bits();
+        result.m_source = WTFMove(u);
         return result;
     }
 
@@ -292,20 +306,20 @@
     MacroAssembler::RegisterID gpr() const
     {
         ASSERT(isInGPR());
-        return m_source.gpr;
+        return m_source.get().gpr;
     }
     
 #if USE(JSVALUE32_64)
     MacroAssembler::RegisterID tagGPR() const
     {
         ASSERT(m_technique == InPair);
-        return m_source.pair.tagGPR;
+        return m_source.get().pair.tagGPR;
     }
     
     MacroAssembler::RegisterID payloadGPR() const
     {
         ASSERT(m_technique == InPair);
-        return m_source.pair.payloadGPR;
+        return m_source.get().pair.payloadGPR;
     }
 
     bool isInJSValueRegs() const
@@ -330,13 +344,13 @@
     MacroAssembler::FPRegisterID fpr() const
     {
         ASSERT(isInFPR());
-        return m_source.fpr;
+        return m_source.get().fpr;
     }
     
     VirtualRegister virtualRegister() const
     {
         ASSERT(isInJSStack());
-        return VirtualRegister(m_source.virtualReg);
+        return VirtualRegister(m_source.get().virtualReg);
     }
     
     ValueRecovery withLocalsOffset(int offset) const
@@ -351,7 +365,9 @@
         case StrictInt52DisplacedInJSStack: {
             ValueRecovery result;
             result.m_technique = m_technique;
-            result.m_source.virtualReg = m_source.virtualReg + offset;
+            UnionType u;
+            u.virtualReg = m_source.get().virtualReg + offset;
+            result.m_source = WTFMove(u);
             return result;
         }
             
@@ -363,13 +379,13 @@
     JSValue constant() const
     {
         ASSERT(isConstant());
-        return JSValue::decode(m_source.constant);
+        return JSValue::decode(m_source.get().constant);
     }
     
     DFG::MinifiedID nodeID() const
     {
         ASSERT(m_technique == DirectArgumentsThatWereNotCreated || m_technique == ClonedArgumentsThatWereNotCreated);
-        return DFG::MinifiedID::fromBits(m_source.nodeID);
+        return DFG::MinifiedID::fromBits(m_source.get().nodeID);
     }
     
     JSValue recover(ExecState*) const;
@@ -408,7 +424,7 @@
 
 private:
     ValueRecoveryTechnique m_technique;
-    union {
+    union UnionType {
         MacroAssembler::RegisterID gpr;
         MacroAssembler::FPRegisterID fpr;
 #if USE(JSVALUE32_64)
@@ -420,7 +436,9 @@
         int virtualReg;
         EncodedJSValue constant;
         unsigned nodeID;
-    } m_source;
+    };
+    Packed<UnionType> m_source;
 };
+static_assert(alignof(ValueRecovery) == 1);
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index f50a8ad..df0f1c8 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -3953,8 +3953,7 @@
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
     ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-    const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
-    JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile, instruction);
+    JITAddIC* addIC = m_jit.codeBlock()->addJITAddIC(arithProfile);
     auto repatchingFunction = operationValueAddOptimize;
     auto nonRepatchingFunction = operationValueAdd;
     
@@ -3978,8 +3977,7 @@
         CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
         unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-        const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
-        JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile, instruction);
+        JITSubIC* subIC = m_jit.codeBlock()->addJITSubIC(arithProfile);
         auto repatchingFunction = operationValueSubOptimize;
         auto nonRepatchingFunction = operationValueSub;
 
@@ -4573,8 +4571,7 @@
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
     ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-    const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
-    JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile, instruction);
+    JITNegIC* negIC = m_jit.codeBlock()->addJITNegIC(arithProfile);
     auto repatchingFunction = operationArithNegateOptimize;
     auto nonRepatchingFunction = operationArithNegate;
     bool needsScratchGPRReg = true;
@@ -4797,8 +4794,7 @@
     CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
     unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex();
     ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-    const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
-    JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile, instruction);
+    JITMulIC* mulIC = m_jit.codeBlock()->addJITMulIC(arithProfile);
     auto repatchingFunction = operationValueMulOptimize;
     auto nonRepatchingFunction = operationValueMul;
 
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.cpp b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
index b36db04..0cacf09 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.cpp
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.cpp
@@ -38,7 +38,9 @@
 {
     ExitValue result;
     result.m_kind = ExitValueMaterializeNewObject;
-    result.u.newObjectMaterializationData = data;
+    UnionType u;
+    u.newObjectMaterializationData = data;
+    result.m_value = WTFMove(u);
     return result;
 }
 
diff --git a/Source/JavaScriptCore/ftl/FTLExitValue.h b/Source/JavaScriptCore/ftl/FTLExitValue.h
index 838da64..38808c1 100644
--- a/Source/JavaScriptCore/ftl/FTLExitValue.h
+++ b/Source/JavaScriptCore/ftl/FTLExitValue.h
@@ -45,7 +45,7 @@
 // telling us the mapping between operands in bytecode and the arguments to
 // the call.
 
-enum ExitValueKind {
+enum ExitValueKind : uint8_t {
     InvalidExitValue,
     ExitValueDead,
     ExitValueArgument,
@@ -79,7 +79,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueInJSStack;
-        result.u.virtualRegister = reg.offset();
+        UnionType u;
+        u.virtualRegister = reg.offset();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -87,7 +89,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueInJSStackAsInt32;
-        result.u.virtualRegister = reg.offset();
+        UnionType u;
+        u.virtualRegister = reg.offset();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -95,7 +99,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueInJSStackAsInt52;
-        result.u.virtualRegister = reg.offset();
+        UnionType u;
+        u.virtualRegister = reg.offset();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -103,7 +109,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueInJSStackAsDouble;
-        result.u.virtualRegister = reg.offset();
+        UnionType u;
+        u.virtualRegister = reg.offset();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -111,7 +119,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueConstant;
-        result.u.constant = JSValue::encode(value);
+        UnionType u;
+        u.constant = JSValue::encode(value);
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -119,7 +129,9 @@
     {
         ExitValue result;
         result.m_kind = ExitValueArgument;
-        result.u.argument = argument.representation();
+        UnionType u;
+        u.argument = argument.representation();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -148,32 +160,34 @@
     ExitArgument exitArgument() const
     {
         ASSERT(isArgument());
-        return ExitArgument(u.argument);
+        return ExitArgument(m_value.get().argument);
     }
     
     void adjustStackmapLocationsIndexByOffset(unsigned offset)
     {
         ASSERT(hasIndexInStackmapLocations());
         ASSERT(isArgument());
+        UnionType u = m_value.get();
         u.argument.argument += offset;
+        m_value = WTFMove(u);
     }
     
     JSValue constant() const
     {
         ASSERT(isConstant());
-        return JSValue::decode(u.constant);
+        return JSValue::decode(m_value.get().constant);
     }
     
     VirtualRegister virtualRegister() const
     {
         ASSERT(isInJSStackSomehow());
-        return VirtualRegister(u.virtualRegister);
+        return VirtualRegister(m_value.get().virtualRegister);
     }
     
     ExitTimeObjectMaterialization* objectMaterialization() const
     {
         ASSERT(isObjectMaterialization());
-        return u.newObjectMaterializationData;
+        return m_value.get().newObjectMaterializationData;
     }
 
     ExitValue withVirtualRegister(VirtualRegister virtualRegister) const
@@ -181,7 +195,9 @@
         ASSERT(isInJSStackSomehow());
         ExitValue result;
         result.m_kind = m_kind;
-        result.u.virtualRegister = virtualRegister.offset();
+        UnionType u;
+        u.virtualRegister = virtualRegister.offset();
+        result.m_value = WTFMove(u);
         return result;
     }
     
@@ -200,12 +216,13 @@
     
 private:
     ExitValueKind m_kind;
-    union {
+    union UnionType {
         ExitArgumentRepresentation argument;
         EncodedJSValue constant;
         int virtualRegister;
         ExitTimeObjectMaterialization* newObjectMaterializationData;
-    } u;
+    };
+    Packed<UnionType> m_value;
 };
 
 } } // namespace JSC::FTL
diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
index 473a038..6c65748 100644
--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
@@ -2070,10 +2070,9 @@
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-        const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
         auto repatchingFunction = operationValueAddOptimize;
         auto nonRepatchingFunction = operationValueAdd;
-        compileBinaryMathIC<JITAddGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
+        compileBinaryMathIC<JITAddGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
     }
 
     void compileValueSub()
@@ -2090,10 +2089,9 @@
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-        const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
         auto repatchingFunction = operationValueSubOptimize;
         auto nonRepatchingFunction = operationValueSub;
-        compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
+        compileBinaryMathIC<JITSubGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
     }
 
     void compileValueMul()
@@ -2110,15 +2108,14 @@
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-        const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
         auto repatchingFunction = operationValueMulOptimize;
         auto nonRepatchingFunction = operationValueMul;
-        compileBinaryMathIC<JITMulGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
+        compileBinaryMathIC<JITMulGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
     }
 
     template <typename Generator, typename Func1, typename Func2,
         typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>>
-    void compileUnaryMathIC(ArithProfile* arithProfile, const Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
+    void compileUnaryMathIC(ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
     {
         Node* node = m_node;
 
@@ -2144,7 +2141,7 @@
 #endif
 
                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
-                JITUnaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
+                JITUnaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile);
                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
 
                 bool shouldEmitProfiling = false;
@@ -2204,7 +2201,7 @@
 
     template <typename Generator, typename Func1, typename Func2,
         typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func1>::type>::value && std::is_function<typename std::remove_pointer<Func2>::type>::value>>
-    void compileBinaryMathIC(ArithProfile* arithProfile, const Instruction* instruction, Func1 repatchingFunction, Func2 nonRepatchingFunction)
+    void compileBinaryMathIC(ArithProfile* arithProfile, Func1 repatchingFunction, Func2 nonRepatchingFunction)
     {
         Node* node = m_node;
         
@@ -2238,7 +2235,7 @@
 #endif
 
                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
-                JITBinaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile, instruction);
+                JITBinaryMathIC<Generator>* mathIC = jit.codeBlock()->addMathIC<Generator>(arithProfile);
                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
@@ -2372,10 +2369,9 @@
             CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
             unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
             ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-            const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
             auto repatchingFunction = operationValueSubOptimize;
             auto nonRepatchingFunction = operationValueSub;
-            compileBinaryMathIC<JITSubGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
+            compileBinaryMathIC<JITSubGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
             break;
         }
 
@@ -3023,10 +3019,9 @@
         CodeBlock* baselineCodeBlock = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic);
         unsigned bytecodeIndex = m_node->origin.semantic.bytecodeIndex();
         ArithProfile* arithProfile = baselineCodeBlock->arithProfileForBytecodeOffset(bytecodeIndex);
-        const Instruction* instruction = baselineCodeBlock->instructions().at(bytecodeIndex).ptr();
         auto repatchingFunction = operationArithNegateOptimize;
         auto nonRepatchingFunction = operationArithNegate;
-        compileUnaryMathIC<JITNegGenerator>(arithProfile, instruction, repatchingFunction, nonRepatchingFunction);
+        compileUnaryMathIC<JITNegGenerator>(arithProfile, repatchingFunction, nonRepatchingFunction);
     }
 
     void compileArithNegate()
diff --git a/Source/JavaScriptCore/jit/CachedRecovery.h b/Source/JavaScriptCore/jit/CachedRecovery.h
index f627ac9..d2e7cd5 100644
--- a/Source/JavaScriptCore/jit/CachedRecovery.h
+++ b/Source/JavaScriptCore/jit/CachedRecovery.h
@@ -123,10 +123,10 @@
 
     FPRReg wantedFPR() const { return m_wantedFPR; }
 private:
+    Vector<VirtualRegister, 1> m_targets;
     ValueRecovery m_recovery;
     JSValueRegs m_wantedJSValueRegs;
     FPRReg m_wantedFPR { InvalidFPRReg };
-    Vector<VirtualRegister, 1> m_targets;
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/jit/CallFrameShuffleData.h b/Source/JavaScriptCore/jit/CallFrameShuffleData.h
index c0df0a3..9e710cb 100644
--- a/Source/JavaScriptCore/jit/CallFrameShuffleData.h
+++ b/Source/JavaScriptCore/jit/CallFrameShuffleData.h
@@ -35,7 +35,6 @@
 struct CallFrameShuffleData {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ValueRecovery callee;
     Vector<ValueRecovery> args;
     unsigned numLocals { UINT_MAX };
     unsigned numPassedArgs { UINT_MAX };
@@ -45,6 +44,7 @@
 
     void setupCalleeSaveRegisters(CodeBlock*);
 #endif
+    ValueRecovery callee;
 };
 
 } // namespace JSC
diff --git a/Source/JavaScriptCore/jit/JITArithmetic.cpp b/Source/JavaScriptCore/jit/JITArithmetic.cpp
index 3389ecf..71e33c8 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic.cpp
@@ -453,7 +453,7 @@
 void JIT::emit_op_negate(const Instruction* currentInstruction)
 {
     ArithProfile* arithProfile = &currentInstruction->as<OpNegate>().metadata(m_codeBlock).m_arithProfile;
-    JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile, currentInstruction);
+    JITNegIC* negateIC = m_codeBlock->addJITNegIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, negateIC);
     emitMathICFast<OpNegate>(negateIC, currentInstruction, operationArithNegateProfiled, operationArithNegate);
 }
@@ -641,7 +641,7 @@
 void JIT::emit_op_add(const Instruction* currentInstruction)
 {
     ArithProfile* arithProfile = &currentInstruction->as<OpAdd>().metadata(m_codeBlock).m_arithProfile;
-    JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile, currentInstruction);
+    JITAddIC* addIC = m_codeBlock->addJITAddIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, addIC);
     emitMathICFast<OpAdd>(addIC, currentInstruction, operationValueAddProfiled, operationValueAdd);
 }
@@ -960,7 +960,7 @@
 void JIT::emit_op_mul(const Instruction* currentInstruction)
 {
     ArithProfile* arithProfile = &currentInstruction->as<OpMul>().metadata(m_codeBlock).m_arithProfile;
-    JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile, currentInstruction);
+    JITMulIC* mulIC = m_codeBlock->addJITMulIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, mulIC);
     emitMathICFast<OpMul>(mulIC, currentInstruction, operationValueMulProfiled, operationValueMul);
 }
@@ -976,7 +976,7 @@
 void JIT::emit_op_sub(const Instruction* currentInstruction)
 {
     ArithProfile* arithProfile = &currentInstruction->as<OpSub>().metadata(m_codeBlock).m_arithProfile;
-    JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile, currentInstruction);
+    JITSubIC* subIC = m_codeBlock->addJITSubIC(arithProfile);
     m_instructionToMathIC.add(currentInstruction, subIC);
     emitMathICFast<OpSub>(subIC, currentInstruction, operationValueSubProfiled, operationValueSub);
 }
diff --git a/Source/JavaScriptCore/jit/JITMathIC.h b/Source/JavaScriptCore/jit/JITMathIC.h
index c8876d0..5645e42 100644
--- a/Source/JavaScriptCore/jit/JITMathIC.h
+++ b/Source/JavaScriptCore/jit/JITMathIC.h
@@ -56,9 +56,8 @@
 class JITMathIC {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    JITMathIC(ArithProfile* arithProfile, const Instruction* instruction)
+    JITMathIC(ArithProfile* arithProfile)
         : m_arithProfile(arithProfile)
-        , m_instruction(instruction)
     {
     }
 
@@ -225,7 +224,6 @@
     }
 
     ArithProfile* arithProfile() const { return m_arithProfile; }
-    const Instruction* instruction() const { return m_instruction; }
 
 #if ENABLE(MATH_IC_STATS)
     size_t m_generatedCodeSize { 0 };
@@ -239,7 +237,6 @@
 #endif
 
     ArithProfile* m_arithProfile;
-    const Instruction* m_instruction;
     MacroAssemblerCodeRef<JITStubRoutinePtrTag> m_code;
     CodeLocationLabel<JSInternalPtrTag> m_inlineStart;
     CodeLocationLabel<JSInternalPtrTag> m_inlineEnd;
@@ -256,8 +253,8 @@
 template <typename GeneratorType>
 class JITBinaryMathIC : public JITMathIC<GeneratorType, isBinaryProfileEmpty> {
 public:
-    JITBinaryMathIC(ArithProfile* arithProfile, const Instruction* instruction)
-        : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile, instruction)
+    JITBinaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isBinaryProfileEmpty>(arithProfile)
     {
     }
 };
@@ -274,8 +271,8 @@
 template <typename GeneratorType>
 class JITUnaryMathIC : public JITMathIC<GeneratorType, isUnaryProfileEmpty> {
 public:
-    JITUnaryMathIC(ArithProfile* arithProfile, const Instruction* instruction)
-        : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile, instruction)
+    JITUnaryMathIC(ArithProfile* arithProfile)
+        : JITMathIC<GeneratorType, isUnaryProfileEmpty>(arithProfile)
     {
     }
 };
diff --git a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h
index 8097a2f..256a5f6 100644
--- a/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h
+++ b/Source/JavaScriptCore/jit/PolymorphicCallStubRoutine.h
@@ -38,7 +38,7 @@
 
 class CallLinkInfo;
 
-class PolymorphicCallNode : public BasicRawSentinelNode<PolymorphicCallNode> {
+class PolymorphicCallNode : public PackedRawSentinelNode<PolymorphicCallNode> {
     WTF_MAKE_NONCOPYABLE(PolymorphicCallNode);
 public:
     PolymorphicCallNode(CallLinkInfo* info)
@@ -50,11 +50,11 @@
     
     void unlink(VM&);
 
-    bool hasCallLinkInfo(CallLinkInfo* info) { return m_callLinkInfo == info; }
+    bool hasCallLinkInfo(CallLinkInfo* info) { return m_callLinkInfo.get() == info; }
     void clearCallLinkInfo();
     
 private:
-    CallLinkInfo* m_callLinkInfo;
+    PackedPtr<CallLinkInfo> m_callLinkInfo;
 };
 
 class PolymorphicCallCase {
diff --git a/Source/JavaScriptCore/jit/SnippetOperand.h b/Source/JavaScriptCore/jit/SnippetOperand.h
index 5da3ec0..0413cb9 100644
--- a/Source/JavaScriptCore/jit/SnippetOperand.h
+++ b/Source/JavaScriptCore/jit/SnippetOperand.h
@@ -28,11 +28,12 @@
 #if ENABLE(JIT)
 
 #include "ResultType.h"
+#include <wtf/Packed.h>
 
 namespace JSC {
 
 class SnippetOperand {
-    enum ConstOrVarType {
+    enum ConstOrVarType : uint8_t {
         Variable,
         ConstInt32,
         ConstDouble
@@ -55,18 +56,18 @@
     bool isConstDouble() const { return m_type == ConstDouble; }
     bool isPositiveConstInt32() const { return isConstInt32() && asConstInt32() > 0; }
 
-    int64_t asRawBits() const { return m_val.rawBits; }
+    int64_t asRawBits() const { return m_val.get().rawBits; }
 
     int32_t asConstInt32() const
     {
         ASSERT(m_type == ConstInt32);
-        return m_val.int32Val;
+        return m_val.get().int32Val;
     }
 
     double asConstDouble() const
     {
         ASSERT(m_type == ConstDouble);
-        return m_val.doubleVal;
+        return m_val.get().doubleVal;
     }
 
     double asConstNumber() const
@@ -80,24 +81,30 @@
     void setConstInt32(int32_t value)
     {
         m_type = ConstInt32;
-        m_val.int32Val = value;
+        UnionType u;
+        u.int32Val = value;
+        m_val = WTFMove(u);
     }
 
     void setConstDouble(double value)
     {
         m_type = ConstDouble;
-        m_val.doubleVal = value;
+        UnionType u;
+        u.doubleVal = value;
+        m_val = WTFMove(u);
     }
 
 private:
     ResultType m_resultType;
     ConstOrVarType m_type { Variable };
-    union {
+    union UnionType {
         int32_t int32Val;
         double doubleVal;
         int64_t rawBits;
-    } m_val;
+    };
+    Packed<UnionType> m_val;
 };
+static_assert(alignof(SnippetOperand) == 1);
 
 } // namespace JSC
 
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index f409f05..8ac3642 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-13  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Compress miscelaneous JIT related data structures with Packed<>
+        https://bugs.webkit.org/show_bug.cgi?id=197830
+
+        Reviewed by Saam Barati.
+
+        * wtf/Packed.h:
+        (WTF::alignof):
+
 2019-05-13  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         Unreviewed, fix unused variable warnings in release builds
diff --git a/Source/WTF/wtf/Packed.h b/Source/WTF/wtf/Packed.h
index d67b4ac..fb8815f 100644
--- a/Source/WTF/wtf/Packed.h
+++ b/Source/WTF/wtf/Packed.h
@@ -161,6 +161,7 @@
     T* operator->() const { return get(); }
     T& operator*() const { return *get(); }
     bool operator!() const { return !get(); }
+    explicit operator bool() const { return get(); }
 
     PackedAlignedPtr& operator=(T* value)
     {