]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/PolymorphicPutByIdList.h
JavaScriptCore-1097.3.tar.gz
[apple/javascriptcore.git] / bytecode / PolymorphicPutByIdList.h
1 /*
2 * Copyright (C) 2012 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 PolymorphicPutByIdList_h
27 #define PolymorphicPutByIdList_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(JIT)
32
33 #include "CodeOrigin.h"
34 #include "MacroAssembler.h"
35 #include "Opcode.h"
36 #include "PutKind.h"
37 #include "Structure.h"
38 #include <wtf/Vector.h>
39
40 namespace JSC {
41
42 struct StructureStubInfo;
43
44 class PutByIdAccess {
45 public:
46 enum AccessType {
47 Invalid,
48 Transition,
49 Replace
50 };
51
52 PutByIdAccess()
53 : m_type(Invalid)
54 {
55 }
56
57 static PutByIdAccess transition(
58 JSGlobalData& globalData,
59 JSCell* owner,
60 Structure* oldStructure,
61 Structure* newStructure,
62 StructureChain* chain,
63 MacroAssemblerCodeRef stubRoutine)
64 {
65 PutByIdAccess result;
66 result.m_type = Transition;
67 result.m_oldStructure.set(globalData, owner, oldStructure);
68 result.m_newStructure.set(globalData, owner, newStructure);
69 result.m_chain.set(globalData, owner, chain);
70 result.m_stubRoutine = stubRoutine;
71 return result;
72 }
73
74 static PutByIdAccess replace(
75 JSGlobalData& globalData,
76 JSCell* owner,
77 Structure* structure,
78 MacroAssemblerCodeRef stubRoutine)
79 {
80 PutByIdAccess result;
81 result.m_type = Replace;
82 result.m_oldStructure.set(globalData, owner, structure);
83 result.m_stubRoutine = stubRoutine;
84 return result;
85 }
86
87 static PutByIdAccess fromStructureStubInfo(
88 StructureStubInfo&,
89 MacroAssemblerCodePtr initialSlowPath);
90
91 bool isSet() const { return m_type != Invalid; }
92 bool operator!() const { return !isSet(); }
93
94 AccessType type() const { return m_type; }
95
96 bool isTransition() const { return m_type == Transition; }
97 bool isReplace() const { return m_type == Replace; }
98
99 Structure* oldStructure() const
100 {
101 // Using this instead of isSet() to make this assertion robust against the possibility
102 // of additional access types being added.
103 ASSERT(isTransition() || isReplace());
104
105 return m_oldStructure.get();
106 }
107
108 Structure* structure() const
109 {
110 ASSERT(isReplace());
111 return m_oldStructure.get();
112 }
113
114 Structure* newStructure() const
115 {
116 ASSERT(isTransition());
117 return m_newStructure.get();
118 }
119
120 StructureChain* chain() const
121 {
122 ASSERT(isTransition());
123 return m_chain.get();
124 }
125
126 MacroAssemblerCodeRef stubRoutine() const
127 {
128 ASSERT(isTransition() || isReplace());
129 return m_stubRoutine;
130 }
131
132 bool visitWeak() const;
133
134 private:
135 AccessType m_type;
136 WriteBarrier<Structure> m_oldStructure;
137 WriteBarrier<Structure> m_newStructure;
138 WriteBarrier<StructureChain> m_chain;
139 MacroAssemblerCodeRef m_stubRoutine;
140 };
141
142 class PolymorphicPutByIdList {
143 WTF_MAKE_FAST_ALLOCATED;
144 public:
145 // Initialize from a stub info; this will place one element in the list and it will
146 // be created by converting the stub info's put by id access information into our
147 // PutByIdAccess.
148 PolymorphicPutByIdList(
149 PutKind,
150 StructureStubInfo&,
151 MacroAssemblerCodePtr initialSlowPath);
152
153 // Either creates a new polymorphic put list, or returns the one that is already
154 // in place.
155 static PolymorphicPutByIdList* from(
156 PutKind,
157 StructureStubInfo&,
158 MacroAssemblerCodePtr initialSlowPath);
159
160 ~PolymorphicPutByIdList();
161
162 MacroAssemblerCodePtr currentSlowPathTarget() const
163 {
164 return m_list.last().stubRoutine().code();
165 }
166
167 void addAccess(const PutByIdAccess&);
168
169 bool isEmpty() const { return m_list.isEmpty(); }
170 unsigned size() const { return m_list.size(); }
171 bool isFull() const;
172 bool isAlmostFull() const; // True if adding an element would make isFull() true.
173 const PutByIdAccess& at(unsigned i) const { return m_list[i]; }
174 const PutByIdAccess& operator[](unsigned i) const { return m_list[i]; }
175
176 PutKind kind() const { return m_kind; }
177
178 bool visitWeak() const;
179
180 private:
181 Vector<PutByIdAccess, 2> m_list;
182 PutKind m_kind;
183 };
184
185 } // namespace JSC
186
187 #endif // ENABLE(JIT)
188
189 #endif // PolymorphicPutByIdList_h
190