]> git.saurik.com Git - apple/javascriptcore.git/blame - runtime/Structure.h
JavaScriptCore-7600.1.4.17.5.tar.gz
[apple/javascriptcore.git] / runtime / Structure.h
CommitLineData
9dae56ea 1/*
93a37866 2 * Copyright (C) 2008, 2009, 2012, 2013 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 *
81345200 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
9dae56ea
A
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
81345200 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
9dae56ea
A
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"
81345200 30#include "ConcurrentJITLock.h"
93a37866
A
31#include "IndexingType.h"
32#include "JSCJSValue.h"
14957cd0 33#include "JSCell.h"
9dae56ea 34#include "JSType.h"
93a37866 35#include "PropertyName.h"
f9bf01c6 36#include "PropertyNameArray.h"
93a37866 37#include "PropertyOffset.h"
f9bf01c6 38#include "Protect.h"
81345200
A
39#include "PutPropertySlot.h"
40#include "StructureIDBlob.h"
93a37866 41#include "StructureRareData.h"
9dae56ea 42#include "StructureTransitionTable.h"
f9bf01c6 43#include "JSTypeInfo.h"
93a37866 44#include "Watchpoint.h"
81345200
A
45#include "Weak.h"
46#include "WriteBarrierInlines.h"
47#include <wtf/CompilationThread.h>
9dae56ea 48#include <wtf/PassRefPtr.h>
81345200 49#include <wtf/PrintStream.h>
9dae56ea 50#include <wtf/RefCounted.h>
93a37866 51#include <wtf/text/StringImpl.h>
9dae56ea 52
9dae56ea
A
53
54namespace JSC {
55
81345200 56class DeferGC;
93a37866
A
57class LLIntOffsetsExtractor;
58class PropertyNameArray;
59class PropertyNameArrayData;
60class PropertyTable;
61class StructureChain;
62class SlotVisitor;
63class JSString;
81345200 64struct DumpContext;
93a37866
A
65
66// The out-of-line property storage capacity to use when first allocating out-of-line
67// storage. Note that all objects start out without having any out-of-line storage;
68// this comes into play only on the first property store that exhausts inline storage.
69static const unsigned initialOutOfLineCapacity = 4;
70
71// The factor by which to grow out-of-line storage when it is exhausted, after the
72// initial allocation.
73static const unsigned outOfLineGrowthFactor = 2;
74
75class Structure : public JSCell {
76public:
77 friend class StructureTransitionTable;
9dae56ea 78
93a37866 79 typedef JSCell Base;
81345200 80
93a37866
A
81 static Structure* create(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
82
81345200
A
83 ~Structure();
84
93a37866
A
85protected:
86 void finishCreation(VM& vm)
87 {
88 Base::finishCreation(vm);
89 ASSERT(m_prototype);
90 ASSERT(m_prototype.isObject() || m_prototype.isNull());
91 }
9dae56ea 92
93a37866
A
93 void finishCreation(VM& vm, CreatingEarlyCellTag)
94 {
95 Base::finishCreation(vm, this, CreatingEarlyCell);
96 ASSERT(m_prototype);
97 ASSERT(m_prototype.isNull());
98 ASSERT(!vm.structureStructure);
99 }
6fe7ccc8 100
93a37866 101public:
81345200
A
102 StructureID id() const { return m_blob.structureID(); }
103 int32_t objectInitializationBlob() const { return m_blob.blobExcludingStructureID(); }
104 int64_t idBlob() const { return m_blob.blob(); }
105
106 bool isProxy() const
107 {
108 JSType type = m_blob.type();
109 return type == ImpureProxyType || type == PureForwardingProxyType;
110 }
111
93a37866
A
112 static void dumpStatistics();
113
81345200
A
114 JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&, PutPropertySlot::Context = PutPropertySlot::UnknownContext);
115 static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&);
93a37866
A
116 JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
117 static Structure* removePropertyTransition(VM&, Structure*, PropertyName, PropertyOffset&);
118 JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(VM&, Structure*, JSValue prototype);
119 JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(VM&, Structure*, PropertyName);
120 static Structure* attributeChangeTransition(VM&, Structure*, PropertyName, unsigned attributes);
81345200 121 JS_EXPORT_PRIVATE static Structure* toCacheableDictionaryTransition(VM&, Structure*);
93a37866
A
122 static Structure* toUncacheableDictionaryTransition(VM&, Structure*);
123 static Structure* sealTransition(VM&, Structure*);
124 static Structure* freezeTransition(VM&, Structure*);
125 static Structure* preventExtensionsTransition(VM&, Structure*);
126 static Structure* nonPropertyTransition(VM&, Structure*, NonPropertyTransition);
127
128 bool isSealed(VM&);
129 bool isFrozen(VM&);
130 bool isExtensible() const { return !m_preventExtensions; }
131 bool didTransition() const { return m_didTransition; }
132 bool putWillGrowOutOfLineStorage();
81345200 133 size_t suggestedNewOutOfLineStorageCapacity();
93a37866 134
81345200 135 JS_EXPORT_PRIVATE Structure* flattenDictionaryStructure(VM&, JSObject*);
93a37866
A
136
137 static const bool needsDestruction = true;
138 static const bool hasImmortalStructure = true;
139 static void destroy(JSCell*);
140
141 // These should be used with caution.
142 JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
143 PropertyOffset removePropertyWithoutTransition(VM&, PropertyName);
144 void setPrototypeWithoutTransition(VM& vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
6fe7ccc8 145
93a37866
A
146 bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
147 bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
9dae56ea 148
81345200
A
149 bool hasBeenFlattenedBefore() const { return m_hasBeenFlattenedBefore; }
150
93a37866
A
151 bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
152
81345200
A
153 // We use SlowPath in GetByIdStatus for structures that may get new impure properties later to prevent
154 // DFG from inlining property accesses since structures don't transition when a new impure property appears.
155 bool takesSlowPathInDFGForImpureProperty()
156 {
157 return typeInfo().hasImpureGetOwnPropertySlot();
158 }
159
93a37866 160 // Type accessors.
81345200 161 TypeInfo typeInfo() const { ASSERT(structure()->classInfo() == info()); return m_blob.typeInfo(m_outOfLineTypeFlags); }
93a37866
A
162 bool isObject() const { return typeInfo().isObject(); }
163
81345200
A
164 IndexingType indexingType() const { return m_blob.indexingType() & AllArrayTypes; }
165 IndexingType indexingTypeIncludingHistory() const { return m_blob.indexingType(); }
f9bf01c6 166
93a37866
A
167 bool mayInterceptIndexedAccesses() const
168 {
169 return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
170 }
f9bf01c6 171
93a37866 172 bool anyObjectInChainMayInterceptIndexedAccesses() const;
81345200 173 bool holesMustForwardToPrototype(VM&) const;
6fe7ccc8 174
93a37866
A
175 bool needsSlowPutIndexing() const;
176 NonPropertyTransition suggestedArrayStorageTransition() const;
ba379fdc 177
93a37866
A
178 JSGlobalObject* globalObject() const { return m_globalObject.get(); }
179 void setGlobalObject(VM& vm, JSGlobalObject* globalObject) { m_globalObject.set(vm, this, globalObject); }
6fe7ccc8 180
93a37866 181 JSValue storedPrototype() const { return m_prototype.get(); }
81345200
A
182 JSObject* storedPrototypeObject() const;
183 Structure* storedPrototypeStructure() const;
93a37866
A
184 JSValue prototypeForLookup(ExecState*) const;
185 JSValue prototypeForLookup(JSGlobalObject*) const;
186 JSValue prototypeForLookup(CodeBlock*) const;
187 StructureChain* prototypeChain(VM&, JSGlobalObject*) const;
188 StructureChain* prototypeChain(ExecState*) const;
189 static void visitChildren(JSCell*, SlotVisitor&);
190
191 // Will just the prototype chain intercept this property access?
192 bool prototypeChainMayInterceptStoreTo(VM&, PropertyName);
193
194 bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
195
196 Structure* previousID() const
197 {
81345200
A
198 ASSERT(structure()->classInfo() == info());
199 if (m_hasRareData)
93a37866
A
200 return rareData()->previousID();
201 return previous();
202 }
203 bool transitivelyTransitionedFrom(Structure* structureToFind);
9dae56ea 204
93a37866
A
205 unsigned outOfLineCapacity() const
206 {
207 ASSERT(checkOffsetConsistency());
208
209 unsigned outOfLineSize = this->outOfLineSize();
f9bf01c6 210
93a37866
A
211 if (!outOfLineSize)
212 return 0;
9dae56ea 213
93a37866
A
214 if (outOfLineSize <= initialOutOfLineCapacity)
215 return initialOutOfLineCapacity;
9dae56ea 216
93a37866
A
217 ASSERT(outOfLineSize > initialOutOfLineCapacity);
218 COMPILE_ASSERT(outOfLineGrowthFactor == 2, outOfLineGrowthFactor_is_two);
219 return WTF::roundUpToPowerOfTwo(outOfLineSize);
220 }
221 unsigned outOfLineSize() const
222 {
223 ASSERT(checkOffsetConsistency());
81345200 224 ASSERT(structure()->classInfo() == info());
93a37866
A
225
226 return numberOfOutOfLineSlotsForLastOffset(m_offset);
227 }
228 bool hasInlineStorage() const
229 {
230 return !!m_inlineCapacity;
231 }
232 unsigned inlineCapacity() const
233 {
234 return m_inlineCapacity;
235 }
236 unsigned inlineSize() const
237 {
238 return std::min<unsigned>(m_offset + 1, m_inlineCapacity);
239 }
240 unsigned totalStorageSize() const
241 {
242 return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
243 }
244 unsigned totalStorageCapacity() const
245 {
81345200 246 ASSERT(structure()->classInfo() == info());
93a37866
A
247 return outOfLineCapacity() + inlineCapacity();
248 }
9dae56ea 249
81345200 250 bool isValidOffset(PropertyOffset offset) const
93a37866 251 {
81345200
A
252 return JSC::isValidOffset(offset)
253 && offset <= m_offset
254 && (offset < m_inlineCapacity || offset >= firstOutOfLineOffset);
93a37866 255 }
81345200
A
256
257 bool couldHaveIndexingHeader() const
93a37866 258 {
81345200
A
259 return hasIndexedProperties(indexingType())
260 || isTypedView(m_classInfo->typedArrayStorageType);
93a37866 261 }
81345200
A
262
263 bool hasIndexingHeader(const JSCell*) const;
264
93a37866 265 bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
14957cd0 266
93a37866
A
267 PropertyOffset get(VM&, PropertyName);
268 PropertyOffset get(VM&, const WTF::String& name);
81345200
A
269 PropertyOffset get(VM&, PropertyName, unsigned& attributes, JSCell*& specificValue);
270
271 PropertyOffset getConcurrently(VM&, StringImpl* uid);
272 PropertyOffset getConcurrently(VM&, StringImpl* uid, unsigned& attributes, JSCell*& specificValue);
9dae56ea 273
93a37866
A
274 bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
275 bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
276 void setHasGetterSetterProperties(bool is__proto__)
277 {
278 m_hasGetterSetterProperties = true;
279 if (!is__proto__)
280 m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
281 }
81345200
A
282
283 bool hasCustomGetterSetterProperties() const { return m_hasCustomGetterSetterProperties; }
284 void setHasCustomGetterSetterProperties(bool is__proto__)
285 {
286 m_hasCustomGetterSetterProperties = true;
287 if (!is__proto__)
288 m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
289 }
290
93a37866
A
291 void setContainsReadOnlyProperties()
292 {
293 m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
294 }
f9bf01c6 295
93a37866
A
296 bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
297
298 bool isEmpty() const
299 {
300 ASSERT(checkOffsetConsistency());
301 return !JSC::isValidOffset(m_offset);
302 }
6fe7ccc8 303
93a37866
A
304 JS_EXPORT_PRIVATE void despecifyDictionaryFunction(VM&, PropertyName);
305 void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
9dae56ea 306
93a37866
A
307 void setEnumerationCache(VM&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
308 JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
309 void getPropertyNamesFromStructure(VM&, PropertyNameArray&, EnumerationMode);
9dae56ea 310
93a37866 311 JSString* objectToStringValue()
9dae56ea 312 {
81345200 313 if (!m_hasRareData)
93a37866
A
314 return 0;
315 return rareData()->objectToStringValue();
14957cd0 316 }
9dae56ea 317
81345200 318 void setObjectToStringValue(VM& vm, JSString* value)
6fe7ccc8 319 {
81345200 320 if (!m_hasRareData)
93a37866 321 allocateRareData(vm);
81345200 322 rareData()->setObjectToStringValue(vm, value);
6fe7ccc8 323 }
93a37866
A
324
325 bool staticFunctionsReified()
14957cd0 326 {
93a37866 327 return m_staticFunctionReified;
14957cd0 328 }
9dae56ea 329
93a37866 330 void setStaticFunctionsReified()
14957cd0 331 {
93a37866 332 m_staticFunctionReified = true;
14957cd0 333 }
9dae56ea 334
93a37866
A
335 const ClassInfo* classInfo() const { return m_classInfo; }
336
81345200
A
337 static ptrdiff_t structureIDOffset()
338 {
339 return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::structureIDOffset();
340 }
341
93a37866 342 static ptrdiff_t prototypeOffset()
14957cd0 343 {
93a37866 344 return OBJECT_OFFSETOF(Structure, m_prototype);
14957cd0 345 }
9dae56ea 346
93a37866 347 static ptrdiff_t globalObjectOffset()
14957cd0 348 {
93a37866 349 return OBJECT_OFFSETOF(Structure, m_globalObject);
14957cd0 350 }
9dae56ea 351
93a37866
A
352 static ptrdiff_t classInfoOffset()
353 {
354 return OBJECT_OFFSETOF(Structure, m_classInfo);
355 }
356
357 static ptrdiff_t indexingTypeOffset()
6fe7ccc8 358 {
81345200 359 return OBJECT_OFFSETOF(Structure, m_blob) + StructureIDBlob::indexingTypeOffset();
14957cd0 360 }
9dae56ea 361
93a37866
A
362 static Structure* createStructure(VM&);
363
364 bool transitionWatchpointSetHasBeenInvalidated() const
14957cd0 365 {
93a37866
A
366 return m_transitionWatchpointSet.hasBeenInvalidated();
367 }
6fe7ccc8 368
93a37866
A
369 bool transitionWatchpointSetIsStillValid() const
370 {
371 return m_transitionWatchpointSet.isStillValid();
372 }
6fe7ccc8 373
93a37866
A
374 void addTransitionWatchpoint(Watchpoint* watchpoint) const
375 {
376 ASSERT(transitionWatchpointSetIsStillValid());
377 m_transitionWatchpointSet.add(watchpoint);
14957cd0 378 }
93a37866
A
379
380 void notifyTransitionFromThisStructure() const
381 {
81345200 382 m_transitionWatchpointSet.fireAll();
93a37866 383 }
81345200
A
384
385 InlineWatchpointSet& transitionWatchpointSet() const
386 {
387 return m_transitionWatchpointSet;
388 }
389
390 void dump(PrintStream&) const;
391 void dumpInContext(PrintStream&, DumpContext*) const;
392 void dumpBrief(PrintStream&, const CString&) const;
393
394 static void dumpContextHeader(PrintStream&);
395
396 DECLARE_EXPORT_INFO;
93a37866
A
397
398private:
399 friend class LLIntOffsetsExtractor;
9dae56ea 400
93a37866
A
401 JS_EXPORT_PRIVATE Structure(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
402 Structure(VM&);
81345200
A
403 Structure(VM&, Structure*);
404
405 static Structure* create(VM&, Structure*);
406
407 static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, StringImpl* uid, unsigned attributes, JSCell* specificValue, PropertyOffset&);
408
409 // This will return the structure that has a usable property table, that property table,
410 // and the list of structures that we visited before we got to it. If it returns a
411 // non-null structure, it will also lock the structure that it returns; it is your job
412 // to unlock it.
413 void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
414
93a37866
A
415 typedef enum {
416 NoneDictionaryKind = 0,
417 CachedDictionaryKind = 1,
418 UncachedDictionaryKind = 2
419 } DictionaryKind;
420 static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind);
421
422 PropertyOffset putSpecificValue(VM&, PropertyName, unsigned attributes, JSCell* specificValue);
423 PropertyOffset remove(PropertyName);
424
81345200 425 void createPropertyMap(const GCSafeConcurrentJITLocker&, VM&, unsigned keyCount = 0);
93a37866
A
426 void checkConsistency();
427
428 bool despecifyFunction(VM&, PropertyName);
429 void despecifyAllFunctions(VM&);
430
431 WriteBarrier<PropertyTable>& propertyTable();
81345200
A
432 PropertyTable* takePropertyTableOrCloneIfPinned(VM&);
433 PropertyTable* copyPropertyTable(VM&);
434 PropertyTable* copyPropertyTableForPinning(VM&);
93a37866 435 JS_EXPORT_PRIVATE void materializePropertyMap(VM&);
81345200 436 ALWAYS_INLINE void materializePropertyMapIfNecessary(VM& vm, DeferGC&)
14957cd0 437 {
81345200
A
438 ASSERT(!isCompilationThread());
439 ASSERT(structure()->classInfo() == info());
93a37866
A
440 ASSERT(checkOffsetConsistency());
441 if (!propertyTable() && previousID())
442 materializePropertyMap(vm);
443 }
81345200 444 ALWAYS_INLINE void materializePropertyMapIfNecessary(VM& vm, PropertyTable*& table)
93a37866 445 {
81345200
A
446 ASSERT(!isCompilationThread());
447 ASSERT(structure()->classInfo() == info());
448 ASSERT(checkOffsetConsistency());
449 table = propertyTable().get();
450 if (!table && previousID()) {
451 DeferGC deferGC(vm.heap);
452 materializePropertyMap(vm);
453 table = propertyTable().get();
454 }
455 }
456 void materializePropertyMapIfNecessaryForPinning(VM& vm, DeferGC&)
457 {
458 ASSERT(structure()->classInfo() == info());
93a37866
A
459 checkOffsetConsistency();
460 if (!propertyTable())
461 materializePropertyMap(vm);
9dae56ea
A
462 }
463
81345200 464 void setPreviousID(VM& vm, Structure* structure)
6fe7ccc8 465 {
81345200
A
466 if (m_hasRareData)
467 rareData()->setPreviousID(vm, structure);
93a37866 468 else
81345200 469 m_previousOrRareData.set(vm, this, structure);
6fe7ccc8
A
470 }
471
93a37866 472 void clearPreviousID()
6fe7ccc8 473 {
81345200 474 if (m_hasRareData)
93a37866
A
475 rareData()->clearPreviousID();
476 else
477 m_previousOrRareData.clear();
6fe7ccc8
A
478 }
479
93a37866 480 int transitionCount() const
6fe7ccc8 481 {
93a37866
A
482 // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
483 return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
6fe7ccc8
A
484 }
485
93a37866
A
486 bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain) const;
487 bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
488
489 void pin();
490
491 Structure* previous() const
492 {
81345200 493 ASSERT(!m_hasRareData);
93a37866
A
494 return static_cast<Structure*>(m_previousOrRareData.get());
495 }
496
497 StructureRareData* rareData() const
498 {
81345200 499 ASSERT(m_hasRareData);
93a37866
A
500 return static_cast<StructureRareData*>(m_previousOrRareData.get());
501 }
502
503 bool checkOffsetConsistency() const;
504
505 void allocateRareData(VM&);
506 void cloneRareDataFrom(VM&, const Structure*);
507
508 static const int s_maxTransitionLength = 64;
81345200 509 static const int s_maxTransitionLengthForNonEvalPutById = 512;
93a37866
A
510
511 static const unsigned maxSpecificFunctionThrashCount = 3;
81345200
A
512
513 // These need to be properly aligned at the beginning of the 'Structure'
514 // part of the object.
515 StructureIDBlob m_blob;
516 TypeInfo::OutOfLineTypeFlags m_outOfLineTypeFlags;
517
93a37866
A
518 WriteBarrier<JSGlobalObject> m_globalObject;
519 WriteBarrier<Unknown> m_prototype;
520 mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
521
522 WriteBarrier<JSCell> m_previousOrRareData;
523
524 RefPtr<StringImpl> m_nameInPrevious;
525 WriteBarrier<JSCell> m_specificValueInPrevious;
526
527 const ClassInfo* m_classInfo;
528
529 StructureTransitionTable m_transitionTable;
530
531 // Should be accessed through propertyTable(). During GC, it may be set to 0 by another thread.
532 WriteBarrier<PropertyTable> m_propertyTableUnsafe;
533
534 mutable InlineWatchpointSet m_transitionWatchpointSet;
535
536 COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
537
538 // m_offset does not account for anonymous slots
539 PropertyOffset m_offset;
540
93a37866 541 uint8_t m_inlineCapacity;
81345200
A
542
543 ConcurrentJITLock m_lock;
544
93a37866 545 unsigned m_dictionaryKind : 2;
81345200 546 bool m_hasBeenFlattenedBefore : 1;
93a37866
A
547 bool m_isPinnedPropertyTable : 1;
548 bool m_hasGetterSetterProperties : 1;
81345200 549 bool m_hasCustomGetterSetterProperties : 1;
93a37866
A
550 bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
551 bool m_hasNonEnumerableProperties : 1;
552 unsigned m_attributesInPrevious : 14;
553 unsigned m_specificFunctionThrashCount : 2;
554 unsigned m_preventExtensions : 1;
555 unsigned m_didTransition : 1;
81345200
A
556 unsigned m_staticFunctionReified : 1;
557 bool m_hasRareData : 1;
93a37866
A
558};
559
9dae56ea
A
560} // namespace JSC
561
562#endif // Structure_h