summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSArray.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-10-17 16:21:14 +0200
commit8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch)
tree17985605dab9263cc2444bd4d45f189e142cca7c /Source/JavaScriptCore/runtime/JSArray.h
parentb9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff)
downloadqtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well as the previously cherry-picked changes
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSArray.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h130
1 files changed, 114 insertions, 16 deletions
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index 6e539c9db..d4622aacc 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -71,8 +71,60 @@ namespace JSC {
void push(ExecState*, JSValue);
JSValue pop(ExecState*);
- bool shiftCount(ExecState*, unsigned count);
- bool unshiftCount(ExecState*, unsigned count);
+ enum ShiftCountMode {
+ // This form of shift hints that we're doing queueing. With this assumption in hand,
+ // we convert to ArrayStorage, which has queue optimizations.
+ ShiftCountForShift,
+
+ // This form of shift hints that we're just doing care and feeding on an array that
+ // is probably typically used for ordinary accesses. With this assumption in hand,
+ // we try to preserve whatever indexing type it has already.
+ ShiftCountForSplice
+ };
+
+ bool shiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData()));
+ }
+ bool shiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ return shiftCountWithAnyIndexingType(exec, startIndex, count);
+ }
+ template<ShiftCountMode shiftCountMode>
+ bool shiftCount(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ switch (shiftCountMode) {
+ case ShiftCountForShift:
+ return shiftCountForShift(exec, startIndex, count);
+ case ShiftCountForSplice:
+ return shiftCountForSplice(exec, startIndex, count);
+ default:
+ CRASH();
+ return false;
+ }
+ }
+
+ bool unshiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData()));
+ }
+ bool unshiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ return unshiftCountWithAnyIndexingType(exec, startIndex, count);
+ }
+ template<ShiftCountMode shiftCountMode>
+ bool unshiftCount(ExecState* exec, unsigned startIndex, unsigned count)
+ {
+ switch (shiftCountMode) {
+ case ShiftCountForShift:
+ return unshiftCountForShift(exec, startIndex, count);
+ case ShiftCountForSplice:
+ return unshiftCountForSplice(exec, startIndex, count);
+ default:
+ CRASH();
+ return false;
+ }
+ }
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToArguments(ExecState*, CallFrame*, uint32_t length);
@@ -94,18 +146,44 @@ namespace JSC {
{
ArrayStorage* storage = arrayStorageOrNull();
if (!storage)
- return false;
+ return true;
SparseArrayValueMap* map = storage->m_sparseMap.get();
return !map || !map->lengthIsReadOnly();
}
+
+ bool shiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
+ bool shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage*);
- void setLengthWritable(ExecState*, bool writable);
+ bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
+ bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*);
+ bool unshiftCountSlowCase(JSGlobalData&, bool, unsigned);
+
+ template<IndexingType indexingType>
+ void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
+
+ template<IndexingType indexingType>
+ void sortCompactedVector(ExecState*, WriteBarrier<Unknown>* begin, unsigned relevantLength);
+
+ template<IndexingType indexingType>
+ void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&);
- bool unshiftCountSlowCase(JSGlobalData&, unsigned count);
+ bool setLengthWithArrayStorage(ExecState*, unsigned newLength, bool throwException, ArrayStorage*);
+ void setLengthWritable(ExecState*, bool writable);
- unsigned compactForSorting(JSGlobalData&);
+ template<IndexingType indexingType>
+ void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength);
};
+ inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length)
+ {
+ IndexingHeader header;
+ header.setVectorLength(std::max(length, BASE_VECTOR_LEN));
+ header.setPublicLength(length);
+ Butterfly* result = Butterfly::create(
+ globalData, 0, 0, true, header, header.vectorLength() * sizeof(EncodedJSValue));
+ return result;
+ }
+
inline Butterfly* createArrayButterfly(JSGlobalData& globalData, unsigned initialLength)
{
Butterfly* butterfly = Butterfly::create(
@@ -121,7 +199,16 @@ namespace JSC {
inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength)
{
- Butterfly* butterfly = createArrayButterfly(globalData, initialLength);
+ Butterfly* butterfly;
+ if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
+ butterfly = createContiguousArrayButterfly(globalData, initialLength);
+ ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX);
+ } else {
+ ASSERT(
+ structure->indexingType() == ArrayWithSlowPutArrayStorage
+ || (initialLength && structure->indexingType() == ArrayWithArrayStorage));
+ butterfly = createArrayButterfly(globalData, initialLength);
+ }
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
array->finishCreation(globalData);
return array;
@@ -133,15 +220,26 @@ namespace JSC {
if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
return 0;
- void* temp;
- if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
- return 0;
- Butterfly* butterfly = Butterfly::fromBase(temp, 0, 0);
- *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
- ArrayStorage* storage = butterfly->arrayStorage();
- storage->m_indexBias = 0;
- storage->m_sparseMap.clear();
- storage->m_numValuesInVector = initialLength;
+ Butterfly* butterfly;
+ if (LIKELY(structure->indexingType() == ArrayWithContiguous)) {
+
+ void* temp;
+ if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp))
+ return 0;
+ butterfly = Butterfly::fromBase(temp, 0, 0);
+ butterfly->setVectorLength(vectorLength);
+ butterfly->setPublicLength(initialLength);
+ } else {
+ void* temp;
+ if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
+ return 0;
+ butterfly = Butterfly::fromBase(temp, 0, 0);
+ *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength);
+ ArrayStorage* storage = butterfly->arrayStorage();
+ storage->m_indexBias = 0;
+ storage->m_sparseMap.clear();
+ storage->m_numValuesInVector = initialLength;
+ }
JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly);
array->finishCreation(globalData);