Commit f860d02f authored by darin's avatar darin

JavaScriptCore:

        Reviewed by Maciej.

        - http://bugs.webkit.org/show_bug.cgi?id=15606
          make cut-off for sparse vs. dense arrays smarter for speed with large arrays

        Makes the morph test in SunSpider 26% faster, and the overall
        benchmark 3% faster.

        This also fixes some small problems we had with the distinction
        between nonexistent and undefined values in arrays.

        * kjs/array_instance.h: Tweaked formatting and naming.
        * kjs/array_instance.cpp: Copied from kjs/array_object.cpp.
        (KJS::storageSize): Added. Computes the size of the storage given a vector length.
        (KJS::increasedVectorLength): Added. Implements the rule for resizing the vector.
        (KJS::isDenseEnoughForVector): Added.
        (KJS::ArrayInstance::ArrayInstance): Initialize the new fields.
        (KJS::ArrayInstance::~ArrayInstance): Since m_storage is now never 0, delete it.
        (KJS::ArrayInstance::getItem): Updated for name changes.
        (KJS::ArrayInstance::lengthGetter): Ditto.
        (KJS::ArrayInstance::inlineGetOwnPropertySlot): Added. Allows both versions of
        getOwnPropertySlot to share more code.
        (KJS::ArrayInstance::getOwnPropertySlot): Just refactored, no code change.
        (KJS::ArrayInstance::put): Added logic for extending the vector as long as the
        array is dense enough. Also keep m_numValuesInVector up to date.
        (KJS::ArrayInstance::deleteProperty): Added code to keep m_numValuesInVector
        up to date.
        (KJS::ArrayInstance::getPropertyNames): Fixed bug where this would omit names
        for array indices with undefined values.
        (KJS::ArrayInstance::increaseVectorLength): Renamed from resizeStorage. Also
        simplified to only handle getting larger.
        (KJS::ArrayInstance::setLength): Added code to update m_numValuesInVector, to
        zero out the unused part of the vector and to delete the map if it's no longer
        needed.
        (KJS::ArrayInstance::mark): Tweaked formatting.
        (KJS::compareByStringForQSort): Ditto.
        (KJS::ArrayInstance::sort): Ditto.
        (KJS::CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
        Ditto.
        (KJS::compareWithCompareFunctionForQSort): Ditto.
        (KJS::ArrayInstance::compactForSorting): Fixed bug where this would turn
        undefined values into nonexistent values in some cases.

        * kjs/array_object.h: Removed MAX_ARRAY_INDEX.
        * kjs/array_object.cpp: Removed ArrayInstance. Moved to a separate file.

        * JavaScriptCore.pri: Added array_instance.cpp.
        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
        * kjs/AllInOneFile.cpp: Ditto.

LayoutTests:

        * fast/js/kde/resources/Array.js: Added tests to cover missing value behavior
        (not the same as undefined values in arrays). This matches the ECMA JavaScript
        specification, but doesn't exactly match Firefox.
        * fast/js/kde/Array-expected.txt: Updated with results.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@26881 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 625dc693
2007-10-22 Darin Adler <darin@apple.com>
Reviewed by Maciej.
- http://bugs.webkit.org/show_bug.cgi?id=15606
make cut-off for sparse vs. dense arrays smarter for speed with large arrays
Makes the morph test in SunSpider 26% faster, and the overall
benchmark 3% faster.
This also fixes some small problems we had with the distinction
between nonexistent and undefined values in arrays.
* kjs/array_instance.h: Tweaked formatting and naming.
* kjs/array_instance.cpp: Copied from kjs/array_object.cpp.
(KJS::storageSize): Added. Computes the size of the storage given a vector length.
(KJS::increasedVectorLength): Added. Implements the rule for resizing the vector.
(KJS::isDenseEnoughForVector): Added.
(KJS::ArrayInstance::ArrayInstance): Initialize the new fields.
(KJS::ArrayInstance::~ArrayInstance): Since m_storage is now never 0, delete it.
(KJS::ArrayInstance::getItem): Updated for name changes.
(KJS::ArrayInstance::lengthGetter): Ditto.
(KJS::ArrayInstance::inlineGetOwnPropertySlot): Added. Allows both versions of
getOwnPropertySlot to share more code.
(KJS::ArrayInstance::getOwnPropertySlot): Just refactored, no code change.
(KJS::ArrayInstance::put): Added logic for extending the vector as long as the
array is dense enough. Also keep m_numValuesInVector up to date.
(KJS::ArrayInstance::deleteProperty): Added code to keep m_numValuesInVector
up to date.
(KJS::ArrayInstance::getPropertyNames): Fixed bug where this would omit names
for array indices with undefined values.
(KJS::ArrayInstance::increaseVectorLength): Renamed from resizeStorage. Also
simplified to only handle getting larger.
(KJS::ArrayInstance::setLength): Added code to update m_numValuesInVector, to
zero out the unused part of the vector and to delete the map if it's no longer
needed.
(KJS::ArrayInstance::mark): Tweaked formatting.
(KJS::compareByStringForQSort): Ditto.
(KJS::ArrayInstance::sort): Ditto.
(KJS::CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
Ditto.
(KJS::compareWithCompareFunctionForQSort): Ditto.
(KJS::ArrayInstance::compactForSorting): Fixed bug where this would turn
undefined values into nonexistent values in some cases.
* kjs/array_object.h: Removed MAX_ARRAY_INDEX.
* kjs/array_object.cpp: Removed ArrayInstance. Moved to a separate file.
* JavaScriptCore.pri: Added array_instance.cpp.
* JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
* kjs/AllInOneFile.cpp: Ditto.
2007-10-22 Andrew Wellington <proton@wiretapped.net>
Reviewed by Mark Rowe.
......
......@@ -56,6 +56,7 @@ SOURCES += \
kjs/DateMath.cpp \
kjs/JSWrapperObject.cpp \
kjs/PropertyNameArray.cpp \
kjs/array_instance.cpp \
kjs/array_object.cpp \
kjs/bool_object.cpp \
kjs/collector.cpp \
......
......@@ -174,6 +174,10 @@
<Filter
Name="KJS"
>
<File
RelativePath="..\..\kjs\array_instance.cpp"
>
</File>
<File
RelativePath="..\..\kjs\array_instance.h"
>
......
......@@ -574,6 +574,7 @@
938C4F690CA06BC700D9310A /* ASCIICType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCIICType.h; sourceTree = "<group>"; };
938C4F6B0CA06BCE00D9310A /* DisallowCType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowCType.h; sourceTree = "<group>"; };
93AA4F770957251F0084B3A7 /* AlwaysInline.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = AlwaysInline.h; sourceTree = "<group>"; tabWidth = 8; };
93ADFCE60CCBD7AC00D30B08 /* array_instance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = array_instance.cpp; sourceTree = "<group>"; };
93B6A0DE0AA64DA40076DE27 /* GetPtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GetPtr.h; sourceTree = "<group>"; };
93E26BC908B1511900F85226 /* pcre_ord2utf8.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_ord2utf8.c; path = pcre/pcre_ord2utf8.c; sourceTree = "<group>"; tabWidth = 8; };
93E26BD308B1514100F85226 /* pcre_xclass.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = pcre_xclass.c; path = pcre/pcre_xclass.c; sourceTree = "<group>"; tabWidth = 8; };
......@@ -951,6 +952,7 @@
65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */,
65400C100A69BAF200509887 /* PropertyNameArray.h */,
938772E5038BFE19008635CE /* array_instance.h */,
93ADFCE60CCBD7AC00D30B08 /* array_instance.cpp */,
659126BC0BDD1728001921FB /* AllInOneFile.cpp */,
F692A84D0255597D01FF60F7 /* array_object.cpp */,
F692A84E0255597D01FF60F7 /* array_object.h */,
......
......@@ -28,6 +28,7 @@
#include "function.cpp"
#include "debugger.cpp"
#include "array_instance.cpp"
#include "array_object.cpp"
#include "bool_object.cpp"
#include "collector.cpp"
......
This diff is collapsed.
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
*
......@@ -27,46 +26,45 @@
namespace KJS {
struct ArrayStorage;
class ArrayInstance : public JSObject {
public:
ArrayInstance(JSObject *proto, unsigned initialLength);
ArrayInstance(JSObject *proto, const List &initialValues);
ArrayInstance(JSObject* prototype, unsigned initialLength);
ArrayInstance(JSObject* prototype, const List& initialValues);
~ArrayInstance();
virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState *, unsigned, PropertySlot&);
virtual void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None);
virtual void put(ExecState *exec, unsigned propertyName, JSValue *value, int attr = None);
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual bool deleteProperty(ExecState *exec, unsigned propertyName);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
virtual void put(ExecState*, const Identifier& propertyName, JSValue*, int attributes = None);
virtual void put(ExecState*, unsigned propertyName, JSValue*, int attributes = None);
virtual bool deleteProperty(ExecState *, const Identifier& propertyName);
virtual bool deleteProperty(ExecState *, unsigned propertyName);
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
virtual void mark();
virtual const ClassInfo *classInfo() const { return &info; }
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
unsigned getLength() const { return length; }
unsigned getLength() const { return m_length; }
JSValue* getItem(unsigned) const;
void sort(ExecState *exec);
void sort(ExecState *exec, JSObject *compareFunction);
void sort(ExecState*);
void sort(ExecState*, JSObject* compareFunction);
private:
static JSValue *lengthGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
static JSValue* lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
bool inlineGetOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
void setLength(unsigned newLength);
void setLength(unsigned);
void increaseVectorLength(unsigned newLength);
unsigned compactForSorting();
void resizeStorage(unsigned);
// store capacity in extra space at the beginning of the storage array to save space
size_t capacity() { return storage ? reinterpret_cast<size_t>(storage[-1]) : 0; }
unsigned compactForSorting();
unsigned length;
unsigned storageLength;
JSValue **storage;
unsigned m_length;
unsigned m_vectorLength;
ArrayStorage* m_storage;
};
} // namespace KJS
......
This diff is collapsed.
......@@ -49,8 +49,6 @@ namespace KJS {
int id;
};
const unsigned MAX_ARRAY_INDEX = 0xFFFFFFFEu;
class ArrayObjectImp : public InternalFunctionImp {
public:
ArrayObjectImp(ExecState *exec,
......
2007-10-22 Darin Adler <darin@apple.com>
* fast/js/kde/resources/Array.js: Added tests to cover missing value behavior
(not the same as undefined values in arrays). This matches the ECMA JavaScript
specification, but doesn't exactly match Firefox.
* fast/js/kde/Array-expected.txt: Updated with results.
2007-10-21 Mark Rowe <mrowe@apple.com>
Reviewed by Mitz.
......@@ -10,8 +17,6 @@
2007-10-21 Nikolas Zimmermann <zimmermann@kde.org>
Not reviewed.
Forgot to land the new computed style results in fast/css - after the addition of glyph-orientation-*.
* fast/css/computed-style-expected.txt:
......
......@@ -45,14 +45,23 @@ PASS [].length is 0
PASS ['a'].length is 1
PASS ['a'][0] is 'a'
PASS ['a',,'c'][2] is 'c'
PASS ['a',undefined,'c'][1] is undefined
PASS ['a',,'c'][1] is undefined
PASS 1 in ['a',,'c'] is false
PASS 1 in ['a',undefined,'c'] is true
PASS 1 in arrayWithDeletion is false
PASS forInSum([]) is ''
PASS forInSum(Array()) is ''
PASS forInSum(Array('a')) is 'a'
PASS forInSum([,undefined,'x','aa']) is 'undefinedxaa'
PASS forInSum(a0) is ''
PASS forInSum(a1) is 'a'
PASS String([].sort()) is ''
PASS String([3,1,'2'].sort()) is '1,2,3'
PASS String([,'x','aa'].sort()) is 'aa,x,'
PASS String([,undefined,'x','aa'].sort()) is 'aa,x,,'
PASS 2 in [,undefined,'x','aa'].sort() is true
PASS 3 in [,undefined,'x','aa'].sort() is false
PASS var a = ['aa', 'b', 'cccc', 'ddd']; String(a.sort(comp)) is 'b,aa,ddd,cccc'
PASS [0, Infinity].sort(function(a, b) { return a - b }).toString() is '0,Infinity'
PASS [].unshift('a') is 1
......
......@@ -72,6 +72,14 @@ shouldBe("[].length", "0");
shouldBe("['a'].length", "1");
shouldBe("['a'][0]", "'a'");
shouldBe("['a',,'c'][2]", "'c'");
shouldBe("['a',undefined,'c'][1]", "undefined");
shouldBe("['a',,'c'][1]", "undefined");
shouldBe("1 in ['a',,'c']", "false");
shouldBe("1 in ['a',undefined,'c']", "true");
var arrayWithDeletion = ['a','b','c'];
delete arrayWithDeletion[1];
shouldBe("1 in arrayWithDeletion", "false");
function forInSum(_a) {
var s = '';
......@@ -83,6 +91,7 @@ function forInSum(_a) {
shouldBe("forInSum([])", "''");
shouldBe("forInSum(Array())", "''");
shouldBe("forInSum(Array('a'))", "'a'");
shouldBe("forInSum([,undefined,'x','aa'])", "'undefinedxaa'");
var a0 = [];
shouldBe("forInSum(a0)", "''");
......@@ -92,7 +101,10 @@ shouldBe("forInSum(a1)", "'a'");
shouldBe("String([].sort())", "''")
shouldBe("String([3,1,'2'].sort())", "'1,2,3'");
shouldBe("String([,'x','aa'].sort())", "'aa,x,'"); // don't assume 'x'>undefined !
shouldBe("String([,'x','aa'].sort())", "'aa,x,'");
shouldBe("String([,undefined,'x','aa'].sort())", "'aa,x,,'");
shouldBe("2 in [,undefined,'x','aa'].sort()", "true");
shouldBe("3 in [,undefined,'x','aa'].sort()", "false");
// sort by length
function comp(a, b) {
......
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