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

Side by Side Diff: src/builtins.cc

Issue 208033002: Builtin helper function EnsureJSArrayWithWritableFastElements() handlified. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // Object.prototype 293 // Object.prototype
294 Object* proto = array_proto->GetPrototype(); 294 Object* proto = array_proto->GetPrototype();
295 if (proto == heap->null_value()) return false; 295 if (proto == heap->null_value()) return false;
296 array_proto = JSObject::cast(proto); 296 array_proto = JSObject::cast(proto);
297 if (array_proto != native_context->initial_object_prototype()) return false; 297 if (array_proto != native_context->initial_object_prototype()) return false;
298 if (array_proto->elements() != heap->empty_fixed_array()) return false; 298 if (array_proto->elements() != heap->empty_fixed_array()) return false;
299 return array_proto->GetPrototype()->IsNull(); 299 return array_proto->GetPrototype()->IsNull();
300 } 300 }
301 301
302 302
303 // Returns empty handle if not applicable.
303 MUST_USE_RESULT 304 MUST_USE_RESULT
304 static inline MaybeObject* EnsureJSArrayWithWritableFastElements( 305 static inline Handle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
305 Heap* heap, Object* receiver, Arguments* args, int first_added_arg) { 306 Isolate* isolate,
306 if (!receiver->IsJSArray()) return NULL; 307 Handle<Object> receiver,
307 JSArray* array = JSArray::cast(receiver); 308 Arguments* args,
308 if (array->map()->is_observed()) return NULL; 309 int first_added_arg) {
309 if (!array->map()->is_extensible()) return NULL; 310 if (!receiver->IsJSArray()) return Handle<FixedArrayBase>::null();
310 HeapObject* elms = array->elements(); 311 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
312 if (array->map()->is_observed()) return Handle<FixedArrayBase>::null();
313 if (!array->map()->is_extensible()) return Handle<FixedArrayBase>::null();
314 Handle<FixedArrayBase> elms(array->elements());
315 Heap* heap = isolate->heap();
311 Map* map = elms->map(); 316 Map* map = elms->map();
312 if (map == heap->fixed_array_map()) { 317 if (map == heap->fixed_array_map()) {
313 if (args == NULL || array->HasFastObjectElements()) return elms; 318 if (args == NULL || array->HasFastObjectElements()) return elms;
314 } else if (map == heap->fixed_cow_array_map()) { 319 } else if (map == heap->fixed_cow_array_map()) {
315 MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); 320 elms = JSObject::EnsureWritableFastElements(array);
316 if (args == NULL || array->HasFastObjectElements() || 321 if (args == NULL || array->HasFastObjectElements()) return elms;
317 !maybe_writable_result->To(&elms)) {
318 return maybe_writable_result;
319 }
320 } else if (map == heap->fixed_double_array_map()) { 322 } else if (map == heap->fixed_double_array_map()) {
321 if (args == NULL) return elms; 323 if (args == NULL) return elms;
322 } else { 324 } else {
323 return NULL; 325 return Handle<FixedArrayBase>::null();
324 } 326 }
325 327
326 // Need to ensure that the arguments passed in args can be contained in 328 // Need to ensure that the arguments passed in args can be contained in
327 // the array. 329 // the array.
328 int args_length = args->length(); 330 int args_length = args->length();
329 if (first_added_arg >= args_length) return array->elements(); 331 if (first_added_arg >= args_length) return handle(array->elements());
330 332
331 ElementsKind origin_kind = array->map()->elements_kind(); 333 ElementsKind origin_kind = array->map()->elements_kind();
332 ASSERT(!IsFastObjectElementsKind(origin_kind)); 334 ASSERT(!IsFastObjectElementsKind(origin_kind));
333 ElementsKind target_kind = origin_kind; 335 ElementsKind target_kind = origin_kind;
334 int arg_count = args->length() - first_added_arg; 336 int arg_count = args->length() - first_added_arg;
335 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); 337 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
336 for (int i = 0; i < arg_count; i++) { 338 for (int i = 0; i < arg_count; i++) {
337 Object* arg = arguments[i]; 339 Object* arg = arguments[i];
338 if (arg->IsHeapObject()) { 340 if (arg->IsHeapObject()) {
339 if (arg->IsHeapNumber()) { 341 if (arg->IsHeapNumber()) {
340 target_kind = FAST_DOUBLE_ELEMENTS; 342 target_kind = FAST_DOUBLE_ELEMENTS;
341 } else { 343 } else {
342 target_kind = FAST_ELEMENTS; 344 target_kind = FAST_ELEMENTS;
343 break; 345 break;
344 } 346 }
345 } 347 }
346 } 348 }
347 if (target_kind != origin_kind) { 349 if (target_kind != origin_kind) {
348 MaybeObject* maybe_failure = array->TransitionElementsKind(target_kind); 350 JSObject::TransitionElementsKind(array, target_kind);
349 if (maybe_failure->IsFailure()) return maybe_failure; 351 return handle(array->elements());
350 return array->elements();
351 } 352 }
352 return elms; 353 return elms;
353 } 354 }
354 355
355 356
356 // TODO(ishell): Temporary wrapper until handlified.
357 MUST_USE_RESULT
358 static inline Handle<Object> EnsureJSArrayWithWritableFastElementsWrapper(
359 Isolate* isolate,
360 Handle<Object> receiver,
361 Arguments* args,
362 int first_added_arg) {
363 CALL_HEAP_FUNCTION(isolate,
364 EnsureJSArrayWithWritableFastElements(
365 isolate->heap(), *receiver, args, first_added_arg),
366 Object);
367 }
368
369
370 // TODO(ishell): Handlify when all Array* builtins are handlified. 357 // TODO(ishell): Handlify when all Array* builtins are handlified.
371 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, 358 static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
372 JSArray* receiver) { 359 JSArray* receiver) {
373 if (!FLAG_clever_optimizations) return false; 360 if (!FLAG_clever_optimizations) return false;
374 Context* native_context = heap->isolate()->context()->native_context(); 361 Context* native_context = heap->isolate()->context()->native_context();
375 JSObject* array_proto = 362 JSObject* array_proto =
376 JSObject::cast(native_context->array_function()->prototype()); 363 JSObject::cast(native_context->array_function()->prototype());
377 return receiver->GetPrototype() == array_proto && 364 return receiver->GetPrototype() == array_proto &&
378 ArrayPrototypeHasNoElements(heap, native_context, array_proto); 365 ArrayPrototypeHasNoElements(heap, native_context, array_proto);
379 } 366 }
(...skipping 22 matching lines...) Expand all
402 argv.start(), 389 argv.start(),
403 &pending_exception); 390 &pending_exception);
404 if (pending_exception) return Failure::Exception(); 391 if (pending_exception) return Failure::Exception();
405 return *result; 392 return *result;
406 } 393 }
407 394
408 395
409 BUILTIN(ArrayPush) { 396 BUILTIN(ArrayPush) {
410 HandleScope scope(isolate); 397 HandleScope scope(isolate);
411 Handle<Object> receiver = args.receiver(); 398 Handle<Object> receiver = args.receiver();
412 Handle<Object> elms_or_null = 399 Handle<FixedArrayBase> elms_obj =
413 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 1); 400 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
414 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); 401 if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPush", args);
415 if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPush", args);
416 402
417 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
418 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 403 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
419 ASSERT(!array->map()->is_observed()); 404 ASSERT(!array->map()->is_observed());
420 405
421 ElementsKind kind = array->GetElementsKind(); 406 ElementsKind kind = array->GetElementsKind();
422 407
423 if (IsFastSmiOrObjectElementsKind(kind)) { 408 if (IsFastSmiOrObjectElementsKind(kind)) {
424 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 409 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
425 410
426 int len = Smi::cast(array->length())->value(); 411 int len = Smi::cast(array->length())->value();
427 int to_add = args.length() - 1; 412 int to_add = args.length() - 1;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 accessor->Get(*receiver, *holder, key, 522 accessor->Get(*receiver, *holder, key,
538 backing_store.is_null() 523 backing_store.is_null()
539 ? *backing_store : NULL), 524 ? *backing_store : NULL),
540 Object); 525 Object);
541 } 526 }
542 527
543 528
544 BUILTIN(ArrayPop) { 529 BUILTIN(ArrayPop) {
545 HandleScope scope(isolate); 530 HandleScope scope(isolate);
546 Handle<Object> receiver = args.receiver(); 531 Handle<Object> receiver = args.receiver();
547 Handle<Object> elms_or_null = 532 Handle<FixedArrayBase> elms_obj =
548 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); 533 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
549 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); 534 if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPop", args);
550 if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
551 535
552 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
553 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 536 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
554 ASSERT(!array->map()->is_observed()); 537 ASSERT(!array->map()->is_observed());
555 538
556 int len = Smi::cast(array->length())->value(); 539 int len = Smi::cast(array->length())->value();
557 if (len == 0) return isolate->heap()->undefined_value(); 540 if (len == 0) return isolate->heap()->undefined_value();
558 541
559 ElementsAccessor* accessor = array->GetElementsAccessor(); 542 ElementsAccessor* accessor = array->GetElementsAccessor();
560 int new_length = len - 1; 543 int new_length = len - 1;
561 Handle<Object> element; 544 Handle<Object> element;
562 if (ElementsAccessorHasElementWrapper( 545 if (ElementsAccessorHasElementWrapper(
563 accessor, array, array, new_length, elms_obj)) { 546 accessor, array, array, new_length, elms_obj)) {
564 element = ElementsAccessorGetWrapper( 547 element = ElementsAccessorGetWrapper(
565 isolate, accessor, array, array, new_length, elms_obj); 548 isolate, accessor, array, array, new_length, elms_obj);
566 } else { 549 } else {
567 Handle<Object> proto(array->GetPrototype(), isolate); 550 Handle<Object> proto(array->GetPrototype(), isolate);
568 element = Object::GetElement(isolate, proto, len - 1); 551 element = Object::GetElement(isolate, proto, len - 1);
569 } 552 }
570 RETURN_IF_EMPTY_HANDLE(isolate, element); 553 RETURN_IF_EMPTY_HANDLE(isolate, element);
571 RETURN_IF_EMPTY_HANDLE(isolate, 554 RETURN_IF_EMPTY_HANDLE(isolate,
572 accessor->SetLength( 555 accessor->SetLength(
573 array, handle(Smi::FromInt(new_length), isolate))); 556 array, handle(Smi::FromInt(new_length), isolate)));
574 return *element; 557 return *element;
575 } 558 }
576 559
577 560
578 BUILTIN(ArrayShift) { 561 BUILTIN(ArrayShift) {
579 HandleScope scope(isolate); 562 HandleScope scope(isolate);
580 Heap* heap = isolate->heap(); 563 Heap* heap = isolate->heap();
581 Handle<Object> receiver = args.receiver(); 564 Handle<Object> receiver = args.receiver();
582 Handle<Object> elms_or_null = 565 Handle<FixedArrayBase> elms_obj =
583 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); 566 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
584 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); 567 if (elms_obj.is_null() ||
585 if ((*elms_or_null == NULL) ||
586 !IsJSArrayFastElementMovingAllowed(heap, 568 !IsJSArrayFastElementMovingAllowed(heap,
587 *Handle<JSArray>::cast(receiver))) { 569 *Handle<JSArray>::cast(receiver))) {
588 return CallJsBuiltin(isolate, "ArrayShift", args); 570 return CallJsBuiltin(isolate, "ArrayShift", args);
589 } 571 }
590 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
591 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 572 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
592 ASSERT(!array->map()->is_observed()); 573 ASSERT(!array->map()->is_observed());
593 574
594 int len = Smi::cast(array->length())->value(); 575 int len = Smi::cast(array->length())->value();
595 if (len == 0) return heap->undefined_value(); 576 if (len == 0) return heap->undefined_value();
596 577
597 // Get first element 578 // Get first element
598 ElementsAccessor* accessor = array->GetElementsAccessor(); 579 ElementsAccessor* accessor = array->GetElementsAccessor();
599 Handle<Object> first = accessor->Get(receiver, array, 0, elms_obj); 580 Handle<Object> first = accessor->Get(receiver, array, 0, elms_obj);
600 if (first->IsTheHole()) { 581 if (first->IsTheHole()) {
(...skipping 20 matching lines...) Expand all
621 array->set_length(Smi::FromInt(len - 1)); 602 array->set_length(Smi::FromInt(len - 1));
622 603
623 return *first; 604 return *first;
624 } 605 }
625 606
626 607
627 BUILTIN(ArrayUnshift) { 608 BUILTIN(ArrayUnshift) {
628 HandleScope scope(isolate); 609 HandleScope scope(isolate);
629 Heap* heap = isolate->heap(); 610 Heap* heap = isolate->heap();
630 Handle<Object> receiver = args.receiver(); 611 Handle<Object> receiver = args.receiver();
631 Handle<Object> elms_or_null = 612 Handle<FixedArrayBase> elms_obj =
632 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); 613 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
633 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); 614 if (elms_obj.is_null() ||
634 if ((*elms_or_null == NULL) ||
635 !IsJSArrayFastElementMovingAllowed(heap, 615 !IsJSArrayFastElementMovingAllowed(heap,
636 *Handle<JSArray>::cast(receiver))) { 616 *Handle<JSArray>::cast(receiver))) {
637 return CallJsBuiltin(isolate, "ArrayUnshift", args); 617 return CallJsBuiltin(isolate, "ArrayUnshift", args);
638 } 618 }
639 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
640 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 619 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
641 ASSERT(!array->map()->is_observed()); 620 ASSERT(!array->map()->is_observed());
642 if (!array->HasFastSmiOrObjectElements()) { 621 if (!array->HasFastSmiOrObjectElements()) {
643 return CallJsBuiltin(isolate, "ArrayUnshift", args); 622 return CallJsBuiltin(isolate, "ArrayUnshift", args);
644 } 623 }
645 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 624 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
646 625
647 int len = Smi::cast(array->length())->value(); 626 int len = Smi::cast(array->length())->value();
648 int to_add = args.length() - 1; 627 int to_add = args.length() - 1;
649 int new_length = len + to_add; 628 int new_length = len + to_add;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 USE(maybe_failure); 795 USE(maybe_failure);
817 796
818 return result_array; 797 return result_array;
819 } 798 }
820 799
821 800
822 BUILTIN(ArraySplice) { 801 BUILTIN(ArraySplice) {
823 HandleScope scope(isolate); 802 HandleScope scope(isolate);
824 Heap* heap = isolate->heap(); 803 Heap* heap = isolate->heap();
825 Handle<Object> receiver = args.receiver(); 804 Handle<Object> receiver = args.receiver();
826 Handle<Object> elms_or_null = 805 Handle<FixedArrayBase> elms_obj =
827 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 3); 806 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
828 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); 807 if (elms_obj.is_null() ||
829
830 if ((*elms_or_null == NULL) ||
831 !IsJSArrayFastElementMovingAllowed(heap, 808 !IsJSArrayFastElementMovingAllowed(heap,
832 *Handle<JSArray>::cast(receiver))) { 809 *Handle<JSArray>::cast(receiver))) {
833 return CallJsBuiltin(isolate, "ArraySplice", args); 810 return CallJsBuiltin(isolate, "ArraySplice", args);
834 } 811 }
835 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
836 Handle<JSArray> array = Handle<JSArray>::cast(receiver); 812 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
837 ASSERT(!array->map()->is_observed()); 813 ASSERT(!array->map()->is_observed());
838 814
839 int len = Smi::cast(array->length())->value(); 815 int len = Smi::cast(array->length())->value();
840 816
841 int n_arguments = args.length() - 1; 817 int n_arguments = args.length() - 1;
842 818
843 int relative_start = 0; 819 int relative_start = 0;
844 if (n_arguments > 0) { 820 if (n_arguments > 0) {
845 Handle<Object> arg1 = args.at<Object>(1); 821 Handle<Object> arg1 = args.at<Object>(1);
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 } 1734 }
1759 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1735 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1760 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1736 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1761 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1737 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1762 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1738 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1763 #undef DEFINE_BUILTIN_ACCESSOR_C 1739 #undef DEFINE_BUILTIN_ACCESSOR_C
1764 #undef DEFINE_BUILTIN_ACCESSOR_A 1740 #undef DEFINE_BUILTIN_ACCESSOR_A
1765 1741
1766 1742
1767 } } // namespace v8::internal 1743 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698