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

Side by Side Diff: src/builtins.cc

Issue 1311363003: Revert of Array.prototype.unshift builtin improvements (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/elements.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 BUILTIN(Illegal) { 168 BUILTIN(Illegal) {
169 UNREACHABLE(); 169 UNREACHABLE();
170 return isolate->heap()->undefined_value(); // Make compiler happy. 170 return isolate->heap()->undefined_value(); // Make compiler happy.
171 } 171 }
172 172
173 173
174 BUILTIN(EmptyFunction) { 174 BUILTIN(EmptyFunction) {
175 return isolate->heap()->undefined_value(); 175 return isolate->heap()->undefined_value();
176 } 176 }
177 177
178 namespace {
179 178
180 bool ObjectToClampedInteger(Object* object, int* out) { 179 // TODO(cbruni): check if this is a suitable method on Object
180 bool ClampedToInteger(Object* object, int* out) {
181 // This is an extended version of ECMA-262 9.4, but additionally 181 // This is an extended version of ECMA-262 9.4, but additionally
182 // clamps values to [kMinInt, kMaxInt] 182 // clamps values to [kMinInt, kMaxInt]
183 if (object->IsSmi()) { 183 if (object->IsSmi()) {
184 *out = Smi::cast(object)->value(); 184 *out = Smi::cast(object)->value();
185 return true; 185 return true;
186 } else if (object->IsHeapNumber()) { 186 } else if (object->IsHeapNumber()) {
187 *out = FastD2IChecked(HeapNumber::cast(object)->value()); 187 *out = FastD2IChecked(HeapNumber::cast(object)->value());
188 return true; 188 return true;
189 } else if (object->IsUndefined()) { 189 } else if (object->IsUndefined()) {
190 *out = 0; 190 *out = 0;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 324 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
325 isolate, result, 325 isolate, result,
326 Execution::Call(isolate, 326 Execution::Call(isolate,
327 function, 327 function,
328 args.receiver(), 328 args.receiver(),
329 argc, 329 argc,
330 argv.start())); 330 argv.start()));
331 return *result; 331 return *result;
332 } 332 }
333 333
334 } // namespace
335 334
336 BUILTIN(ArrayPush) { 335 BUILTIN(ArrayPush) {
337 HandleScope scope(isolate); 336 HandleScope scope(isolate);
338 Handle<Object> receiver = args.receiver(); 337 Handle<Object> receiver = args.receiver();
339 MaybeHandle<FixedArrayBase> maybe_elms_obj = 338 MaybeHandle<FixedArrayBase> maybe_elms_obj =
340 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); 339 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
341 Handle<FixedArrayBase> elms_obj; 340 Handle<FixedArrayBase> elms_obj;
342 if (!maybe_elms_obj.ToHandle(&elms_obj)) { 341 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
343 return CallJsBuiltin(isolate, "$arrayPush", args); 342 return CallJsBuiltin(isolate, "$arrayPush", args);
344 } 343 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 DisallowHeapAllocation no_gc; 425 DisallowHeapAllocation no_gc;
427 heap->MoveElements(*elms, 0, 1, len - 1); 426 heap->MoveElements(*elms, 0, 1, len - 1);
428 elms->set(len - 1, heap->the_hole_value()); 427 elms->set(len - 1, heap->the_hole_value());
429 } else { 428 } else {
430 Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj); 429 Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
431 MoveDoubleElements(*elms, 0, *elms, 1, len - 1); 430 MoveDoubleElements(*elms, 0, *elms, 1, len - 1);
432 elms->set_the_hole(len - 1); 431 elms->set_the_hole(len - 1);
433 } 432 }
434 } 433 }
435 434
435 // Set the length.
436 array->set_length(Smi::FromInt(len - 1)); 436 array->set_length(Smi::FromInt(len - 1));
437 437
438 return *first; 438 return *first;
439 } 439 }
440 440
441 441
442 BUILTIN(ArrayUnshift) { 442 BUILTIN(ArrayUnshift) {
443 HandleScope scope(isolate); 443 HandleScope scope(isolate);
444 Handle<Object> receiver = args.receiver(); 444 Handle<Object> receiver = args.receiver();
445 MaybeHandle<FixedArrayBase> maybe_elms_obj = 445 MaybeHandle<FixedArrayBase> maybe_elms_obj =
446 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); 446 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
447 Handle<FixedArrayBase> elms_obj; 447 Handle<FixedArrayBase> elms_obj;
448 if (!maybe_elms_obj.ToHandle(&elms_obj)) { 448 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
449 return CallJsBuiltin(isolate, "$arrayUnshift", args); 449 return CallJsBuiltin(isolate, "$arrayUnshift", args);
450 } 450 }
451 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 451 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
452 DCHECK(!array->map()->is_observed()); 452 DCHECK(!array->map()->is_observed());
453 if (!array->HasFastSmiOrObjectElements()) {
454 return CallJsBuiltin(isolate, "$arrayUnshift", args);
455 }
453 int len = Smi::cast(array->length())->value(); 456 int len = Smi::cast(array->length())->value();
454 int to_add = args.length() - 1; 457 int to_add = args.length() - 1;
458 int new_length = len + to_add;
459 // Currently fixed arrays cannot grow too big, so
460 // we should never hit this case.
461 DCHECK(to_add <= (Smi::kMaxValue - len));
455 462
456 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { 463 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
457 return CallJsBuiltin(isolate, "$arrayUnshift", args); 464 return CallJsBuiltin(isolate, "$arrayUnshift", args);
458 } 465 }
459 466
460 ElementsAccessor* accessor = array->GetElementsAccessor(); 467 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
461 int new_length = accessor->Unshift(array, elms_obj, args, to_add); 468
469 if (new_length > elms->length()) {
470 // New backing storage is needed.
471 int capacity = new_length + (new_length >> 1) + 16;
472 Handle<FixedArray> new_elms =
473 isolate->factory()->NewUninitializedFixedArray(capacity);
474
475 ElementsKind kind = array->GetElementsKind();
476 ElementsAccessor* accessor = array->GetElementsAccessor();
477 accessor->CopyElements(
478 elms, 0, kind, new_elms, to_add,
479 ElementsAccessor::kCopyToEndAndInitializeToHole);
480
481 elms = new_elms;
482 array->set_elements(*elms);
483 } else {
484 DisallowHeapAllocation no_gc;
485 Heap* heap = isolate->heap();
486 heap->MoveElements(*elms, to_add, 0, len);
487 }
488
489 // Add the provided values.
490 DisallowHeapAllocation no_gc;
491 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
492 for (int i = 0; i < to_add; i++) {
493 elms->set(i, args[i + 1], mode);
494 }
495
496 // Set the length.
497 array->set_length(Smi::FromInt(new_length));
462 return Smi::FromInt(new_length); 498 return Smi::FromInt(new_length);
463 } 499 }
464 500
465 501
466 BUILTIN(ArraySlice) { 502 BUILTIN(ArraySlice) {
467 HandleScope scope(isolate); 503 HandleScope scope(isolate);
468 Handle<Object> receiver = args.receiver(); 504 Handle<Object> receiver = args.receiver();
469 int len = -1; 505 int len = -1;
470 int relative_start = 0; 506 int relative_start = 0;
471 int relative_end = 0; 507 int relative_end = 0;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 if (!maybe_elms_obj.ToHandle(&elms_obj)) { 649 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
614 return CallJsBuiltin(isolate, "$arraySplice", args); 650 return CallJsBuiltin(isolate, "$arraySplice", args);
615 } 651 }
616 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 652 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
617 DCHECK(!array->map()->is_observed()); 653 DCHECK(!array->map()->is_observed());
618 654
619 int argument_count = args.length() - 1; 655 int argument_count = args.length() - 1;
620 int relative_start = 0; 656 int relative_start = 0;
621 if (argument_count > 0) { 657 if (argument_count > 0) {
622 DisallowHeapAllocation no_gc; 658 DisallowHeapAllocation no_gc;
623 if (!ObjectToClampedInteger(args[1], &relative_start)) { 659 if (!ClampedToInteger(args[1], &relative_start)) {
624 AllowHeapAllocation allow_allocation; 660 AllowHeapAllocation allow_allocation;
625 return CallJsBuiltin(isolate, "$arraySplice", args); 661 return CallJsBuiltin(isolate, "$arraySplice", args);
626 } 662 }
627 } 663 }
628 int len = Smi::cast(array->length())->value(); 664 int len = Smi::cast(array->length())->value();
629 // clip relative start to [0, len] 665 // clip relative start to [0, len]
630 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) 666 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
631 : Min(relative_start, len); 667 : Min(relative_start, len);
632 668
633 int actual_delete_count; 669 int actual_delete_count;
634 if (argument_count == 1) { 670 if (argument_count == 1) {
635 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is 671 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
636 // given as a request to delete all the elements from the start. 672 // given as a request to delete all the elements from the start.
637 // And it differs from the case of undefined delete count. 673 // And it differs from the case of undefined delete count.
638 // This does not follow ECMA-262, but we do the same for compatibility. 674 // This does not follow ECMA-262, but we do the same for compatibility.
639 DCHECK(len - actual_start >= 0); 675 DCHECK(len - actual_start >= 0);
640 actual_delete_count = len - actual_start; 676 actual_delete_count = len - actual_start;
641 } else { 677 } else {
642 int delete_count = 0; 678 int delete_count = 0;
643 DisallowHeapAllocation no_gc; 679 DisallowHeapAllocation no_gc;
644 if (argument_count > 1) { 680 if (argument_count > 1) {
645 if (!ObjectToClampedInteger(args[2], &delete_count)) { 681 if (!ClampedToInteger(args[2], &delete_count)) {
646 AllowHeapAllocation allow_allocation; 682 AllowHeapAllocation allow_allocation;
647 return CallJsBuiltin(isolate, "$arraySplice", args); 683 return CallJsBuiltin(isolate, "$arraySplice", args);
648 } 684 }
649 } 685 }
650 actual_delete_count = Min(Max(delete_count, 0), len - actual_start); 686 actual_delete_count = Min(Max(delete_count, 0), len - actual_start);
651 } 687 }
652 688
653 int add_count = (argument_count > 1) ? (argument_count - 2) : 0; 689 int add_count = (argument_count > 1) ? (argument_count - 2) : 0;
654 int new_length = len - actual_delete_count + add_count; 690 int new_length = len - actual_delete_count + add_count;
655 691
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1396 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1361 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1397 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1362 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1398 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1363 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1399 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1364 #undef DEFINE_BUILTIN_ACCESSOR_C 1400 #undef DEFINE_BUILTIN_ACCESSOR_C
1365 #undef DEFINE_BUILTIN_ACCESSOR_A 1401 #undef DEFINE_BUILTIN_ACCESSOR_A
1366 1402
1367 1403
1368 } // namespace internal 1404 } // namespace internal
1369 } // namespace v8 1405 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/elements.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698