]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSCellInlines.h
JavaScriptCore-7600.1.4.15.12.tar.gz
[apple/javascriptcore.git] / runtime / JSCellInlines.h
1 /*
2 * Copyright (C) 2012, 2013 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 JSCellInlines_h
27 #define JSCellInlines_h
28
29 #include "CallFrame.h"
30 #include "DeferGC.h"
31 #include "Handle.h"
32 #include "JSCell.h"
33 #include "JSObject.h"
34 #include "JSString.h"
35 #include "Structure.h"
36 #include <wtf/CompilationThread.h>
37
38 namespace JSC {
39
40 inline JSCell::JSCell(CreatingEarlyCellTag)
41 : m_gcData(NotMarked)
42 {
43 ASSERT(!isCompilationThread());
44 }
45
46 inline JSCell::JSCell(VM&, Structure* structure)
47 : m_structureID(structure->id())
48 , m_indexingType(structure->indexingType())
49 , m_type(structure->typeInfo().type())
50 , m_flags(structure->typeInfo().inlineTypeFlags())
51 , m_gcData(NotMarked)
52 {
53 ASSERT(!isCompilationThread());
54 }
55
56 inline void JSCell::finishCreation(VM& vm)
57 {
58 #if ENABLE(GC_VALIDATION)
59 ASSERT(vm.isInitializingObject());
60 vm.setInitializingObjectClass(0);
61 #else
62 UNUSED_PARAM(vm);
63 #endif
64 ASSERT(m_structureID);
65 }
66
67 inline void JSCell::finishCreation(VM& vm, Structure* structure, CreatingEarlyCellTag)
68 {
69 #if ENABLE(GC_VALIDATION)
70 ASSERT(vm.isInitializingObject());
71 vm.setInitializingObjectClass(0);
72 if (structure) {
73 #endif
74 m_structureID = structure->id();
75 m_indexingType = structure->indexingType();
76 m_type = structure->typeInfo().type();
77 m_flags = structure->typeInfo().inlineTypeFlags();
78 #if ENABLE(GC_VALIDATION)
79 }
80 #else
81 UNUSED_PARAM(vm);
82 #endif
83 // Very first set of allocations won't have a real structure.
84 ASSERT(m_structureID || !vm.structureStructure);
85 }
86
87 inline JSType JSCell::type() const
88 {
89 return m_type;
90 }
91
92 inline IndexingType JSCell::indexingType() const
93 {
94 return m_indexingType;
95 }
96
97 inline Structure* JSCell::structure() const
98 {
99 return Heap::heap(this)->structureIDTable().get(m_structureID);
100 }
101
102 inline Structure* JSCell::structure(VM& vm) const
103 {
104 return vm.heap.structureIDTable().get(m_structureID);
105 }
106
107 inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
108 {
109 Structure* structure = cell->structure(visitor.vm());
110 visitor.appendUnbarrieredPointer(&structure);
111 }
112
113 template<typename T>
114 void* allocateCell(Heap& heap, size_t size)
115 {
116 ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
117 ASSERT(size >= sizeof(T));
118 JSCell* result = 0;
119 if (T::needsDestruction && T::hasImmortalStructure)
120 result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
121 else if (T::needsDestruction)
122 result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
123 else
124 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
125 #if ENABLE(GC_VALIDATION)
126 ASSERT(!heap.vm()->isInitializingObject());
127 heap.vm()->setInitializingObjectClass(T::info());
128 #endif
129 result->clearStructure();
130 return result;
131 }
132
133 template<typename T>
134 void* allocateCell(Heap& heap)
135 {
136 return allocateCell<T>(heap, sizeof(T));
137 }
138
139 inline bool isZapped(const JSCell* cell)
140 {
141 return cell->isZapped();
142 }
143
144 inline bool JSCell::isObject() const
145 {
146 return TypeInfo::isObject(m_type);
147 }
148
149 inline bool JSCell::isString() const
150 {
151 return m_type == StringType;
152 }
153
154 inline bool JSCell::isGetterSetter() const
155 {
156 return m_type == GetterSetterType;
157 }
158
159 inline bool JSCell::isCustomGetterSetter() const
160 {
161 return m_type == CustomGetterSetterType;
162 }
163
164 inline bool JSCell::isProxy() const
165 {
166 return m_type == ImpureProxyType || m_type == PureForwardingProxyType;
167 }
168
169 inline bool JSCell::isAPIValueWrapper() const
170 {
171 return m_type == APIValueWrapperType;
172 }
173
174 inline void JSCell::setStructure(VM& vm, Structure* structure)
175 {
176 ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
177 ASSERT(structure->classInfo() == this->structure()->classInfo());
178 ASSERT(!this->structure()
179 || this->structure()->transitionWatchpointSetHasBeenInvalidated()
180 || Heap::heap(this)->structureIDTable().get(structure->id()) == structure);
181 vm.heap.writeBarrier(this, structure);
182 m_structureID = structure->id();
183 m_flags = structure->typeInfo().inlineTypeFlags();
184 m_type = structure->typeInfo().type();
185 m_indexingType = structure->indexingType();
186 }
187
188 inline const MethodTable* JSCell::methodTable() const
189 {
190 VM& vm = *Heap::heap(this)->vm();
191 Structure* structure = this->structure(vm);
192 if (Structure* rootStructure = structure->structure(vm))
193 RELEASE_ASSERT(rootStructure == rootStructure->structure(vm));
194
195 return &structure->classInfo()->methodTable;
196 }
197
198 inline const MethodTable* JSCell::methodTable(VM& vm) const
199 {
200 Structure* structure = this->structure(vm);
201 if (Structure* rootStructure = structure->structure(vm))
202 RELEASE_ASSERT(rootStructure == rootStructure->structure(vm));
203
204 return &structure->classInfo()->methodTable;
205 }
206
207 inline bool JSCell::inherits(const ClassInfo* info) const
208 {
209 return classInfo()->isSubClassOf(info);
210 }
211
212 // Fast call to get a property where we may not yet have converted the string to an
213 // identifier. The first time we perform a property access with a given string, try
214 // performing the property map lookup without forming an identifier. We detect this
215 // case by checking whether the hash has yet been set for this string.
216 ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(VM& vm, Structure& structure, const String& name)
217 {
218 ASSERT(canUseFastGetOwnProperty(structure));
219 PropertyOffset offset = name.impl()->hasHash()
220 ? structure.get(vm, Identifier(&vm, name))
221 : structure.get(vm, name);
222 if (offset != invalidOffset)
223 return asObject(this)->locationForOffset(offset)->get();
224 return JSValue();
225 }
226
227 inline bool JSCell::canUseFastGetOwnProperty(const Structure& structure)
228 {
229 return !structure.hasGetterSetterProperties()
230 && !structure.hasCustomGetterSetterProperties()
231 && !structure.typeInfo().overridesGetOwnPropertySlot();
232 }
233
234 inline bool JSCell::toBoolean(ExecState* exec) const
235 {
236 if (isString())
237 return static_cast<const JSString*>(this)->toBoolean();
238 return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
239 }
240
241 inline TriState JSCell::pureToBoolean() const
242 {
243 if (isString())
244 return static_cast<const JSString*>(this)->toBoolean() ? TrueTriState : FalseTriState;
245 return MixedTriState;
246 }
247
248 } // namespace JSC
249
250 #endif // JSCellInlines_h