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

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

Issue 1294113004: VM: Link native calls lazily. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: addressed comments Created 5 years, 4 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_mips.cc ('k') | runtime/vm/flow_graph_compiler.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 // The expected pattern of a Dart unoptimized call (static and instance): 19 // The expected pattern of a Dart unoptimized call (static and instance):
20 // 0: 49 8b 9f imm32 mov RBX, [PP + off] 20 // 0: 49 8b 9f imm32 mov RBX, [PP + off]
21 // 7: 41 ff 97 imm32 call [PP + off] 21 // 7: 41 ff 97 imm32 call [PP + off]
22 // 14 <- return address 22 // 14 <- return address
23 class UnoptimizedCall : public ValueObject { 23 class UnoptimizedCall : public ValueObject {
24 public: 24 public:
25 UnoptimizedCall(uword return_address, const Code& code) 25 UnoptimizedCall(uword return_address, const Code& code)
26 : start_(return_address - kCallPatternSize), 26 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
27 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { 27 start_(return_address - kCallPatternSize) {
28 ASSERT(IsValid(return_address)); 28 ASSERT(IsValid(return_address));
29 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize); 29 ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize);
30 } 30 }
31 31
32 static const int kCallPatternSize = 14; 32 static const int kCallPatternSize = 14;
33 33
34 static bool IsValid(uword return_address) { 34 static bool IsValid(uword return_address) {
35 uint8_t* code_bytes = 35 uint8_t* code_bytes =
36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); 36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) && 37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) &&
38 (code_bytes[2] == 0x9F) && 38 (code_bytes[2] == 0x9F) &&
39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) && 39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) &&
40 (code_bytes[9] == 0x97); 40 (code_bytes[9] == 0x97);
41 } 41 }
42 42
43 intptr_t argument_index() const {
44 return IndexFromPPLoad(start_ + 3);
45 }
46
43 RawObject* ic_data() const { 47 RawObject* ic_data() const {
44 intptr_t index = IndexFromPPLoad(start_ + 3); 48 return object_pool_.ObjectAt(argument_index());
45 return object_pool_.ObjectAt(index);
46 } 49 }
47 50
48 uword target() const { 51 uword target() const {
49 intptr_t index = IndexFromPPLoad(start_ + 10); 52 intptr_t index = IndexFromPPLoad(start_ + 10);
50 return object_pool_.RawValueAt(index); 53 return object_pool_.RawValueAt(index);
51 } 54 }
52 55
53 void set_target(uword target) const { 56 void set_target(uword target) const {
54 intptr_t index = IndexFromPPLoad(start_ + 10); 57 intptr_t index = IndexFromPPLoad(start_ + 10);
55 object_pool_.SetRawValueAt(index, target); 58 object_pool_.SetRawValueAt(index, target);
56 // No need to flush the instruction cache, since the code is not modified. 59 // No need to flush the instruction cache, since the code is not modified.
57 } 60 }
58 61
62 protected:
63 const ObjectPool& object_pool_;
64
59 private: 65 private:
60 uword start_; 66 uword start_;
61 const ObjectPool& object_pool_;
62 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); 67 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
63 }; 68 };
64 69
65 70
71 class NativeCall : public UnoptimizedCall {
72 public:
73 NativeCall(uword return_address, const Code& code)
74 : UnoptimizedCall(return_address, code) {
75 }
76
77 NativeFunction native_function() const {
78 return reinterpret_cast<NativeFunction>(
79 object_pool_.RawValueAt(argument_index()));
80 }
81
82 void set_native_function(NativeFunction func) const {
83 object_pool_.SetRawValueAt(argument_index(),
84 reinterpret_cast<uword>(func));
85 }
86
87 private:
88 DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall);
89 };
90
91
66 class InstanceCall : public UnoptimizedCall { 92 class InstanceCall : public UnoptimizedCall {
67 public: 93 public:
68 InstanceCall(uword return_address, const Code& code) 94 InstanceCall(uword return_address, const Code& code)
69 : UnoptimizedCall(return_address, code) { 95 : UnoptimizedCall(return_address, code) {
70 #if defined(DEBUG) 96 #if defined(DEBUG)
71 ICData& test_ic_data = ICData::Handle(); 97 ICData& test_ic_data = ICData::Handle();
72 test_ic_data ^= ic_data(); 98 test_ic_data ^= ic_data();
73 ASSERT(test_ic_data.NumArgsTested() > 0); 99 ASSERT(test_ic_data.NumArgsTested() > 0);
74 #endif // DEBUG 100 #endif // DEBUG
75 } 101 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 UnoptimizedStaticCall static_call(return_address, code); 230 UnoptimizedStaticCall static_call(return_address, code);
205 ICData& ic_data = ICData::Handle(); 231 ICData& ic_data = ICData::Handle();
206 ic_data ^= static_call.ic_data(); 232 ic_data ^= static_call.ic_data();
207 if (ic_data_result != NULL) { 233 if (ic_data_result != NULL) {
208 *ic_data_result = ic_data.raw(); 234 *ic_data_result = ic_data.raw();
209 } 235 }
210 return ic_data.GetTargetAt(0); 236 return ic_data.GetTargetAt(0);
211 } 237 }
212 238
213 239
240 void CodePatcher::PatchNativeCallAt(uword return_address,
241 const Code& code,
242 NativeFunction target,
243 const Code& trampoline) {
244 ASSERT(code.ContainsInstructionAt(return_address));
245 NativeCall call(return_address, code);
246 call.set_target(trampoline.EntryPoint());
247 call.set_native_function(target);
248 }
249
250
251 uword CodePatcher::GetNativeCallAt(uword return_address,
252 const Code& code,
253 NativeFunction* target) {
254 ASSERT(code.ContainsInstructionAt(return_address));
255 NativeCall call(return_address, code);
256 *target = call.native_function();
257 return call.target();
258 }
259
260
214 // The expected code pattern of an edge counter in unoptimized code: 261 // The expected code pattern of an edge counter in unoptimized code:
215 // 49 8b 87 imm32 mov RAX, [PP + offset] 262 // 49 8b 87 imm32 mov RAX, [PP + offset]
216 class EdgeCounter : public ValueObject { 263 class EdgeCounter : public ValueObject {
217 public: 264 public:
218 EdgeCounter(uword pc, const Code& code) 265 EdgeCounter(uword pc, const Code& code)
219 : end_(pc - FlowGraphCompiler::EdgeCounterIncrementSizeInBytes()), 266 : end_(pc - FlowGraphCompiler::EdgeCounterIncrementSizeInBytes()),
220 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { 267 object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
221 ASSERT(IsValid(end_)); 268 ASSERT(IsValid(end_));
222 } 269 }
223 270
(...skipping 14 matching lines...) Expand all
238 285
239 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { 286 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
240 ASSERT(code.ContainsInstructionAt(pc)); 287 ASSERT(code.ContainsInstructionAt(pc));
241 EdgeCounter counter(pc, code); 288 EdgeCounter counter(pc, code);
242 return counter.edge_counter(); 289 return counter.edge_counter();
243 } 290 }
244 291
245 } // namespace dart 292 } // namespace dart
246 293
247 #endif // defined TARGET_ARCH_X64 294 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_mips.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698