Revert 22595: "Keep new arrays allocated with 'new Array(N)' in fast mode"

Due to failures in mjsunit/array-functions-prototype-misc

TBR=verwaest@chromium.org

Review URL: https://codereview.chromium.org/417953004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22601 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2014-07-24 13:38:05 +00:00
parent 70e2a040b3
commit b5a5148260
16 changed files with 40 additions and 91 deletions

View File

@ -897,7 +897,8 @@ class FastElementsAccessor
typedef typename KindTraits::BackingStore BackingStore;
// Adjusts the length of the fast backing store..
// Adjusts the length of the fast backing store or returns the new length or
// undefined in case conversion to a slow backing store should be performed.
static Handle<Object> SetLengthWithoutNormalize(
Handle<FixedArrayBase> backing_store,
Handle<JSArray> array,
@ -949,10 +950,15 @@ class FastElementsAccessor
// Check whether the backing store should be expanded.
uint32_t min = JSObject::NewElementsCapacity(old_capacity);
uint32_t new_capacity = length > min ? length : min;
FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
array, new_capacity, length);
JSObject::ValidateElements(array);
return length_object;
if (!array->ShouldConvertToSlowElements(new_capacity)) {
FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
array, new_capacity, length);
JSObject::ValidateElements(array);
return length_object;
}
// Request conversion to slow elements.
return isolate->factory()->undefined_value();
}
static Handle<Object> DeleteCommon(Handle<JSObject> obj,

View File

@ -11720,17 +11720,6 @@ static void EndPerformSplice(Handle<JSArray> object) {
MaybeHandle<Object> JSArray::SetElementsLength(
Handle<JSArray> array,
Handle<Object> new_length_handle) {
if (array->HasFastElements()) {
// If the new array won't fit in a some non-trivial fraction of the max old
// space size, then force it to go dictionary mode.
int max_fast_array_size = static_cast<int>(
(array->GetHeap()->MaxOldGenerationSize() / kDoubleSize) / 4);
if (new_length_handle->IsNumber() &&
NumberToInt32(*new_length_handle) >= max_fast_array_size) {
NormalizeElements(array);
}
}
// We should never end in here with a pixel or external array.
ASSERT(array->AllowsSetElementsLength());
if (!array->map()->is_observed()) {

View File

@ -10576,30 +10576,7 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
ASSERT(args.length() == 2);
CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
ElementsKind kind = array->GetElementsKind();
bool estimate_keys_as_length = IsFastPackedElementsKind(kind);
if (IsHoleyElementsKind(kind)) {
ElementsAccessor* accessor = array->GetElementsAccessor();
// If more than 10% of the array is holes, then calculate the key set, it's
// much faster than using the runtime to walk the prototype chain in the
// hole case.
int holes = 0;
int length = array->elements()->length();
for (int i = 0; i < length; ++i) {
if (!accessor->HasElement(array, array, i)) {
++holes;
}
}
estimate_keys_as_length = holes < static_cast<int>(length / 10);
}
if (estimate_keys_as_length) {
RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
array->HasFastDoubleElements());
uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
} else {
if (array->elements()->IsDictionary()) {
Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
for (PrototypeIterator iter(isolate, array,
PrototypeIterator::START_AT_RECEIVER);
@ -10626,6 +10603,11 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
}
return *isolate->factory()->NewJSArrayWithElements(keys);
} else {
RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
array->HasFastDoubleElements());
uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
}
}
@ -14949,15 +14931,6 @@ RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
}
RUNTIME_FUNCTION(Runtime_NormalizeElements) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
JSObject::NormalizeElements(array);
return *array;
}
RUNTIME_FUNCTION(Runtime_MaxSmi) {
ASSERT(args.length() == 0);
return Smi::FromInt(Smi::kMaxValue);

View File

@ -440,7 +440,6 @@ namespace internal {
/* Arrays */ \
F(ArrayConstructor, -1, 1) \
F(InternalArrayConstructor, -1, 1) \
F(NormalizeElements, 1, 1) \
\
/* Literals */ \
F(MaterializeRegExpLiteral, 4, 1) \

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
// TODO(jkummerow): There are many ways to improve these tests, e.g.:
// - more variance in randomized inputs
// - better time complexity management
@ -17,9 +15,7 @@ function makeArguments() {
result.push(17);
result.push(-31);
result.push(new Array(100));
var a = %NormalizeElements([]);
a.length = 100003;
result.push(a);
result.push(new Array(100003));
result.push(Number.MIN_VALUE);
result.push("whoops");
result.push("x");

View File

@ -297,6 +297,10 @@ obj = newarraycase_onearg(10, 5);
assertKind(elements_kind.fast_double, obj);
obj = newarraycase_onearg(0, 5);
assertKind(elements_kind.fast_double, obj);
// Now pass a length that forces the dictionary path.
obj = newarraycase_onearg(100000, 5);
assertKind(elements_kind.dictionary, obj);
assertTrue(obj.length == 100000);
// Verify that cross context calls work
var realmA = Realm.current();

View File

@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
function f0() {
return this;
}
@ -116,8 +114,7 @@ function al() {
for (var j = 1; j < 0x40000000; j <<= 1) {
try {
var a = %NormalizeElements([]);
a.length = j;
var a = new Array(j);
a[j - 1] = 42;
assertEquals(42 + j, al.apply(345, a));
} catch (e) {
@ -125,8 +122,7 @@ for (var j = 1; j < 0x40000000; j <<= 1) {
for (; j < 0x40000000; j <<= 1) {
var caught = false;
try {
a = %NormalizeElements([]);
a.length = j;
a = new Array(j);
a[j - 1] = 42;
al.apply(345, a);
assertUnreachable("Apply of array with length " + a.length +

View File

@ -130,7 +130,8 @@ function assertKind(expected, obj, name_opt) {
a = bar(10);
assertKind(elements_kind.fast, a);
assertOptimized(bar);
bar(100000);
a = bar(100000);
assertKind(elements_kind.dictionary, a);
assertOptimized(bar);
// If the argument isn't a smi, things should still work.

View File

@ -92,7 +92,7 @@ function assertKind(expected, obj, name_opt) {
assertKind(elements_kind.fast, b);
a = create1(100000);
assertKind(elements_kind.fast_smi_only, a);
assertKind(elements_kind.dictionary, a);
function create3(arg1, arg2, arg3) {
return Array(arg1, arg2, arg3);

View File

@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Check that splicing array of holes keeps it as array of holes
(function() {
for (var i = 0; i < 7; i++) {
@ -359,9 +357,7 @@
(function() {
for (var i = 0; i < 7; i++) {
try {
var a = %NormalizeElements([]);
a.length = Math.pow(2, 32) - 3;
a.splice(-1, 0, 1, 2, 3, 4, 5);
new Array(Math.pow(2, 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
throw 'Should have thrown RangeError';
} catch (e) {
assertTrue(e instanceof RangeError);
@ -369,8 +365,7 @@
// Check smi boundary
var bigNum = (1 << 30) - 3;
var array = %NormalizeElements([]);
array.length = bigNum;
var array = new Array(bigNum);
array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
assertEquals(bigNum + 7, array.length);
}

View File

@ -194,9 +194,7 @@
(function() {
for (var i = 0; i < 7; i++) {
try {
var a1 = [];
a1[Math.pow(2, 32) - 3 - 1] = 0;
a1.unshift(1, 2, 3, 4, 5);
new Array(Math.pow(2, 32) - 3).unshift(1, 2, 3, 4, 5);
throw 'Should have thrown RangeError';
} catch (e) {
assertTrue(e instanceof RangeError);
@ -204,9 +202,7 @@
// Check smi boundary
var bigNum = (1 << 30) - 3;
var a2 = [];
a2[bigNum - 1] = 0;
assertEquals(bigNum + 7, a2.unshift(1, 2, 3, 4, 5, 6, 7));
assertEquals(bigNum + 7, new Array(bigNum).unshift(1, 2, 3, 4, 5, 6, 7));
}
})();

View File

@ -145,9 +145,7 @@ function test_wrapper() {
}
assertKind(elements_kind.fast, you);
var temp = [];
temp[0xDECAF] = 0;
assertKind(elements_kind.dictionary, temp);
assertKind(elements_kind.dictionary, new Array(0xDECAF));
var fast_double_array = new Array(0xDECAF);
for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2;

View File

@ -1234,9 +1234,8 @@ observer2.assertCallbackRecords([
// Updating length on large (slow) array
reset();
var slow_arr = %NormalizeElements([]);
var slow_arr = new Array(1000000000);
slow_arr[500000000] = 'hello';
slow_arr.length = 1000000000;
Object.observe(slow_arr, observer.callback);
var spliceRecords;
function slowSpliceCallback(records) {

View File

@ -37,7 +37,7 @@ function init_sparse_array(a) {
a[i] = i;
}
a[5000000] = 256;
return %NormalizeElements(a);
assertTrue(%HasDictionaryElements(a));
}
function testPolymorphicLoads() {
@ -49,7 +49,7 @@ function testPolymorphicLoads() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
var sparse_js_array = %NormalizeElements([]);
var sparse_js_array = new Array(5000001);
init_array(object_array);
init_array(js_array);
@ -67,7 +67,7 @@ function testPolymorphicLoads() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
var sparse_js_array = %NormalizeElements([]);
var sparse_js_array = new Array(5000001);
init_array(object_array);
init_array(js_array);
@ -114,8 +114,7 @@ function testPolymorphicStores() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
var sparse_js_array = [];
sparse_js_array.length = 5000001;
var sparse_js_array = new Array(5000001);
init_array(object_array);
init_array(js_array);
@ -133,8 +132,7 @@ function testPolymorphicStores() {
var object_array = new Object;
var sparse_object_array = new Object;
var js_array = new Array(10);
var sparse_js_array = %NormalizeElements([]);
sparse_js_array.length = 5000001;
var sparse_js_array = new Array(5000001);
init_array(object_array);
init_array(js_array);

View File

@ -26,6 +26,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that we can create arrays of any size.
for (var i = 1000; i < 1000000; i += 19703) {
for (var i = 1000; i < 1000000; i += 197) {
new Array(i);
}

View File

@ -47,7 +47,7 @@ EXPAND_MACROS = [
# that the parser doesn't bit-rot. Change the values as needed when you add,
# remove or change runtime functions, but make sure we don't lose our ability
# to parse them!
EXPECTED_FUNCTION_COUNT = 421
EXPECTED_FUNCTION_COUNT = 420
EXPECTED_FUZZABLE_COUNT = 335
EXPECTED_CCTEST_COUNT = 8
EXPECTED_UNKNOWN_COUNT = 4
@ -124,7 +124,6 @@ BLACKLISTED = [
# Arrays
"ArrayConstructor",
"InternalArrayConstructor",
"NormalizeElements",
# Literals
"MaterializeRegExpLiteral",