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

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

Issue 11419073: Remove loading of function object in static calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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_ia32.cc ('k') | runtime/vm/flow_graph_compiler_ia32.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/instructions.h" 11 #include "vm/instructions.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/raw_object.h" 13 #include "vm/raw_object.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 // The pattern of a Dart call is: 17 // The pattern of a Dart instance call is:
18 // 00: 48 bb imm64 mov RBX, immediate 1 18 // 00: 48 bb imm64 mov RBX, immediate 1
19 // 10: 49 ba imm64 mov R10, immediate 2 19 // 10: 49 ba imm64 mov R10, immediate 2
20 // 20: 49 bb imm64 mov R11, target_address 20 // 20: 49 bb imm64 mov R11, target_address
21 // 30: 41 ff d3 call R11 21 // 30: 41 ff d3 call R11
22 // 33: <- return_address 22 // 33: <- return_address
23 class DartCallPattern : public ValueObject { 23 class DartCallPattern : public ValueObject {
24 public: 24 public:
25 explicit DartCallPattern(uword return_address) 25 explicit DartCallPattern(uword return_address)
26 : start_(return_address - kCallPatternSize) { 26 : start_(return_address - kCallPatternSize) {
27 ASSERT(IsValid(return_address)); 27 ASSERT(IsValid(return_address));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 Smi& num_pos_args = Smi::Handle(); 80 Smi& num_pos_args = Smi::Handle();
81 num_pos_args ^= args_desc.At(1); 81 num_pos_args ^= args_desc.At(1);
82 return num_args.Value() - num_pos_args.Value(); 82 return num_args.Value() - num_pos_args.Value();
83 } 83 }
84 84
85 uword start_; 85 uword start_;
86 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern); 86 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern);
87 }; 87 };
88 88
89 89
90 // A Dart static call passes the function object in RBX.
91 class StaticCall : public DartCallPattern {
92 public:
93 explicit StaticCall(uword return_address)
94 : DartCallPattern(return_address) {}
95
96 RawFunction* function() const {
97 Function& f = Function::Handle();
98 f ^= reinterpret_cast<RawObject*>(immediate_one());
99 return f.raw();
100 }
101
102 private:
103 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
104 };
105
106
107 // A Dart instance call passes the ic-data in RBX. 90 // A Dart instance call passes the ic-data in RBX.
91 // The expected pattern of a dart instance call:
92 // mov RBX, ic-data
93 // mov R10, argument_descriptor_array
94 // mov R11, target_address
95 // call R11
96 // <- return address
108 class InstanceCall : public DartCallPattern { 97 class InstanceCall : public DartCallPattern {
109 public: 98 public:
110 explicit InstanceCall(uword return_address) 99 explicit InstanceCall(uword return_address)
111 : DartCallPattern(return_address) {} 100 : DartCallPattern(return_address) {}
112 101
113 RawICData* ic_data() const { 102 RawICData* ic_data() const {
114 ICData& ic_data = ICData::Handle(); 103 ICData& ic_data = ICData::Handle();
115 ic_data ^= reinterpret_cast<RawObject*>(immediate_one()); 104 ic_data ^= reinterpret_cast<RawObject*>(immediate_one());
116 return ic_data.raw(); 105 return ic_data.raw();
117 } 106 }
118 107
119 private: 108 private:
120 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); 109 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall);
121 }; 110 };
122 111
123 112
113 // The expected pattern of a dart static call:
114 // mov R10, argument_descriptor_array (10 bytes)
115 // mov R11, target_address (10 bytes)
116 // call R11 (3 bytes)
117 // <- return address
118 class StaticCall : public ValueObject {
119 public:
120 explicit StaticCall(uword return_address)
121 : start_(return_address - kCallPatternSize) {
122 ASSERT(IsValid(return_address));
123 ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize);
124 }
125
126 static const int kCallPatternSize = 23;
127
128 static bool IsValid(uword return_address) {
129 uint8_t* code_bytes =
130 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
131 return (code_bytes[00] == 0x49) && (code_bytes[01] == 0xBA) &&
132 (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) &&
133 (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) &&
134 (code_bytes[22] == 0xD3);
135 }
136
137 uword target() const {
138 return *reinterpret_cast<uword*>(start_ + 10 + 2);
139 }
140
141 void set_target(uword target) const {
142 uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2);
143 *target_addr = target;
144 CPU::FlushICache(start_ + 10, 2 + 8);
145 }
146
147 private:
148 uword start_;
149
150 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
151 };
152
153
124 uword CodePatcher::GetStaticCallTargetAt(uword return_address) { 154 uword CodePatcher::GetStaticCallTargetAt(uword return_address) {
125 StaticCall call(return_address); 155 StaticCall call(return_address);
126 return call.target(); 156 return call.target();
127 } 157 }
128 158
129 159
130 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) { 160 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) {
131 StaticCall call(return_address); 161 StaticCall call(return_address);
132 call.set_target(new_target); 162 call.set_target(new_target);
133 } 163 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 *reinterpret_cast<uint8_t*>(start) = 0xE8; 271 *reinterpret_cast<uint8_t*>(start) = 0xE8;
242 ShortCallPattern call(start); 272 ShortCallPattern call(start);
243 call.SetTargetAddress(target); 273 call.SetTargetAddress(target);
244 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); 274 CPU::FlushICache(start, ShortCallPattern::InstructionLength());
245 } 275 }
246 276
247 277
248 } // namespace dart 278 } // namespace dart
249 279
250 #endif // defined TARGET_ARCH_X64 280 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher_ia32.cc ('k') | runtime/vm/flow_graph_compiler_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698