| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 // Control flow: | 1525 // Control flow: |
| 1526 // - If receiver is null -> jump to IC miss. | 1526 // - If receiver is null -> jump to IC miss. |
| 1527 // - If receiver is Smi -> load Smi class. | 1527 // - If receiver is Smi -> load Smi class. |
| 1528 // - If receiver is not-Smi -> load receiver's class. | 1528 // - If receiver is not-Smi -> load receiver's class. |
| 1529 // - Check if 'num_args' (including receiver) match any IC data group. | 1529 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1530 // - Match found -> jump to target. | 1530 // - Match found -> jump to target. |
| 1531 // - Match not found -> jump to IC miss. | 1531 // - Match not found -> jump to IC miss. |
| 1532 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, | 1532 void StubCode::GenerateNArgsCheckInlineCacheStub(Assembler* assembler, |
| 1533 intptr_t num_args) { | 1533 intptr_t num_args) { |
| 1534 __ movq(RCX, FieldAddress(RBX, ICData::function_offset())); | 1534 __ movq(RCX, FieldAddress(RBX, ICData::function_offset())); |
| 1535 Label is_hot; |
| 1536 if (FlowGraphCompiler::CanOptimize()) { |
| 1537 ASSERT(FLAG_optimization_counter_threshold > 1); |
| 1538 // The usage_counter is always less than FLAG_optimization_counter_threshold |
| 1539 // except when the function gets optimized. |
| 1540 __ cmpq(FieldAddress(RCX, Function::usage_counter_offset()), |
| 1541 Immediate(FLAG_optimization_counter_threshold - 1)); |
| 1542 // Do not increment to equality with threshold, since a counter greater |
| 1543 // than threshold denotes a function that was already optimized. |
| 1544 // The equality should be reached only at exit of the method |
| 1545 // (return instruction). |
| 1546 __ j(EQUAL, &is_hot, Assembler::kNearJump); |
| 1547 // As long as VM has no OSR do not optimize in the middle of the function |
| 1548 // but only at exit so that we have collected all type feedback before |
| 1549 // optimizing. |
| 1550 } |
| 1535 __ incq(FieldAddress(RCX, Function::usage_counter_offset())); | 1551 __ incq(FieldAddress(RCX, Function::usage_counter_offset())); |
| 1536 if (FlowGraphCompiler::CanOptimize()) { | 1552 __ Bind(&is_hot); |
| 1537 __ cmpq(FieldAddress(RCX, Function::usage_counter_offset()), | 1553 |
| 1538 Immediate(FLAG_optimization_counter_threshold)); | |
| 1539 Label not_yet_hot, already_optimized; | |
| 1540 __ j(LESS, ¬_yet_hot, Assembler::kNearJump); | |
| 1541 __ j(GREATER, &already_optimized, Assembler::kNearJump); | |
| 1542 AssemblerMacros::EnterStubFrame(assembler); | |
| 1543 __ pushq(RBX); // Preserve inline cache data object. | |
| 1544 __ pushq(R10); // Preserve arguments array. | |
| 1545 __ pushq(RCX); // Argument for runtime: function object. | |
| 1546 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | |
| 1547 __ popq(RCX); // Remove argument. | |
| 1548 __ popq(R10); // Restore arguments array. | |
| 1549 __ popq(RBX); // Restore inline cache data object. | |
| 1550 __ LeaveFrame(); | |
| 1551 __ Bind(¬_yet_hot); | |
| 1552 __ Bind(&already_optimized); | |
| 1553 } | |
| 1554 ASSERT(num_args > 0); | 1554 ASSERT(num_args > 0); |
| 1555 // Get receiver (first read number of arguments from argument descriptor array | 1555 // Get receiver (first read number of arguments from argument descriptor array |
| 1556 // and then access the receiver from the stack). | 1556 // and then access the receiver from the stack). |
| 1557 __ movq(RAX, FieldAddress(R10, Array::data_offset())); | 1557 __ movq(RAX, FieldAddress(R10, Array::data_offset())); |
| 1558 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi. | 1558 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi. |
| 1559 | 1559 |
| 1560 Label get_class_id_as_smi, ic_miss; | 1560 Label get_class_id_as_smi, ic_miss; |
| 1561 // RBX: IC data array. | 1561 // RBX: IC data array. |
| 1562 | 1562 |
| 1563 #if defined(DEBUG) | 1563 #if defined(DEBUG) |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1903 void StubCode::GenerateJumpToErrorHandlerStub(Assembler* assembler) { | 1903 void StubCode::GenerateJumpToErrorHandlerStub(Assembler* assembler) { |
| 1904 __ movq(RAX, RCX); // error object. | 1904 __ movq(RAX, RCX); // error object. |
| 1905 __ movq(RBP, RDX); // target frame_pointer. | 1905 __ movq(RBP, RDX); // target frame_pointer. |
| 1906 __ movq(RSP, RSI); // target stack_pointer. | 1906 __ movq(RSP, RSI); // target stack_pointer. |
| 1907 __ jmp(RDI); // Jump to the exception handler code. | 1907 __ jmp(RDI); // Jump to the exception handler code. |
| 1908 } | 1908 } |
| 1909 | 1909 |
| 1910 } // namespace dart | 1910 } // namespace dart |
| 1911 | 1911 |
| 1912 #endif // defined TARGET_ARCH_X64 | 1912 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |