diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 628461f..8c98fda 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -48,561 +48,561 @@
 
 namespace JSC {
 
-    class LLIntOffsetsExtractor;
-    class PropertyNameArray;
-    class PropertyNameArrayData;
-    class StructureChain;
-    class SlotVisitor;
-    class JSString;
+class LLIntOffsetsExtractor;
+class PropertyNameArray;
+class PropertyNameArrayData;
+class StructureChain;
+class SlotVisitor;
+class JSString;
 
-    // The out-of-line property storage capacity to use when first allocating out-of-line
-    // storage. Note that all objects start out without having any out-of-line storage;
-    // this comes into play only on the first property store that exhausts inline storage.
-    static const unsigned initialOutOfLineCapacity = 4;
+// The out-of-line property storage capacity to use when first allocating out-of-line
+// storage. Note that all objects start out without having any out-of-line storage;
+// this comes into play only on the first property store that exhausts inline storage.
+static const unsigned initialOutOfLineCapacity = 4;
 
-    // The factor by which to grow out-of-line storage when it is exhausted, after the
-    // initial allocation.
-    static const unsigned outOfLineGrowthFactor = 2;
+// The factor by which to grow out-of-line storage when it is exhausted, after the
+// initial allocation.
+static const unsigned outOfLineGrowthFactor = 2;
 
-    class Structure : public JSCell {
-    public:
-        friend class StructureTransitionTable;
+class Structure : public JSCell {
+public:
+    friend class StructureTransitionTable;
 
-        typedef JSCell Base;
+    typedef JSCell Base;
 
-        static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
+    static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, unsigned inlineCapacity = 0);
 
-    protected:
-        void finishCreation(JSGlobalData& globalData)
-        {
-            Base::finishCreation(globalData);
-            ASSERT(m_prototype);
-            ASSERT(m_prototype.isObject() || m_prototype.isNull());
-        }
-
-        void finishCreation(JSGlobalData& globalData, CreatingEarlyCellTag)
-        {
-            Base::finishCreation(globalData, this, CreatingEarlyCell);
-            ASSERT(m_prototype);
-            ASSERT(m_prototype.isNull());
-            ASSERT(!globalData.structureStructure);
-        }
-
-    public:
-        static void dumpStatistics();
-
-        JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
-        JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
-        static Structure* removePropertyTransition(JSGlobalData&, Structure*, PropertyName, PropertyOffset&);
-        JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
-        JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, PropertyName);
-        static Structure* attributeChangeTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes);
-        static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*);
-        static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*);
-        static Structure* sealTransition(JSGlobalData&, Structure*);
-        static Structure* freezeTransition(JSGlobalData&, Structure*);
-        static Structure* preventExtensionsTransition(JSGlobalData&, Structure*);
-        static Structure* nonPropertyTransition(JSGlobalData&, Structure*, NonPropertyTransition);
-
-        bool isSealed(JSGlobalData&);
-        bool isFrozen(JSGlobalData&);
-        bool isExtensible() const { return !m_preventExtensions; }
-        bool didTransition() const { return m_didTransition; }
-        bool putWillGrowOutOfLineStorage()
-        {
-            checkOffsetConsistency();
-            
-            ASSERT(outOfLineCapacity() >= outOfLineSize());
-            
-            if (!m_propertyTable) {
-                unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
-                ASSERT(outOfLineCapacity() >= currentSize);
-                return currentSize == outOfLineCapacity();
-            }
-            
-            ASSERT(totalStorageCapacity() >= m_propertyTable->propertyStorageSize());
-            if (m_propertyTable->hasDeletedOffset())
-                return false;
-            
-            ASSERT(totalStorageCapacity() >= m_propertyTable->size());
-            return m_propertyTable->size() == totalStorageCapacity();
-        }
-        JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity(); 
-
-        Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
-
-        static const bool needsDestruction = true;
-        static const bool hasImmortalStructure = true;
-        static void destroy(JSCell*);
-
-        // These should be used with caution.  
-        JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
-        PropertyOffset removePropertyWithoutTransition(JSGlobalData&, PropertyName);
-        void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
-        
-        bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
-        bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
-
-        bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
-
-        // Type accessors.
-        const TypeInfo& typeInfo() const { ASSERT(structure()->classInfo() == &s_info); return m_typeInfo; }
-        bool isObject() const { return typeInfo().isObject(); }
-
-        IndexingType indexingType() const { return m_indexingType & AllArrayTypes; }
-        IndexingType indexingTypeIncludingHistory() const { return m_indexingType; }
-        
-        bool mayInterceptIndexedAccesses() const
-        {
-            return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
-        }
-        
-        bool anyObjectInChainMayInterceptIndexedAccesses() const;
-        
-        bool needsSlowPutIndexing() const;
-        NonPropertyTransition suggestedArrayStorageTransition() const;
-        
-        JSGlobalObject* globalObject() const { return m_globalObject.get(); }
-        void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); }
-        
-        JSValue storedPrototype() const { return m_prototype.get(); }
-        JSValue prototypeForLookup(ExecState*) const;
-        JSValue prototypeForLookup(JSGlobalObject*) const;
-        JSValue prototypeForLookup(CodeBlock*) const;
-        StructureChain* prototypeChain(JSGlobalData&, JSGlobalObject*) const;
-        StructureChain* prototypeChain(ExecState*) const;
-        static void visitChildren(JSCell*, SlotVisitor&);
-        
-        // Will just the prototype chain intercept this property access?
-        bool prototypeChainMayInterceptStoreTo(JSGlobalData&, PropertyName);
-        
-        bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
-        
-        Structure* previousID() const
-        {
-            ASSERT(structure()->classInfo() == &s_info);
-            if (typeInfo().structureHasRareData())
-                return rareData()->previousID();
-            return previous();
-        }
-        bool transitivelyTransitionedFrom(Structure* structureToFind);
-
-        unsigned outOfLineCapacity() const
-        {
-            ASSERT(checkOffsetConsistency());
-            
-            unsigned outOfLineSize = this->outOfLineSize();
-
-            if (!outOfLineSize)
-                return 0;
-
-            if (outOfLineSize <= initialOutOfLineCapacity)
-                return initialOutOfLineCapacity;
-
-            ASSERT(outOfLineSize > initialOutOfLineCapacity);
-            COMPILE_ASSERT(outOfLineGrowthFactor == 2, outOfLineGrowthFactor_is_two);
-            return WTF::roundUpToPowerOfTwo(outOfLineSize);
-        }
-        unsigned outOfLineSize() const
-        {
-            ASSERT(checkOffsetConsistency());
-            ASSERT(structure()->classInfo() == &s_info);
-            
-            return numberOfOutOfLineSlotsForLastOffset(m_offset);
-        }
-        bool hasInlineStorage() const
-        {
-            return !!m_inlineCapacity;
-        }
-        unsigned inlineCapacity() const
-        {
-            return m_inlineCapacity;
-        }
-        unsigned inlineSize() const
-        {
-            return std::min<unsigned>(m_offset + 1, m_inlineCapacity);
-        }
-        unsigned totalStorageSize() const
-        {
-            return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
-        }
-        unsigned totalStorageCapacity() const
-        {
-            ASSERT(structure()->classInfo() == &s_info);
-            return outOfLineCapacity() + inlineCapacity();
-        }
-
-        PropertyOffset firstValidOffset() const
-        {
-            if (hasInlineStorage())
-                return 0;
-            return firstOutOfLineOffset;
-        }
-        PropertyOffset lastValidOffset() const
-        {
-            return m_offset;
-        }
-        bool isValidOffset(PropertyOffset offset) const
-        {
-            return offset >= firstValidOffset()
-                && offset <= lastValidOffset();
-        }
-
-        bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
-
-        PropertyOffset get(JSGlobalData&, PropertyName);
-        PropertyOffset get(JSGlobalData&, const WTF::String& name);
-        JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
-
-        bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
-        bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
-        void setHasGetterSetterProperties(bool is__proto__)
-        {
-            m_hasGetterSetterProperties = true;
-            if (!is__proto__)
-                m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
-        }
-        void setContainsReadOnlyProperties()
-        {
-            m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
-        }
-
-        bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
-        
-        bool isEmpty() const
-        {
-            ASSERT(checkOffsetConsistency());
-            return !JSC::isValidOffset(m_offset);
-        }
-
-        JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, PropertyName);
-        void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
-
-        void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
-        JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
-        void getPropertyNamesFromStructure(JSGlobalData&, PropertyNameArray&, EnumerationMode);
-
-        JSString* objectToStringValue()
-        {
-            if (!typeInfo().structureHasRareData())
-                return 0;
-            return rareData()->objectToStringValue();
-        }
-
-        void setObjectToStringValue(JSGlobalData& globalData, const JSCell* owner, JSString* value)
-        {
-            if (!typeInfo().structureHasRareData())
-                allocateRareData(globalData);
-            rareData()->setObjectToStringValue(globalData, owner, value);
-        }
-
-        bool staticFunctionsReified()
-        {
-            return m_staticFunctionReified;
-        }
-
-        void setStaticFunctionsReified()
-        {
-            m_staticFunctionReified = true;
-        }
-
-        const ClassInfo* classInfo() const { return m_classInfo; }
-
-        static ptrdiff_t prototypeOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_prototype);
-        }
-
-        static ptrdiff_t globalObjectOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_globalObject);
-        }
-
-        static ptrdiff_t typeInfoFlagsOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
-        }
-
-        static ptrdiff_t typeInfoTypeOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
-        }
-        
-        static ptrdiff_t classInfoOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_classInfo);
-        }
-        
-        static ptrdiff_t indexingTypeOffset()
-        {
-            return OBJECT_OFFSETOF(Structure, m_indexingType);
-        }
-
-        static Structure* createStructure(JSGlobalData&);
-        
-        bool transitionWatchpointSetHasBeenInvalidated() const
-        {
-            return m_transitionWatchpointSet.hasBeenInvalidated();
-        }
-        
-        bool transitionWatchpointSetIsStillValid() const
-        {
-            return m_transitionWatchpointSet.isStillValid();
-        }
-        
-        void addTransitionWatchpoint(Watchpoint* watchpoint) const
-        {
-            ASSERT(transitionWatchpointSetIsStillValid());
-            m_transitionWatchpointSet.add(watchpoint);
-        }
-        
-        void notifyTransitionFromThisStructure() const
-        {
-            m_transitionWatchpointSet.notifyWrite();
-        }
-        
-        static JS_EXPORTDATA const ClassInfo s_info;
-
-    private:
-        friend class LLIntOffsetsExtractor;
-
-        JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
-        Structure(JSGlobalData&);
-        Structure(JSGlobalData&, const Structure*);
-
-        static Structure* create(JSGlobalData&, const Structure*);
-        
-        typedef enum { 
-            NoneDictionaryKind = 0,
-            CachedDictionaryKind = 1,
-            UncachedDictionaryKind = 2
-        } DictionaryKind;
-        static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind);
-
-        PropertyOffset putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
-        PropertyOffset remove(PropertyName);
-
-        void createPropertyMap(unsigned keyCount = 0);
-        void checkConsistency();
-
-        bool despecifyFunction(JSGlobalData&, PropertyName);
-        void despecifyAllFunctions(JSGlobalData&);
-
-        PassOwnPtr<PropertyTable> copyPropertyTable(JSGlobalData&, Structure* owner);
-        PassOwnPtr<PropertyTable> copyPropertyTableForPinning(JSGlobalData&, Structure* owner);
-        JS_EXPORT_PRIVATE void materializePropertyMap(JSGlobalData&);
-        void materializePropertyMapIfNecessary(JSGlobalData& globalData)
-        {
-            ASSERT(structure()->classInfo() == &s_info);
-            ASSERT(checkOffsetConsistency());
-            if (!m_propertyTable && previousID())
-                materializePropertyMap(globalData);
-        }
-        void materializePropertyMapIfNecessaryForPinning(JSGlobalData& globalData)
-        {
-            ASSERT(structure()->classInfo() == &s_info);
-            checkOffsetConsistency();
-            if (!m_propertyTable)
-                materializePropertyMap(globalData);
-        }
-
-        void setPreviousID(JSGlobalData& globalData, Structure* transition, Structure* structure)
-        {
-            if (typeInfo().structureHasRareData())
-                rareData()->setPreviousID(globalData, transition, structure);
-            else
-                m_previousOrRareData.set(globalData, transition, structure);
-        }
-
-        void clearPreviousID()
-        {
-            if (typeInfo().structureHasRareData())
-                rareData()->clearPreviousID();
-            else
-                m_previousOrRareData.clear();
-        }
-
-        int transitionCount() const
-        {
-            // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
-            return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
-        }
-
-        bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain) const;
-        bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
-        
-        void pin();
-
-        Structure* previous() const
-        {
-            ASSERT(!typeInfo().structureHasRareData());
-            return static_cast<Structure*>(m_previousOrRareData.get());
-        }
-
-        StructureRareData* rareData() const
-        {
-            ASSERT(typeInfo().structureHasRareData());
-            return static_cast<StructureRareData*>(m_previousOrRareData.get());
-        }
-        
-        ALWAYS_INLINE bool checkOffsetConsistency() const
-        {
-            if (!m_propertyTable) {
-                ASSERT(!m_isPinnedPropertyTable);
-                return true;
-            }
-            
-            RELEASE_ASSERT(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity) == m_propertyTable->propertyStorageSize());
-            unsigned totalSize = m_propertyTable->propertyStorageSize();
-            RELEASE_ASSERT((totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity()) == numberOfOutOfLineSlotsForLastOffset(m_offset));
-            
-            return true;
-        }
-
-        void allocateRareData(JSGlobalData&);
-        void cloneRareDataFrom(JSGlobalData&, const Structure*);
-
-        static const int s_maxTransitionLength = 64;
-
-        static const unsigned maxSpecificFunctionThrashCount = 3;
-
-        TypeInfo m_typeInfo;
-        IndexingType m_indexingType;
-        
-        WriteBarrier<JSGlobalObject> m_globalObject;
-        WriteBarrier<Unknown> m_prototype;
-        mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
-
-        WriteBarrier<JSCell> m_previousOrRareData;
-
-        RefPtr<StringImpl> m_nameInPrevious;
-        WriteBarrier<JSCell> m_specificValueInPrevious;
-
-        const ClassInfo* m_classInfo;
-
-        StructureTransitionTable m_transitionTable;
-
-        OwnPtr<PropertyTable> m_propertyTable;
-
-        mutable InlineWatchpointSet m_transitionWatchpointSet;
-
-        uint8_t m_inlineCapacity;
-        COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
-
-        // m_offset does not account for anonymous slots
-        PropertyOffset m_offset;
-
-        unsigned m_dictionaryKind : 2;
-        bool m_isPinnedPropertyTable : 1;
-        bool m_hasGetterSetterProperties : 1;
-        bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
-        bool m_hasNonEnumerableProperties : 1;
-        unsigned m_attributesInPrevious : 22;
-        unsigned m_specificFunctionThrashCount : 2;
-        unsigned m_preventExtensions : 1;
-        unsigned m_didTransition : 1;
-        unsigned m_staticFunctionReified;
-    };
-
-    inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
+protected:
+    void finishCreation(JSGlobalData& globalData)
     {
-        ASSERT(globalData.structureStructure);
-        ASSERT(classInfo);
-        Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
-        structure->finishCreation(globalData);
-        return structure;
+        Base::finishCreation(globalData);
+        ASSERT(m_prototype);
+        ASSERT(m_prototype.isObject() || m_prototype.isNull());
     }
-        
-    inline Structure* Structure::createStructure(JSGlobalData& globalData)
+
+    void finishCreation(JSGlobalData& globalData, CreatingEarlyCellTag)
     {
+        Base::finishCreation(globalData, this, CreatingEarlyCell);
+        ASSERT(m_prototype);
+        ASSERT(m_prototype.isNull());
         ASSERT(!globalData.structureStructure);
-        Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData);
-        structure->finishCreation(globalData, CreatingEarlyCell);
-        return structure;
     }
 
-    inline Structure* Structure::create(JSGlobalData& globalData, const Structure* structure)
+public:
+    static void dumpStatistics();
+
+    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, JSCell* specificValue, PropertyOffset&);
+    static Structure* removePropertyTransition(JSGlobalData&, Structure*, PropertyName, PropertyOffset&);
+    JS_EXPORT_PRIVATE static Structure* changePrototypeTransition(JSGlobalData&, Structure*, JSValue prototype);
+    JS_EXPORT_PRIVATE static Structure* despecifyFunctionTransition(JSGlobalData&, Structure*, PropertyName);
+    static Structure* attributeChangeTransition(JSGlobalData&, Structure*, PropertyName, unsigned attributes);
+    static Structure* toCacheableDictionaryTransition(JSGlobalData&, Structure*);
+    static Structure* toUncacheableDictionaryTransition(JSGlobalData&, Structure*);
+    static Structure* sealTransition(JSGlobalData&, Structure*);
+    static Structure* freezeTransition(JSGlobalData&, Structure*);
+    static Structure* preventExtensionsTransition(JSGlobalData&, Structure*);
+    static Structure* nonPropertyTransition(JSGlobalData&, Structure*, NonPropertyTransition);
+
+    bool isSealed(JSGlobalData&);
+    bool isFrozen(JSGlobalData&);
+    bool isExtensible() const { return !m_preventExtensions; }
+    bool didTransition() const { return m_didTransition; }
+    bool putWillGrowOutOfLineStorage()
     {
-        ASSERT(globalData.structureStructure);
-        Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure);
-        newStructure->finishCreation(globalData);
-        if (structure->typeInfo().structureHasRareData())
-            newStructure->cloneRareDataFrom(globalData, structure);
-        return newStructure;
-    }
-        
-    inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName)
-    {
-        ASSERT(structure()->classInfo() == &s_info);
-        materializePropertyMapIfNecessary(globalData);
-        if (!m_propertyTable)
-            return invalidOffset;
-
-        PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
-        return entry ? entry->offset : invalidOffset;
-    }
-
-    inline PropertyOffset Structure::get(JSGlobalData& globalData, const WTF::String& name)
-    {
-        ASSERT(structure()->classInfo() == &s_info);
-        materializePropertyMapIfNecessary(globalData);
-        if (!m_propertyTable)
-            return invalidOffset;
-
-        PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first;
-        return entry ? entry->offset : invalidOffset;
-    }
-    
-    inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
-    {
-        return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
-    }
-
-    ALWAYS_INLINE void SlotVisitor::internalAppend(JSCell* cell)
-    {
-        ASSERT(!m_isCheckingForDefaultMarkViolation);
-        if (!cell)
-            return;
-#if ENABLE(GC_VALIDATION)
-        validate(cell);
-#endif
-        if (Heap::testAndSetMarked(cell) || !cell->structure())
-            return;
-
-        m_visitCount++;
-        
-        MARK_LOG_CHILD(*this, cell);
-
-        // Should never attempt to mark something that is zapped.
-        ASSERT(!cell->isZapped());
-        
-        m_stack.append(cell);
-    }
-
-    inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
-    {
-        for (Structure* current = this; current; current = current->previousID()) {
-            if (current == structureToFind)
-                return true;
+        checkOffsetConsistency();
+            
+        ASSERT(outOfLineCapacity() >= outOfLineSize());
+            
+        if (!m_propertyTable) {
+            unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
+            ASSERT(outOfLineCapacity() >= currentSize);
+            return currentSize == outOfLineCapacity();
         }
-        return false;
+            
+        ASSERT(totalStorageCapacity() >= m_propertyTable->propertyStorageSize());
+        if (m_propertyTable->hasDeletedOffset())
+            return false;
+            
+        ASSERT(totalStorageCapacity() >= m_propertyTable->size());
+        return m_propertyTable->size() == totalStorageCapacity();
     }
+    JS_EXPORT_PRIVATE size_t suggestedNewOutOfLineStorageCapacity(); 
 
-    inline void Structure::setEnumerationCache(JSGlobalData& globalData, JSPropertyNameIterator* enumerationCache)
+    Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
+
+    static const bool needsDestruction = true;
+    static const bool hasImmortalStructure = true;
+    static void destroy(JSCell*);
+
+    // These should be used with caution.  
+    JS_EXPORT_PRIVATE PropertyOffset addPropertyWithoutTransition(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
+    PropertyOffset removePropertyWithoutTransition(JSGlobalData&, PropertyName);
+    void setPrototypeWithoutTransition(JSGlobalData& globalData, JSValue prototype) { m_prototype.set(globalData, this, prototype); }
+        
+    bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
+    bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
+
+    bool propertyAccessesAreCacheable() { return m_dictionaryKind != UncachedDictionaryKind && !typeInfo().prohibitsPropertyCaching(); }
+
+    // Type accessors.
+    const TypeInfo& typeInfo() const { ASSERT(structure()->classInfo() == &s_info); return m_typeInfo; }
+    bool isObject() const { return typeInfo().isObject(); }
+
+    IndexingType indexingType() const { return m_indexingType & AllArrayTypes; }
+    IndexingType indexingTypeIncludingHistory() const { return m_indexingType; }
+        
+    bool mayInterceptIndexedAccesses() const
     {
-        ASSERT(!isDictionary());
-        if (!typeInfo().structureHasRareData())
-            allocateRareData(globalData);
-        rareData()->setEnumerationCache(globalData, this, enumerationCache);
+        return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
+    }
+        
+    bool anyObjectInChainMayInterceptIndexedAccesses() const;
+        
+    bool needsSlowPutIndexing() const;
+    NonPropertyTransition suggestedArrayStorageTransition() const;
+        
+    JSGlobalObject* globalObject() const { return m_globalObject.get(); }
+    void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); }
+        
+    JSValue storedPrototype() const { return m_prototype.get(); }
+    JSValue prototypeForLookup(ExecState*) const;
+    JSValue prototypeForLookup(JSGlobalObject*) const;
+    JSValue prototypeForLookup(CodeBlock*) const;
+    StructureChain* prototypeChain(JSGlobalData&, JSGlobalObject*) const;
+    StructureChain* prototypeChain(ExecState*) const;
+    static void visitChildren(JSCell*, SlotVisitor&);
+        
+    // Will just the prototype chain intercept this property access?
+    bool prototypeChainMayInterceptStoreTo(JSGlobalData&, PropertyName);
+        
+    bool transitionDidInvolveSpecificValue() const { return !!m_specificValueInPrevious; }
+        
+    Structure* previousID() const
+    {
+        ASSERT(structure()->classInfo() == &s_info);
+        if (typeInfo().structureHasRareData())
+            return rareData()->previousID();
+        return previous();
+    }
+    bool transitivelyTransitionedFrom(Structure* structureToFind);
+
+    unsigned outOfLineCapacity() const
+    {
+        ASSERT(checkOffsetConsistency());
+            
+        unsigned outOfLineSize = this->outOfLineSize();
+
+        if (!outOfLineSize)
+            return 0;
+
+        if (outOfLineSize <= initialOutOfLineCapacity)
+            return initialOutOfLineCapacity;
+
+        ASSERT(outOfLineSize > initialOutOfLineCapacity);
+        COMPILE_ASSERT(outOfLineGrowthFactor == 2, outOfLineGrowthFactor_is_two);
+        return WTF::roundUpToPowerOfTwo(outOfLineSize);
+    }
+    unsigned outOfLineSize() const
+    {
+        ASSERT(checkOffsetConsistency());
+        ASSERT(structure()->classInfo() == &s_info);
+            
+        return numberOfOutOfLineSlotsForLastOffset(m_offset);
+    }
+    bool hasInlineStorage() const
+    {
+        return !!m_inlineCapacity;
+    }
+    unsigned inlineCapacity() const
+    {
+        return m_inlineCapacity;
+    }
+    unsigned inlineSize() const
+    {
+        return std::min<unsigned>(m_offset + 1, m_inlineCapacity);
+    }
+    unsigned totalStorageSize() const
+    {
+        return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+    }
+    unsigned totalStorageCapacity() const
+    {
+        ASSERT(structure()->classInfo() == &s_info);
+        return outOfLineCapacity() + inlineCapacity();
     }
 
-    inline JSPropertyNameIterator* Structure::enumerationCache()
+    PropertyOffset firstValidOffset() const
+    {
+        if (hasInlineStorage())
+            return 0;
+        return firstOutOfLineOffset;
+    }
+    PropertyOffset lastValidOffset() const
+    {
+        return m_offset;
+    }
+    bool isValidOffset(PropertyOffset offset) const
+    {
+        return offset >= firstValidOffset()
+            && offset <= lastValidOffset();
+    }
+
+    bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject);
+
+    PropertyOffset get(JSGlobalData&, PropertyName);
+    PropertyOffset get(JSGlobalData&, const WTF::String& name);
+    JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue);
+
+    bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
+    bool hasReadOnlyOrGetterSetterPropertiesExcludingProto() const { return m_hasReadOnlyOrGetterSetterPropertiesExcludingProto; }
+    void setHasGetterSetterProperties(bool is__proto__)
+    {
+        m_hasGetterSetterProperties = true;
+        if (!is__proto__)
+            m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+    }
+    void setContainsReadOnlyProperties()
+    {
+        m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
+    }
+
+    bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; }
+        
+    bool isEmpty() const
+    {
+        ASSERT(checkOffsetConsistency());
+        return !JSC::isValidOffset(m_offset);
+    }
+
+    JS_EXPORT_PRIVATE void despecifyDictionaryFunction(JSGlobalData&, PropertyName);
+    void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
+
+    void setEnumerationCache(JSGlobalData&, JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
+    JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
+    void getPropertyNamesFromStructure(JSGlobalData&, PropertyNameArray&, EnumerationMode);
+
+    JSString* objectToStringValue()
     {
         if (!typeInfo().structureHasRareData())
             return 0;
-        return rareData()->enumerationCache();
+        return rareData()->objectToStringValue();
     }
 
+    void setObjectToStringValue(JSGlobalData& globalData, const JSCell* owner, JSString* value)
+    {
+        if (!typeInfo().structureHasRareData())
+            allocateRareData(globalData);
+        rareData()->setObjectToStringValue(globalData, owner, value);
+    }
+
+    bool staticFunctionsReified()
+    {
+        return m_staticFunctionReified;
+    }
+
+    void setStaticFunctionsReified()
+    {
+        m_staticFunctionReified = true;
+    }
+
+    const ClassInfo* classInfo() const { return m_classInfo; }
+
+    static ptrdiff_t prototypeOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_prototype);
+    }
+
+    static ptrdiff_t globalObjectOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_globalObject);
+    }
+
+    static ptrdiff_t typeInfoFlagsOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::flagsOffset();
+    }
+
+    static ptrdiff_t typeInfoTypeOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_typeInfo) + TypeInfo::typeOffset();
+    }
+        
+    static ptrdiff_t classInfoOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_classInfo);
+    }
+        
+    static ptrdiff_t indexingTypeOffset()
+    {
+        return OBJECT_OFFSETOF(Structure, m_indexingType);
+    }
+
+    static Structure* createStructure(JSGlobalData&);
+        
+    bool transitionWatchpointSetHasBeenInvalidated() const
+    {
+        return m_transitionWatchpointSet.hasBeenInvalidated();
+    }
+        
+    bool transitionWatchpointSetIsStillValid() const
+    {
+        return m_transitionWatchpointSet.isStillValid();
+    }
+        
+    void addTransitionWatchpoint(Watchpoint* watchpoint) const
+    {
+        ASSERT(transitionWatchpointSetIsStillValid());
+        m_transitionWatchpointSet.add(watchpoint);
+    }
+        
+    void notifyTransitionFromThisStructure() const
+    {
+        m_transitionWatchpointSet.notifyWrite();
+    }
+        
+    static JS_EXPORTDATA const ClassInfo s_info;
+
+private:
+    friend class LLIntOffsetsExtractor;
+
+    JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, unsigned inlineCapacity);
+    Structure(JSGlobalData&);
+    Structure(JSGlobalData&, const Structure*);
+
+    static Structure* create(JSGlobalData&, const Structure*);
+        
+    typedef enum { 
+        NoneDictionaryKind = 0,
+        CachedDictionaryKind = 1,
+        UncachedDictionaryKind = 2
+    } DictionaryKind;
+    static Structure* toDictionaryTransition(JSGlobalData&, Structure*, DictionaryKind);
+
+    PropertyOffset putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
+    PropertyOffset remove(PropertyName);
+
+    void createPropertyMap(unsigned keyCount = 0);
+    void checkConsistency();
+
+    bool despecifyFunction(JSGlobalData&, PropertyName);
+    void despecifyAllFunctions(JSGlobalData&);
+
+    PassOwnPtr<PropertyTable> copyPropertyTable(JSGlobalData&, Structure* owner);
+    PassOwnPtr<PropertyTable> copyPropertyTableForPinning(JSGlobalData&, Structure* owner);
+    JS_EXPORT_PRIVATE void materializePropertyMap(JSGlobalData&);
+    void materializePropertyMapIfNecessary(JSGlobalData& globalData)
+    {
+        ASSERT(structure()->classInfo() == &s_info);
+        ASSERT(checkOffsetConsistency());
+        if (!m_propertyTable && previousID())
+            materializePropertyMap(globalData);
+    }
+    void materializePropertyMapIfNecessaryForPinning(JSGlobalData& globalData)
+    {
+        ASSERT(structure()->classInfo() == &s_info);
+        checkOffsetConsistency();
+        if (!m_propertyTable)
+            materializePropertyMap(globalData);
+    }
+
+    void setPreviousID(JSGlobalData& globalData, Structure* transition, Structure* structure)
+    {
+        if (typeInfo().structureHasRareData())
+            rareData()->setPreviousID(globalData, transition, structure);
+        else
+            m_previousOrRareData.set(globalData, transition, structure);
+    }
+
+    void clearPreviousID()
+    {
+        if (typeInfo().structureHasRareData())
+            rareData()->clearPreviousID();
+        else
+            m_previousOrRareData.clear();
+    }
+
+    int transitionCount() const
+    {
+        // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
+        return numberOfSlotsForLastOffset(m_offset, m_inlineCapacity);
+    }
+
+    bool isValid(JSGlobalObject*, StructureChain* cachedPrototypeChain) const;
+    bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
+        
+    void pin();
+
+    Structure* previous() const
+    {
+        ASSERT(!typeInfo().structureHasRareData());
+        return static_cast<Structure*>(m_previousOrRareData.get());
+    }
+
+    StructureRareData* rareData() const
+    {
+        ASSERT(typeInfo().structureHasRareData());
+        return static_cast<StructureRareData*>(m_previousOrRareData.get());
+    }
+        
+    ALWAYS_INLINE bool checkOffsetConsistency() const
+    {
+        if (!m_propertyTable) {
+            ASSERT(!m_isPinnedPropertyTable);
+            return true;
+        }
+            
+        RELEASE_ASSERT(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity) == m_propertyTable->propertyStorageSize());
+        unsigned totalSize = m_propertyTable->propertyStorageSize();
+        RELEASE_ASSERT((totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity()) == numberOfOutOfLineSlotsForLastOffset(m_offset));
+            
+        return true;
+    }
+
+    void allocateRareData(JSGlobalData&);
+    void cloneRareDataFrom(JSGlobalData&, const Structure*);
+
+    static const int s_maxTransitionLength = 64;
+
+    static const unsigned maxSpecificFunctionThrashCount = 3;
+
+    TypeInfo m_typeInfo;
+    IndexingType m_indexingType;
+        
+    WriteBarrier<JSGlobalObject> m_globalObject;
+    WriteBarrier<Unknown> m_prototype;
+    mutable WriteBarrier<StructureChain> m_cachedPrototypeChain;
+
+    WriteBarrier<JSCell> m_previousOrRareData;
+
+    RefPtr<StringImpl> m_nameInPrevious;
+    WriteBarrier<JSCell> m_specificValueInPrevious;
+
+    const ClassInfo* m_classInfo;
+
+    StructureTransitionTable m_transitionTable;
+
+    OwnPtr<PropertyTable> m_propertyTable;
+
+    mutable InlineWatchpointSet m_transitionWatchpointSet;
+
+    uint8_t m_inlineCapacity;
+    COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits);
+
+    // m_offset does not account for anonymous slots
+    PropertyOffset m_offset;
+
+    unsigned m_dictionaryKind : 2;
+    bool m_isPinnedPropertyTable : 1;
+    bool m_hasGetterSetterProperties : 1;
+    bool m_hasReadOnlyOrGetterSetterPropertiesExcludingProto : 1;
+    bool m_hasNonEnumerableProperties : 1;
+    unsigned m_attributesInPrevious : 22;
+    unsigned m_specificFunctionThrashCount : 2;
+    unsigned m_preventExtensions : 1;
+    unsigned m_didTransition : 1;
+    unsigned m_staticFunctionReified;
+};
+
+inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
+{
+    ASSERT(globalData.structureStructure);
+    ASSERT(classInfo);
+    Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
+    structure->finishCreation(globalData);
+    return structure;
+}
+        
+inline Structure* Structure::createStructure(JSGlobalData& globalData)
+{
+    ASSERT(!globalData.structureStructure);
+    Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData);
+    structure->finishCreation(globalData, CreatingEarlyCell);
+    return structure;
+}
+
+inline Structure* Structure::create(JSGlobalData& globalData, const Structure* structure)
+{
+    ASSERT(globalData.structureStructure);
+    Structure* newStructure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, structure);
+    newStructure->finishCreation(globalData);
+    if (structure->typeInfo().structureHasRareData())
+        newStructure->cloneRareDataFrom(globalData, structure);
+    return newStructure;
+}
+        
+inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName)
+{
+    ASSERT(structure()->classInfo() == &s_info);
+    materializePropertyMapIfNecessary(globalData);
+    if (!m_propertyTable)
+        return invalidOffset;
+
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
+    return entry ? entry->offset : invalidOffset;
+}
+
+inline PropertyOffset Structure::get(JSGlobalData& globalData, const WTF::String& name)
+{
+    ASSERT(structure()->classInfo() == &s_info);
+    materializePropertyMapIfNecessary(globalData);
+    if (!m_propertyTable)
+        return invalidOffset;
+
+    PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first;
+    return entry ? entry->offset : invalidOffset;
+}
+    
+inline bool Structure::masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject)
+{
+    return typeInfo().masqueradesAsUndefined() && globalObject() == lexicalGlobalObject;
+}
+
+ALWAYS_INLINE void SlotVisitor::internalAppend(JSCell* cell)
+{
+    ASSERT(!m_isCheckingForDefaultMarkViolation);
+    if (!cell)
+        return;
+#if ENABLE(GC_VALIDATION)
+    validate(cell);
+#endif
+    if (Heap::testAndSetMarked(cell) || !cell->structure())
+        return;
+
+    m_visitCount++;
+        
+    MARK_LOG_CHILD(*this, cell);
+
+    // Should never attempt to mark something that is zapped.
+    ASSERT(!cell->isZapped());
+        
+    m_stack.append(cell);
+}
+
+inline bool Structure::transitivelyTransitionedFrom(Structure* structureToFind)
+{
+    for (Structure* current = this; current; current = current->previousID()) {
+        if (current == structureToFind)
+            return true;
+    }
+    return false;
+}
+
+inline void Structure::setEnumerationCache(JSGlobalData& globalData, JSPropertyNameIterator* enumerationCache)
+{
+    ASSERT(!isDictionary());
+    if (!typeInfo().structureHasRareData())
+        allocateRareData(globalData);
+    rareData()->setEnumerationCache(globalData, this, enumerationCache);
+}
+
+inline JSPropertyNameIterator* Structure::enumerationCache()
+{
+    if (!typeInfo().structureHasRareData())
+        return 0;
+    return rareData()->enumerationCache();
+}
+
 } // namespace JSC
 
 #endif // Structure_h
