]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSCellInlines.h
2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef JSCellInlines_h
27 #define JSCellInlines_h
29 #include "CallFrame.h"
35 #include "Structure.h"
36 #include <wtf/CompilationThread.h>
40 inline JSCell::JSCell(CreatingEarlyCellTag
)
43 ASSERT(!isCompilationThread());
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())
53 ASSERT(!isCompilationThread());
56 inline void JSCell::finishCreation(VM
& vm
)
58 #if ENABLE(GC_VALIDATION)
59 ASSERT(vm
.isInitializingObject());
60 vm
.setInitializingObjectClass(0);
64 ASSERT(m_structureID
);
67 inline void JSCell::finishCreation(VM
& vm
, Structure
* structure
, CreatingEarlyCellTag
)
69 #if ENABLE(GC_VALIDATION)
70 ASSERT(vm
.isInitializingObject());
71 vm
.setInitializingObjectClass(0);
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)
83 // Very first set of allocations won't have a real structure.
84 ASSERT(m_structureID
|| !vm
.structureStructure
);
87 inline JSType
JSCell::type() const
92 inline IndexingType
JSCell::indexingType() const
94 return m_indexingType
;
97 inline Structure
* JSCell::structure() const
99 return Heap::heap(this)->structureIDTable().get(m_structureID
);
102 inline Structure
* JSCell::structure(VM
& vm
) const
104 return vm
.heap
.structureIDTable().get(m_structureID
);
107 inline void JSCell::visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
109 Structure
* structure
= cell
->structure(visitor
.vm());
110 visitor
.appendUnbarrieredPointer(&structure
);
114 void* allocateCell(Heap
& heap
, size_t size
)
116 ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
117 ASSERT(size
>= sizeof(T
));
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
));
124 result
= static_cast<JSCell
*>(heap
.allocateWithoutDestructor(size
));
125 #if ENABLE(GC_VALIDATION)
126 ASSERT(!heap
.vm()->isInitializingObject());
127 heap
.vm()->setInitializingObjectClass(T::info());
129 result
->clearStructure();
134 void* allocateCell(Heap
& heap
)
136 return allocateCell
<T
>(heap
, sizeof(T
));
139 inline bool isZapped(const JSCell
* cell
)
141 return cell
->isZapped();
144 inline bool JSCell::isObject() const
146 return TypeInfo::isObject(m_type
);
149 inline bool JSCell::isString() const
151 return m_type
== StringType
;
154 inline bool JSCell::isGetterSetter() const
156 return m_type
== GetterSetterType
;
159 inline bool JSCell::isCustomGetterSetter() const
161 return m_type
== CustomGetterSetterType
;
164 inline bool JSCell::isProxy() const
166 return m_type
== ImpureProxyType
|| m_type
== PureForwardingProxyType
;
169 inline bool JSCell::isAPIValueWrapper() const
171 return m_type
== APIValueWrapperType
;
174 inline void JSCell::setStructure(VM
& vm
, Structure
* structure
)
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();
188 inline const MethodTable
* JSCell::methodTable() const
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
));
195 return &structure
->classInfo()->methodTable
;
198 inline const MethodTable
* JSCell::methodTable(VM
& vm
) const
200 Structure
* structure
= this->structure(vm
);
201 if (Structure
* rootStructure
= structure
->structure(vm
))
202 RELEASE_ASSERT(rootStructure
== rootStructure
->structure(vm
));
204 return &structure
->classInfo()->methodTable
;
207 inline bool JSCell::inherits(const ClassInfo
* info
) const
209 return classInfo()->isSubClassOf(info
);
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
)
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();
227 inline bool JSCell::canUseFastGetOwnProperty(const Structure
& structure
)
229 return !structure
.hasGetterSetterProperties()
230 && !structure
.hasCustomGetterSetterProperties()
231 && !structure
.typeInfo().overridesGetOwnPropertySlot();
234 inline bool JSCell::toBoolean(ExecState
* exec
) const
237 return static_cast<const JSString
*>(this)->toBoolean();
238 return !structure()->masqueradesAsUndefined(exec
->lexicalGlobalObject());
241 inline TriState
JSCell::pureToBoolean() const
244 return static_cast<const JSString
*>(this)->toBoolean() ? TrueTriState
: FalseTriState
;
245 return MixedTriState
;
250 #endif // JSCellInlines_h