Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (205106 => 205107)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-08-28 22:38:41 UTC (rev 205106)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-08-28 23:31:46 UTC (rev 205107)
@@ -54,6 +54,7 @@
#include "StructureSet.h"
#include "TypeLocation.h"
#include "ValueProfile.h"
+#include <type_traits>
#include <wtf/ListDump.h>
namespace JSC {
@@ -254,8 +255,6 @@
, m_virtualRegister(VirtualRegister())
, m_refCount(1)
, m_prediction(SpecNone)
- , m_opInfo(0)
- , m_opInfo2(0)
, owner(nullptr)
{
m_misc.replacement = nullptr;
@@ -270,8 +269,6 @@
, m_virtualRegister(VirtualRegister())
, m_refCount(1)
, m_prediction(SpecNone)
- , m_opInfo(0)
- , m_opInfo2(0)
, owner(nullptr)
{
m_misc.replacement = nullptr;
@@ -288,7 +285,6 @@
, m_refCount(1)
, m_prediction(SpecNone)
, m_opInfo(imm.m_value)
- , m_opInfo2(0)
, owner(nullptr)
{
m_misc.replacement = nullptr;
@@ -304,7 +300,6 @@
, m_refCount(1)
, m_prediction(SpecNone)
, m_opInfo(imm.m_value)
- , m_opInfo2(0)
, owner(nullptr)
{
m_misc.replacement = nullptr;
@@ -406,7 +401,7 @@
void convertToCheckStructure(StructureSet* set)
{
setOpAndDefaultFlags(CheckStructure);
- m_opInfo = bitwise_cast<uintptr_t>(set);
+ m_opInfo = set;
}
void convertToCheckStructureImmediate(Node* structure)
@@ -471,7 +466,7 @@
return FrozenValue::emptySingleton();
}
- return bitwise_cast<FrozenValue*>(m_opInfo);
+ return m_opInfo.as<FrozenValue*>();
}
// Don't call this directly - use Graph::convertToConstant() instead!
@@ -484,7 +479,7 @@
else
m_op = JSConstant;
m_flags &= ~NodeMustGenerate;
- m_opInfo = bitwise_cast<uintptr_t>(value);
+ m_opInfo = value;
children.reset();
}
@@ -494,7 +489,7 @@
{
ASSERT(op() == GetIndexedPropertyStorage);
m_op = ConstantStoragePointer;
- m_opInfo = bitwise_cast<uintptr_t>(pointer);
+ m_opInfo = pointer;
children.reset();
}
@@ -511,8 +506,8 @@
{
m_op = PutStack;
m_flags |= NodeMustGenerate;
- m_opInfo = bitwise_cast<uintptr_t>(data);
- m_opInfo2 = 0;
+ m_opInfo = data;
+ m_opInfo2 = OpInfoWrapper();
}
void convertToGetStack(StackAccessData* data)
@@ -519,8 +514,8 @@
{
m_op = GetStack;
m_flags &= ~NodeMustGenerate;
- m_opInfo = bitwise_cast<uintptr_t>(data);
- m_opInfo2 = 0;
+ m_opInfo = data;
+ m_opInfo2 = OpInfoWrapper();
children.reset();
}
@@ -527,7 +522,7 @@
void convertToGetByOffset(StorageAccessData& data, Edge storage, Edge base)
{
ASSERT(m_op == GetById || m_op == GetByIdFlush || m_op == MultiGetByOffset);
- m_opInfo = bitwise_cast<uintptr_t>(&data);
+ m_opInfo = &data;
children.setChild1(storage);
children.setChild2(base);
m_op = GetByOffset;
@@ -537,7 +532,7 @@
void convertToMultiGetByOffset(MultiGetByOffsetData* data)
{
ASSERT(m_op == GetById || m_op == GetByIdFlush);
- m_opInfo = bitwise_cast<intptr_t>(data);
+ m_opInfo = data;
child1().setUseKind(CellUse);
m_op = MultiGetByOffset;
ASSERT(m_flags & NodeMustGenerate);
@@ -546,7 +541,7 @@
void convertToPutByOffset(StorageAccessData& data, Edge storage, Edge base)
{
ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush || m_op == MultiPutByOffset);
- m_opInfo = bitwise_cast<uintptr_t>(&data);
+ m_opInfo = &data;
children.setChild3(children.child2());
children.setChild2(base);
children.setChild1(storage);
@@ -556,7 +551,7 @@
void convertToMultiPutByOffset(MultiPutByOffsetData* data)
{
ASSERT(m_op == PutById || m_op == PutByIdDirect || m_op == PutByIdFlush);
- m_opInfo = bitwise_cast<intptr_t>(data);
+ m_opInfo = data;
m_op = MultiPutByOffset;
}
@@ -572,8 +567,8 @@
m_op = PhantomNewObject;
m_flags &= ~NodeHasVarArgs;
m_flags |= NodeMustGenerate;
- m_opInfo = 0;
- m_opInfo2 = 0;
+ m_opInfo = OpInfoWrapper();
+ m_opInfo2 = OpInfoWrapper();
children = AdjacencyList();
}
@@ -582,8 +577,8 @@
ASSERT(m_op == NewFunction || m_op == NewGeneratorFunction);
m_op = PhantomNewFunction;
m_flags |= NodeMustGenerate;
- m_opInfo = 0;
- m_opInfo2 = 0;
+ m_opInfo = OpInfoWrapper();
+ m_opInfo2 = OpInfoWrapper();
children = AdjacencyList();
}
@@ -592,8 +587,8 @@
ASSERT(m_op == NewGeneratorFunction);
m_op = PhantomNewGeneratorFunction;
m_flags |= NodeMustGenerate;
- m_opInfo = 0;
- m_opInfo2 = 0;
+ m_opInfo = OpInfoWrapper();
+ m_opInfo2 = OpInfoWrapper();
children = AdjacencyList();
}
@@ -603,8 +598,8 @@
m_op = PhantomCreateActivation;
m_flags &= ~NodeHasVarArgs;
m_flags |= NodeMustGenerate;
- m_opInfo = 0;
- m_opInfo2 = 0;
+ m_opInfo = OpInfoWrapper();
+ m_opInfo2 = OpInfoWrapper();
children = AdjacencyList();
}
@@ -627,8 +622,8 @@
{
ASSERT(m_op == GetLocalUnlinked);
m_op = GetLocal;
- m_opInfo = bitwise_cast<uintptr_t>(variable);
- m_opInfo2 = 0;
+ m_opInfo = variable;
+ m_opInfo2 = OpInfoWrapper();
children.setChild1(Edge(phi));
}
@@ -738,7 +733,7 @@
LazyJSValue lazyJSValue()
{
ASSERT(hasLazyJSValue());
- return *bitwise_cast<LazyJSValue*>(m_opInfo);
+ return *m_opInfo.as<LazyJSValue*>();
}
String tryGetString(Graph&);
@@ -746,7 +741,7 @@
JSValue initializationValueForActivation() const
{
ASSERT(op() == CreateActivation);
- return bitwise_cast<FrozenValue*>(m_opInfo2)->value();
+ return m_opInfo2.as<FrozenValue*>()->value();
}
bool hasArgumentsChild()
@@ -814,7 +809,7 @@
// access data doesn't have one because it hasn't been initialized yet.
VariableAccessData* tryGetVariableAccessData()
{
- VariableAccessData* result = reinterpret_cast<VariableAccessData*>(m_opInfo);
+ VariableAccessData* result = m_opInfo.as<VariableAccessData*>();
if (!result)
return 0;
return result->find();
@@ -822,7 +817,7 @@
VariableAccessData* variableAccessData()
{
- return reinterpret_cast<VariableAccessData*>(m_opInfo)->find();
+ return m_opInfo.as<VariableAccessData*>()->find();
}
VirtualRegister local()
@@ -852,7 +847,7 @@
VirtualRegister unlinkedLocal()
{
ASSERT(hasUnlinkedLocal());
- return static_cast<VirtualRegister>(m_opInfo);
+ return VirtualRegister(m_opInfo.as<int32_t>());
}
bool hasUnlinkedMachineLocal()
@@ -869,7 +864,7 @@
VirtualRegister unlinkedMachineLocal()
{
ASSERT(hasUnlinkedMachineLocal());
- return VirtualRegister(m_opInfo2);
+ return VirtualRegister(m_opInfo2.as<int32_t>());
}
bool hasStackAccessData()
@@ -886,7 +881,7 @@
StackAccessData* stackAccessData()
{
ASSERT(hasStackAccessData());
- return bitwise_cast<StackAccessData*>(m_opInfo);
+ return m_opInfo.as<StackAccessData*>();
}
bool hasPhi()
@@ -897,7 +892,7 @@
Node* phi()
{
ASSERT(hasPhi());
- return bitwise_cast<Node*>(m_opInfo);
+ return m_opInfo.as<Node*>();
}
bool isStoreBarrier()
@@ -932,7 +927,7 @@
unsigned identifierNumber()
{
ASSERT(hasIdentifier());
- return m_opInfo;
+ return m_opInfo.as<unsigned>();
}
bool hasGetPutInfo()
@@ -949,7 +944,7 @@
unsigned getPutInfo()
{
ASSERT(hasGetPutInfo());
- return m_opInfo2;
+ return m_opInfo2.as<unsigned>();
}
bool hasAccessorAttributes()
@@ -973,10 +968,10 @@
case PutGetterById:
case PutSetterById:
case PutGetterSetterById:
- return m_opInfo2;
+ return m_opInfo2.as<int32_t>();
case PutGetterByVal:
case PutSetterByVal:
- return m_opInfo;
+ return m_opInfo.as<int32_t>();
default:
RELEASE_ASSERT_NOT_REACHED();
return 0;
@@ -1024,7 +1019,7 @@
NewArrayBufferData* newArrayBufferData()
{
ASSERT(hasConstantBuffer());
- return reinterpret_cast<NewArrayBufferData*>(m_opInfo);
+ return m_opInfo.as<NewArrayBufferData*>();
}
unsigned startConstant()
@@ -1062,7 +1057,7 @@
ASSERT(hasIndexingType());
if (op() == NewArrayBuffer)
return newArrayBufferData()->indexingType;
- return m_opInfo;
+ return static_cast<IndexingType>(m_opInfo.as<uint32_t>());
}
bool hasTypedArrayType()
@@ -1078,7 +1073,7 @@
TypedArrayType typedArrayType()
{
ASSERT(hasTypedArrayType());
- TypedArrayType result = static_cast<TypedArrayType>(m_opInfo);
+ TypedArrayType result = static_cast<TypedArrayType>(m_opInfo.as<uint32_t>());
ASSERT(isTypedView(result));
return result;
}
@@ -1091,7 +1086,7 @@
unsigned inlineCapacity()
{
ASSERT(hasInlineCapacity());
- return m_opInfo;
+ return m_opInfo.as<unsigned>();
}
void setIndexingType(IndexingType indexingType)
@@ -1108,7 +1103,7 @@
ScopeOffset scopeOffset()
{
ASSERT(hasScopeOffset());
- return ScopeOffset(m_opInfo);
+ return ScopeOffset(m_opInfo.as<uint32_t>());
}
bool hasDirectArgumentsOffset()
@@ -1119,7 +1114,7 @@
DirectArgumentsOffset capturedArgumentsOffset()
{
ASSERT(hasDirectArgumentsOffset());
- return DirectArgumentsOffset(m_opInfo);
+ return DirectArgumentsOffset(m_opInfo.as<uint32_t>());
}
bool hasRegisterPointer()
@@ -1129,7 +1124,7 @@
WriteBarrier<Unknown>* variablePointer()
{
- return bitwise_cast<WriteBarrier<Unknown>*>(m_opInfo);
+ return m_opInfo.as<WriteBarrier<Unknown>*>();
}
bool hasCallVarargsData()
@@ -1152,7 +1147,7 @@
CallVarargsData* callVarargsData()
{
ASSERT(hasCallVarargsData());
- return bitwise_cast<CallVarargsData*>(m_opInfo);
+ return m_opInfo.as<CallVarargsData*>();
}
bool hasLoadVarargsData()
@@ -1163,7 +1158,7 @@
LoadVarargsData* loadVarargsData()
{
ASSERT(hasLoadVarargsData());
- return bitwise_cast<LoadVarargsData*>(m_opInfo);
+ return m_opInfo.as<LoadVarargsData*>();
}
bool hasResult()
@@ -1259,25 +1254,25 @@
unsigned targetBytecodeOffsetDuringParsing()
{
ASSERT(isJump());
- return m_opInfo;
+ return m_opInfo.as<unsigned>();
}
BasicBlock*& targetBlock()
{
ASSERT(isJump());
- return *bitwise_cast<BasicBlock**>(&m_opInfo);
+ return *bitwise_cast<BasicBlock**>(&m_opInfo.u.pointer);
}
BranchData* branchData()
{
ASSERT(isBranch());
- return bitwise_cast<BranchData*>(m_opInfo);
+ return m_opInfo.as<BranchData*>();
}
SwitchData* switchData()
{
ASSERT(isSwitch());
- return bitwise_cast<SwitchData*>(m_opInfo);
+ return m_opInfo.as<SwitchData*>();
}
unsigned numSuccessors()
@@ -1437,7 +1432,7 @@
SpeculatedType getHeapPrediction()
{
ASSERT(hasHeapPrediction());
- return static_cast<SpeculatedType>(m_opInfo2);
+ return m_opInfo2.as<SpeculatedType>();
}
void setHeapPrediction(SpeculatedType prediction)
@@ -1466,7 +1461,7 @@
FrozenValue* cellOperand()
{
ASSERT(hasCellOperand());
- return reinterpret_cast<FrozenValue*>(m_opInfo);
+ return m_opInfo.as<FrozenValue*>();
}
template<typename T>
@@ -1478,7 +1473,7 @@
void setCellOperand(FrozenValue* value)
{
ASSERT(hasCellOperand());
- m_opInfo = bitwise_cast<uintptr_t>(value);
+ m_opInfo = value;
}
bool hasWatchpointSet()
@@ -1489,7 +1484,7 @@
WatchpointSet* watchpointSet()
{
ASSERT(hasWatchpointSet());
- return reinterpret_cast<WatchpointSet*>(m_opInfo);
+ return m_opInfo.as<WatchpointSet*>();
}
bool hasStoragePointer()
@@ -1500,7 +1495,7 @@
void* storagePointer()
{
ASSERT(hasStoragePointer());
- return reinterpret_cast<void*>(m_opInfo);
+ return m_opInfo.as<void*>();
}
bool hasUidOperand()
@@ -1511,7 +1506,7 @@
UniquedStringImpl* uidOperand()
{
ASSERT(hasUidOperand());
- return reinterpret_cast<UniquedStringImpl*>(m_opInfo);
+ return m_opInfo.as<UniquedStringImpl*>();
}
bool hasTypeInfoOperand()
@@ -1521,8 +1516,8 @@
unsigned typeInfoOperand()
{
- ASSERT(hasTypeInfoOperand() && m_opInfo <= UCHAR_MAX);
- return static_cast<unsigned>(m_opInfo);
+ ASSERT(hasTypeInfoOperand() && m_opInfo.as<uint32_t>() <= static_cast<uint32_t>(UCHAR_MAX));
+ return m_opInfo.as<uint32_t>();
}
bool hasTransition()
@@ -1540,7 +1535,7 @@
Transition* transition()
{
ASSERT(hasTransition());
- return reinterpret_cast<Transition*>(m_opInfo);
+ return m_opInfo.as<Transition*>();
}
bool hasStructureSet()
@@ -1558,7 +1553,7 @@
StructureSet& structureSet()
{
ASSERT(hasStructureSet());
- return *reinterpret_cast<StructureSet*>(m_opInfo);
+ return *m_opInfo.as<StructureSet*>();
}
bool hasStructure()
@@ -1576,7 +1571,7 @@
Structure* structure()
{
ASSERT(hasStructure());
- return reinterpret_cast<Structure*>(m_opInfo);
+ return m_opInfo.as<Structure*>();
}
bool hasStorageAccessData()
@@ -1594,7 +1589,7 @@
StorageAccessData& storageAccessData()
{
ASSERT(hasStorageAccessData());
- return *bitwise_cast<StorageAccessData*>(m_opInfo);
+ return *m_opInfo.as<StorageAccessData*>();
}
bool hasMultiGetByOffsetData()
@@ -1605,7 +1600,7 @@
MultiGetByOffsetData& multiGetByOffsetData()
{
ASSERT(hasMultiGetByOffsetData());
- return *reinterpret_cast<MultiGetByOffsetData*>(m_opInfo);
+ return *m_opInfo.as<MultiGetByOffsetData*>();
}
bool hasMultiPutByOffsetData()
@@ -1616,7 +1611,7 @@
MultiPutByOffsetData& multiPutByOffsetData()
{
ASSERT(hasMultiPutByOffsetData());
- return *reinterpret_cast<MultiPutByOffsetData*>(m_opInfo);
+ return *m_opInfo.as<MultiPutByOffsetData*>();
}
bool hasObjectMaterializationData()
@@ -1634,7 +1629,7 @@
ObjectMaterializationData& objectMaterializationData()
{
ASSERT(hasObjectMaterializationData());
- return *reinterpret_cast<ObjectMaterializationData*>(m_opInfo2);
+ return *m_opInfo2.as<ObjectMaterializationData*>();
}
bool isObjectAllocation()
@@ -1743,8 +1738,8 @@
{
ASSERT(hasArrayMode());
if (op() == ArrayifyToStructure)
- return ArrayMode::fromWord(m_opInfo2);
- return ArrayMode::fromWord(m_opInfo);
+ return ArrayMode::fromWord(m_opInfo2.as<uint32_t>());
+ return ArrayMode::fromWord(m_opInfo.as<uint32_t>());
}
bool setArrayMode(ArrayMode arrayMode)
@@ -1777,7 +1772,7 @@
Arith::Mode arithMode()
{
ASSERT(hasArithMode());
- return static_cast<Arith::Mode>(m_opInfo);
+ return static_cast<Arith::Mode>(m_opInfo.as<uint32_t>());
}
void setArithMode(Arith::Mode mode)
@@ -1793,13 +1788,13 @@
Arith::RoundingMode arithRoundingMode()
{
ASSERT(hasArithRoundingMode());
- return static_cast<Arith::RoundingMode>(m_opInfo);
+ return static_cast<Arith::RoundingMode>(m_opInfo.as<uint32_t>());
}
void setArithRoundingMode(Arith::RoundingMode mode)
{
ASSERT(hasArithRoundingMode());
- m_opInfo = static_cast<uintptr_t>(mode);
+ m_opInfo = static_cast<uint32_t>(mode);
}
bool hasVirtualRegister()
@@ -1828,7 +1823,7 @@
Profiler::ExecutionCounter* executionCounter()
{
- return bitwise_cast<Profiler::ExecutionCounter*>(m_opInfo);
+ return m_opInfo.as<Profiler::ExecutionCounter*>();
}
bool shouldGenerate()
@@ -2271,7 +2266,7 @@
TypeLocation* typeLocation()
{
ASSERT(hasTypeLocation());
- return reinterpret_cast<TypeLocation*>(m_opInfo);
+ return m_opInfo.as<TypeLocation*>();
}
bool hasBasicBlockLocation()
@@ -2282,7 +2277,7 @@
BasicBlockLocation* basicBlockLocation()
{
ASSERT(hasBasicBlockLocation());
- return reinterpret_cast<BasicBlockLocation*>(m_opInfo);
+ return m_opInfo.as<BasicBlockLocation*>();
}
Node* replacement() const
@@ -2308,7 +2303,7 @@
unsigned numberOfArgumentsToSkip()
{
ASSERT(op() == CreateRest || op() == GetRestLength);
- return static_cast<unsigned>(m_opInfo);
+ return m_opInfo.as<unsigned>();
}
void dumpChildren(PrintStream& out)
@@ -2345,8 +2340,71 @@
SpeculatedType m_prediction { SpecNone };
// Immediate values, accesses type-checked via accessors above. The first one is
// big enough to store a pointer.
- uintptr_t m_opInfo;
- uintptr_t m_opInfo2;
+ struct OpInfoWrapper {
+ OpInfoWrapper()
+ {
+ u.int64 = 0;
+ }
+ OpInfoWrapper(uint32_t intValue)
+ {
+ u.int64 = 0;
+ u.int32 = intValue;
+ }
+ OpInfoWrapper(uint64_t intValue)
+ {
+ u.int64 = intValue;
+ }
+ OpInfoWrapper(void* pointer)
+ {
+ u.int64 = 0;
+ u.pointer = pointer;
+ }
+ OpInfoWrapper& operator=(uint32_t int32)
+ {
+ u.int64 = 0;
+ u.int32 = int32;
+ return *this;
+ }
+ OpInfoWrapper& operator=(int32_t int32)
+ {
+ u.int64 = 0;
+ u.int32 = int32;
+ return *this;
+ }
+ OpInfoWrapper& operator=(uint64_t int64)
+ {
+ u.int64 = int64;
+ return *this;
+ }
+ OpInfoWrapper& operator=(void* pointer)
+ {
+ u.int64 = 0;
+ u.pointer = pointer;
+ return *this;
+ }
+ template <typename T>
+ ALWAYS_INLINE auto as() const -> typename std::enable_if<std::is_pointer<T>::value, T>::type
+ {
+ return static_cast<T>(u.pointer);
+ }
+ template <typename T>
+ ALWAYS_INLINE auto as() const -> typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 4, T>::type
+ {
+ return u.int32;
+ }
+ template <typename T>
+ ALWAYS_INLINE auto as() const -> typename std::enable_if<std::is_integral<T>::value && sizeof(T) == 8, T>::type
+ {
+ return u.int64;
+ }
+ union {
+ uint32_t int32;
+ uint64_t int64;
+ void* pointer;
+ } u;
+ };
+ OpInfoWrapper m_opInfo;
+ OpInfoWrapper m_opInfo2;
// Miscellaneous data that is usually meaningless, but can hold some analysis results
// if you ask right. For example, if you do Graph::initializeNodeOwners(), Node::owner