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 |