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

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

Issue 8984003: Port code generator to x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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/stack_frame_x64.cc ('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/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" 10 #include "vm/ic_data.h"
(...skipping 25 matching lines...) Expand all
36 const intptr_t argc_offset = NativeArguments::argc_offset(); 36 const intptr_t argc_offset = NativeArguments::argc_offset();
37 const intptr_t argv_offset = NativeArguments::argv_offset(); 37 const intptr_t argv_offset = NativeArguments::argv_offset();
38 const intptr_t retval_offset = NativeArguments::retval_offset(); 38 const intptr_t retval_offset = NativeArguments::retval_offset();
39 39
40 __ EnterFrame(0); 40 __ EnterFrame(0);
41 41
42 // Load current Isolate pointer from Context structure into EAX. 42 // Load current Isolate pointer from Context structure into EAX.
43 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 43 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
44 44
45 // Save exit frame information to enable stack walking as we are about 45 // Save exit frame information to enable stack walking as we are about
46 // to transition to dart VM code. 46 // to transition to Dart VM C++ code.
47 __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP); 47 __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP);
48 48
49 // Save current Context pointer into Isolate structure. 49 // Save current Context pointer into Isolate structure.
50 __ movl(Address(EAX, Isolate::top_context_offset()), CTX); 50 __ movl(Address(EAX, Isolate::top_context_offset()), CTX);
51 51
52 // Cache Isolate pointer into CTX while executing runtime code. 52 // Cache Isolate pointer into CTX while executing runtime code.
53 __ movl(CTX, EAX); 53 __ movl(CTX, EAX);
54 54
55 // Reserve space for arguments and align frame before entering C++ world. 55 // Reserve space for arguments and align frame before entering C++ world.
56 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments))); 56 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments)));
(...skipping 14 matching lines...) Expand all
71 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 71 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
72 72
73 // Load Context pointer from Isolate structure into ECX. 73 // Load Context pointer from Isolate structure into ECX.
74 __ movl(ECX, Address(CTX, Isolate::top_context_offset())); 74 __ movl(ECX, Address(CTX, Isolate::top_context_offset()));
75 75
76 // Reset Context pointer in Isolate structure. 76 // Reset Context pointer in Isolate structure.
77 const Immediate raw_null = 77 const Immediate raw_null =
78 Immediate(reinterpret_cast<intptr_t>(Object::null())); 78 Immediate(reinterpret_cast<intptr_t>(Object::null()));
79 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); 79 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
80 80
81 // Cache Context pointer into CTX while executing dart code. 81 // Cache Context pointer into CTX while executing Dart code.
82 __ movl(CTX, ECX); 82 __ movl(CTX, ECX);
83 83
84 __ LeaveFrame(); 84 __ LeaveFrame();
85 __ ret(); 85 __ ret();
86 } 86 }
87 87
88 88
89 // Input parameters: 89 // Input parameters:
90 // ESP : points to return address. 90 // ESP : points to return address.
91 // ESP + 4 : address of last argument in argument array. 91 // ESP + 4 : address of last argument in argument array.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 __ movl(CTX, EDI); 147 __ movl(CTX, EDI);
148 148
149 // Reserve space for the native arguments structure, the outgoing parameter 149 // Reserve space for the native arguments structure, the outgoing parameter
150 // (pointer to the native arguments structure) and align frame before 150 // (pointer to the native arguments structure) and align frame before
151 // entering the C++ world. 151 // entering the C++ world.
152 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments) - kWordSize)); 152 __ AddImmediate(ESP, Immediate(-sizeof(NativeArguments) - kWordSize));
153 if (OS::ActivationFrameAlignment() > 0) { 153 if (OS::ActivationFrameAlignment() > 0) {
154 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); 154 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
155 } 155 }
156 156
157 // Pass NativeArguments structure by value and call runtime. 157 // Pass NativeArguments structure by value and call native function.
158 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs. 158 __ movl(Address(ESP, isolate_offset), CTX); // Set isolate in NativeArgs.
159 __ movl(Address(ESP, argc_offset), EDX); // Set argc in NativeArguments. 159 __ movl(Address(ESP, argc_offset), EDX); // Set argc in NativeArguments.
160 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. 160 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments.
161 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. 161 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr.
162 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. 162 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments.
163 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. 163 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments.
164 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. 164 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments.
165 __ call(ECX); 165 __ call(ECX);
166 166
167 // Reset exit frame information in Isolate structure. 167 // Reset exit frame information in Isolate structure.
168 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 168 __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
169 169
170 // Load Context pointer from Isolate structure into EDI. 170 // Load Context pointer from Isolate structure into EDI.
171 __ movl(EDI, Address(CTX, Isolate::top_context_offset())); 171 __ movl(EDI, Address(CTX, Isolate::top_context_offset()));
172 172
173 // Reset Context pointer in Isolate structure. 173 // Reset Context pointer in Isolate structure.
174 const Immediate raw_null = 174 const Immediate raw_null =
175 Immediate(reinterpret_cast<intptr_t>(Object::null())); 175 Immediate(reinterpret_cast<intptr_t>(Object::null()));
176 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null); 176 __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
177 177
178 // Cache Context pointer into CTX while executing dart code. 178 // Cache Context pointer into CTX while executing Dart code.
179 __ movl(CTX, EDI); 179 __ movl(CTX, EDI);
180 180
181 __ LeaveFrame(); 181 __ LeaveFrame();
182 __ ret(); 182 __ ret();
183 } 183 }
184 184
185 185
186 // Input parameters: 186 // Input parameters:
187 // ECX: function object. 187 // ECX: function object.
188 // EDX: arguments descriptor array (num_args is first Smi element). 188 // EDX: arguments descriptor array (num_args is first Smi element).
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 __ LeaveFrame(); 595 __ LeaveFrame();
596 __ ret(); 596 __ ret();
597 } 597 }
598 598
599 599
600 // Called for inline allocation of arrays. 600 // Called for inline allocation of arrays.
601 // Input parameters: 601 // Input parameters:
602 // EDX : Array length as Smi. 602 // EDX : Array length as Smi.
603 // ECX : array element type (either NULL or an instantiated type). 603 // ECX : array element type (either NULL or an instantiated type).
604 // Uses EAX, EBX, ECX, EDI as temporary registers. 604 // Uses EAX, EBX, ECX, EDI as temporary registers.
605 // NOTE: EDX cannot be cloberred here as the caller relies on it 605 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved.
606 // being saved.
607 // The newly allocated object is returned in EAX. 606 // The newly allocated object is returned in EAX.
608 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { 607 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
609 Label slow_case; 608 Label slow_case;
610 const Immediate raw_null = 609 const Immediate raw_null =
611 Immediate(reinterpret_cast<intptr_t>(Object::null())); 610 Immediate(reinterpret_cast<intptr_t>(Object::null()));
612 611
613 if (FLAG_inline_alloc) { 612 if (FLAG_inline_alloc) {
614 // Compute the size to be allocated, it is based on the array length 613 // Compute the size to be allocated, it is based on the array length
615 // and it computed as: 614 // and it computed as:
616 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 615 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
617 // Assert that length is a Smi. 616 // Assert that length is a Smi.
618 __ testl(EDX, Immediate(kSmiTagSize)); 617 __ testl(EDX, Immediate(kSmiTagSize));
619 if (FLAG_use_slow_path) { 618 if (FLAG_use_slow_path) {
620 __ jmp(&slow_case); 619 __ jmp(&slow_case);
621 } else { 620 } else {
622 __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); 621 __ j(NOT_ZERO, &slow_case, Assembler::kNearJump);
623 } 622 }
624 __ movl(EDI, FieldAddress(CTX, Context::isolate_offset())); 623 __ movl(EDI, FieldAddress(CTX, Context::isolate_offset()));
625 __ movl(EDI, Address(EDI, Isolate::heap_offset())); 624 __ movl(EDI, Address(EDI, Isolate::heap_offset()));
626 __ movl(EDI, Address(EDI, Heap::new_space_offset())); 625 __ movl(EDI, Address(EDI, Heap::new_space_offset()));
627 626
628 // Calculate and align allocation size. 627 // Calculate and align allocation size.
629 // Load new object start and calculate next object start. 628 // Load new object start and calculate next object start.
630 // ECX: array element type. 629 // ECX: array element type.
631 // EDX: Array length as Smi. 630 // EDX: Array length as Smi.
632 // EDI: Points to new space object. 631 // EDI: Points to new space object.
633 __ movl(EAX, Address(EDI, Scavenger::top_offset())); 632 __ movl(EAX, Address(EDI, Scavenger::top_offset()));
634 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 633 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
635 __ leal(EBX, Address(EDX, TIMES_2, fixed_size)); 634 __ leal(EBX, Address(EDX, TIMES_2, fixed_size)); // EDX is Smi.
636 ASSERT(kSmiTagShift == 1); 635 ASSERT(kSmiTagShift == 1);
637 __ andl(EBX, Immediate(-kObjectAlignment)); 636 __ andl(EBX, Immediate(-kObjectAlignment));
638 __ leal(EBX, Address(EAX, EBX, TIMES_1, 0)); 637 __ leal(EBX, Address(EAX, EBX, TIMES_1, 0));
639 638
640 // Check if the allocation fits into the remaining space. 639 // Check if the allocation fits into the remaining space.
641 // EAX: potential new object start. 640 // EAX: potential new object start.
642 // EBX: potential next object start. 641 // EBX: potential next object start.
643 // ECX: array element type. 642 // ECX: array element type.
644 // EDX: Array length as Smi. 643 // EDX: Array length as Smi.
645 // EDI: Points to new space object. 644 // EDI: Points to new space object.
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 // - If receiver is Smi -> load Smi class. 1449 // - If receiver is Smi -> load Smi class.
1451 // - If receiver is not-Smi -> load receiver's class. 1450 // - If receiver is not-Smi -> load receiver's class.
1452 // - Check if 'num_args' (including receiver) match any IC data group. 1451 // - Check if 'num_args' (including receiver) match any IC data group.
1453 // - Match found -> jump to target. 1452 // - Match found -> jump to target.
1454 // - Match not found -> jump to IC miss. 1453 // - Match not found -> jump to IC miss.
1455 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, 1454 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler,
1456 intptr_t num_args) { 1455 intptr_t num_args) {
1457 ASSERT(num_args > 0); 1456 ASSERT(num_args > 0);
1458 // Get receiver. 1457 // Get receiver.
1459 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1458 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1460 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); 1459 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1461 1460
1462 Label get_class, ic_miss; 1461 Label get_class, ic_miss;
1463 __ call(&get_class); 1462 __ call(&get_class);
1464 // EAX: receiver's class 1463 // EAX: receiver's class
1465 // ECX: IC data array. 1464 // ECX: IC data array.
1466 1465
1467 #if defined(DEBUG) 1466 #if defined(DEBUG)
1468 { Label ok; 1467 { Label ok;
1469 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. 1468 // Check that the IC data array has NumberOfArgumentsChecked() == num_args.
1470 __ movl(EBX, FieldAddress(ECX, 1469 __ movl(EBX, FieldAddress(ECX,
(...skipping 23 matching lines...) Expand all
1494 __ j(EQUAL, &found, Assembler::kNearJump); 1493 __ j(EQUAL, &found, Assembler::kNearJump);
1495 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). 1494 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target).
1496 __ cmpl(EDI, raw_null); // Done? 1495 __ cmpl(EDI, raw_null); // Done?
1497 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1496 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1498 } else if (num_args == 2) { 1497 } else if (num_args == 2) {
1499 Label no_match; 1498 Label no_match;
1500 __ Bind(&loop); 1499 __ Bind(&loop);
1501 __ movl(EDI, Address(EBX, 0)); // Get class from IC data to check. 1500 __ movl(EDI, Address(EBX, 0)); // Get class from IC data to check.
1502 // Get receiver. 1501 // Get receiver.
1503 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1502 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1504 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); 1503 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1505 __ call(&get_class); 1504 __ call(&get_class);
1506 __ cmpl(EAX, EDI); // Match? 1505 __ cmpl(EAX, EDI); // Match?
1507 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); 1506 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump);
1508 // Check second. 1507 // Check second.
1509 __ movl(EDI, Address(EBX, kWordSize)); // Get class from IC data to check. 1508 __ movl(EDI, Address(EBX, kWordSize)); // Get class from IC data to check.
1510 // Get next argument. 1509 // Get next argument.
1511 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1510 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1512 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); 1511 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); // EAX is Smi.
1513 __ call(&get_class); 1512 __ call(&get_class);
1514 __ cmpl(EAX, EDI); // Match? 1513 __ cmpl(EAX, EDI); // Match?
1515 __ j(EQUAL, &found, Assembler::kNearJump); 1514 __ j(EQUAL, &found, Assembler::kNearJump);
1516 __ Bind(&no_match); 1515 __ Bind(&no_match);
1517 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. 1516 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element.
1518 __ cmpl(EDI, raw_null); // Done? 1517 __ cmpl(EDI, raw_null); // Done?
1519 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1518 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1520 } 1519 }
1521 1520
1522 __ Bind(&ic_miss); 1521 __ Bind(&ic_miss);
1523 // Get receiver, again. 1522 // Get receiver, again.
1524 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 1523 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
1525 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); 1524 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1526 __ EnterFrame(0); 1525 __ EnterFrame(0);
1527 // Setup space for return value on stack by pushing smi 0. 1526 // Setup space for return value on stack by pushing smi 0.
1528 __ pushl(EDX); // Preserve arguments array. 1527 __ pushl(EDX); // Preserve arguments array.
1529 __ pushl(ECX); // Preserve IC data array 1528 __ pushl(ECX); // Preserve IC data array
1530 __ pushl(Immediate(0)); // Space for result (target code object). 1529 __ pushl(Immediate(0)); // Space for result (target code object).
1531 __ movl(EDX, FieldAddress(EDX, Array::data_offset())); 1530 __ movl(EDX, FieldAddress(EDX, Array::data_offset()));
1532 // Push call arguments. 1531 // Push call arguments.
1533 for (intptr_t i = 0; i < num_args; i++) { 1532 for (intptr_t i = 0; i < num_args; i++) {
1534 __ movl(EDX, Address(EAX, -kWordSize * i)); 1533 __ movl(EDX, Address(EAX, -kWordSize * i));
1535 __ pushl(EDX); 1534 __ pushl(EDX);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 __ popl(EDX); 1633 __ popl(EDX);
1635 __ popl(ECX); 1634 __ popl(ECX);
1636 __ LeaveFrame(); 1635 __ LeaveFrame();
1637 // Now call the dynamic function. 1636 // Now call the dynamic function.
1638 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); 1637 __ jmp(&StubCode::OneArgCheckInlineCacheLabel());
1639 } 1638 }
1640 1639
1641 } // namespace dart 1640 } // namespace dart
1642 1641
1643 #endif // defined TARGET_ARCH_IA32 1642 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stack_frame_x64.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698