]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/PolymorphicPutByIdList.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / PolymorphicPutByIdList.h
CommitLineData
6fe7ccc8 1/*
81345200 2 * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
6fe7ccc8
A
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
6fe7ccc8
A
29#if ENABLE(JIT)
30
31#include "CodeOrigin.h"
32#include "MacroAssembler.h"
33#include "Opcode.h"
34#include "PutKind.h"
81345200 35#include "PutPropertySlot.h"
6fe7ccc8
A
36#include "Structure.h"
37#include <wtf/Vector.h>
38
39namespace JSC {
40
81345200 41class CodeBlock;
6fe7ccc8
A
42struct StructureStubInfo;
43
44class PutByIdAccess {
45public:
46 enum AccessType {
47 Invalid,
48 Transition,
81345200
A
49 Replace,
50 Setter,
51 CustomSetter
6fe7ccc8
A
52 };
53
54 PutByIdAccess()
55 : m_type(Invalid)
ed1e77d3 56 , m_chainCount(UINT_MAX)
6fe7ccc8
A
57 {
58 }
59
60 static PutByIdAccess transition(
93a37866 61 VM& vm,
6fe7ccc8
A
62 JSCell* owner,
63 Structure* oldStructure,
64 Structure* newStructure,
65 StructureChain* chain,
93a37866 66 PassRefPtr<JITStubRoutine> stubRoutine)
6fe7ccc8
A
67 {
68 PutByIdAccess result;
69 result.m_type = Transition;
93a37866
A
70 result.m_oldStructure.set(vm, owner, oldStructure);
71 result.m_newStructure.set(vm, owner, newStructure);
72 result.m_chain.set(vm, owner, chain);
81345200 73 result.m_customSetter = 0;
6fe7ccc8
A
74 result.m_stubRoutine = stubRoutine;
75 return result;
76 }
81345200 77
6fe7ccc8 78 static PutByIdAccess replace(
93a37866 79 VM& vm,
6fe7ccc8
A
80 JSCell* owner,
81 Structure* structure,
93a37866 82 PassRefPtr<JITStubRoutine> stubRoutine)
6fe7ccc8
A
83 {
84 PutByIdAccess result;
85 result.m_type = Replace;
93a37866 86 result.m_oldStructure.set(vm, owner, structure);
81345200
A
87 result.m_customSetter = 0;
88 result.m_stubRoutine = stubRoutine;
89 return result;
90 }
91
92
93 static PutByIdAccess setter(
94 VM& vm,
95 JSCell* owner,
96 AccessType accessType,
97 Structure* structure,
98 StructureChain* chain,
ed1e77d3 99 unsigned chainCount,
81345200
A
100 PutPropertySlot::PutValueFunc customSetter,
101 PassRefPtr<JITStubRoutine> stubRoutine)
102 {
103 RELEASE_ASSERT(accessType == Setter || accessType == CustomSetter);
104 PutByIdAccess result;
105 result.m_oldStructure.set(vm, owner, structure);
106 result.m_type = accessType;
ed1e77d3 107 if (chain) {
81345200 108 result.m_chain.set(vm, owner, chain);
ed1e77d3
A
109 result.m_chainCount = chainCount;
110 }
81345200 111 result.m_customSetter = customSetter;
6fe7ccc8
A
112 result.m_stubRoutine = stubRoutine;
113 return result;
114 }
115
81345200 116 static PutByIdAccess fromStructureStubInfo(StructureStubInfo&);
6fe7ccc8
A
117
118 bool isSet() const { return m_type != Invalid; }
119 bool operator!() const { return !isSet(); }
120
121 AccessType type() const { return m_type; }
122
123 bool isTransition() const { return m_type == Transition; }
124 bool isReplace() const { return m_type == Replace; }
81345200
A
125 bool isSetter() const { return m_type == Setter; }
126 bool isCustom() const { return m_type == CustomSetter; }
6fe7ccc8
A
127
128 Structure* oldStructure() const
129 {
130 // Using this instead of isSet() to make this assertion robust against the possibility
131 // of additional access types being added.
81345200 132 ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
6fe7ccc8
A
133
134 return m_oldStructure.get();
135 }
136
137 Structure* structure() const
138 {
ed1e77d3 139 ASSERT(isReplace() || isSetter() || isCustom());
6fe7ccc8
A
140 return m_oldStructure.get();
141 }
142
143 Structure* newStructure() const
144 {
145 ASSERT(isTransition());
146 return m_newStructure.get();
147 }
148
149 StructureChain* chain() const
150 {
81345200 151 ASSERT(isTransition() || isSetter() || isCustom());
6fe7ccc8
A
152 return m_chain.get();
153 }
154
ed1e77d3
A
155 unsigned chainCount() const
156 {
157 ASSERT(isSetter() || isCustom());
158 return m_chainCount;
159 }
160
81345200 161 JITStubRoutine* stubRoutine() const
6fe7ccc8 162 {
81345200
A
163 ASSERT(isTransition() || isReplace() || isSetter() || isCustom());
164 return m_stubRoutine.get();
6fe7ccc8 165 }
81345200
A
166
167 PutPropertySlot::PutValueFunc customSetter() const
168 {
169 ASSERT(isCustom());
170 return m_customSetter;
171 }
172
173 bool visitWeak(RepatchBuffer&) const;
6fe7ccc8
A
174
175private:
81345200
A
176 friend class CodeBlock;
177
6fe7ccc8
A
178 AccessType m_type;
179 WriteBarrier<Structure> m_oldStructure;
180 WriteBarrier<Structure> m_newStructure;
181 WriteBarrier<StructureChain> m_chain;
ed1e77d3 182 unsigned m_chainCount;
81345200 183 PutPropertySlot::PutValueFunc m_customSetter;
93a37866 184 RefPtr<JITStubRoutine> m_stubRoutine;
6fe7ccc8
A
185};
186
187class PolymorphicPutByIdList {
188 WTF_MAKE_FAST_ALLOCATED;
189public:
6fe7ccc8
A
190 // Either creates a new polymorphic put list, or returns the one that is already
191 // in place.
81345200 192 static PolymorphicPutByIdList* from(PutKind, StructureStubInfo&);
6fe7ccc8
A
193
194 ~PolymorphicPutByIdList();
195
196 MacroAssemblerCodePtr currentSlowPathTarget() const
197 {
93a37866 198 return m_list.last().stubRoutine()->code().code();
6fe7ccc8
A
199 }
200
201 void addAccess(const PutByIdAccess&);
202
203 bool isEmpty() const { return m_list.isEmpty(); }
204 unsigned size() const { return m_list.size(); }
205 bool isFull() const;
206 bool isAlmostFull() const; // True if adding an element would make isFull() true.
207 const PutByIdAccess& at(unsigned i) const { return m_list[i]; }
208 const PutByIdAccess& operator[](unsigned i) const { return m_list[i]; }
209
210 PutKind kind() const { return m_kind; }
211
81345200 212 bool visitWeak(RepatchBuffer&) const;
6fe7ccc8
A
213
214private:
81345200
A
215 friend class CodeBlock;
216
217 // Initialize from a stub info; this will place one element in the list and it will
218 // be created by converting the stub info's put by id access information into our
219 // PutByIdAccess.
220 PolymorphicPutByIdList(PutKind, StructureStubInfo&);
221
6fe7ccc8
A
222 Vector<PutByIdAccess, 2> m_list;
223 PutKind m_kind;
224};
225
226} // namespace JSC
227
228#endif // ENABLE(JIT)
229
230#endif // PolymorphicPutByIdList_h
231