| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 | 1506 |
| 1507 // Remove the stub frame as we are about to return. | 1507 // Remove the stub frame as we are about to return. |
| 1508 __ LeaveFrame(); | 1508 __ LeaveFrame(); |
| 1509 __ ret(); | 1509 __ ret(); |
| 1510 } | 1510 } |
| 1511 | 1511 |
| 1512 | 1512 |
| 1513 | 1513 |
| 1514 // Generate inline cache check for 'num_args'. | 1514 // Generate inline cache check for 'num_args'. |
| 1515 // ECX: Inline cache data object. | 1515 // ECX: Inline cache data object. |
| 1516 // EDX: Arguments array. | 1516 // EDX: Arguments descriptor array. |
| 1517 // TOS(0): return address | 1517 // TOS(0): return address |
| 1518 // Control flow: | 1518 // Control flow: |
| 1519 // - If receiver is null -> jump to IC miss. | 1519 // - If receiver is null -> jump to IC miss. |
| 1520 // - If receiver is Smi -> load Smi class. | 1520 // - If receiver is Smi -> load Smi class. |
| 1521 // - If receiver is not-Smi -> load receiver's class. | 1521 // - If receiver is not-Smi -> load receiver's class. |
| 1522 // - Check if 'num_args' (including receiver) match any IC data group. | 1522 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1523 // - Match found -> jump to target. | 1523 // - Match found -> jump to target. |
| 1524 // - Match not found -> jump to IC miss. | 1524 // - Match not found -> jump to IC miss. |
| 1525 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1525 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
| 1526 intptr_t num_args) { | 1526 intptr_t num_args) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1537 __ pushl(EBX); // Argument for runtime: function object. | 1537 __ pushl(EBX); // Argument for runtime: function object. |
| 1538 __ CallRuntimeFromStub(kOptimizeInvokedFunctionRuntimeEntry); | 1538 __ CallRuntimeFromStub(kOptimizeInvokedFunctionRuntimeEntry); |
| 1539 __ popl(EBX); // Remove argument. | 1539 __ popl(EBX); // Remove argument. |
| 1540 __ popl(EDX); // Restore arguments array. | 1540 __ popl(EDX); // Restore arguments array. |
| 1541 __ popl(ECX); // Restore inline cache data object. | 1541 __ popl(ECX); // Restore inline cache data object. |
| 1542 __ LeaveFrame(); | 1542 __ LeaveFrame(); |
| 1543 __ Bind(¬_yet_hot); | 1543 __ Bind(¬_yet_hot); |
| 1544 } | 1544 } |
| 1545 | 1545 |
| 1546 ASSERT(num_args > 0); | 1546 ASSERT(num_args > 0); |
| 1547 // Get receiver. | 1547 // Get receiver (first read number of arguments from argument descriptor array |
| 1548 // and then access the receiver from the stack). |
| 1548 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1549 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
| 1549 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. | 1550 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. |
| 1550 | 1551 |
| 1551 Label get_class, ic_miss; | 1552 Label get_class, ic_miss; |
| 1552 __ call(&get_class); | 1553 __ call(&get_class); |
| 1553 // EAX: receiver's class | 1554 // EAX: receiver's class |
| 1554 // ECX: IC data array. | 1555 // ECX: IC data array. |
| 1555 | 1556 |
| 1556 #if defined(DEBUG) | 1557 #if defined(DEBUG) |
| 1557 { Label ok; | 1558 { Label ok; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1606 __ cmpl(EAX, EDI); // Match? | 1607 __ cmpl(EAX, EDI); // Match? |
| 1607 __ j(EQUAL, &found, Assembler::kNearJump); | 1608 __ j(EQUAL, &found, Assembler::kNearJump); |
| 1608 __ Bind(&no_match); | 1609 __ Bind(&no_match); |
| 1609 // Each test entry has (1 + num_args) array elements. | 1610 // Each test entry has (1 + num_args) array elements. |
| 1610 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. | 1611 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. |
| 1611 __ cmpl(EDI, raw_null); // Done? | 1612 __ cmpl(EDI, raw_null); // Done? |
| 1612 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1613 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 1613 } | 1614 } |
| 1614 | 1615 |
| 1615 __ Bind(&ic_miss); | 1616 __ Bind(&ic_miss); |
| 1616 // Get receiver, again. | 1617 // Compute address of arguments (first read number of arguments from argument |
| 1618 // descriptor array and then compute address on the stack). |
| 1617 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1619 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
| 1618 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. | 1620 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. |
| 1619 __ EnterFrame(0); | 1621 __ EnterFrame(0); |
| 1620 __ pushl(EDX); // Preserve arguments array. | 1622 __ pushl(EDX); // Preserve arguments array. |
| 1621 __ pushl(ECX); // Preserve IC data array | 1623 __ pushl(ECX); // Preserve IC data array |
| 1622 __ pushl(raw_null); // Setup space on stack for result (target code object). | 1624 __ pushl(raw_null); // Setup space on stack for result (target code object). |
| 1623 __ movl(EDX, FieldAddress(EDX, Array::data_offset())); | |
| 1624 // Push call arguments. | 1625 // Push call arguments. |
| 1625 for (intptr_t i = 0; i < num_args; i++) { | 1626 for (intptr_t i = 0; i < num_args; i++) { |
| 1626 __ movl(EDX, Address(EAX, -kWordSize * i)); | 1627 __ movl(EDX, Address(EAX, -kWordSize * i)); |
| 1627 __ pushl(EDX); | 1628 __ pushl(EDX); |
| 1628 } | 1629 } |
| 1629 if (num_args == 1) { | 1630 if (num_args == 1) { |
| 1630 __ CallRuntimeFromStub(kInlineCacheMissHandlerOneArgRuntimeEntry); | 1631 __ CallRuntimeFromStub(kInlineCacheMissHandlerOneArgRuntimeEntry); |
| 1631 } else if (num_args == 2) { | 1632 } else if (num_args == 2) { |
| 1632 __ CallRuntimeFromStub(kInlineCacheMissHandlerTwoArgsRuntimeEntry); | 1633 __ CallRuntimeFromStub(kInlineCacheMissHandlerTwoArgsRuntimeEntry); |
| 1633 } else { | 1634 } else { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1829 __ j(EQUAL, ¬_found, Assembler::kNearJump); | 1830 __ j(EQUAL, ¬_found, Assembler::kNearJump); |
| 1830 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); | 1831 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); |
| 1831 __ cmpl(EDX, ECX); | 1832 __ cmpl(EDX, ECX); |
| 1832 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); | 1833 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); |
| 1833 __ jmp(&found, Assembler::kNearJump); | 1834 __ jmp(&found, Assembler::kNearJump); |
| 1834 } | 1835 } |
| 1835 | 1836 |
| 1836 } // namespace dart | 1837 } // namespace dart |
| 1837 | 1838 |
| 1838 #endif // defined TARGET_ARCH_IA32 | 1839 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |