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 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 JSFunction* function, | 1214 JSFunction* function, |
1215 String* name, | 1215 String* name, |
1216 CheckType check) { | 1216 CheckType check) { |
1217 // ----------- S t a t e ------------- | 1217 // ----------- S t a t e ------------- |
1218 // -- ecx : name | 1218 // -- ecx : name |
1219 // -- esp[0] : return address | 1219 // -- esp[0] : return address |
1220 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1220 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1221 // -- ... | 1221 // -- ... |
1222 // -- esp[(argc + 1) * 4] : receiver | 1222 // -- esp[(argc + 1) * 4] : receiver |
1223 // ----------------------------------- | 1223 // ----------------------------------- |
| 1224 ASSERT(check == RECEIVER_MAP_CHECK); |
| 1225 |
1224 Label miss; | 1226 Label miss; |
1225 | 1227 |
1226 // Get the receiver from the stack. | 1228 // Get the receiver from the stack. |
1227 const int argc = arguments().immediate(); | 1229 const int argc = arguments().immediate(); |
1228 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1230 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1229 | 1231 |
1230 // Check that the receiver isn't a smi. | 1232 // Check that the receiver isn't a smi. |
1231 __ test(edx, Immediate(kSmiTagMask)); | 1233 __ test(edx, Immediate(kSmiTagMask)); |
1232 __ j(zero, &miss, not_taken); | 1234 __ j(zero, &miss); |
1233 | 1235 |
1234 CheckPrototypes(JSObject::cast(object), edx, | 1236 CheckPrototypes(JSObject::cast(object), edx, |
1235 holder, ebx, | 1237 holder, ebx, |
1236 eax, name, &miss); | 1238 eax, name, &miss); |
1237 | 1239 |
1238 if (argc == 0) { | 1240 if (argc == 0) { |
1239 // Noop, return the length. | 1241 // Noop, return the length. |
1240 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); | 1242 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); |
1241 __ ret((argc + 1) * kPointerSize); | 1243 __ ret((argc + 1) * kPointerSize); |
1242 } else { | 1244 } else { |
1243 // Get the elements array of the object. | 1245 // Get the elements array of the object. |
1244 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); | 1246 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
1245 | 1247 |
1246 // Check that the elements are in fast mode (not dictionary). | 1248 // Check that the elements are in fast mode (not dictionary). |
1247 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), | 1249 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
1248 Immediate(Factory::fixed_array_map())); | 1250 Immediate(Factory::fixed_array_map())); |
1249 __ j(not_equal, &miss, not_taken); | 1251 __ j(not_equal, &miss); |
1250 | 1252 |
1251 if (argc == 1) { // Otherwise fall through to call builtin. | 1253 if (argc == 1) { // Otherwise fall through to call builtin. |
1252 Label call_builtin, exit, with_rset_update; | 1254 Label call_builtin, exit, with_rset_update; |
1253 | 1255 |
1254 // Get the array's length into eax and calculate new length. | 1256 // Get the array's length into eax and calculate new length. |
1255 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); | 1257 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); |
| 1258 STATIC_ASSERT(kSmiTagSize == 1); |
| 1259 STATIC_ASSERT(kSmiTag == 0); |
1256 __ add(Operand(eax), Immediate(argc << 1)); | 1260 __ add(Operand(eax), Immediate(argc << 1)); |
1257 | 1261 |
1258 // Get the element's length into ecx. | 1262 // Get the element's length into ecx. |
1259 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); | 1263 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset)); |
1260 __ SmiTag(ecx); | 1264 __ SmiTag(ecx); |
1261 | 1265 |
1262 // Check if we could survive without allocation, go to builtin otherwise. | 1266 // Check if we could survive without allocation, go to builtin otherwise. |
1263 __ cmp(eax, Operand(ecx)); | 1267 __ cmp(eax, Operand(ecx)); |
1264 __ j(greater, &call_builtin); | 1268 __ j(greater, &call_builtin); |
1265 | 1269 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1303 | 1307 |
1304 // Return the generated code. | 1308 // Return the generated code. |
1305 String* function_name = NULL; | 1309 String* function_name = NULL; |
1306 if (function->shared()->name()->IsString()) { | 1310 if (function->shared()->name()->IsString()) { |
1307 function_name = String::cast(function->shared()->name()); | 1311 function_name = String::cast(function->shared()->name()); |
1308 } | 1312 } |
1309 return GetCode(CONSTANT_FUNCTION, function_name); | 1313 return GetCode(CONSTANT_FUNCTION, function_name); |
1310 } | 1314 } |
1311 | 1315 |
1312 | 1316 |
| 1317 Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
| 1318 JSObject* holder, |
| 1319 JSFunction* function, |
| 1320 String* name, |
| 1321 CheckType check) { |
| 1322 // ----------- S t a t e ------------- |
| 1323 // -- ecx : name |
| 1324 // -- esp[0] : return address |
| 1325 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1326 // -- ... |
| 1327 // -- esp[(argc + 1) * 4] : receiver |
| 1328 // ----------------------------------- |
| 1329 ASSERT(check == RECEIVER_MAP_CHECK); |
| 1330 |
| 1331 Label miss, empty_array, call_builtin; |
| 1332 |
| 1333 // Get the receiver from the stack. |
| 1334 const int argc = arguments().immediate(); |
| 1335 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1336 |
| 1337 // Check that the receiver isn't a smi. |
| 1338 __ test(edx, Immediate(kSmiTagMask)); |
| 1339 __ j(zero, &miss); |
| 1340 |
| 1341 CheckPrototypes(JSObject::cast(object), edx, |
| 1342 holder, ebx, |
| 1343 eax, name, &miss); |
| 1344 |
| 1345 // Get the elements array of the object. |
| 1346 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); |
| 1347 |
| 1348 // Check that the elements are in fast mode (not dictionary). |
| 1349 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), |
| 1350 Immediate(Factory::fixed_array_map())); |
| 1351 __ j(not_equal, &miss); |
| 1352 |
| 1353 // Get the array's length into ecx and calculate new length. |
| 1354 __ mov(ecx, FieldOperand(edx, JSArray::kLengthOffset)); |
| 1355 __ sub(Operand(ecx), Immediate(Smi::FromInt(1))); |
| 1356 __ j(negative, &empty_array); |
| 1357 |
| 1358 // Get the last element. |
| 1359 STATIC_ASSERT(kSmiTagSize == 1); |
| 1360 STATIC_ASSERT(kSmiTag == 0); |
| 1361 __ mov(eax, FieldOperand(ebx, |
| 1362 ecx, times_half_pointer_size, |
| 1363 FixedArray::kHeaderSize)); |
| 1364 __ cmp(Operand(eax), Immediate(Factory::the_hole_value())); |
| 1365 __ j(equal, &call_builtin); |
| 1366 |
| 1367 // Set the array's length. |
| 1368 __ mov(FieldOperand(edx, JSArray::kLengthOffset), ecx); |
| 1369 |
| 1370 // Fill with the hole. |
| 1371 __ mov(FieldOperand(ebx, |
| 1372 ecx, times_half_pointer_size, |
| 1373 FixedArray::kHeaderSize), |
| 1374 Immediate(Factory::the_hole_value())); |
| 1375 __ ret((argc + 1) * kPointerSize); |
| 1376 |
| 1377 __ bind(&empty_array); |
| 1378 __ mov(eax, Immediate(Factory::undefined_value())); |
| 1379 __ ret((argc + 1) * kPointerSize); |
| 1380 |
| 1381 __ bind(&call_builtin); |
| 1382 |
| 1383 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), |
| 1384 argc + 1, |
| 1385 1); |
| 1386 |
| 1387 __ bind(&miss); |
| 1388 |
| 1389 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 1390 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 1391 |
| 1392 // Return the generated code. |
| 1393 String* function_name = NULL; |
| 1394 if (function->shared()->name()->IsString()) { |
| 1395 function_name = String::cast(function->shared()->name()); |
| 1396 } |
| 1397 return GetCode(CONSTANT_FUNCTION, function_name); |
| 1398 } |
| 1399 |
| 1400 |
1313 Object* CallStubCompiler::CompileCallConstant(Object* object, | 1401 Object* CallStubCompiler::CompileCallConstant(Object* object, |
1314 JSObject* holder, | 1402 JSObject* holder, |
1315 JSFunction* function, | 1403 JSFunction* function, |
1316 String* name, | 1404 String* name, |
1317 CheckType check) { | 1405 CheckType check) { |
1318 // ----------- S t a t e ------------- | 1406 // ----------- S t a t e ------------- |
1319 // -- ecx : name | 1407 // -- ecx : name |
1320 // -- esp[0] : return address | 1408 // -- esp[0] : return address |
1321 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1409 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1322 // -- ... | 1410 // -- ... |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2294 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 2382 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
2295 | 2383 |
2296 // Return the generated code. | 2384 // Return the generated code. |
2297 return GetCode(); | 2385 return GetCode(); |
2298 } | 2386 } |
2299 | 2387 |
2300 | 2388 |
2301 #undef __ | 2389 #undef __ |
2302 | 2390 |
2303 } } // namespace v8::internal | 2391 } } // namespace v8::internal |
OLD | NEW |