1/*
2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef DFGAvailability_h
27#define DFGAvailability_h
28
29#if ENABLE(DFG_JIT)
30
31#include "DFGFlushedAt.h"
32#include "DFGVariableAccessData.h"
33
34namespace JSC { namespace DFG {
35
36struct Node;
37
38class Availability {
39public:
40    Availability()
41        : m_node(0)
42        , m_flushedAt(DeadFlush)
43    {
44    }
45
46    explicit Availability(Node* node)
47        : m_node(node)
48        , m_flushedAt(ConflictingFlush)
49    {
50    }
51
52    explicit Availability(FlushedAt flushedAt)
53        : m_node(unavailableMarker())
54        , m_flushedAt(flushedAt)
55    {
56    }
57
58    Availability(Node* node, FlushedAt flushedAt)
59        : m_node(node)
60        , m_flushedAt(flushedAt)
61    {
62    }
63
64    static Availability unavailable()
65    {
66        return Availability(unavailableMarker(), FlushedAt(ConflictingFlush));
67    }
68
69    Availability withFlush(FlushedAt flush) const
70    {
71        return Availability(m_node, flush);
72    }
73
74    Availability withNode(Node* node) const
75    {
76        return Availability(node, m_flushedAt);
77    }
78
79    Availability withUnavailableNode() const
80    {
81        return withNode(unavailableMarker());
82    }
83
84    bool nodeIsUndecided() const { return !m_node; }
85    bool nodeIsUnavailable() const { return m_node == unavailableMarker(); }
86
87    bool hasNode() const { return !nodeIsUndecided() && !nodeIsUnavailable(); }
88
89    Node* node() const
90    {
91        ASSERT(!nodeIsUndecided());
92        ASSERT(!nodeIsUnavailable());
93        return m_node;
94    }
95
96    FlushedAt flushedAt() const { return m_flushedAt; }
97
98    bool operator!() const { return nodeIsUnavailable() && flushedAt().format() == ConflictingFlush; }
99
100    bool operator==(const Availability& other) const
101    {
102        return m_node == other.m_node
103            && m_flushedAt == other.m_flushedAt;
104    }
105
106    Availability merge(const Availability& other) const
107    {
108        return Availability(
109            mergeNodes(m_node, other.m_node),
110            m_flushedAt.merge(other.m_flushedAt));
111    }
112
113    void dump(PrintStream&) const;
114    void dumpInContext(PrintStream&, DumpContext*) const;
115
116private:
117    static Node* mergeNodes(Node* a, Node* b)
118    {
119        if (!a)
120            return b;
121        if (!b)
122            return a;
123        if (a == b)
124            return a;
125        return unavailableMarker();
126    }
127
128    static Node* unavailableMarker()
129    {
130        return bitwise_cast<Node*>(static_cast<intptr_t>(1));
131    }
132
133    Node* m_node;
134    FlushedAt m_flushedAt;
135};
136
137} } // namespace JSC::DFG
138
139#endif // ENABLE(DFG_JIT)
140
141#endif // DFGAvailability_h
142
143