blob: d1845c0396386520d8735a216e2b8d28be70478d [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#pragma once
#if ENABLE(DFG_JIT)
#include "DFGFlushedAt.h"
#include "DFGVariableAccessData.h"
namespace JSC { namespace DFG {
struct Node;
class Availability {
public:
Availability()
: m_node(0)
, m_flushedAt(DeadFlush)
{
}
explicit Availability(Node* node)
: m_node(node)
, m_flushedAt(ConflictingFlush)
{
}
explicit Availability(FlushedAt flushedAt)
: m_node(unavailableMarker())
, m_flushedAt(flushedAt)
{
}
Availability(Node* node, FlushedAt flushedAt)
: m_node(node)
, m_flushedAt(flushedAt)
{
}
static Availability unavailable()
{
return Availability(unavailableMarker(), FlushedAt(ConflictingFlush));
}
Availability withFlush(FlushedAt flush) const
{
return Availability(m_node, flush);
}
Availability withNode(Node* node) const
{
return Availability(node, m_flushedAt);
}
Availability withUnavailableNode() const
{
return withNode(unavailableMarker());
}
void setFlush(FlushedAt flushedAt)
{
m_flushedAt = flushedAt;
}
void setNode(Node* node)
{
m_node = node;
}
void setNodeUnavailable()
{
m_node = unavailableMarker();
}
bool nodeIsUndecided() const { return !m_node; }
bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
bool shouldUseNode() const { return !isFlushUseful() && hasNode(); }
Node* node() const
{
ASSERT(!nodeIsUndecided());
ASSERT(!nodeIsUnavailable());
return m_node;
}
FlushedAt flushedAt() const { return m_flushedAt; }
bool isFlushUseful() const
{
return flushedAt().format() != DeadFlush && flushedAt().format() != ConflictingFlush;
}
bool isDead() const { return !isFlushUseful() && !hasNode(); }
bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
bool operator==(const Availability& other) const
{
return m_node == other.m_node
&& m_flushedAt == other.m_flushedAt;
}
bool operator!=(const Availability& other) const
{
return !(*this == other);
}
Availability merge(const Availability& other) const
{
return Availability(
mergeNodes(m_node, other.m_node),
m_flushedAt.merge(other.m_flushedAt));
}
void dump(PrintStream&) const;
void dumpInContext(PrintStream&, DumpContext*) const;
private:
static Node* mergeNodes(Node* a, Node* b)
{
if (!a)
return b;
if (!b)
return a;
if (a == b)
return a;
return unavailableMarker();
}
static Node* unavailableMarker()
{
return bitwise_cast<Node*>(static_cast<intptr_t>(1));
}
Node* m_node;
FlushedAt m_flushedAt;
};
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)