60b632d52b44921bb3d3b0d642be2b466ba1f1b1
[WebKit-https.git] / Source / JavaScriptCore / 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