OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 case Token::kADD: { | 1201 case Token::kADD: { |
1202 __ addl(EAX, EDI); | 1202 __ addl(EAX, EDI); |
1203 __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); | 1203 __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); |
1204 break; | 1204 break; |
1205 } | 1205 } |
1206 case Token::kSUB: { | 1206 case Token::kSUB: { |
1207 __ subl(EAX, EDI); | 1207 __ subl(EAX, EDI); |
1208 __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); | 1208 __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); |
1209 break; | 1209 break; |
1210 } | 1210 } |
| 1211 case Token::kMUL: { |
| 1212 __ SmiUntag(EAX); |
| 1213 __ imull(EAX, EDI); |
| 1214 __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump); |
| 1215 break; |
| 1216 } |
1211 case Token::kEQ: { | 1217 case Token::kEQ: { |
1212 Label done, is_true; | 1218 Label done, is_true; |
1213 __ cmpl(EAX, EDI); | 1219 __ cmpl(EAX, EDI); |
1214 __ j(EQUAL, &is_true, Assembler::kNearJump); | 1220 __ j(EQUAL, &is_true, Assembler::kNearJump); |
1215 __ LoadObject(EAX, Bool::False()); | 1221 __ LoadObject(EAX, Bool::False()); |
1216 __ jmp(&done, Assembler::kNearJump); | 1222 __ jmp(&done, Assembler::kNearJump); |
1217 __ Bind(&is_true); | 1223 __ Bind(&is_true); |
1218 __ LoadObject(EAX, Bool::True()); | 1224 __ LoadObject(EAX, Bool::True()); |
1219 __ Bind(&done); | 1225 __ Bind(&done); |
1220 break; | 1226 break; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 // - If receiver is null -> jump to IC miss. | 1264 // - If receiver is null -> jump to IC miss. |
1259 // - If receiver is Smi -> load Smi class. | 1265 // - If receiver is Smi -> load Smi class. |
1260 // - If receiver is not-Smi -> load receiver's class. | 1266 // - If receiver is not-Smi -> load receiver's class. |
1261 // - Check if 'num_args' (including receiver) match any IC data group. | 1267 // - Check if 'num_args' (including receiver) match any IC data group. |
1262 // - Match found -> jump to target. | 1268 // - Match found -> jump to target. |
1263 // - Match not found -> jump to IC miss. | 1269 // - Match not found -> jump to IC miss. |
1264 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1270 void StubCode::GenerateNArgsCheckInlineCacheStub( |
1265 Assembler* assembler, | 1271 Assembler* assembler, |
1266 intptr_t num_args, | 1272 intptr_t num_args, |
1267 const RuntimeEntry& handle_ic_miss, | 1273 const RuntimeEntry& handle_ic_miss, |
1268 Token::Kind kind) { | 1274 Token::Kind kind, |
| 1275 RangeCollectionMode range_collection_mode) { |
1269 ASSERT(num_args > 0); | 1276 ASSERT(num_args > 0); |
1270 #if defined(DEBUG) | 1277 #if defined(DEBUG) |
1271 { Label ok; | 1278 { Label ok; |
1272 // Check that the IC data array has NumArgsTested() == num_args. | 1279 // Check that the IC data array has NumArgsTested() == num_args. |
1273 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1280 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1274 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); | 1281 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
1275 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1282 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
1276 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); | 1283 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); |
1277 __ cmpl(EBX, Immediate(num_args)); | 1284 __ cmpl(EBX, Immediate(num_args)); |
1278 __ j(EQUAL, &ok, Assembler::kNearJump); | 1285 __ j(EQUAL, &ok, Assembler::kNearJump); |
1279 __ Stop("Incorrect stub for IC data"); | 1286 __ Stop("Incorrect stub for IC data"); |
1280 __ Bind(&ok); | 1287 __ Bind(&ok); |
1281 } | 1288 } |
1282 #endif // DEBUG | 1289 #endif // DEBUG |
1283 | 1290 |
1284 // Check single stepping. | 1291 // Check single stepping. |
1285 Label stepping, done_stepping; | 1292 Label stepping, done_stepping; |
1286 uword single_step_address = reinterpret_cast<uword>(Isolate::Current()) + | 1293 uword single_step_address = reinterpret_cast<uword>(Isolate::Current()) + |
1287 Isolate::single_step_offset(); | 1294 Isolate::single_step_offset(); |
1288 __ cmpb(Address::Absolute(single_step_address), Immediate(0)); | 1295 __ cmpb(Address::Absolute(single_step_address), Immediate(0)); |
1289 __ j(NOT_EQUAL, &stepping); | 1296 __ j(NOT_EQUAL, &stepping); |
1290 __ Bind(&done_stepping); | 1297 __ Bind(&done_stepping); |
1291 | 1298 |
| 1299 Label not_smi_or_overflow; |
| 1300 if (range_collection_mode == kCollectRanges) { |
| 1301 ASSERT((num_args == 1) || (num_args == 2)); |
| 1302 if (num_args == 2) { |
| 1303 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 1304 __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, ¬_smi_or_overflow); |
| 1305 } |
| 1306 |
| 1307 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 1308 __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI, |
| 1309 ¬_smi_or_overflow); |
| 1310 } |
1292 if (kind != Token::kILLEGAL) { | 1311 if (kind != Token::kILLEGAL) { |
1293 Label not_smi_or_overflow; | |
1294 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); | 1312 EmitFastSmiOp(assembler, kind, num_args, ¬_smi_or_overflow); |
1295 __ Bind(¬_smi_or_overflow); | |
1296 } | 1313 } |
| 1314 __ Bind(¬_smi_or_overflow); |
1297 | 1315 |
1298 // ECX: IC data object (preserved). | 1316 // ECX: IC data object (preserved). |
1299 // Load arguments descriptor into EDX. | 1317 // Load arguments descriptor into EDX. |
1300 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1318 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
1301 // Loop that checks if there is an IC data match. | 1319 // Loop that checks if there is an IC data match. |
1302 Label loop, update, test, found; | 1320 Label loop, update, test, found; |
1303 // ECX: IC data object (preserved). | 1321 // ECX: IC data object (preserved). |
1304 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); | 1322 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); |
1305 // EBX: ic_data_array with check entries: classes and target functions. | 1323 // EBX: ic_data_array with check entries: classes and target functions. |
1306 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); | 1324 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 __ addl(EAX, Immediate(Smi::RawValue(1))); | 1411 __ addl(EAX, Immediate(Smi::RawValue(1))); |
1394 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); | 1412 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); |
1395 __ cmovno(EDI, EAX); | 1413 __ cmovno(EDI, EAX); |
1396 __ StoreIntoSmiField(Address(EBX, count_offset), EDI); | 1414 __ StoreIntoSmiField(Address(EBX, count_offset), EDI); |
1397 | 1415 |
1398 __ movl(EAX, Address(EBX, target_offset)); | 1416 __ movl(EAX, Address(EBX, target_offset)); |
1399 __ Bind(&call_target_function); | 1417 __ Bind(&call_target_function); |
1400 // EAX: Target function. | 1418 // EAX: Target function. |
1401 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); | 1419 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); |
1402 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1420 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1403 __ jmp(EBX); | 1421 if (range_collection_mode == kCollectRanges) { |
1404 __ int3(); | 1422 __ movl(EDI, Address(ESP, + 1 * kWordSize)); |
| 1423 if (num_args == 2) { |
| 1424 __ movl(ESI, Address(ESP, + 2 * kWordSize)); |
| 1425 } |
| 1426 __ EnterStubFrame(); |
| 1427 __ pushl(ECX); |
| 1428 if (num_args == 2) { |
| 1429 __ pushl(ESI); |
| 1430 } |
| 1431 __ pushl(EDI); |
| 1432 __ call(EBX); |
| 1433 |
| 1434 __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize)); |
| 1435 Label done; |
| 1436 __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, ESI, &done); |
| 1437 __ Bind(&done); |
| 1438 __ LeaveFrame(); |
| 1439 __ ret(); |
| 1440 } else { |
| 1441 __ jmp(EBX); |
| 1442 } |
1405 | 1443 |
1406 __ Bind(&stepping); | 1444 __ Bind(&stepping); |
1407 __ EnterStubFrame(); | 1445 __ EnterStubFrame(); |
1408 __ pushl(ECX); | 1446 __ pushl(ECX); |
1409 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1447 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1410 __ popl(ECX); | 1448 __ popl(ECX); |
1411 __ LeaveFrame(); | 1449 __ LeaveFrame(); |
1412 __ jmp(&done_stepping); | 1450 __ jmp(&done_stepping); |
1413 } | 1451 } |
1414 | 1452 |
1415 | 1453 |
1416 // Use inline cache data array to invoke the target or continue in inline | 1454 // Use inline cache data array to invoke the target or continue in inline |
1417 // cache miss handler. Stub for 1-argument check (receiver class). | 1455 // cache miss handler. Stub for 1-argument check (receiver class). |
1418 // ECX: Inline cache data object. | 1456 // ECX: Inline cache data object. |
1419 // TOS(0): Return address. | 1457 // TOS(0): Return address. |
1420 // Inline cache data object structure: | 1458 // Inline cache data object structure: |
1421 // 0: function-name | 1459 // 0: function-name |
1422 // 1: N, number of arguments checked. | 1460 // 1: N, number of arguments checked. |
1423 // 2 .. (length - 1): group of checks, each check containing: | 1461 // 2 .. (length - 1): group of checks, each check containing: |
1424 // - N classes. | 1462 // - N classes. |
1425 // - 1 target function. | 1463 // - 1 target function. |
1426 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { | 1464 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { |
1427 GenerateUsageCounterIncrement(assembler, EBX); | 1465 GenerateUsageCounterIncrement(assembler, EBX); |
1428 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1466 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
1429 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1467 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1468 Token::kILLEGAL, |
| 1469 kIgnoreRanges); |
1430 } | 1470 } |
1431 | 1471 |
1432 | 1472 |
1433 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { | 1473 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { |
1434 GenerateUsageCounterIncrement(assembler, EBX); | 1474 GenerateUsageCounterIncrement(assembler, EBX); |
1435 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1475 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1436 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1476 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1477 Token::kILLEGAL, |
| 1478 kIgnoreRanges); |
1437 } | 1479 } |
1438 | 1480 |
1439 | 1481 |
1440 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { | 1482 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) { |
1441 GenerateUsageCounterIncrement(assembler, EBX); | 1483 GenerateUsageCounterIncrement(assembler, EBX); |
1442 GenerateNArgsCheckInlineCacheStub(assembler, 3, | 1484 GenerateNArgsCheckInlineCacheStub(assembler, 3, |
1443 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); | 1485 kInlineCacheMissHandlerThreeArgsRuntimeEntry, |
| 1486 Token::kILLEGAL, |
| 1487 kIgnoreRanges); |
1444 } | 1488 } |
1445 | 1489 |
1446 | 1490 |
1447 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { | 1491 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { |
1448 GenerateUsageCounterIncrement(assembler, EBX); | 1492 GenerateUsageCounterIncrement(assembler, EBX); |
1449 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1493 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1450 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD); | 1494 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1495 Token::kADD, |
| 1496 kCollectRanges); |
1451 } | 1497 } |
1452 | 1498 |
1453 | 1499 |
1454 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { | 1500 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { |
1455 GenerateUsageCounterIncrement(assembler, EBX); | 1501 GenerateUsageCounterIncrement(assembler, EBX); |
1456 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1502 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1457 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB); | 1503 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1504 Token::kSUB, |
| 1505 kCollectRanges); |
1458 } | 1506 } |
1459 | 1507 |
1460 | 1508 |
1461 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { | 1509 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { |
1462 GenerateUsageCounterIncrement(assembler, EBX); | 1510 GenerateUsageCounterIncrement(assembler, EBX); |
1463 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1511 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1464 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ); | 1512 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1513 Token::kEQ, |
| 1514 kIgnoreRanges); |
1465 } | 1515 } |
1466 | 1516 |
1467 | 1517 |
| 1518 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( |
| 1519 Assembler* assembler) { |
| 1520 GenerateUsageCounterIncrement(assembler, EBX); |
| 1521 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1522 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1523 Token::kILLEGAL, |
| 1524 kCollectRanges); |
| 1525 } |
| 1526 |
| 1527 |
| 1528 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( |
| 1529 Assembler* assembler) { |
| 1530 GenerateUsageCounterIncrement(assembler, EBX); |
| 1531 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1532 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1533 Token::kILLEGAL, |
| 1534 kCollectRanges); |
| 1535 } |
| 1536 |
| 1537 |
1468 // Use inline cache data array to invoke the target or continue in inline | 1538 // Use inline cache data array to invoke the target or continue in inline |
1469 // cache miss handler. Stub for 1-argument check (receiver class). | 1539 // cache miss handler. Stub for 1-argument check (receiver class). |
1470 // EDI: function which counter needs to be incremented. | 1540 // EDI: function which counter needs to be incremented. |
1471 // ECX: Inline cache data object. | 1541 // ECX: Inline cache data object. |
1472 // TOS(0): Return address. | 1542 // TOS(0): Return address. |
1473 // Inline cache data object structure: | 1543 // Inline cache data object structure: |
1474 // 0: function-name | 1544 // 0: function-name |
1475 // 1: N, number of arguments checked. | 1545 // 1: N, number of arguments checked. |
1476 // 2 .. (length - 1): group of checks, each check containing: | 1546 // 2 .. (length - 1): group of checks, each check containing: |
1477 // - N classes. | 1547 // - N classes. |
1478 // - 1 target function. | 1548 // - 1 target function. |
1479 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( | 1549 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( |
1480 Assembler* assembler) { | 1550 Assembler* assembler) { |
1481 GenerateOptimizedUsageCounterIncrement(assembler); | 1551 GenerateOptimizedUsageCounterIncrement(assembler); |
1482 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1552 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
1483 kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1553 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1554 Token::kILLEGAL, |
| 1555 kIgnoreRanges); |
1484 } | 1556 } |
1485 | 1557 |
1486 | 1558 |
1487 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( | 1559 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( |
1488 Assembler* assembler) { | 1560 Assembler* assembler) { |
1489 GenerateOptimizedUsageCounterIncrement(assembler); | 1561 GenerateOptimizedUsageCounterIncrement(assembler); |
1490 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1562 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1491 kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1563 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1564 Token::kILLEGAL, |
| 1565 kIgnoreRanges); |
1492 } | 1566 } |
1493 | 1567 |
1494 | 1568 |
1495 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( | 1569 void StubCode::GenerateThreeArgsOptimizedCheckInlineCacheStub( |
1496 Assembler* assembler) { | 1570 Assembler* assembler) { |
1497 GenerateOptimizedUsageCounterIncrement(assembler); | 1571 GenerateOptimizedUsageCounterIncrement(assembler); |
1498 GenerateNArgsCheckInlineCacheStub(assembler, 3, | 1572 GenerateNArgsCheckInlineCacheStub(assembler, 3, |
1499 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL); | 1573 kInlineCacheMissHandlerThreeArgsRuntimeEntry, |
| 1574 Token::kILLEGAL, |
| 1575 kIgnoreRanges); |
1500 } | 1576 } |
1501 | 1577 |
1502 | 1578 |
1503 // Intermediary stub between a static call and its target. ICData contains | 1579 // Intermediary stub between a static call and its target. ICData contains |
1504 // the target function and the call count. | 1580 // the target function and the call count. |
1505 // ECX: ICData | 1581 // ECX: ICData |
1506 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1582 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
1507 GenerateUsageCounterIncrement(assembler, EBX); | 1583 GenerateUsageCounterIncrement(assembler, EBX); |
1508 | 1584 |
1509 #if defined(DEBUG) | 1585 #if defined(DEBUG) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1559 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1635 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
1560 __ popl(ECX); | 1636 __ popl(ECX); |
1561 __ LeaveFrame(); | 1637 __ LeaveFrame(); |
1562 __ jmp(&done_stepping, Assembler::kNearJump); | 1638 __ jmp(&done_stepping, Assembler::kNearJump); |
1563 } | 1639 } |
1564 | 1640 |
1565 | 1641 |
1566 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { | 1642 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { |
1567 GenerateUsageCounterIncrement(assembler, EBX); | 1643 GenerateUsageCounterIncrement(assembler, EBX); |
1568 GenerateNArgsCheckInlineCacheStub( | 1644 GenerateNArgsCheckInlineCacheStub( |
1569 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL); | 1645 assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, |
| 1646 Token::kILLEGAL, |
| 1647 kIgnoreRanges); |
1570 } | 1648 } |
1571 | 1649 |
1572 | 1650 |
1573 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1651 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
1574 GenerateUsageCounterIncrement(assembler, EBX); | 1652 GenerateUsageCounterIncrement(assembler, EBX); |
1575 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1653 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
1576 kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL); | 1654 kStaticCallMissHandlerTwoArgsRuntimeEntry, |
| 1655 Token::kILLEGAL, |
| 1656 kIgnoreRanges); |
1577 } | 1657 } |
1578 | 1658 |
1579 | 1659 |
1580 // Stub for compiling a function and jumping to the compiled code. | 1660 // Stub for compiling a function and jumping to the compiled code. |
1581 // ECX: IC-Data (for methods). | 1661 // ECX: IC-Data (for methods). |
1582 // EDX: Arguments descriptor. | 1662 // EDX: Arguments descriptor. |
1583 // EAX: Function. | 1663 // EAX: Function. |
1584 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { | 1664 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
1585 __ EnterStubFrame(); | 1665 __ EnterStubFrame(); |
1586 __ pushl(EDX); // Preserve arguments descriptor array. | 1666 __ pushl(EDX); // Preserve arguments descriptor array. |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 const Register temp = ECX; | 2032 const Register temp = ECX; |
1953 __ movl(left, Address(ESP, 2 * kWordSize)); | 2033 __ movl(left, Address(ESP, 2 * kWordSize)); |
1954 __ movl(right, Address(ESP, 1 * kWordSize)); | 2034 __ movl(right, Address(ESP, 1 * kWordSize)); |
1955 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2035 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1956 __ ret(); | 2036 __ ret(); |
1957 } | 2037 } |
1958 | 2038 |
1959 } // namespace dart | 2039 } // namespace dart |
1960 | 2040 |
1961 #endif // defined TARGET_ARCH_IA32 | 2041 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |