204 } 205 } 206 207 address NativeMovConstReg::set_data_plain(intptr_t data, CodeBlob *cb) { 208 address addr = instruction_address(); 209 address next_address = NULL; 210 if (!cb) cb = CodeCache::find_blob(addr); 211 212 if (cb != NULL && MacroAssembler::is_load_const_from_method_toc_at(addr)) { 213 // A load from the method's TOC (ctable). 214 assert(cb->is_nmethod(), "must be nmethod"); 215 const address ctable = cb->content_begin(); 216 const int toc_offset = MacroAssembler::get_offset_of_load_const_from_method_toc_at(addr); 217 *(intptr_t *)(ctable + toc_offset) = data; 218 next_address = addr + BytesPerInstWord; 219 } else if (cb != NULL && 220 MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) { 221 // A calculation relative to the global TOC. 222 if (MacroAssembler::get_address_of_calculate_address_from_global_toc_at(addr, cb->content_begin()) != 223 (address)data) { 224 const int invalidated_range = 225 MacroAssembler::patch_calculate_address_from_global_toc_at(addr, cb->content_begin(), 226 (address)data); 227 const address start = invalidated_range < 0 ? addr + invalidated_range : addr; 228 // FIXME: 229 const int range = invalidated_range < 0 ? 4 - invalidated_range : 8; 230 ICache::ppc64_flush_icache_bytes(start, range); 231 } 232 next_address = addr + 1 * BytesPerInstWord; 233 } else if (MacroAssembler::is_load_const_at(addr)) { 234 // A normal 5 instruction load_const code sequence. 235 if (MacroAssembler::get_const(addr) != (long)data) { 236 // This is not mt safe, ok in methods like CodeBuffer::copy_code(). 237 MacroAssembler::patch_const(addr, (long)data); 238 ICache::ppc64_flush_icache_bytes(addr, load_const_instruction_size); 239 } 240 next_address = addr + 5 * BytesPerInstWord; 241 } else if (MacroAssembler::is_bl(* (int*) addr)) { 242 // A single branch-and-link instruction. 243 ResourceMark rm; 244 const int code_size = 1 * BytesPerInstWord; 245 CodeBuffer cb(addr, code_size + 1); 246 MacroAssembler* a = new MacroAssembler(&cb); 247 a->bl((address) data); 248 ICache::ppc64_flush_icache_bytes(addr, code_size); 249 next_address = addr + code_size; 274 assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); 275 } 276 } 277 if (iter.type() == relocInfo::metadata_type) { 278 metadata_Relocation *r = iter.metadata_reloc(); 279 if (metadata_addr == NULL) { 280 metadata_addr = r->metadata_addr(); 281 *metadata_addr = (Metadata*)data; 282 } else { 283 assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here"); 284 } 285 } 286 } 287 } 288 } 289 290 void NativeMovConstReg::set_narrow_oop(narrowOop data, CodeBlob *code /* = NULL */) { 291 address addr = addr_at(0); 292 CodeBlob* cb = (code) ? code : CodeCache::find_blob(instruction_address()); 293 if (MacroAssembler::get_narrow_oop(addr, cb->content_begin()) == (long)data) return; 294 const int invalidated_range = 295 MacroAssembler::patch_set_narrow_oop(addr, cb->content_begin(), (long)data); 296 const address start = invalidated_range < 0 ? addr + invalidated_range : addr; 297 // FIXME: 298 const int range = invalidated_range < 0 ? 4 - invalidated_range : 8; 299 ICache::ppc64_flush_icache_bytes(start, range); 300 } 301 302 // Do not use an assertion here. Let clients decide whether they only 303 // want this when assertions are enabled. 304 #ifdef ASSERT 305 void NativeMovConstReg::verify() { 306 address addr = addr_at(0); 307 if (! MacroAssembler::is_load_const_at(addr) && 308 ! MacroAssembler::is_load_const_from_method_toc_at(addr)) { 309 CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // find_nmethod() asserts if nmethod is zombie. 310 if (! (cb != NULL && MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) && 311 ! (cb != NULL && MacroAssembler::is_set_narrow_oop(addr, cb->content_begin())) && 312 ! MacroAssembler::is_bl(*((int*) addr))) { 313 tty->print_cr("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)); 314 // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty); 315 fatal("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)); 316 } 317 } 318 } | 204 } 205 } 206 207 address NativeMovConstReg::set_data_plain(intptr_t data, CodeBlob *cb) { 208 address addr = instruction_address(); 209 address next_address = NULL; 210 if (!cb) cb = CodeCache::find_blob(addr); 211 212 if (cb != NULL && MacroAssembler::is_load_const_from_method_toc_at(addr)) { 213 // A load from the method's TOC (ctable). 214 assert(cb->is_nmethod(), "must be nmethod"); 215 const address ctable = cb->content_begin(); 216 const int toc_offset = MacroAssembler::get_offset_of_load_const_from_method_toc_at(addr); 217 *(intptr_t *)(ctable + toc_offset) = data; 218 next_address = addr + BytesPerInstWord; 219 } else if (cb != NULL && 220 MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) { 221 // A calculation relative to the global TOC. 222 if (MacroAssembler::get_address_of_calculate_address_from_global_toc_at(addr, cb->content_begin()) != 223 (address)data) { 224 const int other_insn_offset = 225 MacroAssembler::patch_calculate_address_from_global_toc_at(addr, cb->content_begin(), 226 (address)data); 227 const address start = other_insn_offset < 0 ? addr + other_insn_offset : addr; 228 const int range = BytesPerInstWord + abs(other_insn_offset); 229 ICache::ppc64_flush_icache_bytes(start, range); 230 } 231 next_address = addr + 1 * BytesPerInstWord; 232 } else if (MacroAssembler::is_load_const_at(addr)) { 233 // A normal 5 instruction load_const code sequence. 234 if (MacroAssembler::get_const(addr) != (long)data) { 235 // This is not mt safe, ok in methods like CodeBuffer::copy_code(). 236 MacroAssembler::patch_const(addr, (long)data); 237 ICache::ppc64_flush_icache_bytes(addr, load_const_instruction_size); 238 } 239 next_address = addr + 5 * BytesPerInstWord; 240 } else if (MacroAssembler::is_bl(* (int*) addr)) { 241 // A single branch-and-link instruction. 242 ResourceMark rm; 243 const int code_size = 1 * BytesPerInstWord; 244 CodeBuffer cb(addr, code_size + 1); 245 MacroAssembler* a = new MacroAssembler(&cb); 246 a->bl((address) data); 247 ICache::ppc64_flush_icache_bytes(addr, code_size); 248 next_address = addr + code_size; 273 assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); 274 } 275 } 276 if (iter.type() == relocInfo::metadata_type) { 277 metadata_Relocation *r = iter.metadata_reloc(); 278 if (metadata_addr == NULL) { 279 metadata_addr = r->metadata_addr(); 280 *metadata_addr = (Metadata*)data; 281 } else { 282 assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here"); 283 } 284 } 285 } 286 } 287 } 288 289 void NativeMovConstReg::set_narrow_oop(narrowOop data, CodeBlob *code /* = NULL */) { 290 address addr = addr_at(0); 291 CodeBlob* cb = (code) ? code : CodeCache::find_blob(instruction_address()); 292 if (MacroAssembler::get_narrow_oop(addr, cb->content_begin()) == (long)data) return; 293 const int other_insn_offset = 294 MacroAssembler::patch_set_narrow_oop(addr, cb->content_begin(), (long)data); 295 const address start = other_insn_offset < 0 ? addr + other_insn_offset : addr; 296 const int range = BytesPerInstWord + abs(other_insn_offset); 297 ICache::ppc64_flush_icache_bytes(start, range); 298 } 299 300 // Do not use an assertion here. Let clients decide whether they only 301 // want this when assertions are enabled. 302 #ifdef ASSERT 303 void NativeMovConstReg::verify() { 304 address addr = addr_at(0); 305 if (! MacroAssembler::is_load_const_at(addr) && 306 ! MacroAssembler::is_load_const_from_method_toc_at(addr)) { 307 CodeBlob* cb = CodeCache::find_blob_unsafe(addr); // find_nmethod() asserts if nmethod is zombie. 308 if (! (cb != NULL && MacroAssembler::is_calculate_address_from_global_toc_at(addr, cb->content_begin())) && 309 ! (cb != NULL && MacroAssembler::is_set_narrow_oop(addr, cb->content_begin())) && 310 ! MacroAssembler::is_bl(*((int*) addr))) { 311 tty->print_cr("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)); 312 // TODO: PPC port: Disassembler::decode(addr, 20, 20, tty); 313 fatal("not a NativeMovConstReg at " PTR_FORMAT, p2i(addr)); 314 } 315 } 316 } |