< prev index next >

src/hotspot/cpu/ppc/nativeInst_ppc.cpp

Print this page


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.


 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;
 250   } else {


 271           oop_addr = r->oop_addr();
 272           *oop_addr = cast_to_oop(data);
 273         } else {
 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 }
 319 #endif // ASSERT


   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.


 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 address inst2_addr = addr;
 225       const address inst1_addr =
 226         MacroAssembler::patch_calculate_address_from_global_toc_at(inst2_addr, cb->content_begin(),
 227                                                                    (address)data);
 228       assert(inst1_addr != NULL && inst1_addr < inst2_addr, "first instruction must be found");
 229       const int range = inst2_addr - inst1_addr + BytesPerInstWord;
 230       ICache::ppc64_flush_icache_bytes(inst1_addr, 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;
 250   } else {


 271           oop_addr = r->oop_addr();
 272           *oop_addr = cast_to_oop(data);
 273         } else {
 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   inst2_addr = addr_at(0);
 292   CodeBlob* cb = (code) ? code : CodeCache::find_blob(instruction_address());
 293   if (MacroAssembler::get_narrow_oop(inst2_addr, cb->content_begin()) == (long)data)
 294     return;
 295   const address inst1_addr =
 296     MacroAssembler::patch_set_narrow_oop(inst2_addr, cb->content_begin(), (long)data);
 297   assert(inst1_addr != NULL && inst1_addr < inst2_addr, "first instruction must be found");
 298   const int range = inst2_addr - inst1_addr + BytesPerInstWord;
 299   ICache::ppc64_flush_icache_bytes(inst1_addr, 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 }
 319 #endif // ASSERT


< prev index next >