summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGValidate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGValidate.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGValidate.cpp264
1 files changed, 52 insertions, 212 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGValidate.cpp b/Source/JavaScriptCore/dfg/DFGValidate.cpp
index 6a134d048..09bea406f 100644
--- a/Source/JavaScriptCore/dfg/DFGValidate.cpp
+++ b/Source/JavaScriptCore/dfg/DFGValidate.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,8 +29,6 @@
#if ENABLE(DFG_JIT)
#include "CodeBlockWithJITType.h"
-#include "DFGMayExit.h"
-#include "JSCInlines.h"
#include <wtf/Assertions.h>
#include <wtf/BitVector.h>
@@ -38,19 +36,17 @@ namespace JSC { namespace DFG {
class Validate {
public:
- Validate(Graph& graph, GraphDumpMode graphDumpMode, CString graphDumpBeforePhase)
+ Validate(Graph& graph, GraphDumpMode graphDumpMode)
: m_graph(graph)
, m_graphDumpMode(graphDumpMode)
- , m_graphDumpBeforePhase(graphDumpBeforePhase)
{
}
#define VALIDATE(context, assertion) do { \
if (!(assertion)) { \
- startCrashing(); \
dataLogF("\n\n\nAt "); \
reportValidationContext context; \
- dataLogF(": validation failed: %s (%s:%d).\n", #assertion, __FILE__, __LINE__); \
+ dataLogF(": validation %s (%s:%d) failed.\n", #assertion, __FILE__, __LINE__); \
dumpGraphIfAppropriate(); \
WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \
CRASH(); \
@@ -59,14 +55,13 @@ public:
#define V_EQUAL(context, left, right) do { \
if (left != right) { \
- startCrashing(); \
dataLogF("\n\n\nAt "); \
reportValidationContext context; \
- dataLogF(": validation failed: (%s = ", #left); \
+ dataLogF(": validation (%s = ", #left); \
dataLog(left); \
dataLogF(") == (%s = ", #right); \
dataLog(right); \
- dataLogF(") (%s:%d).\n", __FILE__, __LINE__); \
+ dataLogF(") (%s:%d) failed.\n", __FILE__, __LINE__); \
dumpGraphIfAppropriate(); \
WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #left " == " #right); \
CRASH(); \
@@ -74,7 +69,7 @@ public:
} while (0)
#define notSet (static_cast<size_t>(-1))
-
+
void validate()
{
// NB. This code is not written for performance, since it is not intended to run
@@ -118,9 +113,6 @@ public:
continue;
m_myRefCounts.find(edge.node())->value++;
-
- validateEdgeWithDoubleResultIfNecessary(node, edge);
- VALIDATE((node, edge), edge->hasInt52Result() == (edge.useKind() == Int52RepUse));
if (m_graph.m_form == SSA) {
// In SSA, all edges must hasResult().
@@ -146,6 +138,31 @@ public:
break;
VALIDATE((node, edge), edge->variableAccessData() == node->variableAccessData());
break;
+ case Phantom:
+ switch (m_graph.m_form) {
+ case LoadStore:
+ if (j) {
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ }
+ switch (edge->op()) {
+ case Phi:
+ case SetArgument:
+ case SetLocal:
+ break;
+ default:
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ }
+ break;
+ case ThreadedCPS:
+ VALIDATE((node, edge), edge->hasResult());
+ break;
+ case SSA:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ break;
default:
VALIDATE((node, edge), edge->hasResult());
break;
@@ -162,103 +179,8 @@ public:
Node* node = block->node(i);
if (m_graph.m_refCountState == ExactRefCount)
V_EQUAL((node), m_myRefCounts.get(node), node->adjustedRefCount());
- }
-
- bool foundTerminal = false;
- for (size_t i = 0 ; i < block->size(); ++i) {
- Node* node = block->at(i);
- if (node->isTerminal()) {
- foundTerminal = true;
- for (size_t j = i + 1; j < block->size(); ++j) {
- node = block->at(j);
- VALIDATE((node), node->op() == Phantom || node->op() == PhantomLocal || node->op() == Flush || node->op() == Check);
- m_graph.doToChildren(
- node,
- [&] (Edge edge) {
- VALIDATE((node, edge), shouldNotHaveTypeCheck(edge.useKind()));
- });
- }
- break;
- }
- }
- VALIDATE((block), foundTerminal);
-
- for (size_t i = 0; i < block->size(); ++i) {
- Node* node = block->at(i);
-
- VALIDATE((node), node->origin.semantic.isSet() == node->origin.forExit.isSet());
- VALIDATE((node), !mayExit(m_graph, node) || node->origin.forExit.isSet());
- VALIDATE((node), !node->hasStructure() || !!node->structure());
- VALIDATE((node), !node->hasCellOperand() || node->cellOperand()->value().isCell());
- VALIDATE((node), !node->hasCellOperand() || !!node->cellOperand()->value());
-
- if (!(node->flags() & NodeHasVarArgs)) {
- if (!node->child2())
- VALIDATE((node), !node->child3());
- if (!node->child1())
- VALIDATE((node), !node->child2());
- }
-
- switch (node->op()) {
- case Identity:
- VALIDATE((node), canonicalResultRepresentation(node->result()) == canonicalResultRepresentation(node->child1()->result()));
- break;
- case SetLocal:
- case PutStack:
- case Upsilon:
- VALIDATE((node), !!node->child1());
- switch (node->child1().useKind()) {
- case UntypedUse:
- case CellUse:
- case Int32Use:
- case Int52RepUse:
- case DoubleRepUse:
- case BooleanUse:
- break;
- default:
- VALIDATE((node), !"Bad use kind");
- break;
- }
- break;
- case MakeRope:
- case ValueAdd:
- case ArithAdd:
- case ArithSub:
- case ArithMul:
- case ArithIMul:
- case ArithDiv:
- case ArithMod:
- case ArithMin:
- case ArithMax:
- case ArithPow:
- case CompareLess:
- case CompareLessEq:
- case CompareGreater:
- case CompareGreaterEq:
- case CompareEq:
- case CompareEqConstant:
- case CompareStrictEq:
- VALIDATE((node), !!node->child1());
- VALIDATE((node), !!node->child2());
- break;
- case PutStructure:
- VALIDATE((node), !node->transition()->previous->dfgShouldWatch());
- break;
- case MultiPutByOffset:
- for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
- const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
- if (variant.kind() != PutByIdVariant::Transition)
- continue;
- VALIDATE((node), !variant.oldStructureForTransition()->dfgShouldWatch());
- }
- break;
- case DoubleConstant:
- case Int52Constant:
- VALIDATE((node), node->isNumberConstant());
- break;
- default:
- break;
- }
+ else
+ V_EQUAL((node), node->refCount(), 1);
}
}
@@ -277,7 +199,6 @@ public:
private:
Graph& m_graph;
GraphDumpMode m_graphDumpMode;
- CString m_graphDumpBeforePhase;
HashMap<Node*, unsigned> m_myRefCounts;
HashSet<Node*> m_acceptableNodes;
@@ -407,7 +328,6 @@ private:
Node* node = block->at(i);
ASSERT(nodesInThisBlock.contains(node));
VALIDATE((node), node->op() != Phi);
- VALIDATE((node), node->origin.forExit.isSet());
for (unsigned j = 0; j < m_graph.numChildren(node); ++j) {
Edge edge = m_graph.child(node, j);
if (!edge)
@@ -418,63 +338,39 @@ private:
case GetLocal:
case Flush:
break;
+ case Phantom:
+ if (m_graph.m_form == LoadStore && !j)
+ break;
+ FALLTHROUGH;
default:
VALIDATE((node, edge), !phisInThisBlock.contains(edge.node()));
break;
}
}
- switch (node->op()) {
- case Phi:
- case Upsilon:
- case CheckInBounds:
- case PhantomNewObject:
- case PhantomNewFunction:
- case PhantomCreateActivation:
- case GetMyArgumentByVal:
- case PutHint:
- case CheckStructureImmediate:
- case MaterializeNewObject:
- case MaterializeCreateActivation:
- case PutStack:
- case KillStack:
- case GetStack:
- VALIDATE((node), !"unexpected node type in CPS");
- break;
- case Phantom:
- VALIDATE((node), m_graph.m_fixpointState != FixpointNotConverged);
- break;
- default:
- break;
- }
-
if (!node->shouldGenerate())
continue;
switch (node->op()) {
case GetLocal:
+ if (node->variableAccessData()->isCaptured())
+ break;
// Ignore GetLocal's that we know to be dead, but that the graph
// doesn't yet know to be dead.
if (!m_myRefCounts.get(node))
break;
- if (m_graph.m_form == ThreadedCPS) {
+ if (m_graph.m_form == ThreadedCPS)
VALIDATE((node, block), getLocalPositions.operand(node->local()) == notSet);
- VALIDATE((node, block), !!node->child1());
- }
getLocalPositions.operand(node->local()) = i;
break;
case SetLocal:
+ if (node->variableAccessData()->isCaptured())
+ break;
// Only record the first SetLocal. There may be multiple SetLocals
// because of flushing.
if (setLocalPositions.operand(node->local()) != notSet)
break;
setLocalPositions.operand(node->local()) = i;
break;
- case SetArgument:
- // This acts like a reset. It's ok to have a second GetLocal for a local in the same
- // block if we had a SetArgument for that local.
- getLocalPositions.operand(node->local()) = notSet;
- setLocalPositions.operand(node->local()) = notSet;
- break;
default:
break;
}
@@ -504,81 +400,30 @@ private:
if (!block)
continue;
- VALIDATE((block), block->phis.isEmpty());
-
unsigned nodeIndex = 0;
- for (; nodeIndex < block->size() && !block->at(nodeIndex)->origin.forExit.isSet(); nodeIndex++) { }
+ for (; nodeIndex < block->size() && !block->at(nodeIndex)->codeOrigin.isSet(); nodeIndex++) { }
VALIDATE((block), nodeIndex < block->size());
for (; nodeIndex < block->size(); nodeIndex++)
- VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->origin.forExit.isSet());
+ VALIDATE((block->at(nodeIndex)), block->at(nodeIndex)->codeOrigin.isSet());
for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
Node* node = block->at(nodeIndex);
switch (node->op()) {
case Phi:
- VALIDATE((node), !node->origin.forExit.isSet());
+ VALIDATE((node), !node->codeOrigin.isSet());
break;
- case GetLocal:
- case SetLocal:
- case GetLocalUnlinked:
- case SetArgument:
- case Phantom:
- VALIDATE((node), !"bad node type for SSA");
- break;
-
default:
// FIXME: Add more things here.
// https://bugs.webkit.org/show_bug.cgi?id=123471
break;
}
- switch (node->op()) {
- case PhantomNewObject:
- case PhantomNewFunction:
- case PhantomCreateActivation:
- case PhantomDirectArguments:
- case PhantomClonedArguments:
- case MovHint:
- case Upsilon:
- case ForwardVarargs:
- case CallForwardVarargs:
- case ConstructForwardVarargs:
- case GetMyArgumentByVal:
- break;
-
- case Check:
- // FIXME: This is probably not correct.
- break;
-
- case PutHint:
- VALIDATE((node), node->child1()->isPhantomAllocation());
- break;
-
- default:
- m_graph.doToChildren(
- node,
- [&] (const Edge& edge) {
- VALIDATE((node), !edge->isPhantomAllocation());
- });
- break;
- }
}
}
}
-
- void validateEdgeWithDoubleResultIfNecessary(Node* node, Edge edge)
- {
- if (!edge->hasDoubleResult())
- return;
-
- if (m_graph.m_planStage < PlanStage::AfterFixup)
- return;
-
- VALIDATE((node, edge), edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepMachineIntUse);
- }
-
+
void checkOperand(
BasicBlock* block, Operands<size_t>& getLocalPositions,
Operands<size_t>& setLocalPositions, VirtualRegister operand)
@@ -613,23 +458,23 @@ private:
void reportValidationContext(VirtualRegister local, BasicBlock* block)
{
if (!block) {
- dataLog(local, " in null Block ");
+ dataLog("r", local, " in null Block ");
return;
}
- dataLog(local, " in Block ", *block);
+ dataLog("r", local, " in Block ", *block);
}
void reportValidationContext(
VirtualRegister local, BasicBlock* sourceBlock, BasicBlock* destinationBlock)
{
- dataLog(local, " in Block ", *sourceBlock, " -> ", *destinationBlock);
+ dataLog("r", local, " in Block ", *sourceBlock, " -> ", *destinationBlock);
}
void reportValidationContext(
VirtualRegister local, BasicBlock* sourceBlock, Node* prevNode)
{
- dataLog(prevNode, " for ", local, " in Block ", *sourceBlock);
+ dataLog(prevNode, " for r", local, " in Block ", *sourceBlock);
}
void reportValidationContext(Node* node, BasicBlock* block)
@@ -652,19 +497,14 @@ private:
{
if (m_graphDumpMode == DontDumpGraph)
return;
- dataLog("\n");
- if (!m_graphDumpBeforePhase.isNull()) {
- dataLog("Before phase:\n");
- dataLog(m_graphDumpBeforePhase);
- }
dataLog("At time of failure:\n");
m_graph.dump();
}
};
-void validate(Graph& graph, GraphDumpMode graphDumpMode, CString graphDumpBeforePhase)
+void validate(Graph& graph, GraphDumpMode graphDumpMode)
{
- Validate validationObject(graph, graphDumpMode, graphDumpBeforePhase);
+ Validate validationObject(graph, graphDumpMode);
validationObject.validate();
}