Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 10581006: Replace class with class ids inside ICData (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 // ECX: Inline cache data object. 1545 // ECX: Inline cache data object.
1546 // EDX: Arguments descriptor array. 1546 // EDX: Arguments descriptor array.
1547 // TOS(0): return address 1547 // TOS(0): return address
1548 // Control flow: 1548 // Control flow:
1549 // - If receiver is null -> jump to IC miss. 1549 // - If receiver is null -> jump to IC miss.
1550 // - If receiver is Smi -> load Smi class. 1550 // - If receiver is Smi -> load Smi class.
1551 // - If receiver is not-Smi -> load receiver's class. 1551 // - If receiver is not-Smi -> load receiver's class.
1552 // - Check if 'num_args' (including receiver) match any IC data group. 1552 // - Check if 'num_args' (including receiver) match any IC data group.
1553 // - Match found -> jump to target. 1553 // - Match found -> jump to target.
1554 // - Match not found -> jump to IC miss. 1554 // - Match not found -> jump to IC miss.
1555 // TODO(srdjan): Change IC data to keep class ids as integers not as Smi-s.
1555 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1556 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1556 intptr_t num_args) { 1557 intptr_t num_args) {
1557 const Immediate raw_null = 1558 const Immediate raw_null =
1558 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1559 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1559 1560
1560 __ movl(EBX, FieldAddress(ECX, ICData::function_offset())); 1561 __ movl(EBX, FieldAddress(ECX, ICData::function_offset()));
1561 __ incl(FieldAddress(EBX, Function::usage_counter_offset())); 1562 __ incl(FieldAddress(EBX, Function::usage_counter_offset()));
1562 if (CodeGenerator::CanOptimize()) { 1563 if (CodeGenerator::CanOptimize()) {
1563 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()), 1564 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()),
1564 Immediate(FLAG_optimization_counter_threshold)); 1565 Immediate(FLAG_optimization_counter_threshold));
(...skipping 12 matching lines...) Expand all
1577 __ LeaveFrame(); 1578 __ LeaveFrame();
1578 __ Bind(&not_yet_hot); 1579 __ Bind(&not_yet_hot);
1579 } 1580 }
1580 1581
1581 ASSERT(num_args > 0); 1582 ASSERT(num_args > 0);
1582 // Get receiver (first read number of arguments from argument descriptor array 1583 // Get receiver (first read number of arguments from argument descriptor array
1583 // and then access the receiver from the stack). 1584 // and then access the receiver from the stack).
1584 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1585 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1585 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi. 1586 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi.
1586 1587
1587 Label get_class, ic_miss; 1588 Label get_class_id_as_smi, ic_miss;
1588 // ECX: IC data array. 1589 // ECX: IC data array.
1589 1590
1590 #if defined(DEBUG) 1591 #if defined(DEBUG)
1591 { Label ok; 1592 { Label ok;
1592 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1593 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1593 // 'num_args_tested' is stored as an untagged int. 1594 // 'num_args_tested' is stored as an untagged int.
1594 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1595 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1595 __ cmpl(EBX, Immediate(num_args)); 1596 __ cmpl(EBX, Immediate(num_args));
1596 __ j(EQUAL, &ok, Assembler::kNearJump); 1597 __ j(EQUAL, &ok, Assembler::kNearJump);
1597 __ Stop("Incorrect stub for IC data"); 1598 __ Stop("Incorrect stub for IC data");
1598 __ Bind(&ok); 1599 __ Bind(&ok);
1599 } 1600 }
1600 #endif // DEBUG 1601 #endif // DEBUG
1601 1602
1602 // Loop that checks if there is an IC data match. 1603 // Loop that checks if there is an IC data match.
1603 // ECX: IC data object (preserved). 1604 // ECX: IC data object (preserved).
1604 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1605 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1605 // EBX: ic_data_array with check entries: classes and target functions. 1606 // EBX: ic_data_array with check entries: classes and target functions.
1606 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1607 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1607 // EBX: points directly to the first ic data array element. 1608 // EBX: points directly to the first ic data array element.
1608 Label loop, found; 1609 Label loop, found;
1609 if (num_args == 1) { 1610 if (num_args == 1) {
1610 __ call(&get_class); 1611 __ call(&get_class_id_as_smi);
1611 // EAX: receiver's class 1612 // EAX: receiver's class id Smi.
1612 __ Bind(&loop); 1613 __ Bind(&loop);
1613 __ movl(EDI, Address(EBX, 0)); // Get class to check. 1614 __ movl(EDI, Address(EBX, 0)); // Get class id (Smi) to check.
1614 __ cmpl(EAX, EDI); // Match? 1615 __ cmpl(EAX, EDI); // Class id match?
1615 __ j(EQUAL, &found, Assembler::kNearJump); 1616 __ j(EQUAL, &found, Assembler::kNearJump);
1616 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). 1617 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target).
1617 __ cmpl(EDI, raw_null); // Done? 1618 __ cmpl(EDI, raw_null); // Done?
1618 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1619 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1619 } else if (num_args == 2) { 1620 } else if (num_args == 2) {
1620 // EDI: class to check. 1621 // EDI: class to check.
1621 Label no_match; 1622 Label no_match;
1622 __ Bind(&loop); 1623 __ Bind(&loop);
1623 // Get class from IC data to check. 1624 // Get class id from IC data to check.
1624 // Get receiver using argument descriptor in EDX. 1625 // Get receiver using argument descriptor in EDX.
1625 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1626 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1626 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi. 1627 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi.
1627 __ call(&get_class); 1628 __ call(&get_class_id_as_smi);
1628 // TODO(vegorov): switch IC data to store class index instead of class.
1629 __ movl(EDI, Address(EBX, 0)); 1629 __ movl(EDI, Address(EBX, 0));
1630 __ cmpl(EAX, EDI); // Match? 1630 __ cmpl(EAX, EDI); // Class id match?
1631 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); 1631 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
1632 // Check second class/argument. 1632 // Check second class/argument.
1633 // Get class from IC data to check. 1633 // Get class id from IC data to check.
1634 // Get next argument. 1634 // Get next argument.
1635 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1635 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1636 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); 1636 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize));
1637 // EAX (argument count) is Smi. 1637 // EAX (argument count) is Smi.
1638 __ call(&get_class); 1638 __ call(&get_class_id_as_smi);
1639 __ movl(EDI, Address(EBX, kWordSize)); 1639 __ movl(EDI, Address(EBX, kWordSize));
1640 __ cmpl(EAX, EDI); // Match? 1640 __ cmpl(EAX, EDI); // Class id match?
1641 __ j(EQUAL, &found, Assembler::kNearJump); 1641 __ j(EQUAL, &found, Assembler::kNearJump);
1642 __ Bind(&no_match); 1642 __ Bind(&no_match);
1643 // Each test entry has (1 + num_args) array elements. 1643 // Each test entry has (1 + num_args) array elements.
1644 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. 1644 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element.
1645 __ cmpl(EDI, raw_null); // Done? 1645 __ cmpl(EDI, raw_null); // Done?
1646 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1646 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1647 } 1647 }
1648 1648
1649 __ Bind(&ic_miss); 1649 __ Bind(&ic_miss);
1650 // Compute address of arguments (first read number of arguments from argument 1650 // Compute address of arguments (first read number of arguments from argument
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 // EBX: Pointer to an IC data check group (classes + target) 1687 // EBX: Pointer to an IC data check group (classes + target)
1688 __ movl(EAX, Address(EBX, kWordSize * num_args)); // Target function. 1688 __ movl(EAX, Address(EBX, kWordSize * num_args)); // Target function.
1689 1689
1690 __ Bind(&call_target_function); 1690 __ Bind(&call_target_function);
1691 // EAX: Target function. 1691 // EAX: Target function.
1692 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); 1692 __ movl(EAX, FieldAddress(EAX, Function::code_offset()));
1693 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); 1693 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset()));
1694 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1694 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1695 __ jmp(EAX); 1695 __ jmp(EAX);
1696 1696
1697 __ Bind(&get_class); 1697 __ Bind(&get_class_id_as_smi);
1698 Label not_smi; 1698 Label not_smi;
1699 // Test if Smi -> load Smi class for comparison. 1699 // Test if Smi -> load Smi class for comparison.
1700 __ testl(EAX, Immediate(kSmiTagMask)); 1700 __ testl(EAX, Immediate(kSmiTagMask));
1701 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 1701 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1702 const Class& smi_class = 1702 __ movl(EAX, Immediate(Smi::RawValue(kSmi)));
1703 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class());
1704 __ LoadObject(EAX, smi_class);
1705 __ ret(); 1703 __ ret();
1706 1704
1707 __ Bind(&not_smi); 1705 __ Bind(&not_smi);
1708 __ LoadClass(EAX, EAX, EDI); 1706 __ LoadClassId(EAX, EAX);
1707 __ SmiTag(EAX);
1709 __ ret(); 1708 __ ret();
1710 } 1709 }
1711 1710
1712 1711
1713 // Use inline cache data array to invoke the target or continue in inline 1712 // Use inline cache data array to invoke the target or continue in inline
1714 // cache miss handler. Stub for 1-argument check (receiver class). 1713 // cache miss handler. Stub for 1-argument check (receiver class).
1715 // ECX: Inline cache data array 1714 // ECX: Inline cache data array
1716 // EDX: Arguments array 1715 // EDX: Arguments array
1717 // TOS(0): return address 1716 // TOS(0): return address
1718 // Inline cache data array structure: 1717 // Inline cache data array structure:
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 // TOS + 2: instance. 1899 // TOS + 2: instance.
1901 // TOS + 3: cache array. 1900 // TOS + 3: cache array.
1902 // Result in ECX: null -> not found, otherwise result (true or false). 1901 // Result in ECX: null -> not found, otherwise result (true or false).
1903 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { 1902 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
1904 GenerateSubtypeNTestCacheStub(assembler, 3); 1903 GenerateSubtypeNTestCacheStub(assembler, 3);
1905 } 1904 }
1906 1905
1907 } // namespace dart 1906 } // namespace dart
1908 1907
1909 #endif // defined TARGET_ARCH_IA32 1908 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698