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" |
11 #include "vm/pages.h" | 11 #include "vm/pages.h" |
12 #include "vm/resolver.h" | 12 #include "vm/resolver.h" |
13 #include "vm/scavenger.h" | 13 #include "vm/scavenger.h" |
14 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
15 | 15 |
16 | 16 |
17 #define __ assembler-> | 17 #define __ assembler-> |
18 | 18 |
19 namespace dart { | 19 namespace dart { |
20 | 20 |
21 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); | 21 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); |
22 DEFINE_FLAG(bool, use_slow_path, false, | 22 DEFINE_FLAG(bool, use_slow_path, false, |
23 "Set to true for debugging & verifying the slow paths."); | 23 "Set to true for debugging & verifying the slow paths."); |
| 24 DECLARE_FLAG(int, optimization_counter_threshold); |
24 | 25 |
25 // Input parameters: | 26 // Input parameters: |
26 // ESP : points to return address. | 27 // ESP : points to return address. |
27 // ESP + 4 : address of last argument in argument array. | 28 // ESP + 4 : address of last argument in argument array. |
28 // ESP + 4*EDX : address of first argument in argument array. | 29 // ESP + 4*EDX : address of first argument in argument array. |
29 // ESP + 4*EDX + 4 : address of return value. | 30 // ESP + 4*EDX + 4 : address of return value. |
30 // ECX : address of the runtime function to call. | 31 // ECX : address of the runtime function to call. |
31 // EDX : number of arguments to the call. | 32 // EDX : number of arguments to the call. |
32 // Must preserve callee saved registers EDI and EBX. | 33 // Must preserve callee saved registers EDI and EBX. |
33 static void GenerateCallRuntimeStub(Assembler* assembler) { | 34 static void GenerateCallRuntimeStub(Assembler* assembler) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // Remove the stub frame as we are about to jump to the dart function. | 262 // Remove the stub frame as we are about to jump to the dart function. |
262 __ LeaveFrame(); | 263 __ LeaveFrame(); |
263 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); | 264 __ movl(EAX, FieldAddress(ECX, Function::code_offset())); |
264 | 265 |
265 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); | 266 __ movl(ECX, FieldAddress(EAX, Code::instructions_offset())); |
266 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 267 __ addl(ECX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
267 __ jmp(ECX); | 268 __ jmp(ECX); |
268 } | 269 } |
269 | 270 |
270 | 271 |
271 // Called when number of invocations exceeds | |
272 // --optimization_invocation_threshold. | |
273 // EAX: target function. | |
274 // EDX: arguments descriptor array (num_args is first Smi element). | |
275 void StubCode::GenerateOptimizeInvokedFunctionStub(Assembler* assembler) { | |
276 __ EnterFrame(0); | |
277 __ pushl(EDX); // Preserve arguments descriptor array. | |
278 __ pushl(EAX); // Preserve target function. | |
279 __ pushl(EAX); // Target function. | |
280 __ CallRuntimeFromStub(kOptimizeInvokedFunctionRuntimeEntry); | |
281 __ popl(EAX); // discard argument. | |
282 __ popl(EAX); // Restore function. | |
283 __ popl(EDX); // Restore arguments descriptor array. | |
284 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); | |
285 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | |
286 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
287 __ LeaveFrame(); | |
288 __ jmp(EAX); | |
289 __ int3(); | |
290 } | |
291 | |
292 | |
293 // Called from a static call only when an invalid code has been entered | 272 // Called from a static call only when an invalid code has been entered |
294 // (invalid because its function was optimized or deoptimized). | 273 // (invalid because its function was optimized or deoptimized). |
295 // ECX: function object. | 274 // ECX: function object. |
296 // EDX: arguments descriptor array (num_args is first Smi element). | 275 // EDX: arguments descriptor array (num_args is first Smi element). |
297 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 276 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
298 __ EnterFrame(0); | 277 __ EnterFrame(0); |
299 __ pushl(EDX); // Preserve arguments descriptor array. | 278 __ pushl(EDX); // Preserve arguments descriptor array. |
300 __ pushl(ECX); // Preserve target function. | 279 __ pushl(ECX); // Preserve target function. |
301 __ pushl(ECX); // Target function. | 280 __ pushl(ECX); // Target function. |
302 __ CallRuntimeFromStub(kFixCallersTargetRuntimeEntry); | 281 __ CallRuntimeFromStub(kFixCallersTargetRuntimeEntry); |
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 // TOS(0): return address | 1518 // TOS(0): return address |
1540 // Control flow: | 1519 // Control flow: |
1541 // - If receiver is null -> jump to IC miss. | 1520 // - If receiver is null -> jump to IC miss. |
1542 // - If receiver is Smi -> load Smi class. | 1521 // - If receiver is Smi -> load Smi class. |
1543 // - If receiver is not-Smi -> load receiver's class. | 1522 // - If receiver is not-Smi -> load receiver's class. |
1544 // - Check if 'num_args' (including receiver) match any IC data group. | 1523 // - Check if 'num_args' (including receiver) match any IC data group. |
1545 // - Match found -> jump to target. | 1524 // - Match found -> jump to target. |
1546 // - Match not found -> jump to IC miss. | 1525 // - Match not found -> jump to IC miss. |
1547 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1526 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
1548 intptr_t num_args) { | 1527 intptr_t num_args) { |
| 1528 __ movl(EBX, FieldAddress(ECX, ICData::function_offset())); |
| 1529 __ incl(FieldAddress(EBX, Function::usage_counter_offset())); |
| 1530 if (CodeGenerator::CanOptimize()) { |
| 1531 __ cmpl(FieldAddress(EBX, Function::usage_counter_offset()), |
| 1532 Immediate(FLAG_optimization_counter_threshold)); |
| 1533 Label not_yet_hot; |
| 1534 __ j(LESS_EQUAL, ¬_yet_hot); |
| 1535 __ EnterFrame(0); |
| 1536 __ pushl(ECX); // Preserve inline cache data object. |
| 1537 __ pushl(EDX); // Preserve arguments array. |
| 1538 __ pushl(EBX); // Argument for runtime: function object. |
| 1539 __ CallRuntimeFromStub(kOptimizeInvokedFunctionRuntimeEntry); |
| 1540 __ popl(EBX); // Remove argument. |
| 1541 __ popl(EDX); // Restore arguments array. |
| 1542 __ popl(ECX); // Restore inline cache data object. |
| 1543 __ LeaveFrame(); |
| 1544 __ Bind(¬_yet_hot); |
| 1545 } |
| 1546 |
1549 ASSERT(num_args > 0); | 1547 ASSERT(num_args > 0); |
1550 // Get receiver. | 1548 // Get receiver. |
1551 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1549 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
1552 __ 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. |
1553 | 1551 |
1554 Label get_class, ic_miss; | 1552 Label get_class, ic_miss; |
1555 __ call(&get_class); | 1553 __ call(&get_class); |
1556 // EAX: receiver's class | 1554 // EAX: receiver's class |
1557 // ECX: IC data array. | 1555 // ECX: IC data array. |
1558 | 1556 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 __ popl(EDX); | 1727 __ popl(EDX); |
1730 __ popl(ECX); | 1728 __ popl(ECX); |
1731 __ LeaveFrame(); | 1729 __ LeaveFrame(); |
1732 // Now call the dynamic function. | 1730 // Now call the dynamic function. |
1733 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); | 1731 __ jmp(&StubCode::OneArgCheckInlineCacheLabel()); |
1734 } | 1732 } |
1735 | 1733 |
1736 } // namespace dart | 1734 } // namespace dart |
1737 | 1735 |
1738 #endif // defined TARGET_ARCH_IA32 | 1736 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |