Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (244308 => 244309)
--- trunk/Source/_javascript_Core/ChangeLog 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-04-15 23:53:23 UTC (rev 244309)
@@ -1,3 +1,139 @@
+2019-04-15 Robin Morisset <[email protected]>
+
+ B3::Value should have different kinds of adjacency lists
+ https://bugs.webkit.org/show_bug.cgi?id=196091
+
+ Reviewed by Filip Pizlo.
+
+ 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:
+ - Nothing (0 bytes)
+ - 1 Value* (8 bytes)
+ - 2 Value* (16 bytes)
+ - 3 Value* (24 bytes)
+ - A Vector<Value*, 3>
+ after the end of the Value object, depending on the kind of the Value.
+ So for example, when allocating an Add, we would allocate an extra 16 bytes into which to store 2 Values.
+ 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).
+
+ A few implementation points:
+ - 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)
+ - We must make sure to destroy the vector whenever we destroy a Value which is VarArgs
+ - 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
+ Thankfully, we have an extra byte of padding to use in the middle of B3::Value
+ - 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
+ - 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.
+ - 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.
+ This is done through the B3_SPECIALIZE_VALUE_FOR_... defined at the bottom of B3Value.h
+ - 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.
+ - 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
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * b3/B3ArgumentRegValue.cpp:
+ (JSC::B3::ArgumentRegValue::cloneImpl const): Deleted.
+ * b3/B3ArgumentRegValue.h:
+ * b3/B3AtomicValue.cpp:
+ (JSC::B3::AtomicValue::AtomicValue):
+ (JSC::B3::AtomicValue::cloneImpl const): Deleted.
+ * b3/B3AtomicValue.h:
+ * b3/B3BasicBlock.h:
+ * b3/B3BasicBlockInlines.h:
+ (JSC::B3::BasicBlock::appendNewNonTerminal): Deleted.
+ * b3/B3CCallValue.cpp:
+ (JSC::B3::CCallValue::appendArgs):
+ (JSC::B3::CCallValue::cloneImpl const): Deleted.
+ * b3/B3CCallValue.h:
+ * b3/B3CheckValue.cpp:
+ (JSC::B3::CheckValue::cloneImpl const): Deleted.
+ * b3/B3CheckValue.h:
+ * b3/B3Const32Value.cpp:
+ (JSC::B3::Const32Value::cloneImpl const): Deleted.
+ * b3/B3Const32Value.h:
+ * b3/B3Const64Value.cpp:
+ (JSC::B3::Const64Value::cloneImpl const): Deleted.
+ * b3/B3Const64Value.h:
+ * b3/B3ConstDoubleValue.cpp:
+ (JSC::B3::ConstDoubleValue::cloneImpl const): Deleted.
+ * b3/B3ConstDoubleValue.h:
+ * b3/B3ConstFloatValue.cpp:
+ (JSC::B3::ConstFloatValue::cloneImpl const): Deleted.
+ * b3/B3ConstFloatValue.h:
+ * b3/B3ConstPtrValue.h:
+ (JSC::B3::ConstPtrValue::opcodeFromConstructor):
+ * b3/B3FenceValue.cpp:
+ (JSC::B3::FenceValue::FenceValue):
+ (JSC::B3::FenceValue::cloneImpl const): Deleted.
+ * b3/B3FenceValue.h:
+ * b3/B3MemoryValue.cpp:
+ (JSC::B3::MemoryValue::MemoryValue):
+ (JSC::B3::MemoryValue::cloneImpl const): Deleted.
+ * b3/B3MemoryValue.h:
+ * b3/B3MoveConstants.cpp:
+ * b3/B3PatchpointValue.cpp:
+ (JSC::B3::PatchpointValue::cloneImpl const): Deleted.
+ * b3/B3PatchpointValue.h:
+ (JSC::B3::PatchpointValue::opcodeFromConstructor):
+ * b3/B3Procedure.cpp:
+ * b3/B3Procedure.h:
+ * b3/B3ProcedureInlines.h:
+ (JSC::B3::Procedure::add):
+ * b3/B3SlotBaseValue.cpp:
+ (JSC::B3::SlotBaseValue::cloneImpl const): Deleted.
+ * b3/B3SlotBaseValue.h:
+ * b3/B3StackmapSpecial.cpp:
+ (JSC::B3::StackmapSpecial::forEachArgImpl):
+ (JSC::B3::StackmapSpecial::isValidImpl):
+ * b3/B3StackmapValue.cpp:
+ (JSC::B3::StackmapValue::append):
+ (JSC::B3::StackmapValue::StackmapValue):
+ * b3/B3StackmapValue.h:
+ * b3/B3SwitchValue.cpp:
+ (JSC::B3::SwitchValue::SwitchValue):
+ (JSC::B3::SwitchValue::cloneImpl const): Deleted.
+ * b3/B3SwitchValue.h:
+ (JSC::B3::SwitchValue::opcodeFromConstructor):
+ * b3/B3UpsilonValue.cpp:
+ (JSC::B3::UpsilonValue::cloneImpl const): Deleted.
+ * b3/B3UpsilonValue.h:
+ * b3/B3Value.cpp:
+ (JSC::B3::DeepValueDump::dump const):
+ (JSC::B3::Value::~Value):
+ (JSC::B3::Value::replaceWithIdentity):
+ (JSC::B3::Value::replaceWithNopIgnoringType):
+ (JSC::B3::Value::replaceWithPhi):
+ (JSC::B3::Value::replaceWithJump):
+ (JSC::B3::Value::replaceWithOops):
+ (JSC::B3::Value::replaceWith):
+ (JSC::B3::Value::invertedCompare const):
+ (JSC::B3::Value::returnsBool const):
+ (JSC::B3::Value::cloneImpl const): Deleted.
+ * b3/B3Value.h:
+ (JSC::B3::DeepValueDump::dump const): Deleted.
+ * b3/B3ValueInlines.h:
+ (JSC::B3::Value::adjacencyListOffset const):
+ (JSC::B3::Value::cloneImpl const):
+ * b3/B3VariableValue.cpp:
+ (JSC::B3::VariableValue::VariableValue):
+ (JSC::B3::VariableValue::cloneImpl const): Deleted.
+ * b3/B3VariableValue.h:
+ * b3/B3WasmAddressValue.cpp:
+ (JSC::B3::WasmAddressValue::WasmAddressValue):
+ (JSC::B3::WasmAddressValue::cloneImpl const): Deleted.
+ * b3/B3WasmAddressValue.h:
+ * b3/B3WasmBoundsCheckValue.cpp:
+ (JSC::B3::WasmBoundsCheckValue::WasmBoundsCheckValue):
+ (JSC::B3::WasmBoundsCheckValue::cloneImpl const): Deleted.
+ * b3/B3WasmBoundsCheckValue.h:
+ (JSC::B3::WasmBoundsCheckValue::accepts):
+ (JSC::B3::WasmBoundsCheckValue::opcodeFromConstructor):
+ * b3/testb3.cpp:
+ (JSC::B3::testCallFunctionWithHellaArguments):
+ (JSC::B3::testCallFunctionWithHellaArguments2):
+ (JSC::B3::testCallFunctionWithHellaArguments3):
+ (JSC::B3::testCallFunctionWithHellaDoubleArguments):
+ (JSC::B3::testCallFunctionWithHellaFloatArguments):
+ * ftl/FTLOutput.h:
+ (JSC::FTL::Output::call):
+
2019-04-15 Tadeu Zagallo <[email protected]>
Bytecode cache should not encode the SourceProvider for UnlinkedFunctionExecutable's classSource
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (244308 => 244309)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-04-15 23:53:23 UTC (rev 244309)
@@ -669,7 +669,6 @@
0FEC85401BDACDAC0080FF74 /* B3UseCounts.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84F61BDACDAC0080FF74 /* B3UseCounts.h */; };
0FEC85421BDACDAC0080FF74 /* B3Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84F81BDACDAC0080FF74 /* B3Validate.h */; };
0FEC85441BDACDAC0080FF74 /* B3Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FA1BDACDAC0080FF74 /* B3Value.h */; };
- 0FEC85451BDACDAC0080FF74 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; };
0FEC85471BDACDAC0080FF74 /* B3ValueRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FD1BDACDAC0080FF74 /* B3ValueRep.h */; };
0FEC856E1BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC85491BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h */; };
0FEC85701BDACDC70080FF74 /* AirArg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC854B1BDACDC70080FF74 /* AirArg.h */; };
@@ -857,6 +856,8 @@
2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 425BA1337E4344E1B269A671 /* SourceOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
3395C70722555F6D00BDBFAD /* B3EliminateDeadCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3395C70522555F6D00BDBFAD /* B3EliminateDeadCode.h */; };
+ 33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; };
+ 33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; };
371D842D17C98B6E00ECF994 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 371D842C17C98B6E00ECF994 /* libz.dylib */; };
37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C738D11EDB5672003F2B0B /* ParseInt.h */; settings = {ATTRIBUTES = (Private, ); }; };
412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -918,7 +919,6 @@
5333BBDB2110F7D2007618EC /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
5333BBDC2110F7D9007618EC /* DFGSpeculativeJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EC9DC21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp */; };
5333BBDD2110F7E1007618EC /* DFGSpeculativeJIT64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */; };
- 5333BBDE2110FA3E007618EC /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; };
5341FC721DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 5341FC711DAC343C00E7E4D7 /* B3WasmBoundsCheckValue.h */; };
534638711E70CF3D00F12AC1 /* JSRunLoopTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 534638701E70CF3D00F12AC1 /* JSRunLoopTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
534638751E70DDEC00F12AC1 /* PromiseDeferredTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 534638741E70DDEC00F12AC1 /* PromiseDeferredTimer.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -8506,6 +8506,7 @@
0F2C63BC1E63440C00C13839 /* AirBlockInsertionSet.h in Headers */,
0FB3878E1BFBC44D00E3AB1E /* AirBlockWorklist.h in Headers */,
0F79C7CA1E74C93B00EB34D1 /* AirBreakCriticalEdges.h in Headers */,
+ 33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */,
0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */,
0FEC85741BDACDC70080FF74 /* AirCCallSpecial.h in Headers */,
0FF4B4C71E8893C500DBBE86 /* AirCFG.h in Headers */,
@@ -8698,7 +8699,6 @@
0FEC85401BDACDAC0080FF74 /* B3UseCounts.h in Headers */,
0FEC85421BDACDAC0080FF74 /* B3Validate.h in Headers */,
0FEC85441BDACDAC0080FF74 /* B3Value.h in Headers */,
- 0FEC85451BDACDAC0080FF74 /* B3ValueInlines.h in Headers */,
0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */,
0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */,
0FEC85471BDACDAC0080FF74 /* B3ValueRep.h in Headers */,
@@ -10703,7 +10703,6 @@
5333BBDC2110F7D9007618EC /* DFGSpeculativeJIT.cpp in Sources */,
5333BBDB2110F7D2007618EC /* DFGSpeculativeJIT32_64.cpp in Sources */,
5333BBDD2110F7E1007618EC /* DFGSpeculativeJIT64.cpp in Sources */,
- 5333BBDE2110FA3E007618EC /* FTLLowerDFGToB3.cpp in Sources */,
536B319E1F735F160037FC33 /* LowLevelInterpreter.cpp in Sources */,
0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
@@ -10837,6 +10836,7 @@
536B310C1F71C5990037FC33 /* UnifiedSource119.cpp in Sources */,
536B31261F71C5990037FC33 /* UnifiedSource120.cpp in Sources */,
536B312D1F71C5990037FC33 /* UnifiedSource121.cpp in Sources */,
+ 33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */,
536B31251F71C5990037FC33 /* UnifiedSource122.cpp in Sources */,
536B311E1F71C5990037FC33 /* UnifiedSource123.cpp in Sources */,
536B31141F71C5990037FC33 /* UnifiedSource124.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -39,11 +39,6 @@
out.print(comma, m_reg);
}
-Value* ArgumentRegValue::cloneImpl() const
-{
- return new ArgumentRegValue(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ArgumentRegValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -40,16 +40,19 @@
Reg argumentReg() const { return m_reg; }
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+
+ static Opcode opcodeFromConstructor(Origin, Reg) { return ArgumentReg; }
ArgumentRegValue(Origin origin, Reg reg)
- : Value(CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, origin)
+ : Value(CheckedOpcode, ArgumentReg, reg.isGPR() ? pointerType() : Double, Zero, origin)
, m_reg(reg)
{
ASSERT(reg.isSet());
Modified: trunk/Source/_javascript_Core/b3/B3AtomicValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3AtomicValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3AtomicValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -41,13 +41,8 @@
MemoryValue::dumpMeta(comma, out);
}
-Value* AtomicValue::cloneImpl() const
-{
- return new AtomicValue(*this);
-}
-
AtomicValue::AtomicValue(AtomicValue::AtomicValueRMW, Kind kind, Origin origin, Width width, Value* operand, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
- : MemoryValue(CheckedOpcode, kind, operand->type(), origin, offset, range, fenceRange, operand, pointer)
+ : MemoryValue(CheckedOpcode, kind, operand->type(), Two, origin, offset, range, fenceRange, operand, pointer)
, m_width(width)
{
ASSERT(bestType(GP, accessWidth()) == accessType());
@@ -66,7 +61,7 @@
}
AtomicValue::AtomicValue(AtomicValue::AtomicValueCAS, Kind kind, Origin origin, Width width, Value* expectedValue, Value* newValue, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
- : MemoryValue(CheckedOpcode, kind, kind.opcode() == AtomicWeakCAS ? Int32 : expectedValue->type(), origin, offset, range, fenceRange, expectedValue, newValue, pointer)
+ : MemoryValue(CheckedOpcode, kind, kind.opcode() == AtomicWeakCAS ? Int32 : expectedValue->type(), Three, origin, offset, range, fenceRange, expectedValue, newValue, pointer)
, m_width(width)
{
ASSERT(bestType(GP, accessWidth()) == accessType());
Modified: trunk/Source/_javascript_Core/b3/B3AtomicValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3AtomicValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3AtomicValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -44,14 +44,15 @@
Type accessType() const { return child(0)->type(); }
Width accessWidth() const { return m_width; }
+
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
-
- Value* cloneImpl() const override;
-
+
private:
friend class Procedure;
+ friend class Value;
enum AtomicValueRMW { AtomicValueRMWTag };
enum AtomicValueCAS { AtomicValueCASTag };
Modified: trunk/Source/_javascript_Core/b3/B3BasicBlock.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3BasicBlock.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3BasicBlock.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -84,8 +84,6 @@
template<typename ValueType, typename... Arguments>
ValueType* appendNew(Procedure&, Arguments...);
- template<typename ValueType, typename... Arguments>
- ValueType* appendNewNonTerminal(Procedure&, Arguments...);
JS_EXPORT_PRIVATE Value* appendIntConstant(Procedure&, Origin, Type, int64_t value);
Value* appendIntConstant(Procedure&, Value* likeValue, int64_t value);
Modified: trunk/Source/_javascript_Core/b3/B3BasicBlockInlines.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3BasicBlockInlines.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3BasicBlockInlines.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -42,14 +42,6 @@
}
template<typename ValueType, typename... Arguments>
-ValueType* BasicBlock::appendNewNonTerminal(Procedure& procedure, Arguments... arguments)
-{
- ValueType* result = procedure.add<ValueType>(arguments...);
- appendNonTerminal(result);
- return result;
-}
-
-template<typename ValueType, typename... Arguments>
ValueType* BasicBlock::replaceLastWithNew(Procedure& procedure, Arguments... arguments)
{
ValueType* result = procedure.add<ValueType>(arguments...);
Modified: trunk/Source/_javascript_Core/b3/B3CCallValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3CCallValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3CCallValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -34,9 +34,9 @@
{
}
-Value* CCallValue::cloneImpl() const
+void CCallValue::appendArgs(const Vector<Value*>& args)
{
- return new CCallValue(*this);
+ childrenVector().appendVector(args);
}
} } // namespace JSC::B3
Modified: trunk/Source/_javascript_Core/b3/B3CCallValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3CCallValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3CCallValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -38,17 +38,23 @@
~CCallValue();
+ void appendArgs(const Vector<Value*>&);
+
Effects effects;
-protected:
- Value* cloneImpl() const override;
-
+ B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
+
private:
friend class Procedure;
+ friend class Value;
template<typename... Arguments>
+ static Opcode opcodeFromConstructor(Arguments...) { return CCall; }
+
+ template<typename... Arguments>
CCallValue(Type type, Origin origin, Arguments... arguments)
- : Value(CheckedOpcode, CCall, type, origin, arguments...)
+ : Value(CheckedOpcode, CCall, type, VarArgs, origin, static_cast<Value*>(arguments)...)
, effects(Effects::forCall())
{
RELEASE_ASSERT(numChildren() >= 1);
@@ -56,7 +62,7 @@
template<typename... Arguments>
CCallValue(Type type, Origin origin, const Effects& effects, Arguments... arguments)
- : Value(CheckedOpcode, CCall, type, origin, arguments...)
+ : Value(CheckedOpcode, CCall, type, VarArgs, origin, static_cast<Value*>(arguments)...)
, effects(effects)
{
RELEASE_ASSERT(numChildren() >= 1);
Modified: trunk/Source/_javascript_Core/b3/B3CheckValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3CheckValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3CheckValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -40,11 +40,6 @@
m_kind = CheckAdd;
}
-Value* CheckValue::cloneImpl() const
-{
- return new CheckValue(*this);
-}
-
// Use this form for CheckAdd, CheckSub, and CheckMul.
CheckValue::CheckValue(Kind kind, Origin origin, Value* left, Value* right)
: StackmapValue(CheckedOpcode, kind, left->type(), origin)
Modified: trunk/Source/_javascript_Core/b3/B3CheckValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3CheckValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3CheckValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -50,11 +50,11 @@
void convertToAdd();
-protected:
- Value* cloneImpl() const override;
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
private:
friend class Procedure;
+ friend class Value;
// Use this form for CheckAdd, CheckSub, and CheckMul.
JS_EXPORT_PRIVATE CheckValue(Kind, Origin, Value* left, Value* right);
Modified: trunk/Source/_javascript_Core/b3/B3Const32Value.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Const32Value.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Const32Value.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -303,11 +303,6 @@
out.print(comma, m_value);
}
-Value* Const32Value::cloneImpl() const
-{
- return new Const32Value(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3Const32Value.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Const32Value.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Const32Value.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -75,20 +75,24 @@
TriState aboveEqualConstant(const Value* other) const override;
TriState belowEqualConstant(const Value* other) const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
+ // Protected because of ConstPtrValue
+ static Opcode opcodeFromConstructor(Origin = Origin(), int32_t = 0) { return Const32; }
- friend class Procedure;
-
Const32Value(Origin origin, int32_t value)
- : Value(CheckedOpcode, Const32, Int32, origin)
+ : Value(CheckedOpcode, Const32, Int32, Zero, origin)
, m_value(value)
{
}
private:
+ friend class Procedure;
+ friend class Value;
+
int32_t m_value;
};
Modified: trunk/Source/_javascript_Core/b3/B3Const64Value.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Const64Value.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Const64Value.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -303,11 +303,6 @@
out.print(comma, m_value);
}
-Value* Const64Value::cloneImpl() const
-{
- return new Const64Value(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3Const64Value.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Const64Value.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Const64Value.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -75,20 +75,24 @@
TriState aboveEqualConstant(const Value* other) const override;
TriState belowEqualConstant(const Value* other) const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
+ // Protected because of ConstPtrValue
+ static Opcode opcodeFromConstructor(Origin = Origin(), int64_t = 0) { return Const64; }
- friend class Procedure;
-
Const64Value(Origin origin, int64_t value)
- : Value(CheckedOpcode, Const64, Int64, origin)
+ : Value(CheckedOpcode, Const64, Int64, Zero, origin)
, m_value(value)
{
}
-
+
private:
+ friend class Procedure;
+ friend class Value;
+
int64_t m_value;
};
Modified: trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -197,11 +197,6 @@
out.printf("%le", m_value);
}
-Value* ConstDoubleValue::cloneImpl() const
-{
- return new ConstDoubleValue(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ConstDoubleValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -64,16 +64,18 @@
TriState greaterEqualConstant(const Value* other) const override;
TriState equalOrUnorderedConstant(const Value* other) const override;
-protected:
- void dumpMeta(CommaPrinter&, PrintStream&) const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ void dumpMeta(CommaPrinter&, PrintStream&) const override;
+
+ static Opcode opcodeFromConstructor(Origin, double) { return ConstDouble; }
+
ConstDoubleValue(Origin origin, double value)
- : Value(CheckedOpcode, ConstDouble, Double, origin)
+ : Value(CheckedOpcode, ConstDouble, Double, Zero, origin)
, m_value(value)
{
}
Modified: trunk/Source/_javascript_Core/b3/B3ConstFloatValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ConstFloatValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ConstFloatValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -189,11 +189,6 @@
out.printf("%le", m_value);
}
-Value* ConstFloatValue::cloneImpl() const
-{
- return new ConstFloatValue(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3ConstFloatValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ConstFloatValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ConstFloatValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -63,16 +63,18 @@
TriState greaterEqualConstant(const Value* other) const override;
TriState equalOrUnorderedConstant(const Value* other) const override;
-protected:
- void dumpMeta(CommaPrinter&, PrintStream&) const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ void dumpMeta(CommaPrinter&, PrintStream&) const override;
+
+ static Opcode opcodeFromConstructor(Origin, float) { return ConstFloat; }
+
ConstFloatValue(Origin origin, float value)
- : Value(CheckedOpcode, ConstFloat, Float, origin)
+ : Value(CheckedOpcode, ConstFloat, Float, Zero, origin)
, m_value(value)
{
}
Modified: trunk/Source/_javascript_Core/b3/B3ConstPtrValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ConstPtrValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ConstPtrValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -51,13 +51,18 @@
private:
friend class Procedure;
+ friend class Value;
template<typename T>
+ static Opcode opcodeFromConstructor(Origin, T*) { return ConstPtrValueBase::opcodeFromConstructor(); }
+ template<typename T>
ConstPtrValue(Origin origin, T* pointer)
: ConstPtrValueBase(origin, bitwise_cast<intptr_t>(pointer))
{
}
template<typename T>
+ static Opcode opcodeFromConstructor(Origin, T) { return ConstPtrValueBase::opcodeFromConstructor(); }
+ template<typename T>
ConstPtrValue(Origin origin, T pointer)
: ConstPtrValueBase(origin, static_cast<intptr_t>(pointer))
{
Modified: trunk/Source/_javascript_Core/b3/B3FenceValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3FenceValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3FenceValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -34,13 +34,8 @@
{
}
-Value* FenceValue::cloneImpl() const
-{
- return new FenceValue(*this);
-}
-
FenceValue::FenceValue(Origin origin, HeapRange read, HeapRange write)
- : Value(CheckedOpcode, Fence, Void, origin)
+ : Value(CheckedOpcode, Fence, Void, Zero, origin)
, read(read)
, write(write)
{
Modified: trunk/Source/_javascript_Core/b3/B3FenceValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3FenceValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3FenceValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -72,14 +72,14 @@
HeapRange read { HeapRange::top() };
HeapRange write { HeapRange::top() };
-protected:
- Value* cloneImpl() const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Origin, HeapRange = HeapRange(), HeapRange = HeapRange()) { return Fence; }
FenceValue(Origin origin, HeapRange read, HeapRange write);
-
FenceValue(Origin origin);
};
Modified: trunk/Source/_javascript_Core/b3/B3MemoryValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3MemoryValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3MemoryValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -73,15 +73,10 @@
out.print(comma, "fenceRange = ", fenceRange());
}
-Value* MemoryValue::cloneImpl() const
-{
- return new MemoryValue(*this);
-}
-
// Use this form for Load (but not Load8Z, Load8S, or any of the Loads that have a suffix that
// describes the returned type).
MemoryValue::MemoryValue(MemoryValue::MemoryValueLoad, Kind kind, Type type, Origin origin, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
- : Value(CheckedOpcode, kind, type, origin, pointer)
+ : Value(CheckedOpcode, kind, type, One, origin, pointer)
, m_offset(offset)
, m_range(range)
, m_fenceRange(fenceRange)
@@ -126,7 +121,7 @@
// Use this form for stores.
MemoryValue::MemoryValue(MemoryValue::MemoryValueStore, Kind kind, Origin origin, Value* value, Value* pointer, MemoryValue::OffsetType offset, HeapRange range, HeapRange fenceRange)
- : Value(CheckedOpcode, kind, Void, origin, value, pointer)
+ : Value(CheckedOpcode, kind, Void, Two, origin, value, pointer)
, m_offset(offset)
, m_range(range)
, m_fenceRange(fenceRange)
Modified: trunk/Source/_javascript_Core/b3/B3MemoryValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3MemoryValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3MemoryValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -84,14 +84,14 @@
bool isCanonicalWidth() const { return B3::isCanonicalWidth(accessWidth()); }
+ B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
-
- Value* cloneImpl() const override;
-
+
template<typename Int, typename = IsLegalOffset<Int>, typename... Arguments>
- MemoryValue(CheckedOpcodeTag, Kind kind, Type type, Origin origin, Int offset, HeapRange range, HeapRange fenceRange, Arguments... arguments)
- : Value(CheckedOpcode, kind, type, origin, arguments...)
+ MemoryValue(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Int offset, HeapRange range, HeapRange fenceRange, Arguments... arguments)
+ : Value(CheckedOpcode, kind, type, numChildren, origin, static_cast<Value*>(arguments)...)
, m_offset(offset)
, m_range(range)
, m_fenceRange(fenceRange)
@@ -100,6 +100,7 @@
private:
friend class Procedure;
+ friend class Value;
bool isLegalOffsetImpl(int32_t offset) const;
bool isLegalOffsetImpl(int64_t offset) const;
Modified: trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3MoveConstants.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -58,7 +58,7 @@
[&] (const ValueKey& key) -> bool {
return key.opcode() == ConstFloat || key.opcode() == ConstDouble;
});
-
+
lowerFPConstants();
hoistConstants(
Modified: trunk/Source/_javascript_Core/b3/B3PatchpointValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3PatchpointValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3PatchpointValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -44,11 +44,6 @@
out.print(comma, "numFPScratchRegisters = ", numFPScratchRegisters);
}
-Value* PatchpointValue::cloneImpl() const
-{
- return new PatchpointValue(*this);
-}
-
PatchpointValue::PatchpointValue(Type type, Origin origin)
: Base(CheckedOpcode, Patchpoint, type, origin)
, effects(Effects::forCall())
Modified: trunk/Source/_javascript_Core/b3/B3PatchpointValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3PatchpointValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3PatchpointValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -61,14 +61,16 @@
uint8_t numGPScratchRegisters { 0 };
uint8_t numFPScratchRegisters { 0 };
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Type, Origin) { return Patchpoint; }
JS_EXPORT_PRIVATE PatchpointValue(Type, Origin);
};
Modified: trunk/Source/_javascript_Core/b3/B3Procedure.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Procedure.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -93,7 +93,6 @@
return m_values.add(WTFMove(clone));
}
-
Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
{
switch (type) {
Modified: trunk/Source/_javascript_Core/b3/B3Procedure.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Procedure.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -292,7 +292,7 @@
bool m_needsUsedRegisters { true };
bool m_hasQuirks { false };
};
-
+
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3ProcedureInlines.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ProcedureInlines.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ProcedureInlines.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -29,13 +29,14 @@
#include "B3BasicBlock.h"
#include "B3Procedure.h"
+#include "B3Value.h"
namespace JSC { namespace B3 {
-
+
template<typename ValueType, typename... Arguments>
ValueType* Procedure::add(Arguments... arguments)
{
- return static_cast<ValueType*>(addValueImpl(new ValueType(arguments...)));
+ return static_cast<ValueType*>(addValueImpl(Value::allocate<ValueType>(arguments...)));
}
} } // namespace JSC::B3
Modified: trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -41,11 +41,6 @@
out.print(comma, pointerDump(m_slot));
}
-Value* SlotBaseValue::cloneImpl() const
-{
- return new SlotBaseValue(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -41,16 +41,17 @@
StackSlot* slot() const { return m_slot; }
-protected:
- void dumpMeta(CommaPrinter&, PrintStream&) const override;
+ B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ void dumpMeta(CommaPrinter&, PrintStream&) const override;
+
+ static Opcode opcodeFromConstructor(Origin, StackSlot*) { return SlotBase; }
SlotBaseValue(Origin origin, StackSlot* slot)
- : Value(CheckedOpcode, SlotBase, pointerType(), origin)
+ : Value(CheckedOpcode, SlotBase, pointerType(), Zero, origin)
, m_slot(slot)
{
}
Modified: trunk/Source/_javascript_Core/b3/B3StackmapSpecial.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3StackmapSpecial.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3StackmapSpecial.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -83,11 +83,11 @@
// Check that insane things have not happened.
ASSERT(inst.args.size() >= numIgnoredAirArgs);
- ASSERT(value->children().size() >= numIgnoredB3Args);
- ASSERT(inst.args.size() - numIgnoredAirArgs >= value->children().size() - numIgnoredB3Args);
+ ASSERT(value->numChildren() >= numIgnoredB3Args);
+ ASSERT(inst.args.size() - numIgnoredAirArgs >= value->numChildren() - numIgnoredB3Args);
ASSERT(inst.args[0].kind() == Arg::Kind::Special);
- for (unsigned i = 0; i < value->children().size() - numIgnoredB3Args; ++i) {
+ for (unsigned i = 0; i < value->numChildren() - numIgnoredB3Args; ++i) {
Arg& arg = inst.args[i + numIgnoredAirArgs];
ConstrainedValue child = value->constrainedChild(i + numIgnoredB3Args);
@@ -160,16 +160,16 @@
// Check that insane things have not happened.
ASSERT(inst.args.size() >= numIgnoredAirArgs);
- ASSERT(value->children().size() >= numIgnoredB3Args);
+ ASSERT(value->numChildren() >= numIgnoredB3Args);
// For the Inst to be valid, it needs to have the right number of arguments.
- if (inst.args.size() - numIgnoredAirArgs < value->children().size() - numIgnoredB3Args)
+ if (inst.args.size() - numIgnoredAirArgs < value->numChildren() - numIgnoredB3Args)
return false;
// Regardless of constraints, stackmaps have some basic requirements for their arguments. For
// example, you can't have a non-FP-offset address. This verifies those conditions as well as the
// argument types.
- for (unsigned i = 0; i < value->children().size() - numIgnoredB3Args; ++i) {
+ for (unsigned i = 0; i < value->numChildren() - numIgnoredB3Args; ++i) {
Value* child = value->child(i + numIgnoredB3Args);
Arg& arg = inst.args[i + numIgnoredAirArgs];
@@ -178,7 +178,7 @@
}
// The number of constraints has to be no greater than the number of B3 children.
- ASSERT(value->m_reps.size() <= value->children().size());
+ ASSERT(value->m_reps.size() <= value->numChildren());
// Verify any explicitly supplied constraints.
for (unsigned i = numIgnoredB3Args; i < value->m_reps.size(); ++i) {
Modified: trunk/Source/_javascript_Core/b3/B3StackmapValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3StackmapValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3StackmapValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -37,7 +37,7 @@
void StackmapValue::append(Value* value, const ValueRep& rep)
{
if (rep == ValueRep::ColdAny) {
- children().append(value);
+ childrenVector().append(value);
return;
}
@@ -44,7 +44,7 @@
while (m_reps.size() < numChildren())
m_reps.append(ValueRep::ColdAny);
- children().append(value);
+ childrenVector().append(value);
m_reps.append(rep);
}
@@ -89,7 +89,7 @@
}
StackmapValue::StackmapValue(CheckedOpcodeTag, Kind kind, Type type, Origin origin)
- : Value(CheckedOpcode, kind, type, origin)
+ : Value(CheckedOpcode, kind, type, VarArgs, origin)
{
ASSERT(accepts(kind));
}
Modified: trunk/Source/_javascript_Core/b3/B3StackmapValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3StackmapValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3StackmapValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -60,8 +60,7 @@
~StackmapValue();
- // Use this to add children. Note that you could also add children by doing
- // children().append(). That will work fine, but it's not recommended.
+ // Use this to add children.
void append(const ConstrainedValue& value)
{
append(value.value(), value.rep());
@@ -285,6 +284,8 @@
return ConstrainedValueCollection(*this);
}
+ B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN
+
protected:
void dumpChildren(CommaPrinter&, PrintStream&) const override;
void dumpMeta(CommaPrinter&, PrintStream&) const override;
Modified: trunk/Source/_javascript_Core/b3/B3SwitchValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3SwitchValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3SwitchValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -106,13 +106,8 @@
out.print(comma, "cases = [", listDump(m_values), "]");
}
-Value* SwitchValue::cloneImpl() const
-{
- return new SwitchValue(*this);
-}
-
SwitchValue::SwitchValue(Origin origin, Value* child)
- : Value(CheckedOpcode, Switch, Void, origin, child)
+ : Value(CheckedOpcode, Switch, Void, One, origin, child)
{
}
Modified: trunk/Source/_javascript_Core/b3/B3SwitchValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3SwitchValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3SwitchValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -64,14 +64,17 @@
void dumpSuccessors(const BasicBlock*, PrintStream&) const override;
+ B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1)
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Origin, Value*) { return Switch; }
JS_EXPORT_PRIVATE SwitchValue(Origin, Value* child);
Vector<int64_t> m_values;
Modified: trunk/Source/_javascript_Core/b3/B3UpsilonValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3UpsilonValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3UpsilonValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -45,11 +45,6 @@
}
}
-Value* UpsilonValue::cloneImpl() const
-{
- return new UpsilonValue(*this);
-}
-
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3UpsilonValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3UpsilonValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3UpsilonValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -45,19 +45,22 @@
m_phi = phi;
}
+ B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1)
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Origin, Value*, Value* = nullptr) { return Upsilon; }
// Note that passing the Phi during construction is optional. A valid pattern is to first create
// the Upsilons without the Phi, then create the Phi, then go back and tell the Upsilons about
// the Phi. This allows you to emit code in its natural order.
UpsilonValue(Origin origin, Value* value, Value* phi = nullptr)
- : Value(CheckedOpcode, Upsilon, Void, origin, value)
+ : Value(CheckedOpcode, Upsilon, Void, One, origin, value)
, m_phi(phi)
{
if (phi)
Modified: trunk/Source/_javascript_Core/b3/B3Value.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Value.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Value.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -47,13 +47,23 @@
#include <wtf/CommaPrinter.h>
#include <wtf/ListDump.h>
#include <wtf/StringPrintStream.h>
+#include <wtf/Vector.h>
namespace JSC { namespace B3 {
const char* const Value::dumpPrefix = "@";
+void DeepValueDump::dump(PrintStream& out) const
+{
+ if (m_value)
+ m_value->deepDump(m_proc, out);
+ else
+ out.print("<null>");
+}
Value::~Value()
{
+ if (m_numChildren == VarArgs)
+ bitwise_cast<Vector<Value*, 3> *>(childrenAlloc())->Vector<Value*, 3>::~Vector();
}
void Value::replaceWithIdentity(Value* value)
@@ -62,27 +72,13 @@
// a plain Identity Value. We first collect all of the information we need, then we destruct the
// previous value in place, and then we construct the Identity Value in place.
- ASSERT(m_type == value->m_type);
+ RELEASE_ASSERT(m_type == value->m_type);
ASSERT(value != this);
- if (m_type == Void) {
+ if (m_type == Void)
replaceWithNopIgnoringType();
- return;
- }
-
- unsigned index = m_index;
- Type type = m_type;
- Origin origin = m_origin;
- BasicBlock* owner = this->owner;
-
- RELEASE_ASSERT(type == value->type());
-
- this->~Value();
-
- new (this) Value(Identity, type, origin, value);
-
- this->owner = owner;
- this->m_index = index;
+ else
+ replaceWith(Identity, m_type, this->owner, value);
}
void Value::replaceWithBottom(InsertionSet& insertionSet, size_t index)
@@ -98,16 +94,7 @@
void Value::replaceWithNopIgnoringType()
{
- unsigned index = m_index;
- Origin origin = m_origin;
- BasicBlock* owner = this->owner;
-
- this->~Value();
-
- new (this) Value(Nop, Void, origin);
-
- this->owner = owner;
- this->m_index = index;
+ replaceWith(Nop, Void, this->owner);
}
void Value::replaceWithPhi()
@@ -116,34 +103,14 @@
replaceWithNop();
return;
}
-
- unsigned index = m_index;
- Origin origin = m_origin;
- BasicBlock* owner = this->owner;
- Type type = m_type;
- this->~Value();
-
- new (this) Value(Phi, type, origin);
-
- this->owner = owner;
- this->m_index = index;
+ replaceWith(Phi, m_type, this->owner);
}
void Value::replaceWithJump(BasicBlock* owner, FrequentedBlock target)
{
RELEASE_ASSERT(owner->last() == this);
-
- unsigned index = m_index;
- Origin origin = m_origin;
-
- this->~Value();
-
- new (this) Value(Jump, Void, origin);
-
- this->owner = owner;
- this->m_index = index;
-
+ replaceWith(Jump, Void, this->owner);
owner->setSuccessors(target);
}
@@ -150,17 +117,7 @@
void Value::replaceWithOops(BasicBlock* owner)
{
RELEASE_ASSERT(owner->last() == this);
-
- unsigned index = m_index;
- Origin origin = m_origin;
-
- this->~Value();
-
- new (this) Value(Oops, Void, origin);
-
- this->owner = owner;
- this->m_index = index;
-
+ replaceWith(Oops, Void, this->owner);
owner->clearSuccessors();
}
@@ -174,6 +131,30 @@
replaceWithOops(owner);
}
+void Value::replaceWith(Kind kind, Type type, BasicBlock* owner)
+{
+ unsigned index = m_index;
+
+ this->~Value();
+
+ new (this) Value(kind, type, m_origin);
+
+ this->m_index = index;
+ this->owner = owner;
+}
+
+void Value::replaceWith(Kind kind, Type type, BasicBlock* owner, Value* value)
+{
+ unsigned index = m_index;
+
+ this->~Value();
+
+ new (this) Value(kind, type, m_origin, value);
+
+ this->m_index = index;
+ this->owner = owner;
+}
+
void Value::dump(PrintStream& out) const
{
bool isConstant = false;
@@ -205,11 +186,6 @@
out.print(")");
}
-Value* Value::cloneImpl() const
-{
- return new Value(*this);
-}
-
void Value::dumpChildren(CommaPrinter& comma, PrintStream& out) const
{
for (Value* child : children())
@@ -458,11 +434,11 @@
Value* Value::invertedCompare(Procedure& proc) const
{
- if (!numChildren())
+ if (numChildren() != 2)
return nullptr;
if (Optional<Opcode> invertedOpcode = B3::invertedCompare(opcode(), child(0)->type())) {
ASSERT(!kind().hasExtraBits());
- return proc.add<Value>(*invertedOpcode, type(), origin(), children());
+ return proc.add<Value>(*invertedOpcode, type(), origin(), child(0), child(1));
}
return nullptr;
}
@@ -496,6 +472,7 @@
{
if (type() != Int32)
return false;
+
switch (opcode()) {
case Const32:
return asInt32() == 0 || asInt32() == 1;
Modified: trunk/Source/_javascript_Core/b3/B3Value.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3Value.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3Value.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -38,7 +38,7 @@
#include "B3Width.h"
#include <wtf/CommaPrinter.h>
#include <wtf/FastMalloc.h>
-#include <wtf/Noncopyable.h>
+#include <wtf/IteratorRange.h>
#include <wtf/StdLibExtras.h>
#include <wtf/TriState.h>
@@ -53,8 +53,6 @@
class JS_EXPORT_PRIVATE Value {
WTF_MAKE_FAST_ALLOCATED;
public:
- typedef Vector<Value*, 3> AdjacencyList;
-
static const char* const dumpPrefix;
static bool accepts(Kind) { return true; }
@@ -82,14 +80,6 @@
Origin origin() const { return m_origin; }
void setOrigin(Origin origin) { m_origin = origin; }
- Value*& child(unsigned index) { return m_children[index]; }
- Value* child(unsigned index) const { return m_children[index]; }
-
- Value*& lastChild() { return m_children.last(); }
- Value* lastChild() const { return m_children.last(); }
-
- unsigned numChildren() const { return m_children.size(); }
-
Type type() const { return m_type; }
void setType(Type type) { m_type = type; }
@@ -97,9 +87,58 @@
Bank resultBank() const { return bankForType(type()); }
Width resultWidth() const { return widthForType(type()); }
- AdjacencyList& children() { return m_children; }
- const AdjacencyList& children() const { return m_children; }
+ unsigned numChildren() const
+ {
+ if (m_numChildren == VarArgs)
+ return childrenVector().size();
+ return m_numChildren;
+ }
+
+ Value*& child(unsigned index)
+ {
+ ASSERT(index < numChildren());
+ return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index];
+ }
+ Value* child(unsigned index) const
+ {
+ ASSERT(index < numChildren());
+ return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index];
+ }
+
+ Value*& lastChild()
+ {
+ if (m_numChildren == VarArgs)
+ return childrenVector().last();
+ ASSERT(m_numChildren >= 1);
+ return childrenArray()[m_numChildren - 1];
+ }
+ Value* lastChild() const
+ {
+ if (m_numChildren == VarArgs)
+ return childrenVector().last();
+ ASSERT(m_numChildren >= 1);
+ return childrenArray()[m_numChildren - 1];
+ }
+ WTF::IteratorRange<Value**> children()
+ {
+ if (m_numChildren == VarArgs) {
+ Vector<Value*, 3>& vec = childrenVector();
+ return WTF::makeIteratorRange(&*vec.begin(), &*vec.end());
+ }
+ Value** buffer = childrenArray();
+ return {buffer, buffer + m_numChildren };
+ }
+ WTF::IteratorRange<Value* const*> children() const
+ {
+ if (m_numChildren == VarArgs) {
+ const Vector<Value*, 3>& vec = childrenVector();
+ return WTF::makeIteratorRange(&*vec.begin(), &*vec.end());
+ }
+ Value* const* buffer = childrenArray();
+ return {buffer, buffer + m_numChildren };
+ }
+
// If you want to replace all uses of this value with a different value, then replace this
// value with Identity. Then do a pass of performSubstitution() on all of the values that use
// this one. Usually we do all of this in one pass in pre-order, which ensures that the
@@ -301,19 +340,218 @@
typename std::enable_if<sizeof(Int) <= sizeof(OffsetType)>::type
> { };
+protected:
+ Value* cloneImpl() const;
-protected:
- virtual Value* cloneImpl() const;
-
+ void replaceWith(Kind, Type, BasicBlock*);
+ void replaceWith(Kind, Type, BasicBlock*, Value*);
+
virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
+ // The specific value of VarArgs does not matter, but the value of the others is assumed to match their meaning.
+ enum NumChildren : uint8_t { Zero = 0, _One_ = 1, Two = 2, Three = 3, VarArgs = 4};
+
+ char* childrenAlloc() { return bitwise_cast<char*>(this) + adjacencyListOffset(); }
+ const char* childrenAlloc() const { return bitwise_cast<const char*>(this) + adjacencyListOffset(); }
+ Vector<Value*, 3>& childrenVector()
+ {
+ ASSERT(m_numChildren == VarArgs);
+ return *bitwise_cast<Vector<Value*, 3>*>(childrenAlloc());
+ }
+ const Vector<Value*, 3>& childrenVector() const
+ {
+ ASSERT(m_numChildren == VarArgs);
+ return *bitwise_cast<Vector<Value*, 3> const*>(childrenAlloc());
+ }
+ Value** childrenArray()
+ {
+ ASSERT(m_numChildren != VarArgs);
+ return bitwise_cast<Value**>(childrenAlloc());
+ }
+ Value* const* childrenArray() const
+ {
+ ASSERT(m_numChildren != VarArgs);
+ return bitwise_cast<Value* const*>(childrenAlloc());
+ }
+
+ template<typename... Arguments>
+ static Opcode opcodeFromConstructor(Kind kind, Arguments...) { return kind.opcode(); }
+ ALWAYS_INLINE static size_t adjacencyListSpace(Kind kind)
+ {
+ switch (kind.opcode()) {
+ case FramePointer:
+ case Nop:
+ case Phi:
+ case Jump:
+ case Oops:
+ case EntrySwitch:
+ case ArgumentReg:
+ case Const32:
+ case Const64:
+ case ConstFloat:
+ case ConstDouble:
+ case Fence:
+ case SlotBase:
+ case Get:
+ return 0;
+ case Return:
+ case Identity:
+ case Opaque:
+ case Neg:
+ case Clz:
+ case Abs:
+ case Ceil:
+ case Floor:
+ case Sqrt:
+ case SExt8:
+ case SExt16:
+ case Trunc:
+ case SExt32:
+ case ZExt32:
+ case FloatToDouble:
+ case IToD:
+ case DoubleToFloat:
+ case IToF:
+ case BitwiseCast:
+ case Branch:
+ case Depend:
+ case Load8Z:
+ case Load8S:
+ case Load16Z:
+ case Load16S:
+ case Load:
+ case Switch:
+ case Upsilon:
+ case Set:
+ case WasmAddress:
+ case WasmBoundsCheck:
+ return sizeof(Value*);
+ case Add:
+ case Sub:
+ case Mul:
+ case Div:
+ case UDiv:
+ case Mod:
+ case UMod:
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ case Shl:
+ case SShr:
+ case ZShr:
+ case RotR:
+ case RotL:
+ case Equal:
+ case NotEqual:
+ case LessThan:
+ case GreaterThan:
+ case LessEqual:
+ case GreaterEqual:
+ case Above:
+ case Below:
+ case AboveEqual:
+ case BelowEqual:
+ case EqualOrUnordered:
+ case AtomicXchgAdd:
+ case AtomicXchgAnd:
+ case AtomicXchgOr:
+ case AtomicXchgSub:
+ case AtomicXchgXor:
+ case AtomicXchg:
+ case Store8:
+ case Store16:
+ case Store:
+ return 2 * sizeof(Value*);
+ case Select:
+ case AtomicWeakCAS:
+ case AtomicStrongCAS:
+ return 3 * sizeof(Value*);
+ case CCall:
+ case Check:
+ case CheckAdd:
+ case CheckSub:
+ case CheckMul:
+ case Patchpoint:
+ return sizeof(Vector<Value*, 3>);
+ default:
+ break;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+ return 0;
+ }
+
private:
+ static char* allocateSpace(Opcode opcode, size_t size)
+ {
+ size_t adjacencyListSpace = Value::adjacencyListSpace(opcode);
+ // We must allocate enough space that replaceWithIdentity can work without buffer overflow.
+ size_t allocIdentitySize = sizeof(Value) + sizeof(Value*);
+ size_t allocSize = std::max(size + adjacencyListSpace, allocIdentitySize);
+ return static_cast<char*>(WTF::fastMalloc(allocSize));
+ }
+
+protected:
+ template<typename ValueType, typename... Arguments>
+ static ValueType* allocate(Arguments... arguments)
+ {
+ char* alloc = allocateSpace(ValueType::opcodeFromConstructor(arguments...), sizeof(ValueType));
+ return new (alloc) ValueType(arguments...);
+ }
+ template<typename ValueType>
+ static ValueType* allocate(const ValueType& valueToClone)
+ {
+ char* alloc = allocateSpace(valueToClone.opcode(), sizeof(ValueType));
+ ValueType* result = new (alloc) ValueType(valueToClone);
+ result->buildAdjacencyList(sizeof(ValueType), valueToClone);
+ return result;
+ }
+
+ // Protected so it will only be called from allocate above, possibly through the subclasses'copy constructors
+ Value(const Value&) = default;
+
+ Value(Value&&) = delete;
+ Value& operator=(const Value&) = delete;
+ Value& operator=(Value&&) = delete;
+
+ size_t adjacencyListOffset() const;
+
friend class Procedure;
friend class SparseCollection<Value>;
+private:
+ template<typename... Arguments>
+ void buildAdjacencyList(NumChildren numChildren, Arguments... arguments)
+ {
+ if (numChildren == VarArgs) {
+ new (childrenAlloc()) Vector<Value*, 3> { arguments... };
+ return;
+ }
+ ASSERT(numChildren == sizeof...(arguments));
+ new (childrenAlloc()) Value*[sizeof...(arguments)] { arguments... };
+ }
+ void buildAdjacencyList(size_t offset, const Value& valueToClone)
+ {
+ switch (valueToClone.m_numChildren) {
+ case VarArgs:
+ new (bitwise_cast<char*>(this) + offset) Vector<Value*, 3> (valueToClone.childrenVector());
+ break;
+ case Three:
+ bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[2] = valueToClone.childrenArray()[2];
+ FALLTHROUGH;
+ case Two:
+ bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[1] = valueToClone.childrenArray()[1];
+ FALLTHROUGH;
+ case One:
+ bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[0] = valueToClone.childrenArray()[0];
+ break;
+ case Zero:
+ break;
+ }
+ }
+
// Checks that this kind is valid for use with B3::Value.
- ALWAYS_INLINE static void checkKind(Kind kind, unsigned numArgs)
+ ALWAYS_INLINE static NumChildren numChildrenForKind(Kind kind, unsigned numArgs)
{
switch (kind.opcode()) {
case FramePointer:
@@ -324,11 +562,11 @@
case EntrySwitch:
if (UNLIKELY(numArgs))
badKind(kind, numArgs);
- break;
+ return Zero;
case Return:
if (UNLIKELY(numArgs > 1))
badKind(kind, numArgs);
- break;
+ return numArgs ? One : Zero;
case Identity:
case Opaque:
case Neg:
@@ -351,7 +589,7 @@
case Depend:
if (UNLIKELY(numArgs != 1))
badKind(kind, numArgs);
- break;
+ return One;
case Add:
case Sub:
case Mul:
@@ -380,129 +618,105 @@
case EqualOrUnordered:
if (UNLIKELY(numArgs != 2))
badKind(kind, numArgs);
- break;
+ return Two;
case Select:
if (UNLIKELY(numArgs != 3))
badKind(kind, numArgs);
- break;
+ return Three;
default:
badKind(kind, numArgs);
break;
}
+ return VarArgs;
}
protected:
enum CheckedOpcodeTag { CheckedOpcode };
-
- Value(const Value&) = default;
- Value& operator=(const Value&) = default;
// Instantiate values via Procedure.
// This form requires specifying the type explicitly:
template<typename... Arguments>
- explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments)
+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Value* firstChild, Arguments... arguments)
: m_kind(kind)
, m_type(type)
+ , m_numChildren(numChildren)
, m_origin(origin)
- , m_children{ firstChild, arguments... }
{
+ buildAdjacencyList(numChildren, firstChild, arguments...);
}
// This form is for specifying the type explicitly when the opcode has no children:
- explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin)
+ explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin)
: m_kind(kind)
, m_type(type)
+ , m_numChildren(numChildren)
, m_origin(origin)
{
+ buildAdjacencyList(numChildren);
}
- // This form is for those opcodes that can infer their type from the opcode and first child:
- template<typename... Arguments>
- explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild)
- : m_kind(kind)
- , m_type(typeFor(kind, firstChild))
- , m_origin(origin)
- , m_children{ firstChild }
- {
- }
- // This form is for those opcodes that can infer their type from the opcode and first and second child:
- template<typename... Arguments>
- explicit Value(CheckedOpcodeTag, Kind kind, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
- : m_kind(kind)
- , m_type(typeFor(kind, firstChild, secondChild))
- , m_origin(origin)
- , m_children{ firstChild, secondChild, arguments... }
- {
- }
// This form is for those opcodes that can infer their type from the opcode alone, and that don't
// take any arguments:
- explicit Value(CheckedOpcodeTag, Kind kind, Origin origin)
+ explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin)
: m_kind(kind)
, m_type(typeFor(kind, nullptr))
+ , m_numChildren(numChildren)
, m_origin(origin)
{
+ buildAdjacencyList(numChildren);
}
- // Use this form for varargs.
- explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, const AdjacencyList& children)
+ // This form is for those opcodes that can infer their type from the opcode and first child:
+ explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild)
: m_kind(kind)
- , m_type(type)
+ , m_type(typeFor(kind, firstChild))
+ , m_numChildren(numChildren)
, m_origin(origin)
- , m_children(children)
{
+ buildAdjacencyList(numChildren, firstChild);
}
- explicit Value(CheckedOpcodeTag, Kind kind, Type type, Origin origin, AdjacencyList&& children)
+ // This form is for those opcodes that can infer their type from the opcode and first and second child:
+ template<typename... Arguments>
+ explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
: m_kind(kind)
- , m_type(type)
+ , m_type(typeFor(kind, firstChild, secondChild))
+ , m_numChildren(numChildren)
, m_origin(origin)
- , m_children(WTFMove(children))
{
+ buildAdjacencyList(numChildren, firstChild, secondChild, arguments...);
}
// This is the constructor you end up actually calling, if you're instantiating Value
// directly.
- template<typename... Arguments>
- explicit Value(Kind kind, Type type, Origin origin)
- : Value(CheckedOpcode, kind, type, origin)
+ explicit Value(Kind kind, Type type, Origin origin)
+ : Value(CheckedOpcode, kind, type, Zero, origin)
{
- checkKind(kind, 0);
+ RELEASE_ASSERT(numChildrenForKind(kind, 0) == Zero);
}
+ // We explicitly convert the extra arguments to Value* (they may be pointers to some subclasses of Value) to limit template explosion
template<typename... Arguments>
- explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments&&... arguments)
- : Value(CheckedOpcode, kind, type, origin, firstChild, std::forward<Arguments>(arguments)...)
+ explicit Value(Kind kind, Origin origin, Arguments... arguments)
+ : Value(CheckedOpcode, kind, numChildrenForKind(kind, sizeof...(arguments)), origin, static_cast<Value*>(arguments)...)
{
- checkKind(kind, 1 + sizeof...(arguments));
}
template<typename... Arguments>
- explicit Value(Kind kind, Type type, Origin origin, const AdjacencyList& children)
- : Value(CheckedOpcode, kind, type, origin, children)
+ explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments)
+ : Value(CheckedOpcode, kind, type, numChildrenForKind(kind, 1 + sizeof...(arguments)), origin, firstChild, static_cast<Value*>(arguments)...)
{
- checkKind(kind, children.size());
}
- template<typename... Arguments>
- explicit Value(Kind kind, Type type, Origin origin, AdjacencyList&& children)
- : Value(CheckedOpcode, kind, type, origin, WTFMove(children))
- {
- checkKind(kind, m_children.size());
- }
- template<typename... Arguments>
- explicit Value(Kind kind, Origin origin, Arguments&&... arguments)
- : Value(CheckedOpcode, kind, origin, std::forward<Arguments>(arguments)...)
- {
- checkKind(kind, sizeof...(arguments));
- }
private:
friend class CheckValue; // CheckValue::convertToAdd() modifies m_kind.
-
+
static Type typeFor(Kind, Value* firstChild, Value* secondChild = nullptr);
- // This group of fields is arranged to fit in 64 bits.
+ // m_index to m_numChildren are arranged to fit in 64 bits.
protected:
unsigned m_index { UINT_MAX };
private:
Kind m_kind;
Type m_type;
-
+protected:
+ NumChildren m_numChildren;
+private:
Origin m_origin;
- AdjacencyList m_children;
NO_RETURN_DUE_TO_CRASH static void badKind(Kind, unsigned);
@@ -518,13 +732,7 @@
{
}
- void dump(PrintStream& out) const
- {
- if (m_value)
- m_value->deepDump(m_proc, out);
- else
- out.print("<null>");
- }
+ void dump(PrintStream& out) const;
private:
const Procedure* m_proc;
@@ -540,6 +748,116 @@
return DeepValueDump(nullptr, value);
}
+// The following macros are designed for subclasses of B3::Value to use.
+// They are never required for correctness, but can improve the performance of child/lastChild/numChildren/children methods,
+// for users that already know the specific subclass of Value they are manipulating.
+// 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:
+// - B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN: always 0 children (e.g. Const32Value)
+// - B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n): always n children, with n in {1, 2, 3} (e.g. UpsilonValue, with n = 1)
+// - 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)
+// - B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN: always a varargs (e.g. CCallValue)
+// The second set is only to be used by classes that we know are not further subclassed by anyone adding fields,
+// as they hardcode the offset of the children array/vector (which is equal to the size of the object).
+// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
+#define B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN \
+ unsigned numChildren() const { return 0; } \
+ WTF::IteratorRange<Value**> children() { return {nullptr, nullptr}; } \
+ WTF::IteratorRange<Value* const*> children() const { return { nullptr, nullptr}; }
+
+#define B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n) \
+public: \
+ unsigned numChildren() const { return n; } \
+ Value*& child(unsigned index) \
+ { \
+ ASSERT(index <= n); \
+ return childrenArray()[index]; \
+ } \
+ Value* child(unsigned index) const \
+ { \
+ ASSERT(index <= n); \
+ return childrenArray()[index]; \
+ } \
+ Value*& lastChild() \
+ { \
+ return childrenArray()[n - 1]; \
+ } \
+ Value* lastChild() const \
+ { \
+ return childrenArray()[n - 1]; \
+ } \
+ WTF::IteratorRange<Value**> children() \
+ { \
+ Value** buffer = childrenArray(); \
+ return {buffer, buffer + n }; \
+ } \
+ WTF::IteratorRange<Value* const*> children() const \
+ { \
+ Value* const* buffer = childrenArray(); \
+ return {buffer, buffer + n }; \
+ } \
+
+#define B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN \
+public: \
+ unsigned numChildren() const { return m_numChildren; } \
+ Value*& child(unsigned index) { return childrenArray()[index]; } \
+ Value* child(unsigned index) const { return childrenArray()[index]; } \
+ Value*& lastChild() { return childrenArray()[numChildren() - 1]; } \
+ Value* lastChild() const { return childrenArray()[numChildren() - 1]; } \
+ WTF::IteratorRange<Value**> children() \
+ { \
+ Value** buffer = childrenArray(); \
+ return {buffer, buffer + numChildren() }; \
+ } \
+ WTF::IteratorRange<Value* const*> children() const \
+ { \
+ Value* const* buffer = childrenArray(); \
+ return {buffer, buffer + numChildren() }; \
+ } \
+
+#define B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN \
+public: \
+ unsigned numChildren() const { return childrenVector().size(); } \
+ Value*& child(unsigned index) { return childrenVector()[index]; } \
+ Value* child(unsigned index) const { return childrenVector()[index]; } \
+ Value*& lastChild() { return childrenVector().last(); } \
+ Value* lastChild() const { return childrenVector().last(); } \
+ WTF::IteratorRange<Value**> children() \
+ { \
+ Vector<Value*, 3>& vec = childrenVector(); \
+ return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
+ } \
+ WTF::IteratorRange<Value* const*> children() const \
+ { \
+ const Vector<Value*, 3>& vec = childrenVector(); \
+ return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
+ } \
+
+// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
+// Also there is no point in applying this to classes with no children, as they don't have a children array to access.
+#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN \
+private: \
+ Value** childrenArray() \
+ { \
+ return bitwise_cast<Value**>(bitwise_cast<char*>(this) + sizeof(*this)); \
+ } \
+ Value* const* childrenArray() const \
+ { \
+ return bitwise_cast<Value* const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
+ }
+
+// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
+#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN \
+private: \
+ Vector<Value*, 3>& childrenVector() \
+ { \
+ return *bitwise_cast<Vector<Value*, 3>*>(bitwise_cast<char*>(this) + sizeof(*this)); \
+ } \
+ const Vector<Value*, 3>& childrenVector() const \
+ { \
+ return *bitwise_cast<Vector<Value*, 3> const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
+ } \
+
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3ValueInlines.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3ValueInlines.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3ValueInlines.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -27,19 +27,157 @@
#if ENABLE(B3_JIT)
+#include "B3ArgumentRegValue.h"
+#include "B3AtomicValue.h"
+#include "B3CCallValue.h"
#include "B3CheckValue.h"
#include "B3Const32Value.h"
#include "B3Const64Value.h"
#include "B3ConstDoubleValue.h"
#include "B3ConstFloatValue.h"
+#include "B3FenceValue.h"
+#include "B3MemoryValue.h"
#include "B3PatchpointValue.h"
#include "B3PhiChildren.h"
#include "B3Procedure.h"
+#include "B3SlotBaseValue.h"
+#include "B3SwitchValue.h"
+#include "B3UpsilonValue.h"
#include "B3Value.h"
+#include "B3VariableValue.h"
+#include "B3WasmAddressValue.h"
+#include "B3WasmBoundsCheckValue.h"
#include <wtf/GraphNodeWorklist.h>
namespace JSC { namespace B3 {
+#define DISPATCH_ON_KIND(MACRO) \
+ switch (kind().opcode()) { \
+ case FramePointer: \
+ case Nop: \
+ case Phi: \
+ case Jump: \
+ case Oops: \
+ case EntrySwitch: \
+ case Return: \
+ case Identity: \
+ case Opaque: \
+ case Neg: \
+ case Clz: \
+ case Abs: \
+ case Ceil: \
+ case Floor: \
+ case Sqrt: \
+ case SExt8: \
+ case SExt16: \
+ case Trunc: \
+ case SExt32: \
+ case ZExt32: \
+ case FloatToDouble: \
+ case IToD: \
+ case DoubleToFloat: \
+ case IToF: \
+ case BitwiseCast: \
+ case Branch: \
+ case Depend: \
+ case Add: \
+ case Sub: \
+ case Mul: \
+ case Div: \
+ case UDiv: \
+ case Mod: \
+ case UMod: \
+ case BitAnd: \
+ case BitOr: \
+ case BitXor: \
+ case Shl: \
+ case SShr: \
+ case ZShr: \
+ case RotR: \
+ case RotL: \
+ case Equal: \
+ case NotEqual: \
+ case LessThan: \
+ case GreaterThan: \
+ case LessEqual: \
+ case GreaterEqual: \
+ case Above: \
+ case Below: \
+ case AboveEqual: \
+ case BelowEqual: \
+ case EqualOrUnordered: \
+ case Select: \
+ return MACRO(Value); \
+ case ArgumentReg: \
+ return MACRO(ArgumentRegValue); \
+ case Const32: \
+ return MACRO(Const32Value); \
+ case Const64: \
+ return MACRO(Const64Value); \
+ case ConstFloat: \
+ return MACRO(ConstFloatValue); \
+ case ConstDouble: \
+ return MACRO(ConstDoubleValue); \
+ case Fence: \
+ return MACRO(FenceValue); \
+ case SlotBase: \
+ return MACRO(SlotBaseValue); \
+ case Get: \
+ case Set: \
+ return MACRO(VariableValue); \
+ case Load8Z: \
+ case Load8S: \
+ case Load16Z: \
+ case Load16S: \
+ case Load: \
+ case Store8: \
+ case Store16: \
+ case Store: \
+ return MACRO(MemoryValue); \
+ case Switch: \
+ return MACRO(SwitchValue); \
+ case Upsilon: \
+ return MACRO(UpsilonValue); \
+ case WasmAddress: \
+ return MACRO(WasmAddressValue); \
+ case WasmBoundsCheck: \
+ return MACRO(WasmBoundsCheckValue); \
+ case AtomicXchgAdd: \
+ case AtomicXchgAnd: \
+ case AtomicXchgOr: \
+ case AtomicXchgSub: \
+ case AtomicXchgXor: \
+ case AtomicXchg: \
+ case AtomicWeakCAS: \
+ case AtomicStrongCAS: \
+ return MACRO(AtomicValue); \
+ case CCall: \
+ return MACRO(CCallValue); \
+ case Check: \
+ case CheckAdd: \
+ case CheckSub: \
+ case CheckMul: \
+ return MACRO(CheckValue); \
+ case Patchpoint: \
+ return MACRO(PatchpointValue); \
+ default: \
+ RELEASE_ASSERT_NOT_REACHED(); \
+ }
+
+ALWAYS_INLINE size_t Value::adjacencyListOffset() const
+{
+#define VALUE_TYPE_SIZE(ValueType) sizeof(ValueType)
+ DISPATCH_ON_KIND(VALUE_TYPE_SIZE);
+#undef VALUE_TYPE_SIZE
+}
+
+ALWAYS_INLINE Value* Value::cloneImpl() const
+{
+#define VALUE_TYPE_CLONE(ValueType) allocate<ValueType>(*static_cast<const ValueType*>(this))
+ DISPATCH_ON_KIND(VALUE_TYPE_CLONE);
+#undef VALUE_TYPE_CLONE
+}
+
template<typename BottomProvider>
void Value::replaceWithBottom(const BottomProvider& bottomProvider)
{
Modified: trunk/Source/_javascript_Core/b3/B3VariableValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3VariableValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3VariableValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -41,13 +41,8 @@
out.print(comma, pointerDump(m_variable));
}
-Value* VariableValue::cloneImpl() const
-{
- return new VariableValue(*this);
-}
-
VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable, Value* value)
- : Value(CheckedOpcode, kind, Void, origin, value)
+ : Value(CheckedOpcode, kind, Void, One, origin, value)
, m_variable(variable)
{
ASSERT(kind == Set);
@@ -54,7 +49,7 @@
}
VariableValue::VariableValue(Kind kind, Origin origin, Variable* variable)
- : Value(CheckedOpcode, kind, variable->type(), origin)
+ : Value(CheckedOpcode, kind, variable->type(), Zero, origin)
, m_variable(variable)
{
ASSERT(kind == Get);
Modified: trunk/Source/_javascript_Core/b3/B3VariableValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3VariableValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3VariableValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -41,13 +41,15 @@
Variable* variable() const { return m_variable; }
+ B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
// Use this for Set.
VariableValue(Kind, Origin, Variable*, Value*);
Modified: trunk/Source/_javascript_Core/b3/B3WasmAddressValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3WasmAddressValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3WasmAddressValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -39,13 +39,8 @@
out.print(comma, m_pinnedGPR);
}
-Value* WasmAddressValue::cloneImpl() const
-{
- return new WasmAddressValue(*this);
-}
-
WasmAddressValue::WasmAddressValue(Origin origin, Value* value, GPRReg pinnedGPR)
- : Value(CheckedOpcode, WasmAddress, Int64, origin, value)
+ : Value(CheckedOpcode, WasmAddress, Int64, One, origin, value)
, m_pinnedGPR(pinnedGPR)
{
}
Modified: trunk/Source/_javascript_Core/b3/B3WasmAddressValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3WasmAddressValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3WasmAddressValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -40,14 +40,17 @@
GPRReg pinnedGPR() const { return m_pinnedGPR; }
+ B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1)
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Origin, Value*, GPRReg) { return WasmAddress; }
WasmAddressValue(Origin, Value*, GPRReg);
GPRReg m_pinnedGPR;
Modified: trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -36,7 +36,7 @@
}
WasmBoundsCheckValue::WasmBoundsCheckValue(Origin origin, GPRReg pinnedSize, Value* ptr, unsigned offset)
- : Value(CheckedOpcode, WasmBoundsCheck, origin, ptr)
+ : Value(CheckedOpcode, WasmBoundsCheck, One, origin, ptr)
, m_offset(offset)
, m_boundsType(Type::Pinned)
{
@@ -44,7 +44,7 @@
}
WasmBoundsCheckValue::WasmBoundsCheckValue(Origin origin, Value* ptr, unsigned offset, size_t maximum)
- : Value(CheckedOpcode, WasmBoundsCheck, origin, ptr)
+ : Value(CheckedOpcode, WasmBoundsCheck, One, origin, ptr)
, m_offset(offset)
, m_boundsType(Type::Maximum)
{
@@ -55,11 +55,6 @@
m_bounds.maximum = maximum;
}
-Value* WasmBoundsCheckValue::cloneImpl() const
-{
- return new WasmBoundsCheckValue(*this);
-}
-
void WasmBoundsCheckValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
{
switch (m_boundsType) {
Modified: trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.h (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/B3WasmBoundsCheckValue.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -34,15 +34,7 @@
class WasmBoundsCheckValue : public Value {
public:
- static bool accepts(Kind kind)
- {
- switch (kind.opcode()) {
- case WasmBoundsCheck:
- return true;
- default:
- return false;
- }
- }
+ static bool accepts(Kind kind) { return kind == WasmBoundsCheck; }
~WasmBoundsCheckValue();
@@ -60,15 +52,20 @@
Type boundsType() const { return m_boundsType; }
Bounds bounds() const { return m_bounds; }
+ B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(1)
+ B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
+
protected:
void dumpMeta(CommaPrinter&, PrintStream&) const override;
- Value* cloneImpl() const override;
-
private:
friend class Procedure;
+ friend class Value;
+ static Opcode opcodeFromConstructor(Origin, GPRReg, Value*, unsigned) { return WasmBoundsCheck; }
JS_EXPORT_PRIVATE WasmBoundsCheckValue(Origin, GPRReg pinnedGPR, Value* ptr, unsigned offset);
+
+ static Opcode opcodeFromConstructor(Origin, Value*, unsigned, size_t) { return WasmBoundsCheck; }
JS_EXPORT_PRIVATE WasmBoundsCheckValue(Origin, Value* ptr, unsigned offset, size_t maximum);
unsigned m_offset;
Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (244308 => 244309)
--- trunk/Source/_javascript_Core/b3/testb3.cpp 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp 2019-04-15 23:53:23 UTC (rev 244309)
@@ -10960,7 +10960,7 @@
CCallValue* call = root->appendNew<CCallValue>(
proc, Int32, Origin(),
root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments, B3CCallPtrTag)));
- call->children().appendVector(args);
+ call->appendArgs(args);
root->appendNewControlValue(proc, Return, Origin(), call);
@@ -10986,7 +10986,7 @@
CCallValue* call = root->appendNew<CCallValue>(
proc, Int64, Origin(),
root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments2, B3CCallPtrTag)));
- call->children().appendVector(args);
+ call->appendArgs(args);
root->appendNewControlValue(proc, Return, Origin(), call);
@@ -11008,7 +11008,7 @@
CCallValue* call = root->appendNew<CCallValue>(
proc, Int32, Origin(),
root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaArguments3, B3CCallPtrTag)));
- call->children().appendVector(args);
+ call->appendArgs(args);
root->appendNewControlValue(proc, Return, Origin(), call);
@@ -11108,7 +11108,7 @@
CCallValue* call = root->appendNew<CCallValue>(
proc, Double, Origin(),
root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaDoubleArguments, B3CCallPtrTag)));
- call->children().appendVector(args);
+ call->appendArgs(args);
root->appendNewControlValue(proc, Return, Origin(), call);
@@ -11132,7 +11132,7 @@
CCallValue* call = root->appendNew<CCallValue>(
proc, Float, Origin(),
root->appendNew<ConstPtrValue>(proc, Origin(), tagCFunctionPtr<void*>(functionWithHellaFloatArguments, B3CCallPtrTag)));
- call->children().appendVector(args);
+ call->appendArgs(args);
root->appendNewControlValue(proc, Return, Origin(), call);
Modified: trunk/Source/_javascript_Core/ftl/FTLOutput.h (244308 => 244309)
--- trunk/Source/_javascript_Core/ftl/FTLOutput.h 2019-04-15 23:48:57 UTC (rev 244308)
+++ trunk/Source/_javascript_Core/ftl/FTLOutput.h 2019-04-15 23:53:23 UTC (rev 244309)
@@ -380,7 +380,7 @@
LValue call(LType type, LValue function, const VectorType& vector)
{
B3::CCallValue* result = m_block->appendNew<B3::CCallValue>(m_proc, type, origin(), function);
- result->children().appendVector(vector);
+ result->appendArgs(vector);
return result;
}
LValue call(LType type, LValue function) { return m_block->appendNew<B3::CCallValue>(m_proc, type, origin(), function); }