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

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

Issue 11783066: Optimize function at its entry instead of at exit. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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.cc ('k') | runtime/vm/code_patcher_x64.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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 call.set_target(new_target); 153 call.set_target(new_target);
154 } 154 }
155 155
156 156
157 void CodePatcher::PatchInstanceCallAt(uword return_address, uword new_target) { 157 void CodePatcher::PatchInstanceCallAt(uword return_address, uword new_target) {
158 InstanceCall call(return_address); 158 InstanceCall call(return_address);
159 call.set_target(new_target); 159 call.set_target(new_target);
160 } 160 }
161 161
162 162
163 static void SwapCode(intptr_t num_bytes, char* a, char* b) {
164 for (intptr_t i = 0; i < num_bytes; i++) {
165 char tmp = *a;
166 *a = *b;
167 *b = tmp;
168 a++;
169 b++;
170 }
171 }
172 163
173 164 void CodePatcher::InsertCallAt(uword start, uword target) {
174 // The patch code buffer contains the jmp code which will be inserted at 165 *reinterpret_cast<uint8_t*>(start) = 0xE8;
175 // entry point. 166 CallPattern call(start);
176 void CodePatcher::PatchEntry(const Code& code) { 167 call.SetTargetAddress(target);
177 JumpPattern jmp_entry(code.EntryPoint()); 168 CPU::FlushICache(start, CallPattern::InstructionLength());
178 ASSERT(!jmp_entry.IsValid());
179 const uword patch_buffer = code.GetPatchCodePc();
180 ASSERT(patch_buffer != 0);
181 JumpPattern jmp_patch(patch_buffer);
182 ASSERT(jmp_patch.IsValid());
183 const uword jump_target = jmp_patch.TargetAddress();
184 SwapCode(jmp_patch.pattern_length_in_bytes(),
185 reinterpret_cast<char*>(code.EntryPoint()),
186 reinterpret_cast<char*>(patch_buffer));
187 jmp_entry.SetTargetAddress(jump_target);
188 }
189
190
191 // The entry point is a jmp instruction, the patch code buffer contains
192 // original code, the entry point contains the jump instruction.
193 void CodePatcher::RestoreEntry(const Code& code) {
194 JumpPattern jmp_entry(code.EntryPoint());
195 ASSERT(jmp_entry.IsValid());
196 const uword jump_target = jmp_entry.TargetAddress();
197 const uword patch_buffer = code.GetPatchCodePc();
198 ASSERT(patch_buffer != 0);
199 // 'patch_buffer' contains original entry code.
200 JumpPattern jmp_patch(patch_buffer);
201 ASSERT(!jmp_patch.IsValid());
202 SwapCode(jmp_patch.pattern_length_in_bytes(),
203 reinterpret_cast<char*>(code.EntryPoint()),
204 reinterpret_cast<char*>(patch_buffer));
205 ASSERT(jmp_patch.IsValid());
206 jmp_patch.SetTargetAddress(jump_target);
207 }
208
209
210 bool CodePatcher::CodeIsPatchable(const Code& code) {
211 JumpPattern jmp_entry(code.EntryPoint());
212 if (code.Size() < (jmp_entry.pattern_length_in_bytes() * 2)) {
213 return false;
214 }
215 uword limit = code.EntryPoint() + jmp_entry.pattern_length_in_bytes();
216 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
217 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
218 if (addr < limit) {
219 return false;
220 }
221 }
222 return true;
223 } 169 }
224 170
225 171
226 bool CodePatcher::IsDartCall(uword return_address) { 172 bool CodePatcher::IsDartCall(uword return_address) {
227 return DartCallPattern::IsValid(return_address); 173 return DartCallPattern::IsValid(return_address);
228 } 174 }
229 175
230 176
231 uword CodePatcher::GetInstanceCallAt(uword return_address, 177 uword CodePatcher::GetInstanceCallAt(uword return_address,
232 ICData* ic_data, 178 ICData* ic_data,
233 Array* arguments_descriptor) { 179 Array* arguments_descriptor) {
234 InstanceCall call(return_address); 180 InstanceCall call(return_address);
235 if (ic_data != NULL) { 181 if (ic_data != NULL) {
236 *ic_data ^= call.ic_data(); 182 *ic_data ^= call.ic_data();
237 } 183 }
238 if (arguments_descriptor != NULL) { 184 if (arguments_descriptor != NULL) {
239 *arguments_descriptor ^= call.arguments_descriptor(); 185 *arguments_descriptor ^= call.arguments_descriptor();
240 } 186 }
241 return call.target(); 187 return call.target();
242 } 188 }
243 189
244 190
245 intptr_t CodePatcher::InstanceCallSizeInBytes() { 191 intptr_t CodePatcher::InstanceCallSizeInBytes() {
246 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize; 192 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize;
247 } 193 }
248 194
249
250 void CodePatcher::InsertCallAt(uword start, uword target) {
251 *reinterpret_cast<uint8_t*>(start) = 0xE8;
252 CallPattern call(start);
253 call.SetTargetAddress(target);
254 CPU::FlushICache(start, CallPattern::InstructionLength());
255 }
256
257
258 } // namespace dart 195 } // namespace dart
259 196
260 #endif // defined TARGET_ARCH_IA32 197 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_patcher.cc ('k') | runtime/vm/code_patcher_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698