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

Side by Side Diff: src/builtins.cc

Issue 1317053006: Adding ElementsAccessor::Shift (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-09-01_array_builtin_cleanup
Patch Set: Only use range checks in builtins Created 5 years, 3 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 *out = 0; 188 *out = 0;
189 return true; 189 return true;
190 } else if (object->IsBoolean()) { 190 } else if (object->IsBoolean()) {
191 *out = object->IsTrue(); 191 *out = object->IsTrue();
192 return true; 192 return true;
193 } 193 }
194 return false; 194 return false;
195 } 195 }
196 196
197 197
198 void MoveDoubleElements(FixedDoubleArray* dst, int dst_index,
199 FixedDoubleArray* src, int src_index, int len) {
200 if (len == 0) return;
201 MemMove(dst->data_start() + dst_index, src->data_start() + src_index,
202 len * kDoubleSize);
203 }
204
205
206 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object, 198 inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object,
207 int* out) { 199 int* out) {
208 Map* arguments_map = 200 Map* arguments_map =
209 isolate->context()->native_context()->sloppy_arguments_map(); 201 isolate->context()->native_context()->sloppy_arguments_map();
210 if (object->map() != arguments_map || !object->HasFastElements()) { 202 if (object->map() != arguments_map || !object->HasFastElements()) {
211 return false; 203 return false;
212 } 204 }
213 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); 205 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
214 if (!len_obj->IsSmi()) { 206 if (!len_obj->IsSmi()) {
215 return false; 207 return false;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 417 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
426 DCHECK(!array->map()->is_observed()); 418 DCHECK(!array->map()->is_observed());
427 419
428 int len = Smi::cast(array->length())->value(); 420 int len = Smi::cast(array->length())->value();
429 if (len == 0) return heap->undefined_value(); 421 if (len == 0) return heap->undefined_value();
430 422
431 if (JSArray::HasReadOnlyLength(array)) { 423 if (JSArray::HasReadOnlyLength(array)) {
432 return CallJsIntrinsic(isolate, isolate->array_shift(), args); 424 return CallJsIntrinsic(isolate, isolate->array_shift(), args);
433 } 425 }
434 426
435 // Get first element 427 Handle<Object> first = array->GetElementsAccessor()->Shift(array, elms_obj);
436 Handle<Object> first;
437 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, first,
438 Object::GetElement(isolate, array, 0));
439
440 if (heap->CanMoveObjectStart(*elms_obj)) {
441 array->set_elements(heap->LeftTrimFixedArray(*elms_obj, 1));
442 } else {
443 // Shift the elements.
444 if (elms_obj->IsFixedArray()) {
445 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
446 DisallowHeapAllocation no_gc;
447 heap->MoveElements(*elms, 0, 1, len - 1);
448 elms->set(len - 1, heap->the_hole_value());
449 } else {
450 Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
451 MoveDoubleElements(*elms, 0, *elms, 1, len - 1);
452 elms->set_the_hole(len - 1);
453 }
454 }
455
456 // Set the length.
457 array->set_length(Smi::FromInt(len - 1));
458
459 return *first; 428 return *first;
460 } 429 }
461 430
462 431
463 BUILTIN(ArrayUnshift) { 432 BUILTIN(ArrayUnshift) {
464 HandleScope scope(isolate); 433 HandleScope scope(isolate);
465 Handle<Object> receiver = args.receiver(); 434 Handle<Object> receiver = args.receiver();
466 MaybeHandle<FixedArrayBase> maybe_elms_obj = 435 MaybeHandle<FixedArrayBase> maybe_elms_obj =
467 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); 436 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
468 Handle<FixedArrayBase> elms_obj; 437 Handle<FixedArrayBase> elms_obj;
469 if (!maybe_elms_obj.ToHandle(&elms_obj)) { 438 if (!maybe_elms_obj.ToHandle(&elms_obj)) {
470 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); 439 return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
471 } 440 }
472 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 441 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
473 DCHECK(!array->map()->is_observed()); 442 DCHECK(!array->map()->is_observed());
474 int to_add = args.length() - 1; 443 int to_add = args.length() - 1;
444 if (to_add == 0) {
445 return array->length();
446 }
475 // Currently fixed arrays cannot grow too big, so 447 // Currently fixed arrays cannot grow too big, so
476 // we should never hit this case. 448 // we should never hit this case.
477 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value())); 449 DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value()));
478 450
479 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) { 451 if (to_add > 0 && JSArray::HasReadOnlyLength(array)) {
480 return CallJsIntrinsic(isolate, isolate->array_unshift(), args); 452 return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
481 } 453 }
482 454
483 ElementsAccessor* accessor = array->GetElementsAccessor(); 455 ElementsAccessor* accessor = array->GetElementsAccessor();
484 int new_length = accessor->Unshift(array, elms_obj, &args, to_add); 456 int new_length = accessor->Unshift(array, elms_obj, &args, to_add);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 } 518 }
547 519
548 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. 520 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
549 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0) 521 uint32_t actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
550 : Min(relative_start, len); 522 : Min(relative_start, len);
551 523
552 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. 524 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
553 uint32_t actual_end = 525 uint32_t actual_end =
554 (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len); 526 (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
555 527
528 if (actual_end <= actual_start) {
529 Handle<JSArray> result_array =
530 isolate->factory()->NewJSArray(GetInitialFastElementsKind(), 0, 0);
531 return *result_array;
532 }
533
556 ElementsAccessor* accessor = object->GetElementsAccessor(); 534 ElementsAccessor* accessor = object->GetElementsAccessor();
557 if (is_sloppy_arguments && 535 if (is_sloppy_arguments &&
558 !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) { 536 !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) {
559 // Don't deal with arguments with holes in C++ 537 // Don't deal with arguments with holes in C++
560 AllowHeapAllocation allow_allocation; 538 AllowHeapAllocation allow_allocation;
561 return CallJsIntrinsic(isolate, isolate->array_slice(), args); 539 return CallJsIntrinsic(isolate, isolate->array_slice(), args);
562 } 540 }
563 Handle<JSArray> result_array = 541 Handle<JSArray> result_array =
564 accessor->Slice(object, elms_obj, actual_start, actual_end); 542 accessor->Slice(object, elms_obj, actual_start, actual_end);
565 return *result_array; 543 return *result_array;
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1313 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1336 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1314 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1337 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1315 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1338 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1316 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1339 #undef DEFINE_BUILTIN_ACCESSOR_C 1317 #undef DEFINE_BUILTIN_ACCESSOR_C
1340 #undef DEFINE_BUILTIN_ACCESSOR_A 1318 #undef DEFINE_BUILTIN_ACCESSOR_A
1341 1319
1342 1320
1343 } // namespace internal 1321 } // namespace internal
1344 } // namespace v8 1322 } // 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