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

Side by Side Diff: src/arm/assembler-arm-inl.h

Issue 1128009: Replace the constant pool access ldr instructions with movw/movt, and remove ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 return Assembler::target_address_at(pc_); 66 return Assembler::target_address_at(pc_);
67 } 67 }
68 68
69 69
70 Address RelocInfo::target_address_address() { 70 Address RelocInfo::target_address_address() {
71 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 71 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
72 return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_)); 72 return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_));
73 } 73 }
74 74
75 75
76 void RelocInfo::set_target_address(Address target) { 76 void RelocInfo::set_target_address(Address target, bool need_icache_flush) {
77 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 77 ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
78 Assembler::set_target_address_at(pc_, target); 78 Assembler::set_target_address_at(pc_, target, need_icache_flush);
79 } 79 }
80 80
81 81
82 Object* RelocInfo::target_object() { 82 Object* RelocInfo::target_object() {
83 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 83 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
84 return Memory::Object_at(Assembler::target_address_address_at(pc_)); 84 return Memory::Object_at(Assembler::target_address_address_at(pc_));
85 } 85 }
86 86
87 static uint32_t get_movw_movt_address(Address pc) {
88 Instr instr = Memory::int32_at(pc);
89 ASSERT((instr & kMovwMovtMask) == kMovwPattern);
90 Instr instr_movt = Memory::int32_at(pc + Assembler::kInstrSize);
91 int i = 0;
92 while ((instr_movt & kMovwMovtMask) != kMovtPattern) {
93 i++;
94 instr_movt = Memory::int32_at(pc + Assembler::kInstrSize * i);
95 }
96 ASSERT((instr_movt & kMovwMovtMask) == kMovtPattern);
97 uint32_t offset = ((instr & 0xf0000) >> 4) | (instr & 0xfff);
Erik Corry 2010/05/03 10:06:28 The name 'offset' seems wrong here. It's the imme
98 int32_t offset_movt = ((instr_movt & 0xf0000) >> 4) | (instr_movt & 0xfff);
99 offset = offset | offset_movt << 16;
100 return offset;
101 }
102
87 103
88 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) { 104 Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
89 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 105 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
90 return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_)); 106 Instr instr = Memory::int32_at(pc_);
107 if ((instr & kLdrMask) == kLdrPattern) {
108 return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_));
109 } else {
110 return reinterpret_cast<Object**>(get_movw_movt_address(pc_));
Erik Corry 2010/05/03 10:06:28 This seems wrong. This function is expected to re
111 }
91 } 112 }
92 113
93 114
94 Object** RelocInfo::target_object_address() { 115 Object** RelocInfo::target_object_address() {
95 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 116 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
96 return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_)); 117 return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_));
97 } 118 }
98 119
99 120
100 void RelocInfo::set_target_object(Object* target) { 121 void RelocInfo::set_target_object(Object* target, bool need_icache_flush) {
101 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 122 ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
102 Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 123 Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target),
Erik Corry 2010/05/03 10:06:28 If all arguments don't fit on one line it is neate
124 need_icache_flush);
103 } 125 }
104 126
105 127
106 Address* RelocInfo::target_reference_address() { 128 Address* RelocInfo::target_reference_address() {
107 ASSERT(rmode_ == EXTERNAL_REFERENCE); 129 ASSERT(rmode_ == EXTERNAL_REFERENCE);
108 return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_)); 130 return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_));
109 } 131 }
110 132
111 133
112 Address RelocInfo::call_address() { 134 Address RelocInfo::call_address() {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 259
238 #ifdef USE_BLX 260 #ifdef USE_BLX
239 // If we have a blx instruction, the instruction before it is 261 // If we have a blx instruction, the instruction before it is
240 // what needs to be patched. 262 // what needs to be patched.
241 if ((instr & kBlxRegMask) == kBlxRegPattern) { 263 if ((instr & kBlxRegMask) == kBlxRegPattern) {
242 target_pc -= kInstrSize; 264 target_pc -= kInstrSize;
243 instr = Memory::int32_at(target_pc); 265 instr = Memory::int32_at(target_pc);
244 } 266 }
245 #endif 267 #endif
246 268
247 // Verify that the instruction to patch is a 269 if ((instr & kLdrMask) == kLdrPattern) {
248 // ldr<cond> <Rd>, [pc +/- offset_12]. 270 int offset = instr & 0xfff; // offset_12 is unsigned
249 ASSERT((instr & 0x0f7f0000) == 0x051f0000); 271 // U bit defines offset sign
250 int offset = instr & 0xfff; // offset_12 is unsigned 272 if ((instr & (1 << 23)) == 0) offset = -offset;
251 if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign 273 // Verify that the constant pool comes after the instruction referencing it.
252 // Verify that the constant pool comes after the instruction referencing it. 274 ASSERT(offset >= -4);
253 ASSERT(offset >= -4); 275 return pc + offset + 8;
254 return target_pc + offset + 8; 276 } else {
277 return (Address) get_movw_movt_address(pc);
278 }
255 } 279 }
256 280
257 281
258 Address Assembler::target_address_at(Address pc) { 282 Address Assembler::target_address_at(Address pc) {
259 return Memory::Address_at(target_address_address_at(pc)); 283 Instr instr = Memory::int32_at(pc);
284 if ((instr & kLdrMask) == kLdrPattern) {
285 return Memory::Address_at(target_address_address_at(pc));
286 } else {
287 return (Address) get_movw_movt_address(pc);
288 }
260 } 289 }
261 290
262 291
263 void Assembler::set_target_at(Address constant_pool_entry, 292 void Assembler::set_target_at(Address constant_pool_entry,
264 Address target) { 293 Address target) {
265 Memory::Address_at(constant_pool_entry) = target; 294 Memory::Address_at(constant_pool_entry) = target;
266 } 295 }
267 296
268 297
269 void Assembler::set_target_address_at(Address pc, Address target) { 298 void Assembler::set_target_address_at(Address pc, Address target,
Erik Corry 2010/05/03 10:06:28 Please put arguments either on one line or on a li
270 Memory::Address_at(target_address_address_at(pc)) = target; 299 bool need_icache_flush) {
300 Instr instr = Memory::int32_at(pc);
301 if ((instr & kLdrMask) == kLdrPattern) {
302 Memory::Address_at(target_address_address_at(pc)) = target;
303 } else {
304 // movw movt instructions.
305 uint32_t* new_pc = reinterpret_cast<uint32_t*>(pc);
306 uint32_t new_addr = reinterpret_cast<uint32_t>(target);
307 *new_pc = (*new_pc & 0xfff0f000) | ((new_addr & 0xf000) << 4) |
Erik Corry 2010/05/03 10:06:28 Please give this constant, 0xfff0ff000, a name and
308 (new_addr & 0xfff);
309 Instr instr_movt = Memory::int32_at(pc + Assembler::kInstrSize);
310 int i = 1;
311 while ((instr_movt & kMovwMovtMask) != kMovtPattern) {
312 i++;
313 instr_movt = Memory::int32_at(pc + Assembler::kInstrSize * i);
314 }
315 ASSERT((instr_movt & kMovwMovtMask) == kMovtPattern);
316 int32_t new_movt_addr = new_addr >> 16;
317 *(new_pc + i) = (*(new_pc + i) & 0xfff0f000) |
318 ((new_movt_addr & 0xf000) << 4) | (new_movt_addr & 0xfff);
319 if (need_icache_flush)
Erik Corry 2010/05/03 10:06:28 Please use braces on multiline if statements. Thi
320 CPU::FlushICache(pc, sizeof(target));
Erik Corry 2010/05/03 10:06:28 sizeof(target) looks wrong here. With the loop ab
321 }
322
271 // Intuitively, we would think it is necessary to flush the instruction cache 323 // Intuitively, we would think it is necessary to flush the instruction cache
272 // after patching a target address in the code as follows: 324 // after patching a target address in the code as follows:
273 // CPU::FlushICache(pc, sizeof(target)); 325 // CPU::FlushICache(pc, sizeof(target));
274 // However, on ARM, no instruction was actually patched by the assignment 326 // However, on ARM, no instruction was actually patched by the assignment
275 // above; the target address is not part of an instruction, it is patched in 327 // above; the target address is not part of an instruction, it is patched in
276 // the constant pool and is read via a data access; the instruction accessing 328 // the constant pool and is read via a data access; the instruction accessing
277 // this address in the constant pool remains unchanged. 329 // this address in the constant pool remains unchanged.
278 } 330 }
279 331
280 } } // namespace v8::internal 332 } } // namespace v8::internal
281 333
282 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_ 334 #endif // V8_ARM_ASSEMBLER_ARM_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698