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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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
« no previous file with comments | « runtime/vm/code_patcher_ia32_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/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/instructions.h" 13 #include "vm/instructions.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/raw_object.h" 15 #include "vm/raw_object.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19
20 static bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) { 19 static bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
21 uint8_t* bytes = reinterpret_cast<uint8_t*>(addr); 20 uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
22 for (intptr_t i = 0; i < size; i++) { 21 for (intptr_t i = 0; i < size; i++) {
23 int16_t val = pattern[i]; 22 int16_t val = pattern[i];
24 if ((val >= 0) && (val != bytes[i])) { 23 if ((val >= 0) && (val != bytes[i])) {
25 return false; 24 return false;
26 } 25 }
27 } 26 }
28 return true; 27 return true;
29 } 28 }
30 29
31
32 intptr_t IndexFromPPLoad(uword start) { 30 intptr_t IndexFromPPLoad(uword start) {
33 int32_t offset = *reinterpret_cast<int32_t*>(start); 31 int32_t offset = *reinterpret_cast<int32_t*>(start);
34 return ObjectPool::IndexFromOffset(offset); 32 return ObjectPool::IndexFromOffset(offset);
35 } 33 }
36 34
37
38 intptr_t IndexFromPPLoadDisp8(uword start) { 35 intptr_t IndexFromPPLoadDisp8(uword start) {
39 int8_t offset = *reinterpret_cast<int8_t*>(start); 36 int8_t offset = *reinterpret_cast<int8_t*>(start);
40 return ObjectPool::IndexFromOffset(offset); 37 return ObjectPool::IndexFromOffset(offset);
41 } 38 }
42 39
43
44 class UnoptimizedCall : public ValueObject { 40 class UnoptimizedCall : public ValueObject {
45 public: 41 public:
46 UnoptimizedCall(uword return_address, const Code& code) 42 UnoptimizedCall(uword return_address, const Code& code)
47 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 43 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
48 start_(return_address - kCallPatternSize) { 44 start_(return_address - kCallPatternSize) {
49 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize); 45 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize);
50 ASSERT(IsValid()); 46 ASSERT(IsValid());
51 } 47 }
52 48
53 static const int kCallPatternSize = 22; 49 static const int kCallPatternSize = 22;
(...skipping 26 matching lines...) Expand all
80 } 76 }
81 77
82 protected: 78 protected:
83 const ObjectPool& object_pool_; 79 const ObjectPool& object_pool_;
84 80
85 private: 81 private:
86 uword start_; 82 uword start_;
87 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); 83 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
88 }; 84 };
89 85
90
91 class NativeCall : public UnoptimizedCall { 86 class NativeCall : public UnoptimizedCall {
92 public: 87 public:
93 NativeCall(uword return_address, const Code& code) 88 NativeCall(uword return_address, const Code& code)
94 : UnoptimizedCall(return_address, code) {} 89 : UnoptimizedCall(return_address, code) {}
95 90
96 NativeFunction native_function() const { 91 NativeFunction native_function() const {
97 return reinterpret_cast<NativeFunction>( 92 return reinterpret_cast<NativeFunction>(
98 object_pool_.RawValueAt(argument_index())); 93 object_pool_.RawValueAt(argument_index()));
99 } 94 }
100 95
101 void set_native_function(NativeFunction func) const { 96 void set_native_function(NativeFunction func) const {
102 object_pool_.SetRawValueAt(argument_index(), reinterpret_cast<uword>(func)); 97 object_pool_.SetRawValueAt(argument_index(), reinterpret_cast<uword>(func));
103 } 98 }
104 99
105 private: 100 private:
106 DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall); 101 DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall);
107 }; 102 };
108 103
109
110 class InstanceCall : public UnoptimizedCall { 104 class InstanceCall : public UnoptimizedCall {
111 public: 105 public:
112 InstanceCall(uword return_address, const Code& code) 106 InstanceCall(uword return_address, const Code& code)
113 : UnoptimizedCall(return_address, code) { 107 : UnoptimizedCall(return_address, code) {
114 #if defined(DEBUG) 108 #if defined(DEBUG)
115 ICData& test_ic_data = ICData::Handle(); 109 ICData& test_ic_data = ICData::Handle();
116 test_ic_data ^= ic_data(); 110 test_ic_data ^= ic_data();
117 ASSERT(test_ic_data.NumArgsTested() > 0); 111 ASSERT(test_ic_data.NumArgsTested() > 0);
118 #endif // DEBUG 112 #endif // DEBUG
119 } 113 }
120 114
121 private: 115 private:
122 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 116 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
123 }; 117 };
124 118
125
126 class UnoptimizedStaticCall : public UnoptimizedCall { 119 class UnoptimizedStaticCall : public UnoptimizedCall {
127 public: 120 public:
128 UnoptimizedStaticCall(uword return_address, const Code& code) 121 UnoptimizedStaticCall(uword return_address, const Code& code)
129 : UnoptimizedCall(return_address, code) { 122 : UnoptimizedCall(return_address, code) {
130 #if defined(DEBUG) 123 #if defined(DEBUG)
131 ICData& test_ic_data = ICData::Handle(); 124 ICData& test_ic_data = ICData::Handle();
132 test_ic_data ^= ic_data(); 125 test_ic_data ^= ic_data();
133 ASSERT(test_ic_data.NumArgsTested() >= 0); 126 ASSERT(test_ic_data.NumArgsTested() >= 0);
134 #endif // DEBUG 127 #endif // DEBUG
135 } 128 }
136 129
137 private: 130 private:
138 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall); 131 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedStaticCall);
139 }; 132 };
140 133
141
142 // The expected pattern of a call where the target is loaded from 134 // The expected pattern of a call where the target is loaded from
143 // the object pool. 135 // the object pool.
144 class PoolPointerCall : public ValueObject { 136 class PoolPointerCall : public ValueObject {
145 public: 137 public:
146 explicit PoolPointerCall(uword return_address, const Code& code) 138 explicit PoolPointerCall(uword return_address, const Code& code)
147 : start_(return_address - kCallPatternSize), 139 : start_(return_address - kCallPatternSize),
148 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { 140 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
149 ASSERT(IsValid()); 141 ASSERT(IsValid());
150 } 142 }
151 143
(...skipping 22 matching lines...) Expand all
174 } 166 }
175 167
176 protected: 168 protected:
177 uword start_; 169 uword start_;
178 const ObjectPool& object_pool_; 170 const ObjectPool& object_pool_;
179 171
180 private: 172 private:
181 DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall); 173 DISALLOW_IMPLICIT_CONSTRUCTORS(PoolPointerCall);
182 }; 174 };
183 175
184
185 // Instance call that can switch between a direct monomorphic call, an IC call, 176 // Instance call that can switch between a direct monomorphic call, an IC call,
186 // and a megamorphic call. 177 // and a megamorphic call.
187 // load guarded cid load ICData load MegamorphicCache 178 // load guarded cid load ICData load MegamorphicCache
188 // load monomorphic target <-> load ICLookup stub -> load MMLookup stub 179 // load monomorphic target <-> load ICLookup stub -> load MMLookup stub
189 // call target.entry call stub.entry call stub.entry 180 // call target.entry call stub.entry call stub.entry
190 class SwitchableCall : public ValueObject { 181 class SwitchableCall : public ValueObject {
191 public: 182 public:
192 SwitchableCall(uword return_address, const Code& code) 183 SwitchableCall(uword return_address, const Code& code)
193 : start_(return_address - kCallPatternSize), 184 : start_(return_address - kCallPatternSize),
194 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { 185 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 220 }
230 221
231 protected: 222 protected:
232 uword start_; 223 uword start_;
233 const ObjectPool& object_pool_; 224 const ObjectPool& object_pool_;
234 225
235 private: 226 private:
236 DISALLOW_IMPLICIT_CONSTRUCTORS(SwitchableCall); 227 DISALLOW_IMPLICIT_CONSTRUCTORS(SwitchableCall);
237 }; 228 };
238 229
239
240 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address, 230 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
241 const Code& code) { 231 const Code& code) {
242 ASSERT(code.ContainsInstructionAt(return_address)); 232 ASSERT(code.ContainsInstructionAt(return_address));
243 PoolPointerCall call(return_address, code); 233 PoolPointerCall call(return_address, code);
244 return call.Target(); 234 return call.Target();
245 } 235 }
246 236
247
248 void CodePatcher::PatchStaticCallAt(uword return_address, 237 void CodePatcher::PatchStaticCallAt(uword return_address,
249 const Code& code, 238 const Code& code,
250 const Code& new_target) { 239 const Code& new_target) {
251 PatchPoolPointerCallAt(return_address, code, new_target); 240 PatchPoolPointerCallAt(return_address, code, new_target);
252 } 241 }
253 242
254
255 void CodePatcher::PatchPoolPointerCallAt(uword return_address, 243 void CodePatcher::PatchPoolPointerCallAt(uword return_address,
256 const Code& code, 244 const Code& code,
257 const Code& new_target) { 245 const Code& new_target) {
258 ASSERT(code.ContainsInstructionAt(return_address)); 246 ASSERT(code.ContainsInstructionAt(return_address));
259 PoolPointerCall call(return_address, code); 247 PoolPointerCall call(return_address, code);
260 call.SetTarget(new_target); 248 call.SetTarget(new_target);
261 } 249 }
262 250
263
264 RawCode* CodePatcher::GetInstanceCallAt(uword return_address, 251 RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
265 const Code& code, 252 const Code& code,
266 ICData* ic_data) { 253 ICData* ic_data) {
267 ASSERT(code.ContainsInstructionAt(return_address)); 254 ASSERT(code.ContainsInstructionAt(return_address));
268 InstanceCall call(return_address, code); 255 InstanceCall call(return_address, code);
269 if (ic_data != NULL) { 256 if (ic_data != NULL) {
270 *ic_data ^= call.ic_data(); 257 *ic_data ^= call.ic_data();
271 } 258 }
272 return call.target(); 259 return call.target();
273 } 260 }
274 261
275
276 intptr_t CodePatcher::InstanceCallSizeInBytes() { 262 intptr_t CodePatcher::InstanceCallSizeInBytes() {
277 return InstanceCall::kCallPatternSize; 263 return InstanceCall::kCallPatternSize;
278 } 264 }
279 265
280
281 void CodePatcher::InsertDeoptimizationCallAt(uword start) { 266 void CodePatcher::InsertDeoptimizationCallAt(uword start) {
282 UNREACHABLE(); 267 UNREACHABLE();
283 } 268 }
284 269
285
286 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address, 270 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address,
287 const Code& code, 271 const Code& code,
288 ICData* ic_data_result) { 272 ICData* ic_data_result) {
289 ASSERT(code.ContainsInstructionAt(return_address)); 273 ASSERT(code.ContainsInstructionAt(return_address));
290 UnoptimizedStaticCall static_call(return_address, code); 274 UnoptimizedStaticCall static_call(return_address, code);
291 ICData& ic_data = ICData::Handle(); 275 ICData& ic_data = ICData::Handle();
292 ic_data ^= static_call.ic_data(); 276 ic_data ^= static_call.ic_data();
293 if (ic_data_result != NULL) { 277 if (ic_data_result != NULL) {
294 *ic_data_result = ic_data.raw(); 278 *ic_data_result = ic_data.raw();
295 } 279 }
296 return ic_data.GetTargetAt(0); 280 return ic_data.GetTargetAt(0);
297 } 281 }
298 282
299
300 void CodePatcher::PatchSwitchableCallAt(uword return_address, 283 void CodePatcher::PatchSwitchableCallAt(uword return_address,
301 const Code& caller_code, 284 const Code& caller_code,
302 const Object& data, 285 const Object& data,
303 const Code& target) { 286 const Code& target) {
304 ASSERT(caller_code.ContainsInstructionAt(return_address)); 287 ASSERT(caller_code.ContainsInstructionAt(return_address));
305 SwitchableCall call(return_address, caller_code); 288 SwitchableCall call(return_address, caller_code);
306 call.SetData(data); 289 call.SetData(data);
307 call.SetTarget(target); 290 call.SetTarget(target);
308 } 291 }
309 292
310
311 RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address, 293 RawCode* CodePatcher::GetSwitchableCallTargetAt(uword return_address,
312 const Code& caller_code) { 294 const Code& caller_code) {
313 ASSERT(caller_code.ContainsInstructionAt(return_address)); 295 ASSERT(caller_code.ContainsInstructionAt(return_address));
314 SwitchableCall call(return_address, caller_code); 296 SwitchableCall call(return_address, caller_code);
315 return call.target(); 297 return call.target();
316 } 298 }
317 299
318
319 RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address, 300 RawObject* CodePatcher::GetSwitchableCallDataAt(uword return_address,
320 const Code& caller_code) { 301 const Code& caller_code) {
321 ASSERT(caller_code.ContainsInstructionAt(return_address)); 302 ASSERT(caller_code.ContainsInstructionAt(return_address));
322 SwitchableCall call(return_address, caller_code); 303 SwitchableCall call(return_address, caller_code);
323 return call.data(); 304 return call.data();
324 } 305 }
325 306
326
327 void CodePatcher::PatchNativeCallAt(uword return_address, 307 void CodePatcher::PatchNativeCallAt(uword return_address,
328 const Code& code, 308 const Code& code,
329 NativeFunction target, 309 NativeFunction target,
330 const Code& trampoline) { 310 const Code& trampoline) {
331 ASSERT(code.ContainsInstructionAt(return_address)); 311 ASSERT(code.ContainsInstructionAt(return_address));
332 NativeCall call(return_address, code); 312 NativeCall call(return_address, code);
333 call.set_target(trampoline); 313 call.set_target(trampoline);
334 call.set_native_function(target); 314 call.set_native_function(target);
335 } 315 }
336 316
337
338 RawCode* CodePatcher::GetNativeCallAt(uword return_address, 317 RawCode* CodePatcher::GetNativeCallAt(uword return_address,
339 const Code& code, 318 const Code& code,
340 NativeFunction* target) { 319 NativeFunction* target) {
341 ASSERT(code.ContainsInstructionAt(return_address)); 320 ASSERT(code.ContainsInstructionAt(return_address));
342 NativeCall call(return_address, code); 321 NativeCall call(return_address, code);
343 *target = call.native_function(); 322 *target = call.native_function();
344 return call.target(); 323 return call.target();
345 } 324 }
346 325
347 } // namespace dart 326 } // namespace dart
348 327
349 #endif // defined TARGET_ARCH_X64 328 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_ia32_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