+ PassRefPtr<StructureShape> toStructureShape(JSValue);
+
+ // Determines if the two structures match enough that this one could be used for allocations
+ // of the other one.
+ bool canUseForAllocationsOf(Structure*);
+
+ void dump(PrintStream&) const;
+ void dumpInContext(PrintStream&, DumpContext*) const;
+ void dumpBrief(PrintStream&, const CString&) const;
+
+ static void dumpContextHeader(PrintStream&);
+
+ DECLARE_EXPORT_INFO;
+
+private:
+ typedef enum {
+ NoneDictionaryKind = 0,
+ CachedDictionaryKind = 1,
+ UncachedDictionaryKind = 2
+ } DictionaryKind;
+
+public:
+#define DEFINE_BITFIELD(type, lowerName, upperName, width, offset) \
+ static const uint32_t s_##lowerName##Shift = offset;\
+ static const uint32_t s_##lowerName##Mask = ((1 << (width - 1)) | ((1 << (width - 1)) - 1));\
+ type lowerName() const { return static_cast<type>((m_bitField >> offset) & s_##lowerName##Mask); }\
+ void set##upperName(type newValue) \
+ {\
+ m_bitField &= ~(s_##lowerName##Mask << offset);\
+ m_bitField |= (newValue & s_##lowerName##Mask) << offset;\
+ }
+
+ DEFINE_BITFIELD(DictionaryKind, dictionaryKind, DictionaryKind, 2, 0);
+ DEFINE_BITFIELD(bool, isPinnedPropertyTable, IsPinnedPropertyTable, 1, 2);
+ DEFINE_BITFIELD(bool, hasGetterSetterProperties, HasGetterSetterProperties, 1, 3);
+ DEFINE_BITFIELD(bool, hasReadOnlyOrGetterSetterPropertiesExcludingProto, HasReadOnlyOrGetterSetterPropertiesExcludingProto, 1, 4);
+ DEFINE_BITFIELD(bool, hasNonEnumerableProperties, HasNonEnumerableProperties, 1, 5);
+ DEFINE_BITFIELD(unsigned, attributesInPrevious, AttributesInPrevious, 14, 6);
+ DEFINE_BITFIELD(bool, preventExtensions, PreventExtensions, 1, 20);
+ DEFINE_BITFIELD(bool, didTransition, DidTransition, 1, 21);
+ DEFINE_BITFIELD(bool, staticFunctionsReified, StaticFunctionsReified, 1, 22);
+ DEFINE_BITFIELD(bool, hasRareData, HasRareData, 1, 23);
+ DEFINE_BITFIELD(bool, hasBeenFlattenedBefore, HasBeenFlattenedBefore, 1, 24);
+ DEFINE_BITFIELD(bool, hasCustomGetterSetterProperties, HasCustomGetterSetterProperties, 1, 25);
+ DEFINE_BITFIELD(bool, didWatchInternalProperties, DidWatchInternalProperties, 1, 26);
+
+private:
+ friend class LLIntOffsetsExtractor;
+
+ JS_EXPORT_PRIVATE Structure(VM&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
+ Structure(VM&);
+ Structure(VM&, Structure*);
+
+ static Structure* create(VM&, Structure*);
+
+ static Structure* addPropertyTransitionToExistingStructureImpl(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
+
+ // This will return the structure that has a usable property table, that property table,
+ // and the list of structures that we visited before we got to it. If it returns a
+ // non-null structure, it will also lock the structure that it returns; it is your job
+ // to unlock it.
+ void findStructuresAndMapForMaterialization(Vector<Structure*, 8>& structures, Structure*&, PropertyTable*&);
+
+ static Structure* toDictionaryTransition(VM&, Structure*, DictionaryKind);
+
+ PropertyOffset add(VM&, PropertyName, unsigned attributes);
+ PropertyOffset remove(PropertyName);
+
+ void createPropertyMap(const GCSafeConcurrentJITLocker&, VM&, unsigned keyCount = 0);
+ void checkConsistency();
+
+ WriteBarrier<PropertyTable>& propertyTable();
+ PropertyTable* takePropertyTableOrCloneIfPinned(VM&);
+ PropertyTable* copyPropertyTable(VM&);
+ PropertyTable* copyPropertyTableForPinning(VM&);
+ JS_EXPORT_PRIVATE void materializePropertyMap(VM&);
+ ALWAYS_INLINE void materializePropertyMapIfNecessary(VM& vm, DeferGC&)
+ {
+ ASSERT(!isCompilationThread());
+ ASSERT(structure()->classInfo() == info());
+ ASSERT(checkOffsetConsistency());
+ if (!propertyTable() && previousID())
+ materializePropertyMap(vm);
+ }
+ ALWAYS_INLINE void materializePropertyMapIfNecessary(VM& vm, PropertyTable*& table)
+ {
+ ASSERT(!isCompilationThread());
+ ASSERT(structure()->classInfo() == info());
+ ASSERT(checkOffsetConsistency());
+ table = propertyTable().get();
+ if (!table && previousID()) {
+ DeferGC deferGC(vm.heap);
+ materializePropertyMap(vm);
+ table = propertyTable().get();
+ }
+ }
+ void materializePropertyMapIfNecessaryForPinning(VM& vm, DeferGC&)