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

Side by Side Diff: runtime/vm/code_patcher_ia32.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_arm64.cc ('k') | runtime/vm/code_patcher_mips.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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"
(...skipping 26 matching lines...) Expand all
37 } 37 }
38 38
39 uword target() const { 39 uword target() const {
40 const uword offset = *reinterpret_cast<uword*>(call_address() + 1); 40 const uword offset = *reinterpret_cast<uword*>(call_address() + 1);
41 return return_address() + offset; 41 return return_address() + offset;
42 } 42 }
43 43
44 void set_target(uword target) const { 44 void set_target(uword target) const {
45 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1); 45 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1);
46 uword offset = target - return_address(); 46 uword offset = target - return_address();
47 WritableInstructionsScope writable(reinterpret_cast<uword>(target_addr),
48 sizeof(offset));
47 *target_addr = offset; 49 *target_addr = offset;
48 CPU::FlushICache(call_address(), kInstructionSize); 50 CPU::FlushICache(call_address(), kInstructionSize);
49 } 51 }
50 52
51 RawObject* ic_data() const { 53 RawObject* ic_data() const {
52 return *reinterpret_cast<RawObject**>(start_ + 1); 54 return *reinterpret_cast<RawObject**>(start_ + 1);
53 } 55 }
54 56
55 static const int kNumInstructions = 2; 57 static const int kNumInstructions = 2;
56 static const int kInstructionSize = 5; // All instructions have same length. 58 static const int kInstructionSize = 5; // All instructions have same length.
57 59
58 private: 60 private:
59 uword return_address() const { 61 uword return_address() const {
60 return start_ + kNumInstructions * kInstructionSize; 62 return start_ + kNumInstructions * kInstructionSize;
61 } 63 }
62 64
63 uword call_address() const { 65 uword call_address() const {
64 return start_ + 1 * kInstructionSize; 66 return start_ + 1 * kInstructionSize;
65 } 67 }
66 68
69 protected:
67 uword start_; 70 uword start_;
71
72 private:
68 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); 73 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
69 }; 74 };
70 75
71 76
77 class NativeCall : public UnoptimizedCall {
78 public:
79 explicit NativeCall(uword return_address) : UnoptimizedCall(return_address) {
80 }
81
82 NativeFunction native_function() const {
83 return *reinterpret_cast<NativeFunction*>(start_ + 1);
84 }
85
86 void set_native_function(NativeFunction func) const {
87 WritableInstructionsScope writable(start_ + 1, sizeof(func));
88 *reinterpret_cast<NativeFunction*>(start_ + 1) = func;
89 }
90
91 private:
92 DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall);
93 };
94
95
72 class InstanceCall : public UnoptimizedCall { 96 class InstanceCall : public UnoptimizedCall {
73 public: 97 public:
74 explicit InstanceCall(uword return_address) 98 explicit InstanceCall(uword return_address)
75 : UnoptimizedCall(return_address) { 99 : UnoptimizedCall(return_address) {
76 #if defined(DEBUG) 100 #if defined(DEBUG)
77 ICData& test_ic_data = ICData::Handle(); 101 ICData& test_ic_data = ICData::Handle();
78 test_ic_data ^= ic_data(); 102 test_ic_data ^= ic_data();
79 ASSERT(test_ic_data.NumArgsTested() > 0); 103 ASSERT(test_ic_data.NumArgsTested() > 0);
80 #endif // DEBUG 104 #endif // DEBUG
81 } 105 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 UnoptimizedStaticCall static_call(return_address); 227 UnoptimizedStaticCall static_call(return_address);
204 ICData& ic_data = ICData::Handle(); 228 ICData& ic_data = ICData::Handle();
205 ic_data ^= static_call.ic_data(); 229 ic_data ^= static_call.ic_data();
206 if (ic_data_result != NULL) { 230 if (ic_data_result != NULL) {
207 *ic_data_result = ic_data.raw(); 231 *ic_data_result = ic_data.raw();
208 } 232 }
209 return ic_data.GetTargetAt(0); 233 return ic_data.GetTargetAt(0);
210 } 234 }
211 235
212 236
237 void CodePatcher::PatchNativeCallAt(uword return_address,
238 const Code& code,
239 NativeFunction target,
240 const Code& trampoline) {
241 ASSERT(code.ContainsInstructionAt(return_address));
242 NativeCall call(return_address);
243 call.set_target(trampoline.EntryPoint());
244 call.set_native_function(target);
245 }
246
247
248 uword CodePatcher::GetNativeCallAt(uword return_address,
249 const Code& code,
250 NativeFunction* target) {
251 ASSERT(code.ContainsInstructionAt(return_address));
252 NativeCall call(return_address);
253 *target = call.native_function();
254 return call.target();
255 }
256
257
258
213 intptr_t CodePatcher::InstanceCallSizeInBytes() { 259 intptr_t CodePatcher::InstanceCallSizeInBytes() {
214 return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize; 260 return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
215 } 261 }
216 262
217 263
218 // The expected code pattern of an edge counter in unoptimized code: 264 // The expected code pattern of an edge counter in unoptimized code:
219 // b8 imm32 mov EAX, immediate 265 // b8 imm32 mov EAX, immediate
220 class EdgeCounter : public ValueObject { 266 class EdgeCounter : public ValueObject {
221 public: 267 public:
222 EdgeCounter(uword pc, const Code& ignored) 268 EdgeCounter(uword pc, const Code& ignored)
(...skipping 16 matching lines...) Expand all
239 285
240 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { 286 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) {
241 ASSERT(code.ContainsInstructionAt(pc)); 287 ASSERT(code.ContainsInstructionAt(pc));
242 EdgeCounter counter(pc, code); 288 EdgeCounter counter(pc, code);
243 return counter.edge_counter(); 289 return counter.edge_counter();
244 } 290 }
245 291
246 } // namespace dart 292 } // namespace dart
247 293
248 #endif // defined TARGET_ARCH_IA32 294 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_arm64.cc ('k') | runtime/vm/code_patcher_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698