Commit 59415ea5 authored by mhahnenberg@apple.com's avatar mhahnenberg@apple.com

Replace JSArray destructor with finalizer

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
parent a940bf03
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
......@@ -15,5 +15,13 @@ shouldBe('array[0]', 'NaN');
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('');
......@@ -11,6 +11,10 @@ PASS array[0] is NaN
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
......@@ -288,10 +288,8 @@ __ZN3JSC7JSArray17defineOwnPropertyEPNS_8JSObjectEPNS_9ExecStateERKNS_10Identifi
__ZN3JSC7JSArray25getOwnPropertySlotByIndexEPNS_6JSCellEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3JSC7JSArray30tryFinishCreationUninitializedERNS_12JSGlobalDataEj
__ZN3JSC7JSArray6s_infoE
__ZN3JSC7JSArray7destroyEPNS_6JSCellE
__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureE
__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureE
__ZN3JSC7JSArrayD2Ev
__ZN3JSC7JSValue13isValidCalleeEv
__ZN3JSC7Options17numberOfGCMarkersE
__ZN3JSC7Options24opaqueRootMergeThresholdE
......
......@@ -200,16 +200,12 @@ JSArray* JSArray::tryFinishCreationUninitialized(JSGlobalData& globalData, unsig
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)
......@@ -309,13 +305,27 @@ inline void SparseArrayValueMap::visitChildren(SlotVisitor& visitor)
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;
......@@ -404,7 +414,7 @@ bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, Property
return true;
}
enterSparseMode(exec->globalData());
enterDictionaryMode(exec->globalData());
}
SparseArrayValueMap* map = m_sparseValueMap;
......@@ -514,7 +524,7 @@ void JSArray::setLengthWritable(ExecState* exec, bool writable)
if (!isLengthWritable() || writable)
return;
enterSparseMode(exec->globalData());
enterDictionaryMode(exec->globalData());
SparseArrayValueMap* map = m_sparseValueMap;
ASSERT(map);
......@@ -787,8 +797,8 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
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;
}
......@@ -822,8 +832,7 @@ NEVER_INLINE void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigne
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];
......@@ -1134,10 +1143,8 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException
} 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();
}
}
}
......@@ -1202,10 +1209,8 @@ JSValue JSArray::pop(ExecState* exec)
}
map->remove(it);
if (map->isEmpty() && !map->sparseMode()) {
delete map;
m_sparseValueMap = 0;
}
if (map->isEmpty() && !map->sparseMode())
deallocateSparseMap();
}
}
}
......@@ -1640,8 +1645,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
++numDefined;
}
delete map;
m_sparseValueMap = 0;
deallocateSparseMap();
}
ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
......@@ -1753,8 +1757,7 @@ unsigned JSArray::compactForSorting(JSGlobalData& globalData)
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)
......
......@@ -133,8 +133,7 @@ namespace JSC {
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)
{
......@@ -275,7 +274,9 @@ namespace JSC {
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment