nativeInst_ppc.hpp revision 6005:b858620b0081
1292236Sjhb/*
2292236Sjhb * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3292236Sjhb * Copyright 2012, 2013 SAP AG. All rights reserved.
4292236Sjhb * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5298107Sgjb *
6292236Sjhb * This code is free software; you can redistribute it and/or modify it
7292236Sjhb * under the terms of the GNU General Public License version 2 only, as
8311999Sjhb * published by the Free Software Foundation.
9292236Sjhb *
10292236Sjhb * This code is distributed in the hope that it will be useful, but WITHOUT
11311999Sjhb * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12313538Sngie * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13313538Sngie * version 2 for more details (a copy is included in the LICENSE file that
14294849Sjhb * accompanied this code).
15311999Sjhb *
16295931Sjhb * You should have received a copy of the GNU General Public License version
17311999Sjhb * 2 along with this work; if not, write to the Free Software Foundation,
18332247Stuexen * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19311999Sjhb *
20311999Sjhb * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21328454Sjhb * or visit www.oracle.com if you need additional information or have any
22292622Sjhb * questions.
23311999Sjhb *
24311999Sjhb */
25332244Stuexen
26311999Sjhb#ifndef CPU_PPC_VM_NATIVEINST_PPC_HPP
27311999Sjhb#define CPU_PPC_VM_NATIVEINST_PPC_HPP
28319417Stuexen
29294849Sjhb#include "asm/assembler.hpp"
30292236Sjhb#include "asm/macroAssembler.hpp"
31311999Sjhb#include "memory/allocation.hpp"
32311999Sjhb#include "runtime/icache.hpp"
33311999Sjhb#include "runtime/os.hpp"
34311999Sjhb#include "utilities/top.hpp"
35311999Sjhb
36311999Sjhb// We have interfaces for the following instructions:
37311999Sjhb//
38326044Sjhb// - NativeInstruction
39311999Sjhb//   - NativeCall
40311999Sjhb//   - NativeFarCall
41311999Sjhb//   - NativeMovConstReg
42311999Sjhb//   - NativeJump
43311999Sjhb//   - NativeIllegalInstruction
44311999Sjhb//   - NativeConditionalFarBranch
45311999Sjhb//   - NativeCallTrampolineStub
46311999Sjhb
47311999Sjhb// The base class for different kinds of native instruction abstractions.
48326044Sjhb// It provides the primitive operations to manipulate code relative to this.
49311999Sjhbclass NativeInstruction VALUE_OBJ_CLASS_SPEC {
50311999Sjhb  friend class Relocation;
51311999Sjhb
52311999Sjhb public:
53311999Sjhb  bool is_sigtrap_ic_miss_check() {
54311999Sjhb    assert(UseSIGTRAP, "precondition");
55332243Stuexen    return MacroAssembler::is_trap_ic_miss_check(long_at(0));
56311999Sjhb  }
57311999Sjhb
58311999Sjhb  bool is_sigtrap_null_check() {
59311999Sjhb    assert(UseSIGTRAP && TrapBasedNullChecks, "precondition");
60311999Sjhb    return MacroAssembler::is_trap_null_check(long_at(0));
61311999Sjhb  }
62311999Sjhb
63311999Sjhb  // We use a special trap for marking a method as not_entrant or zombie
64311999Sjhb  // iff UseSIGTRAP.
65311999Sjhb  bool is_sigtrap_zombie_not_entrant() {
66311999Sjhb    assert(UseSIGTRAP, "precondition");
67311999Sjhb    return MacroAssembler::is_trap_zombie_not_entrant(long_at(0));
68311999Sjhb  }
69311999Sjhb
70311999Sjhb  // We use an illtrap for marking a method as not_entrant or zombie
71326044Sjhb  // iff !UseSIGTRAP.
72311999Sjhb  bool is_sigill_zombie_not_entrant() {
73311999Sjhb    assert(!UseSIGTRAP, "precondition");
74311999Sjhb    // Work around a C++ compiler bug which changes 'this'.
75311999Sjhb    return NativeInstruction::is_sigill_zombie_not_entrant_at(addr_at(0));
76328454Sjhb  }
77328454Sjhb  static bool is_sigill_zombie_not_entrant_at(address addr);
78328454Sjhb
79311999Sjhb#ifdef COMPILER2
80326044Sjhb  // SIGTRAP-based implicit range checks
81311999Sjhb  bool is_sigtrap_range_check() {
82311999Sjhb    assert(UseSIGTRAP && TrapBasedRangeChecks, "precondition");
83311999Sjhb    return MacroAssembler::is_trap_range_check(long_at(0));
84311999Sjhb  }
85311999Sjhb#endif
86311999Sjhb
87311999Sjhb  // 'should not reach here'.
88311999Sjhb  bool is_sigtrap_should_not_reach_here() {
89311999Sjhb    return MacroAssembler::is_trap_should_not_reach_here(long_at(0));
90311999Sjhb  }
91311999Sjhb
92311999Sjhb  bool is_safepoint_poll() {
93311999Sjhb    // Is the current instruction a POTENTIAL read access to the polling page?
94311999Sjhb    // The current arguments of the instruction are not checked!
95311999Sjhb    return MacroAssembler::is_load_from_polling_page(long_at(0), NULL);
96311999Sjhb  }
97311999Sjhb
98311999Sjhb  bool is_memory_serialization(JavaThread *thread, void *ucontext) {
99332248Stuexen    // Is the current instruction a write access of thread to the
100332248Stuexen    // memory serialization page?
101332248Stuexen    return MacroAssembler::is_memory_serialization(long_at(0), thread, ucontext);
102311999Sjhb  }
103311999Sjhb
104311999Sjhb  address get_stack_bang_address(void *ucontext) {
105311999Sjhb    // If long_at(0) is not a stack bang, return 0. Otherwise, return
106311999Sjhb    // banged address.
107311999Sjhb    return MacroAssembler::get_stack_bang_address(long_at(0), ucontext);
108311999Sjhb  }
109292236Sjhb
110351891Sbdrewery protected:
111292622Sjhb  address  addr_at(int offset) const    { return address(this) + offset; }
112292622Sjhb  int      long_at(int offset) const    { return *(int*)addr_at(offset); }
113292622Sjhb
114292622Sjhb public:
115292622Sjhb  void verify() NOT_DEBUG_RETURN;
116292622Sjhb};
117292622Sjhb
118292622Sjhbinline NativeInstruction* nativeInstruction_at(address address) {
119292622Sjhb  NativeInstruction* inst = (NativeInstruction*)address;
120292622Sjhb  inst->verify();
121292622Sjhb  return inst;
122294849Sjhb}
123294849Sjhb
124294849Sjhb// The NativeCall is an abstraction for accessing/manipulating call
125294849Sjhb// instructions. It is used to manipulate inline caches, primitive &
126361020Sjhb// dll calls, etc.
127361020Sjhb//
128361020Sjhb// Sparc distinguishes `NativeCall' and `NativeFarCall'. On PPC64,
129361020Sjhb// at present, we provide a single class `NativeCall' representing the
130361020Sjhb// sequence `load_const, mtctr, bctrl' or the sequence 'ld_from_toc,
131361020Sjhb// mtctr, bctrl'.
132361020Sjhbclass NativeCall: public NativeInstruction {
133292622Sjhb public:
134292622Sjhb
135311999Sjhb  enum ppc_specific_constants {
136311999Sjhb    load_const_instruction_size                 = 28,
137311999Sjhb    load_const_from_method_toc_instruction_size = 16,
138311999Sjhb    instruction_size                            = 16 // Used in shared code for calls with reloc_info.
139311999Sjhb  };
140311999Sjhb
141311999Sjhb  static bool is_call_at(address a) {
142311999Sjhb    return Assembler::is_bl(*(int*)(a));
143311999Sjhb  }
144311999Sjhb
145321687Skp  static bool is_call_before(address return_address) {
146292622Sjhb    return NativeCall::is_call_at(return_address - 4);
147292622Sjhb  }
148311999Sjhb
149292622Sjhb  address instruction_address() const {
150292236Sjhb    return addr_at(0);
151  }
152
153  address next_instruction_address() const {
154    // We have only bl.
155    assert(MacroAssembler::is_bl(*(int*)instruction_address()), "Should be bl instruction!");
156    return addr_at(4);
157  }
158
159  address return_address() const {
160    return next_instruction_address();
161  }
162
163  address destination() const;
164
165  // The parameter assert_lock disables the assertion during code generation.
166  void set_destination_mt_safe(address dest, bool assert_lock = true);
167
168  address get_trampoline();
169
170  void verify_alignment() {} // do nothing on ppc
171  void verify() NOT_DEBUG_RETURN;
172};
173
174inline NativeCall* nativeCall_at(address instr) {
175  NativeCall* call = (NativeCall*)instr;
176  call->verify();
177  return call;
178}
179
180inline NativeCall* nativeCall_before(address return_address) {
181  NativeCall* call = NULL;
182  if (MacroAssembler::is_bl(*(int*)(return_address - 4)))
183    call = (NativeCall*)(return_address - 4);
184  call->verify();
185  return call;
186}
187
188// The NativeFarCall is an abstraction for accessing/manipulating native
189// call-anywhere instructions.
190// Used to call native methods which may be loaded anywhere in the address
191// space, possibly out of reach of a call instruction.
192class NativeFarCall: public NativeInstruction {
193 public:
194  // We use MacroAssembler::bl64_patchable() for implementing a
195  // call-anywhere instruction.
196
197  // Checks whether instr points at a NativeFarCall instruction.
198  static bool is_far_call_at(address instr) {
199    return MacroAssembler::is_bl64_patchable_at(instr);
200  }
201
202  // Does the NativeFarCall implementation use a pc-relative encoding
203  // of the call destination?
204  // Used when relocating code.
205  bool is_pcrelative() {
206    assert(MacroAssembler::is_bl64_patchable_at((address)this),
207           "unexpected call type");
208    return MacroAssembler::is_bl64_patchable_pcrelative_at((address)this);
209  }
210
211  // Returns the NativeFarCall's destination.
212  address destination() const {
213    assert(MacroAssembler::is_bl64_patchable_at((address)this),
214           "unexpected call type");
215    return MacroAssembler::get_dest_of_bl64_patchable_at((address)this);
216  }
217
218  // Sets the NativeCall's destination, not necessarily mt-safe.
219  // Used when relocating code.
220  void set_destination(address dest) {
221    // Set new destination (implementation of call may change here).
222    assert(MacroAssembler::is_bl64_patchable_at((address)this),
223           "unexpected call type");
224    MacroAssembler::set_dest_of_bl64_patchable_at((address)this, dest);
225  }
226
227  void verify() NOT_DEBUG_RETURN;
228};
229
230// Instantiates a NativeFarCall object starting at the given instruction
231// address and returns the NativeFarCall object.
232inline NativeFarCall* nativeFarCall_at(address instr) {
233  NativeFarCall* call = (NativeFarCall*)instr;
234  call->verify();
235  return call;
236}
237
238// An interface for accessing/manipulating native set_oop imm, reg instructions.
239// (used to manipulate inlined data references, etc.)
240class NativeMovConstReg: public NativeInstruction {
241 public:
242
243  enum ppc_specific_constants {
244    load_const_instruction_size                 = 20,
245    load_const_from_method_toc_instruction_size =  8,
246    instruction_size                            =  8 // Used in shared code for calls with reloc_info.
247  };
248
249  address instruction_address() const {
250    return addr_at(0);
251  }
252
253  address next_instruction_address() const;
254
255  // (The [set_]data accessor respects oop_type relocs also.)
256  intptr_t data() const;
257
258  // Patch the code stream.
259  address set_data_plain(intptr_t x, CodeBlob *code);
260  // Patch the code stream and oop pool.
261  void set_data(intptr_t x);
262
263  // Patch narrow oop constants. Use this also for narrow klass.
264  void set_narrow_oop(narrowOop data, CodeBlob *code = NULL);
265
266  void verify() NOT_DEBUG_RETURN;
267};
268
269inline NativeMovConstReg* nativeMovConstReg_at(address address) {
270  NativeMovConstReg* test = (NativeMovConstReg*)address;
271  test->verify();
272  return test;
273}
274
275// The NativeJump is an abstraction for accessing/manipulating native
276// jump-anywhere instructions.
277class NativeJump: public NativeInstruction {
278 public:
279  // We use MacroAssembler::b64_patchable() for implementing a
280  // jump-anywhere instruction.
281
282  enum ppc_specific_constants {
283    instruction_size = MacroAssembler::b64_patchable_size
284  };
285
286  // Checks whether instr points at a NativeJump instruction.
287  static bool is_jump_at(address instr) {
288    return MacroAssembler::is_b64_patchable_at(instr)
289      || (   MacroAssembler::is_load_const_from_method_toc_at(instr)
290          && Assembler::is_mtctr(*(int*)(instr + 2 * 4))
291          && Assembler::is_bctr(*(int*)(instr + 3 * 4)));
292  }
293
294  // Does the NativeJump implementation use a pc-relative encoding
295  // of the call destination?
296  // Used when relocating code or patching jumps.
297  bool is_pcrelative() {
298    return MacroAssembler::is_b64_patchable_pcrelative_at((address)this);
299  }
300
301  // Returns the NativeJump's destination.
302  address jump_destination() const {
303    if (MacroAssembler::is_b64_patchable_at((address)this)) {
304      return MacroAssembler::get_dest_of_b64_patchable_at((address)this);
305    } else if (MacroAssembler::is_load_const_from_method_toc_at((address)this)
306               && Assembler::is_mtctr(*(int*)((address)this + 2 * 4))
307               && Assembler::is_bctr(*(int*)((address)this + 3 * 4))) {
308      return (address)((NativeMovConstReg *)this)->data();
309    } else {
310      ShouldNotReachHere();
311      return NULL;
312    }
313  }
314
315  // Sets the NativeJump's destination, not necessarily mt-safe.
316  // Used when relocating code or patching jumps.
317  void set_jump_destination(address dest) {
318    // Set new destination (implementation of call may change here).
319    if (MacroAssembler::is_b64_patchable_at((address)this)) {
320      MacroAssembler::set_dest_of_b64_patchable_at((address)this, dest);
321    } else if (MacroAssembler::is_load_const_from_method_toc_at((address)this)
322               && Assembler::is_mtctr(*(int*)((address)this + 2 * 4))
323               && Assembler::is_bctr(*(int*)((address)this + 3 * 4))) {
324      ((NativeMovConstReg *)this)->set_data((intptr_t)dest);
325    } else {
326      ShouldNotReachHere();
327    }
328  }
329
330  // MT-safe insertion of native jump at verified method entry
331  static void patch_verified_entry(address entry, address verified_entry, address dest);
332
333  void verify() NOT_DEBUG_RETURN;
334
335  static void check_verified_entry_alignment(address entry, address verified_entry) {
336    // We just patch one instruction on ppc64, so the jump doesn't have to
337    // be aligned. Nothing to do here.
338  }
339};
340
341// Instantiates a NativeJump object starting at the given instruction
342// address and returns the NativeJump object.
343inline NativeJump* nativeJump_at(address instr) {
344  NativeJump* call = (NativeJump*)instr;
345  call->verify();
346  return call;
347}
348
349// NativeConditionalFarBranch is abstraction for accessing/manipulating
350// conditional far branches.
351class NativeConditionalFarBranch : public NativeInstruction {
352 public:
353
354  static bool is_conditional_far_branch_at(address instr) {
355    return MacroAssembler::is_bc_far_at(instr);
356  }
357
358  address branch_destination() const {
359    return MacroAssembler::get_dest_of_bc_far_at((address)this);
360  }
361
362  void set_branch_destination(address dest) {
363    MacroAssembler::set_dest_of_bc_far_at((address)this, dest);
364  }
365};
366
367inline NativeConditionalFarBranch* NativeConditionalFarBranch_at(address address) {
368  assert(NativeConditionalFarBranch::is_conditional_far_branch_at(address),
369         "must be a conditional far branch");
370  return (NativeConditionalFarBranch*)address;
371}
372
373// Call trampoline stubs.
374class NativeCallTrampolineStub : public NativeInstruction {
375 private:
376
377  address encoded_destination_addr() const;
378
379 public:
380
381  address destination(nmethod *nm = NULL) const;
382  int destination_toc_offset() const;
383
384  void set_destination(address new_destination);
385};
386
387inline bool is_NativeCallTrampolineStub_at(address address) {
388  int first_instr = *(int*)address;
389  return Assembler::is_addis(first_instr) &&
390    (Register)(intptr_t)Assembler::inv_rt_field(first_instr) == R12_scratch2;
391}
392
393inline NativeCallTrampolineStub* NativeCallTrampolineStub_at(address address) {
394  assert(is_NativeCallTrampolineStub_at(address), "no call trampoline found");
395  return (NativeCallTrampolineStub*)address;
396}
397
398#endif // CPU_PPC_VM_NATIVEINST_PPC_HPP
399