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