Changeset 244309 in webkit
- Timestamp:
- Apr 15, 2019, 4:53:23 PM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 51 edited
-
ChangeLog (modified) (1 diff)
-
JavaScriptCore.xcodeproj/project.pbxproj (modified) (7 diffs)
-
b3/B3ArgumentRegValue.cpp (modified) (1 diff)
-
b3/B3ArgumentRegValue.h (modified) (1 diff)
-
b3/B3AtomicValue.cpp (modified) (2 diffs)
-
b3/B3AtomicValue.h (modified) (1 diff)
-
b3/B3BasicBlock.h (modified) (1 diff)
-
b3/B3BasicBlockInlines.h (modified) (1 diff)
-
b3/B3CCallValue.cpp (modified) (1 diff)
-
b3/B3CCallValue.h (modified) (2 diffs)
-
b3/B3CheckValue.cpp (modified) (1 diff)
-
b3/B3CheckValue.h (modified) (1 diff)
-
b3/B3Const32Value.cpp (modified) (1 diff)
-
b3/B3Const32Value.h (modified) (2 diffs)
-
b3/B3Const64Value.cpp (modified) (1 diff)
-
b3/B3Const64Value.h (modified) (1 diff)
-
b3/B3ConstDoubleValue.cpp (modified) (1 diff)
-
b3/B3ConstDoubleValue.h (modified) (1 diff)
-
b3/B3ConstFloatValue.cpp (modified) (1 diff)
-
b3/B3ConstFloatValue.h (modified) (1 diff)
-
b3/B3ConstPtrValue.h (modified) (2 diffs)
-
b3/B3FenceValue.cpp (modified) (1 diff)
-
b3/B3FenceValue.h (modified) (1 diff)
-
b3/B3MemoryValue.cpp (modified) (2 diffs)
-
b3/B3MemoryValue.h (modified) (2 diffs)
-
b3/B3MoveConstants.cpp (modified) (1 diff)
-
b3/B3PatchpointValue.cpp (modified) (1 diff)
-
b3/B3PatchpointValue.h (modified) (1 diff)
-
b3/B3Procedure.cpp (modified) (1 diff)
-
b3/B3Procedure.h (modified) (1 diff)
-
b3/B3ProcedureInlines.h (modified) (1 diff)
-
b3/B3SlotBaseValue.cpp (modified) (1 diff)
-
b3/B3SlotBaseValue.h (modified) (1 diff)
-
b3/B3StackmapSpecial.cpp (modified) (4 diffs)
-
b3/B3StackmapValue.cpp (modified) (3 diffs)
-
b3/B3StackmapValue.h (modified) (2 diffs)
-
b3/B3SwitchValue.cpp (modified) (1 diff)
-
b3/B3SwitchValue.h (modified) (1 diff)
-
b3/B3UpsilonValue.cpp (modified) (1 diff)
-
b3/B3UpsilonValue.h (modified) (1 diff)
-
b3/B3Value.cpp (modified) (7 diffs)
-
b3/B3Value.h (modified) (11 diffs)
-
b3/B3ValueInlines.h (modified) (2 diffs)
-
b3/B3VariableValue.cpp (modified) (2 diffs)
-
b3/B3VariableValue.h (modified) (1 diff)
-
b3/B3WasmAddressValue.cpp (modified) (1 diff)
-
b3/B3WasmAddressValue.h (modified) (1 diff)
-
b3/B3WasmBoundsCheckValue.cpp (modified) (3 diffs)
-
b3/B3WasmBoundsCheckValue.h (modified) (2 diffs)
-
b3/testb3.cpp (modified) (5 diffs)
-
ftl/FTLOutput.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r244300 r244309 1 2019-04-15 Robin Morisset <rmorisset@apple.com> 2 3 B3::Value should have different kinds of adjacency lists 4 https://bugs.webkit.org/show_bug.cgi?id=196091 5 6 Reviewed by Filip Pizlo. 7 8 The key idea of this optimization is to replace the Vector<Value*, 3> m_children in B3::Value (40 bytes on 64-bits platform) by one of the following: 9 - Nothing (0 bytes) 10 - 1 Value* (8 bytes) 11 - 2 Value* (16 bytes) 12 - 3 Value* (24 bytes) 13 - A Vector<Value*, 3> 14 after the end of the Value object, depending on the kind of the Value. 15 So for example, when allocating an Add, we would allocate an extra 16 bytes into which to store 2 Values. 16 This would halve the memory consumption of Const64/Const32/Nop/Identity and a bunch more kinds of values, and reduce by a more moderate amount the memory consumption of the rest of non-varargs values (e.g. Add would go from 72 to 48 bytes). 17 18 A few implementation points: 19 - Even if there is no children, we must remember to allocate at least enough space for replaceWithIdentity to work later. It needs sizeof(Value) (for the object itself) + sizeof(Value*) (for the pointer to its child) 20 - We must make sure to destroy the vector whenever we destroy a Value which is VarArgs 21 - We must remember how many elements there are in the case where we did not allocate a Vector. We cannot do it purely by relying on the kind, both for speed reasons and because Return can have either 0 or 1 argument in B3 22 Thankfully, we have an extra byte of padding to use in the middle of B3::Value 23 - In order to support clone(), we must have a separate version of allocate, which extracts the opcode from the to-be-cloned object instead of from the call to the constructor 24 - Speaking of which, we need a special templated function opcodeFromConstructor, because some of the constructors of subclasses of Value don't take an explicit Opcode as argument, typically because they match a single one. 25 - To maximize performance, we provide specialized versions of child/lastChild/numChildren/children in the subclasses of Value, skipping checks when the actual type of the Value is already known. 26 This is done through the B3_SPECIALIZE_VALUE_FOR_... defined at the bottom of B3Value.h 27 - In the constructors of Value, we convert all extra children arguments to Value* eagerly. It is not required for correctness (they will be converted when put into a Vector<Value*> or a Value* in the end), but it helps limit an explosion in the number of template instantiations. 28 - I moved DeepValueDump::dump from the .h to the .cpp, as there is no good reason to inline it, and recompiling JSC is already slow enough 29 30 * JavaScriptCore.xcodeproj/project.pbxproj: 31 * b3/B3ArgumentRegValue.cpp: 32 (JSC::B3::ArgumentRegValue::cloneImpl const): Deleted. 33 * b3/B3ArgumentRegValue.h: 34 * b3/B3AtomicValue.cpp: 35 (JSC::B3::AtomicValue::AtomicValue): 36 (JSC::B3::AtomicValue::cloneImpl const): Deleted. 37 * b3/B3AtomicValue.h: 38 * b3/B3BasicBlock.h: 39 * b3/B3BasicBlockInlines.h: 40 (JSC::B3::BasicBlock::appendNewNonTerminal): Deleted. 41 * b3/B3CCallValue.cpp: 42 (JSC::B3::CCallValue::appendArgs): 43 (JSC::B3::CCallValue::cloneImpl const): Deleted. 44 * b3/B3CCallValue.h: 45 * b3/B3CheckValue.cpp: 46 (JSC::B3::CheckValue::cloneImpl const): Deleted. 47 * b3/B3CheckValue.h: 48 * b3/B3Const32Value.cpp: 49 (JSC::B3::Const32Value::cloneImpl const): Deleted. 50 * b3/B3Const32Value.h: 51 * b3/B3Const64Value.cpp: 52 (JSC::B3::Const64Value::cloneImpl const): Deleted. 53 * b3/B3Const64Value.h: 54 * b3/B3ConstDoubleValue.cpp: 55 (JSC::B3::ConstDoubleValue::cloneImpl const): Deleted. 56 * b3/B3ConstDoubleValue.h: 57 * b3/B3ConstFloatValue.cpp: 58 (JSC::B3::ConstFloatValue::cloneImpl const): Deleted. 59 * b3/B3ConstFloatValue.h: 60 * b3/B3ConstPtrValue.h: 61 (JSC::B3::ConstPtrValue::opcodeFromConstructor): 62 * b3/B3FenceValue.cpp: 63 (JSC::B3::FenceValue::FenceValue): 64 (JSC::B3::FenceValue::cloneImpl const): Deleted. 65 * b3/B3FenceValue.h: 66 * b3/B3MemoryValue.cpp: 67 (JSC::B3::MemoryValue::MemoryValue): 68 (JSC::B3::MemoryValue::cloneImpl const): Deleted. 69 * b3/B3MemoryValue.h: 70 * b3/B3MoveConstants.cpp: 71 * b3/B3PatchpointValue.cpp: 72 (JSC::B3::PatchpointValue::cloneImpl const): Deleted. 73 * b3/B3PatchpointValue.h: 74 (JSC::B3::PatchpointValue::opcodeFromConstructor): 75 * b3/B3Procedure.cpp: 76 * b3/B3Procedure.h: 77 * b3/B3ProcedureInlines.h: 78 (JSC::B3::Procedure::add): 79 * b3/B3SlotBaseValue.cpp: 80 (JSC::B3::SlotBaseValue::cloneImpl const): Deleted. 81 * b3/B3SlotBaseValue.h: 82 * b3/B3StackmapSpecial.cpp: 83 (JSC::B3::StackmapSpecial::forEachArgImpl): 84 (JSC::B3::StackmapSpecial::isValidImpl): 85 * b3/B3StackmapValue.cpp: 86 (JSC::B3::StackmapValue::append): 87 (JSC::B3::StackmapValue::StackmapValue): 88 * b3/B3StackmapValue.h: 89 * b3/B3SwitchValue.cpp: 90 (JSC::B3::SwitchValue::SwitchValue): 91 (JSC::B3::SwitchValue::cloneImpl const): Deleted. 92 * b3/B3SwitchValue.h: 93 (JSC::B3::SwitchValue::opcodeFromConstructor): 94 * b3/B3UpsilonValue.cpp: 95 (JSC::B3::UpsilonValue::cloneImpl const): Deleted. 96 * b3/B3UpsilonValue.h: 97 * b3/B3Value.cpp: 98 (JSC::B3::DeepValueDump::dump const): 99 (JSC::B3::Value::~Value): 100 (JSC::B3::Value::replaceWithIdentity): 101 (JSC::B3::Value::replaceWithNopIgnoringType): 102 (JSC::B3::Value::replaceWithPhi): 103 (JSC::B3::Value::replaceWithJump): 104 (JSC::B3::Value::replaceWithOops): 105 (JSC::B3::Value::replaceWith): 106 (JSC::B3::Value::invertedCompare const): 107 (JSC::B3::Value::returnsBool const): 108 (JSC::B3::Value::cloneImpl const): Deleted. 109 * b3/B3Value.h: 110 (JSC::B3::DeepValueDump::dump const): Deleted. 111 * b3/B3ValueInlines.h: 112 (JSC::B3::Value::adjacencyListOffset const): 113 (JSC::B3::Value::cloneImpl const): 114 * b3/B3VariableValue.cpp: 115 (JSC::B3::VariableValue::VariableValue): 116 (JSC::B3::VariableValue::cloneImpl const): Deleted. 117 * b3/B3VariableValue.h: 118 * b3/B3WasmAddressValue.cpp: 119 (JSC::B3::WasmAddressValue::WasmAddressValue): 120 (JSC::B3::WasmAddressValue::cloneImpl const): Deleted. 121 * b3/B3WasmAddressValue.h: 122 * b3/B3WasmBoundsCheckValue.cpp: 123 (JSC::B3::WasmBoundsCheckValue::WasmBoundsCheckValue): 124 (JSC::B3::WasmBoundsCheckValue::cloneImpl const): Deleted. 125 * b3/B3WasmBoundsCheckValue.h: 126 (JSC::B3::WasmBoundsCheckValue::accepts): 127 (JSC::B3::WasmBoundsCheckValue::opcodeFromConstructor): 128 * b3/testb3.cpp: 129 (JSC::B3::testCallFunctionWithHellaArguments): 130 (JSC::B3::testCallFunctionWithHellaArguments2): 131 (JSC::B3::testCallFunctionWithHellaArguments3): 132 (JSC::B3::testCallFunctionWithHellaDoubleArguments): 133 (JSC::B3::testCallFunctionWithHellaFloatArguments): 134 * ftl/FTLOutput.h: 135 (JSC::FTL::Output::call): 136 1 137 2019-04-15 Tadeu Zagallo <tzagallo@apple.com> 2 138 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r244298 r244309 670 670 0FEC85421BDACDAC0080FF74 /* B3Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84F81BDACDAC0080FF74 /* B3Validate.h */; }; 671 671 0FEC85441BDACDAC0080FF74 /* B3Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FA1BDACDAC0080FF74 /* B3Value.h */; }; 672 0FEC85451BDACDAC0080FF74 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; };673 672 0FEC85471BDACDAC0080FF74 /* B3ValueRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FD1BDACDAC0080FF74 /* B3ValueRep.h */; }; 674 673 0FEC856E1BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC85491BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h */; }; … … 858 857 2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 425BA1337E4344E1B269A671 /* SourceOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; }; 859 858 3395C70722555F6D00BDBFAD /* B3EliminateDeadCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3395C70522555F6D00BDBFAD /* B3EliminateDeadCode.h */; }; 859 33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; }; 860 33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; }; 860 861 371D842D17C98B6E00ECF994 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 371D842C17C98B6E00ECF994 /* libz.dylib */; }; 861 862 37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C738D11EDB5672003F2B0B /* ParseInt.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 919 920 5333BBDC2110F7D9007618EC /* DFGSpeculativeJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */; }; 920 921 5333BBDD2110F7E1007618EC /* DFGSpeculativeJIT64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */; }; 921 5333BBDE2110FA3E007618EC /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; };922 922 5341FC721DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */; }; 923 923 534638711E70CF3D00F12AC1 /* JSRunLoopTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 534638701E70CF3D00F12AC1 /* JSRunLoopTimer.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 8507 8507 0FB3878E1BFBC44D00E3AB1E /* AirBlockWorklist.h in Headers */, 8508 8508 0F79C7CA1E74C93B00EB34D1 /* AirBreakCriticalEdges.h in Headers */, 8509 33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */, 8509 8510 0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */, 8510 8511 0FEC85741BDACDC70080FF74 /* AirCCallSpecial.h in Headers */, … … 8699 8700 0FEC85421BDACDAC0080FF74 /* B3Validate.h in Headers */, 8700 8701 0FEC85441BDACDAC0080FF74 /* B3Value.h in Headers */, 8701 0FEC85451BDACDAC0080FF74 /* B3ValueInlines.h in Headers */,8702 8702 0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */, 8703 8703 0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */, … … 10704 10704 5333BBDB2110F7D2007618EC /* DFGSpeculativeJIT32_64.cpp in Sources */, 10705 10705 5333BBDD2110F7E1007618EC /* DFGSpeculativeJIT64.cpp in Sources */, 10706 5333BBDE2110FA3E007618EC /* FTLLowerDFGToB3.cpp in Sources */,10707 10706 536B319E1F735F160037FC33 /* LowLevelInterpreter.cpp in Sources */, 10708 10707 0FF4274A158EBE91004CB9FF /* udis86.c in Sources */, … … 10838 10837 536B31261F71C5990037FC33 /* UnifiedSource120.cpp in Sources */, 10839 10838 536B312D1F71C5990037FC33 /* UnifiedSource121.cpp in Sources */, 10839 33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */, 10840 10840 536B31251F71C5990037FC33 /* UnifiedSource122.cpp in Sources */, 10841 10841 536B311E1F71C5990037FC33 /* UnifiedSource123.cpp in Sources */, -
trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp
r195395 r244309 40 40 } 41 41 42 Value* ArgumentRegValue::cloneImpl() const43 {44 return new ArgumentRegValue(*this);45 }46 47 42 } } // namespace JSC::B3 48 43 -
trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h
r209764 r244309 41 41 Reg argumentReg() const { return m_reg; } 42 42 43 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 44 43 45 protected: 44 46 void dumpMeta(CommaPrinter&, PrintStream&) const override; 45 47 46 Value* cloneImpl() const override;47 48 48 private: 49 49 friend class Procedure; 50 friend class Value; 51 52 static Opcode opcodeFromConstructor(Origin, Reg) { return ArgumentReg; } 50 53 51 54 ArgumentRegValue(Origin origin, Reg reg) 52 : Value(CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, origin)55 : Value(CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, Zero, origin) 53 56 , m_reg(reg) 54 57 { -
trunk/Source/JavaScriptCore/b3/B3AtomicValue.cpp
r215407 r244309 42 42 } 43 43 44 Value* AtomicValue::cloneImpl() const45 {46 return new AtomicValue(*this);47 }48 49 44 AtomicValue::AtomicValue(AtomicValue::AtomicValueRMW, Kind kind, Origin origin, Width width, Value* operand, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange) 50 : MemoryValue(CheckedOpcode, kind, operand->type(), origin, offset, range, fenceRange, operand, pointer)45 : MemoryValue(CheckedOpcode, kind, operand->type(), Two, origin, offset, range, fenceRange, operand, pointer) 51 46 , m_width(width) 52 47 { … … 67 62 68 63 AtomicValue::AtomicValue(AtomicValue::AtomicValueCAS, Kind kind, Origin origin, Width width, Value* expectedValue, Value* newValue, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange) 69 : MemoryValue(CheckedOpcode, kind, kind.opcode() == AtomicWeakCAS ? Int32 : expectedValue->type(), origin, offset, range, fenceRange, expectedValue, newValue, pointer)64 : MemoryValue(CheckedOpcode, kind, kind.opcode() == AtomicWeakCAS ? Int32 : expectedValue->type(), Three, origin, offset, range, fenceRange, expectedValue, newValue, pointer) 70 65 , m_width(width) 71 66 { -
trunk/Source/JavaScriptCore/b3/B3AtomicValue.h
r215407 r244309 45 45 46 46 Width accessWidth() const { return m_width; } 47 48 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 47 49 48 50 protected: 49 51 void dumpMeta(CommaPrinter&, PrintStream&) const override; 50 51 Value* cloneImpl() const override; 52 52 53 53 private: 54 54 friend class Procedure; 55 friend class Value; 55 56 56 57 enum AtomicValueRMW { AtomicValueRMWTag }; -
trunk/Source/JavaScriptCore/b3/B3BasicBlock.h
r214410 r244309 85 85 template<typename ValueType, typename... Arguments> 86 86 ValueType* appendNew(Procedure&, Arguments...); 87 template<typename ValueType, typename... Arguments>88 ValueType* appendNewNonTerminal(Procedure&, Arguments...);89 87 90 88 JS_EXPORT_PRIVATE Value* appendIntConstant(Procedure&, Origin, Type, int64_t value); -
trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h
r206525 r244309 39 39 ValueType* result = procedure.add<ValueType>(arguments...); 40 40 append(result); 41 return result;42 }43 44 template<typename ValueType, typename... Arguments>45 ValueType* BasicBlock::appendNewNonTerminal(Procedure& procedure, Arguments... arguments)46 {47 ValueType* result = procedure.add<ValueType>(arguments...);48 appendNonTerminal(result);49 41 return result; 50 42 } -
trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp
r195395 r244309 35 35 } 36 36 37 Value* CCallValue::cloneImpl() const 37 void CCallValue::appendArgs(const Vector<Value*>& args) 38 38 { 39 return new CCallValue(*this);39 childrenVector().appendVector(args); 40 40 } 41 41 -
trunk/Source/JavaScriptCore/b3/B3CCallValue.h
r206595 r244309 39 39 ~CCallValue(); 40 40 41 void appendArgs(const Vector<Value*>&); 42 41 43 Effects effects; 42 44 43 protected: 44 Value* cloneImpl() const override;45 45 B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN 46 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN 47 46 48 private: 47 49 friend class Procedure; 50 friend class Value; 51 52 template<typename... Arguments> 53 static Opcode opcodeFromConstructor(Arguments...) { return CCall; } 48 54 49 55 template<typename... Arguments> 50 56 CCallValue(Type type, Origin origin, Arguments... arguments) 51 : Value(CheckedOpcode, CCall, type, origin, arguments...)57 : Value(CheckedOpcode, CCall, type, VarArgs, origin, static_cast<Value*>(arguments)...) 52 58 , effects(Effects::forCall()) 53 59 { … … 57 63 template<typename... Arguments> 58 64 CCallValue(Type type, Origin origin, const Effects& effects, Arguments... arguments) 59 : Value(CheckedOpcode, CCall, type, origin, arguments...)65 : Value(CheckedOpcode, CCall, type, VarArgs, origin, static_cast<Value*>(arguments)...) 60 66 , effects(effects) 61 67 { -
trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp
r206595 r244309 41 41 } 42 42 43 Value* CheckValue::cloneImpl() const44 {45 return new CheckValue(*this);46 }47 48 43 // Use this form for CheckAdd, CheckSub, and CheckMul. 49 44 CheckValue::CheckValue(Kind kind, Origin origin, Value* left, Value* right) -
trunk/Source/JavaScriptCore/b3/B3CheckValue.h
r206595 r244309 51 51 void convertToAdd(); 52 52 53 protected: 54 Value* cloneImpl() const override; 53 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN 55 54 56 55 private: 57 56 friend class Procedure; 57 friend class Value; 58 58 59 59 // Use this form for CheckAdd, CheckSub, and CheckMul. -
trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp
r229517 r244309 304 304 } 305 305 306 Value* Const32Value::cloneImpl() const307 {308 return new Const32Value(*this);309 }310 311 306 } } // namespace JSC::B3 312 307 -
trunk/Source/JavaScriptCore/b3/B3Const32Value.h
r208848 r244309 76 76 TriState belowEqualConstant(const Value* other) const override; 77 77 78 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 79 78 80 protected: 79 81 void dumpMeta(CommaPrinter&, PrintStream&) const override; 80 82 81 Value* cloneImpl() const override; 82 83 friend class Procedure; 83 // Protected because of ConstPtrValue 84 static Opcode opcodeFromConstructor(Origin = Origin(), int32_t = 0) { return Const32; } 84 85 85 86 Const32Value(Origin origin, int32_t value) 86 : Value(CheckedOpcode, Const32, Int32, origin)87 : Value(CheckedOpcode, Const32, Int32, Zero, origin) 87 88 , m_value(value) 88 89 { … … 90 91 91 92 private: 93 friend class Procedure; 94 friend class Value; 95 92 96 int32_t m_value; 93 97 }; -
trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp
r229517 r244309 304 304 } 305 305 306 Value* Const64Value::cloneImpl() const307 {308 return new Const64Value(*this);309 }310 311 306 } } // namespace JSC::B3 312 307 -
trunk/Source/JavaScriptCore/b3/B3Const64Value.h
r208848 r244309 76 76 TriState belowEqualConstant(const Value* other) const override; 77 77 78 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 79 78 80 protected: 79 81 void dumpMeta(CommaPrinter&, PrintStream&) const override; 80 82 81 Value* cloneImpl() const override; 82 83 friend class Procedure; 83 // Protected because of ConstPtrValue 84 static Opcode opcodeFromConstructor(Origin = Origin(), int64_t = 0) { return Const64; } 84 85 85 86 Const64Value(Origin origin, int64_t value) 86 : Value(CheckedOpcode, Const64, Int64, origin)87 : Value(CheckedOpcode, Const64, Int64, Zero, origin) 87 88 , m_value(value) 88 89 { 89 90 } 90 91 91 92 private: 93 friend class Procedure; 94 friend class Value; 95 92 96 int64_t m_value; 93 97 }; -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp
r210124 r244309 198 198 } 199 199 200 Value* ConstDoubleValue::cloneImpl() const201 {202 return new ConstDoubleValue(*this);203 }204 205 200 } } // namespace JSC::B3 206 201 -
trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h
r210124 r244309 65 65 TriState equalOrUnorderedConstant(const Value* other) const override; 66 66 67 protected: 68 void dumpMeta(CommaPrinter&, PrintStream&) const override; 69 70 Value* cloneImpl() const override; 67 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 71 68 72 69 private: 73 70 friend class Procedure; 71 friend class Value; 72 73 void dumpMeta(CommaPrinter&, PrintStream&) const override; 74 75 static Opcode opcodeFromConstructor(Origin, double) { return ConstDouble; } 74 76 75 77 ConstDoubleValue(Origin origin, double value) 76 : Value(CheckedOpcode, ConstDouble, Double, origin)78 : Value(CheckedOpcode, ConstDouble, Double, Zero, origin) 77 79 , m_value(value) 78 80 { -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp
r219038 r244309 190 190 } 191 191 192 Value* ConstFloatValue::cloneImpl() const193 {194 return new ConstFloatValue(*this);195 }196 197 192 } } // namespace JSC::B3 198 193 -
trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h
r219038 r244309 64 64 TriState equalOrUnorderedConstant(const Value* other) const override; 65 65 66 protected: 67 void dumpMeta(CommaPrinter&, PrintStream&) const override; 68 69 Value* cloneImpl() const override; 66 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 70 67 71 68 private: 72 69 friend class Procedure; 70 friend class Value; 71 72 void dumpMeta(CommaPrinter&, PrintStream&) const override; 73 74 static Opcode opcodeFromConstructor(Origin, float) { return ConstFloat; } 73 75 74 76 ConstFloatValue(Origin origin, float value) 75 : Value(CheckedOpcode, ConstFloat, Float, origin)77 : Value(CheckedOpcode, ConstFloat, Float, Zero, origin) 76 78 , m_value(value) 77 79 { -
trunk/Source/JavaScriptCore/b3/B3ConstPtrValue.h
r237173 r244309 52 52 private: 53 53 friend class Procedure; 54 friend class Value; 54 55 56 template<typename T> 57 static Opcode opcodeFromConstructor(Origin, T*) { return ConstPtrValueBase::opcodeFromConstructor(); } 55 58 template<typename T> 56 59 ConstPtrValue(Origin origin, T* pointer) … … 58 61 { 59 62 } 63 template<typename T> 64 static Opcode opcodeFromConstructor(Origin, T) { return ConstPtrValueBase::opcodeFromConstructor(); } 60 65 template<typename T> 61 66 ConstPtrValue(Origin origin, T pointer) -
trunk/Source/JavaScriptCore/b3/B3FenceValue.cpp
r206226 r244309 35 35 } 36 36 37 Value* FenceValue::cloneImpl() const38 {39 return new FenceValue(*this);40 }41 42 37 FenceValue::FenceValue(Origin origin, HeapRange read, HeapRange write) 43 : Value(CheckedOpcode, Fence, Void, origin)38 : Value(CheckedOpcode, Fence, Void, Zero, origin) 44 39 , read(read) 45 40 , write(write) -
trunk/Source/JavaScriptCore/b3/B3FenceValue.h
r213704 r244309 73 73 HeapRange write { HeapRange::top() }; 74 74 75 protected: 76 Value* cloneImpl() const override; 75 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 77 76 78 77 private: 79 78 friend class Procedure; 79 friend class Value; 80 80 81 static Opcode opcodeFromConstructor(Origin, HeapRange = HeapRange(), HeapRange = HeapRange()) { return Fence; } 81 82 FenceValue(Origin origin, HeapRange read, HeapRange write); 82 83 83 FenceValue(Origin origin); 84 84 }; -
trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp
r215407 r244309 74 74 } 75 75 76 Value* MemoryValue::cloneImpl() const77 {78 return new MemoryValue(*this);79 }80 81 76 // Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that 82 77 // describes the returned type). 83 78 MemoryValue::MemoryValue(MemoryValue::MemoryValueLoad, Kind kind, Type type, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange) 84 : Value(CheckedOpcode, kind, type, origin, pointer)79 : Value(CheckedOpcode, kind, type, One, origin, pointer) 85 80 , m_offset(offset) 86 81 , m_range(range) … … 127 122 // Use this form for stores. 128 123 MemoryValue::MemoryValue(MemoryValue::MemoryValueStore, Kind kind, Origin origin, Value* value, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange) 129 : Value(CheckedOpcode, kind, Void, origin, value, pointer)124 : Value(CheckedOpcode, kind, Void, Two, origin, value, pointer) 130 125 , m_offset(offset) 131 126 , m_range(range) -
trunk/Source/JavaScriptCore/b3/B3MemoryValue.h
r215407 r244309 85 85 bool isCanonicalWidth() const { return B3::isCanonicalWidth(accessWidth()); } 86 86 87 B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN 88 87 89 protected: 88 90 void dumpMeta(CommaPrinter&, PrintStream&) const override; 89 90 Value* cloneImpl() const override; 91 91 92 92 template<typename Int, typename = IsLegalOffset<Int>, typename... Arguments> 93 MemoryValue(CheckedOpcodeTag, Kind kind, Type type, Origin origin, Int offset, HeapRange range, HeapRange fenceRange, Arguments... arguments)94 : Value(CheckedOpcode, kind, type, origin, arguments...)93 MemoryValue(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Int offset, HeapRange range, HeapRange fenceRange, Arguments... arguments) 94 : Value(CheckedOpcode, kind, type, numChildren, origin, static_cast<Value*>(arguments)...) 95 95 , m_offset(offset) 96 96 , m_range(range) … … 101 101 private: 102 102 friend class Procedure; 103 friend class Value; 103 104 104 105 bool isLegalOffsetImpl(int32_t offset) const; -
trunk/Source/JavaScriptCore/b3/B3MoveConstants.cpp
r225375 r244309 59 59 return key.opcode() == ConstFloat || key.opcode() == ConstDouble; 60 60 }); 61 61 62 62 lowerFPConstants(); 63 63 -
trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp
r196032 r244309 45 45 } 46 46 47 Value* PatchpointValue::cloneImpl() const48 {49 return new PatchpointValue(*this);50 }51 52 47 PatchpointValue::PatchpointValue(Type type, Origin origin) 53 48 : Base(CheckedOpcode, Patchpoint, type, origin) -
trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h
r206595 r244309 62 62 uint8_t numFPScratchRegisters { 0 }; 63 63 64 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN 65 64 66 protected: 65 67 void dumpMeta(CommaPrinter&, PrintStream&) const override; 66 68 67 Value* cloneImpl() const override;68 69 69 private: 70 70 friend class Procedure; 71 friend class Value; 71 72 73 static Opcode opcodeFromConstructor(Type, Origin) { return Patchpoint; } 72 74 JS_EXPORT_PRIVATE PatchpointValue(Type, Origin); 73 75 }; -
trunk/Source/JavaScriptCore/b3/B3Procedure.cpp
r221703 r244309 94 94 } 95 95 96 97 96 Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value) 98 97 { -
trunk/Source/JavaScriptCore/b3/B3Procedure.h
r221703 r244309 293 293 bool m_hasQuirks { false }; 294 294 }; 295 295 296 296 } } // namespace JSC::B3 297 297 -
trunk/Source/JavaScriptCore/b3/B3ProcedureInlines.h
r206525 r244309 30 30 #include "B3BasicBlock.h" 31 31 #include "B3Procedure.h" 32 #include "B3Value.h" 32 33 33 34 namespace JSC { namespace B3 { 34 35 35 36 template<typename ValueType, typename... Arguments> 36 37 ValueType* Procedure::add(Arguments... arguments) 37 38 { 38 return static_cast<ValueType*>(addValueImpl( new ValueType(arguments...)));39 return static_cast<ValueType*>(addValueImpl(Value::allocate<ValueType>(arguments...))); 39 40 } 40 41 -
trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.cpp
r195620 r244309 42 42 } 43 43 44 Value* SlotBaseValue::cloneImpl() const45 {46 return new SlotBaseValue(*this);47 }48 49 44 } } // namespace JSC::B3 50 45 -
trunk/Source/JavaScriptCore/b3/B3SlotBaseValue.h
r206595 r244309 42 42 StackSlot* slot() const { return m_slot; } 43 43 44 protected: 45 void dumpMeta(CommaPrinter&, PrintStream&) const override; 46 47 Value* cloneImpl() const override; 44 B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN 48 45 49 46 private: 50 47 friend class Procedure; 48 friend class Value; 51 49 50 void dumpMeta(CommaPrinter&, PrintStream&) const override; 51 52 static Opcode opcodeFromConstructor(Origin, StackSlot*) { return SlotBase; } 52 53 SlotBaseValue(Origin origin, StackSlot* slot) 53 : Value(CheckedOpcode, SlotBase, pointerType(), origin)54 : Value(CheckedOpcode, SlotBase, pointerType(), Zero, origin) 54 55 , m_slot(slot) 55 56 { -
trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp
r239427 r244309 84 84 // Check that insane things have not happened. 85 85 ASSERT(inst.args.size() >= numIgnoredAirArgs); 86 ASSERT(value-> children().size() >= numIgnoredB3Args);87 ASSERT(inst.args.size() - numIgnoredAirArgs >= value-> children().size() - numIgnoredB3Args);86 ASSERT(value->numChildren() >= numIgnoredB3Args); 87 ASSERT(inst.args.size() - numIgnoredAirArgs >= value->numChildren() - numIgnoredB3Args); 88 88 ASSERT(inst.args[0].kind() == Arg::Kind::Special); 89 89 90 for (unsigned i = 0; i < value-> children().size() - numIgnoredB3Args; ++i) {90 for (unsigned i = 0; i < value->numChildren() - numIgnoredB3Args; ++i) { 91 91 Arg& arg = inst.args[i + numIgnoredAirArgs]; 92 92 ConstrainedValue child = value->constrainedChild(i + numIgnoredB3Args); … … 161 161 // Check that insane things have not happened. 162 162 ASSERT(inst.args.size() >= numIgnoredAirArgs); 163 ASSERT(value-> children().size() >= numIgnoredB3Args);163 ASSERT(value->numChildren() >= numIgnoredB3Args); 164 164 165 165 // For the Inst to be valid, it needs to have the right number of arguments. 166 if (inst.args.size() - numIgnoredAirArgs < value-> children().size() - numIgnoredB3Args)166 if (inst.args.size() - numIgnoredAirArgs < value->numChildren() - numIgnoredB3Args) 167 167 return false; 168 168 … … 170 170 // example, you can't have a non-FP-offset address. This verifies those conditions as well as the 171 171 // argument types. 172 for (unsigned i = 0; i < value-> children().size() - numIgnoredB3Args; ++i) {172 for (unsigned i = 0; i < value->numChildren() - numIgnoredB3Args; ++i) { 173 173 Value* child = value->child(i + numIgnoredB3Args); 174 174 Arg& arg = inst.args[i + numIgnoredAirArgs]; … … 179 179 180 180 // The number of constraints has to be no greater than the number of B3 children. 181 ASSERT(value->m_reps.size() <= value-> children().size());181 ASSERT(value->m_reps.size() <= value->numChildren()); 182 182 183 183 // Verify any explicitly supplied constraints. -
trunk/Source/JavaScriptCore/b3/B3StackmapValue.cpp
r227617 r244309 38 38 { 39 39 if (rep == ValueRep::ColdAny) { 40 children ().append(value);40 childrenVector().append(value); 41 41 return; 42 42 } … … 45 45 m_reps.append(ValueRep::ColdAny); 46 46 47 children ().append(value);47 childrenVector().append(value); 48 48 m_reps.append(rep); 49 49 } … … 90 90 91 91 StackmapValue::StackmapValue(CheckedOpcodeTag, Kind kind, Type type, Origin origin) 92 : Value(CheckedOpcode, kind, type, origin)92 : Value(CheckedOpcode, kind, type, VarArgs, origin) 93 93 { 94 94 ASSERT(accepts(kind)); -
trunk/Source/JavaScriptCore/b3/B3StackmapValue.h
r227617 r244309 61 61 ~StackmapValue(); 62 62 63 // Use this to add children. Note that you could also add children by doing 64 // children().append(). That will work fine, but it's not recommended. 63 // Use this to add children. 65 64 void append(const ConstrainedValue& value) 66 65 { … … 285 284 return ConstrainedValueCollection(*this); 286 285 } 286 287 B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN 287 288 288 289 protected: -
trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp
r227597 r244309 107 107 } 108 108 109 Value* SwitchValue::cloneImpl() const110 {111 return new SwitchValue(*this);112 }113 114 109 SwitchValue::SwitchValue(Origin origin, Value* child) 115 : Value(CheckedOpcode, Switch, Void, origin, child)110 : Value(CheckedOpcode, Switch, Void, One, origin, child) 116 111 { 117 112 } -
trunk/Source/JavaScriptCore/b3/B3SwitchValue.h
r215908 r244309 65 65 void dumpSuccessors(const BasicBlock*, PrintStream&) const override; 66 66 67 B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1) 68 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 69 67 70 protected: 68 71 void dumpMeta(CommaPrinter&, PrintStream&) const override; 69 72 70 Value* cloneImpl() const override;71 72 73 private: 73 74 friend class Procedure; 75 friend class Value; 74 76 77 static Opcode opcodeFromConstructor(Origin, Value*) { return Switch; } 75 78 JS_EXPORT_PRIVATE SwitchValue(Origin, Value* child); 76 79 -
trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp
r195395 r244309 46 46 } 47 47 48 Value* UpsilonValue::cloneImpl() const49 {50 return new UpsilonValue(*this);51 }52 53 48 } } // namespace JSC::B3 54 49 -
trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h
r206595 r244309 46 46 } 47 47 48 B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1) 49 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 50 48 51 protected: 49 52 void dumpMeta(CommaPrinter&, PrintStream&) const override; 50 53 51 Value* cloneImpl() const override;52 53 54 private: 54 55 friend class Procedure; 56 friend class Value; 55 57 58 static Opcode opcodeFromConstructor(Origin, Value*, Value* = nullptr) { return Upsilon; } 56 59 // Note that passing the Phi during construction is optional. A valid pattern is to first create 57 60 // the Upsilons without the Phi, then create the Phi, then go back and tell the Upsilons about 58 61 // the Phi. This allows you to emit code in its natural order. 59 62 UpsilonValue(Origin origin, Value* value, Value* phi = nullptr) 60 : Value(CheckedOpcode, Upsilon, Void, origin, value)63 : Value(CheckedOpcode, Upsilon, Void, One, origin, value) 61 64 , m_phi(phi) 62 65 { -
trunk/Source/JavaScriptCore/b3/B3Value.cpp
r243851 r244309 48 48 #include <wtf/ListDump.h> 49 49 #include <wtf/StringPrintStream.h> 50 #include <wtf/Vector.h> 50 51 51 52 namespace JSC { namespace B3 { 52 53 53 54 const char* const Value::dumpPrefix = "@"; 55 void DeepValueDump::dump(PrintStream& out) const 56 { 57 if (m_value) 58 m_value->deepDump(m_proc, out); 59 else 60 out.print("<null>"); 61 } 54 62 55 63 Value::~Value() 56 64 { 65 if (m_numChildren == VarArgs) 66 bitwise_cast<Vector<Value*, 3> *>(childrenAlloc())->Vector<Value*, 3>::~Vector(); 57 67 } 58 68 … … 63 73 // previous value in place, and then we construct the Identity Value in place. 64 74 65 ASSERT(m_type == value->m_type);75 RELEASE_ASSERT(m_type == value->m_type); 66 76 ASSERT(value != this); 67 77 68 if (m_type == Void) {78 if (m_type == Void) 69 79 replaceWithNopIgnoringType(); 70 return; 71 } 72 73 unsigned index = m_index; 74 Type type = m_type; 75 Origin origin = m_origin; 76 BasicBlock* owner = this->owner; 77 78 RELEASE_ASSERT(type == value->type()); 79 80 this->~Value(); 81 82 new (this) Value(Identity, type, origin, value); 83 84 this->owner = owner; 85 this->m_index = index; 80 else 81 replaceWith(Identity, m_type, this->owner, value); 86 82 } 87 83 … … 99 95 void Value::replaceWithNopIgnoringType() 100 96 { 101 unsigned index = m_index; 102 Origin origin = m_origin; 103 BasicBlock* owner = this->owner; 104 105 this->~Value(); 106 107 new (this) Value(Nop, Void, origin); 108 109 this->owner = owner; 110 this->m_index = index; 97 replaceWith(Nop, Void, this->owner); 111 98 } 112 99 … … 117 104 return; 118 105 } 119 106 107 replaceWith(Phi, m_type, this->owner); 108 } 109 110 void Value::replaceWithJump(BasicBlock* owner, FrequentedBlock target) 111 { 112 RELEASE_ASSERT(owner->last() == this); 113 replaceWith(Jump, Void, this->owner); 114 owner->setSuccessors(target); 115 } 116 117 void Value::replaceWithOops(BasicBlock* owner) 118 { 119 RELEASE_ASSERT(owner->last() == this); 120 replaceWith(Oops, Void, this->owner); 121 owner->clearSuccessors(); 122 } 123 124 void Value::replaceWithJump(FrequentedBlock target) 125 { 126 replaceWithJump(owner, target); 127 } 128 129 void Value::replaceWithOops() 130 { 131 replaceWithOops(owner); 132 } 133 134 void Value::replaceWith(Kind kind, Type type, BasicBlock* owner) 135 { 120 136 unsigned index = m_index; 121 Origin origin = m_origin;122 BasicBlock* owner = this->owner;123 Type type = m_type;124 137 125 138 this->~Value(); 126 139 127 new (this) Value(Phi, type, origin); 128 140 new (this) Value(kind, type, m_origin); 141 142 this->m_index = index; 129 143 this->owner = owner; 144 } 145 146 void Value::replaceWith(Kind kind, Type type, BasicBlock* owner, Value* value) 147 { 148 unsigned index = m_index; 149 150 this->~Value(); 151 152 new (this) Value(kind, type, m_origin, value); 153 130 154 this->m_index = index; 131 }132 133 void Value::replaceWithJump(BasicBlock* owner, FrequentedBlock target)134 {135 RELEASE_ASSERT(owner->last() == this);136 137 unsigned index = m_index;138 Origin origin = m_origin;139 140 this->~Value();141 142 new (this) Value(Jump, Void, origin);143 144 155 this->owner = owner; 145 this->m_index = index;146 147 owner->setSuccessors(target);148 }149 150 void Value::replaceWithOops(BasicBlock* owner)151 {152 RELEASE_ASSERT(owner->last() == this);153 154 unsigned index = m_index;155 Origin origin = m_origin;156 157 this->~Value();158 159 new (this) Value(Oops, Void, origin);160 161 this->owner = owner;162 this->m_index = index;163 164 owner->clearSuccessors();165 }166 167 void Value::replaceWithJump(FrequentedBlock target)168 {169 replaceWithJump(owner, target);170 }171 172 void Value::replaceWithOops()173 {174 replaceWithOops(owner);175 156 } 176 157 … … 204 185 if (isConstant) 205 186 out.print(")"); 206 }207 208 Value* Value::cloneImpl() const209 {210 return new Value(*this);211 187 } 212 188 … … 459 435 Value* Value::invertedCompare(Procedure& proc) const 460 436 { 461 if ( !numChildren())437 if (numChildren() != 2) 462 438 return nullptr; 463 439 if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type())) { 464 440 ASSERT(!kind().hasExtraBits()); 465 return proc.add<Value>(*invertedOpcode, type(), origin(), child ren());441 return proc.add<Value>(*invertedOpcode, type(), origin(), child(0), child(1)); 466 442 } 467 443 return nullptr; … … 497 473 if (type() != Int32) 498 474 return false; 475 499 476 switch (opcode()) { 500 477 case Const32: -
trunk/Source/JavaScriptCore/b3/B3Value.h
r231204 r244309 39 39 #include <wtf/CommaPrinter.h> 40 40 #include <wtf/FastMalloc.h> 41 #include <wtf/ Noncopyable.h>41 #include <wtf/IteratorRange.h> 42 42 #include <wtf/StdLibExtras.h> 43 43 #include <wtf/TriState.h> … … 54 54 WTF_MAKE_FAST_ALLOCATED; 55 55 public: 56 typedef Vector<Value*, 3> AdjacencyList;57 58 56 static const char* const dumpPrefix; 59 57 … … 83 81 void setOrigin(Origin origin) { m_origin = origin; } 84 82 85 Value*& child(unsigned index) { return m_children[index]; }86 Value* child(unsigned index) const { return m_children[index]; }87 88 Value*& lastChild() { return m_children.last(); }89 Value* lastChild() const { return m_children.last(); }90 91 unsigned numChildren() const { return m_children.size(); }92 93 83 Type type() const { return m_type; } 94 84 void setType(Type type) { m_type = type; } … … 98 88 Width resultWidth() const { return widthForType(type()); } 99 89 100 AdjacencyList& children() { return m_children; } 101 const AdjacencyList& children() const { return m_children; } 90 unsigned numChildren() const 91 { 92 if (m_numChildren == VarArgs) 93 return childrenVector().size(); 94 return m_numChildren; 95 } 96 97 Value*& child(unsigned index) 98 { 99 ASSERT(index < numChildren()); 100 return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index]; 101 } 102 Value* child(unsigned index) const 103 { 104 ASSERT(index < numChildren()); 105 return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index]; 106 } 107 108 Value*& lastChild() 109 { 110 if (m_numChildren == VarArgs) 111 return childrenVector().last(); 112 ASSERT(m_numChildren >= 1); 113 return childrenArray()[m_numChildren - 1]; 114 } 115 Value* lastChild() const 116 { 117 if (m_numChildren == VarArgs) 118 return childrenVector().last(); 119 ASSERT(m_numChildren >= 1); 120 return childrenArray()[m_numChildren - 1]; 121 } 122 123 WTF::IteratorRange<Value**> children() 124 { 125 if (m_numChildren == VarArgs) { 126 Vector<Value*, 3>& vec = childrenVector(); 127 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); 128 } 129 Value** buffer = childrenArray(); 130 return {buffer, buffer + m_numChildren }; 131 } 132 WTF::IteratorRange<Value* const*> children() const 133 { 134 if (m_numChildren == VarArgs) { 135 const Vector<Value*, 3>& vec = childrenVector(); 136 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); 137 } 138 Value* const* buffer = childrenArray(); 139 return {buffer, buffer + m_numChildren }; 140 } 102 141 103 142 // If you want to replace all uses of this value with a different value, then replace this … … 302 341 > { }; 303 342 304 305 343 protected: 306 virtual Value* cloneImpl() const; 307 344 Value* cloneImpl() const; 345 346 void replaceWith(Kind, Type, BasicBlock*); 347 void replaceWith(Kind, Type, BasicBlock*, Value*); 348 308 349 virtual void dumpChildren(CommaPrinter&, PrintStream&) const; 309 350 virtual void dumpMeta(CommaPrinter&, PrintStream&) const; 310 351 352 // The specific value of VarArgs does not matter, but the value of the others is assumed to match their meaning. 353 enum NumChildren : uint8_t { Zero = 0, One = 1, Two = 2, Three = 3, VarArgs = 4}; 354 355 char* childrenAlloc() { return bitwise_cast<char*>(this) + adjacencyListOffset(); } 356 const char* childrenAlloc() const { return bitwise_cast<const char*>(this) + adjacencyListOffset(); } 357 Vector<Value*, 3>& childrenVector() 358 { 359 ASSERT(m_numChildren == VarArgs); 360 return *bitwise_cast<Vector<Value*, 3>*>(childrenAlloc()); 361 } 362 const Vector<Value*, 3>& childrenVector() const 363 { 364 ASSERT(m_numChildren == VarArgs); 365 return *bitwise_cast<Vector<Value*, 3> const*>(childrenAlloc()); 366 } 367 Value** childrenArray() 368 { 369 ASSERT(m_numChildren != VarArgs); 370 return bitwise_cast<Value**>(childrenAlloc()); 371 } 372 Value* const* childrenArray() const 373 { 374 ASSERT(m_numChildren != VarArgs); 375 return bitwise_cast<Value* const*>(childrenAlloc()); 376 } 377 378 template<typename... Arguments> 379 static Opcode opcodeFromConstructor(Kind kind, Arguments...) { return kind.opcode(); } 380 ALWAYS_INLINE static size_t adjacencyListSpace(Kind kind) 381 { 382 switch (kind.opcode()) { 383 case FramePointer: 384 case Nop: 385 case Phi: 386 case Jump: 387 case Oops: 388 case EntrySwitch: 389 case ArgumentReg: 390 case Const32: 391 case Const64: 392 case ConstFloat: 393 case ConstDouble: 394 case Fence: 395 case SlotBase: 396 case Get: 397 return 0; 398 case Return: 399 case Identity: 400 case Opaque: 401 case Neg: 402 case Clz: 403 case Abs: 404 case Ceil: 405 case Floor: 406 case Sqrt: 407 case SExt8: 408 case SExt16: 409 case Trunc: 410 case SExt32: 411 case ZExt32: 412 case FloatToDouble: 413 case IToD: 414 case DoubleToFloat: 415 case IToF: 416 case BitwiseCast: 417 case Branch: 418 case Depend: 419 case Load8Z: 420 case Load8S: 421 case Load16Z: 422 case Load16S: 423 case Load: 424 case Switch: 425 case Upsilon: 426 case Set: 427 case WasmAddress: 428 case WasmBoundsCheck: 429 return sizeof(Value*); 430 case Add: 431 case Sub: 432 case Mul: 433 case Div: 434 case UDiv: 435 case Mod: 436 case UMod: 437 case BitAnd: 438 case BitOr: 439 case BitXor: 440 case Shl: 441 case SShr: 442 case ZShr: 443 case RotR: 444 case RotL: 445 case Equal: 446 case NotEqual: 447 case LessThan: 448 case GreaterThan: 449 case LessEqual: 450 case GreaterEqual: 451 case Above: 452 case Below: 453 case AboveEqual: 454 case BelowEqual: 455 case EqualOrUnordered: 456 case AtomicXchgAdd: 457 case AtomicXchgAnd: 458 case AtomicXchgOr: 459 case AtomicXchgSub: 460 case AtomicXchgXor: 461 case AtomicXchg: 462 case Store8: 463 case Store16: 464 case Store: 465 return 2 * sizeof(Value*); 466 case Select: 467 case AtomicWeakCAS: 468 case AtomicStrongCAS: 469 return 3 * sizeof(Value*); 470 case CCall: 471 case Check: 472 case CheckAdd: 473 case CheckSub: 474 case CheckMul: 475 case Patchpoint: 476 return sizeof(Vector<Value*, 3>); 477 default: 478 break; 479 } 480 RELEASE_ASSERT_NOT_REACHED(); 481 return 0; 482 } 483 311 484 private: 485 static char* allocateSpace(Opcode opcode, size_t size) 486 { 487 size_t adjacencyListSpace = Value::adjacencyListSpace(opcode); 488 // We must allocate enough space that replaceWithIdentity can work without buffer overflow. 489 size_t allocIdentitySize = sizeof(Value) + sizeof(Value*); 490 size_t allocSize = std::max(size + adjacencyListSpace, allocIdentitySize); 491 return static_cast<char*>(WTF::fastMalloc(allocSize)); 492 } 493 494 protected: 495 template<typename ValueType, typename... Arguments> 496 static ValueType* allocate(Arguments... arguments) 497 { 498 char* alloc = allocateSpace(ValueType::opcodeFromConstructor(arguments...), sizeof(ValueType)); 499 return new (alloc) ValueType(arguments...); 500 } 501 template<typename ValueType> 502 static ValueType* allocate(const ValueType& valueToClone) 503 { 504 char* alloc = allocateSpace(valueToClone.opcode(), sizeof(ValueType)); 505 ValueType* result = new (alloc) ValueType(valueToClone); 506 result->buildAdjacencyList(sizeof(ValueType), valueToClone); 507 return result; 508 } 509 510 // Protected so it will only be called from allocate above, possibly through the subclasses'copy constructors 511 Value(const Value&) = default; 512 513 Value(Value&&) = delete; 514 Value& operator=(const Value&) = delete; 515 Value& operator=(Value&&) = delete; 516 517 size_t adjacencyListOffset() const; 518 312 519 friend class Procedure; 313 520 friend class SparseCollection<Value>; 314 521 522 private: 523 template<typename... Arguments> 524 void buildAdjacencyList(NumChildren numChildren, Arguments... arguments) 525 { 526 if (numChildren == VarArgs) { 527 new (childrenAlloc()) Vector<Value*, 3> { arguments... }; 528 return; 529 } 530 ASSERT(numChildren == sizeof...(arguments)); 531 new (childrenAlloc()) Value*[sizeof...(arguments)] { arguments... }; 532 } 533 void buildAdjacencyList(size_t offset, const Value& valueToClone) 534 { 535 switch (valueToClone.m_numChildren) { 536 case VarArgs: 537 new (bitwise_cast<char*>(this) + offset) Vector<Value*, 3> (valueToClone.childrenVector()); 538 break; 539 case Three: 540 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[2] = valueToClone.childrenArray()[2]; 541 FALLTHROUGH; 542 case Two: 543 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[1] = valueToClone.childrenArray()[1]; 544 FALLTHROUGH; 545 case One: 546 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[0] = valueToClone.childrenArray()[0]; 547 break; 548 case Zero: 549 break; 550 } 551 } 552 315 553 // Checks that this kind is valid for use with B3::Value. 316 ALWAYS_INLINE static void checkKind(Kind kind, unsigned numArgs)554 ALWAYS_INLINE static NumChildren numChildrenForKind(Kind kind, unsigned numArgs) 317 555 { 318 556 switch (kind.opcode()) { … … 325 563 if (UNLIKELY(numArgs)) 326 564 badKind(kind, numArgs); 327 break;565 return Zero; 328 566 case Return: 329 567 if (UNLIKELY(numArgs > 1)) 330 568 badKind(kind, numArgs); 331 break;569 return numArgs ? One : Zero; 332 570 case Identity: 333 571 case Opaque: … … 352 590 if (UNLIKELY(numArgs != 1)) 353 591 badKind(kind, numArgs); 354 break;592 return One; 355 593 case Add: 356 594 case Sub: … … 381 619 if (UNLIKELY(numArgs != 2)) 382 620 badKind(kind, numArgs); 383 break;621 return Two; 384 622 case Select: 385 623 if (UNLIKELY(numArgs != 3)) 386 624 badKind(kind, numArgs); 387 break;625 return Three; 388 626 default: 389 627 badKind(kind, numArgs); 390 628 break; 391 629 } 630 return VarArgs; 392 631 } 393 632 394 633 protected: 395 634 enum CheckedOpcodeTag { CheckedOpcode }; 396 397 Value(const Value&) = default;398 Value& operator=(const Value&) = default;399 635 400 636 // Instantiate values via Procedure. 401 637 // This form requires specifying the type explicitly: 402 638 template<typename... Arguments> 403 explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments)639 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Value* firstChild, Arguments... arguments) 404 640 : m_kind(kind) 405 641 , m_type(type) 642 , m_numChildren(numChildren) 406 643 , m_origin(origin) 407 , m_children{ firstChild, arguments... }408 {644 { 645 buildAdjacencyList(numChildren, firstChild, arguments...); 409 646 } 410 647 // This form is for specifying the type explicitly when the opcode has no children: 411 explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin)648 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin) 412 649 : m_kind(kind) 413 650 , m_type(type) 651 , m_numChildren(numChildren) 414 652 , m_origin(origin) 415 653 { 654 buildAdjacencyList(numChildren); 655 } 656 // This form is for those opcodes that can infer their type from the opcode alone, and that don't 657 // take any arguments: 658 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin) 659 : m_kind(kind) 660 , m_type(typeFor(kind, nullptr)) 661 , m_numChildren(numChildren) 662 , m_origin(origin) 663 { 664 buildAdjacencyList(numChildren); 416 665 } 417 666 // This form is for those opcodes that can infer their type from the opcode and first child: 418 template<typename... Arguments> 419 explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild) 667 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild) 420 668 : m_kind(kind) 421 669 , m_type(typeFor(kind, firstChild)) 670 , m_numChildren(numChildren) 422 671 , m_origin(origin) 423 , m_children{ firstChild }424 {672 { 673 buildAdjacencyList(numChildren, firstChild); 425 674 } 426 675 // This form is for those opcodes that can infer their type from the opcode and first and second child: 427 676 template<typename... Arguments> 428 explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)677 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments) 429 678 : m_kind(kind) 430 679 , m_type(typeFor(kind, firstChild, secondChild)) 680 , m_numChildren(numChildren) 431 681 , m_origin(origin) 432 , m_children{ firstChild, secondChild, arguments... } 433 { 434 } 435 // This form is for those opcodes that can infer their type from the opcode alone, and that don't 436 // take any arguments: 437 explicit Value(CheckedOpcodeTag, Kind kind, Origin origin) 438 : m_kind(kind) 439 , m_type(typeFor(kind, nullptr)) 440 , m_origin(origin) 441 { 442 } 443 // Use this form for varargs. 444 explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, const AdjacencyList& children) 445 : m_kind(kind) 446 , m_type(type) 447 , m_origin(origin) 448 , m_children(children) 449 { 450 } 451 explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, AdjacencyList&& children) 452 : m_kind(kind) 453 , m_type(type) 454 , m_origin(origin) 455 , m_children(WTFMove(children)) 456 { 682 { 683 buildAdjacencyList(numChildren, firstChild, secondChild, arguments...); 457 684 } 458 685 459 686 // This is the constructor you end up actually calling, if you're instantiating Value 460 687 // directly. 688 explicit Value(Kind kind, Type type, Origin origin) 689 : Value(CheckedOpcode, kind, type, Zero, origin) 690 { 691 RELEASE_ASSERT(numChildrenForKind(kind, 0) == Zero); 692 } 693 // We explicitly convert the extra arguments to Value* (they may be pointers to some subclasses of Value) to limit template explosion 461 694 template<typename... Arguments> 462 explicit Value(Kind kind, Type type, Origin origin) 463 : Value(CheckedOpcode, kind, type, origin) 464 { 465 checkKind(kind, 0); 695 explicit Value(Kind kind, Origin origin, Arguments... arguments) 696 : Value(CheckedOpcode, kind, numChildrenForKind(kind, sizeof...(arguments)), origin, static_cast<Value*>(arguments)...) 697 { 466 698 } 467 699 template<typename... Arguments> 468 explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments&&... arguments) 469 : Value(CheckedOpcode, kind, type, origin, firstChild, std::forward<Arguments>(arguments)...) 470 { 471 checkKind(kind, 1 + sizeof...(arguments)); 472 } 473 template<typename... Arguments> 474 explicit Value(Kind kind, Type type, Origin origin, const AdjacencyList& children) 475 : Value(CheckedOpcode, kind, type, origin, children) 476 { 477 checkKind(kind, children.size()); 478 } 479 template<typename... Arguments> 480 explicit Value(Kind kind, Type type, Origin origin, AdjacencyList&& children) 481 : Value(CheckedOpcode, kind, type, origin, WTFMove(children)) 482 { 483 checkKind(kind, m_children.size()); 484 } 485 template<typename... Arguments> 486 explicit Value(Kind kind, Origin origin, Arguments&&... arguments) 487 : Value(CheckedOpcode, kind, origin, std::forward<Arguments>(arguments)...) 488 { 489 checkKind(kind, sizeof...(arguments)); 700 explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments) 701 : Value(CheckedOpcode, kind, type, numChildrenForKind(kind, 1 + sizeof...(arguments)), origin, firstChild, static_cast<Value*>(arguments)...) 702 { 490 703 } 491 704 492 705 private: 493 706 friend class CheckValue; // CheckValue::convertToAdd() modifies m_kind. 494 707 495 708 static Type typeFor(Kind, Value* firstChild, Value* secondChild = nullptr); 496 709 497 // This group of fields isarranged to fit in 64 bits.710 // m_index to m_numChildren are arranged to fit in 64 bits. 498 711 protected: 499 712 unsigned m_index { UINT_MAX }; … … 501 714 Kind m_kind; 502 715 Type m_type; 503 716 protected: 717 NumChildren m_numChildren; 718 private: 504 719 Origin m_origin; 505 AdjacencyList m_children;506 720 507 721 NO_RETURN_DUE_TO_CRASH static void badKind(Kind, unsigned); … … 519 733 } 520 734 521 void dump(PrintStream& out) const 522 { 523 if (m_value) 524 m_value->deepDump(m_proc, out); 525 else 526 out.print("<null>"); 527 } 735 void dump(PrintStream& out) const; 528 736 529 737 private: … … 541 749 } 542 750 751 // The following macros are designed for subclasses of B3::Value to use. 752 // They are never required for correctness, but can improve the performance of child/lastChild/numChildren/children methods, 753 // for users that already know the specific subclass of Value they are manipulating. 754 // The first set is to be used when you know something about the number of children of all values of a class, including its subclasses: 755 // - B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN: always 0 children (e.g. Const32Value) 756 // - B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n): always n children, with n in {1, 2, 3} (e.g. UpsilonValue, with n = 1) 757 // - B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN: different numbers of children, but never a variable number at runtime (e.g. MemoryValue, that can have between 1 and 3 children) 758 // - B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN: always a varargs (e.g. CCallValue) 759 // The second set is only to be used by classes that we know are not further subclassed by anyone adding fields, 760 // as they hardcode the offset of the children array/vector (which is equal to the size of the object). 761 // - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 762 // - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN 763 #define B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN \ 764 unsigned numChildren() const { return 0; } \ 765 WTF::IteratorRange<Value**> children() { return {nullptr, nullptr}; } \ 766 WTF::IteratorRange<Value* const*> children() const { return { nullptr, nullptr}; } 767 768 #define B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n) \ 769 public: \ 770 unsigned numChildren() const { return n; } \ 771 Value*& child(unsigned index) \ 772 { \ 773 ASSERT(index <= n); \ 774 return childrenArray()[index]; \ 775 } \ 776 Value* child(unsigned index) const \ 777 { \ 778 ASSERT(index <= n); \ 779 return childrenArray()[index]; \ 780 } \ 781 Value*& lastChild() \ 782 { \ 783 return childrenArray()[n - 1]; \ 784 } \ 785 Value* lastChild() const \ 786 { \ 787 return childrenArray()[n - 1]; \ 788 } \ 789 WTF::IteratorRange<Value**> children() \ 790 { \ 791 Value** buffer = childrenArray(); \ 792 return {buffer, buffer + n }; \ 793 } \ 794 WTF::IteratorRange<Value* const*> children() const \ 795 { \ 796 Value* const* buffer = childrenArray(); \ 797 return {buffer, buffer + n }; \ 798 } \ 799 800 #define B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN \ 801 public: \ 802 unsigned numChildren() const { return m_numChildren; } \ 803 Value*& child(unsigned index) { return childrenArray()[index]; } \ 804 Value* child(unsigned index) const { return childrenArray()[index]; } \ 805 Value*& lastChild() { return childrenArray()[numChildren() - 1]; } \ 806 Value* lastChild() const { return childrenArray()[numChildren() - 1]; } \ 807 WTF::IteratorRange<Value**> children() \ 808 { \ 809 Value** buffer = childrenArray(); \ 810 return {buffer, buffer + numChildren() }; \ 811 } \ 812 WTF::IteratorRange<Value* const*> children() const \ 813 { \ 814 Value* const* buffer = childrenArray(); \ 815 return {buffer, buffer + numChildren() }; \ 816 } \ 817 818 #define B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN \ 819 public: \ 820 unsigned numChildren() const { return childrenVector().size(); } \ 821 Value*& child(unsigned index) { return childrenVector()[index]; } \ 822 Value* child(unsigned index) const { return childrenVector()[index]; } \ 823 Value*& lastChild() { return childrenVector().last(); } \ 824 Value* lastChild() const { return childrenVector().last(); } \ 825 WTF::IteratorRange<Value**> children() \ 826 { \ 827 Vector<Value*, 3>& vec = childrenVector(); \ 828 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \ 829 } \ 830 WTF::IteratorRange<Value* const*> children() const \ 831 { \ 832 const Vector<Value*, 3>& vec = childrenVector(); \ 833 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \ 834 } \ 835 836 // Only use this for classes with no subclass that add new fields (as it uses sizeof(*this)) 837 // Also there is no point in applying this to classes with no children, as they don't have a children array to access. 838 #define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN \ 839 private: \ 840 Value** childrenArray() \ 841 { \ 842 return bitwise_cast<Value**>(bitwise_cast<char*>(this) + sizeof(*this)); \ 843 } \ 844 Value* const* childrenArray() const \ 845 { \ 846 return bitwise_cast<Value* const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \ 847 } 848 849 // Only use this for classes with no subclass that add new fields (as it uses sizeof(*this)) 850 #define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN \ 851 private: \ 852 Vector<Value*, 3>& childrenVector() \ 853 { \ 854 return *bitwise_cast<Vector<Value*, 3>*>(bitwise_cast<char*>(this) + sizeof(*this)); \ 855 } \ 856 const Vector<Value*, 3>& childrenVector() const \ 857 { \ 858 return *bitwise_cast<Vector<Value*, 3> const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \ 859 } \ 860 543 861 } } // namespace JSC::B3 544 862 -
trunk/Source/JavaScriptCore/b3/B3ValueInlines.h
r207039 r244309 28 28 #if ENABLE(B3_JIT) 29 29 30 #include "B3ArgumentRegValue.h" 31 #include "B3AtomicValue.h" 32 #include "B3CCallValue.h" 30 33 #include "B3CheckValue.h" 31 34 #include "B3Const32Value.h" … … 33 36 #include "B3ConstDoubleValue.h" 34 37 #include "B3ConstFloatValue.h" 38 #include "B3FenceValue.h" 39 #include "B3MemoryValue.h" 35 40 #include "B3PatchpointValue.h" 36 41 #include "B3PhiChildren.h" 37 42 #include "B3Procedure.h" 43 #include "B3SlotBaseValue.h" 44 #include "B3SwitchValue.h" 45 #include "B3UpsilonValue.h" 38 46 #include "B3Value.h" 47 #include "B3VariableValue.h" 48 #include "B3WasmAddressValue.h" 49 #include "B3WasmBoundsCheckValue.h" 39 50 #include <wtf/GraphNodeWorklist.h> 40 51 41 52 namespace JSC { namespace B3 { 53 54 #define DISPATCH_ON_KIND(MACRO) \ 55 switch (kind().opcode()) { \ 56 case FramePointer: \ 57 case Nop: \ 58 case Phi: \ 59 case Jump: \ 60 case Oops: \ 61 case EntrySwitch: \ 62 case Return: \ 63 case Identity: \ 64 case Opaque: \ 65 case Neg: \ 66 case Clz: \ 67 case Abs: \ 68 case Ceil: \ 69 case Floor: \ 70 case Sqrt: \ 71 case SExt8: \ 72 case SExt16: \ 73 case Trunc: \ 74 case SExt32: \ 75 case ZExt32: \ 76 case FloatToDouble: \ 77 case IToD: \ 78 case DoubleToFloat: \ 79 case IToF: \ 80 case BitwiseCast: \ 81 case Branch: \ 82 case Depend: \ 83 case Add: \ 84 case Sub: \ 85 case Mul: \ 86 case Div: \ 87 case UDiv: \ 88 case Mod: \ 89 case UMod: \ 90 case BitAnd: \ 91 case BitOr: \ 92 case BitXor: \ 93 case Shl: \ 94 case SShr: \ 95 case ZShr: \ 96 case RotR: \ 97 case RotL: \ 98 case Equal: \ 99 case NotEqual: \ 100 case LessThan: \ 101 case GreaterThan: \ 102 case LessEqual: \ 103 case GreaterEqual: \ 104 case Above: \ 105 case Below: \ 106 case AboveEqual: \ 107 case BelowEqual: \ 108 case EqualOrUnordered: \ 109 case Select: \ 110 return MACRO(Value); \ 111 case ArgumentReg: \ 112 return MACRO(ArgumentRegValue); \ 113 case Const32: \ 114 return MACRO(Const32Value); \ 115 case Const64: \ 116 return MACRO(Const64Value); \ 117 case ConstFloat: \ 118 return MACRO(ConstFloatValue); \ 119 case ConstDouble: \ 120 return MACRO(ConstDoubleValue); \ 121 case Fence: \ 122 return MACRO(FenceValue); \ 123 case SlotBase: \ 124 return MACRO(SlotBaseValue); \ 125 case Get: \ 126 case Set: \ 127 return MACRO(VariableValue); \ 128 case Load8Z: \ 129 case Load8S: \ 130 case Load16Z: \ 131 case Load16S: \ 132 case Load: \ 133 case Store8: \ 134 case Store16: \ 135 case Store: \ 136 return MACRO(MemoryValue); \ 137 case Switch: \ 138 return MACRO(SwitchValue); \ 139 case Upsilon: \ 140 return MACRO(UpsilonValue); \ 141 case WasmAddress: \ 142 return MACRO(WasmAddressValue); \ 143 case WasmBoundsCheck: \ 144 return MACRO(WasmBoundsCheckValue); \ 145 case AtomicXchgAdd: \ 146 case AtomicXchgAnd: \ 147 case AtomicXchgOr: \ 148 case AtomicXchgSub: \ 149 case AtomicXchgXor: \ 150 case AtomicXchg: \ 151 case AtomicWeakCAS: \ 152 case AtomicStrongCAS: \ 153 return MACRO(AtomicValue); \ 154 case CCall: \ 155 return MACRO(CCallValue); \ 156 case Check: \ 157 case CheckAdd: \ 158 case CheckSub: \ 159 case CheckMul: \ 160 return MACRO(CheckValue); \ 161 case Patchpoint: \ 162 return MACRO(PatchpointValue); \ 163 default: \ 164 RELEASE_ASSERT_NOT_REACHED(); \ 165 } 166 167 ALWAYS_INLINE size_t Value::adjacencyListOffset() const 168 { 169 #define VALUE_TYPE_SIZE(ValueType) sizeof(ValueType) 170 DISPATCH_ON_KIND(VALUE_TYPE_SIZE); 171 #undef VALUE_TYPE_SIZE 172 } 173 174 ALWAYS_INLINE Value* Value::cloneImpl() const 175 { 176 #define VALUE_TYPE_CLONE(ValueType) allocate<ValueType>(*static_cast<const ValueType*>(this)) 177 DISPATCH_ON_KIND(VALUE_TYPE_CLONE); 178 #undef VALUE_TYPE_CLONE 179 } 42 180 43 181 template<typename BottomProvider> -
trunk/Source/JavaScriptCore/b3/B3VariableValue.cpp
r206595 r244309 42 42 } 43 43 44 Value* VariableValue::cloneImpl() const45 {46 return new VariableValue(*this);47 }48 49 44 VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable, Value* value) 50 : Value(CheckedOpcode, kind, Void, origin, value)45 : Value(CheckedOpcode, kind, Void, One, origin, value) 51 46 , m_variable(variable) 52 47 { … … 55 50 56 51 VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable) 57 : Value(CheckedOpcode, kind, variable->type(), origin)52 : Value(CheckedOpcode, kind, variable->type(), Zero, origin) 58 53 , m_variable(variable) 59 54 { -
trunk/Source/JavaScriptCore/b3/B3VariableValue.h
r206595 r244309 42 42 Variable* variable() const { return m_variable; } 43 43 44 B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN 45 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 46 44 47 protected: 45 48 void dumpMeta(CommaPrinter&, PrintStream&) const override; 46 49 47 Value* cloneImpl() const override;48 49 50 private: 50 51 friend class Procedure; 52 friend class Value; 51 53 52 54 // Use this for Set. -
trunk/Source/JavaScriptCore/b3/B3WasmAddressValue.cpp
r207360 r244309 40 40 } 41 41 42 Value* WasmAddressValue::cloneImpl() const43 {44 return new WasmAddressValue(*this);45 }46 47 42 WasmAddressValue::WasmAddressValue(Origin origin, Value* value, GPRReg pinnedGPR) 48 : Value(CheckedOpcode, WasmAddress, Int64, origin, value)43 : Value(CheckedOpcode, WasmAddress, Int64, One, origin, value) 49 44 , m_pinnedGPR(pinnedGPR) 50 45 { -
trunk/Source/JavaScriptCore/b3/B3WasmAddressValue.h
r212970 r244309 41 41 GPRReg pinnedGPR() const { return m_pinnedGPR; } 42 42 43 B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1) 44 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 45 43 46 protected: 44 47 void dumpMeta(CommaPrinter&, PrintStream&) const override; 45 48 46 Value* cloneImpl() const override;47 48 49 private: 49 50 friend class Procedure; 51 friend class Value; 50 52 53 static Opcode opcodeFromConstructor(Origin, Value*, GPRReg) { return WasmAddress; } 51 54 WasmAddressValue(Origin, Value*, GPRReg); 52 55 -
trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.cpp
r230144 r244309 37 37 38 38 WasmBoundsCheckValue::WasmBoundsCheckValue(Origin origin, GPRReg pinnedSize, Value* ptr, unsigned offset) 39 : Value(CheckedOpcode, WasmBoundsCheck, origin, ptr)39 : Value(CheckedOpcode, WasmBoundsCheck, One, origin, ptr) 40 40 , m_offset(offset) 41 41 , m_boundsType(Type::Pinned) … … 45 45 46 46 WasmBoundsCheckValue::WasmBoundsCheckValue(Origin origin, Value* ptr, unsigned offset, size_t maximum) 47 : Value(CheckedOpcode, WasmBoundsCheck, origin, ptr)47 : Value(CheckedOpcode, WasmBoundsCheck, One, origin, ptr) 48 48 , m_offset(offset) 49 49 , m_boundsType(Type::Maximum) … … 54 54 #endif 55 55 m_bounds.maximum = maximum; 56 }57 58 Value* WasmBoundsCheckValue::cloneImpl() const59 {60 return new WasmBoundsCheckValue(*this);61 56 } 62 57 -
trunk/Source/JavaScriptCore/b3/B3WasmBoundsCheckValue.h
r230144 r244309 35 35 class WasmBoundsCheckValue : public Value { 36 36 public: 37 static bool accepts(Kind kind) 38 { 39 switch (kind.opcode()) { 40 case WasmBoundsCheck: 41 return true; 42 default: 43 return false; 44 } 45 } 37 static bool accepts(Kind kind) { return kind == WasmBoundsCheck; } 46 38 47 39 ~WasmBoundsCheckValue(); … … 61 53 Bounds bounds() const { return m_bounds; } 62 54 55 B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1) 56 B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN 57 63 58 protected: 64 59 void dumpMeta(CommaPrinter&, PrintStream&) const override; 65 60 66 Value* cloneImpl() const override;67 68 61 private: 69 62 friend class Procedure; 63 friend class Value; 70 64 65 static Opcode opcodeFromConstructor(Origin, GPRReg, Value*, unsigned) { return WasmBoundsCheck; } 71 66 JS_EXPORT_PRIVATE WasmBoundsCheckValue(Origin, GPRReg pinnedGPR, Value* ptr, unsigned offset); 67 68 static Opcode opcodeFromConstructor(Origin, Value*, unsigned, size_t) { return WasmBoundsCheck; } 72 69 JS_EXPORT_PRIVATE WasmBoundsCheckValue(Origin, Value* ptr, unsigned offset, size_t maximum); 73 70 -
trunk/Source/JavaScriptCore/b3/testb3.cpp
r243851 r244309 10961 10961 proc, Int32, Origin(), 10962 10962 root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments, B3CCallPtrTag))); 10963 call-> children().appendVector(args);10963 call->appendArgs(args); 10964 10964 10965 10965 root->appendNewControlValue(proc, Return, Origin(), call); … … 10987 10987 proc, Int64, Origin(), 10988 10988 root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments2, B3CCallPtrTag))); 10989 call-> children().appendVector(args);10989 call->appendArgs(args); 10990 10990 10991 10991 root->appendNewControlValue(proc, Return, Origin(), call); … … 11009 11009 proc, Int32, Origin(), 11010 11010 root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments3, B3CCallPtrTag))); 11011 call-> children().appendVector(args);11011 call->appendArgs(args); 11012 11012 11013 11013 root->appendNewControlValue(proc, Return, Origin(), call); … … 11109 11109 proc, Double, Origin(), 11110 11110 root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaDoubleArguments, B3CCallPtrTag))); 11111 call-> children().appendVector(args);11111 call->appendArgs(args); 11112 11112 11113 11113 root->appendNewControlValue(proc, Return, Origin(), call); … … 11133 11133 proc, Float, Origin(), 11134 11134 root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaFloatArguments, B3CCallPtrTag))); 11135 call-> children().appendVector(args);11135 call->appendArgs(args); 11136 11136 11137 11137 root->appendNewControlValue(proc, Return, Origin(), call); -
trunk/Source/JavaScriptCore/ftl/FTLOutput.h
r242123 r244309 381 381 { 382 382 B3::CCallValue* result = m_block->appendNew<B3::CCallValue>(m_proc, type, origin(), function); 383 result-> children().appendVector(vector);383 result->appendArgs(vector); 384 384 return result; 385 385 }
Note:
See TracChangeset
for help on using the changeset viewer.