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

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

Issue 9395016: First part of new ICData infrastructure: use a wrapper object instead of an array. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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
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/code_generator.h" 8 #include "vm/code_generator.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/ic_data.h"
11 #include "vm/object_store.h" 10 #include "vm/object_store.h"
12 #include "vm/pages.h" 11 #include "vm/pages.h"
13 #include "vm/resolver.h" 12 #include "vm/resolver.h"
14 #include "vm/scavenger.h" 13 #include "vm/scavenger.h"
15 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
16 15
17 16
18 #define __ assembler-> 17 #define __ assembler->
19 18
20 namespace dart { 19 namespace dart {
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // Iterate and search for identical name. 356 // Iterate and search for identical name.
358 __ leal(EBX, FieldAddress(EAX, Array::data_offset())); 357 __ leal(EBX, FieldAddress(EAX, Array::data_offset()));
359 358
360 // EBX is pointing into content of functions_map_ array. 359 // EBX is pointing into content of functions_map_ array.
361 __ Bind(&loop); 360 __ Bind(&loop);
362 __ movl(EDI, Address(EBX, FunctionsCache::kFunctionName * kWordSize)); 361 __ movl(EDI, Address(EBX, FunctionsCache::kFunctionName * kWordSize));
363 362
364 __ cmpl(EDI, raw_null); 363 __ cmpl(EDI, raw_null);
365 __ j(EQUAL, &not_found, Assembler::kNearJump); 364 __ j(EQUAL, &not_found, Assembler::kNearJump);
366 365
367 ASSERT(ICData::kNameIndex == 0); 366 __ cmpl(EDI, FieldAddress(ECX, ICData::target_name_offset()));
368 __ cmpl(EDI, FieldAddress(ECX, Array::data_offset()));
369 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 367 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
370 368
371 // Name found, check total argument count and named argument count. 369 // Name found, check total argument count and named argument count.
372 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 370 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
373 // EAX is total argument count as Smi. 371 // EAX is total argument count as Smi.
374 __ movl(EDI, Address(EBX, FunctionsCache::kArgCount * kWordSize)); 372 __ movl(EDI, Address(EBX, FunctionsCache::kArgCount * kWordSize));
375 __ cmpl(EAX, EDI); // Compare total argument counts. 373 __ cmpl(EAX, EDI); // Compare total argument counts.
376 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump); 374 __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
377 __ subl(EAX, FieldAddress(EDX, Array::data_offset() + kWordSize)); 375 __ subl(EAX, FieldAddress(EDX, Array::data_offset() + kWordSize));
378 // EAX is named argument count as Smi. 376 // EAX is named argument count as Smi.
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 __ popl(EAX); // Get result into EAX. 1527 __ popl(EAX); // Get result into EAX.
1530 1528
1531 // Remove the stub frame as we are about to return. 1529 // Remove the stub frame as we are about to return.
1532 __ LeaveFrame(); 1530 __ LeaveFrame();
1533 __ ret(); 1531 __ ret();
1534 } 1532 }
1535 1533
1536 1534
1537 1535
1538 // Generate inline cache check for 'num_args'. 1536 // Generate inline cache check for 'num_args'.
1539 // ECX: Inline cache data array. 1537 // ECX: Inline cache data object.
1540 // EDX: Arguments array. 1538 // EDX: Arguments array.
1541 // TOS(0): return address 1539 // TOS(0): return address
1542 // Control flow: 1540 // Control flow:
1543 // - If receiver is null -> jump to IC miss. 1541 // - If receiver is null -> jump to IC miss.
1544 // - If receiver is Smi -> load Smi class. 1542 // - If receiver is Smi -> load Smi class.
1545 // - If receiver is not-Smi -> load receiver's class. 1543 // - If receiver is not-Smi -> load receiver's class.
1546 // - Check if 'num_args' (including receiver) match any IC data group. 1544 // - Check if 'num_args' (including receiver) match any IC data group.
1547 // - Match found -> jump to target. 1545 // - Match found -> jump to target.
1548 // - Match not found -> jump to IC miss. 1546 // - Match not found -> jump to IC miss.
1549 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1547 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1550 intptr_t num_args) { 1548 intptr_t num_args) {
1551 ASSERT(num_args > 0); 1549 ASSERT(num_args > 0);
1552 // Get receiver. 1550 // Get receiver.
1553 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1551 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1554 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1552 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is Smi.
1555 1553
1556 Label get_class, ic_miss; 1554 Label get_class, ic_miss;
1557 __ call(&get_class); 1555 __ call(&get_class);
1558 // EAX: receiver's class 1556 // EAX: receiver's class
1559 // ECX: IC data array. 1557 // ECX: IC data array.
1560 1558
1561 #if defined(DEBUG) 1559 #if defined(DEBUG)
1562 { Label ok; 1560 { Label ok;
1563 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1561 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1564 __ movl(EBX, FieldAddress(ECX, 1562 // 'num_args_tested' is stored as an untagged int.
1565 Array::data_offset() + ICData::kNumArgsCheckedIndex * kWordSize)); 1563 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1566 const Immediate value = 1564 __ cmpl(EBX, Immediate(num_args));
1567 Immediate(reinterpret_cast<int32_t>(Smi::New(num_args)));
1568 __ cmpl(EBX, value);
1569 __ j(EQUAL, &ok, Assembler::kNearJump); 1565 __ j(EQUAL, &ok, Assembler::kNearJump);
1570 __ Stop("Incorrect stub for IC data"); 1566 __ Stop("Incorrect stub for IC data");
1571 __ Bind(&ok); 1567 __ Bind(&ok);
1572 } 1568 }
1573 #endif // DEBUG 1569 #endif // DEBUG
1574 1570
1575 // Loop that checks if there is an IC data match. 1571 // Loop that checks if there is an IC data match.
1576 // EAX: receiver's class. 1572 // EAX: receiver's class.
1577 // ECX: IC data array (preserved). 1573 // ECX: IC data object (preserved).
1578 __ leal(EBX, FieldAddress(ECX, 1574 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1579 Array::data_offset() + ICData::kChecksStartIndex * kWordSize)); 1575 // EBX: ic_data_array with check entries: classes and target functions.
1580 // EBX: pointing to a class to check against (into IC data array). 1576 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1577 // EBX: points directly to the first ic data array element.
1581 const Immediate raw_null = 1578 const Immediate raw_null =
1582 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1579 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1583 Label loop, found; 1580 Label loop, found;
1584 if (num_args == 1) { 1581 if (num_args == 1) {
1585 __ Bind(&loop); 1582 __ Bind(&loop);
1586 __ movl(EDI, Address(EBX, 0)); // Get class to check. 1583 __ movl(EDI, Address(EBX, 0)); // Get class to check.
1587 __ cmpl(EAX, EDI); // Match? 1584 __ cmpl(EAX, EDI); // Match?
1588 __ j(EQUAL, &found, Assembler::kNearJump); 1585 __ j(EQUAL, &found, Assembler::kNearJump);
1589 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). 1586 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target).
1590 __ cmpl(EDI, raw_null); // Done? 1587 __ cmpl(EDI, raw_null); // Done?
1591 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1588 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1592 } else if (num_args == 2) { 1589 } else if (num_args == 2) {
1590 // EDI: class to check.
1593 Label no_match; 1591 Label no_match;
1594 __ Bind(&loop); 1592 __ Bind(&loop);
1595 __ movl(EDI, Address(EBX, 0)); // Get class from IC data to check. 1593 // Get class from IC data to check.
1596 // Get receiver. 1594 __ movl(EDI, Address(EBX, 0));
1595 // Get receiver using argument descriptor in EDX.
1597 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1596 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1598 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1597 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi.
1599 __ call(&get_class); 1598 __ call(&get_class);
1600 __ cmpl(EAX, EDI); // Match? 1599 __ cmpl(EAX, EDI); // Match?
1601 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); 1600 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
1602 // Check second. 1601 // Check second class/argument.
1603 __ movl(EDI, Address(EBX, kWordSize)); // Get class from IC data to check. 1602 // Get class from IC data to check.
1603 __ movl(EDI, Address(EBX, kWordSize));
1604 // Get next argument. 1604 // Get next argument.
1605 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1605 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1606 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); // EAX is Smi. 1606 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize));
1607 // EAX (argument count) is Smi.
1607 __ call(&get_class); 1608 __ call(&get_class);
1608 __ cmpl(EAX, EDI); // Match? 1609 __ cmpl(EAX, EDI); // Match?
1609 __ j(EQUAL, &found, Assembler::kNearJump); 1610 __ j(EQUAL, &found, Assembler::kNearJump);
1610 __ Bind(&no_match); 1611 __ Bind(&no_match);
1612 // Each test entry has (1 + num_args) array elements.
1611 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. 1613 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element.
1612 __ cmpl(EDI, raw_null); // Done? 1614 __ cmpl(EDI, raw_null); // Done?
1613 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1615 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1614 } 1616 }
1615 1617
1616 __ Bind(&ic_miss); 1618 __ Bind(&ic_miss);
1617 // Get receiver, again. 1619 // Get receiver, again.
1618 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1620 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1619 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1621 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1620 __ EnterFrame(0); 1622 __ EnterFrame(0);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 __ popl(EDX); 1729 __ popl(EDX);
1728 __ popl(ECX); 1730 __ popl(ECX);
1729 __ LeaveFrame(); 1731 __ LeaveFrame();
1730 // Now call the dynamic function. 1732 // Now call the dynamic function.
1731 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1733 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1732 } 1734 }
1733 1735
1734 } // namespace dart 1736 } // namespace dart
1735 1737
1736 #endif // defined TARGET_ARCH_IA32 1738 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698