Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Unified Diff: src/builtins.cc

Issue 1549016: [Not for commit] Make Array.splice change receiver's FixedArray when significant part is cut. (Closed)
Patch Set: Additional tests for splice Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/mjsunit/array-splice.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index f40b5c27741787d5869fd3e0a61e92bb917d3bf1..5fbe000f87f7d7745390880d3ae61fc1a9f338e1 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -336,6 +336,7 @@ static FixedArray* LeftTrimFixedArray(FixedArray* elms, int to_trim) {
// In old space we do not use this trick to avoid dealing with
// remembered sets.
ASSERT(Heap::new_space()->Contains(elms));
+ ASSERT(to_trim > 0);
STATIC_ASSERT(FixedArray::kMapOffset == 0);
STATIC_ASSERT(FixedArray::kLengthOffset == kPointerSize);
@@ -718,97 +719,138 @@ BUILTIN(ArraySplice) {
}
int actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
+ int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
+
+ int new_length = len - actual_delete_count + item_count;
+
JSArray* result_array = NULL;
- if (actual_delete_count == 0) {
- Object* result = AllocateEmptyJSArray();
- if (result->IsFailure()) return result;
- result_array = JSArray::cast(result);
- } else {
- // Allocate result array.
+ if (Heap::new_space()->Contains(elms) &&
+ (2 * actual_delete_count >= len + item_count)) {
antonm 2010/04/05 12:21:13 looks like you're trying to keep the number of wri
iegorov 2010/04/05 13:01:49 My counts differ: - when making inplace (terminolo
antonm 2010/04/05 14:34:30 Sorry, I should have been explicit but I didn't ac
+ // Allocate array for receiver's array.
Object* result = AllocateJSArray();
if (result->IsFailure()) return result;
result_array = JSArray::cast(result);
- result = Heap::AllocateUninitializedFixedArray(actual_delete_count);
+ result = Heap::AllocateUninitializedFixedArray(new_length);
if (result->IsFailure()) return result;
- FixedArray* result_elms = FixedArray::cast(result);
+ FixedArray* receiver_elms = FixedArray::cast(result);
- AssertNoAllocation no_gc;
- // Fill newly created array.
- CopyElements(&no_gc,
- result_elms, 0,
- elms, actual_start,
- actual_delete_count);
+ int tail_length = len - actual_start - actual_delete_count;
+ ASSERT(tail_length >= 0);
- // Set elements.
- result_array->set_elements(result_elms);
+ AssertNoAllocation no_gc;
+ // Fill with receiver elements.
+ if (actual_start > 0) {
+ CopyElements(&no_gc,
+ receiver_elms, 0,
+ elms, 0,
+ actual_start);
+ }
+ if (tail_length > 0) {
+ CopyElements(&no_gc,
+ receiver_elms, actual_start + item_count,
+ elms, actual_start + actual_delete_count,
+ tail_length);
+ }
+ array->set_elements(receiver_elms);
+ array->set_length(Smi::FromInt(new_length));
- // Set the length.
+ if (actual_start > 0) {
+ elms = LeftTrimFixedArray(elms, actual_start);
antonm 2010/04/05 12:21:13 good you noticed that---was going to bring your at
iegorov 2010/04/05 13:01:49 Yeah, testing rocks :) On 2010/04/05 12:21:13, ant
+ }
+ result_array->set_elements(elms, SKIP_WRITE_BARRIER);
result_array->set_length(Smi::FromInt(actual_delete_count));
- }
+ FillWithHoles(elms, actual_delete_count, len - actual_start);
- int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
-
- int new_length = len - actual_delete_count + item_count;
+ elms = receiver_elms;
+ } else {
+ if (actual_delete_count == 0) {
+ Object* result = AllocateEmptyJSArray();
+ if (result->IsFailure()) return result;
+ result_array = JSArray::cast(result);
+ } else {
+ // Allocate result array.
+ Object* result = AllocateJSArray();
+ if (result->IsFailure()) return result;
+ result_array = JSArray::cast(result);
- if (item_count < actual_delete_count) {
- // Shrink the array.
- const bool trim_array = Heap::new_space()->Contains(elms) &&
- ((actual_start + item_count) <
- (len - actual_delete_count - actual_start));
- if (trim_array) {
- const int delta = actual_delete_count - item_count;
-
- if (actual_start > 0) {
- Object** start = elms->data_start();
- memmove(start + delta, start, actual_start * kPointerSize);
- }
+ result = Heap::AllocateUninitializedFixedArray(actual_delete_count);
+ if (result->IsFailure()) return result;
+ FixedArray* result_elms = FixedArray::cast(result);
- elms = LeftTrimFixedArray(elms, delta);
- array->set_elements(elms, SKIP_WRITE_BARRIER);
- } else {
AssertNoAllocation no_gc;
- MoveElements(&no_gc,
- elms, actual_start + item_count,
- elms, actual_start + actual_delete_count,
- (len - actual_delete_count - actual_start));
- FillWithHoles(elms, new_length, len);
+ // Fill newly created array.
+ CopyElements(&no_gc,
+ result_elms, 0,
+ elms, actual_start,
+ actual_delete_count);
+
+ // Set elements.
+ result_array->set_elements(result_elms);
+
+ // Set the length.
+ result_array->set_length(Smi::FromInt(actual_delete_count));
}
- } else if (item_count > actual_delete_count) {
- // Currently fixed arrays cannot grow too big, so
- // we should never hit this case.
- ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
-
- // Check if array need to grow.
- if (new_length > elms->length()) {
- // New backing storage is needed.
- int capacity = new_length + (new_length >> 1) + 16;
- Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
- if (obj->IsFailure()) return obj;
- FixedArray* new_elms = FixedArray::cast(obj);
- AssertNoAllocation no_gc;
- // Copy the part before actual_start as is.
- if (actual_start > 0) {
- CopyElements(&no_gc, new_elms, 0, elms, 0, actual_start);
- }
- const int to_copy = len - actual_delete_count - actual_start;
- if (to_copy > 0) {
- CopyElements(&no_gc,
- new_elms, actual_start + item_count,
+ if (item_count < actual_delete_count) {
+ // Shrink the array.
+ const bool trim_array = Heap::new_space()->Contains(elms) &&
+ ((actual_start + item_count) <
+ (len - actual_delete_count - actual_start));
+ if (trim_array) {
+ const int delta = actual_delete_count - item_count;
+
+ if (actual_start > 0) {
+ Object** start = elms->data_start();
+ memmove(start + delta, start, actual_start * kPointerSize);
+ }
+
+ elms = LeftTrimFixedArray(elms, delta);
+ array->set_elements(elms, SKIP_WRITE_BARRIER);
+ } else {
+ AssertNoAllocation no_gc;
+ MoveElements(&no_gc,
+ elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
- to_copy);
+ (len - actual_delete_count - actual_start));
+ FillWithHoles(elms, new_length, len);
}
- FillWithHoles(new_elms, new_length, capacity);
+ } else if (item_count > actual_delete_count) {
+ // Currently fixed arrays cannot grow too big, so
+ // we should never hit this case.
+ ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
+
+ // Check if array need to grow.
+ if (new_length > elms->length()) {
+ // New backing storage is needed.
+ int capacity = new_length + (new_length >> 1) + 16;
+ Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
+ if (obj->IsFailure()) return obj;
+ FixedArray* new_elms = FixedArray::cast(obj);
- elms = new_elms;
- array->set_elements(elms);
- } else {
- AssertNoAllocation no_gc;
- MoveElements(&no_gc,
- elms, actual_start + item_count,
- elms, actual_start + actual_delete_count,
- (len - actual_delete_count - actual_start));
+ AssertNoAllocation no_gc;
+ // Copy the part before actual_start as is.
+ if (actual_start > 0) {
+ CopyElements(&no_gc, new_elms, 0, elms, 0, actual_start);
+ }
+ const int to_copy = len - actual_delete_count - actual_start;
+ if (to_copy > 0) {
+ CopyElements(&no_gc,
+ new_elms, actual_start + item_count,
+ elms, actual_start + actual_delete_count,
+ to_copy);
+ }
+ FillWithHoles(new_elms, new_length, capacity);
+
+ elms = new_elms;
+ array->set_elements(elms);
+ } else {
+ AssertNoAllocation no_gc;
+ MoveElements(&no_gc,
+ elms, actual_start + item_count,
+ elms, actual_start + actual_delete_count,
+ (len - actual_delete_count - actual_start));
+ }
}
}
« no previous file with comments | « no previous file | test/mjsunit/array-splice.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698