| 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 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); | 1502 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
| 1503 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1503 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1504 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); | 1504 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); |
| 1505 __ cmpl(EBX, Immediate(0)); | 1505 __ cmpl(EBX, Immediate(0)); |
| 1506 __ j(EQUAL, &ok, Assembler::kNearJump); | 1506 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 1507 __ Stop("Incorrect IC data for unoptimized static call"); | 1507 __ Stop("Incorrect IC data for unoptimized static call"); |
| 1508 __ Bind(&ok); | 1508 __ Bind(&ok); |
| 1509 } | 1509 } |
| 1510 #endif // DEBUG | 1510 #endif // DEBUG |
| 1511 // Check single stepping. | 1511 // Check single stepping. |
| 1512 Label not_stepping; | 1512 Label stepping, done_stepping; |
| 1513 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1513 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1514 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1514 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 1515 __ cmpl(EAX, Immediate(0)); | 1515 __ cmpl(EAX, Immediate(0)); |
| 1516 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1516 __ j(NOT_EQUAL, &stepping, Assembler::kNearJump); |
| 1517 | 1517 __ Bind(&done_stepping); |
| 1518 __ EnterStubFrame(); | |
| 1519 __ pushl(ECX); | |
| 1520 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | |
| 1521 __ popl(ECX); | |
| 1522 __ LeaveFrame(); | |
| 1523 __ Bind(¬_stepping); | |
| 1524 | 1518 |
| 1525 // ECX: IC data object (preserved). | 1519 // ECX: IC data object (preserved). |
| 1526 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); | 1520 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); |
| 1527 // EBX: ic_data_array with entries: target functions and count. | 1521 // EBX: ic_data_array with entries: target functions and count. |
| 1528 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); | 1522 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); |
| 1529 // EBX: points directly to the first ic data array element. | 1523 // EBX: points directly to the first ic data array element. |
| 1530 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; | 1524 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; |
| 1531 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; | 1525 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; |
| 1532 | 1526 |
| 1533 // Increment count for this call. | 1527 // Increment count for this call. |
| 1534 Label increment_done; | 1528 __ movl(EAX, Address(EBX, count_offset)); |
| 1535 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1))); | 1529 __ addl(EAX, Immediate(Smi::RawValue(1))); |
| 1536 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); | 1530 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1537 __ movl(Address(EBX, count_offset), Immediate(Smi::RawValue(Smi::kMaxValue))); | 1531 __ cmovno(EDI, EAX); |
| 1538 __ Bind(&increment_done); | 1532 __ movl(Address(EBX, count_offset), EDI); |
| 1539 | 1533 |
| 1540 // Load arguments descriptor into EDX. | 1534 // Load arguments descriptor into EDX. |
| 1541 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1535 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
| 1542 | 1536 |
| 1543 // Get function and call it, if possible. | 1537 // Get function and call it, if possible. |
| 1544 __ movl(EAX, Address(EBX, target_offset)); | 1538 __ movl(EAX, Address(EBX, target_offset)); |
| 1545 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); | 1539 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); |
| 1546 | 1540 |
| 1547 // EBX: Target instructions. | 1541 // EBX: Target instructions. |
| 1548 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1542 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1549 __ jmp(EBX); | 1543 __ jmp(EBX); |
| 1544 |
| 1545 __ Bind(&stepping); |
| 1546 __ EnterStubFrame(); |
| 1547 __ pushl(ECX); |
| 1548 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1549 __ popl(ECX); |
| 1550 __ LeaveFrame(); |
| 1551 __ jmp(&done_stepping, Assembler::kNearJump); |
| 1550 } | 1552 } |
| 1551 | 1553 |
| 1552 | 1554 |
| 1553 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1555 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1554 GenerateUsageCounterIncrement(assembler, EBX); | 1556 GenerateUsageCounterIncrement(assembler, EBX); |
| 1555 GenerateNArgsCheckInlineCacheStub( | 1557 GenerateNArgsCheckInlineCacheStub( |
| 1556 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); | 1558 assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry); |
| 1557 } | 1559 } |
| 1558 | 1560 |
| 1559 | 1561 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1628 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1630 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
| 1629 __ popl(EAX); // Address of original stub. | 1631 __ popl(EAX); // Address of original stub. |
| 1630 __ LeaveFrame(); | 1632 __ LeaveFrame(); |
| 1631 __ jmp(EAX); // Jump to original stub. | 1633 __ jmp(EAX); // Jump to original stub. |
| 1632 } | 1634 } |
| 1633 | 1635 |
| 1634 | 1636 |
| 1635 // Called only from unoptimized code. | 1637 // Called only from unoptimized code. |
| 1636 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { | 1638 void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) { |
| 1637 // Check single stepping. | 1639 // Check single stepping. |
| 1638 Label not_stepping; | 1640 Label stepping, done_stepping; |
| 1639 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1641 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1640 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1642 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 1641 __ cmpl(EAX, Immediate(0)); | 1643 __ cmpl(EAX, Immediate(0)); |
| 1642 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1644 __ j(NOT_EQUAL, &stepping, Assembler::kNearJump); |
| 1645 __ Bind(&done_stepping); |
| 1646 __ ret(); |
| 1643 | 1647 |
| 1648 __ Bind(&stepping); |
| 1644 __ EnterStubFrame(); | 1649 __ EnterStubFrame(); |
| 1645 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1650 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1646 __ LeaveFrame(); | 1651 __ LeaveFrame(); |
| 1647 __ Bind(¬_stepping); | 1652 __ jmp(&done_stepping, Assembler::kNearJump); |
| 1648 | |
| 1649 __ ret(); | |
| 1650 } | 1653 } |
| 1651 | 1654 |
| 1652 | 1655 |
| 1653 // Used to check class and type arguments. Arguments passed on stack: | 1656 // Used to check class and type arguments. Arguments passed on stack: |
| 1654 // TOS + 0: return address. | 1657 // TOS + 0: return address. |
| 1655 // TOS + 1: instantiator type arguments (can be NULL). | 1658 // TOS + 1: instantiator type arguments (can be NULL). |
| 1656 // TOS + 2: instance. | 1659 // TOS + 2: instance. |
| 1657 // TOS + 3: SubtypeTestCache. | 1660 // TOS + 3: SubtypeTestCache. |
| 1658 // Result in ECX: null -> not found, otherwise result (true or false). | 1661 // Result in ECX: null -> not found, otherwise result (true or false). |
| 1659 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1662 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 | 1892 |
| 1890 | 1893 |
| 1891 // Called only from unoptimized code. All relevant registers have been saved. | 1894 // Called only from unoptimized code. All relevant registers have been saved. |
| 1892 // TOS + 0: return address | 1895 // TOS + 0: return address |
| 1893 // TOS + 1: right argument. | 1896 // TOS + 1: right argument. |
| 1894 // TOS + 2: left argument. | 1897 // TOS + 2: left argument. |
| 1895 // Returns ZF set. | 1898 // Returns ZF set. |
| 1896 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( | 1899 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( |
| 1897 Assembler* assembler) { | 1900 Assembler* assembler) { |
| 1898 // Check single stepping. | 1901 // Check single stepping. |
| 1899 Label not_stepping; | 1902 Label stepping, done_stepping; |
| 1900 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1903 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
| 1901 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1904 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
| 1902 __ cmpl(EAX, Immediate(0)); | 1905 __ cmpl(EAX, Immediate(0)); |
| 1903 __ j(EQUAL, ¬_stepping, Assembler::kNearJump); | 1906 __ j(NOT_EQUAL, &stepping); |
| 1904 | 1907 __ Bind(&done_stepping); |
| 1905 __ EnterStubFrame(); | |
| 1906 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | |
| 1907 __ LeaveFrame(); | |
| 1908 __ Bind(¬_stepping); | |
| 1909 | 1908 |
| 1910 const Register left = EAX; | 1909 const Register left = EAX; |
| 1911 const Register right = EDX; | 1910 const Register right = EDX; |
| 1912 const Register temp = ECX; | 1911 const Register temp = ECX; |
| 1913 __ movl(left, Address(ESP, 2 * kWordSize)); | 1912 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 1914 __ movl(right, Address(ESP, 1 * kWordSize)); | 1913 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 1915 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1914 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1916 __ ret(); | 1915 __ ret(); |
| 1916 |
| 1917 __ Bind(&stepping); |
| 1918 __ EnterStubFrame(); |
| 1919 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1920 __ LeaveFrame(); |
| 1921 __ jmp(&done_stepping); |
| 1917 } | 1922 } |
| 1918 | 1923 |
| 1919 | 1924 |
| 1920 // Called from optimized code only. | 1925 // Called from optimized code only. |
| 1921 // TOS + 0: return address | 1926 // TOS + 0: return address |
| 1922 // TOS + 1: right argument. | 1927 // TOS + 1: right argument. |
| 1923 // TOS + 2: left argument. | 1928 // TOS + 2: left argument. |
| 1924 // Returns ZF set. | 1929 // Returns ZF set. |
| 1925 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( | 1930 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( |
| 1926 Assembler* assembler) { | 1931 Assembler* assembler) { |
| 1927 const Register left = EAX; | 1932 const Register left = EAX; |
| 1928 const Register right = EDX; | 1933 const Register right = EDX; |
| 1929 const Register temp = ECX; | 1934 const Register temp = ECX; |
| 1930 __ movl(left, Address(ESP, 2 * kWordSize)); | 1935 __ movl(left, Address(ESP, 2 * kWordSize)); |
| 1931 __ movl(right, Address(ESP, 1 * kWordSize)); | 1936 __ movl(right, Address(ESP, 1 * kWordSize)); |
| 1932 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1937 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1933 __ ret(); | 1938 __ ret(); |
| 1934 } | 1939 } |
| 1935 | 1940 |
| 1936 } // namespace dart | 1941 } // namespace dart |
| 1937 | 1942 |
| 1938 #endif // defined TARGET_ARCH_IA32 | 1943 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |