| 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 } | 1219 } |
| 1220 | 1220 |
| 1221 | 1221 |
| 1222 // Note: RBX must be preserved. | 1222 // Note: RBX must be preserved. |
| 1223 // Attempt a quick Smi operation for known operations ('kind'). The ICData | 1223 // Attempt a quick Smi operation for known operations ('kind'). The ICData |
| 1224 // must have been primed with a Smi/Smi check that will be used for counting | 1224 // must have been primed with a Smi/Smi check that will be used for counting |
| 1225 // the invocations. | 1225 // the invocations. |
| 1226 static void EmitFastSmiOp(Assembler* assembler, | 1226 static void EmitFastSmiOp(Assembler* assembler, |
| 1227 Token::Kind kind, | 1227 Token::Kind kind, |
| 1228 intptr_t num_args, | 1228 intptr_t num_args, |
| 1229 Label* not_smi_or_overflow, | 1229 Label* not_smi_or_overflow) { |
| 1230 bool should_update_result_range) { | |
| 1231 __ Comment("Fast Smi op"); | 1230 __ Comment("Fast Smi op"); |
| 1232 ASSERT(num_args == 2); | 1231 ASSERT(num_args == 2); |
| 1233 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Right | 1232 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Right |
| 1234 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left. | 1233 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left. |
| 1235 __ movq(R13, RCX); | 1234 __ movq(R13, RCX); |
| 1236 __ orq(R13, RAX); | 1235 __ orq(R13, RAX); |
| 1237 __ testq(R13, Immediate(kSmiTagMask)); | 1236 __ testq(R13, Immediate(kSmiTagMask)); |
| 1238 __ j(NOT_ZERO, not_smi_or_overflow); | 1237 __ j(NOT_ZERO, not_smi_or_overflow); |
| 1239 switch (kind) { | 1238 switch (kind) { |
| 1240 case Token::kADD: { | 1239 case Token::kADD: { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1254 __ LoadObject(RAX, Bool::False()); | 1253 __ LoadObject(RAX, Bool::False()); |
| 1255 __ jmp(&done, Assembler::kNearJump); | 1254 __ jmp(&done, Assembler::kNearJump); |
| 1256 __ Bind(&is_true); | 1255 __ Bind(&is_true); |
| 1257 __ LoadObject(RAX, Bool::True()); | 1256 __ LoadObject(RAX, Bool::True()); |
| 1258 __ Bind(&done); | 1257 __ Bind(&done); |
| 1259 break; | 1258 break; |
| 1260 } | 1259 } |
| 1261 default: UNIMPLEMENTED(); | 1260 default: UNIMPLEMENTED(); |
| 1262 } | 1261 } |
| 1263 | 1262 |
| 1264 | |
| 1265 if (should_update_result_range) { | |
| 1266 Label done; | |
| 1267 __ movq(RSI, RAX); | |
| 1268 __ UpdateRangeFeedback(RSI, 2, RBX, RCX, &done); | |
| 1269 __ Bind(&done); | |
| 1270 } | |
| 1271 | |
| 1272 // RBX: IC data object (preserved). | 1263 // RBX: IC data object (preserved). |
| 1273 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 1264 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
| 1274 // R13: ic_data_array with check entries: classes and target functions. | 1265 // R13: ic_data_array with check entries: classes and target functions. |
| 1275 __ leaq(R13, FieldAddress(R13, Array::data_offset())); | 1266 __ leaq(R13, FieldAddress(R13, Array::data_offset())); |
| 1276 // R13: points directly to the first ic data array element. | 1267 // R13: points directly to the first ic data array element. |
| 1277 #if defined(DEBUG) | 1268 #if defined(DEBUG) |
| 1278 // Check that first entry is for Smi/Smi. | 1269 // Check that first entry is for Smi/Smi. |
| 1279 Label error, ok; | 1270 Label error, ok; |
| 1280 const Immediate& imm_smi_cid = | 1271 const Immediate& imm_smi_cid = |
| 1281 Immediate(reinterpret_cast<intptr_t>(Smi::New(kSmiCid))); | 1272 Immediate(reinterpret_cast<intptr_t>(Smi::New(kSmiCid))); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1310 // - If receiver is Smi -> load Smi class. | 1301 // - If receiver is Smi -> load Smi class. |
| 1311 // - If receiver is not-Smi -> load receiver's class. | 1302 // - If receiver is not-Smi -> load receiver's class. |
| 1312 // - Check if 'num_args' (including receiver) match any IC data group. | 1303 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1313 // - Match found -> jump to target. | 1304 // - Match found -> jump to target. |
| 1314 // - Match not found -> jump to IC miss. | 1305 // - Match not found -> jump to IC miss. |
| 1315 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1306 void StubCode::GenerateNArgsCheckInlineCacheStub( |
| 1316 Assembler* assembler, | 1307 Assembler* assembler, |
| 1317 intptr_t num_args, | 1308 intptr_t num_args, |
| 1318 const RuntimeEntry& handle_ic_miss, | 1309 const RuntimeEntry& handle_ic_miss, |
| 1319 Token::Kind kind, | 1310 Token::Kind kind, |
| 1320 RangeCollectionMode range_collection_mode, | |
| 1321 bool optimized) { | 1311 bool optimized) { |
| 1322 ASSERT(num_args > 0); | 1312 ASSERT(num_args > 0); |
| 1323 #if defined(DEBUG) | 1313 #if defined(DEBUG) |
| 1324 { Label ok; | 1314 { Label ok; |
| 1325 // Check that the IC data array has NumArgsTested() == num_args. | 1315 // Check that the IC data array has NumArgsTested() == num_args. |
| 1326 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1316 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1327 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); | 1317 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); |
| 1328 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1318 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1329 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); | 1319 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); |
| 1330 __ cmpq(RCX, Immediate(num_args)); | 1320 __ cmpq(RCX, Immediate(num_args)); |
| 1331 __ j(EQUAL, &ok, Assembler::kNearJump); | 1321 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 1332 __ Stop("Incorrect stub for IC data"); | 1322 __ Stop("Incorrect stub for IC data"); |
| 1333 __ Bind(&ok); | 1323 __ Bind(&ok); |
| 1334 } | 1324 } |
| 1335 #endif // DEBUG | 1325 #endif // DEBUG |
| 1336 | 1326 |
| 1337 Label stepping, done_stepping; | 1327 Label stepping, done_stepping; |
| 1338 if (FLAG_support_debugger && !optimized) { | 1328 if (FLAG_support_debugger && !optimized) { |
| 1339 __ Comment("Check single stepping"); | 1329 __ Comment("Check single stepping"); |
| 1340 __ LoadIsolate(RAX); | 1330 __ LoadIsolate(RAX); |
| 1341 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); | 1331 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); |
| 1342 __ j(NOT_EQUAL, &stepping); | 1332 __ j(NOT_EQUAL, &stepping); |
| 1343 __ Bind(&done_stepping); | 1333 __ Bind(&done_stepping); |
| 1344 } | 1334 } |
| 1345 | 1335 |
| 1346 __ Comment("Range feedback collection"); | |
| 1347 Label not_smi_or_overflow; | 1336 Label not_smi_or_overflow; |
| 1348 if (range_collection_mode == kCollectRanges) { | |
| 1349 ASSERT((num_args == 1) || (num_args == 2)); | |
| 1350 if (num_args == 2) { | |
| 1351 __ movq(RAX, Address(RSP, + 2 * kWordSize)); | |
| 1352 __ UpdateRangeFeedback(RAX, 0, RBX, RCX, ¬_smi_or_overflow); | |
| 1353 } | |
| 1354 | |
| 1355 __ movq(RAX, Address(RSP, + 1 * kWordSize)); | |
| 1356 __ UpdateRangeFeedback(RAX, (num_args - 1), RBX, RCX, ¬_smi_or_overflow); | |
| 1357 } | |
| 1358 if (kind != Token::kILLEGAL) { | 1337 if (kind != Token::kILLEGAL) { |
| 1359 EmitFastSmiOp( | 1338 EmitFastSmiOp( |
| 1360 assembler, | 1339 assembler, |
| 1361 kind, | 1340 kind, |
| 1362 num_args, | 1341 num_args, |
| 1363 ¬_smi_or_overflow, | 1342 ¬_smi_or_overflow); |
| 1364 range_collection_mode == kCollectRanges); | |
| 1365 } | 1343 } |
| 1366 __ Bind(¬_smi_or_overflow); | 1344 __ Bind(¬_smi_or_overflow); |
| 1367 | 1345 |
| 1368 __ Comment("Extract ICData initial values and receiver cid"); | 1346 __ Comment("Extract ICData initial values and receiver cid"); |
| 1369 // Load arguments descriptor into R10. | 1347 // Load arguments descriptor into R10. |
| 1370 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 1348 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1371 // Loop that checks if there is an IC data match. | 1349 // Loop that checks if there is an IC data match. |
| 1372 Label loop, update, test, found; | 1350 Label loop, update, test, found; |
| 1373 // RBX: IC data object (preserved). | 1351 // RBX: IC data object (preserved). |
| 1374 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); | 1352 __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset())); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 __ addq(R8, Immediate(Smi::RawValue(1))); | 1445 __ addq(R8, Immediate(Smi::RawValue(1))); |
| 1468 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue))); | 1446 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1469 __ cmovnoq(R9, R8); | 1447 __ cmovnoq(R9, R8); |
| 1470 __ StoreIntoSmiField(Address(R13, count_offset), R9); | 1448 __ StoreIntoSmiField(Address(R13, count_offset), R9); |
| 1471 } | 1449 } |
| 1472 | 1450 |
| 1473 __ Comment("Call target"); | 1451 __ Comment("Call target"); |
| 1474 __ Bind(&call_target_function); | 1452 __ Bind(&call_target_function); |
| 1475 // RAX: Target function. | 1453 // RAX: Target function. |
| 1476 Label is_compiled; | 1454 Label is_compiled; |
| 1477 if (range_collection_mode == kCollectRanges) { | 1455 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); |
| 1478 __ movq(R13, FieldAddress(RAX, Function::code_offset())); | 1456 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
| 1479 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | 1457 __ jmp(RCX); |
| 1480 __ movq(R8, Address(RSP, + 1 * kWordSize)); | |
| 1481 if (num_args == 2) { | |
| 1482 __ movq(R9, Address(RSP, + 2 * kWordSize)); | |
| 1483 } | |
| 1484 __ EnterStubFrame(); | |
| 1485 __ pushq(RBX); | |
| 1486 if (num_args == 2) { | |
| 1487 __ pushq(R9); | |
| 1488 } | |
| 1489 __ pushq(R8); | |
| 1490 __ movq(CODE_REG, R13); | |
| 1491 __ call(RCX); | |
| 1492 | |
| 1493 Label done; | |
| 1494 __ movq(RDX, RAX); | |
| 1495 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); | |
| 1496 __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done); | |
| 1497 __ Bind(&done); | |
| 1498 __ LeaveStubFrame(); | |
| 1499 __ ret(); | |
| 1500 } else { | |
| 1501 __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset())); | |
| 1502 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); | |
| 1503 __ jmp(RCX); | |
| 1504 } | |
| 1505 | 1458 |
| 1506 if (FLAG_support_debugger && !optimized) { | 1459 if (FLAG_support_debugger && !optimized) { |
| 1507 __ Bind(&stepping); | 1460 __ Bind(&stepping); |
| 1508 __ EnterStubFrame(); | 1461 __ EnterStubFrame(); |
| 1509 __ pushq(RBX); | 1462 __ pushq(RBX); |
| 1510 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1463 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1511 __ popq(RBX); | 1464 __ popq(RBX); |
| 1512 __ RestoreCodePointer(); | 1465 __ RestoreCodePointer(); |
| 1513 __ LeaveStubFrame(); | 1466 __ LeaveStubFrame(); |
| 1514 __ jmp(&done_stepping); | 1467 __ jmp(&done_stepping); |
| 1515 } | 1468 } |
| 1516 } | 1469 } |
| 1517 | 1470 |
| 1518 | 1471 |
| 1519 // Use inline cache data array to invoke the target or continue in inline | 1472 // Use inline cache data array to invoke the target or continue in inline |
| 1520 // cache miss handler. Stub for 1-argument check (receiver class). | 1473 // cache miss handler. Stub for 1-argument check (receiver class). |
| 1521 // RBX: Inline cache data object. | 1474 // RBX: Inline cache data object. |
| 1522 // TOS(0): Return address. | 1475 // TOS(0): Return address. |
| 1523 // Inline cache data object structure: | 1476 // Inline cache data object structure: |
| 1524 // 0: function-name | 1477 // 0: function-name |
| 1525 // 1: N, number of arguments checked. | 1478 // 1: N, number of arguments checked. |
| 1526 // 2 .. (length - 1): group of checks, each check containing: | 1479 // 2 .. (length - 1): group of checks, each check containing: |
| 1527 // - N classes. | 1480 // - N classes. |
| 1528 // - 1 target function. | 1481 // - 1 target function. |
| 1529 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { | 1482 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) { |
| 1530 GenerateUsageCounterIncrement(assembler, RCX); | 1483 GenerateUsageCounterIncrement(assembler, RCX); |
| 1531 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1484 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1532 kInlineCacheMissHandlerOneArgRuntimeEntry, | 1485 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1533 Token::kILLEGAL, | 1486 Token::kILLEGAL); |
| 1534 kIgnoreRanges); | |
| 1535 } | 1487 } |
| 1536 | 1488 |
| 1537 | 1489 |
| 1538 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { | 1490 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { |
| 1539 GenerateUsageCounterIncrement(assembler, RCX); | 1491 GenerateUsageCounterIncrement(assembler, RCX); |
| 1540 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1492 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1541 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1493 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1542 Token::kILLEGAL, | 1494 Token::kILLEGAL); |
| 1543 kIgnoreRanges); | |
| 1544 } | 1495 } |
| 1545 | 1496 |
| 1546 | 1497 |
| 1547 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { | 1498 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) { |
| 1548 GenerateUsageCounterIncrement(assembler, RCX); | 1499 GenerateUsageCounterIncrement(assembler, RCX); |
| 1549 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1500 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1550 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1501 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1551 Token::kADD, | 1502 Token::kADD); |
| 1552 kCollectRanges); | |
| 1553 } | 1503 } |
| 1554 | 1504 |
| 1555 | 1505 |
| 1556 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { | 1506 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) { |
| 1557 GenerateUsageCounterIncrement(assembler, RCX); | 1507 GenerateUsageCounterIncrement(assembler, RCX); |
| 1558 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1508 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1559 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1509 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1560 Token::kSUB, | 1510 Token::kSUB); |
| 1561 kCollectRanges); | |
| 1562 } | 1511 } |
| 1563 | 1512 |
| 1564 | 1513 |
| 1565 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { | 1514 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) { |
| 1566 GenerateUsageCounterIncrement(assembler, RCX); | 1515 GenerateUsageCounterIncrement(assembler, RCX); |
| 1567 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1516 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1568 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1517 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1569 Token::kEQ, | 1518 Token::kEQ); |
| 1570 kIgnoreRanges); | |
| 1571 } | 1519 } |
| 1572 | 1520 |
| 1573 | 1521 |
| 1574 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( | 1522 void StubCode::GenerateUnaryRangeCollectingInlineCacheStub( |
| 1575 Assembler* assembler) { | 1523 Assembler* assembler) { |
| 1576 GenerateUsageCounterIncrement(assembler, RCX); | 1524 GenerateUsageCounterIncrement(assembler, RCX); |
| 1577 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1525 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1578 kInlineCacheMissHandlerOneArgRuntimeEntry, | 1526 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1579 Token::kILLEGAL, | 1527 Token::kILLEGAL); |
| 1580 kCollectRanges); | |
| 1581 } | 1528 } |
| 1582 | 1529 |
| 1583 | 1530 |
| 1584 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( | 1531 void StubCode::GenerateBinaryRangeCollectingInlineCacheStub( |
| 1585 Assembler* assembler) { | 1532 Assembler* assembler) { |
| 1586 GenerateUsageCounterIncrement(assembler, RCX); | 1533 GenerateUsageCounterIncrement(assembler, RCX); |
| 1587 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1534 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1588 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1535 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1589 Token::kILLEGAL, | 1536 Token::kILLEGAL); |
| 1590 kCollectRanges); | |
| 1591 } | 1537 } |
| 1592 | 1538 |
| 1593 | 1539 |
| 1594 // Use inline cache data array to invoke the target or continue in inline | 1540 // Use inline cache data array to invoke the target or continue in inline |
| 1595 // cache miss handler. Stub for 1-argument check (receiver class). | 1541 // cache miss handler. Stub for 1-argument check (receiver class). |
| 1596 // RDI: function which counter needs to be incremented. | 1542 // RDI: function which counter needs to be incremented. |
| 1597 // RBX: Inline cache data object. | 1543 // RBX: Inline cache data object. |
| 1598 // TOS(0): Return address. | 1544 // TOS(0): Return address. |
| 1599 // Inline cache data object structure: | 1545 // Inline cache data object structure: |
| 1600 // 0: function-name | 1546 // 0: function-name |
| 1601 // 1: N, number of arguments checked. | 1547 // 1: N, number of arguments checked. |
| 1602 // 2 .. (length - 1): group of checks, each check containing: | 1548 // 2 .. (length - 1): group of checks, each check containing: |
| 1603 // - N classes. | 1549 // - N classes. |
| 1604 // - 1 target function. | 1550 // - 1 target function. |
| 1605 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( | 1551 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( |
| 1606 Assembler* assembler) { | 1552 Assembler* assembler) { |
| 1607 GenerateOptimizedUsageCounterIncrement(assembler); | 1553 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1608 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1554 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1609 kInlineCacheMissHandlerOneArgRuntimeEntry, | 1555 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1610 Token::kILLEGAL, | 1556 Token::kILLEGAL, |
| 1611 kIgnoreRanges, true /* optimized */); | 1557 true /* optimized */); |
| 1612 } | 1558 } |
| 1613 | 1559 |
| 1614 | 1560 |
| 1615 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( | 1561 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( |
| 1616 Assembler* assembler) { | 1562 Assembler* assembler) { |
| 1617 GenerateOptimizedUsageCounterIncrement(assembler); | 1563 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1618 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1564 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1619 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1565 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1620 Token::kILLEGAL, | 1566 Token::kILLEGAL, |
| 1621 kIgnoreRanges, true /* optimized */); | 1567 true /* optimized */); |
| 1622 } | 1568 } |
| 1623 | 1569 |
| 1624 | 1570 |
| 1625 // Intermediary stub between a static call and its target. ICData contains | 1571 // Intermediary stub between a static call and its target. ICData contains |
| 1626 // the target function and the call count. | 1572 // the target function and the call count. |
| 1627 // RBX: ICData | 1573 // RBX: ICData |
| 1628 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1574 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1629 GenerateUsageCounterIncrement(assembler, RCX); | 1575 GenerateUsageCounterIncrement(assembler, RCX); |
| 1630 #if defined(DEBUG) | 1576 #if defined(DEBUG) |
| 1631 { Label ok; | 1577 { Label ok; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1694 } | 1640 } |
| 1695 } | 1641 } |
| 1696 | 1642 |
| 1697 | 1643 |
| 1698 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { | 1644 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1699 GenerateUsageCounterIncrement(assembler, RCX); | 1645 GenerateUsageCounterIncrement(assembler, RCX); |
| 1700 GenerateNArgsCheckInlineCacheStub( | 1646 GenerateNArgsCheckInlineCacheStub( |
| 1701 assembler, | 1647 assembler, |
| 1702 1, | 1648 1, |
| 1703 kStaticCallMissHandlerOneArgRuntimeEntry, | 1649 kStaticCallMissHandlerOneArgRuntimeEntry, |
| 1704 Token::kILLEGAL, | 1650 Token::kILLEGAL); |
| 1705 kIgnoreRanges); | |
| 1706 } | 1651 } |
| 1707 | 1652 |
| 1708 | 1653 |
| 1709 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1654 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1710 GenerateUsageCounterIncrement(assembler, RCX); | 1655 GenerateUsageCounterIncrement(assembler, RCX); |
| 1711 GenerateNArgsCheckInlineCacheStub(assembler, | 1656 GenerateNArgsCheckInlineCacheStub(assembler, |
| 1712 2, | 1657 2, |
| 1713 kStaticCallMissHandlerTwoArgsRuntimeEntry, | 1658 kStaticCallMissHandlerTwoArgsRuntimeEntry, |
| 1714 Token::kILLEGAL, | 1659 Token::kILLEGAL); |
| 1715 kIgnoreRanges); | |
| 1716 } | 1660 } |
| 1717 | 1661 |
| 1718 | 1662 |
| 1719 // Stub for compiling a function and jumping to the compiled code. | 1663 // Stub for compiling a function and jumping to the compiled code. |
| 1720 // RCX: IC-Data (for methods). | 1664 // RCX: IC-Data (for methods). |
| 1721 // R10: Arguments descriptor. | 1665 // R10: Arguments descriptor. |
| 1722 // RAX: Function. | 1666 // RAX: Function. |
| 1723 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { | 1667 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { |
| 1724 __ EnterStubFrame(); | 1668 __ EnterStubFrame(); |
| 1725 __ pushq(R10); // Preserve arguments descriptor array. | 1669 __ pushq(R10); // Preserve arguments descriptor array. |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2238 } | 2182 } |
| 2239 | 2183 |
| 2240 | 2184 |
| 2241 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { | 2185 void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) { |
| 2242 __ int3(); | 2186 __ int3(); |
| 2243 } | 2187 } |
| 2244 | 2188 |
| 2245 } // namespace dart | 2189 } // namespace dart |
| 2246 | 2190 |
| 2247 #endif // defined TARGET_ARCH_X64 | 2191 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |