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

Side by Side Diff: src/builtins.cc

Issue 206073007: ArraySplice builtin handlified. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing review notes 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 | src/elements.cc » ('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 // 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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 MaybeObject* maybe_failure = accessor->CopyElements( 818 MaybeObject* maybe_failure = accessor->CopyElements(
819 NULL, k, kind, result_array->elements(), 0, result_len, elms); 819 NULL, k, kind, result_array->elements(), 0, result_len, elms);
820 ASSERT(!maybe_failure->IsFailure()); 820 ASSERT(!maybe_failure->IsFailure());
821 USE(maybe_failure); 821 USE(maybe_failure);
822 822
823 return result_array; 823 return result_array;
824 } 824 }
825 825
826 826
827 BUILTIN(ArraySplice) { 827 BUILTIN(ArraySplice) {
828 HandleScope scope(isolate);
828 Heap* heap = isolate->heap(); 829 Heap* heap = isolate->heap();
829 Object* receiver = *args.receiver(); 830 Handle<Object> receiver = args.receiver();
830 FixedArrayBase* elms_obj; 831 Handle<Object> elms_or_null =
831 MaybeObject* maybe_elms = 832 EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 3);
832 EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3); 833 RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null);
833 if (maybe_elms == NULL) { 834
835 if ((*elms_or_null == NULL) ||
836 !IsJSArrayFastElementMovingAllowed(heap,
837 *Handle<JSArray>::cast(receiver))) {
834 return CallJsBuiltin(isolate, "ArraySplice", args); 838 return CallJsBuiltin(isolate, "ArraySplice", args);
835 } 839 }
836 if (!maybe_elms->To(&elms_obj)) return maybe_elms; 840 Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
837 841 Handle<JSArray> array = Handle<JSArray>::cast(receiver);
838 if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
839 return CallJsBuiltin(isolate, "ArraySplice", args);
840 }
841 JSArray* array = JSArray::cast(receiver);
842 ASSERT(!array->map()->is_observed()); 842 ASSERT(!array->map()->is_observed());
843 843
844 int len = Smi::cast(array->length())->value(); 844 int len = Smi::cast(array->length())->value();
845 845
846 int n_arguments = args.length() - 1; 846 int n_arguments = args.length() - 1;
847 847
848 int relative_start = 0; 848 int relative_start = 0;
849 if (n_arguments > 0) { 849 if (n_arguments > 0) {
850 Object* arg1 = args[1]; 850 Handle<Object> arg1 = args.at<Object>(1);
851 if (arg1->IsSmi()) { 851 if (arg1->IsSmi()) {
852 relative_start = Smi::cast(arg1)->value(); 852 relative_start = Handle<Smi>::cast(arg1)->value();
853 } else if (arg1->IsHeapNumber()) { 853 } else if (arg1->IsHeapNumber()) {
854 double start = HeapNumber::cast(arg1)->value(); 854 double start = Handle<HeapNumber>::cast(arg1)->value();
855 if (start < kMinInt || start > kMaxInt) { 855 if (start < kMinInt || start > kMaxInt) {
856 return CallJsBuiltin(isolate, "ArraySplice", args); 856 return CallJsBuiltin(isolate, "ArraySplice", args);
857 } 857 }
858 relative_start = std::isnan(start) ? 0 : static_cast<int>(start); 858 relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
859 } else if (!arg1->IsUndefined()) { 859 } else if (!arg1->IsUndefined()) {
860 return CallJsBuiltin(isolate, "ArraySplice", args); 860 return CallJsBuiltin(isolate, "ArraySplice", args);
861 } 861 }
862 } 862 }
863 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) 863 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
864 : Min(relative_start, len); 864 : Min(relative_start, len);
(...skipping 24 matching lines...) Expand all
889 889
890 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; 890 int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
891 int new_length = len - actual_delete_count + item_count; 891 int new_length = len - actual_delete_count + item_count;
892 892
893 // For double mode we do not support changing the length. 893 // For double mode we do not support changing the length.
894 if (new_length > len && IsFastDoubleElementsKind(elements_kind)) { 894 if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
895 return CallJsBuiltin(isolate, "ArraySplice", args); 895 return CallJsBuiltin(isolate, "ArraySplice", args);
896 } 896 }
897 897
898 if (new_length == 0) { 898 if (new_length == 0) {
899 MaybeObject* maybe_array = heap->AllocateJSArrayWithElements( 899 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
900 elms_obj, elements_kind, actual_delete_count); 900 elms_obj, elements_kind, actual_delete_count);
901 if (maybe_array->IsFailure()) return maybe_array;
902 array->set_elements(heap->empty_fixed_array()); 901 array->set_elements(heap->empty_fixed_array());
903 array->set_length(Smi::FromInt(0)); 902 array->set_length(Smi::FromInt(0));
904 return maybe_array; 903 return *result;
905 } 904 }
906 905
907 JSArray* result_array = NULL; 906 Handle<JSArray> result_array =
908 MaybeObject* maybe_array = 907 isolate->factory()->NewJSArray(elements_kind,
909 heap->AllocateJSArrayAndStorage(elements_kind, 908 actual_delete_count,
910 actual_delete_count, 909 actual_delete_count);
911 actual_delete_count);
912 if (!maybe_array->To(&result_array)) return maybe_array;
913 910
914 if (actual_delete_count > 0) { 911 if (actual_delete_count > 0) {
915 DisallowHeapAllocation no_gc; 912 DisallowHeapAllocation no_gc;
916 ElementsAccessor* accessor = array->GetElementsAccessor(); 913 ElementsAccessor* accessor = array->GetElementsAccessor();
917 MaybeObject* maybe_failure = accessor->CopyElements( 914 accessor->CopyElements(
918 NULL, actual_start, elements_kind, result_array->elements(), 915 Handle<JSObject>::null(), actual_start, elements_kind,
919 0, actual_delete_count, elms_obj); 916 handle(result_array->elements()), 0, actual_delete_count, elms_obj);
920 // Cannot fail since the origin and target array are of the same elements
921 // kind.
922 ASSERT(!maybe_failure->IsFailure());
923 USE(maybe_failure);
924 } 917 }
925 918
926 bool elms_changed = false; 919 bool elms_changed = false;
927 if (item_count < actual_delete_count) { 920 if (item_count < actual_delete_count) {
928 // Shrink the array. 921 // Shrink the array.
929 const bool trim_array = !heap->lo_space()->Contains(elms_obj) && 922 const bool trim_array = !heap->lo_space()->Contains(*elms_obj) &&
930 ((actual_start + item_count) < 923 ((actual_start + item_count) <
931 (len - actual_delete_count - actual_start)); 924 (len - actual_delete_count - actual_start));
932 if (trim_array) { 925 if (trim_array) {
933 const int delta = actual_delete_count - item_count; 926 const int delta = actual_delete_count - item_count;
934 927
935 if (elms_obj->IsFixedDoubleArray()) { 928 if (elms_obj->IsFixedDoubleArray()) {
936 FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj); 929 Handle<FixedDoubleArray> elms =
937 MoveDoubleElements(elms, delta, elms, 0, actual_start); 930 Handle<FixedDoubleArray>::cast(elms_obj);
931 MoveDoubleElements(*elms, delta, *elms, 0, actual_start);
938 } else { 932 } else {
939 FixedArray* elms = FixedArray::cast(elms_obj); 933 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
940 DisallowHeapAllocation no_gc; 934 DisallowHeapAllocation no_gc;
941 heap->MoveElements(elms, delta, 0, actual_start); 935 heap->MoveElements(*elms, delta, 0, actual_start);
942 } 936 }
943 937
944 elms_obj = LeftTrimFixedArray(heap, elms_obj, delta); 938 elms_obj = handle(LeftTrimFixedArray(heap, *elms_obj, delta));
945 939
946 elms_changed = true; 940 elms_changed = true;
947 } else { 941 } else {
948 if (elms_obj->IsFixedDoubleArray()) { 942 if (elms_obj->IsFixedDoubleArray()) {
949 FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj); 943 Handle<FixedDoubleArray> elms =
950 MoveDoubleElements(elms, actual_start + item_count, 944 Handle<FixedDoubleArray>::cast(elms_obj);
951 elms, actual_start + actual_delete_count, 945 MoveDoubleElements(*elms, actual_start + item_count,
946 *elms, actual_start + actual_delete_count,
952 (len - actual_delete_count - actual_start)); 947 (len - actual_delete_count - actual_start));
953 FillWithHoles(elms, new_length, len); 948 FillWithHoles(*elms, new_length, len);
954 } else { 949 } else {
955 FixedArray* elms = FixedArray::cast(elms_obj); 950 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
956 DisallowHeapAllocation no_gc; 951 DisallowHeapAllocation no_gc;
957 heap->MoveElements(elms, actual_start + item_count, 952 heap->MoveElements(*elms, actual_start + item_count,
958 actual_start + actual_delete_count, 953 actual_start + actual_delete_count,
959 (len - actual_delete_count - actual_start)); 954 (len - actual_delete_count - actual_start));
960 FillWithHoles(heap, elms, new_length, len); 955 FillWithHoles(heap, *elms, new_length, len);
961 } 956 }
962 } 957 }
963 } else if (item_count > actual_delete_count) { 958 } else if (item_count > actual_delete_count) {
964 FixedArray* elms = FixedArray::cast(elms_obj); 959 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
965 // Currently fixed arrays cannot grow too big, so 960 // Currently fixed arrays cannot grow too big, so
966 // we should never hit this case. 961 // we should never hit this case.
967 ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); 962 ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
968 963
969 // Check if array need to grow. 964 // Check if array need to grow.
970 if (new_length > elms->length()) { 965 if (new_length > elms->length()) {
971 // New backing storage is needed. 966 // New backing storage is needed.
972 int capacity = new_length + (new_length >> 1) + 16; 967 int capacity = new_length + (new_length >> 1) + 16;
973 FixedArray* new_elms; 968 Handle<FixedArray> new_elms =
974 MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity); 969 isolate->factory()->NewUninitializedFixedArray(capacity);
975 if (!maybe_obj->To(&new_elms)) return maybe_obj;
976 970
977 DisallowHeapAllocation no_gc; 971 DisallowHeapAllocation no_gc;
978 972
979 ElementsKind kind = array->GetElementsKind(); 973 ElementsKind kind = array->GetElementsKind();
980 ElementsAccessor* accessor = array->GetElementsAccessor(); 974 ElementsAccessor* accessor = array->GetElementsAccessor();
981 if (actual_start > 0) { 975 if (actual_start > 0) {
982 // Copy the part before actual_start as is. 976 // Copy the part before actual_start as is.
983 MaybeObject* maybe_failure = accessor->CopyElements( 977 accessor->CopyElements(
984 NULL, 0, kind, new_elms, 0, actual_start, elms); 978 Handle<JSObject>::null(), 0, kind, new_elms, 0, actual_start, elms);
985 ASSERT(!maybe_failure->IsFailure());
986 USE(maybe_failure);
987 } 979 }
988 MaybeObject* maybe_failure = accessor->CopyElements( 980 accessor->CopyElements(
989 NULL, actual_start + actual_delete_count, kind, new_elms, 981 Handle<JSObject>::null(), actual_start + actual_delete_count, kind,
990 actual_start + item_count, 982 new_elms, actual_start + item_count,
991 ElementsAccessor::kCopyToEndAndInitializeToHole, elms); 983 ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
992 ASSERT(!maybe_failure->IsFailure());
993 USE(maybe_failure);
994 984
995 elms_obj = new_elms; 985 elms_obj = new_elms;
996 elms_changed = true; 986 elms_changed = true;
997 } else { 987 } else {
998 DisallowHeapAllocation no_gc; 988 DisallowHeapAllocation no_gc;
999 heap->MoveElements(elms, actual_start + item_count, 989 heap->MoveElements(*elms, actual_start + item_count,
1000 actual_start + actual_delete_count, 990 actual_start + actual_delete_count,
1001 (len - actual_delete_count - actual_start)); 991 (len - actual_delete_count - actual_start));
1002 } 992 }
1003 } 993 }
1004 994
1005 if (IsFastDoubleElementsKind(elements_kind)) { 995 if (IsFastDoubleElementsKind(elements_kind)) {
1006 FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj); 996 Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
1007 for (int k = actual_start; k < actual_start + item_count; k++) { 997 for (int k = actual_start; k < actual_start + item_count; k++) {
1008 Object* arg = args[3 + k - actual_start]; 998 Object* arg = args[3 + k - actual_start];
1009 if (arg->IsSmi()) { 999 if (arg->IsSmi()) {
1010 elms->set(k, Smi::cast(arg)->value()); 1000 elms->set(k, Smi::cast(arg)->value());
1011 } else { 1001 } else {
1012 elms->set(k, HeapNumber::cast(arg)->value()); 1002 elms->set(k, HeapNumber::cast(arg)->value());
1013 } 1003 }
1014 } 1004 }
1015 } else { 1005 } else {
1016 FixedArray* elms = FixedArray::cast(elms_obj); 1006 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
1017 DisallowHeapAllocation no_gc; 1007 DisallowHeapAllocation no_gc;
1018 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 1008 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
1019 for (int k = actual_start; k < actual_start + item_count; k++) { 1009 for (int k = actual_start; k < actual_start + item_count; k++) {
1020 elms->set(k, args[3 + k - actual_start], mode); 1010 elms->set(k, args[3 + k - actual_start], mode);
1021 } 1011 }
1022 } 1012 }
1023 1013
1024 if (elms_changed) { 1014 if (elms_changed) {
1025 array->set_elements(elms_obj); 1015 array->set_elements(*elms_obj);
1026 } 1016 }
1027 // Set the length. 1017 // Set the length.
1028 array->set_length(Smi::FromInt(new_length)); 1018 array->set_length(Smi::FromInt(new_length));
1029 1019
1030 return result_array; 1020 return *result_array;
1031 } 1021 }
1032 1022
1033 1023
1034 BUILTIN(ArrayConcat) { 1024 BUILTIN(ArrayConcat) {
1035 Heap* heap = isolate->heap(); 1025 Heap* heap = isolate->heap();
1036 Context* native_context = isolate->context()->native_context(); 1026 Context* native_context = isolate->context()->native_context();
1037 JSObject* array_proto = 1027 JSObject* array_proto =
1038 JSObject::cast(native_context->array_function()->prototype()); 1028 JSObject::cast(native_context->array_function()->prototype());
1039 if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) { 1029 if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
1040 return CallJsBuiltin(isolate, "ArrayConcat", args); 1030 return CallJsBuiltin(isolate, "ArrayConcat", args);
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1773 } 1763 }
1774 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 1764 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
1775 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 1765 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
1776 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 1766 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
1777 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 1767 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
1778 #undef DEFINE_BUILTIN_ACCESSOR_C 1768 #undef DEFINE_BUILTIN_ACCESSOR_C
1779 #undef DEFINE_BUILTIN_ACCESSOR_A 1769 #undef DEFINE_BUILTIN_ACCESSOR_A
1780 1770
1781 1771
1782 } } // namespace v8::internal 1772 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/elements.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698