]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/StructureTransitionTable.h
5b4f4e63221b83043fd78e7cd167e723cdced22a
[apple/javascriptcore.git] / runtime / StructureTransitionTable.h
1 /*
2 * Copyright (C) 2008, 2009 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 COMPUTER, 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 COMPUTER, 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 StructureTransitionTable_h
27 #define StructureTransitionTable_h
28
29 #include "UString.h"
30 #include <wtf/HashFunctions.h>
31 #include <wtf/HashMap.h>
32 #include <wtf/HashTraits.h>
33 #include <wtf/RefPtr.h>
34
35 namespace JSC {
36
37 class Structure;
38
39 struct StructureTransitionTableHash {
40 typedef std::pair<RefPtr<UString::Rep>, unsigned> Key;
41 static unsigned hash(const Key& p)
42 {
43 return p.first->computedHash();
44 }
45
46 static bool equal(const Key& a, const Key& b)
47 {
48 return a == b;
49 }
50
51 static const bool safeToCompareToEmptyOrDeleted = true;
52 };
53
54 struct StructureTransitionTableHashTraits {
55 typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
56 typedef WTF::GenericHashTraits<unsigned> SecondTraits;
57 typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType;
58
59 static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
60 static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
61
62 static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction;
63
64 static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); }
65 static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
66 };
67
68 class StructureTransitionTable {
69 typedef std::pair<Structure*, Structure*> Transition;
70 typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable;
71 public:
72 // The contains and get methods accept imprecise matches, so if an unspecialised transition exists
73 // for the given key they will consider that transition to be a match. If a specialised transition
74 // exists and it matches the provided specificValue, get will return the specific transition.
75 inline bool contains(const StructureTransitionTableHash::Key&, JSCell* specificValue);
76 inline Structure* get(const StructureTransitionTableHash::Key&, JSCell* specificValue) const;
77 bool hasTransition(const StructureTransitionTableHash::Key& key)
78 {
79 return m_table.contains(key);
80 }
81 void remove(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
82 {
83 TransitionTable::iterator find = m_table.find(key);
84 if (!specificValue)
85 find->second.first = 0;
86 else
87 find->second.second = 0;
88 if (!find->second.first && !find->second.second)
89 m_table.remove(find);
90 }
91 void add(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue)
92 {
93 if (!specificValue) {
94 TransitionTable::iterator find = m_table.find(key);
95 if (find == m_table.end())
96 m_table.add(key, Transition(structure, 0));
97 else
98 find->second.first = structure;
99 } else {
100 // If we're adding a transition to a specific value, then there cannot be
101 // an existing transition
102 ASSERT(!m_table.contains(key));
103 m_table.add(key, Transition(0, structure));
104 }
105
106 }
107 private:
108 TransitionTable m_table;
109 };
110
111 } // namespace JSC
112
113 #endif // StructureTransitionTable_h