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
|