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

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

Issue 11438017: Pass IC data and arguments descriptor to IC miss runtime functions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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.h ('k') | runtime/vm/code_patcher_ia32_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_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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1); 46 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1);
47 uword offset = target - return_address(); 47 uword offset = target - return_address();
48 *target_addr = offset; 48 *target_addr = offset;
49 CPU::FlushICache(call_address(), kInstructionSize); 49 CPU::FlushICache(call_address(), kInstructionSize);
50 } 50 }
51 51
52 RawObject* immediate_one() const { 52 RawObject* immediate_one() const {
53 return *reinterpret_cast<RawObject**>(start_ + 1); 53 return *reinterpret_cast<RawObject**>(start_ + 1);
54 } 54 }
55 55
56 void set_immediate_one(uint32_t value) {
57 uint32_t* target_addr = reinterpret_cast<uint32_t*>(start_ + 1);
58 *target_addr = value;
59 CPU::FlushICache(start_, kInstructionSize);
60 }
61
62 RawObject* immediate_two() const { 56 RawObject* immediate_two() const {
63 return *reinterpret_cast<RawObject**>(start_ + kInstructionSize + 1); 57 return *reinterpret_cast<RawObject**>(start_ + kInstructionSize + 1);
64 } 58 }
65 59
66 intptr_t argument_count() const {
67 ArgumentsDescriptor args_desc(immediate_two());
68 return args_desc.Count();
69 }
70
71 intptr_t named_argument_count() const {
72 ArgumentsDescriptor args_desc(immediate_two());
73 return args_desc.NamedCount();
74 }
75
76 static const int kNumInstructions = 3; 60 static const int kNumInstructions = 3;
77 static const int kInstructionSize = 5; // All instructions have same length. 61 static const int kInstructionSize = 5; // All instructions have same length.
78 62
79 private: 63 private:
80 uword return_address() const { 64 uword return_address() const {
81 return start_ + kNumInstructions * kInstructionSize; 65 return start_ + kNumInstructions * kInstructionSize;
82 } 66 }
83 67
84 uword call_address() const { 68 uword call_address() const {
85 return start_ + 2 * kInstructionSize; 69 return start_ + 2 * kInstructionSize;
86 } 70 }
87 71
88 uword start_; 72 uword start_;
89 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern); 73 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
90 }; 74 };
91 75
92 76
93 // The expected pattern of a dart instance call: 77 // The expected pattern of a dart instance call:
94 // mov ECX, ic-data 78 // mov ECX, ic-data
95 // mov EDX, arguments_descriptor_array 79 // mov EDX, arguments_descriptor_array
96 // call target_address 80 // call target_address
97 // <- return address 81 // <- return address
98 class InstanceCall : public DartCallPattern { 82 class InstanceCall : public DartCallPattern {
99 public: 83 public:
100 explicit InstanceCall(uword return_address) 84 explicit InstanceCall(uword return_address)
101 : DartCallPattern(return_address) {} 85 : DartCallPattern(return_address) {}
102 86
103 RawICData* ic_data() const { 87 RawObject* ic_data() const { return immediate_one(); }
104 ICData& ic_data = ICData::Handle(); 88 RawObject* arguments_descriptor() const { return immediate_two(); }
105 ic_data ^= immediate_one();
106 return ic_data.raw();
107 }
108 89
109 private: 90 private:
110 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 91 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
111 }; 92 };
112 93
113 94
114 // The expected pattern of a dart static call: 95 // The expected pattern of a dart static call:
115 // mov EDX, arguments_descriptor_array 96 // mov EDX, arguments_descriptor_array
116 // call target_address 97 // call target_address
117 // <- return address 98 // <- return address
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 221 }
241 return true; 222 return true;
242 } 223 }
243 224
244 225
245 bool CodePatcher::IsDartCall(uword return_address) { 226 bool CodePatcher::IsDartCall(uword return_address) {
246 return DartCallPattern::IsValid(return_address); 227 return DartCallPattern::IsValid(return_address);
247 } 228 }
248 229
249 230
250 void CodePatcher::GetInstanceCallAt(uword return_address, 231 uword CodePatcher::GetInstanceCallAt(uword return_address,
251 String* function_name, 232 ICData* ic_data,
252 int* num_arguments, 233 Array* arguments_descriptor) {
253 int* num_named_arguments,
254 uword* target) {
255 ASSERT(num_arguments != NULL);
256 ASSERT(num_named_arguments != NULL);
257 ASSERT(target != NULL);
258 InstanceCall call(return_address); 234 InstanceCall call(return_address);
259 *num_arguments = call.argument_count(); 235 if (ic_data != NULL) {
260 *num_named_arguments = call.named_argument_count(); 236 *ic_data ^= call.ic_data();
261 *target = call.target();
262 const ICData& ic_data = ICData::Handle(call.ic_data());
263 if (function_name != NULL) {
264 *function_name = ic_data.target_name();
265 } 237 }
238 if (arguments_descriptor != NULL) {
239 *arguments_descriptor ^= call.arguments_descriptor();
240 }
241 return call.target();
266 } 242 }
267 243
268 244
269 RawICData* CodePatcher::GetInstanceCallIcDataAt(uword return_address) {
270 InstanceCall call(return_address);
271 return call.ic_data();
272 }
273
274
275 intptr_t CodePatcher::InstanceCallSizeInBytes() { 245 intptr_t CodePatcher::InstanceCallSizeInBytes() {
276 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize; 246 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize;
277 } 247 }
278 248
279 249
280 void CodePatcher::InsertCallAt(uword start, uword target) { 250 void CodePatcher::InsertCallAt(uword start, uword target) {
281 *reinterpret_cast<uint8_t*>(start) = 0xE8; 251 *reinterpret_cast<uint8_t*>(start) = 0xE8;
282 CallPattern call(start); 252 CallPattern call(start);
283 call.SetTargetAddress(target); 253 call.SetTargetAddress(target);
284 CPU::FlushICache(start, CallPattern::InstructionLength()); 254 CPU::FlushICache(start, CallPattern::InstructionLength());
285 } 255 }
286 256
287 257
288 } // namespace dart 258 } // namespace dart
289 259
290 #endif // defined TARGET_ARCH_IA32 260 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher.h ('k') | runtime/vm/code_patcher_ia32_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698