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

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

Issue 16453002: Removed flag optimize-constructed-arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment fixes Created 7 years, 5 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 | « src/hydrogen.cc ('k') | src/ia32/code-stubs-ia32.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 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY); 1008 __ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
1009 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1009 __ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1010 RelocInfo::CODE_TARGET); 1010 RelocInfo::CODE_TARGET);
1011 1011
1012 // Leave internal frame. 1012 // Leave internal frame.
1013 } 1013 }
1014 __ ret(3 * kPointerSize); // remove this, receiver, and arguments 1014 __ ret(3 * kPointerSize); // remove this, receiver, and arguments
1015 } 1015 }
1016 1016
1017 1017
1018 // Allocate an empty JSArray. The allocated array is put into the result
1019 // register. If the parameter initial_capacity is larger than zero an elements
1020 // backing store is allocated with this size and filled with the hole values.
1021 // Otherwise the elements backing store is set to the empty FixedArray.
1022 static void AllocateEmptyJSArray(MacroAssembler* masm,
1023 Register array_function,
1024 Register result,
1025 Register scratch1,
1026 Register scratch2,
1027 Register scratch3,
1028 Label* gc_required) {
1029 const int initial_capacity = JSArray::kPreallocatedArrayElements;
1030 STATIC_ASSERT(initial_capacity >= 0);
1031
1032 __ LoadInitialArrayMap(array_function, scratch2, scratch1, false);
1033
1034 // Allocate the JSArray object together with space for a fixed array with the
1035 // requested elements.
1036 int size = JSArray::kSize;
1037 if (initial_capacity > 0) {
1038 size += FixedArray::SizeFor(initial_capacity);
1039 }
1040 __ Allocate(size, result, scratch2, scratch3, gc_required, TAG_OBJECT);
1041
1042 // Allocated the JSArray. Now initialize the fields except for the elements
1043 // array.
1044 // result: JSObject
1045 // scratch1: initial map
1046 // scratch2: start of next object
1047 __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
1048 Factory* factory = masm->isolate()->factory();
1049 __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
1050 factory->empty_fixed_array());
1051 // Field JSArray::kElementsOffset is initialized later.
1052 __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
1053
1054 // If no storage is requested for the elements array just set the empty
1055 // fixed array.
1056 if (initial_capacity == 0) {
1057 __ mov(FieldOperand(result, JSArray::kElementsOffset),
1058 factory->empty_fixed_array());
1059 return;
1060 }
1061
1062 // Calculate the location of the elements array and set elements array member
1063 // of the JSArray.
1064 // result: JSObject
1065 // scratch2: start of next object
1066 __ lea(scratch1, Operand(result, JSArray::kSize));
1067 __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1);
1068
1069 // Initialize the FixedArray and fill it with holes. FixedArray length is
1070 // stored as a smi.
1071 // result: JSObject
1072 // scratch1: elements array
1073 // scratch2: start of next object
1074 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
1075 factory->fixed_array_map());
1076 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
1077 Immediate(Smi::FromInt(initial_capacity)));
1078
1079 // Fill the FixedArray with the hole value. Inline the code if short.
1080 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed.
1081 static const int kLoopUnfoldLimit = 4;
1082 if (initial_capacity <= kLoopUnfoldLimit) {
1083 // Use a scratch register here to have only one reloc info when unfolding
1084 // the loop.
1085 __ mov(scratch3, factory->the_hole_value());
1086 for (int i = 0; i < initial_capacity; i++) {
1087 __ mov(FieldOperand(scratch1,
1088 FixedArray::kHeaderSize + i * kPointerSize),
1089 scratch3);
1090 }
1091 } else {
1092 Label loop, entry;
1093 __ mov(scratch2, Immediate(initial_capacity));
1094 __ jmp(&entry);
1095 __ bind(&loop);
1096 __ mov(FieldOperand(scratch1,
1097 scratch2,
1098 times_pointer_size,
1099 FixedArray::kHeaderSize),
1100 factory->the_hole_value());
1101 __ bind(&entry);
1102 __ dec(scratch2);
1103 __ j(not_sign, &loop);
1104 }
1105 }
1106
1107
1108 // Allocate a JSArray with the number of elements stored in a register. The
1109 // register array_function holds the built-in Array function and the register
1110 // array_size holds the size of the array as a smi. The allocated array is put
1111 // into the result register and beginning and end of the FixedArray elements
1112 // storage is put into registers elements_array and elements_array_end (see
1113 // below for when that is not the case). If the parameter fill_with_holes is
1114 // true the allocated elements backing store is filled with the hole values
1115 // otherwise it is left uninitialized. When the backing store is filled the
1116 // register elements_array is scratched.
1117 static void AllocateJSArray(MacroAssembler* masm,
1118 Register array_function, // Array function.
1119 Register array_size, // As a smi, cannot be 0.
1120 Register result,
1121 Register elements_array,
1122 Register elements_array_end,
1123 Register scratch,
1124 bool fill_with_hole,
1125 Label* gc_required) {
1126 ASSERT(scratch.is(edi)); // rep stos destination
1127 ASSERT(!fill_with_hole || array_size.is(ecx)); // rep stos count
1128 ASSERT(!fill_with_hole || !result.is(eax)); // result is never eax
1129
1130 __ LoadInitialArrayMap(array_function, scratch,
1131 elements_array, fill_with_hole);
1132
1133 // Allocate the JSArray object together with space for a FixedArray with the
1134 // requested elements.
1135 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1136 __ Allocate(JSArray::kSize + FixedArray::kHeaderSize,
1137 times_pointer_size,
1138 array_size,
1139 REGISTER_VALUE_IS_SMI,
1140 result,
1141 elements_array_end,
1142 scratch,
1143 gc_required,
1144 TAG_OBJECT);
1145
1146 // Allocated the JSArray. Now initialize the fields except for the elements
1147 // array.
1148 // result: JSObject
1149 // elements_array: initial map
1150 // elements_array_end: start of next object
1151 // array_size: size of array (smi)
1152 __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
1153 Factory* factory = masm->isolate()->factory();
1154 __ mov(elements_array, factory->empty_fixed_array());
1155 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
1156 // Field JSArray::kElementsOffset is initialized later.
1157 __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size);
1158
1159 // Calculate the location of the elements array and set elements array member
1160 // of the JSArray.
1161 // result: JSObject
1162 // elements_array_end: start of next object
1163 // array_size: size of array (smi)
1164 __ lea(elements_array, Operand(result, JSArray::kSize));
1165 __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array);
1166
1167 // Initialize the fixed array. FixedArray length is stored as a smi.
1168 // result: JSObject
1169 // elements_array: elements array
1170 // elements_array_end: start of next object
1171 // array_size: size of array (smi)
1172 __ mov(FieldOperand(elements_array, FixedArray::kMapOffset),
1173 factory->fixed_array_map());
1174 // For non-empty JSArrays the length of the FixedArray and the JSArray is the
1175 // same.
1176 __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
1177
1178 // Fill the allocated FixedArray with the hole value if requested.
1179 // result: JSObject
1180 // elements_array: elements array
1181 if (fill_with_hole) {
1182 __ SmiUntag(array_size);
1183 __ lea(edi, Operand(elements_array,
1184 FixedArray::kHeaderSize - kHeapObjectTag));
1185 __ mov(eax, factory->the_hole_value());
1186 __ cld();
1187 // Do not use rep stos when filling less than kRepStosThreshold
1188 // words.
1189 const int kRepStosThreshold = 16;
1190 Label loop, entry, done;
1191 __ cmp(ecx, kRepStosThreshold);
1192 __ j(below, &loop); // Note: ecx > 0.
1193 __ rep_stos();
1194 __ jmp(&done);
1195 __ bind(&loop);
1196 __ stos();
1197 __ bind(&entry);
1198 __ cmp(edi, elements_array_end);
1199 __ j(below, &loop);
1200 __ bind(&done);
1201 }
1202 }
1203
1204
1205 // Create a new array for the built-in Array function. This function allocates
1206 // the JSArray object and the FixedArray elements array and initializes these.
1207 // If the Array cannot be constructed in native code the runtime is called. This
1208 // function assumes the following state:
1209 // edi: constructor (built-in Array function)
1210 // eax: argc
1211 // esp[0]: return address
1212 // esp[4]: last argument
1213 // This function is used for both construct and normal calls of Array. Whether
1214 // it is a construct call or not is indicated by the construct_call parameter.
1215 // The only difference between handling a construct call and a normal call is
1216 // that for a construct call the constructor function in edi needs to be
1217 // preserved for entering the generic code. In both cases argc in eax needs to
1218 // be preserved.
1219 void ArrayNativeCode(MacroAssembler* masm,
1220 bool construct_call,
1221 Label* call_generic_code) {
1222 Label argc_one_or_more, argc_two_or_more, prepare_generic_code_call,
1223 empty_array, not_empty_array, finish, cant_transition_map, not_double;
1224
1225 // Push the constructor and argc. No need to tag argc as a smi, as there will
1226 // be no garbage collection with this on the stack.
1227 int push_count = 0;
1228 if (construct_call) {
1229 push_count++;
1230 __ push(edi);
1231 }
1232 push_count++;
1233 __ push(eax);
1234
1235 // Check for array construction with zero arguments.
1236 __ test(eax, eax);
1237 __ j(not_zero, &argc_one_or_more);
1238
1239 __ bind(&empty_array);
1240 // Handle construction of an empty array.
1241 AllocateEmptyJSArray(masm,
1242 edi,
1243 eax,
1244 ebx,
1245 ecx,
1246 edi,
1247 &prepare_generic_code_call);
1248 __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
1249 __ pop(ebx);
1250 if (construct_call) {
1251 __ pop(edi);
1252 }
1253 __ ret(kPointerSize);
1254
1255 // Check for one argument. Bail out if argument is not smi or if it is
1256 // negative.
1257 __ bind(&argc_one_or_more);
1258 __ cmp(eax, 1);
1259 __ j(not_equal, &argc_two_or_more);
1260 STATIC_ASSERT(kSmiTag == 0);
1261 __ mov(ecx, Operand(esp, (push_count + 1) * kPointerSize));
1262 __ test(ecx, ecx);
1263 __ j(not_zero, &not_empty_array);
1264
1265 // The single argument passed is zero, so we jump to the code above used to
1266 // handle the case of no arguments passed. To adapt the stack for that we move
1267 // the return address and the pushed constructor (if pushed) one stack slot up
1268 // thereby removing the passed argument. Argc is also on the stack - at the
1269 // bottom - and it needs to be changed from 1 to 0 to have the call into the
1270 // runtime system work in case a GC is required.
1271 for (int i = push_count; i > 0; i--) {
1272 __ mov(eax, Operand(esp, i * kPointerSize));
1273 __ mov(Operand(esp, (i + 1) * kPointerSize), eax);
1274 }
1275 __ Drop(2); // Drop two stack slots.
1276 __ push(Immediate(0)); // Treat this as a call with argc of zero.
1277 __ jmp(&empty_array);
1278
1279 __ bind(&not_empty_array);
1280 __ test(ecx, Immediate(kIntptrSignBit | kSmiTagMask));
1281 __ j(not_zero, &prepare_generic_code_call);
1282
1283 // Handle construction of an empty array of a certain size. Get the size from
1284 // the stack and bail out if size is to large to actually allocate an elements
1285 // array.
1286 __ cmp(ecx, JSObject::kInitialMaxFastElementArray << kSmiTagSize);
1287 __ j(greater_equal, &prepare_generic_code_call);
1288
1289 // edx: array_size (smi)
1290 // edi: constructor
1291 // esp[0]: argc (cannot be 0 here)
1292 // esp[4]: constructor (only if construct_call)
1293 // esp[8]: return address
1294 // esp[C]: argument
1295 AllocateJSArray(masm,
1296 edi,
1297 ecx,
1298 ebx,
1299 eax,
1300 edx,
1301 edi,
1302 true,
1303 &prepare_generic_code_call);
1304 Counters* counters = masm->isolate()->counters();
1305 __ IncrementCounter(counters->array_function_native(), 1);
1306 __ mov(eax, ebx);
1307 __ pop(ebx);
1308 if (construct_call) {
1309 __ pop(edi);
1310 }
1311 __ ret(2 * kPointerSize);
1312
1313 // Handle construction of an array from a list of arguments.
1314 __ bind(&argc_two_or_more);
1315 STATIC_ASSERT(kSmiTag == 0);
1316 __ SmiTag(eax); // Convet argc to a smi.
1317 // eax: array_size (smi)
1318 // edi: constructor
1319 // esp[0] : argc
1320 // esp[4]: constructor (only if construct_call)
1321 // esp[8] : return address
1322 // esp[C] : last argument
1323 AllocateJSArray(masm,
1324 edi,
1325 eax,
1326 ebx,
1327 ecx,
1328 edx,
1329 edi,
1330 false,
1331 &prepare_generic_code_call);
1332 __ IncrementCounter(counters->array_function_native(), 1);
1333 __ push(ebx);
1334 __ mov(ebx, Operand(esp, kPointerSize));
1335 // ebx: argc
1336 // edx: elements_array_end (untagged)
1337 // esp[0]: JSArray
1338 // esp[4]: argc
1339 // esp[8]: constructor (only if construct_call)
1340 // esp[12]: return address
1341 // esp[16]: last argument
1342
1343 // Location of the last argument
1344 int last_arg_offset = (construct_call ? 4 : 3) * kPointerSize;
1345 __ lea(edi, Operand(esp, last_arg_offset));
1346
1347 // Location of the first array element (Parameter fill_with_holes to
1348 // AllocateJSArray is false, so the FixedArray is returned in ecx).
1349 __ lea(edx, Operand(ecx, FixedArray::kHeaderSize - kHeapObjectTag));
1350
1351 Label has_non_smi_element;
1352
1353 // ebx: argc
1354 // edx: location of the first array element
1355 // edi: location of the last argument
1356 // esp[0]: JSArray
1357 // esp[4]: argc
1358 // esp[8]: constructor (only if construct_call)
1359 // esp[12]: return address
1360 // esp[16]: last argument
1361 Label loop, entry;
1362 __ mov(ecx, ebx);
1363 __ jmp(&entry);
1364 __ bind(&loop);
1365 __ mov(eax, Operand(edi, ecx, times_pointer_size, 0));
1366 if (FLAG_smi_only_arrays) {
1367 __ JumpIfNotSmi(eax, &has_non_smi_element);
1368 }
1369 __ mov(Operand(edx, 0), eax);
1370 __ add(edx, Immediate(kPointerSize));
1371 __ bind(&entry);
1372 __ dec(ecx);
1373 __ j(greater_equal, &loop);
1374
1375 // Remove caller arguments from the stack and return.
1376 // ebx: argc
1377 // esp[0]: JSArray
1378 // esp[4]: argc
1379 // esp[8]: constructor (only if construct_call)
1380 // esp[12]: return address
1381 // esp[16]: last argument
1382 __ bind(&finish);
1383 __ mov(ecx, Operand(esp, last_arg_offset - kPointerSize));
1384 __ pop(eax);
1385 __ pop(ebx);
1386 __ lea(esp, Operand(esp, ebx, times_pointer_size,
1387 last_arg_offset - kPointerSize));
1388 __ jmp(ecx);
1389
1390 __ bind(&has_non_smi_element);
1391 // Double values are handled by the runtime.
1392 __ CheckMap(eax,
1393 masm->isolate()->factory()->heap_number_map(),
1394 &not_double,
1395 DONT_DO_SMI_CHECK);
1396 __ bind(&cant_transition_map);
1397 // Throw away the array that's only been partially constructed.
1398 __ pop(eax);
1399 __ UndoAllocationInNewSpace(eax);
1400 __ jmp(&prepare_generic_code_call);
1401
1402 __ bind(&not_double);
1403 // Transition FAST_SMI_ELEMENTS to FAST_ELEMENTS.
1404 __ mov(ebx, Operand(esp, 0));
1405 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
1406 __ LoadTransitionedArrayMapConditional(
1407 FAST_SMI_ELEMENTS,
1408 FAST_ELEMENTS,
1409 edi,
1410 eax,
1411 &cant_transition_map);
1412 __ mov(FieldOperand(ebx, HeapObject::kMapOffset), edi);
1413 __ RecordWriteField(ebx, HeapObject::kMapOffset, edi, eax,
1414 kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
1415
1416 // Prepare to re-enter the loop
1417 __ lea(edi, Operand(esp, last_arg_offset));
1418
1419 // Finish the array initialization loop.
1420 Label loop2;
1421 __ bind(&loop2);
1422 __ mov(eax, Operand(edi, ecx, times_pointer_size, 0));
1423 __ mov(Operand(edx, 0), eax);
1424 __ add(edx, Immediate(kPointerSize));
1425 __ dec(ecx);
1426 __ j(greater_equal, &loop2);
1427 __ jmp(&finish);
1428
1429 // Restore argc and constructor before running the generic code.
1430 __ bind(&prepare_generic_code_call);
1431 __ pop(eax);
1432 if (construct_call) {
1433 __ pop(edi);
1434 }
1435 __ jmp(call_generic_code);
1436 }
1437
1438
1439 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { 1018 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
1440 // ----------- S t a t e ------------- 1019 // ----------- S t a t e -------------
1441 // -- eax : argc 1020 // -- eax : argc
1442 // -- esp[0] : return address 1021 // -- esp[0] : return address
1443 // -- esp[4] : last argument 1022 // -- esp[4] : last argument
1444 // ----------------------------------- 1023 // -----------------------------------
1445 Label generic_array_code; 1024 Label generic_array_code;
1446 1025
1447 // Get the InternalArray function. 1026 // Get the InternalArray function.
1448 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); 1027 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);
1449 1028
1450 if (FLAG_debug_code) { 1029 if (FLAG_debug_code) {
1451 // Initial map for the builtin InternalArray function should be a map. 1030 // Initial map for the builtin InternalArray function should be a map.
1452 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 1031 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1453 // Will both indicate a NULL and a Smi. 1032 // Will both indicate a NULL and a Smi.
1454 __ test(ebx, Immediate(kSmiTagMask)); 1033 __ test(ebx, Immediate(kSmiTagMask));
1455 __ Assert(not_zero, "Unexpected initial map for InternalArray function"); 1034 __ Assert(not_zero, "Unexpected initial map for InternalArray function");
1456 __ CmpObjectType(ebx, MAP_TYPE, ecx); 1035 __ CmpObjectType(ebx, MAP_TYPE, ecx);
1457 __ Assert(equal, "Unexpected initial map for InternalArray function"); 1036 __ Assert(equal, "Unexpected initial map for InternalArray function");
1458 } 1037 }
1459 1038
1460 // Run the native code for the InternalArray function called as a normal 1039 // Run the native code for the InternalArray function called as a normal
1461 // function. 1040 // function.
1462 if (FLAG_optimize_constructed_arrays) { 1041 // tail call a stub
1463 // tail call a stub 1042 InternalArrayConstructorStub stub(masm->isolate());
1464 InternalArrayConstructorStub stub(masm->isolate()); 1043 __ TailCallStub(&stub);
1465 __ TailCallStub(&stub);
1466 } else {
1467 ArrayNativeCode(masm, false, &generic_array_code);
1468
1469 // Jump to the generic internal array code in case the specialized code
1470 // cannot handle the construction.
1471 __ bind(&generic_array_code);
1472 Handle<Code> array_code =
1473 masm->isolate()->builtins()->InternalArrayCodeGeneric();
1474 __ jmp(array_code, RelocInfo::CODE_TARGET);
1475 }
1476 } 1044 }
1477 1045
1478 1046
1479 void Builtins::Generate_ArrayCode(MacroAssembler* masm) { 1047 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1480 // ----------- S t a t e ------------- 1048 // ----------- S t a t e -------------
1481 // -- eax : argc 1049 // -- eax : argc
1482 // -- esp[0] : return address 1050 // -- esp[0] : return address
1483 // -- esp[4] : last argument 1051 // -- esp[4] : last argument
1484 // ----------------------------------- 1052 // -----------------------------------
1485 Label generic_array_code; 1053 Label generic_array_code;
1486 1054
1487 // Get the Array function. 1055 // Get the Array function.
1488 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi); 1056 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, edi);
1489 1057
1490 if (FLAG_debug_code) { 1058 if (FLAG_debug_code) {
1491 // Initial map for the builtin Array function should be a map. 1059 // Initial map for the builtin Array function should be a map.
1492 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 1060 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1493 // Will both indicate a NULL and a Smi. 1061 // Will both indicate a NULL and a Smi.
1494 __ test(ebx, Immediate(kSmiTagMask)); 1062 __ test(ebx, Immediate(kSmiTagMask));
1495 __ Assert(not_zero, "Unexpected initial map for Array function"); 1063 __ Assert(not_zero, "Unexpected initial map for Array function");
1496 __ CmpObjectType(ebx, MAP_TYPE, ecx); 1064 __ CmpObjectType(ebx, MAP_TYPE, ecx);
1497 __ Assert(equal, "Unexpected initial map for Array function"); 1065 __ Assert(equal, "Unexpected initial map for Array function");
1498 } 1066 }
1499 1067
1500 // Run the native code for the Array function called as a normal function. 1068 // Run the native code for the Array function called as a normal function.
1501 if (FLAG_optimize_constructed_arrays) { 1069 // tail call a stub
1502 // tail call a stub 1070 Handle<Object> undefined_sentinel(
1503 Handle<Object> undefined_sentinel( 1071 masm->isolate()->heap()->undefined_value(),
1504 masm->isolate()->heap()->undefined_value(), 1072 masm->isolate());
1505 masm->isolate()); 1073 __ mov(ebx, Immediate(undefined_sentinel));
1506 __ mov(ebx, Immediate(undefined_sentinel)); 1074 ArrayConstructorStub stub(masm->isolate());
1507 ArrayConstructorStub stub(masm->isolate()); 1075 __ TailCallStub(&stub);
1508 __ TailCallStub(&stub);
1509 } else {
1510 ArrayNativeCode(masm, false, &generic_array_code);
1511
1512 // Jump to the generic internal array code in case the specialized code
1513 // cannot handle the construction.
1514 __ bind(&generic_array_code);
1515 Handle<Code> array_code =
1516 masm->isolate()->builtins()->ArrayCodeGeneric();
1517 __ jmp(array_code, RelocInfo::CODE_TARGET);
1518 }
1519 } 1076 }
1520 1077
1521 1078
1522 void Builtins::Generate_CommonArrayConstructCode(MacroAssembler* masm) {
1523 // ----------- S t a t e -------------
1524 // -- eax : argc
1525 // -- ebx : type info cell
1526 // -- edi : constructor
1527 // -- esp[0] : return address
1528 // -- esp[4] : last argument
1529 // -----------------------------------
1530 if (FLAG_debug_code) {
1531 // The array construct code is only set for the global and natives
1532 // builtin Array functions which always have maps.
1533
1534 // Initial map for the builtin Array function should be a map.
1535 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
1536 // Will both indicate a NULL and a Smi.
1537 __ test(ecx, Immediate(kSmiTagMask));
1538 __ Assert(not_zero, "Unexpected initial map for Array function");
1539 __ CmpObjectType(ecx, MAP_TYPE, ecx);
1540 __ Assert(equal, "Unexpected initial map for Array function");
1541 }
1542
1543 Label generic_constructor;
1544 // Run the native code for the Array function called as constructor.
1545 ArrayNativeCode(masm, true, &generic_constructor);
1546
1547 // Jump to the generic construct code in case the specialized code cannot
1548 // handle the construction.
1549 __ bind(&generic_constructor);
1550 Handle<Code> generic_construct_stub =
1551 masm->isolate()->builtins()->JSConstructStubGeneric();
1552 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
1553 }
1554
1555
1556 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1079 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1557 // ----------- S t a t e ------------- 1080 // ----------- S t a t e -------------
1558 // -- eax : number of arguments 1081 // -- eax : number of arguments
1559 // -- edi : constructor function 1082 // -- edi : constructor function
1560 // -- esp[0] : return address 1083 // -- esp[0] : return address
1561 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1084 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1562 // -- esp[(argc + 1) * 4] : receiver 1085 // -- esp[(argc + 1) * 4] : receiver
1563 // ----------------------------------- 1086 // -----------------------------------
1564 Counters* counters = masm->isolate()->counters(); 1087 Counters* counters = masm->isolate()->counters();
1565 __ IncrementCounter(counters->string_ctor_calls(), 1); 1088 __ IncrementCounter(counters->string_ctor_calls(), 1);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); 1353 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR);
1831 generator.Generate(); 1354 generator.Generate();
1832 } 1355 }
1833 1356
1834 1357
1835 #undef __ 1358 #undef __
1836 } 1359 }
1837 } // namespace v8::internal 1360 } // namespace v8::internal
1838 1361
1839 #endif // V8_TARGET_ARCH_IA32 1362 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698