OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 Register array_function, // Array function. | 799 Register array_function, // Array function. |
800 Register array_size, // As a smi, cannot be 0. | 800 Register array_size, // As a smi, cannot be 0. |
801 Register result, | 801 Register result, |
802 Register elements_array, | 802 Register elements_array, |
803 Register elements_array_end, | 803 Register elements_array_end, |
804 Register scratch, | 804 Register scratch, |
805 bool fill_with_hole, | 805 bool fill_with_hole, |
806 Label* gc_required) { | 806 Label* gc_required) { |
807 ASSERT(scratch.is(edi)); // rep stos destination | 807 ASSERT(scratch.is(edi)); // rep stos destination |
808 ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count | 808 ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count |
| 809 ASSERT(!fill_with_hole || !result.is(eax)); // result is never eax |
809 | 810 |
810 // Load the initial map from the array function. | 811 // Load the initial map from the array function. |
811 __ mov(elements_array, | 812 __ mov(elements_array, |
812 FieldOperand(array_function, | 813 FieldOperand(array_function, |
813 JSFunction::kPrototypeOrInitialMapOffset)); | 814 JSFunction::kPrototypeOrInitialMapOffset)); |
814 | 815 |
815 // Allocate the JSArray object together with space for a FixedArray with the | 816 // Allocate the JSArray object together with space for a FixedArray with the |
816 // requested elements. | 817 // requested elements. |
817 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 818 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); |
818 __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize, | 819 __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 // For non-empty JSArrays the length of the FixedArray and the JSArray is the | 857 // For non-empty JSArrays the length of the FixedArray and the JSArray is the |
857 // same. | 858 // same. |
858 __ mov(FieldOperand(elements_array, Array::kLengthOffset), array_size); | 859 __ mov(FieldOperand(elements_array, Array::kLengthOffset), array_size); |
859 | 860 |
860 // Fill the allocated FixedArray with the hole value if requested. | 861 // Fill the allocated FixedArray with the hole value if requested. |
861 // result: JSObject | 862 // result: JSObject |
862 // elements_array: elements array | 863 // elements_array: elements array |
863 if (fill_with_hole) { | 864 if (fill_with_hole) { |
864 __ lea(edi, Operand(elements_array, | 865 __ lea(edi, Operand(elements_array, |
865 FixedArray::kHeaderSize - kHeapObjectTag)); | 866 FixedArray::kHeaderSize - kHeapObjectTag)); |
866 | |
867 __ push(eax); | |
868 __ mov(eax, Factory::the_hole_value()); | 867 __ mov(eax, Factory::the_hole_value()); |
869 | |
870 __ cld(); | 868 __ cld(); |
| 869 // Do not use rep stos when filling less than kRepStosThreshold |
| 870 // words. |
| 871 const int kRepStosThreshold = 16; |
| 872 Label loop, entry, done; |
| 873 __ cmp(ecx, kRepStosThreshold); |
| 874 __ j(below, &loop); // Note: ecx > 0. |
871 __ rep_stos(); | 875 __ rep_stos(); |
872 | 876 __ jmp(&done); |
873 // Restore saved registers. | 877 __ bind(&loop); |
874 __ pop(eax); | 878 __ stos(); |
| 879 __ bind(&entry); |
| 880 __ cmp(edi, Operand(elements_array_end)); |
| 881 __ j(below, &loop); |
| 882 __ bind(&done); |
875 } | 883 } |
876 } | 884 } |
877 | 885 |
878 | 886 |
879 // Create a new array for the built-in Array function. This function allocates | 887 // Create a new array for the built-in Array function. This function allocates |
880 // the JSArray object and the FixedArray elements array and initializes these. | 888 // the JSArray object and the FixedArray elements array and initializes these. |
881 // If the Array cannot be constructed in native code the runtime is called. This | 889 // If the Array cannot be constructed in native code the runtime is called. This |
882 // function assumes the following state: | 890 // function assumes the following state: |
883 // edi: constructor (built-in Array function) | 891 // edi: constructor (built-in Array function) |
884 // eax: argc | 892 // eax: argc |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 | 971 |
964 // edx: array_size (smi) | 972 // edx: array_size (smi) |
965 // edi: constructor | 973 // edi: constructor |
966 // esp[0]: argc (cannot be 0 here) | 974 // esp[0]: argc (cannot be 0 here) |
967 // esp[4]: constructor (only if construct_call) | 975 // esp[4]: constructor (only if construct_call) |
968 // esp[8]: return address | 976 // esp[8]: return address |
969 // esp[C]: argument | 977 // esp[C]: argument |
970 AllocateJSArray(masm, | 978 AllocateJSArray(masm, |
971 edi, | 979 edi, |
972 ecx, | 980 ecx, |
| 981 ebx, |
973 eax, | 982 eax, |
974 ebx, | |
975 edx, | 983 edx, |
976 edi, | 984 edi, |
977 true, | 985 true, |
978 &prepare_generic_code_call); | 986 &prepare_generic_code_call); |
979 __ IncrementCounter(&Counters::array_function_native, 1); | 987 __ IncrementCounter(&Counters::array_function_native, 1); |
| 988 __ mov(eax, ebx); |
980 __ pop(ebx); | 989 __ pop(ebx); |
981 if (construct_call) { | 990 if (construct_call) { |
982 __ pop(edi); | 991 __ pop(edi); |
983 } | 992 } |
984 __ ret(2 * kPointerSize); | 993 __ ret(2 * kPointerSize); |
985 | 994 |
986 // Handle construction of an array from a list of arguments. | 995 // Handle construction of an array from a list of arguments. |
987 __ bind(&argc_two_or_more); | 996 __ bind(&argc_two_or_more); |
988 ASSERT(kSmiTag == 0); | 997 ASSERT(kSmiTag == 0); |
989 __ SmiTag(eax); // Convet argc to a smi. | 998 __ SmiTag(eax); // Convet argc to a smi. |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 // Dont adapt arguments. | 1249 // Dont adapt arguments. |
1241 // ------------------------------------------- | 1250 // ------------------------------------------- |
1242 __ bind(&dont_adapt_arguments); | 1251 __ bind(&dont_adapt_arguments); |
1243 __ jmp(Operand(edx)); | 1252 __ jmp(Operand(edx)); |
1244 } | 1253 } |
1245 | 1254 |
1246 | 1255 |
1247 #undef __ | 1256 #undef __ |
1248 | 1257 |
1249 } } // namespace v8::internal | 1258 } } // namespace v8::internal |
OLD | NEW |