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

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

Issue 17554003: Change static calls in unoptimized code to always call via a stub. Using ICData, the call count of … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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/code_patcher_mips_test.cc ('k') | runtime/vm/code_patcher_x64_test.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) 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" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
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/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/instructions.h" 12 #include "vm/instructions.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/raw_object.h" 14 #include "vm/raw_object.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 // A Dart instance call passes the ic-data in RBX. 18 // The expected pattern of a Dart unoptimized call (static and instance):
19 // The expected pattern of a dart instance call:
20 // 00: 48 bb imm64 mov RBX, ic-data 19 // 00: 48 bb imm64 mov RBX, ic-data
21 // 10: 49 bb imm64 mov R11, target_address 20 // 10: 49 bb imm64 mov R11, target_address
22 // 20: 41 ff d3 call R11 21 // 20: 41 ff d3 call R11
23 // 23 <- return address 22 // 23 <- return address
24 class InstanceCall : public ValueObject { 23 class UnoptimizedCall : public ValueObject {
25 public: 24 public:
26 explicit InstanceCall(uword return_address) 25 explicit UnoptimizedCall(uword return_address)
27 : start_(return_address - kCallPatternSize) { 26 : start_(return_address - kCallPatternSize) {
28 ASSERT(IsValid(return_address)); 27 ASSERT(IsValid(return_address));
29 ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize); 28 ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize);
30 } 29 }
31 30
32 static const int kCallPatternSize = 23; 31 static const int kCallPatternSize = 23;
33 32
34 static bool IsValid(uword return_address) { 33 static bool IsValid(uword return_address) {
35 uint8_t* code_bytes = 34 uint8_t* code_bytes =
36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); 35 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
(...skipping 12 matching lines...) Expand all
49 } 48 }
50 49
51 void set_target(uword target) const { 50 void set_target(uword target) const {
52 uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2); 51 uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2);
53 *target_addr = target; 52 *target_addr = target;
54 CPU::FlushICache(start_ + 10, 2 + 8); 53 CPU::FlushICache(start_ + 10, 2 + 8);
55 } 54 }
56 55
57 private: 56 private:
58 uword start_; 57 uword start_;
58 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
59 };
60
61
62 class InstanceCall : public UnoptimizedCall {
63 public:
64 explicit InstanceCall(uword return_address)
65 : UnoptimizedCall(return_address) {
66 #if defined(DEBUG)
67 ICData& test_ic_data = ICData::Handle();
68 test_ic_data ^= ic_data();
69 ASSERT(test_ic_data.num_args_tested() > 0);
70 #endif // DEBUG
71 }
72
73 private:
59 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 74 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
60 }; 75 };
61 76
62 77
78 class UnoptimizedStaticCall : public UnoptimizedCall {
79 public:
80 explicit UnoptimizedStaticCall(uword return_address)
81 : UnoptimizedCall(return_address) {
82 #if defined(DEBUG)
83 ICData& test_ic_data = ICData::Handle();
84 test_ic_data ^= ic_data();
85 ASSERT(test_ic_data.num_args_tested() == 0);
86 #endif // DEBUG
87 }
88
89 private:
90 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
91 };
92
93
63 // The expected pattern of a dart static call: 94 // The expected pattern of a dart static call:
64 // mov R10, arguments_descriptor_array (10 bytes) (optional in polym. calls) 95 // mov R10, arguments_descriptor_array (10 bytes) (optional in polym. calls)
65 // mov R11, target_address (10 bytes) 96 // mov R11, target_address (10 bytes)
66 // call R11 (3 bytes) 97 // call R11 (3 bytes)
67 // <- return address 98 // <- return address
68 class StaticCall : public ValueObject { 99 class StaticCall : public ValueObject {
69 public: 100 public:
70 explicit StaticCall(uword return_address) 101 explicit StaticCall(uword return_address)
71 : start_(return_address - kCallPatternSize) { 102 : start_(return_address - kCallPatternSize) {
72 ASSERT(IsValid(return_address)); 103 ASSERT(IsValid(return_address));
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 207 }
177 return call.target(); 208 return call.target();
178 } 209 }
179 210
180 211
181 intptr_t CodePatcher::InstanceCallSizeInBytes() { 212 intptr_t CodePatcher::InstanceCallSizeInBytes() {
182 return InstanceCall::kCallPatternSize; 213 return InstanceCall::kCallPatternSize;
183 } 214 }
184 215
185 216
217 RawFunction* CodePatcher::GetUnoptimizedStaticCallTargetAt(
218 uword return_address, const Code& code) {
219 ASSERT(code.ContainsInstructionAt(return_address));
220 UnoptimizedStaticCall static_call(return_address);
221 ICData& ic_data = ICData::Handle();
222 ic_data ^= static_call.ic_data();
223 return ic_data.GetTargetAt(0);
224 }
225
226
186 void CodePatcher::InsertCallAt(uword start, uword target) { 227 void CodePatcher::InsertCallAt(uword start, uword target) {
187 // The inserted call should not overlap the lazy deopt jump code. 228 // The inserted call should not overlap the lazy deopt jump code.
188 ASSERT(start + ShortCallPattern::InstructionLength() <= target); 229 ASSERT(start + ShortCallPattern::InstructionLength() <= target);
189 *reinterpret_cast<uint8_t*>(start) = 0xE8; 230 *reinterpret_cast<uint8_t*>(start) = 0xE8;
190 ShortCallPattern call(start); 231 ShortCallPattern call(start);
191 call.SetTargetAddress(target); 232 call.SetTargetAddress(target);
192 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); 233 CPU::FlushICache(start, ShortCallPattern::InstructionLength());
193 } 234 }
194 235
195 236
196 } // namespace dart 237 } // namespace dart
197 238
198 #endif // defined TARGET_ARCH_X64 239 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_mips_test.cc ('k') | runtime/vm/code_patcher_x64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698