Unreviewed, rolling out r144708.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Mar 2013 17:26:48 +0000 (17:26 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Mar 2013 17:26:48 +0000 (17:26 +0000)
http://trac.webkit.org/changeset/144708
https://bugs.webkit.org/show_bug.cgi?id=111447

random assertion crashes in inspector tests on qt+mac bots
(Requested by kling on #webkit).

Patch by Sheriff Bot <webkit.review.bot@gmail.com> on 2013-03-05

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.gypi:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
(JSGlobalData):
* runtime/PropertyMapHashTable.h:
(PropertyTable):
(JSC::PropertyTable::PropertyTable):
(JSC):
(JSC::PropertyTable::~PropertyTable):
(JSC::PropertyTable::copy):
* runtime/PropertyTable.cpp: Removed.
* runtime/Structure.cpp:
(JSC::Structure::dumpStatistics):
(JSC::Structure::materializePropertyMap):
(JSC::Structure::despecifyDictionaryFunction):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::changePrototypeTransition):
(JSC::Structure::despecifyFunctionTransition):
(JSC::Structure::attributeChangeTransition):
(JSC::Structure::toDictionaryTransition):
(JSC::Structure::sealTransition):
(JSC::Structure::freezeTransition):
(JSC::Structure::preventExtensionsTransition):
(JSC::Structure::nonPropertyTransition):
(JSC::Structure::isSealed):
(JSC::Structure::isFrozen):
(JSC::Structure::flattenDictionaryStructure):
(JSC::Structure::pin):
(JSC::Structure::copyPropertyTable):
(JSC::Structure::copyPropertyTableForPinning):
(JSC::Structure::get):
(JSC::Structure::despecifyFunction):
(JSC::Structure::despecifyAllFunctions):
(JSC::Structure::putSpecificValue):
(JSC::Structure::remove):
(JSC::Structure::createPropertyMap):
(JSC::Structure::getPropertyNamesFromStructure):
(JSC::Structure::visitChildren):
(JSC::Structure::checkConsistency):
* runtime/Structure.h:
(JSC):
(JSC::Structure::putWillGrowOutOfLineStorage):
(JSC::Structure::materializePropertyMapIfNecessary):
(JSC::Structure::materializePropertyMapIfNecessaryForPinning):
(JSC::Structure::checkOffsetConsistency):
(Structure):
* runtime/StructureInlines.h:
(JSC::Structure::get):
* runtime/WriteBarrier.h:
(JSC::WriteBarrierBase::get):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144767 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.gypi
Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/runtime/JSGlobalData.cpp
Source/JavaScriptCore/runtime/JSGlobalData.h
Source/JavaScriptCore/runtime/PropertyMapHashTable.h
Source/JavaScriptCore/runtime/PropertyTable.cpp [deleted file]
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureInlines.h
Source/JavaScriptCore/runtime/WriteBarrier.h

index 3bb3912..3bd6823 100644 (file)
@@ -280,7 +280,6 @@ set(JavaScriptCore_SOURCES
     runtime/PropertyDescriptor.cpp
     runtime/PropertyNameArray.cpp
     runtime/PropertySlot.cpp
-    runtime/PropertyTable.cpp
     runtime/PrototypeMap.cpp
     runtime/RegExp.cpp
     runtime/RegExpCache.cpp
index 5a21e2e..177e0c4 100644 (file)
@@ -1,3 +1,69 @@
+2013-03-05  Sheriff Bot  <webkit.review.bot@gmail.com>
+
+        Unreviewed, rolling out r144708.
+        http://trac.webkit.org/changeset/144708
+        https://bugs.webkit.org/show_bug.cgi?id=111447
+
+        random assertion crashes in inspector tests on qt+mac bots
+        (Requested by kling on #webkit).
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.gypi:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+        * runtime/JSGlobalData.cpp:
+        (JSC::JSGlobalData::JSGlobalData):
+        * runtime/JSGlobalData.h:
+        (JSGlobalData):
+        * runtime/PropertyMapHashTable.h:
+        (PropertyTable):
+        (JSC::PropertyTable::PropertyTable):
+        (JSC):
+        (JSC::PropertyTable::~PropertyTable):
+        (JSC::PropertyTable::copy):
+        * runtime/PropertyTable.cpp: Removed.
+        * runtime/Structure.cpp:
+        (JSC::Structure::dumpStatistics):
+        (JSC::Structure::materializePropertyMap):
+        (JSC::Structure::despecifyDictionaryFunction):
+        (JSC::Structure::addPropertyTransition):
+        (JSC::Structure::changePrototypeTransition):
+        (JSC::Structure::despecifyFunctionTransition):
+        (JSC::Structure::attributeChangeTransition):
+        (JSC::Structure::toDictionaryTransition):
+        (JSC::Structure::sealTransition):
+        (JSC::Structure::freezeTransition):
+        (JSC::Structure::preventExtensionsTransition):
+        (JSC::Structure::nonPropertyTransition):
+        (JSC::Structure::isSealed):
+        (JSC::Structure::isFrozen):
+        (JSC::Structure::flattenDictionaryStructure):
+        (JSC::Structure::pin):
+        (JSC::Structure::copyPropertyTable):
+        (JSC::Structure::copyPropertyTableForPinning):
+        (JSC::Structure::get):
+        (JSC::Structure::despecifyFunction):
+        (JSC::Structure::despecifyAllFunctions):
+        (JSC::Structure::putSpecificValue):
+        (JSC::Structure::remove):
+        (JSC::Structure::createPropertyMap):
+        (JSC::Structure::getPropertyNamesFromStructure):
+        (JSC::Structure::visitChildren):
+        (JSC::Structure::checkConsistency):
+        * runtime/Structure.h:
+        (JSC):
+        (JSC::Structure::putWillGrowOutOfLineStorage):
+        (JSC::Structure::materializePropertyMapIfNecessary):
+        (JSC::Structure::materializePropertyMapIfNecessaryForPinning):
+        (JSC::Structure::checkOffsetConsistency):
+        (Structure):
+        * runtime/StructureInlines.h:
+        (JSC::Structure::get):
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase::get):
+
 2013-03-05  David Kilzer  <ddkilzer@apple.com>
 
         BUILD FIX (r144698): Only enable SPEECH_SYNTHESIS for Mac
index 51d5a41..e8a1f2b 100644 (file)
@@ -722,7 +722,6 @@ javascriptcore_sources += \
        Source/JavaScriptCore/runtime/PropertyOffset.h \
        Source/JavaScriptCore/runtime/PropertySlot.cpp \
        Source/JavaScriptCore/runtime/PropertySlot.h \
-       Source/JavaScriptCore/runtime/PropertyTable.cpp \
        Source/JavaScriptCore/runtime/PrototypeMap.cpp \
        Source/JavaScriptCore/runtime/PrototypeMap.h \
        Source/JavaScriptCore/runtime/PropertyStorage.h \
index c27e7d6..0a9fb14 100644 (file)
             'runtime/PropertyOffset.h',
             'runtime/PropertySlot.cpp',
             'runtime/PropertySlot.h',
-            'runtime/PropertyTable.cpp',
             'runtime/PropertyStorage.h',
             'runtime/Protect.h',
             'runtime/PrototypeMap.cpp',
index 0fa914f..325e725 100644 (file)
     <ClCompile Include="..\runtime\PropertyDescriptor.cpp" />\r
     <ClCompile Include="..\runtime\PropertyNameArray.cpp" />\r
     <ClCompile Include="..\runtime\PropertySlot.cpp" />\r
-    <ClCompile Include="..\runtime\PropertyTable.cpp" />\r
     <ClCompile Include="..\runtime\PrototypeMap.cpp" />\r
     <ClCompile Include="..\runtime\RegExp.cpp" />\r
     <ClCompile Include="..\runtime\RegExpCache.cpp" />\r
index eaa393a..f50d36c 100644 (file)
                A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
                A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7FB604B103F5EAB0017A286 /* PropertyDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A8A4748E151A8306004123FF /* libWTF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A8A4748D151A8306004123FF /* libWTF.a */; };
-               ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */; };
                BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9050E1839DB000F9297 /* ErrorConstructor.h */; };
                BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9070E1839DB000F9297 /* ErrorPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC02E9110E1839DB000F9297 /* NativeErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC02E9090E1839DB000F9297 /* NativeErrorConstructor.h */; };
                A8A4748D151A8306004123FF /* libWTF.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libWTF.a; sourceTree = BUILT_PRODUCTS_DIR; };
                A8E894310CD0602400367179 /* JSCallbackObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackObjectFunctions.h; sourceTree = "<group>"; };
                A8E894330CD0603F00367179 /* JSGlobalObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObject.h; sourceTree = "<group>"; };
-               AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyTable.cpp; sourceTree = "<group>"; };
                BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ToolExecutable.xcconfig; sourceTree = "<group>"; };
                BC02E9040E1839DB000F9297 /* ErrorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ErrorConstructor.cpp; sourceTree = "<group>"; };
                BC02E9050E1839DB000F9297 /* ErrorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ErrorConstructor.h; sourceTree = "<group>"; };
                                65621E6B089E859700760F35 /* PropertySlot.cpp */,
                                65621E6C089E859700760F35 /* PropertySlot.h */,
                                0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */,
-                               AD1CF06816DCAB2D00B97123 /* PropertyTable.cpp */,
                                65C02FBB0637462A003E7EE6 /* Protect.h */,
                                14D844A216AA2C7000A65AF0 /* PrototypeMap.cpp */,
                                14D844A316AA2C7000A65AF0 /* PrototypeMap.h */,
                                0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */,
                                0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
                                0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
-                               ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 6608a07..58140f6 100644 (file)
@@ -298,7 +298,6 @@ SOURCES += \
     runtime/PropertyDescriptor.cpp \
     runtime/PropertyNameArray.cpp \
     runtime/PropertySlot.cpp \
-    runtime/PropertyTable.cpp \
     runtime/PrototypeMap.cpp \
     runtime/RegExpConstructor.cpp \
     runtime/RegExpCachedResult.cpp \
index 508a876..c06cf5c 100644 (file)
@@ -232,7 +232,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
     unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull()));
     unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull()));
     unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
-    propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
     smallStrings.initializeCommonStrings(*this);
 
     wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable);
index 1895a06..dc9881f 100644 (file)
@@ -256,7 +256,6 @@ namespace JSC {
         Strong<Structure> unlinkedProgramCodeBlockStructure;
         Strong<Structure> unlinkedEvalCodeBlockStructure;
         Strong<Structure> unlinkedFunctionCodeBlockStructure;
-        Strong<Structure> propertyTableStructure;
 
         IdentifierTable* identifierTable;
         CommonIdentifiers* propertyNames;
index 54e2973..2422c5b 100644 (file)
@@ -22,7 +22,6 @@
 #define PropertyMapHashTable_h
 
 #include "PropertyOffset.h"
-#include "Structure.h"
 #include "WriteBarrier.h"
 #include <wtf/HashTable.h>
 #include <wtf/MathExtras.h>
@@ -86,7 +85,8 @@ struct PropertyMapEntry {
     }
 };
 
-class PropertyTable : public JSCell {
+class PropertyTable {
+    WTF_MAKE_FAST_ALLOCATED;
 
     // This is the implementation for 'iterator' and 'const_iterator',
     // used for iterating over the table in insertion order.
@@ -129,19 +129,6 @@ class PropertyTable : public JSCell {
     };
 
 public:
-    static const bool needsDestruction = true;
-    static const bool hasImmortalStructure = true;
-    static void destroy(JSCell*);
-
-    static JS_EXPORTDATA const ClassInfo s_info;
-
-    static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
-    {
-        return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, OverridesVisitChildren), &s_info);
-    }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-
     typedef StringImpl* KeyType;
     typedef PropertyMapEntry ValueType;
 
@@ -155,9 +142,9 @@ public:
     typedef std::pair<ValueType*, unsigned> find_iterator;
 
     // Constructor is passed an initial capacity, a PropertyTable to copy, or both.
-    static PropertyTable* create(JSGlobalData&, unsigned initialCapacity);
-    static PropertyTable* clone(JSGlobalData&, JSCell* owner, const PropertyTable&);
-    static PropertyTable* clone(JSGlobalData&, JSCell* owner, unsigned initialCapacity, const PropertyTable&);
+    explicit PropertyTable(unsigned initialCapacity);
+    PropertyTable(JSGlobalData&, JSCell*, const PropertyTable&);
+    PropertyTable(JSGlobalData&, JSCell*, unsigned initialCapacity, const PropertyTable&);
     ~PropertyTable();
 
     // Ordered iteration methods.
@@ -194,7 +181,7 @@ public:
     PropertyOffset nextOffset(PropertyOffset inlineCapacity);
 
     // Copy this PropertyTable, ensuring the copy has at least the capacity provided.
-    PropertyTable* copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
+    PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity);
 
 #ifndef NDEBUG
     size_t sizeInMemory();
@@ -202,10 +189,6 @@ public:
 #endif
 
 private:
-    PropertyTable(JSGlobalData&, unsigned initialCapacity);
-    PropertyTable(JSGlobalData&, JSCell*, const PropertyTable&);
-    PropertyTable(JSGlobalData&, JSCell*, unsigned initialCapacity, const PropertyTable&);
-
     PropertyTable(const PropertyTable&);
     // Used to insert a value known not to be in the table, and where we know capacity to be available.
     void reinsert(const ValueType& entry);
@@ -256,6 +239,72 @@ private:
     static const unsigned EmptyEntryIndex = 0;
 };
 
+inline PropertyTable::PropertyTable(unsigned initialCapacity)
+    : m_indexSize(sizeForCapacity(initialCapacity))
+    , m_indexMask(m_indexSize - 1)
+    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+    , m_keyCount(0)
+    , m_deletedCount(0)
+{
+    ASSERT(isPowerOf2(m_indexSize));
+}
+
+inline PropertyTable::PropertyTable(JSGlobalData&, JSCell* owner, const PropertyTable& other)
+    : m_indexSize(other.m_indexSize)
+    , m_indexMask(other.m_indexMask)
+    , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
+    , m_keyCount(other.m_keyCount)
+    , m_deletedCount(other.m_deletedCount)
+{
+    ASSERT(isPowerOf2(m_indexSize));
+
+    memcpy(m_index, other.m_index, dataSize());
+
+    iterator end = this->end();
+    for (iterator iter = begin(); iter != end; ++iter) {
+        iter->key->ref();
+        Heap::writeBarrier(owner, iter->specificValue.get());
+    }
+
+    // Copy the m_deletedOffsets vector.
+    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
+    if (otherDeletedOffsets)
+        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+}
+
+inline PropertyTable::PropertyTable(JSGlobalData&, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
+    : m_indexSize(sizeForCapacity(initialCapacity))
+    , m_indexMask(m_indexSize - 1)
+    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
+    , m_keyCount(0)
+    , m_deletedCount(0)
+{
+    ASSERT(isPowerOf2(m_indexSize));
+    ASSERT(initialCapacity >= other.m_keyCount);
+
+    const_iterator end = other.end();
+    for (const_iterator iter = other.begin(); iter != end; ++iter) {
+        ASSERT(canInsert());
+        reinsert(*iter);
+        iter->key->ref();
+        Heap::writeBarrier(owner, iter->specificValue.get());
+    }
+
+    // Copy the m_deletedOffsets vector.
+    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
+    if (otherDeletedOffsets)
+        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
+}
+
+inline PropertyTable::~PropertyTable()
+{
+    iterator end = this->end();
+    for (iterator iter = begin(); iter != end; ++iter)
+        iter->key->deref();
+
+    fastFree(m_index);
+}
+
 inline PropertyTable::iterator PropertyTable::begin()
 {
     return iterator(skipDeletedEntries(table()));
@@ -453,15 +502,15 @@ inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity)
     return offsetForPropertyNumber(size(), inlineCapacity);
 }
 
-inline PropertyTable* PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
+inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity)
 {
     ASSERT(newCapacity >= m_keyCount);
 
     // Fast case; if the new table will be the same m_indexSize as this one, we can memcpy it,
     // save rehashing all keys.
     if (sizeForCapacity(newCapacity) == m_indexSize)
-        return PropertyTable::clone(globalData, owner, *this);
-    return PropertyTable::clone(globalData, owner, newCapacity, *this);
+        return adoptPtr(new PropertyTable(globalData, owner, *this));
+    return adoptPtr(new PropertyTable(globalData, owner, newCapacity, *this));
 }
 
 #ifndef NDEBUG
diff --git a/Source/JavaScriptCore/runtime/PropertyTable.cpp b/Source/JavaScriptCore/runtime/PropertyTable.cpp
deleted file mode 100644 (file)
index 99d2676..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "PropertyMapHashTable.h"
-
-#include "JSCJSValueInlines.h"
-#include "JSCellInlines.h"
-#include "SlotVisitorInlines.h"
-#include "StructureInlines.h"
-
-namespace JSC {
-
-const ClassInfo PropertyTable::s_info = { "PropertyTable", 0, 0, 0, CREATE_METHOD_TABLE(PropertyTable) };
-
-PropertyTable* PropertyTable::create(JSGlobalData& globalData, unsigned initialCapacity)
-{
-    PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(globalData.heap)) PropertyTable(globalData, initialCapacity);
-    table->finishCreation(globalData);
-    return table;
-}
-
-PropertyTable* PropertyTable::clone(JSGlobalData& globalData, JSCell* owner, const PropertyTable& other)
-{
-    PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(globalData.heap)) PropertyTable(globalData, owner, other);
-    table->finishCreation(globalData);
-    return table;
-}
-
-PropertyTable* PropertyTable::clone(JSGlobalData& globalData, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
-{
-    PropertyTable* table = new (NotNull, allocateCell<PropertyTable>(globalData.heap)) PropertyTable(globalData, owner, initialCapacity, other);
-    table->finishCreation(globalData);
-    return table;
-}
-
-PropertyTable::PropertyTable(JSGlobalData& globalData, unsigned initialCapacity)
-    : JSCell(globalData, globalData.propertyTableStructure.get())
-    , m_indexSize(sizeForCapacity(initialCapacity))
-    , m_indexMask(m_indexSize - 1)
-    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
-    , m_keyCount(0)
-    , m_deletedCount(0)
-{
-    ASSERT(isPowerOf2(m_indexSize));
-}
-
-PropertyTable::PropertyTable(JSGlobalData& globalData, JSCell* owner, const PropertyTable& other)
-    : JSCell(globalData, globalData.propertyTableStructure.get())
-    , m_indexSize(other.m_indexSize)
-    , m_indexMask(other.m_indexMask)
-    , m_index(static_cast<unsigned*>(fastMalloc(dataSize())))
-    , m_keyCount(other.m_keyCount)
-    , m_deletedCount(other.m_deletedCount)
-{
-    ASSERT(isPowerOf2(m_indexSize));
-
-    memcpy(m_index, other.m_index, dataSize());
-
-    iterator end = this->end();
-    for (iterator iter = begin(); iter != end; ++iter) {
-        iter->key->ref();
-        Heap::writeBarrier(owner, iter->specificValue.get());
-    }
-
-    // Copy the m_deletedOffsets vector.
-    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
-    if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
-}
-
-PropertyTable::PropertyTable(JSGlobalData& globalData, JSCell* owner, unsigned initialCapacity, const PropertyTable& other)
-    : JSCell(globalData, globalData.propertyTableStructure.get())
-    , m_indexSize(sizeForCapacity(initialCapacity))
-    , m_indexMask(m_indexSize - 1)
-    , m_index(static_cast<unsigned*>(fastZeroedMalloc(dataSize())))
-    , m_keyCount(0)
-    , m_deletedCount(0)
-{
-    ASSERT(isPowerOf2(m_indexSize));
-    ASSERT(initialCapacity >= other.m_keyCount);
-
-    const_iterator end = other.end();
-    for (const_iterator iter = other.begin(); iter != end; ++iter) {
-        ASSERT(canInsert());
-        reinsert(*iter);
-        iter->key->ref();
-        Heap::writeBarrier(owner, iter->specificValue.get());
-    }
-
-    // Copy the m_deletedOffsets vector.
-    Vector<PropertyOffset>* otherDeletedOffsets = other.m_deletedOffsets.get();
-    if (otherDeletedOffsets)
-        m_deletedOffsets = adoptPtr(new Vector<PropertyOffset>(*otherDeletedOffsets));
-}
-
-void PropertyTable::destroy(JSCell* cell)
-{
-    static_cast<PropertyTable*>(cell)->PropertyTable::~PropertyTable();
-}
-
-PropertyTable::~PropertyTable()
-{
-    iterator end = this->end();
-    for (iterator iter = begin(); iter != end; ++iter)
-        iter->key->deref();
-
-    fastFree(m_index);
-}
-
-void PropertyTable::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    PropertyTable* thisObject = jsCast<PropertyTable*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-
-    JSCell::visitChildren(thisObject, visitor);
-
-    PropertyTable::iterator end = thisObject->end();
-    for (PropertyTable::iterator ptr = thisObject->begin(); ptr != end; ++ptr)
-        visitor.append(&ptr->specificValue);
-}
-
-}
index 973166f..b79c106 100644 (file)
@@ -131,9 +131,9 @@ void Structure::dumpStatistics()
                 break;
         }
 
-        if (structure->propertyTable()) {
+        if (structure->m_propertyTable) {
             ++numberWithPropertyMaps;
-            totalPropertyMapsSize += structure->propertyTable()->sizeInMemory();
+            totalPropertyMapsSize += structure->m_propertyTable->sizeInMemory();
         }
     }
 
@@ -234,7 +234,7 @@ void Structure::destroy(JSCell* cell)
 void Structure::materializePropertyMap(JSGlobalData& globalData)
 {
     ASSERT(structure()->classInfo() == &s_info);
-    ASSERT(!propertyTable());
+    ASSERT(!m_propertyTable);
 
     Vector<Structure*, 8> structures;
     structures.append(this);
@@ -244,25 +244,25 @@ void Structure::materializePropertyMap(JSGlobalData& globalData)
     // Search for the last Structure with a property table.
     while ((structure = structure->previousID())) {
         if (structure->m_isPinnedPropertyTable) {
-            ASSERT(structure->propertyTable());
+            ASSERT(structure->m_propertyTable);
             ASSERT(!structure->previousID());
 
-            propertyTable().set(globalData, this, structure->propertyTable()->copy(globalData, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)));
+            m_propertyTable = structure->m_propertyTable->copy(globalData, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
             break;
         }
 
         structures.append(structure);
     }
 
-    if (!propertyTable())
-        createPropertyMap(globalData, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
+    if (!m_propertyTable)
+        createPropertyMap(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
 
     for (ptrdiff_t i = structures.size() - 1; i >= 0; --i) {
         structure = structures[i];
         if (!structure->m_nameInPrevious)
             continue;
         PropertyMapEntry entry(globalData, this, structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious.get());
-        propertyTable()->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
+        m_propertyTable->add(entry, m_offset, PropertyTable::PropertyOffsetMustNotChange);
     }
     
     checkOffsetConsistency();
@@ -287,9 +287,9 @@ void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyNa
     materializePropertyMapIfNecessary(globalData);
 
     ASSERT(isDictionary());
-    ASSERT(propertyTable());
+    ASSERT(m_propertyTable);
 
-    PropertyMapEntry* entry = propertyTable()->find(rep).first;
+    PropertyMapEntry* entry = m_propertyTable->find(rep).first;
     ASSERT(entry);
     entry->specificValue.clear();
 }
@@ -373,19 +373,17 @@ Structure* Structure::addPropertyTransition(JSGlobalData& globalData, Structure*
     transition->m_attributesInPrevious = attributes;
     transition->m_specificValueInPrevious.setMayBeNull(globalData, transition, specificValue);
 
-    if (structure->propertyTable()) {
+    if (structure->m_propertyTable) {
         structure->checkOffsetConsistency();
         if (structure->m_isPinnedPropertyTable)
-            transition->propertyTable().set(globalData, transition, structure->propertyTable()->copy(globalData, transition, structure->propertyTable()->size() + 1));
-        else {
-            transition->propertyTable().set(globalData, transition, structure->propertyTable().get());
-            structure->propertyTable().clear();
-        }
+            transition->m_propertyTable = structure->m_propertyTable->copy(globalData, transition, structure->m_propertyTable->size() + 1);
+        else
+            transition->m_propertyTable = structure->m_propertyTable.release();
     } else {
         if (structure->previousID())
             transition->materializePropertyMap(globalData);
         else
-            transition->createPropertyMap(globalData);
+            transition->createPropertyMap();
     }
     transition->m_offset = structure->m_offset;
 
@@ -417,7 +415,7 @@ Structure* Structure::changePrototypeTransition(JSGlobalData& globalData, Struct
     transition->m_prototype.set(globalData, transition, prototype);
 
     structure->materializePropertyMapIfNecessary(globalData);
-    transition->propertyTable().set(globalData, transition, structure->copyPropertyTableForPinning(globalData, transition));
+    transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
     transition->m_offset = structure->m_offset;
     transition->pin();
 
@@ -433,7 +431,7 @@ Structure* Structure::despecifyFunctionTransition(JSGlobalData& globalData, Stru
     ++transition->m_specificFunctionThrashCount;
 
     structure->materializePropertyMapIfNecessary(globalData);
-    transition->propertyTable().set(globalData, transition, structure->copyPropertyTableForPinning(globalData, transition));
+    transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
     transition->m_offset = structure->m_offset;
     transition->pin();
 
@@ -454,15 +452,15 @@ Structure* Structure::attributeChangeTransition(JSGlobalData& globalData, Struct
         Structure* transition = create(globalData, structure);
 
         structure->materializePropertyMapIfNecessary(globalData);
-        transition->propertyTable().set(globalData, transition, structure->copyPropertyTableForPinning(globalData, transition));
+        transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
         transition->m_offset = structure->m_offset;
         transition->pin();
         
         structure = transition;
     }
 
-    ASSERT(structure->propertyTable());
-    PropertyMapEntry* entry = structure->propertyTable()->find(propertyName.uid()).first;
+    ASSERT(structure->m_propertyTable);
+    PropertyMapEntry* entry = structure->m_propertyTable->find(propertyName.uid()).first;
     ASSERT(entry);
     entry->attributes = attributes;
 
@@ -477,7 +475,7 @@ Structure* Structure::toDictionaryTransition(JSGlobalData& globalData, Structure
     Structure* transition = create(globalData, structure);
 
     structure->materializePropertyMapIfNecessary(globalData);
-    transition->propertyTable().set(globalData, transition, structure->copyPropertyTableForPinning(globalData, transition));
+    transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
     transition->m_offset = structure->m_offset;
     transition->m_dictionaryKind = kind;
     transition->pin();
@@ -501,9 +499,9 @@ Structure* Structure::sealTransition(JSGlobalData& globalData, Structure* struct
 {
     Structure* transition = preventExtensionsTransition(globalData, structure);
 
-    if (transition->propertyTable()) {
-        PropertyTable::iterator end = transition->propertyTable()->end();
-        for (PropertyTable::iterator iter = transition->propertyTable()->begin(); iter != end; ++iter)
+    if (transition->m_propertyTable) {
+        PropertyTable::iterator end = transition->m_propertyTable->end();
+        for (PropertyTable::iterator iter = transition->m_propertyTable->begin(); iter != end; ++iter)
             iter->attributes |= DontDelete;
     }
 
@@ -516,9 +514,9 @@ Structure* Structure::freezeTransition(JSGlobalData& globalData, Structure* stru
 {
     Structure* transition = preventExtensionsTransition(globalData, structure);
 
-    if (transition->propertyTable()) {
-        PropertyTable::iterator iter = transition->propertyTable()->begin();
-        PropertyTable::iterator end = transition->propertyTable()->end();
+    if (transition->m_propertyTable) {
+        PropertyTable::iterator iter = transition->m_propertyTable->begin();
+        PropertyTable::iterator end = transition->m_propertyTable->end();
         if (iter != end)
             transition->m_hasReadOnlyOrGetterSetterPropertiesExcludingProto = true;
         for (; iter != end; ++iter)
@@ -537,7 +535,7 @@ Structure* Structure::preventExtensionsTransition(JSGlobalData& globalData, Stru
     // Don't set m_offset, as one can not transition to this.
 
     structure->materializePropertyMapIfNecessary(globalData);
-    transition->propertyTable().set(globalData, transition, structure->copyPropertyTableForPinning(globalData, transition));
+    transition->m_propertyTable = structure->copyPropertyTableForPinning(globalData, transition);
     transition->m_offset = structure->m_offset;
     transition->m_preventExtensions = true;
     transition->pin();
@@ -574,19 +572,17 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure*
     transition->m_offset = structure->m_offset;
     checkOffset(transition->m_offset, transition->inlineCapacity());
     
-    if (structure->propertyTable()) {
+    if (structure->m_propertyTable) {
         structure->checkOffsetConsistency();
         if (structure->m_isPinnedPropertyTable)
-            transition->propertyTable().set(globalData, transition, structure->propertyTable()->copy(globalData, transition, structure->propertyTable()->size() + 1));
-        else {
-            transition->propertyTable().set(globalData, transition, structure->propertyTable().get());
-            structure->propertyTable().clear();
-        }
+            transition->m_propertyTable = structure->m_propertyTable->copy(globalData, transition, structure->m_propertyTable->size() + 1);
+        else
+            transition->m_propertyTable = structure->m_propertyTable.release();
     } else {
         if (structure->previousID())
             transition->materializePropertyMap(globalData);
         else
-            transition->createPropertyMap(globalData);
+            transition->createPropertyMap();
     }
     
     structure->m_transitionTable.add(globalData, transition);
@@ -601,11 +597,11 @@ bool Structure::isSealed(JSGlobalData& globalData)
         return false;
 
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return true;
 
-    PropertyTable::iterator end = propertyTable()->end();
-    for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
+    PropertyTable::iterator end = m_propertyTable->end();
+    for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
         if ((iter->attributes & DontDelete) != DontDelete)
             return false;
     }
@@ -619,11 +615,11 @@ bool Structure::isFrozen(JSGlobalData& globalData)
         return false;
 
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return true;
 
-    PropertyTable::iterator end = propertyTable()->end();
-    for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
+    PropertyTable::iterator end = m_propertyTable->end();
+    for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
         if (!(iter->attributes & DontDelete))
             return false;
         if (!(iter->attributes & (ReadOnly | Accessor)))
@@ -637,18 +633,18 @@ Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObj
     checkOffsetConsistency();
     ASSERT(isDictionary());
     if (isUncacheableDictionary()) {
-        ASSERT(propertyTable());
+        ASSERT(m_propertyTable);
 
-        size_t propertyCount = propertyTable()->size();
+        size_t propertyCount = m_propertyTable->size();
 
         // Holds our values compacted by insertion order.
         Vector<JSValue> values(propertyCount);
 
         // Copies out our values from their hashed locations, compacting property table offsets as we go.
         unsigned i = 0;
-        PropertyTable::iterator end = propertyTable()->end();
+        PropertyTable::iterator end = m_propertyTable->end();
         m_offset = invalidOffset;
-        for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter, ++i) {
+        for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter, ++i) {
             values[i] = object->getDirect(iter->offset);
             m_offset = iter->offset = offsetForPropertyNumber(i, m_inlineCapacity);
         }
@@ -657,7 +653,7 @@ Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObj
         for (unsigned i = 0; i < propertyCount; i++)
             object->putDirect(globalData, offsetForPropertyNumber(i, m_inlineCapacity), values[i]);
 
-        propertyTable()->clearDeletedOffsets();
+        m_propertyTable->clearDeletedOffsets();
         checkOffsetConsistency();
     }
 
@@ -692,7 +688,7 @@ PropertyOffset Structure::removePropertyWithoutTransition(JSGlobalData& globalDa
 
 void Structure::pin()
 {
-    ASSERT(propertyTable());
+    ASSERT(m_propertyTable);
     m_isPinnedPropertyTable = true;
     clearPreviousID();
     m_nameInPrevious.clear();
@@ -741,18 +737,14 @@ inline void Structure::checkConsistency()
 
 #endif
 
-PropertyTable* Structure::copyPropertyTable(JSGlobalData& globalData, Structure* owner)
+PassOwnPtr<PropertyTable> Structure::copyPropertyTable(JSGlobalData& globalData, Structure* owner)
 {
-    if (!propertyTable())
-        return 0;
-    return PropertyTable::clone(globalData, owner, *propertyTable().get());
+    return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : 0);
 }
 
-PropertyTable* Structure::copyPropertyTableForPinning(JSGlobalData& globalData, Structure* owner)
+PassOwnPtr<PropertyTable> Structure::copyPropertyTableForPinning(JSGlobalData& globalData, Structure* owner)
 {
-    if (propertyTable())
-        return PropertyTable::clone(globalData, owner, *propertyTable().get());
-    return PropertyTable::create(globalData, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
+    return adoptPtr(m_propertyTable ? new PropertyTable(globalData, owner, *m_propertyTable) : new PropertyTable(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity)));
 }
 
 PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyName, unsigned& attributes, JSCell*& specificValue)
@@ -760,10 +752,10 @@ PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyNam
     ASSERT(structure()->classInfo() == &s_info);
 
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return invalidOffset;
 
-    PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     if (!entry)
         return invalidOffset;
 
@@ -775,10 +767,10 @@ PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName propertyNam
 bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propertyName)
 {
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return false;
 
-    PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     if (!entry)
         return false;
 
@@ -790,11 +782,11 @@ bool Structure::despecifyFunction(JSGlobalData& globalData, PropertyName propert
 void Structure::despecifyAllFunctions(JSGlobalData& globalData)
 {
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return;
 
-    PropertyTable::iterator end = propertyTable()->end();
-    for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter)
+    PropertyTable::iterator end = m_propertyTable->end();
+    for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter)
         iter->specificValue.clear();
 }
 
@@ -808,12 +800,12 @@ PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyNam
 
     StringImpl* rep = propertyName.uid();
 
-    if (!propertyTable())
-        createPropertyMap(globalData);
+    if (!m_propertyTable)
+        createPropertyMap();
 
-    PropertyOffset newOffset = propertyTable()->nextOffset(m_inlineCapacity);
+    PropertyOffset newOffset = m_propertyTable->nextOffset(m_inlineCapacity);
 
-    propertyTable()->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange);
+    m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue), m_offset, PropertyTable::PropertyOffsetMayChange);
     
     checkConsistency();
     return newOffset;
@@ -825,40 +817,40 @@ PropertyOffset Structure::remove(PropertyName propertyName)
 
     StringImpl* rep = propertyName.uid();
 
-    if (!propertyTable())
+    if (!m_propertyTable)
         return invalidOffset;
 
-    PropertyTable::find_iterator position = propertyTable()->find(rep);
+    PropertyTable::find_iterator position = m_propertyTable->find(rep);
     if (!position.first)
         return invalidOffset;
 
     PropertyOffset offset = position.first->offset;
 
-    propertyTable()->remove(position);
-    propertyTable()->addDeletedOffset(offset);
+    m_propertyTable->remove(position);
+    m_propertyTable->addDeletedOffset(offset);
 
     checkConsistency();
     return offset;
 }
 
-void Structure::createPropertyMap(JSGlobalData& globalData, unsigned capacity)
+void Structure::createPropertyMap(unsigned capacity)
 {
-    ASSERT(!propertyTable());
+    ASSERT(!m_propertyTable);
 
     checkConsistency();
-    propertyTable().set(globalData, this, PropertyTable::create(globalData, capacity));
+    m_propertyTable = adoptPtr(new PropertyTable(capacity));
 }
 
 void Structure::getPropertyNamesFromStructure(JSGlobalData& globalData, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return;
 
     bool knownUnique = !propertyNames.size();
 
-    PropertyTable::iterator end = propertyTable()->end();
-    for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
+    PropertyTable::iterator end = m_propertyTable->end();
+    for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
         ASSERT(m_hasNonEnumerableProperties || !(iter->attributes & DontEnum));
         if (iter->key->isIdentifier() && (!(iter->attributes & DontEnum) || mode == IncludeDontEnumProperties)) {
             if (knownUnique)
@@ -890,12 +882,11 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor)
     }
     visitor.append(&thisObject->m_previousOrRareData);
     visitor.append(&thisObject->m_specificValueInPrevious);
-
-    if (thisObject->m_isPinnedPropertyTable) {
-        ASSERT(thisObject->m_propertyTableUnsafe);
-        visitor.append(&thisObject->m_propertyTableUnsafe);
-    } else if (thisObject->m_propertyTableUnsafe)
-        thisObject->m_propertyTableUnsafe.clear();
+    if (thisObject->m_propertyTable) {
+        PropertyTable::iterator end = thisObject->m_propertyTable->end();
+        for (PropertyTable::iterator ptr = thisObject->m_propertyTable->begin(); ptr != end; ++ptr)
+            visitor.append(&ptr->specificValue);
+    }
 }
 
 bool Structure::prototypeChainMayInterceptStoreTo(JSGlobalData& globalData, PropertyName propertyName)
@@ -986,17 +977,17 @@ void PropertyTable::checkConsistency()
 
 void Structure::checkConsistency()
 {
-    if (!propertyTable())
+    if (!m_propertyTable)
         return;
 
     if (!m_hasNonEnumerableProperties) {
-        PropertyTable::iterator end = propertyTable()->end();
-        for (PropertyTable::iterator iter = propertyTable()->begin(); iter != end; ++iter) {
+        PropertyTable::iterator end = m_propertyTable->end();
+        for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter) {
             ASSERT(!(iter->attributes & DontEnum));
         }
     }
 
-    propertyTable()->checkConsistency();
+    m_propertyTable->checkConsistency();
 }
 
 #endif // DO_PROPERTYMAP_CONSTENCY_CHECK
index 303be39..2359c6c 100644 (file)
 #include "JSCJSValue.h"
 #include "JSCell.h"
 #include "JSType.h"
+#include "PropertyMapHashTable.h"
 #include "PropertyName.h"
 #include "PropertyNameArray.h"
-#include "PropertyOffset.h"
 #include "Protect.h"
 #include "StructureRareData.h"
 #include "StructureTransitionTable.h"
 #include "JSTypeInfo.h"
 #include "Watchpoint.h"
 #include "Weak.h"
+#include <wtf/PassOwnPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/text/StringImpl.h>
@@ -50,7 +51,6 @@ namespace JSC {
 class LLIntOffsetsExtractor;
 class PropertyNameArray;
 class PropertyNameArrayData;
-class PropertyTable;
 class StructureChain;
 class SlotVisitor;
 class JSString;
@@ -108,7 +108,25 @@ public:
     bool isFrozen(JSGlobalData&);
     bool isExtensible() const { return !m_preventExtensions; }
     bool didTransition() const { return m_didTransition; }
-    bool putWillGrowOutOfLineStorage();
+    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*);
@@ -364,29 +382,27 @@ private:
     PropertyOffset putSpecificValue(JSGlobalData&, PropertyName, unsigned attributes, JSCell* specificValue);
     PropertyOffset remove(PropertyName);
 
-    void createPropertyMap(JSGlobalData&, unsigned keyCount = 0);
+    void createPropertyMap(unsigned keyCount = 0);
     void checkConsistency();
 
     bool despecifyFunction(JSGlobalData&, PropertyName);
     void despecifyAllFunctions(JSGlobalData&);
 
-    WriteBarrier<PropertyTable>& propertyTable();
-
-    PropertyTable* copyPropertyTable(JSGlobalData&, Structure* owner);
-    PropertyTable* copyPropertyTableForPinning(JSGlobalData&, Structure* owner);
+    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 (!propertyTable() && previousID())
+        if (!m_propertyTable && previousID())
             materializePropertyMap(globalData);
     }
     void materializePropertyMapIfNecessaryForPinning(JSGlobalData& globalData)
     {
         ASSERT(structure()->classInfo() == &s_info);
         checkOffsetConsistency();
-        if (!propertyTable())
+        if (!m_propertyTable)
             materializePropertyMap(globalData);
     }
 
@@ -429,7 +445,19 @@ private:
         return static_cast<StructureRareData*>(m_previousOrRareData.get());
     }
         
-    bool checkOffsetConsistency() const;
+    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*);
@@ -454,8 +482,7 @@ private:
 
     StructureTransitionTable m_transitionTable;
 
-    // Should be accessed through propertyTable(). During GC, it may be set to 0 by another thread.
-    WriteBarrier<PropertyTable> m_propertyTableUnsafe;
+    OwnPtr<PropertyTable> m_propertyTable;
 
     mutable InlineWatchpointSet m_transitionWatchpointSet;
 
index 522e827..5bfd2d5 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef StructureInlines_h
 #define StructureInlines_h
 
-#include "PropertyMapHashTable.h"
 #include "Structure.h"
 
 namespace JSC {
@@ -62,10 +61,10 @@ inline PropertyOffset Structure::get(JSGlobalData& globalData, PropertyName prop
 {
     ASSERT(structure()->classInfo() == &s_info);
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return invalidOffset;
 
-    PropertyMapEntry* entry = propertyTable()->find(propertyName.uid()).first;
+    PropertyMapEntry* entry = m_propertyTable->find(propertyName.uid()).first;
     return entry ? entry->offset : invalidOffset;
 }
 
@@ -73,10 +72,10 @@ inline PropertyOffset Structure::get(JSGlobalData& globalData, const WTF::String
 {
     ASSERT(structure()->classInfo() == &s_info);
     materializePropertyMapIfNecessary(globalData);
-    if (!propertyTable())
+    if (!m_propertyTable)
         return invalidOffset;
 
-    PropertyMapEntry* entry = propertyTable()->findWithString(name.impl()).first;
+    PropertyMapEntry* entry = m_propertyTable->findWithString(name.impl()).first;
     return entry ? entry->offset : invalidOffset;
 }
     
@@ -180,48 +179,6 @@ inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeC
     return isValid(exec->lexicalGlobalObject(), cachedPrototypeChain);
 }
 
-inline bool Structure::putWillGrowOutOfLineStorage()
-{
-    checkOffsetConsistency();
-
-    ASSERT(outOfLineCapacity() >= outOfLineSize());
-
-    if (!propertyTable()) {
-        unsigned currentSize = numberOfOutOfLineSlotsForLastOffset(m_offset);
-        ASSERT(outOfLineCapacity() >= currentSize);
-        return currentSize == outOfLineCapacity();
-    }
-
-    ASSERT(totalStorageCapacity() >= propertyTable()->propertyStorageSize());
-    if (propertyTable()->hasDeletedOffset())
-        return false;
-
-    ASSERT(totalStorageCapacity() >= propertyTable()->size());
-    return propertyTable()->size() == totalStorageCapacity();
-}
-
-ALWAYS_INLINE WriteBarrier<PropertyTable>& Structure::propertyTable()
-{
-    ASSERT(!globalObject() || !globalObject()->globalData().heap.isBusy());
-    return m_propertyTableUnsafe;
-}
-
-ALWAYS_INLINE bool Structure::checkOffsetConsistency() const
-{
-    PropertyTable* propertyTable = m_propertyTableUnsafe.get();
-
-    if (!propertyTable) {
-        ASSERT(!m_isPinnedPropertyTable);
-        return true;
-    }
-
-    RELEASE_ASSERT(numberOfSlotsForLastOffset(m_offset, m_inlineCapacity) == propertyTable->propertyStorageSize());
-    unsigned totalSize = propertyTable->propertyStorageSize();
-    RELEASE_ASSERT((totalSize < inlineCapacity() ? 0 : totalSize - inlineCapacity()) == numberOfOutOfLineSlotsForLastOffset(m_offset));
-
-    return true;
-}
-
 } // namespace JSC
 
 #endif // StructureInlines_h
index 6fa8b63..ef8c3af 100644 (file)
@@ -99,11 +99,9 @@ public:
     
     T* get() const
     {
-        // Copy m_cell to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>)
-        JSCell* cell = m_cell;
-        if (cell)
-            validateCell(cell);
-        return reinterpret_cast<T*>(static_cast<void*>(cell));
+        if (m_cell)
+            validateCell(m_cell);
+        return reinterpret_cast<T*>(static_cast<void*>(m_cell));
     }
 
     T* operator*() const