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

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

Issue 1127523004: Add flag --support_debugger, controls emitting single stepping checks. Disable in --noopt, 6% gain. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 7 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/stub_code_mips.cc ('k') | no next file » | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/heap.h" 12 #include "vm/heap.h"
13 #include "vm/instructions.h" 13 #include "vm/instructions.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/resolver.h" 15 #include "vm/resolver.h"
16 #include "vm/scavenger.h" 16 #include "vm/scavenger.h"
17 #include "vm/stack_frame.h" 17 #include "vm/stack_frame.h"
18 #include "vm/stub_code.h" 18 #include "vm/stub_code.h"
19 #include "vm/tags.h" 19 #include "vm/tags.h"
20 20
21 #define __ assembler-> 21 #define __ assembler->
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects."); 25 DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
26 DEFINE_FLAG(bool, use_slow_path, false, 26 DEFINE_FLAG(bool, use_slow_path, false,
27 "Set to true for debugging & verifying the slow paths."); 27 "Set to true for debugging & verifying the slow paths.");
28 DECLARE_FLAG(bool, trace_optimized_ic_calls); 28 DECLARE_FLAG(bool, trace_optimized_ic_calls);
29 DECLARE_FLAG(int, optimization_counter_threshold); 29 DECLARE_FLAG(int, optimization_counter_threshold);
30 DECLARE_FLAG(bool, support_debugger);
30 31
31 // Input parameters: 32 // Input parameters:
32 // RSP : points to return address. 33 // RSP : points to return address.
33 // RSP + 8 : address of last argument in argument array. 34 // RSP + 8 : address of last argument in argument array.
34 // RSP + 8*R10 : address of first argument in argument array. 35 // RSP + 8*R10 : address of first argument in argument array.
35 // RSP + 8*R10 + 8 : address of return value. 36 // RSP + 8*R10 + 8 : address of return value.
36 // RBX : address of the runtime function to call. 37 // RBX : address of the runtime function to call.
37 // R10 : number of arguments to the call. 38 // R10 : number of arguments to the call.
38 // Must preserve callee saved registers R12 and R13. 39 // Must preserve callee saved registers R12 and R13.
39 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
(...skipping 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); 1338 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset()));
1338 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1339 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1339 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); 1340 __ andq(RCX, Immediate(ICData::NumArgsTestedMask()));
1340 __ cmpq(RCX, Immediate(num_args)); 1341 __ cmpq(RCX, Immediate(num_args));
1341 __ j(EQUAL, &ok, Assembler::kNearJump); 1342 __ j(EQUAL, &ok, Assembler::kNearJump);
1342 __ Stop("Incorrect stub for IC data"); 1343 __ Stop("Incorrect stub for IC data");
1343 __ Bind(&ok); 1344 __ Bind(&ok);
1344 } 1345 }
1345 #endif // DEBUG 1346 #endif // DEBUG
1346 1347
1347 __ Comment("Check single stepping");
1348 Label stepping, done_stepping; 1348 Label stepping, done_stepping;
1349 __ LoadIsolate(RAX); 1349 if (FLAG_support_debugger) {
1350 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); 1350 __ Comment("Check single stepping");
1351 __ j(NOT_EQUAL, &stepping); 1351 __ LoadIsolate(RAX);
1352 __ Bind(&done_stepping); 1352 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0));
1353 __ j(NOT_EQUAL, &stepping);
1354 __ Bind(&done_stepping);
1355 }
1353 1356
1354 __ Comment("Range feedback collection"); 1357 __ Comment("Range feedback collection");
1355 Label not_smi_or_overflow; 1358 Label not_smi_or_overflow;
1356 if (range_collection_mode == kCollectRanges) { 1359 if (range_collection_mode == kCollectRanges) {
1357 ASSERT((num_args == 1) || (num_args == 2)); 1360 ASSERT((num_args == 1) || (num_args == 2));
1358 if (num_args == 2) { 1361 if (num_args == 2) {
1359 __ movq(RAX, Address(RSP, + 2 * kWordSize)); 1362 __ movq(RAX, Address(RSP, + 2 * kWordSize));
1360 __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow); 1363 __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow);
1361 } 1364 }
1362 1365
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 __ movq(RDX, RAX); 1499 __ movq(RDX, RAX);
1497 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); 1500 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
1498 __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done); 1501 __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done);
1499 __ Bind(&done); 1502 __ Bind(&done);
1500 __ LeaveStubFrame(); 1503 __ LeaveStubFrame();
1501 __ ret(); 1504 __ ret();
1502 } else { 1505 } else {
1503 __ jmp(RCX); 1506 __ jmp(RCX);
1504 } 1507 }
1505 1508
1506 __ Bind(&stepping); 1509 if (FLAG_support_debugger) {
1507 __ EnterStubFrame(); 1510 __ Bind(&stepping);
1508 __ pushq(RBX); 1511 __ EnterStubFrame();
1509 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1512 __ pushq(RBX);
1510 __ popq(RBX); 1513 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1511 __ LeaveStubFrame(); 1514 __ popq(RBX);
1512 __ jmp(&done_stepping); 1515 __ LeaveStubFrame();
1516 __ jmp(&done_stepping);
1517 }
1513 } 1518 }
1514 1519
1515 1520
1516 // Use inline cache data array to invoke the target or continue in inline 1521 // Use inline cache data array to invoke the target or continue in inline
1517 // cache miss handler. Stub for 1-argument check (receiver class). 1522 // cache miss handler. Stub for 1-argument check (receiver class).
1518 // RBX: Inline cache data object. 1523 // RBX: Inline cache data object.
1519 // TOS(0): Return address. 1524 // TOS(0): Return address.
1520 // Inline cache data object structure: 1525 // Inline cache data object structure:
1521 // 0: function-name 1526 // 0: function-name
1522 // 1: N, number of arguments checked. 1527 // 1: N, number of arguments checked.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); 1657 __ andq(RCX, Immediate(ICData::NumArgsTestedMask()));
1653 __ cmpq(RCX, Immediate(0)); 1658 __ cmpq(RCX, Immediate(0));
1654 __ j(EQUAL, &ok, Assembler::kNearJump); 1659 __ j(EQUAL, &ok, Assembler::kNearJump);
1655 __ Stop("Incorrect IC data for unoptimized static call"); 1660 __ Stop("Incorrect IC data for unoptimized static call");
1656 __ Bind(&ok); 1661 __ Bind(&ok);
1657 } 1662 }
1658 #endif // DEBUG 1663 #endif // DEBUG
1659 1664
1660 // Check single stepping. 1665 // Check single stepping.
1661 Label stepping, done_stepping; 1666 Label stepping, done_stepping;
1662 __ LoadIsolate(RAX); 1667 if (FLAG_support_debugger) {
1663 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 1668 __ LoadIsolate(RAX);
1664 __ cmpq(RAX, Immediate(0)); 1669 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
1670 __ cmpq(RAX, Immediate(0));
1665 #if defined(DEBUG) 1671 #if defined(DEBUG)
1666 static const bool kJumpLength = Assembler::kFarJump; 1672 static const bool kJumpLength = Assembler::kFarJump;
1667 #else 1673 #else
1668 static const bool kJumpLength = Assembler::kNearJump; 1674 static const bool kJumpLength = Assembler::kNearJump;
1669 #endif // DEBUG 1675 #endif // DEBUG
1670 __ j(NOT_EQUAL, &stepping, kJumpLength); 1676 __ j(NOT_EQUAL, &stepping, kJumpLength);
1671 __ Bind(&done_stepping); 1677 __ Bind(&done_stepping);
1678 }
1672 1679
1673 // RBX: IC data object (preserved). 1680 // RBX: IC data object (preserved).
1674 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1681 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1675 // R12: ic_data_array with entries: target functions and count. 1682 // R12: ic_data_array with entries: target functions and count.
1676 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1683 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1677 // R12: points directly to the first ic data array element. 1684 // R12: points directly to the first ic data array element.
1678 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize; 1685 const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
1679 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize; 1686 const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
1680 1687
1681 if (FLAG_optimization_counter_threshold >= 0) { 1688 if (FLAG_optimization_counter_threshold >= 0) {
1682 // Increment count for this call. 1689 // Increment count for this call.
1683 __ movq(R8, Address(R12, count_offset)); 1690 __ movq(R8, Address(R12, count_offset));
1684 __ addq(R8, Immediate(Smi::RawValue(1))); 1691 __ addq(R8, Immediate(Smi::RawValue(1)));
1685 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue))); 1692 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue)));
1686 __ cmovnoq(R9, R8); 1693 __ cmovnoq(R9, R8);
1687 __ StoreIntoSmiField(Address(R12, count_offset), R9); 1694 __ StoreIntoSmiField(Address(R12, count_offset), R9);
1688 } 1695 }
1689 1696
1690 // Load arguments descriptor into R10. 1697 // Load arguments descriptor into R10.
1691 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1698 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1692 1699
1693 // Get function and call it, if possible. 1700 // Get function and call it, if possible.
1694 __ movq(RAX, Address(R12, target_offset)); 1701 __ movq(RAX, Address(R12, target_offset));
1695 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); 1702 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
1696 // RCX: Target instructions. 1703 // RCX: Target instructions.
1697 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1704 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1698 __ jmp(RCX); 1705 __ jmp(RCX);
1699 1706
1700 __ Bind(&stepping); 1707 if (FLAG_support_debugger) {
1701 __ EnterStubFrame(); 1708 __ Bind(&stepping);
1702 __ pushq(RBX); // Preserve IC data object. 1709 __ EnterStubFrame();
1703 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1710 __ pushq(RBX); // Preserve IC data object.
1704 __ popq(RBX); 1711 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1705 __ LeaveStubFrame(); 1712 __ popq(RBX);
1706 __ jmp(&done_stepping, Assembler::kNearJump); 1713 __ LeaveStubFrame();
1714 __ jmp(&done_stepping, Assembler::kNearJump);
1715 }
1707 } 1716 }
1708 1717
1709 1718
1710 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) { 1719 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
1711 GenerateUsageCounterIncrement(assembler, RCX); 1720 GenerateUsageCounterIncrement(assembler, RCX);
1712 GenerateNArgsCheckInlineCacheStub( 1721 GenerateNArgsCheckInlineCacheStub(
1713 assembler, 1722 assembler,
1714 1, 1723 1,
1715 kStaticCallMissHandlerOneArgRuntimeEntry, 1724 kStaticCallMissHandlerOneArgRuntimeEntry,
1716 Token::kILLEGAL, 1725 Token::kILLEGAL,
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 2076
2068 // Called only from unoptimized code. All relevant registers have been saved. 2077 // Called only from unoptimized code. All relevant registers have been saved.
2069 // TOS + 0: return address 2078 // TOS + 0: return address
2070 // TOS + 1: right argument. 2079 // TOS + 1: right argument.
2071 // TOS + 2: left argument. 2080 // TOS + 2: left argument.
2072 // Returns ZF set. 2081 // Returns ZF set.
2073 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub( 2082 void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
2074 Assembler* assembler) { 2083 Assembler* assembler) {
2075 // Check single stepping. 2084 // Check single stepping.
2076 Label stepping, done_stepping; 2085 Label stepping, done_stepping;
2077 __ LoadIsolate(RAX); 2086 if (FLAG_support_debugger) {
2078 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset())); 2087 __ LoadIsolate(RAX);
2079 __ cmpq(RAX, Immediate(0)); 2088 __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
2080 __ j(NOT_EQUAL, &stepping); 2089 __ cmpq(RAX, Immediate(0));
2081 __ Bind(&done_stepping); 2090 __ j(NOT_EQUAL, &stepping);
2091 __ Bind(&done_stepping);
2092 }
2082 2093
2083 const Register left = RAX; 2094 const Register left = RAX;
2084 const Register right = RDX; 2095 const Register right = RDX;
2085 2096
2086 __ movq(left, Address(RSP, 2 * kWordSize)); 2097 __ movq(left, Address(RSP, 2 * kWordSize));
2087 __ movq(right, Address(RSP, 1 * kWordSize)); 2098 __ movq(right, Address(RSP, 1 * kWordSize));
2088 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2099 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2089 __ ret(); 2100 __ ret();
2090 2101
2091 __ Bind(&stepping); 2102 if (FLAG_support_debugger) {
2092 __ EnterStubFrame(); 2103 __ Bind(&stepping);
2093 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 2104 __ EnterStubFrame();
2094 __ LeaveStubFrame(); 2105 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
2095 __ jmp(&done_stepping); 2106 __ LeaveStubFrame();
2107 __ jmp(&done_stepping);
2108 }
2096 } 2109 }
2097 2110
2098 2111
2099 // Called from optimized code only. 2112 // Called from optimized code only.
2100 // TOS + 0: return address 2113 // TOS + 0: return address
2101 // TOS + 1: right argument. 2114 // TOS + 1: right argument.
2102 // TOS + 2: left argument. 2115 // TOS + 2: left argument.
2103 // Returns ZF set. 2116 // Returns ZF set.
2104 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub( 2117 void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
2105 Assembler* assembler) { 2118 Assembler* assembler) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2161 // Result: 2174 // Result:
2162 // RCX: entry point. 2175 // RCX: entry point.
2163 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2176 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2164 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); 2177 EmitMegamorphicLookup(assembler, RDI, RBX, RCX);
2165 __ ret(); 2178 __ ret();
2166 } 2179 }
2167 2180
2168 } // namespace dart 2181 } // namespace dart
2169 2182
2170 #endif // defined TARGET_ARCH_X64 2183 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698