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

Side by Side Diff: src/ia32/builtins-ia32.cc

Issue 8359034: Refactor and clean up array allocation across platforms. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 2 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); 908 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
909 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 909 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
910 RelocInfo::CODE_TARGET); 910 RelocInfo::CODE_TARGET);
911 911
912 // Leave internal frame. 912 // Leave internal frame.
913 } 913 }
914 __ ret(3 * kPointerSize); // remove this, receiver, and arguments 914 __ ret(3 * kPointerSize); // remove this, receiver, and arguments
915 } 915 }
916 916
917 917
918 // Number of empty elements to allocate for an empty array.
919 static const int kPreallocatedArrayElements = 4;
920
921
922 // Allocate an empty JSArray. The allocated array is put into the result 918 // Allocate an empty JSArray. The allocated array is put into the result
923 // register. If the parameter initial_capacity is larger than zero an elements 919 // register. If the parameter initial_capacity is larger than zero an elements
924 // backing store is allocated with this size and filled with the hole values. 920 // backing store is allocated with this size and filled with the hole values.
925 // Otherwise the elements backing store is set to the empty FixedArray. 921 // Otherwise the elements backing store is set to the empty FixedArray.
926 static void AllocateEmptyJSArray(MacroAssembler* masm, 922 static void AllocateEmptyJSArray(MacroAssembler* masm,
927 Register array_function, 923 Register array_function,
928 Register result, 924 Register result,
929 Register scratch1, 925 Register scratch1,
930 Register scratch2, 926 Register scratch2,
931 Register scratch3, 927 Register scratch3,
932 int initial_capacity,
933 Label* gc_required) { 928 Label* gc_required) {
929 int initial_capacity = JSArray::kPreallocatedArrayElements;
934 ASSERT(initial_capacity >= 0); 930 ASSERT(initial_capacity >= 0);
935
936 // Load the initial map from the array function. 931 // Load the initial map from the array function.
937 __ mov(scratch1, FieldOperand(array_function, 932 __ mov(scratch1, FieldOperand(array_function,
938 JSFunction::kPrototypeOrInitialMapOffset)); 933 JSFunction::kPrototypeOrInitialMapOffset));
939 934
940 // Allocate the JSArray object together with space for a fixed array with the 935 // Allocate the JSArray object together with space for a fixed array with the
941 // requested elements. 936 // requested elements.
942 int size = JSArray::kSize; 937 int size = JSArray::kSize;
943 if (initial_capacity > 0) { 938 if (initial_capacity > 0) {
944 size += FixedArray::SizeFor(initial_capacity); 939 size += FixedArray::SizeFor(initial_capacity);
945 } 940 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 // scratch1: elements array 978 // scratch1: elements array
984 // scratch2: start of next object 979 // scratch2: start of next object
985 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), 980 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
986 factory->fixed_array_map()); 981 factory->fixed_array_map());
987 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), 982 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
988 Immediate(Smi::FromInt(initial_capacity))); 983 Immediate(Smi::FromInt(initial_capacity)));
989 984
990 // Fill the FixedArray with the hole value. Inline the code if short. 985 // Fill the FixedArray with the hole value. Inline the code if short.
991 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. 986 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
992 static const int kLoopUnfoldLimit = 4; 987 static const int kLoopUnfoldLimit = 4;
993 STATIC_ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit);
994 if (initial_capacity <= kLoopUnfoldLimit) { 988 if (initial_capacity <= kLoopUnfoldLimit) {
995 // Use a scratch register here to have only one reloc info when unfolding 989 // Use a scratch register here to have only one reloc info when unfolding
996 // the loop. 990 // the loop.
997 __ mov(scratch3, factory->the_hole_value()); 991 __ mov(scratch3, factory->the_hole_value());
998 for (int i = 0; i < initial_capacity; i++) { 992 for (int i = 0; i < initial_capacity; i++) {
999 __ mov(FieldOperand(scratch1, 993 __ mov(FieldOperand(scratch1,
1000 FixedArray::kHeaderSize + i * kPointerSize), 994 FixedArray::kHeaderSize + i * kPointerSize),
1001 scratch3); 995 scratch3);
1002 } 996 }
1003 } else { 997 } else {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 __ j(not_zero, &argc_one_or_more); 1140 __ j(not_zero, &argc_one_or_more);
1147 1141
1148 __ bind(&empty_array); 1142 __ bind(&empty_array);
1149 // Handle construction of an empty array. 1143 // Handle construction of an empty array.
1150 AllocateEmptyJSArray(masm, 1144 AllocateEmptyJSArray(masm,
1151 edi, 1145 edi,
1152 eax, 1146 eax,
1153 ebx, 1147 ebx,
1154 ecx, 1148 ecx,
1155 edi, 1149 edi,
1156 kPreallocatedArrayElements,
1157 &prepare_generic_code_call); 1150 &prepare_generic_code_call);
1158 __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1); 1151 __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
1159 __ pop(ebx); 1152 __ pop(ebx);
1160 if (construct_call) { 1153 if (construct_call) {
1161 __ pop(edi); 1154 __ pop(edi);
1162 } 1155 }
1163 __ ret(kPointerSize); 1156 __ ret(kPointerSize);
1164 1157
1165 // Check for one argument. Bail out if argument is not smi or if it is 1158 // Check for one argument. Bail out if argument is not smi or if it is
1166 // negative. 1159 // negative.
1167 __ bind(&argc_one_or_more); 1160 __ bind(&argc_one_or_more);
1168 __ cmp(eax, 1); 1161 __ cmp(eax, 1);
1169 __ j(not_equal, &argc_two_or_more); 1162 __ j(not_equal, &argc_two_or_more);
1170 STATIC_ASSERT(kSmiTag == 0); 1163 STATIC_ASSERT(kSmiTag == 0);
1171 __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize)); 1164 __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize));
1172 __ test(ecx, ecx); 1165 __ test(ecx, ecx);
1173 __ j(not_zero, &not_empty_array); 1166 __ j(not_zero, &not_empty_array);
1174 1167
1175 // The single argument passed is zero, so we jump to the code above used to 1168 // The single argument passed is zero, so we jump to the code above used to
1176 // handle the case of no arguments passed. To adapt the stack for that we move 1169 // handle the case of no arguments passed. To adapt the stack for that we move
1177 // the return address and the pushed constructor (if pushed) one stack slot up 1170 // the return address and the pushed constructor (if pushed) one stack slot up
1178 // thereby removing the passed argument. Argc is also on the stack - at the 1171 // thereby removing the passed argument. Argc is also on the stack - at the
1179 // bottom - and it needs to be changed from 1 to 0 to have the call into the 1172 // bottom - and it needs to be changed from 1 to 0 to have the call into the
1180 // runtime system work in case a GC is required. 1173 // runtime system work in case a GC is required.
1181 for (int i = push_count; i > 0; i--) { 1174 for (int i = push_count; i > 0; i--) {
1182 __ mov(eax, Operand(esp, i * kPointerSize)); 1175 __ mov(eax, Operand(esp, i * kPointerSize));
1183 __ mov(Operand(esp, (i + 1) * kPointerSize), eax); 1176 __ mov(Operand(esp, (i + 1) * kPointerSize), eax);
1184 } 1177 }
1185 __ add(esp, Immediate(2 * kPointerSize)); // Drop two stack slots. 1178 __ Drop(2); // Drop two stack slots.
1186 __ push(Immediate(0)); // Treat this as a call with argc of zero. 1179 __ push(Immediate(0)); // Treat this as a call with argc of zero.
1187 __ jmp(&empty_array); 1180 __ jmp(&empty_array);
1188 1181
1189 __ bind(&not_empty_array); 1182 __ bind(&not_empty_array);
1190 __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask)); 1183 __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask));
1191 __ j(not_zero, &prepare_generic_code_call); 1184 __ j(not_zero, &prepare_generic_code_call);
1192 1185
1193 // Handle construction of an empty array of a certain size. Get the size from 1186 // Handle construction of an empty array of a certain size. Get the size from
1194 // the stack and bail out if size is to large to actually allocate an elements 1187 // the stack and bail out if size is to large to actually allocate an elements
1195 // array. 1188 // array.
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1672 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1680 generator.Generate(); 1673 generator.Generate();
1681 } 1674 }
1682 1675
1683 1676
1684 #undef __ 1677 #undef __
1685 } 1678 }
1686 } // namespace v8::internal 1679 } // namespace v8::internal
1687 1680
1688 #endif // V8_TARGET_ARCH_IA32 1681 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/arm/builtins-arm.cc ('K') | « src/arm/builtins-arm.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698