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

Side by Side Diff: runtime/vm/code_patcher_x64.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_mips_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/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 // A Dart instance call passes the ic-data in RBX.
19 // 00: 48 bb imm64 mov RBX, immediate 1 19 // The expected pattern of a dart instance call:
20 // 10: 49 ba imm64 mov R10, immediate 2 20 // 00: 48 bb imm64 mov RBX, ic-data
21 // 20: 49 bb imm64 mov R11, target_address 21 // 10: 49 bb imm64 mov R11, target_address
22 // 30: 41 ff d3 call R11 22 // 20: 41 ff d3 call R11
23 // 33: <- return_address 23 // 23 <- return address
24 class DartCallPattern : public ValueObject { 24 class InstanceCall : public ValueObject {
25 public: 25 public:
26 explicit DartCallPattern(uword return_address) 26 explicit InstanceCall(uword return_address)
27 : start_(return_address - kCallPatternSize) { 27 : start_(return_address - kCallPatternSize) {
28 ASSERT(IsValid(return_address)); 28 ASSERT(IsValid(return_address));
29 ASSERT((kCallPatternSize - 20) == Assembler::kCallExternalLabelSize); 29 ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize);
30 } 30 }
31 31
32 static const int kCallPatternSize = 33; 32 static const int kCallPatternSize = 23;
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[00] == 0x48) && (code_bytes[01] == 0xBB) && 37 return (code_bytes[00] == 0x48) && (code_bytes[01] == 0xBB) &&
38 (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBA) && 38 (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) &&
39 (code_bytes[20] == 0x49) && (code_bytes[21] == 0xBB) && 39 (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) &&
40 (code_bytes[30] == 0x41) && (code_bytes[31] == 0xFF) && 40 (code_bytes[22] == 0xD3);
41 (code_bytes[32] == 0xD3); 41 }
42
43 RawObject* ic_data() const {
44 return *reinterpret_cast<RawObject**>(start_ + 0 + 2);
42 } 45 }
43 46
44 uword target() const { 47 uword target() const {
45 return *reinterpret_cast<uword*>(start_ + 20 + 2); 48 return *reinterpret_cast<uword*>(start_ + 10 + 2);
46 } 49 }
47 50
48 void set_target(uword target) const { 51 void set_target(uword target) const {
49 uword* target_addr = reinterpret_cast<uword*>(start_ + 20 + 2); 52 uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2);
50 *target_addr = target; 53 *target_addr = target;
51 CPU::FlushICache(start_ + 20, 2 + 8); 54 CPU::FlushICache(start_ + 10, 2 + 8);
52 }
53
54 RawObject* immediate_one() const {
55 return *reinterpret_cast<RawObject**>(start_ + 0 + 2);
56 }
57
58 RawObject* immediate_two() const {
59 return *reinterpret_cast<RawObject**>(start_ + 10 + 2);
60 } 55 }
61 56
62 private: 57 private:
63 uword start_; 58 uword start_;
64 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
65 };
66
67
68 // A Dart instance call passes the ic-data in RBX.
69 // The expected pattern of a dart instance call:
70 // mov RBX, ic-data
71 // mov R10, arguments_descriptor_array
72 // mov R11, target_address
73 // call R11
74 // <- return address
75 class InstanceCall : public DartCallPattern {
76 public:
77 explicit InstanceCall(uword return_address)
78 : DartCallPattern(return_address) {}
79
80 RawObject* ic_data() const { return immediate_one(); }
81 RawObject* arguments_descriptor() const { return immediate_two(); }
82
83 private:
84 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 59 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
85 }; 60 };
86 61
87 62
88 // The expected pattern of a dart static call: 63 // The expected pattern of a dart static call:
89 // mov R10, arguments_descriptor_array (10 bytes) (optional in polym. calls) 64 // mov R10, arguments_descriptor_array (10 bytes) (optional in polym. calls)
90 // mov R11, target_address (10 bytes) 65 // mov R11, target_address (10 bytes)
91 // call R11 (3 bytes) 66 // call R11 (3 bytes)
92 // <- return address 67 // <- return address
93 class StaticCall : public ValueObject { 68 class StaticCall : public ValueObject {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 const Code& code, 161 const Code& code,
187 uword new_target) { 162 uword new_target) {
188 ASSERT(code.ContainsInstructionAt(return_address)); 163 ASSERT(code.ContainsInstructionAt(return_address));
189 InstanceCall call(return_address); 164 InstanceCall call(return_address);
190 call.set_target(new_target); 165 call.set_target(new_target);
191 } 166 }
192 167
193 168
194 uword CodePatcher::GetInstanceCallAt(uword return_address, 169 uword CodePatcher::GetInstanceCallAt(uword return_address,
195 const Code& code, 170 const Code& code,
196 ICData* ic_data, 171 ICData* ic_data) {
197 Array* arguments_descriptor) {
198 ASSERT(code.ContainsInstructionAt(return_address)); 172 ASSERT(code.ContainsInstructionAt(return_address));
199 InstanceCall call(return_address); 173 InstanceCall call(return_address);
200 if (ic_data != NULL) { 174 if (ic_data != NULL) {
201 *ic_data ^= call.ic_data(); 175 *ic_data ^= call.ic_data();
202 } 176 }
203 if (arguments_descriptor != NULL) {
204 *arguments_descriptor ^= call.arguments_descriptor();
205 }
206 return call.target(); 177 return call.target();
207 } 178 }
208 179
209 180
210 intptr_t CodePatcher::InstanceCallSizeInBytes() { 181 intptr_t CodePatcher::InstanceCallSizeInBytes() {
211 return DartCallPattern::kCallPatternSize; 182 return InstanceCall::kCallPatternSize;
212 } 183 }
213 184
214 185
215 void CodePatcher::InsertCallAt(uword start, uword target) { 186 void CodePatcher::InsertCallAt(uword start, uword target) {
216 // The inserted call should not overlap the lazy deopt jump code. 187 // The inserted call should not overlap the lazy deopt jump code.
217 ASSERT(start + ShortCallPattern::InstructionLength() <= target); 188 ASSERT(start + ShortCallPattern::InstructionLength() <= target);
218 *reinterpret_cast<uint8_t*>(start) = 0xE8; 189 *reinterpret_cast<uint8_t*>(start) = 0xE8;
219 ShortCallPattern call(start); 190 ShortCallPattern call(start);
220 call.SetTargetAddress(target); 191 call.SetTargetAddress(target);
221 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); 192 CPU::FlushICache(start, ShortCallPattern::InstructionLength());
222 } 193 }
223 194
224 195
225 } // namespace dart 196 } // namespace dart
226 197
227 #endif // defined TARGET_ARCH_X64 198 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_mips_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