Changeset 262562 in webkit
- Timestamp:
- Jun 4, 2020 12:54:17 PM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r262542 r262562 1 2020-06-04 Mark Lam <mark.lam@apple.com> 2 3 Reduce DFGDoesGCCheck to only storing a uint32_t. 4 https://bugs.webkit.org/show_bug.cgi?id=212734 5 6 Reviewed by Saam Barati and Caio Lima. 7 8 This patch changes the encoding of DoesGCCheck so that it will fit better in a 9 uint32_t. This has the following benefits: 10 1. speed improvement for debug builds because it now takes less instructions 11 (especially in JITted code) to store to DoesGCCheck::m_value. 12 2. enables this check for 32-bit platforms as well. 13 14 Fun fact: we currently have 373 DFG::NodeTypes. Hence, 9 bits for nodeOp. 15 16 The new encoding provides 21 bis for the nodeIndex. This gives us up to 2097152 17 node indexes. In my experience, I've never seen more than 3 decimal digits for 18 the nodeIndex so far. If we ever find that we need more than 21 bits of nodeIndex, 19 we have 2 options to deal with it: 20 21 1. We can just ignore the high bits. After all, it is the nodeOp that is the 22 most interesting piece of data we need to debug doesGC issues. 23 24 2. We can make DoesGCCheck use uint64_t for storage. This encoding automatically 25 scales to 64-bit, while still allowing the more efficient form of storing a 26 32-bit immediate to be used for the common cases. 27 28 This patch also makes ENABLE_DFG_DOES_GC_VALIDATION dependent on ENABLE(DFG_JIT). 29 DoesGC is only relevant for the DFG and FTL JITs. 30 31 * dfg/DFGDoesGCCheck.cpp: 32 (JSC::DFG::DoesGCCheck::verifyCanGC): 33 * dfg/DFGDoesGCCheck.h: 34 (JSC::DFG::DoesGCCheck::encode): 35 (JSC::DFG::DoesGCCheck::expectDoesGC const): 36 (JSC::DFG::DoesGCCheck::isSpecial const): 37 (JSC::DFG::DoesGCCheck::special): 38 (JSC::DFG::DoesGCCheck::nodeOp): 39 (JSC::DFG::DoesGCCheck::nodeIndex): 40 (JSC::DFG::DoesGCCheck::expectDoesGC): Deleted. 41 (JSC::DFG::DoesGCCheck::isSpecial): Deleted. 42 (JSC::DFG::DoesGCCheck::specialIndex): Deleted. 43 (JSC::DFG::DoesGCCheck::bits): Deleted. 44 * dfg/DFGNodeType.h: 45 * dfg/DFGOSRExit.cpp: 46 (JSC::DFG::OSRExit::compileExit): 47 * dfg/DFGSpeculativeJIT32_64.cpp: 48 (JSC::DFG::SpeculativeJIT::compile): 49 * dfg/DFGSpeculativeJIT64.cpp: 50 (JSC::DFG::SpeculativeJIT::compile): 51 * ftl/FTLLowerDFGToB3.cpp: 52 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 53 * ftl/FTLOSRExitCompiler.cpp: 54 (JSC::FTL::compileStub): 55 * heap/Heap.h: 56 1 57 2020-06-04 Tim Horton <timothy_horton@apple.com> 2 58 -
trunk/Source/JavaScriptCore/dfg/DFGDoesGCCheck.cpp
r262517 r262562 29 29 #include "CallFrame.h" 30 30 #include "CodeBlock.h" 31 #include "DFGNodeType.h" 31 32 #include "Heap.h" 32 33 #include "VMInspector.h" … … 42 43 void DoesGCCheck::verifyCanGC(VM& vm) 43 44 { 45 // We do this check here just so we don't have to #include DFGNodeType.h 46 // in the header file. 47 static_assert(numberOfNodeTypes <= (1 << nodeOpBits)); 48 44 49 if (!expectDoesGC()) { 45 50 dataLog("Error: DoesGC failed"); … … 54 59 dataLog(" @ FTL osr exit"); 55 60 break; 56 case Special::ReservedUnused:57 61 case Special::NumberOfSpecials: 58 62 RELEASE_ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/dfg/DFGDoesGCCheck.h
r262517 r262562 37 37 struct DoesGCCheck { 38 38 enum class Special { 39 ReservedUnused, // so that specials start with 1. isSpecial() relies on this.40 39 Uninitialized, 41 40 DFGOSRExit, … … 48 47 { } 49 48 50 static uint 64_t encode(bool expectDoesGC, unsigned nodeIndex, unsigned nodeOp)49 static uint32_t encode(bool expectDoesGC, unsigned nodeIndex, unsigned nodeOp) 51 50 { 52 uint64_t result = bits(nodeIndex) << nodeIndexShift; 53 result |= bits(nodeOp) << nodeOpShift; 54 result |= bits(expectDoesGC) << expectDoesGCShift; 55 return result; 51 // We know nodeOp always fits because of the static_assert in DFGDoesGCCheck.cpp. 52 ASSERT((nodeIndex << nodeIndexShift) >> nodeIndexShift == nodeIndex); 53 return nodeIndex << nodeIndexShift | nodeOp << nodeOpShift | bits(expectDoesGC); 56 54 } 57 55 58 static uint 64_t encode(bool expectDoesGC, Special special)56 static uint32_t encode(bool expectDoesGC, Special special) 59 57 { 60 ASSERT(bits(special) < numberOfSpecials); 61 uint64_t result = bits(special) << specialShift; 62 result |= bits(expectDoesGC) << expectDoesGCShift; 63 return result; 58 return bits(special) << specialShift | isSpecialBit | bits(expectDoesGC); 64 59 } 65 60 … … 74 69 } 75 70 76 bool expectDoesGC() { return m_value & expectDoesGCMask; } 77 Special special() { return static_cast<Special>(specialIndex()); } 71 bool expectDoesGC() const { return m_value & expectDoesGCBit; } 72 bool isSpecial() const { return m_value & isSpecialBit; } 73 74 Special special() { return static_cast<Special>(m_value >> specialShift); } 75 76 unsigned nodeOp() { return (m_value >> nodeOpShift) & nodeOpMask; } 78 77 unsigned nodeIndex() { return m_value >> nodeIndexShift; } 79 unsigned nodeOp() { return (m_value >> nodeOpShift) & nodeOpMask; }80 81 bool isSpecial() { return specialIndex(); }82 78 83 79 JS_EXPORT_PRIVATE void verifyCanGC(VM&); 84 80 85 81 private: 86 unsigned specialIndex() { return (m_value >> specialShift) & specialMask; }82 template<typename T> static uint32_t bits(T value) { return static_cast<uint32_t>(value); } 87 83 88 template<typename T> static uint64_t bits(T value) { return static_cast<uint64_t>(value); } 84 // The value cannot be both a Special and contain node information at the 85 // time. Hence, the 2 can have separate encodings. The isSpecial bit 86 // determines which encoding is in use. 89 87 90 static constexpr uint64_t numberOfSpecials = static_cast<uint64_t>(Special::NumberOfSpecials); 88 static constexpr unsigned expectDoesGCBit = 1 << 0; 89 static constexpr unsigned isSpecialBit = 1 << 1; 90 static constexpr unsigned commonBits = 2; 91 static_assert((expectDoesGCBit | isSpecialBit) == (1 << commonBits) - 1); 91 92 92 static constexpr unsigned expectDoesGCShift = 0; 93 static constexpr unsigned specialShift = 1; 94 static constexpr unsigned nodeOpShift = 16; 95 static constexpr unsigned nodeIndexShift = 32; 93 static constexpr unsigned specialShift = commonBits; 96 94 97 static constexpr unsigned expectDoesGCMask = 0x1;98 static constexpr unsigned specialMask = 0x7fff;99 static constexpr unsigned nodeOp Mask = 0xffff;95 static constexpr unsigned nodeOpBits = 9; 96 static constexpr unsigned nodeOpMask = (1 << nodeOpBits) - 1; 97 static constexpr unsigned nodeOpShift = commonBits; 100 98 101 uint64_t m_value { 0 }; 99 static constexpr unsigned nodeIndexBits = 21; 100 static constexpr unsigned nodeIndexShift = nodeOpShift + nodeOpBits; 101 static_assert(nodeIndexShift + nodeIndexBits == 32); 102 103 uint32_t m_value { 0 }; 102 104 }; 103 105 -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r262252 r262562 1 1 /* 2 * Copyright (C) 2012-20 19Apple Inc. All rights reserved.2 * Copyright (C) 2012-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 553 553 }; 554 554 555 #define DFG_OP_COUNT(opcode, flags) + 1 556 constexpr unsigned numberOfNodeTypes = FOR_EACH_DFG_OP(DFG_OP_COUNT); 557 #undef DFG_OP_COUNT 558 555 559 // Specifies the default flags for each node. 556 560 inline NodeFlags defaultFlags(NodeType op) -
trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp
r262534 r262562 561 561 // we exit from this site, but all subsequent exits will take this compiled 562 562 // ramp without calling compileOSRExit() first. 563 jit.store 64(CCallHelpers::TrustedImm64(DoesGCCheck::encode(true, DoesGCCheck::Special::DFGOSRExit)), vm.heap.addressOfDoesGC());563 jit.store32(CCallHelpers::TrustedImm32(DoesGCCheck::encode(true, DoesGCCheck::Special::DFGOSRExit)), vm.heap.addressOfDoesGC()); 564 564 } 565 565 #endif -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r262252 r262562 1 1 /* 2 * Copyright (C) 2011-20 19Apple Inc. All rights reserved.2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2011 Intel Corporation. All rights reserved. 4 4 * … … 34 34 #include "DFGAbstractInterpreterInlines.h" 35 35 #include "DFGCallArrayAllocatorSlowPathGenerator.h" 36 #include "DFGDoesGC.h" 36 37 #include "DFGOperations.h" 37 38 #include "DFGSlowPathGenerator.h" … … 1806 1807 { 1807 1808 NodeType op = node->op(); 1809 1810 if (validateDFGDoesGC) { 1811 bool expectDoesGC = doesGC(m_jit.graph(), node); 1812 m_jit.store32(TrustedImm32(DoesGCCheck::encode(expectDoesGC, node->index(), node->op())), vm().heap.addressOfDoesGC()); 1813 } 1808 1814 1809 1815 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r262535 r262562 2139 2139 if (validateDFGDoesGC) { 2140 2140 bool expectDoesGC = doesGC(m_jit.graph(), node); 2141 m_jit.store 64(TrustedImm64(DoesGCCheck::encode(expectDoesGC, node->index(), node->op())), vm().heap.addressOfDoesGC());2141 m_jit.store32(TrustedImm32(DoesGCCheck::encode(expectDoesGC, node->index(), node->op())), vm().heap.addressOfDoesGC()); 2142 2142 } 2143 2143 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r262513 r262562 705 705 if (validateDFGDoesGC) { 706 706 bool expectDoesGC = doesGC(m_graph, m_node); 707 m_out.store(m_out.constInt 64(DoesGCCheck::encode(expectDoesGC, m_node->index(), m_node->op())), m_out.absolute(vm().heap.addressOfDoesGC()));707 m_out.store(m_out.constInt32(DoesGCCheck::encode(expectDoesGC, m_node->index(), m_node->op())), m_out.absolute(vm().heap.addressOfDoesGC())); 708 708 } 709 709 -
trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
r262513 r262562 216 216 // we exit from this site, but all subsequent exits will take this compiled 217 217 // ramp without calling compileFTLOSRExit() first. 218 jit.store 64(CCallHelpers::TrustedImm64(DoesGCCheck::encode(true, DoesGCCheck::Special::FTLOSRExit)), vm.heap.addressOfDoesGC());218 jit.store32(CCallHelpers::TrustedImm32(DoesGCCheck::encode(true, DoesGCCheck::Special::FTLOSRExit)), vm.heap.addressOfDoesGC()); 219 219 } 220 220 -
trunk/Source/JavaScriptCore/heap/Heap.h
r262513 r262562 99 99 } 100 100 101 #define ENABLE_DFG_DOES_GC_VALIDATION ASSERT_ENABLED 101 #if ENABLE(DFG_JIT) && ASSERT_ENABLED 102 #define ENABLE_DFG_DOES_GC_VALIDATION 1 103 #else 104 #define ENABLE_DFG_DOES_GC_VALIDATION 0 105 #endif 106 102 107 constexpr bool validateDFGDoesGC = ENABLE_DFG_DOES_GC_VALIDATION; 103 108
Note: See TracChangeset
for help on using the changeset viewer.