]>
Commit | Line | Data |
---|---|---|
9dae56ea | 1 | /* |
f9bf01c6 | 2 | * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. |
9dae56ea 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 COMPUTER, 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 COMPUTER, 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 Structure_h | |
27 | #define Structure_h | |
28 | ||
6fe7ccc8 | 29 | #include "ClassInfo.h" |
9dae56ea | 30 | #include "Identifier.h" |
14957cd0 | 31 | #include "JSCell.h" |
9dae56ea A |
32 | #include "JSType.h" |
33 | #include "JSValue.h" | |
34 | #include "PropertyMapHashTable.h" | |
f9bf01c6 A |
35 | #include "PropertyNameArray.h" |
36 | #include "Protect.h" | |
9dae56ea | 37 | #include "StructureTransitionTable.h" |
f9bf01c6 | 38 | #include "JSTypeInfo.h" |
9dae56ea | 39 | #include "UString.h" |
14957cd0 A |
40 | #include "Weak.h" |
41 | #include <wtf/PassOwnPtr.h> | |
9dae56ea A |
42 | #include <wtf/PassRefPtr.h> |
43 | #include <wtf/RefCounted.h> | |
44 | ||
9dae56ea A |
45 | |
46 | namespace JSC { | |
47 | ||
6fe7ccc8 | 48 | class LLIntOffsetsExtractor; |
9dae56ea A |
49 | class PropertyNameArray; |
50 | class PropertyNameArrayData; | |
14957cd0 | 51 | class StructureChain; |
6fe7ccc8 A |
52 | class SlotVisitor; |
53 | class JSString; | |
f9bf01c6 | 54 | |
14957cd0 | 55 | class Structure : public JSCell { |
9dae56ea | 56 | public: |
f9bf01c6 | 57 | friend class StructureTransitionTable; |
6fe7ccc8 A |
58 | |
59 | typedef JSCell Base; | |
60 | ||
61 | static Structure* create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo) | |
9dae56ea | 62 | { |
14957cd0 A |
63 | ASSERT(globalData.structureStructure); |
64 | ASSERT(classInfo); | |
6fe7ccc8 A |
65 | Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo); |
66 | structure->finishCreation(globalData); | |
67 | return structure; | |
9dae56ea A |
68 | } |
69 | ||
6fe7ccc8 A |
70 | protected: |
71 | void finishCreation(JSGlobalData& globalData) | |
72 | { | |
73 | Base::finishCreation(globalData); | |
74 | ASSERT(m_prototype); | |
75 | ASSERT(m_prototype.isObject() || m_prototype.isNull()); | |
76 | } | |
77 | ||
78 | void finishCreation(JSGlobalData& globalData, CreatingEarlyCellTag) | |
79 | { | |
80 | Base::finishCreation(globalData, this, CreatingEarlyCell); | |
81 | ASSERT(m_prototype); | |
82 | ASSERT(m_prototype.isNull()); | |
83 | ASSERT(!globalData.structureStructure); | |
84 | } | |
85 | ||
86 | public: | |
9dae56ea A |
87 | static void dumpStatistics(); |
88 | ||
6fe7ccc8 A |
89 | JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); |
90 | JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset); | |
14957cd0 | 91 | static Structure* removePropertyTransition(JSGlobalData&, Structure*, const Identifier& propertyName, size_t& offset); |
6fe7ccc8 A |
92 | JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype); |
93 | JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, const Identifier&); | |
94 | static Structure* attributeChangeTransition(JSGlobalData&, Structure*, const Identifier& propertyName, unsigned attributes); | |
14957cd0 A |
95 | static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*); |
96 | static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*); | |
97 | static Structure* sealTransition(JSGlobalData&, Structure*); | |
98 | static Structure* freezeTransition(JSGlobalData&, Structure*); | |
99 | static Structure* preventExtensionsTransition(JSGlobalData&, Structure*); | |
100 | ||
101 | bool isSealed(JSGlobalData&); | |
102 | bool isFrozen(JSGlobalData&); | |
103 | bool isExtensible() const { return !m_preventExtensions; } | |
104 | bool didTransition() const { return m_didTransition; } | |
6fe7ccc8 A |
105 | bool shouldGrowPropertyStorage() { return propertyStorageCapacity() == propertyStorageSize(); } |
106 | JS_EXPORT_PRIVATE size_t suggestedNewPropertyStorageSize(); | |
14957cd0 A |
107 | |
108 | Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*); | |
9dae56ea | 109 | |
6fe7ccc8 | 110 | static void destroy(JSCell*); |
9dae56ea | 111 | |
9dae56ea | 112 | // These should be used with caution. |
6fe7ccc8 | 113 | JS_EXPORT_PRIVATE size_t addPropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue); |
14957cd0 A |
114 | size_t removePropertyWithoutTransition(JSGlobalData&, const Identifier& propertyName); |
115 | void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); } | |
ba379fdc A |
116 | |
117 | bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; } | |
118 | bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; } | |
9dae56ea | 119 | |
6fe7ccc8 | 120 | // Type accessors. |
14957cd0 | 121 | const TypeInfo& typeInfo() const { ASSERT(structure()->classInfo() == &s_info); return m_typeInfo; } |
6fe7ccc8 | 122 | bool isObject() const { return typeInfo().isObject(); } |
9dae56ea | 123 | |
6fe7ccc8 A |
124 | |
125 | JSGlobalObject* globalObject() const { return m_globalObject.get(); } | |
126 | void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); } | |
127 | ||
14957cd0 | 128 | JSValue storedPrototype() const { return m_prototype.get(); } |
ba379fdc | 129 | JSValue prototypeForLookup(ExecState*) const; |
9dae56ea | 130 | StructureChain* prototypeChain(ExecState*) const; |
6fe7ccc8 | 131 | static void visitChildren(JSCell*, SlotVisitor&); |
9dae56ea | 132 | |
14957cd0 | 133 | Structure* previousID() const { ASSERT(structure()->classInfo() == &s_info); return m_previous.get(); } |
6fe7ccc8 | 134 | bool transitivelyTransitionedFrom(Structure* structureToFind); |
9dae56ea A |
135 | |
136 | void growPropertyStorageCapacity(); | |
14957cd0 | 137 | unsigned propertyStorageCapacity() const { ASSERT(structure()->classInfo() == &s_info); return m_propertyStorageCapacity; } |
6fe7ccc8 | 138 | unsigned propertyStorageSize() const { ASSERT(structure()->classInfo() == &s_info); return (m_propertyTable ? m_propertyTable->propertyStorageSize() : static_cast<unsigned>(m_offset + 1)); } |
ba379fdc | 139 | bool isUsingInlineStorage() const; |
9dae56ea | 140 | |
14957cd0 | 141 | size_t get(JSGlobalData&, const Identifier& propertyName); |
6fe7ccc8 A |
142 | size_t get(JSGlobalData&, const UString& name); |
143 | JS_EXPORT_PRIVATE size_t get(JSGlobalData&, StringImpl* propertyName, unsigned& attributes, JSCell*& specificValue); | |
14957cd0 | 144 | size_t get(JSGlobalData& globalData, const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) |
ba379fdc A |
145 | { |
146 | ASSERT(!propertyName.isNull()); | |
14957cd0 A |
147 | ASSERT(structure()->classInfo() == &s_info); |
148 | return get(globalData, propertyName.impl(), attributes, specificValue); | |
ba379fdc A |
149 | } |
150 | ||
9dae56ea | 151 | bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } |
6fe7ccc8 A |
152 | bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; } |
153 | void setHasGetterSetterProperties(bool is__proto__) | |
154 | { | |
155 | m_hasGetterSetterProperties = true; | |
156 | if (!is__proto__) | |
157 | m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true; | |
158 | } | |
159 | void setContainsReadOnlyProperties() | |
160 | { | |
161 | m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true; | |
162 | } | |
9dae56ea | 163 | |
f9bf01c6 | 164 | bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } |
f9bf01c6 | 165 | |
14957cd0 | 166 | bool isEmpty() const { return m_propertyTable ? m_propertyTable->isEmpty() : m_offset == noOffset; } |
9dae56ea | 167 | |
6fe7ccc8 | 168 | JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, const Identifier& propertyName); |
f9bf01c6 | 169 | void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; } |
9dae56ea | 170 | |
14957cd0 | 171 | void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. |
f9bf01c6 | 172 | JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h. |
6fe7ccc8 A |
173 | void getPropertyNamesFromStructure(JSGlobalData&, PropertyNameArray&, EnumerationMode); |
174 | ||
175 | JSString* objectToStringValue() { return m_objectToStringValue.get(); } | |
176 | ||
177 | void setObjectToStringValue(JSGlobalData& globalData, const JSCell* owner, JSString* value) | |
178 | { | |
179 | m_objectToStringValue.set(globalData, owner, value); | |
180 | } | |
181 | ||
182 | bool staticFunctionsReified() | |
183 | { | |
184 | return m_staticFunctionReified; | |
185 | } | |
186 | ||
187 | void setStaticFunctionsReified() | |
188 | { | |
189 | m_staticFunctionReified = true; | |
190 | } | |
14957cd0 A |
191 | |
192 | const ClassInfo* classInfo() const { return m_classInfo; } | |
193 | ||
194 | static ptrdiff_t prototypeOffset() | |
195 | { | |
196 | return OBJECT_OFFSETOF(Structure, m_prototype); | |
197 | } | |
198 | ||
199 | static ptrdiff_t typeInfoFlagsOffset() | |
200 | { | |
201 | return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset(); | |
202 | } | |
203 | ||
204 | static ptrdiff_t typeInfoTypeOffset() | |
205 | { | |
206 | return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset(); | |
207 | } | |
208 | ||
209 | static Structure* createStructure(JSGlobalData& globalData) | |
210 | { | |
211 | ASSERT(!globalData.structureStructure); | |
6fe7ccc8 A |
212 | Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData); |
213 | structure->finishCreation(globalData, CreatingEarlyCell); | |
214 | return structure; | |
14957cd0 | 215 | } |
f9bf01c6 | 216 | |
14957cd0 A |
217 | static JS_EXPORTDATA const ClassInfo s_info; |
218 | ||
ba379fdc | 219 | private: |
6fe7ccc8 A |
220 | friend class LLIntOffsetsExtractor; |
221 | ||
222 | JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*); | |
14957cd0 A |
223 | Structure(JSGlobalData&); |
224 | Structure(JSGlobalData&, const Structure*); | |
f9bf01c6 | 225 | |
14957cd0 A |
226 | static Structure* create(JSGlobalData& globalData, const Structure* structure) |
227 | { | |
228 | ASSERT(globalData.structureStructure); | |
6fe7ccc8 A |
229 | Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure); |
230 | newStructure->finishCreation(globalData); | |
231 | return newStructure; | |
14957cd0 | 232 | } |
ba379fdc A |
233 | |
234 | typedef enum { | |
235 | NoneDictionaryKind = 0, | |
236 | CachedDictionaryKind = 1, | |
237 | UncachedDictionaryKind = 2 | |
238 | } DictionaryKind; | |
14957cd0 | 239 | static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind); |
ba379fdc | 240 | |
14957cd0 | 241 | size_t putSpecificValue(JSGlobalData&, const Identifier& propertyName, unsigned attributes, JSCell* specificValue); |
9dae56ea | 242 | size_t remove(const Identifier& propertyName); |
9dae56ea | 243 | |
14957cd0 | 244 | void createPropertyMap(unsigned keyCount = 0); |
9dae56ea A |
245 | void checkConsistency(); |
246 | ||
14957cd0 A |
247 | bool despecifyFunction(JSGlobalData&, const Identifier&); |
248 | void despecifyAllFunctions(JSGlobalData&); | |
ba379fdc | 249 | |
14957cd0 | 250 | PassOwnPtr<PropertyTable> copyPropertyTable(JSGlobalData&, Structure* owner); |
6fe7ccc8 A |
251 | PassOwnPtr<PropertyTable> copyPropertyTableForPinning(JSGlobalData&, Structure* owner); |
252 | JS_EXPORT_PRIVATE void materializePropertyMap(JSGlobalData&); | |
14957cd0 | 253 | void materializePropertyMapIfNecessary(JSGlobalData& globalData) |
9dae56ea | 254 | { |
14957cd0 A |
255 | ASSERT(structure()->classInfo() == &s_info); |
256 | if (!m_propertyTable && m_previous) | |
257 | materializePropertyMap(globalData); | |
9dae56ea | 258 | } |
6fe7ccc8 A |
259 | void materializePropertyMapIfNecessaryForPinning(JSGlobalData& globalData) |
260 | { | |
261 | ASSERT(structure()->classInfo() == &s_info); | |
262 | if (!m_propertyTable) | |
263 | materializePropertyMap(globalData); | |
264 | } | |
9dae56ea | 265 | |
6fe7ccc8 | 266 | int transitionCount() const |
9dae56ea A |
267 | { |
268 | // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both. | |
269 | return m_offset == noOffset ? 0 : m_offset + 1; | |
270 | } | |
4e4e5a6f | 271 | |
9dae56ea | 272 | bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const; |
6fe7ccc8 A |
273 | |
274 | void pin(); | |
9dae56ea | 275 | |
6fe7ccc8 | 276 | static const int s_maxTransitionLength = 64; |
9dae56ea | 277 | |
6fe7ccc8 | 278 | static const int noOffset = -1; |
9dae56ea | 279 | |
f9bf01c6 A |
280 | static const unsigned maxSpecificFunctionThrashCount = 3; |
281 | ||
9dae56ea | 282 | TypeInfo m_typeInfo; |
6fe7ccc8 A |
283 | |
284 | WriteBarrier<JSGlobalObject> m_globalObject; | |
14957cd0 A |
285 | WriteBarrier<Unknown> m_prototype; |
286 | mutable WriteBarrier<StructureChain> m_cachedPrototypeChain; | |
9dae56ea | 287 | |
14957cd0 A |
288 | WriteBarrier<Structure> m_previous; |
289 | RefPtr<StringImpl> m_nameInPrevious; | |
290 | WriteBarrier<JSCell> m_specificValueInPrevious; | |
9dae56ea | 291 | |
14957cd0 | 292 | const ClassInfo* m_classInfo; |
9dae56ea | 293 | |
14957cd0 | 294 | StructureTransitionTable m_transitionTable; |
9dae56ea | 295 | |
14957cd0 A |
296 | WriteBarrier<JSPropertyNameIterator> m_enumerationCache; |
297 | ||
298 | OwnPtr<PropertyTable> m_propertyTable; | |
9dae56ea | 299 | |
f9bf01c6 A |
300 | uint32_t m_propertyStorageCapacity; |
301 | ||
6fe7ccc8 A |
302 | WriteBarrier<JSString> m_objectToStringValue; |
303 | ||
f9bf01c6 | 304 | // m_offset does not account for anonymous slots |
6fe7ccc8 | 305 | int m_offset; |
9dae56ea | 306 | |
ba379fdc | 307 | unsigned m_dictionaryKind : 2; |
9dae56ea A |
308 | bool m_isPinnedPropertyTable : 1; |
309 | bool m_hasGetterSetterProperties : 1; | |
6fe7ccc8 | 310 | bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1; |
f9bf01c6 | 311 | bool m_hasNonEnumerableProperties : 1; |
ba379fdc | 312 | unsigned m_attributesInPrevious : 7; |
f9bf01c6 | 313 | unsigned m_specificFunctionThrashCount : 2; |
14957cd0 A |
314 | unsigned m_preventExtensions : 1; |
315 | unsigned m_didTransition : 1; | |
6fe7ccc8 | 316 | unsigned m_staticFunctionReified; |
9dae56ea A |
317 | }; |
318 | ||
14957cd0 | 319 | inline size_t Structure::get(JSGlobalData& globalData, const Identifier& propertyName) |
9dae56ea | 320 | { |
14957cd0 A |
321 | ASSERT(structure()->classInfo() == &s_info); |
322 | materializePropertyMapIfNecessary(globalData); | |
9dae56ea | 323 | if (!m_propertyTable) |
14957cd0 | 324 | return notFound; |
9dae56ea | 325 | |
14957cd0 | 326 | PropertyMapEntry* entry = m_propertyTable->find(propertyName.impl()).first; |
14957cd0 A |
327 | return entry ? entry->offset : notFound; |
328 | } | |
9dae56ea | 329 | |
6fe7ccc8 A |
330 | inline size_t Structure::get(JSGlobalData& globalData, const UString& name) |
331 | { | |
332 | ASSERT(structure()->classInfo() == &s_info); | |
333 | materializePropertyMapIfNecessary(globalData); | |
334 | if (!m_propertyTable) | |
335 | return notFound; | |
336 | ||
337 | PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first; | |
338 | return entry ? entry->offset : notFound; | |
339 | } | |
340 | ||
14957cd0 A |
341 | inline bool JSCell::isObject() const |
342 | { | |
6fe7ccc8 | 343 | return m_structure->isObject(); |
14957cd0 | 344 | } |
9dae56ea | 345 | |
14957cd0 A |
346 | inline bool JSCell::isString() const |
347 | { | |
348 | return m_structure->typeInfo().type() == StringType; | |
349 | } | |
9dae56ea | 350 | |
6fe7ccc8 | 351 | inline bool JSCell::isGetterSetter() const |
14957cd0 | 352 | { |
6fe7ccc8 | 353 | return m_structure->typeInfo().type() == GetterSetterType; |
14957cd0 | 354 | } |
9dae56ea | 355 | |
6fe7ccc8 | 356 | inline bool JSCell::isAPIValueWrapper() const |
14957cd0 | 357 | { |
6fe7ccc8 | 358 | return m_structure->typeInfo().type() == APIValueWrapperType; |
14957cd0 | 359 | } |
9dae56ea | 360 | |
6fe7ccc8 | 361 | inline void JSCell::setStructure(JSGlobalData& globalData, Structure* structure) |
14957cd0 | 362 | { |
6fe7ccc8 A |
363 | ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren()); |
364 | ASSERT(structure->classInfo() == m_structure->classInfo()); | |
365 | m_structure.set(globalData, this, structure); | |
366 | } | |
367 | ||
368 | inline const ClassInfo* JSCell::validatedClassInfo() const | |
369 | { | |
370 | #if ENABLE(GC_VALIDATION) | |
371 | ASSERT(m_structure.unvalidatedGet()->classInfo() == m_classInfo); | |
372 | #else | |
373 | ASSERT(m_structure->classInfo() == m_classInfo); | |
374 | #endif | |
375 | return m_classInfo; | |
14957cd0 | 376 | } |
9dae56ea | 377 | |
14957cd0 A |
378 | ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell) |
379 | { | |
380 | ASSERT(!m_isCheckingForDefaultMarkViolation); | |
6fe7ccc8 A |
381 | #if ENABLE(GC_VALIDATION) |
382 | validate(cell); | |
383 | #endif | |
384 | m_visitCount++; | |
385 | if (Heap::testAndSetMarked(cell) || !cell->structure()) | |
14957cd0 | 386 | return; |
6fe7ccc8 A |
387 | |
388 | // Should never attempt to mark something that is zapped. | |
389 | ASSERT(!cell->isZapped()); | |
390 | ||
391 | m_stack.append(cell); | |
14957cd0 | 392 | } |
9dae56ea | 393 | |
14957cd0 A |
394 | inline StructureTransitionTable::Hash::Key StructureTransitionTable::keyForWeakGCMapFinalizer(void*, Structure* structure) |
395 | { | |
396 | // Newer versions of the STL have an std::make_pair function that takes rvalue references. | |
397 | // When either of the parameters are bitfields, the C++ compiler will try to bind them as lvalues, which is invalid. To work around this, use unary "+" to make the parameter an rvalue. | |
398 | // See https://bugs.webkit.org/show_bug.cgi?id=59261 for more details. | |
399 | return Hash::Key(structure->m_nameInPrevious.get(), +structure->m_attributesInPrevious); | |
9dae56ea A |
400 | } |
401 | ||
6fe7ccc8 A |
402 | inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind) |
403 | { | |
404 | for (Structure* current = this; current; current = current->previousID()) { | |
405 | if (current == structureToFind) | |
406 | return true; | |
407 | } | |
408 | return false; | |
409 | } | |
410 | ||
411 | inline JSCell::JSCell(JSGlobalData& globalData, Structure* structure) | |
412 | : m_classInfo(structure->classInfo()) | |
413 | , m_structure(globalData, this, structure) | |
414 | { | |
415 | } | |
416 | ||
417 | inline void JSCell::finishCreation(JSGlobalData& globalData, Structure* structure, CreatingEarlyCellTag) | |
418 | { | |
419 | #if ENABLE(GC_VALIDATION) | |
420 | ASSERT(globalData.isInitializingObject()); | |
421 | globalData.setInitializingObjectClass(0); | |
422 | if (structure) | |
423 | #endif | |
424 | m_structure.setEarlyValue(globalData, this, structure); | |
425 | m_classInfo = structure->classInfo(); | |
426 | // Very first set of allocations won't have a real structure. | |
427 | ASSERT(m_structure || !globalData.structureStructure); | |
428 | } | |
429 | ||
9dae56ea A |
430 | } // namespace JSC |
431 | ||
432 | #endif // Structure_h |