https://bugs.webkit.org/show_bug.cgi?id=77488
Reviewed by Geoffrey Garen.
Source/JavaScriptCore:
* JavaScriptCore.exp:
* runtime/JSArray.cpp:
(JSC::JSArray::finalize): Added finalizer.
(JSC::JSArray::allocateSparseMap): Factored out code for allocating new sparse maps.
(JSC):
(JSC::JSArray::deallocateSparseMap): Factored out code for deallocating sparse maps.
(JSC::JSArray::enterDictionaryMode): Renamed enterSparseMode to enterDictionaryMode
because the old name was confusing because we could have a sparse array that never
called enterSparseMode.
(JSC::JSArray::defineOwnNumericProperty):
(JSC::JSArray::setLengthWritable):
(JSC::JSArray::putByIndexBeyondVectorLength):
(JSC::JSArray::setLength):
(JSC::JSArray::pop):
(JSC::JSArray::sort):
(JSC::JSArray::compactForSorting):
* runtime/JSArray.h:
(JSArray):
LayoutTests:
* fast/js/script-tests/sparse-array.js: Added code to test oscillation between
sparse and dense arrays.
* fast/js/sparse-array-expected.txt:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@106496
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-02-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Replace JSArray destructor with finalizer
+ https://bugs.webkit.org/show_bug.cgi?id=77488
+
+ Reviewed by Geoffrey Garen.
+
+ * fast/js/script-tests/sparse-array.js: Added code to test oscillation between
+ sparse and dense arrays.
+ * fast/js/sparse-array-expected.txt:
+
2012-02-01 Elliot Poger <epoger@google.com>
rebaseline box-shadow-clipped-slices
shouldBe('array[49999]', 'undefined');
shouldBe('array[50000]', '100');
shouldBe('array[50001]', 'undefined');
+// This tests oscillation between being sparse and dense.
+delete array[50000];
+array.length = 5;
+array[50000] = 100;
+shouldBe('array[0]', 'NaN');
+shouldBe('array[49999]', 'undefined');
+shouldBe('array[50000]', '100');
+shouldBe('array[50001]', 'undefined');
debug('');
PASS array[49999] is undefined
PASS array[50000] is 100
PASS array[50001] is undefined
+PASS array[0] is NaN
+PASS array[49999] is undefined
+PASS array[50000] is 100
+PASS array[50001] is undefined
PASS successfullyParsed is true
+2012-02-01 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Replace JSArray destructor with finalizer
+ https://bugs.webkit.org/show_bug.cgi?id=77488
+
+ Reviewed by Geoffrey Garen.
+
+ * JavaScriptCore.exp:
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::finalize): Added finalizer.
+ (JSC::JSArray::allocateSparseMap): Factored out code for allocating new sparse maps.
+ (JSC):
+ (JSC::JSArray::deallocateSparseMap): Factored out code for deallocating sparse maps.
+ (JSC::JSArray::enterDictionaryMode): Renamed enterSparseMode to enterDictionaryMode
+ because the old name was confusing because we could have a sparse array that never
+ called enterSparseMode.
+ (JSC::JSArray::defineOwnNumericProperty):
+ (JSC::JSArray::setLengthWritable):
+ (JSC::JSArray::putByIndexBeyondVectorLength):
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::compactForSorting):
+ * runtime/JSArray.h:
+ (JSArray):
+
2012-02-01 Andy Wingo <wingo@igalia.com>
Refactor identifier resolution in BytecodeGenerator
__ZN3JSC7JSArray25getOwnPropertySlotByIndexEPNS_6JSCellEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3JSC7JSArray30tryFinishCreationUninitializedERNS_12JSGlobalDataEj
__ZN3JSC7JSArray6s_infoE
-__ZN3JSC7JSArray7destroyEPNS_6JSCellE
__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureE
__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureE
-__ZN3JSC7JSArrayD2Ev
__ZN3JSC7JSValue13isValidCalleeEv
__ZN3JSC7Options17numberOfGCMarkersE
__ZN3JSC7Options24opaqueRootMergeThresholdE
return this;
}
-JSArray::~JSArray()
+// This function can be called multiple times on the same object.
+void JSArray::finalize(JSCell* cell)
{
- ASSERT(jsCast<JSArray*>(this));
- checkConsistency(DestructorConsistencyCheck);
- delete m_sparseValueMap;
-}
-
-void JSArray::destroy(JSCell* cell)
-{
- jsCast<JSArray*>(cell)->JSArray::~JSArray();
+ JSArray* thisObject = jsCast<JSArray*>(cell);
+ thisObject->checkConsistency(DestructorConsistencyCheck);
+ thisObject->deallocateSparseMap();
}
inline std::pair<SparseArrayValueMap::iterator, bool> SparseArrayValueMap::add(JSArray* array, unsigned i)
visitor.append(&it->second);
}
-void JSArray::enterSparseMode(JSGlobalData& globalData)
+void JSArray::allocateSparseMap(JSGlobalData& globalData)
+{
+ m_sparseValueMap = new SparseArrayValueMap;
+ globalData.heap.addFinalizer(this, finalize);
+}
+
+void JSArray::deallocateSparseMap()
+{
+ delete m_sparseValueMap;
+ m_sparseValueMap = 0;
+}
+
+void JSArray::enterDictionaryMode(JSGlobalData& globalData)
{
ArrayStorage* storage = m_storage;
SparseArrayValueMap* map = m_sparseValueMap;
- if (!map)
- map = m_sparseValueMap = new SparseArrayValueMap;
+ if (!map) {
+ allocateSparseMap(globalData);
+ map = m_sparseValueMap;
+ }
if (map->sparseMode())
return;
return true;
}
- enterSparseMode(exec->globalData());
+ enterDictionaryMode(exec->globalData());
}
SparseArrayValueMap* map = m_sparseValueMap;
if (!isLengthWritable() || writable)
return;
- enterSparseMode(exec->globalData());
+ enterDictionaryMode(exec->globalData());
SparseArrayValueMap* map = m_sparseValueMap;
ASSERT(map);
return;
}
// We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value.
- map = new SparseArrayValueMap;
- m_sparseValueMap = map;
+ allocateSparseMap(exec->globalData());
+ map = m_sparseValueMap;
map->put(exec, this, i, value);
return;
}
SparseArrayValueMap::const_iterator end = map->end();
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
vector[it->first].set(globalData, this, it->second.getNonSparseMode());
- delete map;
- m_sparseValueMap = 0;
+ deallocateSparseMap();
// Store the new property into the vector.
WriteBarrier<Unknown>& valueSlot = vector[i];
} else {
for (unsigned i = 0; i < keys.size(); ++i)
map->remove(keys[i]);
- if (map->isEmpty()) {
- delete map;
- m_sparseValueMap = 0;
- }
+ if (map->isEmpty())
+ deallocateSparseMap();
}
}
}
}
map->remove(it);
- if (map->isEmpty() && !map->sparseMode()) {
- delete map;
- m_sparseValueMap = 0;
- }
+ if (map->isEmpty() && !map->sparseMode())
+ deallocateSparseMap();
}
}
}
++numDefined;
}
- delete map;
- m_sparseValueMap = 0;
+ deallocateSparseMap();
}
ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it)
storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.getNonSparseMode());
- delete map;
- m_sparseValueMap = 0;
+ deallocateSparseMap();
}
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
public:
typedef JSNonFinalObject Base;
- JS_EXPORT_PRIVATE ~JSArray();
- JS_EXPORT_PRIVATE static void destroy(JSCell*);
+ static void finalize(JSCell*);
static JSArray* create(JSGlobalData& globalData, Structure* structure, unsigned initialLength = 0)
{
void setLengthWritable(ExecState*, bool writable);
void putDescriptor(ExecState*, SparseArrayEntry*, PropertyDescriptor&, PropertyDescriptor& old);
bool defineOwnNumericProperty(ExecState*, unsigned, PropertyDescriptor&, bool throwException);
- void enterSparseMode(JSGlobalData&);
+ void enterDictionaryMode(JSGlobalData&);
+ void allocateSparseMap(JSGlobalData&);
+ void deallocateSparseMap();
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue);