| 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 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 Immediate(Factory::fixed_array_map())); | 1172 Immediate(Factory::fixed_array_map())); |
| 1173 __ j(not_equal, &miss); | 1173 __ j(not_equal, &miss); |
| 1174 | 1174 |
| 1175 if (argc == 1) { // Otherwise fall through to call builtin. | 1175 if (argc == 1) { // Otherwise fall through to call builtin. |
| 1176 Label call_builtin, exit, with_rset_update, attempt_to_grow_elements; | 1176 Label call_builtin, exit, with_rset_update, attempt_to_grow_elements; |
| 1177 | 1177 |
| 1178 // Get the array's length into eax and calculate new length. | 1178 // Get the array's length into eax and calculate new length. |
| 1179 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); | 1179 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); |
| 1180 STATIC_ASSERT(kSmiTagSize == 1); | 1180 STATIC_ASSERT(kSmiTagSize == 1); |
| 1181 STATIC_ASSERT(kSmiTag == 0); | 1181 STATIC_ASSERT(kSmiTag == 0); |
| 1182 __ add(Operand(eax), Immediate(argc << 1)); | 1182 __ add(Operand(eax), Immediate(Smi::FromInt(argc))); |
| 1183 | 1183 |
| 1184 // Get the element's length into ecx. | 1184 // Get the element's length into ecx. |
| 1185 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); | 1185 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
| 1186 __ SmiTag(ecx); | 1186 __ SmiTag(ecx); |
| 1187 | 1187 |
| 1188 // Check if we could survive without allocation. | 1188 // Check if we could survive without allocation. |
| 1189 __ cmp(eax, Operand(ecx)); | 1189 __ cmp(eax, Operand(ecx)); |
| 1190 __ j(greater, &attempt_to_grow_elements); | 1190 __ j(greater, &attempt_to_grow_elements); |
| 1191 | 1191 |
| 1192 // Save new length. | 1192 // Save new length. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1225 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); | 1225 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); |
| 1226 | 1226 |
| 1227 // Check if it's the end of elements. | 1227 // Check if it's the end of elements. |
| 1228 __ lea(edx, FieldOperand(ebx, | 1228 __ lea(edx, FieldOperand(ebx, |
| 1229 eax, times_half_pointer_size, | 1229 eax, times_half_pointer_size, |
| 1230 FixedArray::kHeaderSize - argc * kPointerSize)); | 1230 FixedArray::kHeaderSize - argc * kPointerSize)); |
| 1231 __ cmp(edx, Operand(ecx)); | 1231 __ cmp(edx, Operand(ecx)); |
| 1232 __ j(not_equal, &call_builtin); | 1232 __ j(not_equal, &call_builtin); |
| 1233 __ add(Operand(ecx), Immediate(kAllocationDelta * kPointerSize)); | 1233 __ add(Operand(ecx), Immediate(kAllocationDelta * kPointerSize)); |
| 1234 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit)); | 1234 __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit)); |
| 1235 __ j(greater, &call_builtin); | 1235 __ j(above, &call_builtin); |
| 1236 | 1236 |
| 1237 // We fit and could grow elements. | 1237 // We fit and could grow elements. |
| 1238 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); | 1238 __ mov(Operand::StaticVariable(new_space_allocation_top), ecx); |
| 1239 __ mov(ecx, Operand(esp, argc * kPointerSize)); | 1239 __ mov(ecx, Operand(esp, argc * kPointerSize)); |
| 1240 | 1240 |
| 1241 // Push the argument... | 1241 // Push the argument... |
| 1242 __ mov(Operand(edx, 0), ecx); | 1242 __ mov(Operand(edx, 0), ecx); |
| 1243 // ... and fill the rest with holes. | 1243 // ... and fill the rest with holes. |
| 1244 for (int i = 1; i < kAllocationDelta; i++) { | 1244 for (int i = 1; i < kAllocationDelta; i++) { |
| 1245 __ mov(Operand(edx, i * kPointerSize), | 1245 __ mov(Operand(edx, i * kPointerSize), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 // -- ... | 1291 // -- ... |
| 1292 // -- esp[(argc + 1) * 4] : receiver | 1292 // -- esp[(argc + 1) * 4] : receiver |
| 1293 // ----------------------------------- | 1293 // ----------------------------------- |
| 1294 ASSERT(check == RECEIVER_MAP_CHECK); | 1294 ASSERT(check == RECEIVER_MAP_CHECK); |
| 1295 | 1295 |
| 1296 // If object is not an array, bail out to regular call. | 1296 // If object is not an array, bail out to regular call. |
| 1297 if (!object->IsJSArray()) { | 1297 if (!object->IsJSArray()) { |
| 1298 return Heap::undefined_value(); | 1298 return Heap::undefined_value(); |
| 1299 } | 1299 } |
| 1300 | 1300 |
| 1301 Label miss, empty_array, call_builtin; | 1301 Label miss, return_undefined, call_builtin; |
| 1302 | 1302 |
| 1303 // Get the receiver from the stack. | 1303 // Get the receiver from the stack. |
| 1304 const int argc = arguments().immediate(); | 1304 const int argc = arguments().immediate(); |
| 1305 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1305 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1306 | 1306 |
| 1307 // Check that the receiver isn't a smi. | 1307 // Check that the receiver isn't a smi. |
| 1308 __ test(edx, Immediate(kSmiTagMask)); | 1308 __ test(edx, Immediate(kSmiTagMask)); |
| 1309 __ j(zero, &miss); | 1309 __ j(zero, &miss); |
| 1310 | |
| 1311 CheckPrototypes(JSObject::cast(object), edx, | 1310 CheckPrototypes(JSObject::cast(object), edx, |
| 1312 holder, ebx, | 1311 holder, ebx, |
| 1313 eax, name, &miss); | 1312 eax, name, &miss); |
| 1314 | 1313 |
| 1315 // Get the elements array of the object. | 1314 // Get the elements array of the object. |
| 1316 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); | 1315 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
| 1317 | 1316 |
| 1318 // Check that the elements are in fast mode (not dictionary). | 1317 // Check that the elements are in fast mode (not dictionary). |
| 1319 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 1318 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
| 1320 Immediate(Factory::fixed_array_map())); | 1319 Immediate(Factory::fixed_array_map())); |
| 1321 __ j(not_equal, &miss); | 1320 __ j(not_equal, &miss); |
| 1322 | 1321 |
| 1323 // Get the array's length into ecx and calculate new length. | 1322 // Get the array's length into ecx and calculate new length. |
| 1324 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); | 1323 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); |
| 1325 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); | 1324 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); |
| 1326 __ j(negative, &empty_array); | 1325 __ j(negative, &return_undefined); |
| 1327 | 1326 |
| 1328 // Get the last element. | 1327 // Get the last element. |
| 1329 STATIC_ASSERT(kSmiTagSize == 1); | 1328 STATIC_ASSERT(kSmiTagSize == 1); |
| 1330 STATIC_ASSERT(kSmiTag == 0); | 1329 STATIC_ASSERT(kSmiTag == 0); |
| 1331 __ mov(eax, FieldOperand(ebx, | 1330 __ mov(eax, FieldOperand(ebx, |
| 1332 ecx, times_half_pointer_size, | 1331 ecx, times_half_pointer_size, |
| 1333 FixedArray::kHeaderSize)); | 1332 FixedArray::kHeaderSize)); |
| 1334 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); | 1333 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); |
| 1335 __ j(equal, &call_builtin); | 1334 __ j(equal, &call_builtin); |
| 1336 | 1335 |
| 1337 // Set the array's length. | 1336 // Set the array's length. |
| 1338 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); | 1337 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); |
| 1339 | 1338 |
| 1340 // Fill with the hole. | 1339 // Fill with the hole. |
| 1341 __ mov(FieldOperand(ebx, | 1340 __ mov(FieldOperand(ebx, |
| 1342 ecx, times_half_pointer_size, | 1341 ecx, times_half_pointer_size, |
| 1343 FixedArray::kHeaderSize), | 1342 FixedArray::kHeaderSize), |
| 1344 Immediate(Factory::the_hole_value())); | 1343 Immediate(Factory::the_hole_value())); |
| 1345 __ ret((argc + 1) * kPointerSize); | 1344 __ ret((argc + 1) * kPointerSize); |
| 1346 | 1345 |
| 1347 __ bind(&empty_array); | 1346 __ bind(&return_undefined); |
| 1348 __ mov(eax, Immediate(Factory::undefined_value())); | 1347 __ mov(eax, Immediate(Factory::undefined_value())); |
| 1349 __ ret((argc + 1) * kPointerSize); | 1348 __ ret((argc + 1) * kPointerSize); |
| 1350 | 1349 |
| 1351 __ bind(&call_builtin); | 1350 __ bind(&call_builtin); |
| 1352 | |
| 1353 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 1351 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), |
| 1354 argc + 1, | 1352 argc + 1, |
| 1355 1); | 1353 1); |
| 1356 | 1354 |
| 1357 __ bind(&miss); | 1355 __ bind(&miss); |
| 1358 | 1356 |
| 1359 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 1357 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 1360 __ jmp(ic, RelocInfo::CODE_TARGET); | 1358 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 1361 | 1359 |
| 1362 // Return the generated code. | 1360 // Return the generated code. |
| (...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2398 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 2396 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 2399 | 2397 |
| 2400 // Return the generated code. | 2398 // Return the generated code. |
| 2401 return GetCode(); | 2399 return GetCode(); |
| 2402 } | 2400 } |
| 2403 | 2401 |
| 2404 | 2402 |
| 2405 #undef __ | 2403 #undef __ |
| 2406 | 2404 |
| 2407 } } // namespace v8::internal | 2405 } } // namespace v8::internal |
| OLD | NEW |