From: rossberg@chromium.org Date: Tue, 28 May 2013 13:00:53 +0000 (+0000) Subject: Revert "Implement ObservedArrayPop, ObservedArrayShift, ObservedArrayUnshift & Observ... X-Git-Tag: upstream/4.7.83~14090 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ecb6bd27189b11c86b008a85e29bb623d5d4e523;p=platform%2Fupstream%2Fv8.git Revert "Implement ObservedArrayPop, ObservedArrayShift, ObservedArrayUnshift & ObservedArraySplice" This reverts commit r14846. Broke Mozilla test (see http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20shared/builds/3608/steps/Mozilla/logs/stdio), e.g.: === mozilla/js1_5/Array/regress-451483 === --- stdout --- BUGNUMBER: 451483 STATUS: [].splice.call(0) == [] /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/data/js1_5/Array/regress-451483.js:57: illegal access var result = [].splice.call(0); ^ Command: /mnt/data/b/build/slave/v8-linux-shared/build/v8/out/Release/d8 --test --nobreak-on-abort --nodead-code-elimination --nofold-constants --expose-gc /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/mozilla-shell-emulation.js /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/data/shell.js /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/data/js1_5/shell.js /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/data/js1_5/Array/shell.js /mnt/data/b/build/slave/v8-linux-shared/build/v8/test/mozilla/data/js1_5/Array/regress-451483.js TBR=rafaelw@chromium.org BUG= Review URL: https://codereview.chromium.org/16150003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14851 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/array.js b/src/array.js index dcfcde5..a3674e8 100644 --- a/src/array.js +++ b/src/array.js @@ -395,23 +395,6 @@ function ArrayJoin(separator) { } -function ObservedArrayPop(n) { - n--; - var value = this[n]; - - EnqueueSpliceRecord(this, n, [value], 1, 0); - - try { - BeginPerformSplice(this); - delete this[n]; - this.length = n; - } finally { - EndPerformSplice(this); - } - - return value; -} - // Removes the last element from the array and returns it. See // ECMA-262, section 15.4.4.6. function ArrayPop() { @@ -425,10 +408,6 @@ function ArrayPop() { this.length = n; return; } - - if (%IsObserved(this)) - return ObservedArrayPop.call(this, n); - n--; var value = this[n]; delete this[n]; @@ -445,6 +424,7 @@ function ObservedArrayPush() { try { BeginPerformSplice(this); + for (var i = 0; i < m; i++) { this[i+n] = %_Arguments(i); } @@ -578,22 +558,6 @@ function ArrayReverse() { } -function ObservedArrayShift(len) { - var first = this[0]; - - EnqueueSpliceRecord(this, 0, [first], 1, 0); - - try { - BeginPerformSplice(this); - SimpleMove(this, 0, 1, len, 0); - this.length = len - 1; - } finally { - EndPerformSplice(this); - } - - return first; -} - function ArrayShift() { if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { throw MakeTypeError("called_on_null_or_undefined", @@ -607,12 +571,9 @@ function ArrayShift() { return; } - if (%IsObserved(this)) - return ObservedArrayShift.call(this, len); - var first = this[0]; - if (IS_ARRAY(this)) { + if (IS_ARRAY(this) && !%IsObserved(this)) { SmartMove(this, 0, 1, len, 0); } else { SimpleMove(this, 0, 1, len, 0); @@ -623,25 +584,6 @@ function ArrayShift() { return first; } -function ObservedArrayUnshift() { - var len = TO_UINT32(this.length); - var num_arguments = %_ArgumentsLength(); - - EnqueueSpliceRecord(this, 0, [], 0, num_arguments); - - try { - BeginPerformSplice(this); - SimpleMove(this, 0, 0, len, num_arguments); - for (var i = 0; i < num_arguments; i++) { - this[i] = %_Arguments(i); - } - this.length = len + num_arguments; - } finally { - EndPerformSplice(this); - } - - return len + num_arguments; -} function ArrayUnshift(arg1) { // length == 1 if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { @@ -649,13 +591,10 @@ function ArrayUnshift(arg1) { // length == 1 ["Array.prototype.unshift"]); } - if (%IsObserved(this)) - return ObservedArrayUnshift.apply(this, arguments); - var len = TO_UINT32(this.length); var num_arguments = %_ArgumentsLength(); - if (IS_ARRAY(this)) { + if (IS_ARRAY(this) && !%IsObserved(this)) { SmartMove(this, 0, 0, len, num_arguments); } else { SimpleMove(this, 0, 0, len, num_arguments); @@ -716,100 +655,52 @@ function ArraySlice(start, end) { } -function ComputeSpliceStartIndex(start_i, len) { - if (start_i < 0) { - start_i += len; - return start_i < 0 ? 0 : start_i; +function ArraySplice(start, delete_count) { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Array.prototype.splice"]); } - return start_i > len ? len : start_i; -} + var num_arguments = %_ArgumentsLength(); + var len = TO_UINT32(this.length); + var start_i = TO_INTEGER(start); + + if (start_i < 0) { + start_i += len; + if (start_i < 0) start_i = 0; + } else { + if (start_i > len) start_i = len; + } -function ComputeSpliceDeleteCount(delete_count, num_arguments, len, start_i) { // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is // given as a request to delete all the elements from the start. // And it differs from the case of undefined delete count. // This does not follow ECMA-262, but we do the same for // compatibility. var del_count = 0; - if (num_arguments == 1) - return len - start_i; - - del_count = TO_INTEGER(delete_count); - if (del_count < 0) - return 0; - - if (del_count > len - start_i) - return len - start_i; - - return del_count; -} - + if (num_arguments == 1) { + del_count = len - start_i; + } else { + del_count = TO_INTEGER(delete_count); + if (del_count < 0) del_count = 0; + if (del_count > len - start_i) del_count = len - start_i; + } -function ObservedArraySplice(start, delete_count) { - var num_arguments = %_ArgumentsLength(); - var len = TO_UINT32(this.length); - var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); - var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, - start_i); var deleted_elements = []; deleted_elements.length = del_count; - var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; - - try { - BeginPerformSplice(this); - SimpleSlice(this, start_i, del_count, len, deleted_elements); - SimpleMove(this, start_i, del_count, len, num_elements_to_add); - - // Insert the arguments into the resulting array in - // place of the deleted elements. - var i = start_i; - var arguments_index = 2; - var arguments_length = %_ArgumentsLength(); - while (arguments_index < arguments_length) { - this[i++] = %_Arguments(arguments_index++); - } - this.length = len - del_count + num_elements_to_add; - - } finally { - EndPerformSplice(this); - if (deleted_elements.length || num_elements_to_add) { - EnqueueSpliceRecord(this, - start_i, - deleted_elements.slice(), - deleted_elements.length, - num_elements_to_add); - } - } - - // Return the deleted elements. - return deleted_elements; -} - - -function ArraySplice(start, delete_count) { - if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { - throw MakeTypeError("called_on_null_or_undefined", - ["Array.prototype.splice"]); + // Number of elements to add. + var num_additional_args = 0; + if (num_arguments > 2) { + num_additional_args = num_arguments - 2; } - if (%IsObserved(this)) - return ObservedArraySplice.apply(this, arguments); - - var num_arguments = %_ArgumentsLength(); - var len = TO_UINT32(this.length); - var start_i = ComputeSpliceStartIndex(TO_INTEGER(start), len); - var del_count = ComputeSpliceDeleteCount(delete_count, num_arguments, len, - start_i); - var deleted_elements = []; - deleted_elements.length = del_count; - var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; - var use_simple_splice = true; + if (IS_ARRAY(this) && - num_elements_to_add !== del_count) { + !%IsObserved(this) && + num_additional_args !== del_count) { // If we are only deleting/moving a few things near the end of the // array then the simple version is going to be faster, because it // doesn't touch most of the array. @@ -821,10 +712,10 @@ function ArraySplice(start, delete_count) { if (use_simple_splice) { SimpleSlice(this, start_i, del_count, len, deleted_elements); - SimpleMove(this, start_i, del_count, len, num_elements_to_add); + SimpleMove(this, start_i, del_count, len, num_additional_args); } else { SmartSlice(this, start_i, del_count, len, deleted_elements); - SmartMove(this, start_i, del_count, len, num_elements_to_add); + SmartMove(this, start_i, del_count, len, num_additional_args); } // Insert the arguments into the resulting array in @@ -835,7 +726,7 @@ function ArraySplice(start, delete_count) { while (arguments_index < arguments_length) { this[i++] = %_Arguments(arguments_index++); } - this.length = len - del_count + num_elements_to_add; + this.length = len - del_count + num_additional_args; // Return the deleted elements. return deleted_elements; diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js index 4c75e63..47b5d8c 100644 --- a/test/mjsunit/harmony/object-observe.js +++ b/test/mjsunit/harmony/object-observe.js @@ -1175,13 +1175,11 @@ observer.assertCallbackRecords([ ]); // Pop -reset(); -var array = [1, 2]; +reset() +var array = {0: 1, 1: 2, length: 2}; Object.observe(array, observer.callback); -Array.observe(array, observer2.callback); -array.pop(); -array.pop(); -array.pop(); +Array.prototype.pop.call(array); +Array.prototype.pop.call(array); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ { object: array, name: '1', type: 'deleted', oldValue: 2 }, @@ -1189,20 +1187,13 @@ observer.assertCallbackRecords([ { object: array, name: '0', type: 'deleted', oldValue: 1 }, { object: array, name: 'length', type: 'updated', oldValue: 1 }, ]); -Object.deliverChangeRecords(observer2.callback); -observer2.assertCallbackRecords([ - { object: array, type: 'splice', index: 1, removed: [2], addedCount: 0 }, - { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 } -]); // Shift -reset(); -var array = [1, 2]; +reset() +var array = {0: 1, 1: 2, length: 2}; Object.observe(array, observer.callback); -Array.observe(array, observer2.callback); -array.shift(); -array.shift(); -array.shift(); +Array.prototype.shift.call(array); +Array.prototype.shift.call(array); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ { object: array, name: '0', type: 'updated', oldValue: 1 }, @@ -1211,71 +1202,32 @@ observer.assertCallbackRecords([ { object: array, name: '0', type: 'deleted', oldValue: 2 }, { object: array, name: 'length', type: 'updated', oldValue: 1 }, ]); -Object.deliverChangeRecords(observer2.callback); -observer2.assertCallbackRecords([ - { object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 }, - { object: array, type: 'splice', index: 0, removed: [2], addedCount: 0 } -]); // Unshift -reset(); -var array = [1, 2]; +reset() +var array = {0: 1, 1: 2, length: 2}; Object.observe(array, observer.callback); -Array.observe(array, observer2.callback); -array.unshift(3, 4); -array.unshift(5); +Array.prototype.unshift.call(array, 3, 4); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ { object: array, name: '3', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 2 }, { object: array, name: '2', type: 'new' }, { object: array, name: '0', type: 'updated', oldValue: 1 }, { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '4', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 4 }, - { object: array, name: '3', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 4 }, - { object: array, name: '0', type: 'updated', oldValue: 3 }, -]); -Object.deliverChangeRecords(observer2.callback); -observer2.assertCallbackRecords([ - { object: array, type: 'splice', index: 0, removed: [], addedCount: 2 }, - { object: array, type: 'splice', index: 0, removed: [], addedCount: 1 } + { object: array, name: 'length', type: 'updated', oldValue: 2 }, ]); // Splice -reset(); -var array = [1, 2, 3]; +reset() +var array = {0: 1, 1: 2, 2: 3, length: 3}; Object.observe(array, observer.callback); -Array.observe(array, observer2.callback); -array.splice(1, 0, 4, 5); // 1 4 5 2 3 -array.splice(0, 2); // 5 2 3 -array.splice(1, 2, 6, 7); // 5 6 7 -array.splice(2, 0); +Array.prototype.splice.call(array, 1, 1, 4, 5); Object.deliverChangeRecords(observer.callback); observer.assertCallbackRecords([ - { object: array, name: '4', type: 'new' }, - { object: array, name: 'length', type: 'updated', oldValue: 3 }, { object: array, name: '3', type: 'new' }, { object: array, name: '1', type: 'updated', oldValue: 2 }, { object: array, name: '2', type: 'updated', oldValue: 3 }, - - { object: array, name: '0', type: 'updated', oldValue: 1 }, - { object: array, name: '1', type: 'updated', oldValue: 4 }, - { object: array, name: '2', type: 'updated', oldValue: 5 }, - { object: array, name: '4', type: 'deleted', oldValue: 3 }, - { object: array, name: '3', type: 'deleted', oldValue: 2 }, - { object: array, name: 'length', type: 'updated', oldValue: 5 }, - - { object: array, name: '1', type: 'updated', oldValue: 2 }, - { object: array, name: '2', type: 'updated', oldValue: 3 }, -]); -Object.deliverChangeRecords(observer2.callback); -observer2.assertCallbackRecords([ - { object: array, type: 'splice', index: 1, removed: [], addedCount: 2 }, - { object: array, type: 'splice', index: 0, removed: [1, 4], addedCount: 0 }, - { object: array, type: 'splice', index: 1, removed: [2, 3], addedCount: 2 }, + { object: array, name: 'length', type: 'updated', oldValue: 3 }, ]); // Exercise StoreIC_ArrayLength