[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
barraclough at apple.com
barraclough at apple.com
Wed Dec 22 11:31:29 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 616284aa4d9434685f2066802e4272ad9bc21509
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Jul 28 00:36:56 2010 +0000
Temporarily rolling out http://trac.webkit.org/changeset/64177,
this seems to give QT ARM/Win a headache (specifically, looks
like structure layour differs, objects get too large -
"..\..\..\JavaScriptCore\runtime\ArrayPrototype.cpp:41:"
"error: size of array 'dummyclass_fits_in_cell' is negative").
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::privateCompilePatchGetArrayLength):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_get_by_val):
(JSC::JIT::emit_op_put_by_val):
(JSC::JIT::privateCompilePatchGetArrayLength):
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncShift):
(JSC::arrayProtoFuncSplice):
(JSC::arrayProtoFuncUnShift):
* runtime/JSArray.cpp:
(JSC::increasedVectorLength):
(JSC::JSArray::JSArray):
(JSC::JSArray::~JSArray):
(JSC::JSArray::getOwnPropertySlot):
(JSC::JSArray::getOwnPropertyDescriptor):
(JSC::JSArray::put):
(JSC::JSArray::putSlowCase):
(JSC::JSArray::deleteProperty):
(JSC::JSArray::getOwnPropertyNames):
(JSC::JSArray::increaseVectorLength):
(JSC::JSArray::setLength):
(JSC::JSArray::pop):
(JSC::JSArray::push):
(JSC::JSArray::sortNumeric):
(JSC::JSArray::sort):
(JSC::JSArray::fillArgList):
(JSC::JSArray::copyToRegisters):
(JSC::JSArray::compactForSorting):
(JSC::JSArray::subclassData):
(JSC::JSArray::setSubclassData):
(JSC::JSArray::checkConsistency):
* runtime/JSArray.h:
(JSC::JSArray::length):
(JSC::JSArray::canGetIndex):
(JSC::JSArray::getIndex):
(JSC::JSArray::setIndex):
(JSC::JSArray::uncheckedSetIndex):
(JSC::JSArray::markChildrenDirect):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64184 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 2844f59..6ba333c 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,5 +1,55 @@
2010-07-27 Gavin Barraclough <barraclough at apple.com>
+ Temporarily rolling out http://trac.webkit.org/changeset/64177,
+ this seems to give QT ARM/Win a headache (specifically, looks
+ like structure layour differs, objects get too large -
+ "..\..\..\JavaScriptCore\runtime\ArrayPrototype.cpp:41:"
+ "error: size of array 'dummyclass_fits_in_cell' is negative").
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncShift):
+ (JSC::arrayProtoFuncSplice):
+ (JSC::arrayProtoFuncUnShift):
+ * runtime/JSArray.cpp:
+ (JSC::increasedVectorLength):
+ (JSC::JSArray::JSArray):
+ (JSC::JSArray::~JSArray):
+ (JSC::JSArray::getOwnPropertySlot):
+ (JSC::JSArray::getOwnPropertyDescriptor):
+ (JSC::JSArray::put):
+ (JSC::JSArray::putSlowCase):
+ (JSC::JSArray::deleteProperty):
+ (JSC::JSArray::getOwnPropertyNames):
+ (JSC::JSArray::increaseVectorLength):
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::sortNumeric):
+ (JSC::JSArray::sort):
+ (JSC::JSArray::fillArgList):
+ (JSC::JSArray::copyToRegisters):
+ (JSC::JSArray::compactForSorting):
+ (JSC::JSArray::subclassData):
+ (JSC::JSArray::setSubclassData):
+ (JSC::JSArray::checkConsistency):
+ * runtime/JSArray.h:
+ (JSC::JSArray::length):
+ (JSC::JSArray::canGetIndex):
+ (JSC::JSArray::getIndex):
+ (JSC::JSArray::setIndex):
+ (JSC::JSArray::uncheckedSetIndex):
+ (JSC::JSArray::markChildrenDirect):
+
+2010-07-27 Gavin Barraclough <barraclough at apple.com>
+
Speculative build fix for Chromium/Win
* wtf/Platform.h:
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
index 10dcd3f..580e73f 100644
--- a/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -103,10 +103,10 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, base);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
- loadPtr(BaseIndex(regT2, regT1, ScalePtr), regT0);
+ loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0);
addSlowCase(branchTestPtr(Zero, regT0));
emitPutVirtualRegister(dst);
@@ -214,21 +214,22 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2);
- Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+
+ Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
Label storeResult(this);
emitGetVirtualRegister(value, regT0);
- storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr));
+ storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
Jump end = jump();
empty.link(this);
- add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)-OBJECT_OFFSETOF(ArrayStorage, m_vector)));
- branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))).linkTo(storeResult, this);
+ add32(Imm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ branch32(Below, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
move(regT1, regT0);
add32(Imm32(1), regT0);
- store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)));
+ store32(regT0, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)));
jump().linkTo(storeResult, this);
end.link(this);
@@ -725,8 +726,9 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3);
- load32(Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)), regT2);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+ load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
+
Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt));
emitFastArithIntToImmNoCheck(regT2, regT0);
diff --git a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 375d3e8..6234842 100644
--- a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -311,11 +311,11 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(base, regT1);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
- load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
- load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
+ load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag
+ load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)));
emitStore(dst, regT1, regT0);
@@ -364,22 +364,22 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT3);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
- Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag));
+ Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::EmptyValueTag));
Label storeResult(this);
emitLoad(value, regT1, regT0);
- store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); // payload
- store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); // tag
+ store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); // payload
+ store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); // tag
Jump end = jump();
empty.link(this);
- add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)-OBJECT_OFFSETOF(ArrayStorage, m_vector)));
- branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector))).linkTo(storeResult, this);
+ add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+ branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
add32(Imm32(1), regT2, regT0);
- store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)));
+ store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)));
jump().linkTo(storeResult, this);
end.link(this);
@@ -731,8 +731,8 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
// Checks out okay! - get the length from the storage
- loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_vector)), regT2);
- load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)-OBJECT_OFFSETOF(ArrayStorage, m_vector)), regT2);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+ load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
Jump failureCases2 = branch32(Above, regT2, Imm32(INT_MAX));
move(regT2, regT0);
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index fa6eb99..e79c46d 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -424,17 +424,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec)
result = jsUndefined();
} else {
result = thisObj->get(exec, 0);
- if (isJSArray(&exec->globalData(), thisObj))
- ((JSArray *)thisObj)->shiftCount(exec, 1);
- else {
- for (unsigned k = 1; k < length; k++) {
- if (JSValue obj = getProperty(exec, thisObj, k))
- thisObj->put(exec, k - 1, obj);
- else
- thisObj->deleteProperty(exec, k - 1);
- }
- thisObj->deleteProperty(exec, length - 1);
+ for (unsigned k = 1; k < length; k++) {
+ if (JSValue obj = getProperty(exec, thisObj, k))
+ thisObj->put(exec, k - 1, obj);
+ else
+ thisObj->deleteProperty(exec, k - 1);
}
+ thisObj->deleteProperty(exec, length - 1);
putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - 1));
}
return JSValue::encode(result);
@@ -582,28 +578,20 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
if (additionalArgs != deleteCount) {
if (additionalArgs < deleteCount) {
- if ((!begin) && (isJSArray(&exec->globalData(), thisObj)))
- ((JSArray *)thisObj)->shiftCount(exec, deleteCount - additionalArgs);
- else {
- for (unsigned k = begin; k < length - deleteCount; ++k) {
- if (JSValue v = getProperty(exec, thisObj, k + deleteCount))
- thisObj->put(exec, k + additionalArgs, v);
- else
- thisObj->deleteProperty(exec, k + additionalArgs);
- }
- for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
- thisObj->deleteProperty(exec, k - 1);
+ for (unsigned k = begin; k < length - deleteCount; ++k) {
+ if (JSValue v = getProperty(exec, thisObj, k + deleteCount))
+ thisObj->put(exec, k + additionalArgs, v);
+ else
+ thisObj->deleteProperty(exec, k + additionalArgs);
}
+ for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
+ thisObj->deleteProperty(exec, k - 1);
} else {
- if ((!begin) && (isJSArray(&exec->globalData(), thisObj)))
- ((JSArray *)thisObj)->unshiftCount(exec, additionalArgs - deleteCount);
- else {
- for (unsigned k = length - deleteCount; k > begin; --k) {
- if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
- thisObj->put(exec, k + additionalArgs - 1, obj);
- else
- thisObj->deleteProperty(exec, k + additionalArgs - 1);
- }
+ for (unsigned k = length - deleteCount; k > begin; --k) {
+ if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
+ thisObj->put(exec, k + additionalArgs - 1, obj);
+ else
+ thisObj->deleteProperty(exec, k + additionalArgs - 1);
}
}
}
@@ -622,16 +610,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec)
// 15.4.4.13
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned nrArgs = exec->argumentCount();
- if ((nrArgs) && (length)) {
- if (isJSArray(&exec->globalData(), thisObj))
- ((JSArray *)thisObj)->unshiftCount(exec, nrArgs);
- else {
- for (unsigned k = length; k > 0; --k) {
- if (JSValue v = getProperty(exec, thisObj, k - 1))
- thisObj->put(exec, k + nrArgs - 1, v);
- else
- thisObj->deleteProperty(exec, k + nrArgs - 1);
- }
+ if (nrArgs) {
+ for (unsigned k = length; k > 0; --k) {
+ if (JSValue v = getProperty(exec, thisObj, k - 1))
+ thisObj->put(exec, k + nrArgs - 1, v);
+ else
+ thisObj->deleteProperty(exec, k + nrArgs - 1);
}
}
for (unsigned k = 0; k < nrArgs; ++k)
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 99e1a10..56603a3 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -78,14 +78,6 @@ ASSERT_CLASS_FITS_IN_CELL(JSArray);
// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
#define MAX_ARRAY_INDEX 0xFFFFFFFEU
-// The value BASE_VECTOR_LEN is the maximum number of vector elements we'll allocate
-// for an array that was created with a sepcified length (e.g. a = new Array(123))
-#define BASE_VECTOR_LEN 4U
-
-// The upper bound to the size we'll grow a zero length array when the first element
-// is added.
-#define FIRST_VECTOR_GROW 4U
-
// Our policy for when to use a vector and when to use a sparse map.
// For all array indices under MIN_SPARSE_ARRAY_INDEX, we always use a vector.
// When indices greater than MIN_SPARSE_ARRAY_INDEX are involved, we use a vector
@@ -94,11 +86,6 @@ static const unsigned minDensityMultiplier = 8;
const ClassInfo JSArray::info = {"Array", 0, 0, 0};
-// We keep track of the size of the last array after it was grown. We use this
-// as a simple heuristic for as the value to grow the next array from size 0.
-// This value is capped by the constant FIRST_VECTOR_GROW defined above.
-static unsigned lastArraySize = 0;
-
static inline size_t storageSize(unsigned vectorLength)
{
ASSERT(vectorLength <= MAX_STORAGE_VECTOR_LENGTH);
@@ -113,6 +100,21 @@ static inline size_t storageSize(unsigned vectorLength)
return size;
}
+static inline unsigned increasedVectorLength(unsigned newLength)
+{
+ ASSERT(newLength <= MAX_STORAGE_VECTOR_LENGTH);
+
+ // Mathematically equivalent to:
+ // increasedLength = (newLength * 3 + 1) / 2;
+ // or:
+ // increasedLength = (unsigned)ceil(newLength * 1.5));
+ // This form is not prone to internal overflow.
+ unsigned increasedLength = newLength + (newLength >> 1) + (newLength & 1);
+ ASSERT(increasedLength >= newLength);
+
+ return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH);
+}
+
static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues)
{
return length / minDensityMultiplier <= numValues;
@@ -131,9 +133,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
{
unsigned initialCapacity = 0;
- ArrayStorage* storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
- m_indexBias = 0;
- setArrayStorage(storage);
+ m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
m_vectorLength = initialCapacity;
checkConsistency();
@@ -146,36 +146,33 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength,
if (creationMode == CreateCompact)
initialCapacity = initialLength;
else
- initialCapacity = min(BASE_VECTOR_LEN, MIN_SPARSE_ARRAY_INDEX);
-
- ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
- storage->m_length = initialLength;
- m_indexBias = 0;
+ initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
+
+ m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
m_vectorLength = initialCapacity;
- setArrayStorage(storage);
- storage->m_sparseValueMap = 0;
- storage->subclassData = 0;
- storage->reportedMapCapacity = 0;
+ m_storage->m_sparseValueMap = 0;
+ m_storage->subclassData = 0;
+ m_storage->reportedMapCapacity = 0;
if (creationMode == CreateCompact) {
#if CHECK_ARRAY_CONSISTENCY
- storage->m_inCompactInitialization = !!initialCapacity;
+ m_storage->m_inCompactInitialization = !!initialCapacity;
#endif
- storage->m_length = 0;
- storage->m_numValuesInVector = initialCapacity;
+ m_storage->m_length = 0;
+ m_storage->m_numValuesInVector = initialCapacity;
} else {
#if CHECK_ARRAY_CONSISTENCY
- storage->m_inCompactInitialization = false;
+ m_storage->m_inCompactInitialization = false;
#endif
- storage->m_length = initialLength;
- storage->m_numValuesInVector = 0;
- JSValue* vector = m_vector;
+ m_storage->m_length = initialLength;
+ m_storage->m_numValuesInVector = 0;
+ JSValue* vector = m_storage->m_vector;
for (size_t i = 0; i < initialCapacity; ++i)
vector[i] = JSValue();
}
checkConsistency();
-
+
Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue));
}
@@ -184,24 +181,21 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
{
unsigned initialCapacity = list.size();
- ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
- m_indexBias = 0;
- storage->m_length = initialCapacity;
+ m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
+ m_storage->m_length = initialCapacity;
m_vectorLength = initialCapacity;
- storage->m_numValuesInVector = initialCapacity;
- storage->m_sparseValueMap = 0;
- storage->subclassData = 0;
- storage->reportedMapCapacity = 0;
+ m_storage->m_numValuesInVector = initialCapacity;
+ m_storage->m_sparseValueMap = 0;
+ m_storage->subclassData = 0;
+ m_storage->reportedMapCapacity = 0;
#if CHECK_ARRAY_CONSISTENCY
- storage->m_inCompactInitialization = false;
+ m_storage->m_inCompactInitialization = false;
#endif
- setArrayStorage(storage);
size_t i = 0;
- JSValue* vector = m_vector;
ArgList::const_iterator end = list.end();
for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
- vector[i] = *it;
+ m_storage->m_vector[i] = *it;
checkConsistency();
@@ -213,16 +207,14 @@ JSArray::~JSArray()
ASSERT(vptr() == JSGlobalData::jsArrayVPtr);
checkConsistency(DestructorConsistencyCheck);
- ArrayStorage* storage = arrayStorage();
- delete storage->m_sparseValueMap;
- char* realStorage = reinterpret_cast<char*>(storage) - (m_indexBias * sizeof(JSValue));
- fastFree(realStorage);
+ delete m_storage->m_sparseValueMap;
+ fastFree(m_storage);
}
bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
{
- ArrayStorage* storage = arrayStorage();
-
+ ArrayStorage* storage = m_storage;
+
if (i >= storage->m_length) {
if (i > MAX_ARRAY_INDEX)
return getOwnPropertySlot(exec, Identifier::from(exec, i), slot);
@@ -230,7 +222,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
}
if (i < m_vectorLength) {
- JSValue& valueSlot = m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
if (valueSlot) {
slot.setValueSlot(&valueSlot);
return true;
@@ -269,21 +261,19 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper
descriptor.setDescriptor(jsNumber(exec, length()), DontDelete | DontEnum);
return true;
}
-
- ArrayStorage* storage = arrayStorage();
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(&isArrayIndex);
if (isArrayIndex) {
- if (i >= storage->m_length)
+ if (i >= m_storage->m_length)
return false;
if (i < m_vectorLength) {
- JSValue& value = m_vector[i];
+ JSValue& value = m_storage->m_vector[i];
if (value) {
descriptor.setDescriptor(value, 0);
return true;
}
- } else if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ } else if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
if (i >= MIN_SPARSE_ARRAY_INDEX) {
SparseArrayValueMap::iterator it = map->find(i);
if (it != map->end()) {
@@ -323,23 +313,21 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value)
{
checkConsistency();
- ArrayStorage* storage = arrayStorage();
-
- unsigned length = storage->m_length;
+ unsigned length = m_storage->m_length;
if (i >= length && i <= MAX_ARRAY_INDEX) {
length = i + 1;
- storage->m_length = length;
+ m_storage->m_length = length;
}
if (i < m_vectorLength) {
- JSValue& valueSlot = m_vector[i];
+ JSValue& valueSlot = m_storage->m_vector[i];
if (valueSlot) {
valueSlot = value;
checkConsistency();
return;
}
valueSlot = value;
- ++storage->m_numValuesInVector;
+ ++m_storage->m_numValuesInVector;
checkConsistency();
return;
}
@@ -349,8 +337,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValue value)
NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue value)
{
- ArrayStorage* storage = arrayStorage();
-
+ ArrayStorage* storage = m_storage;
SparseArrayValueMap* map = storage->m_sparseValueMap;
if (i >= MIN_SPARSE_ARRAY_INDEX) {
@@ -387,8 +374,9 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
// Fast case is when there is no sparse map, so we can increase the vector size without moving values from it.
if (!map || map->isEmpty()) {
if (increaseVectorLength(i + 1)) {
- m_vector[i] = value;
- ++arrayStorage()->m_numValuesInVector;
+ storage = m_storage;
+ storage->m_vector[i] = value;
+ ++storage->m_numValuesInVector;
checkConsistency();
} else
throwOutOfMemoryError(exec);
@@ -397,7 +385,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
// Decide how many values it would be best to move from the map.
unsigned newNumValuesInVector = storage->m_numValuesInVector + 1;
- unsigned newVectorLength = getNewVectorLength(i + 1);
+ unsigned newVectorLength = increasedVectorLength(i + 1);
for (unsigned j = max(m_vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
newNumValuesInVector += map->contains(j);
if (i >= MIN_SPARSE_ARRAY_INDEX)
@@ -406,7 +394,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
unsigned proposedNewNumValuesInVector = newNumValuesInVector;
// If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further.
while (newVectorLength < MAX_STORAGE_VECTOR_LENGTH) {
- unsigned proposedNewVectorLength = getNewVectorLength(newVectorLength + 1);
+ unsigned proposedNewVectorLength = increasedVectorLength(newVectorLength + 1);
for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j)
proposedNewNumValuesInVector += map->contains(j);
if (!isDenseEnoughForVector(proposedNewVectorLength, proposedNewNumValuesInVector))
@@ -416,37 +404,31 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
}
}
- int baseBias = m_indexBias * sizeof(JSValue);
- char* baseStorage = reinterpret_cast<char*>(storage - baseBias);
-
- if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) {
+ if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) {
throwOutOfMemoryError(exec);
return;
}
- storage = reinterpret_cast<ArrayStorage*>(baseStorage + baseBias);
- setArrayStorage(storage);
-
unsigned vectorLength = m_vectorLength;
if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
for (unsigned j = vectorLength; j < newVectorLength; ++j)
- m_vector[j] = JSValue();
+ storage->m_vector[j] = JSValue();
if (i > MIN_SPARSE_ARRAY_INDEX)
map->remove(i);
} else {
for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
- m_vector[j] = JSValue();
+ storage->m_vector[j] = JSValue();
for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
- m_vector[j] = map->take(j);
+ storage->m_vector[j] = map->take(j);
}
- ASSERT(i < newVectorLength);
+ storage->m_vector[i] = value;
m_vectorLength = newVectorLength;
storage->m_numValuesInVector = newNumValuesInVector;
- m_vector[i] = value;
+ m_storage = storage;
checkConsistency();
@@ -470,10 +452,10 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
{
checkConsistency();
- ArrayStorage* storage = arrayStorage();
-
+ ArrayStorage* storage = m_storage;
+
if (i < m_vectorLength) {
- JSValue& valueSlot = m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
if (!valueSlot) {
checkConsistency();
return false;
@@ -509,11 +491,11 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa
// is incredibly inefficient for large arrays. We need a different approach,
// which almost certainly means a different structure for PropertyNameArray.
- ArrayStorage* storage = arrayStorage();
-
+ ArrayStorage* storage = m_storage;
+
unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
for (unsigned i = 0; i < usedVectorLength; ++i) {
- if (m_vector[i])
+ if (storage->m_vector[i])
propertyNames.add(Identifier::from(exec, i));
}
@@ -529,101 +511,32 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa
JSObject::getOwnPropertyNames(exec, propertyNames, mode);
}
-ALWAYS_INLINE unsigned JSArray::getNewVectorLength(unsigned desiredLength)
-{
- ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH);
-
- unsigned increasedLength;
- unsigned length = arrayStorage()->m_length;
-
- if (desiredLength < length)
- increasedLength = length;
- else if (!m_vectorLength)
- increasedLength = max(desiredLength, lastArraySize);
- else {
- // Mathematically equivalent to:
- // increasedLength = (newLength * 3 + 1) / 2;
- // or:
- // increasedLength = (unsigned)ceil(newLength * 1.5));
- // This form is not prone to internal overflow.
- increasedLength = desiredLength + (desiredLength >> 1) + (desiredLength & 1);
- }
-
- ASSERT(increasedLength >= desiredLength);
-
- lastArraySize = min(increasedLength, FIRST_VECTOR_GROW);
-
- return min(increasedLength, MAX_STORAGE_VECTOR_LENGTH);
-}
-
bool JSArray::increaseVectorLength(unsigned newLength)
{
// This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
// to the vector. Callers have to account for that, because they can do it more efficiently.
- ArrayStorage* storage = arrayStorage();
+ ArrayStorage* storage = m_storage;
unsigned vectorLength = m_vectorLength;
ASSERT(newLength > vectorLength);
ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);
- unsigned newVectorLength = getNewVectorLength(newLength);
- int baseBias = m_indexBias * sizeof(JSValue);
- char* baseStorage = reinterpret_cast<char*>(storage) - baseBias;
+ unsigned newVectorLength = increasedVectorLength(newLength);
- if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage))
+ if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage))
return false;
-
- storage = reinterpret_cast<ArrayStorage*>(baseStorage + baseBias);
- setArrayStorage(storage);
-
- JSValue* vector = m_vector;
- for (unsigned i = vectorLength; i < newVectorLength; ++i)
- vector[i] = JSValue();
m_vectorLength = newVectorLength;
-
- Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
- return true;
-}
+ for (unsigned i = vectorLength; i < newVectorLength; ++i)
+ storage->m_vector[i] = JSValue();
-bool JSArray::increaseVectorPrefixLength(unsigned newLength)
-{
- // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map
- // to the vector. Callers have to account for that, because they can do it more efficiently.
-
- ArrayStorage* storage = arrayStorage();
- ArrayStorage* newStorage;
-
- unsigned vectorLength = m_vectorLength;
- ASSERT(newLength > vectorLength);
- ASSERT(newLength <= MAX_STORAGE_VECTOR_INDEX);
- unsigned newVectorLength = getNewVectorLength(newLength);
- char* baseStorage = reinterpret_cast<char*>(storage) - (m_indexBias * sizeof(JSValue));
-
- char* newBaseStorage = reinterpret_cast<char*>(fastMalloc(storageSize(newVectorLength + m_indexBias)));
- if (!newBaseStorage)
- return false;
-
- m_indexBias += newVectorLength - newLength;
- int newStorageOffset = m_indexBias * sizeof(JSValue);
-
- newStorage = reinterpret_cast<ArrayStorage*>(newBaseStorage + newStorageOffset);
-
- memcpy(newStorage, storage, storageSize(0));
- memcpy(&newStorage->m_vector[newLength - m_vectorLength], &storage->m_vector[0], storage->m_length * sizeof(JSValue));
-
- m_vectorLength = newLength;
-
- fastFree(baseStorage);
+ m_storage = storage;
- setArrayStorage(newStorage);
-
Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength));
-
+
return true;
}
-
void JSArray::setLength(unsigned newLength)
{
@@ -634,14 +547,14 @@ void JSArray::setLength(unsigned newLength)
m_storage->m_inCompactInitialization = false;
#endif
- ArrayStorage* storage = arrayStorage();
-
- unsigned length = storage->m_length;
+ ArrayStorage* storage = m_storage;
+
+ unsigned length = m_storage->m_length;
if (newLength < length) {
unsigned usedVectorLength = min(length, m_vectorLength);
for (unsigned i = newLength; i < usedVectorLength; ++i) {
- JSValue& valueSlot = m_vector[i];
+ JSValue& valueSlot = storage->m_vector[i];
bool hadValue = valueSlot;
valueSlot = JSValue();
storage->m_numValuesInVector -= hadValue;
@@ -661,7 +574,7 @@ void JSArray::setLength(unsigned newLength)
}
}
- storage->m_length = newLength;
+ m_storage->m_length = newLength;
checkConsistency();
}
@@ -670,9 +583,7 @@ JSValue JSArray::pop()
{
checkConsistency();
- ArrayStorage* storage = arrayStorage();
-
- unsigned length = storage->m_length;
+ unsigned length = m_storage->m_length;
if (!length)
return jsUndefined();
@@ -681,29 +592,29 @@ JSValue JSArray::pop()
JSValue result;
if (length < m_vectorLength) {
- JSValue& valueSlot = m_vector[length];
+ JSValue& valueSlot = m_storage->m_vector[length];
if (valueSlot) {
- --storage->m_numValuesInVector;
+ --m_storage->m_numValuesInVector;
result = valueSlot;
valueSlot = JSValue();
} else
result = jsUndefined();
} else {
result = jsUndefined();
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(length);
if (it != map->end()) {
result = it->second;
map->remove(it);
if (map->isEmpty()) {
delete map;
- storage->m_sparseValueMap = 0;
+ m_storage->m_sparseValueMap = 0;
}
}
}
}
- storage->m_length = length;
+ m_storage->m_length = length;
checkConsistency();
@@ -713,25 +624,22 @@ JSValue JSArray::pop()
void JSArray::push(ExecState* exec, JSValue value)
{
checkConsistency();
-
- ArrayStorage* storage = arrayStorage();
- if (storage->m_length < m_vectorLength) {
- m_vector[storage->m_length] = value;
- ++storage->m_numValuesInVector;
- ++storage->m_length;
+ if (m_storage->m_length < m_vectorLength) {
+ m_storage->m_vector[m_storage->m_length] = value;
+ ++m_storage->m_numValuesInVector;
+ ++m_storage->m_length;
checkConsistency();
return;
}
- if (storage->m_length < MIN_SPARSE_ARRAY_INDEX) {
- SparseArrayValueMap* map = storage->m_sparseValueMap;
+ if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) {
+ SparseArrayValueMap* map = m_storage->m_sparseValueMap;
if (!map || map->isEmpty()) {
- if (increaseVectorLength(storage->m_length + 1)) {
- storage = arrayStorage();
- m_vector[storage->m_length] = value;
- ++storage->m_numValuesInVector;
- ++storage->m_length;
+ if (increaseVectorLength(m_storage->m_length + 1)) {
+ m_storage->m_vector[m_storage->m_length] = value;
+ ++m_storage->m_numValuesInVector;
+ ++m_storage->m_length;
checkConsistency();
return;
}
@@ -741,98 +649,7 @@ void JSArray::push(ExecState* exec, JSValue value)
}
}
- putSlowCase(exec, storage->m_length++, value);
-}
-
-void JSArray::shiftCount(ExecState* exec, int count)
-{
- ASSERT(count > 0);
-
- ArrayStorage* storage = arrayStorage();
-
- unsigned oldLength = storage->m_length;
-
- if (!oldLength)
- return;
-
- if (oldLength != storage->m_numValuesInVector) {
- // If m_length and m_numValuesInVector aren't the same, we have a sparse vector
- // which means we need to go through each entry looking for the the "empty"
- // slots and then fill them with possible properties. See ECMA spec.
- // 15.4.4.9 steps 11 through 13.
- for (unsigned i = count; i < oldLength; ++i) {
- if ((i >= m_vectorLength) || (!m_vector[i])) {
- PropertySlot slot(this);
- JSValue p = prototype();
- if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
- put(exec, i, slot.getValue(exec, i));
- }
- }
-
- storage = arrayStorage(); // The put() above could have grown the vector and realloc'ed storage.
-
- // Need to decrement numValuesInvector based on number of real entries
- for (unsigned i = 0; i < (unsigned)count; ++i)
- if ((i < m_vectorLength) && (m_vector[i]))
- --storage->m_numValuesInVector;
- } else
- storage->m_numValuesInVector -= count;
-
- storage->m_length -= count;
-
- if (m_vectorLength) {
- count = min(m_vectorLength, (unsigned)count);
-
- m_vectorLength -= count;
-
- if (m_vectorLength) {
- char* newBaseStorage = reinterpret_cast<char*>(storage) + count * sizeof(JSValue);
- memmove(newBaseStorage, storage, storageSize(0));
- storage = reinterpret_cast<ArrayStorage*>(newBaseStorage);
-
- m_indexBias += count;
- setArrayStorage(storage);
- }
- }
-}
-
-void JSArray::unshiftCount(ExecState* exec, int count)
-{
- ArrayStorage* storage = arrayStorage();
-
- ASSERT(m_indexBias >= 0);
- ASSERT(count >= 0);
-
- unsigned length = storage->m_length;
-
- if (length != storage->m_numValuesInVector) {
- // If m_length and m_numValuesInVector aren't the same, we have a sparse vector
- // which means we need to go through each entry looking for the the "empty"
- // slots and then fill them with possible properties. See ECMA spec.
- // 15.4.4.13 steps 8 through 10.
- for (unsigned i = 0; i < length; ++i) {
- if ((i >= m_vectorLength) || (!m_vector[i])) {
- PropertySlot slot(this);
- JSValue p = prototype();
- if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
- put(exec, i, slot.getValue(exec, i));
- }
- }
- }
-
- storage = arrayStorage(); // The put() above could have grown the vector and realloc'ed storage.
-
- if (m_indexBias >= count) {
- m_indexBias -= count;
- char* newBaseStorage = reinterpret_cast<char*>(storage) - count * sizeof(JSValue);
- memmove(newBaseStorage, storage, storageSize(0));
- storage = reinterpret_cast<ArrayStorage*>(newBaseStorage);
- setArrayStorage(storage);
- m_vectorLength += count;
- } else if ((!m_indexBias) && (!increaseVectorPrefixLength(m_vectorLength + count))) {
- throwOutOfMemoryError(exec);
- return;
- }
+ putSlowCase(exec, m_storage->m_length++, value);
}
void JSArray::markChildren(MarkStack& markStack)
@@ -858,10 +675,8 @@ static int compareByStringPairForQSort(const void* a, const void* b)
void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
{
- ArrayStorage* storage = arrayStorage();
-
unsigned lengthNotIncludingUndefined = compactForSorting();
- if (storage->m_sparseValueMap) {
+ if (m_storage->m_sparseValueMap) {
throwOutOfMemoryError(exec);
return;
}
@@ -870,9 +685,9 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
return;
bool allValuesAreNumbers = true;
- size_t size = storage->m_numValuesInVector;
+ size_t size = m_storage->m_numValuesInVector;
for (size_t i = 0; i < size; ++i) {
- if (!m_vector[i].isNumber()) {
+ if (!m_storage->m_vector[i].isNumber()) {
allValuesAreNumbers = false;
break;
}
@@ -884,17 +699,15 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal
// For numeric comparison, which is fast, qsort is faster than mergesort. We
// also don't require mergesort's stability, since there's no user visible
// side-effect from swapping the order of equal primitive values.
- qsort(m_vector, size, sizeof(JSValue), compareNumbersForQSort);
+ qsort(m_storage->m_vector, size, sizeof(JSValue), compareNumbersForQSort);
checkConsistency(SortConsistencyCheck);
}
void JSArray::sort(ExecState* exec)
{
- ArrayStorage* storage = arrayStorage();
-
unsigned lengthNotIncludingUndefined = compactForSorting();
- if (storage->m_sparseValueMap) {
+ if (m_storage->m_sparseValueMap) {
throwOutOfMemoryError(exec);
return;
}
@@ -914,7 +727,7 @@ void JSArray::sort(ExecState* exec)
}
for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
- JSValue value = m_vector[i];
+ JSValue value = m_storage->m_vector[i];
ASSERT(!value.isUndefined());
values[i].first = value;
}
@@ -946,7 +759,7 @@ void JSArray::sort(ExecState* exec)
// modifying the vector incorrectly.
for (size_t i = 0; i < lengthNotIncludingUndefined; i++)
- m_vector[i] = values[i].first;
+ m_storage->m_vector[i] = values[i].first;
checkConsistency(SortConsistencyCheck);
}
@@ -1033,20 +846,18 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
{
checkConsistency();
- ArrayStorage* storage = arrayStorage();
-
// FIXME: This ignores exceptions raised in the compare function or in toNumber.
// The maximum tree depth is compiled in - but the caller is clearly up to no good
// if a larger array is passed.
- ASSERT(storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
- if (storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
+ ASSERT(m_storage->m_length <= static_cast<unsigned>(std::numeric_limits<int>::max()));
+ if (m_storage->m_length > static_cast<unsigned>(std::numeric_limits<int>::max()))
return;
- if (!storage->m_length)
+ if (!m_storage->m_length)
return;
- unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
+ unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength);
AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items
tree.abstractor().m_exec = exec;
@@ -1054,7 +865,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
tree.abstractor().m_compareCallType = callType;
tree.abstractor().m_compareCallData = &callData;
tree.abstractor().m_globalThisValue = exec->globalThisValue();
- tree.abstractor().m_nodes.resize(usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0));
+ tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0));
if (callType == CallTypeJS)
tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, asFunction(compareFunction), 2, exec->exceptionSlot()));
@@ -1072,14 +883,14 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue v = m_vector[numDefined];
+ JSValue v = m_storage->m_vector[numDefined];
if (!v || v.isUndefined())
break;
tree.abstractor().m_nodes[numDefined].value = v;
tree.insert(numDefined);
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValue v = m_vector[i];
+ JSValue v = m_storage->m_vector[i];
if (v) {
if (v.isUndefined())
++numUndefined;
@@ -1093,7 +904,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
unsigned newUsedVectorLength = numDefined + numUndefined;
- if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
+ if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
newUsedVectorLength += map->size();
if (newUsedVectorLength > m_vectorLength) {
// Check that it is possible to allocate an array large enough to hold all the entries.
@@ -1102,8 +913,6 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
return;
}
}
-
- storage = arrayStorage();
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
@@ -1113,7 +922,7 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
}
delete map;
- storage->m_sparseValueMap = 0;
+ m_storage->m_sparseValueMap = 0;
}
ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
@@ -1125,29 +934,27 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType,
AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
iter.start_iter_least(tree);
for (unsigned i = 0; i < numDefined; ++i) {
- m_vector[i] = tree.abstractor().m_nodes[*iter].value;
+ m_storage->m_vector[i] = tree.abstractor().m_nodes[*iter].value;
++iter;
}
// Put undefined values back in.
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
- m_vector[i] = jsUndefined();
+ m_storage->m_vector[i] = jsUndefined();
// Ensure that unused values in the vector are zeroed out.
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- m_vector[i] = JSValue();
+ m_storage->m_vector[i] = JSValue();
- storage->m_numValuesInVector = newUsedVectorLength;
+ m_storage->m_numValuesInVector = newUsedVectorLength;
checkConsistency(SortConsistencyCheck);
}
void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
- ArrayStorage* storage = arrayStorage();
-
- JSValue* vector = storage->m_vector;
- unsigned vectorEnd = min(storage->m_length, m_vectorLength);
+ JSValue* vector = m_storage->m_vector;
+ unsigned vectorEnd = min(m_storage->m_length, m_vectorLength);
unsigned i = 0;
for (; i < vectorEnd; ++i) {
JSValue& v = vector[i];
@@ -1156,15 +963,15 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
args.append(v);
}
- for (; i < storage->m_length; ++i)
+ for (; i < m_storage->m_length; ++i)
args.append(get(exec, i));
}
void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
{
- ASSERT(arrayStorage()->m_length >= maxSize);
+ ASSERT(m_storage->m_length >= maxSize);
UNUSED_PARAM(maxSize);
- JSValue* vector = m_vector;
+ JSValue* vector = m_storage->m_vector;
unsigned vectorEnd = min(maxSize, m_vectorLength);
unsigned i = 0;
for (; i < vectorEnd; ++i) {
@@ -1182,25 +989,25 @@ unsigned JSArray::compactForSorting()
{
checkConsistency();
- ArrayStorage* storage = arrayStorage();
+ ArrayStorage* storage = m_storage;
- unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
+ unsigned usedVectorLength = min(m_storage->m_length, m_vectorLength);
unsigned numDefined = 0;
unsigned numUndefined = 0;
for (; numDefined < usedVectorLength; ++numDefined) {
- JSValue v = m_vector[numDefined];
+ JSValue v = storage->m_vector[numDefined];
if (!v || v.isUndefined())
break;
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- JSValue v = m_vector[i];
+ JSValue v = storage->m_vector[i];
if (v) {
if (v.isUndefined())
++numUndefined;
else
- m_vector[numDefined++] = v;
+ storage->m_vector[numDefined++] = v;
}
}
@@ -1213,22 +1020,21 @@ unsigned JSArray::compactForSorting()
// exception is thrown by caller.
if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength))
return 0;
-
- storage = arrayStorage();
+ storage = m_storage;
}
SparseArrayValueMap::iterator end = map->end();
for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
- m_vector[numDefined++] = it->second;
+ storage->m_vector[numDefined++] = it->second;
delete map;
storage->m_sparseValueMap = 0;
}
for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
- m_vector[i] = jsUndefined();
+ storage->m_vector[i] = jsUndefined();
for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
- m_vector[i] = JSValue();
+ storage->m_vector[i] = JSValue();
storage->m_numValuesInVector = newUsedVectorLength;
@@ -1239,44 +1045,42 @@ unsigned JSArray::compactForSorting()
void* JSArray::subclassData() const
{
- return arrayStorage()->subclassData;
+ return m_storage->subclassData;
}
void JSArray::setSubclassData(void* d)
{
- arrayStorage()->subclassData = d;
+ m_storage->subclassData = d;
}
#if CHECK_ARRAY_CONSISTENCY
void JSArray::checkConsistency(ConsistencyCheckType type)
{
- ArrayStorage* storage = arrayStorage();
-
- ASSERT(storage);
+ ASSERT(m_storage);
if (type == SortConsistencyCheck)
- ASSERT(!storage->m_sparseValueMap);
+ ASSERT(!m_storage->m_sparseValueMap);
unsigned numValuesInVector = 0;
for (unsigned i = 0; i < m_vectorLength; ++i) {
- if (JSValue value = m_vector[i]) {
- ASSERT(i < storage->m_length);
+ if (JSValue value = m_storage->m_vector[i]) {
+ ASSERT(i < m_storage->m_length);
if (type != DestructorConsistencyCheck)
value.isUndefined(); // Likely to crash if the object was deallocated.
++numValuesInVector;
} else {
if (type == SortConsistencyCheck)
- ASSERT(i >= storage->m_numValuesInVector);
+ ASSERT(i >= m_storage->m_numValuesInVector);
}
}
- ASSERT(numValuesInVector == storage->m_numValuesInVector);
- ASSERT(numValuesInVector <= storage->m_length);
+ ASSERT(numValuesInVector == m_storage->m_numValuesInVector);
+ ASSERT(numValuesInVector <= m_storage->m_length);
- if (storage->m_sparseValueMap) {
- SparseArrayValueMap::iterator end = storage->m_sparseValueMap->end();
- for (SparseArrayValueMap::iterator it = storage->m_sparseValueMap->begin(); it != end; ++it) {
+ if (m_storage->m_sparseValueMap) {
+ SparseArrayValueMap::iterator end = m_storage->m_sparseValueMap->end();
+ for (SparseArrayValueMap::iterator it = m_storage->m_sparseValueMap->begin(); it != end; ++it) {
unsigned index = it->first;
- ASSERT(index < storage->m_length);
+ ASSERT(index < m_storage->m_length);
ASSERT(index >= m_vectorLength);
ASSERT(index <= MAX_ARRAY_INDEX);
ASSERT(it->second);
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index a7ce328..b6dd7cc 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -29,13 +29,8 @@ namespace JSC {
typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
- // This struct holds the actual data values of an array. A JSArray object points to it's contained ArrayStorage
- // struct by pointing to m_vector. To access the contained ArrayStorage struct, use the getStorage() and
- // setStorage() methods. It is important to note that there may be space before the ArrayStorage that
- // is used to quick unshift / shift operation. The actual allocated pointer is available by using:
- // getStorage() - m_indexBias * sizeof(JSValue)
struct ArrayStorage {
- unsigned m_length; // The "length" property on the array
+ unsigned m_length;
unsigned m_numValuesInVector;
SparseArrayValueMap* m_sparseValueMap;
void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
@@ -72,8 +67,8 @@ namespace JSC {
virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem.
static JS_EXPORTDATA const ClassInfo info;
-
- unsigned length() const { return arrayStorage()->m_length; }
+
+ unsigned length() const { return m_storage->m_length; }
void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray.
void sort(ExecState*);
@@ -83,39 +78,33 @@ namespace JSC {
void push(ExecState*, JSValue);
JSValue pop();
- void shiftCount(ExecState*, int count);
- void unshiftCount(ExecState*, int count);
-
- bool canGetIndex(unsigned i) { return i < m_vectorLength && m_vector[i]; }
+ bool canGetIndex(unsigned i) { return i < m_vectorLength && m_storage->m_vector[i]; }
JSValue getIndex(unsigned i)
{
ASSERT(canGetIndex(i));
- return m_vector[i];
+ return m_storage->m_vector[i];
}
bool canSetIndex(unsigned i) { return i < m_vectorLength; }
void setIndex(unsigned i, JSValue v)
{
ASSERT(canSetIndex(i));
-
- JSValue& x = m_vector[i];
+ JSValue& x = m_storage->m_vector[i];
if (!x) {
- ArrayStorage *storage = arrayStorage();
- ++storage->m_numValuesInVector;
- if (i >= storage->m_length)
- storage->m_length = i + 1;
+ ++m_storage->m_numValuesInVector;
+ if (i >= m_storage->m_length)
+ m_storage->m_length = i + 1;
}
x = v;
}
-
+
void uncheckedSetIndex(unsigned i, JSValue v)
{
ASSERT(canSetIndex(i));
- ArrayStorage *storage = arrayStorage();
#if CHECK_ARRAY_CONSISTENCY
- ASSERT(storage->m_inCompactInitialization);
+ ASSERT(m_storage->m_inCompactInitialization);
#endif
- storage->m_vector[i] = v;
+ m_storage->m_vector[i] = v;
}
void fillArgList(ExecState*, MarkedArgumentBuffer&);
@@ -138,16 +127,6 @@ namespace JSC {
void* subclassData() const;
void setSubclassData(void*);
-
- inline ArrayStorage *arrayStorage() const
- {
- return reinterpret_cast<ArrayStorage*>(reinterpret_cast<char*>(m_vector) - (sizeof(ArrayStorage) - sizeof(JSValue)));
- }
-
- inline void setArrayStorage(ArrayStorage *storage)
- {
- m_vector = &storage->m_vector[0];
- }
private:
virtual const ClassInfo* classInfo() const { return &info; }
@@ -155,18 +134,15 @@ namespace JSC {
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putSlowCase(ExecState*, unsigned propertyName, JSValue);
- unsigned getNewVectorLength(unsigned desiredLength);
bool increaseVectorLength(unsigned newLength);
- bool increaseVectorPrefixLength(unsigned newLength);
unsigned compactForSorting();
enum ConsistencyCheckType { NormalConsistencyCheck, DestructorConsistencyCheck, SortConsistencyCheck };
void checkConsistency(ConsistencyCheckType = NormalConsistencyCheck);
- unsigned m_vectorLength; // The valid length of m_vector
- int m_indexBias; // The number of JSValue sized blocks before ArrayStorage.
- JSValue* m_vector; // Copy of ArrayStorage.m_vector. Used for quick vector access and to materialize ArrayStorage ptr.
+ unsigned m_vectorLength;
+ ArrayStorage* m_storage;
};
JSArray* asArray(JSValue);
@@ -192,7 +168,7 @@ namespace JSC {
{
JSObject::markChildrenDirect(markStack);
- ArrayStorage* storage = arrayStorage();
+ ArrayStorage* storage = m_storage;
unsigned usedVectorLength = std::min(storage->m_length, m_vectorLength);
markStack.appendValues(storage->m_vector, usedVectorLength, MayContainNullValues);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list