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

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

Issue 17421003: Store arguments descriptor in ICData. Remove loading of arguments descriptor at unoptimized call si… (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_arm_test.cc ('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"
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 // The pattern of a Dart instance call is: 18 // The expected pattern of a dart instance call:
19 // 1: mov ECX, immediate 1 19 // mov ECX, ic-data
20 // 2: mov EDX, immediate 2 20 // call target_address
21 // 3: call target_address 21 // <- return address
22 // <- return_address 22 class InstanceCall : public ValueObject {
23 class DartCallPattern : public ValueObject {
24 public: 23 public:
25 explicit DartCallPattern(uword return_address) 24 explicit InstanceCall(uword return_address)
26 : start_(return_address - (kNumInstructions * kInstructionSize)) { 25 : start_(return_address - (kNumInstructions * kInstructionSize)) {
27 ASSERT(IsValid(return_address)); 26 ASSERT(IsValid(return_address));
28 ASSERT(kInstructionSize == Assembler::kCallExternalLabelSize); 27 ASSERT(kInstructionSize == Assembler::kCallExternalLabelSize);
29 } 28 }
30 29
31 static bool IsValid(uword return_address) { 30 static bool IsValid(uword return_address) {
32 uint8_t* code_bytes = 31 uint8_t* code_bytes =
33 reinterpret_cast<uint8_t*>( 32 reinterpret_cast<uint8_t*>(
34 return_address - (kNumInstructions * kInstructionSize)); 33 return_address - (kNumInstructions * kInstructionSize));
35 return (code_bytes[0] == 0xB9) && 34 return (code_bytes[0] == 0xB9) &&
36 (code_bytes[kInstructionSize] == 0xBA) && 35 (code_bytes[1 * kInstructionSize] == 0xE8);
37 (code_bytes[2 * kInstructionSize] == 0xE8);
38 } 36 }
39 37
40 uword target() const { 38 uword target() const {
41 const uword offset = *reinterpret_cast<uword*>(call_address() + 1); 39 const uword offset = *reinterpret_cast<uword*>(call_address() + 1);
42 return return_address() + offset; 40 return return_address() + offset;
43 } 41 }
44 42
45 void set_target(uword target) const { 43 void set_target(uword target) const {
46 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1); 44 uword* target_addr = reinterpret_cast<uword*>(call_address() + 1);
47 uword offset = target - return_address(); 45 uword offset = target - return_address();
48 *target_addr = offset; 46 *target_addr = offset;
49 CPU::FlushICache(call_address(), kInstructionSize); 47 CPU::FlushICache(call_address(), kInstructionSize);
50 } 48 }
51 49
52 RawObject* immediate_one() const { 50 RawObject* ic_data() const {
53 return *reinterpret_cast<RawObject**>(start_ + 1); 51 return *reinterpret_cast<RawObject**>(start_ + 1);
54 } 52 }
55 53
56 RawObject* immediate_two() const { 54 static const int kNumInstructions = 2;
57 return *reinterpret_cast<RawObject**>(start_ + kInstructionSize + 1);
58 }
59
60 static const int kNumInstructions = 3;
61 static const int kInstructionSize = 5; // All instructions have same length. 55 static const int kInstructionSize = 5; // All instructions have same length.
62 56
63 private: 57 private:
64 uword return_address() const { 58 uword return_address() const {
65 return start_ + kNumInstructions * kInstructionSize; 59 return start_ + kNumInstructions * kInstructionSize;
66 } 60 }
67 61
68 uword call_address() const { 62 uword call_address() const {
69 return start_ + 2 * kInstructionSize; 63 return start_ + 1 * kInstructionSize;
70 } 64 }
71 65
72 uword start_; 66 uword start_;
73 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
74 };
75
76
77 // The expected pattern of a dart instance call:
78 // mov ECX, ic-data
79 // mov EDX, arguments_descriptor_array
80 // call target_address
81 // <- return address
82 class InstanceCall : public DartCallPattern {
83 public:
84 explicit InstanceCall(uword return_address)
85 : DartCallPattern(return_address) {}
86
87 RawObject* ic_data() const { return immediate_one(); }
88 RawObject* arguments_descriptor() const { return immediate_two(); }
89
90 private:
91 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 67 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
92 }; 68 };
93 69
94 70
95 // The expected pattern of a dart static call: 71 // The expected pattern of a dart static call:
96 // mov EDX, arguments_descriptor_array (optional in polymorphic calls) 72 // mov EDX, arguments_descriptor_array (optional in polymorphic calls)
97 // call target_address 73 // call target_address
98 // <- return address 74 // <- return address
99 class StaticCall : public ValueObject { 75 class StaticCall : public ValueObject {
100 public: 76 public:
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 ASSERT(start + CallPattern::InstructionLength() <= target); 194 ASSERT(start + CallPattern::InstructionLength() <= target);
219 *reinterpret_cast<uint8_t*>(start) = 0xE8; 195 *reinterpret_cast<uint8_t*>(start) = 0xE8;
220 CallPattern call(start); 196 CallPattern call(start);
221 call.SetTargetAddress(target); 197 call.SetTargetAddress(target);
222 CPU::FlushICache(start, CallPattern::InstructionLength()); 198 CPU::FlushICache(start, CallPattern::InstructionLength());
223 } 199 }
224 200
225 201
226 uword CodePatcher::GetInstanceCallAt(uword return_address, 202 uword CodePatcher::GetInstanceCallAt(uword return_address,
227 const Code& code, 203 const Code& code,
228 ICData* ic_data, 204 ICData* ic_data) {
229 Array* arguments_descriptor) {
230 ASSERT(code.ContainsInstructionAt(return_address)); 205 ASSERT(code.ContainsInstructionAt(return_address));
231 InstanceCall call(return_address); 206 InstanceCall call(return_address);
232 if (ic_data != NULL) { 207 if (ic_data != NULL) {
233 *ic_data ^= call.ic_data(); 208 *ic_data ^= call.ic_data();
234 } 209 }
235 if (arguments_descriptor != NULL) {
236 *arguments_descriptor ^= call.arguments_descriptor();
237 }
238 return call.target(); 210 return call.target();
239 } 211 }
240 212
241 213
242 intptr_t CodePatcher::InstanceCallSizeInBytes() { 214 intptr_t CodePatcher::InstanceCallSizeInBytes() {
243 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize; 215 return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
244 } 216 }
245 217
246 } // namespace dart 218 } // namespace dart
247 219
248 #endif // defined TARGET_ARCH_IA32 220 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_arm_test.cc ('k') | runtime/vm/code_patcher_ia32_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698