annotate src/cpu/sparc/vm/nativeInst_sparc.cpp @ 6812:988bf00cc564

7200261: G1: Liveness counting inconsistencies during marking verification Summary: The clipping code in the routine that sets the bits for a range of cards, in the liveness accounting verification code was incorrect. It set all the bits in the card bitmap from the given starting index which would lead to spurious marking verification failures. Reviewed-by: brutisso, jwilhelm, jmasa
author johnc
date Thu, 27 Sep 2012 15:44:01 -0700
parents da91efe96a93
children f0c2369fda5a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 727
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 727
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 727
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
26 #include "assembler_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
27 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
28 #include "nativeInst_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
29 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
30 #include "runtime/handles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
31 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
32 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
33 #include "utilities/ostream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
34 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
35 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1748
diff changeset
36 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 0
diff changeset
39 bool NativeInstruction::is_dtrace_trap() {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 0
diff changeset
40 return !is_nop();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 0
diff changeset
41 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 0
diff changeset
42
0
a61af66fc99e Initial load
duke
parents:
diff changeset
43 void NativeInstruction::set_data64_sethi(address instaddr, intptr_t x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
44 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 CodeBuffer buf(instaddr, 10 * BytesPerInstWord );
a61af66fc99e Initial load
duke
parents:
diff changeset
46 MacroAssembler* _masm = new MacroAssembler(&buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 Register destreg;
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 destreg = inv_rd(*(unsigned int *)instaddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Generate a the new sequence
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
51 _masm->patchable_sethi(x, destreg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
52 ICache::invalidate_range(instaddr, 7 * BytesPerInstWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
2375
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
55 void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) {
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
56 ResourceMark rm;
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
57 unsigned char buffer[10 * BytesPerInstWord];
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
58 CodeBuffer buf(buffer, 10 * BytesPerInstWord);
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
59 MacroAssembler masm(&buf);
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
60
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
61 Register destreg = inv_rd(*(unsigned int *)instaddr);
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
62 // Generate the proper sequence into a temporary buffer and compare
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
63 // it with the original sequence.
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
64 masm.patchable_sethi(x, destreg);
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
65 int len = buffer - masm.pc();
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
66 for (int i = 0; i < len; i++) {
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
67 assert(instaddr[i] == buffer[i], "instructions must match");
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
68 }
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
69 }
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 1972
diff changeset
70
0
a61af66fc99e Initial load
duke
parents:
diff changeset
71 void NativeInstruction::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // make sure code pattern is actually an instruction address
a61af66fc99e Initial load
duke
parents:
diff changeset
73 address addr = addr_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 if (addr == 0 || ((intptr_t)addr & 3) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 fatal("not an instruction address");
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 void NativeInstruction::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 tty->print_cr(INTPTR_FORMAT ": 0x%x", addr_at(0), long_at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
81 }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 void NativeInstruction::set_long_at(int offset, int i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 address addr = addr_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
85 *(int*)addr = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 ICache::invalidate_word(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 void NativeInstruction::set_jlong_at(int offset, jlong i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 address addr = addr_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 *(jlong*)addr = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // Don't need to invalidate 2 words here, because
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // the flush instruction operates on doublewords.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 ICache::invalidate_word(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void NativeInstruction::set_addr_at(int offset, address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 address addr = addr_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 assert( ((intptr_t)addr & (wordSize-1)) == 0, "set_addr_at bad address alignment");
a61af66fc99e Initial load
duke
parents:
diff changeset
100 *(uintptr_t*)addr = (uintptr_t)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Don't need to invalidate 2 words here in the 64-bit case,
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // because the flush instruction operates on doublewords.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 ICache::invalidate_word(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // The Intel code has this assertion for NativeCall::set_destination,
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // NativeMovConstReg::set_data, NativeMovRegMem::set_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // NativeJump::set_jump_destination, and NativePushImm32::set_data
a61af66fc99e Initial load
duke
parents:
diff changeset
107 //assert (Patching_lock->owned_by_self(), "must hold lock to patch instruction")
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 bool NativeInstruction::is_zero_test(Register &reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 int x = long_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 Assembler::op3s temp = (Assembler::op3s) (Assembler::sub_op3 | Assembler::cc_bit_op3);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (is_op3(x, temp, Assembler::arith_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
114 inv_immed(x) && inv_rd(x) == G0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 if (inv_rs1(x) == G0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 reg = inv_rs2(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 } else if (inv_rs2(x) == G0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 reg = inv_rs1(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 bool NativeInstruction::is_load_store_with_small_offset(Register reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 int x = long_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
128 if (is_op(x, Assembler::ldst_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
129 inv_rs1(x) == reg && inv_immed(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 void NativeCall::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 NativeInstruction::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // make sure code pattern is actually a call instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
138 if (!is_op(long_at(0), Assembler::call_op)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 fatal("not a call");
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void NativeCall::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
144 tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination());
a61af66fc99e Initial load
duke
parents:
diff changeset
145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // MT-safe patching of a call instruction (and following word).
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // First patches the second word, and then atomicly replaces
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // the first word with the first new instruction word.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Other processors might briefly see the old first word
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // followed by the new second word. This is OK if the old
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // second word is harmless, and the new second word may be
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // harmlessly executed in the delay slot of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
155 void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 assert(Patching_lock->is_locked() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
157 SafepointSynchronize::is_at_safepoint(), "concurrent code patching");
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert (instr_addr != NULL, "illegal address for code patching");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 NativeCall* n_call = nativeCall_at (instr_addr); // checking that it is a call
a61af66fc99e Initial load
duke
parents:
diff changeset
160 assert(NativeCall::instruction_size == 8, "wrong instruction size; must be 8");
a61af66fc99e Initial load
duke
parents:
diff changeset
161 int i0 = ((int*)code_buffer)[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
162 int i1 = ((int*)code_buffer)[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
163 int* contention_addr = (int*) n_call->addr_at(1*BytesPerInstWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 assert(inv_op(*contention_addr) == Assembler::arith_op ||
a61af66fc99e Initial load
duke
parents:
diff changeset
165 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
a61af66fc99e Initial load
duke
parents:
diff changeset
166 "must not interfere with original call");
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order
a61af66fc99e Initial load
duke
parents:
diff changeset
168 n_call->set_long_at(1*BytesPerInstWord, i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 n_call->set_long_at(0*BytesPerInstWord, i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // NOTE: It is possible that another thread T will execute
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // only the second patched word.
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // In other words, since the original instruction is this
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // call patching_stub; nop (NativeCall)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // and the new sequence from the buffer is this:
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg)
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // what T will execute is this:
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // call patching_stub; add %r, %lo(K), %r
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // thereby putting garbage into %r before calling the patching stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // This is OK, because the patching stub ignores the value of %r.
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Make sure the first-patched instruction, which may co-exist
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // briefly with the call, will do something harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 assert(inv_op(*contention_addr) == Assembler::arith_op ||
a61af66fc99e Initial load
duke
parents:
diff changeset
184 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
a61af66fc99e Initial load
duke
parents:
diff changeset
185 "must not interfere with original call");
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Similar to replace_mt_safe, but just changes the destination. The
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // important thing is that free-running threads are able to execute this
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // call instruction at all times. Thus, the displacement field must be
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // instruction-word-aligned. This is always true on SPARC.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 //
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // Used in the runtime linkage of calls; see class CompiledIC.
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void NativeCall::set_destination_mt_safe(address dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 assert(Patching_lock->is_locked() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
196 SafepointSynchronize::is_at_safepoint(), "concurrent code patching");
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // set_destination uses set_long_at which does the ICache::invalidate
a61af66fc99e Initial load
duke
parents:
diff changeset
198 set_destination(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // Code for unit testing implementation of NativeCall class
a61af66fc99e Initial load
duke
parents:
diff changeset
202 void NativeCall::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
204 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 CodeBuffer cb("test", 100, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 NativeCall *nc;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 0xfffffff0,
a61af66fc99e Initial load
duke
parents:
diff changeset
212 0x7ffffff0,
a61af66fc99e Initial load
duke
parents:
diff changeset
213 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
214 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
215 0x4000,
a61af66fc99e Initial load
duke
parents:
diff changeset
216 };
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 a->call( a->pc(), relocInfo::none );
a61af66fc99e Initial load
duke
parents:
diff changeset
221 a->delayed()->nop();
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
222 nc = nativeCall_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
223 nc->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 nc = nativeCall_overwriting_at( nc->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
226 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
227 nc->set_destination( cb.insts_begin() + offsets[idx] );
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
228 assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
229 nc->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
232 nc = nativeCall_before( cb.insts_begin() + 8 );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
233 nc->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
236 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // End code for unit testing implementation of NativeCall class
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 //-------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 void NativeFarCall::set_destination(address dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // Address materialized in the instruction stream, so nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #if 0 // What we'd do if we really did want to change the destination
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (destination() == dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 CodeBuffer buf(addr_at(0), instruction_size + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
253 MacroAssembler* _masm = new MacroAssembler(&buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Generate the new sequence
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
255 AddressLiteral(dest);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
256 _masm->jumpl_to(dest, O7, O7);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
257 ICache::invalidate_range(addr_at(0), instruction_size );
a61af66fc99e Initial load
duke
parents:
diff changeset
258 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 void NativeFarCall::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // make sure code pattern is actually a jumpl_to instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
263 assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to");
a61af66fc99e Initial load
duke
parents:
diff changeset
264 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
a61af66fc99e Initial load
duke
parents:
diff changeset
265 nativeJump_at(addr_at(0))->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 bool NativeFarCall::is_call_at(address instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 return nativeInstruction_at(instr)->is_sethi();
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 void NativeFarCall::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination());
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 bool NativeFarCall::destination_is_compiled_verified_entry_point() {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 nmethod* callee = CodeCache::find_nmethod(destination());
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (callee == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 return destination() == callee->verified_entry_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // MT-safe patching of a far call.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Code for unit testing implementation of NativeFarCall class
a61af66fc99e Initial load
duke
parents:
diff changeset
291 void NativeFarCall::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // End code for unit testing implementation of NativeFarCall class
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 #endif // _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 //-------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 void NativeMovConstReg::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 NativeInstruction::verify();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
303 // make sure code pattern is actually a "set_metadata" synthetic instruction
0
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // see MacroAssembler::set_oop()
a61af66fc99e Initial load
duke
parents:
diff changeset
305 int i0 = long_at(sethi_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 int i1 = long_at(add_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg"
a61af66fc99e Initial load
duke
parents:
diff changeset
309 Register rd = inv_rd(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
312 is_op3(i1, Assembler::add_op3, Assembler::arith_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
313 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
314 rd == inv_rs1(i1) && rd == inv_rd(i1))) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
315 fatal("not a set_metadata");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
319 fatal("not a set_metadata");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 void NativeMovConstReg::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data());
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
331 intptr_t NativeMovConstReg::data() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return data64(addr_at(sethi_offset), long_at(add_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
335 intptr_t NativeMovConstReg::data() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return data32(long_at(sethi_offset), long_at(add_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 void NativeMovConstReg::set_data(intptr_t x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
343 set_data64_sethi(addr_at(sethi_offset), x);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
345 set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x));
a61af66fc99e Initial load
duke
parents:
diff changeset
346 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
347 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // also store the value into an oop_Relocation cell, if any
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 727
diff changeset
350 CodeBlob* cb = CodeCache::find_blob(instruction_address());
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 727
diff changeset
351 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (nm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 RelocIterator iter(nm, instruction_address(), next_instruction_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
354 oop* oop_addr = NULL;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
355 Metadata** metadata_addr = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
356 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (iter.type() == relocInfo::oop_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 oop_Relocation *r = iter.oop_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (oop_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 oop_addr = r->oop_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
361 *oop_addr = (oop)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
362 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
366 if (iter.type() == relocInfo::metadata_type) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
367 metadata_Relocation *r = iter.metadata_reloc();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
368 if (metadata_addr == NULL) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
369 metadata_addr = r->metadata_addr();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
370 *metadata_addr = (Metadata*)x;
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
371 } else {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
372 assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
373 }
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
374 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Code for unit testing implementation of NativeMovConstReg class
a61af66fc99e Initial load
duke
parents:
diff changeset
381 void NativeMovConstReg::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
383 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 CodeBuffer cb("test", 100, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 NativeMovConstReg* nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
387 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
390 0x7fffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
391 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
392 0xffffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
393 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
394 4096,
a61af66fc99e Initial load
duke
parents:
diff changeset
395 4097,
a61af66fc99e Initial load
duke
parents:
diff changeset
396 };
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
399
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
400 AddressLiteral al1(0xaaaabbbb, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
401 a->sethi(al1, I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
402 a->add(I3, al1.low10(), I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
403 AddressLiteral al2(0xccccdddd, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
404 a->sethi(al2, O2);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
405 a->add(O2, al2.low10(), O2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
406
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
407 nm = nativeMovConstReg_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
408 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 nm = nativeMovConstReg_at( nm->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
411 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 nm->set_data( offsets[idx] );
a61af66fc99e Initial load
duke
parents:
diff changeset
413 assert(nm->data() == offsets[idx], "check unit test");
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
418 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // End code for unit testing implementation of NativeMovConstReg class
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 //-------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void NativeMovConstRegPatching::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 NativeInstruction::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // Make sure code pattern is sethi/nop/add.
a61af66fc99e Initial load
duke
parents:
diff changeset
427 int i0 = long_at(sethi_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 int i1 = long_at(nop_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 int i2 = long_at(add_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
430 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Verify the pattern "sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg"
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // The casual reader should note that on Sparc a nop is a special case if sethi
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // in which the destination register is %g0.
a61af66fc99e Initial load
duke
parents:
diff changeset
435 Register rd0 = inv_rd(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
436 Register rd1 = inv_rd(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
438 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi
a61af66fc99e Initial load
duke
parents:
diff changeset
439 is_op3(i2, Assembler::add_op3, Assembler::arith_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
440 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
441 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
442 fatal("not a set_metadata");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 void NativeMovConstRegPatching::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data());
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 int NativeMovConstRegPatching::data() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
454 return data64(addr_at(sethi_offset), long_at(add_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
455 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
456 return data32(long_at(sethi_offset), long_at(add_offset));
a61af66fc99e Initial load
duke
parents:
diff changeset
457 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 void NativeMovConstRegPatching::set_data(int x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
463 set_data64_sethi(addr_at(sethi_offset), x);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
465 set_long_at(sethi_offset, set_data32_sethi(long_at(sethi_offset), x));
a61af66fc99e Initial load
duke
parents:
diff changeset
466 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
467 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x));
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // also store the value into an oop_Relocation cell, if any
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 727
diff changeset
470 CodeBlob* cb = CodeCache::find_blob(instruction_address());
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 727
diff changeset
471 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (nm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 RelocIterator iter(nm, instruction_address(), next_instruction_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
474 oop* oop_addr = NULL;
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
475 Metadata** metadata_addr = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
476 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 if (iter.type() == relocInfo::oop_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
478 oop_Relocation *r = iter.oop_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (oop_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 oop_addr = r->oop_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
481 *oop_addr = (oop)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
a61af66fc99e Initial load
duke
parents:
diff changeset
484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
486 if (iter.type() == relocInfo::metadata_type) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
487 metadata_Relocation *r = iter.metadata_reloc();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
488 if (metadata_addr == NULL) {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
489 metadata_addr = r->metadata_addr();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
490 *metadata_addr = (Metadata*)x;
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
491 } else {
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
492 assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
493 }
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 2426
diff changeset
494 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Code for unit testing implementation of NativeMovConstRegPatching class
a61af66fc99e Initial load
duke
parents:
diff changeset
501 void NativeMovConstRegPatching::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
503 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
504 CodeBuffer cb("test", 100, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
505 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 NativeMovConstRegPatching* nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
508 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
510 0x7fffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
511 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
512 0xffffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
513 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
514 4096,
a61af66fc99e Initial load
duke
parents:
diff changeset
515 4097,
a61af66fc99e Initial load
duke
parents:
diff changeset
516 };
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
519
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
520 AddressLiteral al1(0xaaaabbbb, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
521 a->sethi(al1, I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
522 a->nop();
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
523 a->add(I3, al1.low10(), I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
524 AddressLiteral al2(0xccccdddd, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
525 a->sethi(al2, O2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
526 a->nop();
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
527 a->add(O2, al2.low10(), O2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
528
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
529 nm = nativeMovConstRegPatching_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
530 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 nm = nativeMovConstRegPatching_at( nm->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
533 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 nm->set_data( offsets[idx] );
a61af66fc99e Initial load
duke
parents:
diff changeset
535 assert(nm->data() == offsets[idx], "check unit test");
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
540 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // End code for unit testing implementation of NativeMovConstRegPatching class
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 //-------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 void NativeMovRegMem::copy_instruction_to(address new_instruction_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 Untested("copy_instruction_to");
a61af66fc99e Initial load
duke
parents:
diff changeset
550 int instruction_size = next_instruction_address() - instruction_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
551 for (int i = 0; i < instruction_size; i += BytesPerInstWord) {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 *(int*)(new_instruction_address + i) = *(int*)(address(this) + i);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 void NativeMovRegMem::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 NativeInstruction::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // make sure code pattern is actually a "ld" or "st" of some sort.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 int i0 = long_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
561 int op3 = inv_op3(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 assert((int)add_offset == NativeMovConstReg::add_offset, "sethi size ok");
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (!(is_op(i0, Assembler::ldst_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
566 inv_immed(i0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
567 0 != (op3 < op3_ldst_int_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
568 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st)
a61af66fc99e Initial load
duke
parents:
diff changeset
569 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))))
a61af66fc99e Initial load
duke
parents:
diff changeset
570 {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 int i1 = long_at(ldst_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 Register rd = inv_rd(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
573
a61af66fc99e Initial load
duke
parents:
diff changeset
574 op3 = inv_op3(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (!is_op(i1, Assembler::ldst_op) && rd == inv_rs2(i1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
576 0 != (op3 < op3_ldst_int_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
577 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st)
a61af66fc99e Initial load
duke
parents:
diff changeset
578 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 fatal("not a ld* or st* op");
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 void NativeMovRegMem::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 if (is_immediate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
588 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // Code for unit testing implementation of NativeMovRegMem class
a61af66fc99e Initial load
duke
parents:
diff changeset
595 void NativeMovRegMem::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
597 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 CodeBuffer cb("test", 1000, 1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 NativeMovRegMem* nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 uint idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 uint idx1;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
605 0xffffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
606 0x7fffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
607 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
608 4096,
a61af66fc99e Initial load
duke
parents:
diff changeset
609 4097,
a61af66fc99e Initial load
duke
parents:
diff changeset
610 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
611 0x4000,
a61af66fc99e Initial load
duke
parents:
diff changeset
612 };
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
615
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
616 AddressLiteral al1(0xffffffff, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
617 AddressLiteral al2(0xaaaabbbb, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
618 a->ldsw( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
619 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
620 a->ldsw( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
621 a->ldsb( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
622 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
623 a->ldsb( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
624 a->ldsh( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
625 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
626 a->ldsh( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
627 a->lduw( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
628 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
629 a->lduw( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
630 a->ldub( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
631 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
632 a->ldub( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
633 a->lduh( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
634 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
635 a->lduh( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
636 a->ldx( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
637 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
638 a->ldx( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
639 a->ldd( G5, al1.low10(), G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
640 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
641 a->ldd( G5, I3, G4 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 a->ldf( FloatRegisterImpl::D, O2, -1, F14 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
643 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
644 a->ldf( FloatRegisterImpl::S, O0, I3, F15 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
645
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
646 a->stw( G5, G4, al1.low10() ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
647 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
648 a->stw( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
649 a->stb( G5, G4, al1.low10() ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
650 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 a->stb( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
652 a->sth( G5, G4, al1.low10() ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
653 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
654 a->sth( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
655 a->stx( G5, G4, al1.low10() ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
656 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
657 a->stx( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
658 a->std( G5, G4, al1.low10() ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
659 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
660 a->std( G5, G4, I3 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 a->stf( FloatRegisterImpl::S, F18, O2, -1 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
662 a->sethi(al2, I3); a->add(I3, al2.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
663 a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
664
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
665 nm = nativeMovRegMem_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
666 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
667 nm->set_offset( low10(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
668 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
669 nm->add_offset_in_bytes( low10(0xbb) * wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
670 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 while (--idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 nm = nativeMovRegMem_at( nm->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
674 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
675 for (idx1 = 0; idx1 < ARRAY_SIZE(offsets); idx1++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 nm->set_offset( nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1] );
a61af66fc99e Initial load
duke
parents:
diff changeset
677 assert(nm->offset() == (nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
678 "check unit test");
a61af66fc99e Initial load
duke
parents:
diff changeset
679 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
681 nm->add_offset_in_bytes( low10(0xbb) * wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
682 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
686 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // End code for unit testing implementation of NativeMovRegMem class
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 void NativeMovRegMemPatching::copy_instruction_to(address new_instruction_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 Untested("copy_instruction_to");
a61af66fc99e Initial load
duke
parents:
diff changeset
696 int instruction_size = next_instruction_address() - instruction_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
697 for (int i = 0; i < instruction_size; i += wordSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
698 *(long*)(new_instruction_address + i) = *(long*)(address(this) + i);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 void NativeMovRegMemPatching::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 NativeInstruction::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // make sure code pattern is actually a "ld" or "st" of some sort.
a61af66fc99e Initial load
duke
parents:
diff changeset
706 int i0 = long_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
707 int op3 = inv_op3(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 if (!(is_op(i0, Assembler::ldst_op) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
712 inv_immed(i0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
713 0 != (op3 < op3_ldst_int_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
714 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st)
a61af66fc99e Initial load
duke
parents:
diff changeset
715 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf)))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 int i1 = long_at(ldst_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 Register rd = inv_rd(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 op3 = inv_op3(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (!is_op(i1, Assembler::ldst_op) && rd == inv_rs2(i1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
721 0 != (op3 < op3_ldst_int_limit
a61af66fc99e Initial load
duke
parents:
diff changeset
722 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st)
a61af66fc99e Initial load
duke
parents:
diff changeset
723 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 fatal("not a ld* or st* op");
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 void NativeMovRegMemPatching::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
731 if (is_immediate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
733 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // Code for unit testing implementation of NativeMovRegMemPatching class
a61af66fc99e Initial load
duke
parents:
diff changeset
740 void NativeMovRegMemPatching::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
742 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
743 CodeBuffer cb("test", 1000, 1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
745 NativeMovRegMemPatching* nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
746 uint idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
747 uint idx1;
a61af66fc99e Initial load
duke
parents:
diff changeset
748 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
750 0xffffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
751 0x7fffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
752 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
753 4096,
a61af66fc99e Initial load
duke
parents:
diff changeset
754 4097,
a61af66fc99e Initial load
duke
parents:
diff changeset
755 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
756 0x4000,
a61af66fc99e Initial load
duke
parents:
diff changeset
757 };
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
760
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
761 AddressLiteral al(0xffffffff, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
762 a->ldsw( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
763 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
764 a->ldsw( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
765 a->ldsb( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
766 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
767 a->ldsb( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
768 a->ldsh( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
769 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
770 a->ldsh( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
771 a->lduw( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
772 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
773 a->lduw( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
774 a->ldub( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
775 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
776 a->ldub( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
777 a->lduh( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
778 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
779 a->lduh( G5, I3, G4 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
780 a->ldx( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
781 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
782 a->ldx( G5, I3, G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
783 a->ldd( G5, al.low10(), G4); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
784 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
785 a->ldd( G5, I3, G4 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
786 a->ldf( FloatRegisterImpl::D, O2, -1, F14 ); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
787 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
788 a->ldf( FloatRegisterImpl::S, O0, I3, F15 ); idx++;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
789
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
790 a->stw( G5, G4, al.low10()); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
791 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
792 a->stw( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
793 a->stb( G5, G4, al.low10()); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
794 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
795 a->stb( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
796 a->sth( G5, G4, al.low10()); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
797 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
798 a->sth( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
799 a->stx( G5, G4, al.low10()); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
800 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
801 a->stx( G5, G4, I3 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
802 a->std( G5, G4, al.low10()); idx++;
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
803 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
804 a->std( G5, G4, I3 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
805 a->stf( FloatRegisterImpl::S, F18, O2, -1 ); idx++;
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
806 a->sethi(al, I3); a->nop(); a->add(I3, al.low10(), I3);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
807 a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++;
a61af66fc99e Initial load
duke
parents:
diff changeset
808
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
809 nm = nativeMovRegMemPatching_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
810 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
811 nm->set_offset( low10(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
812 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
813 nm->add_offset_in_bytes( low10(0xbb) * wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
814 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
815
a61af66fc99e Initial load
duke
parents:
diff changeset
816 while (--idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 nm = nativeMovRegMemPatching_at( nm->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
818 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
819 for (idx1 = 0; idx1 < ARRAY_SIZE(offsets); idx1++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 nm->set_offset( nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1] );
a61af66fc99e Initial load
duke
parents:
diff changeset
821 assert(nm->offset() == (nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
822 "check unit test");
a61af66fc99e Initial load
duke
parents:
diff changeset
823 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 nm->add_offset_in_bytes( low10(0xbb) * wordSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
826 nm->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
830 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // End code for unit testing implementation of NativeMovRegMemPatching class
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 void NativeJump::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 NativeInstruction::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
840 int i0 = long_at(sethi_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 int i1 = long_at(jmpl_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
842 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg"
a61af66fc99e Initial load
duke
parents:
diff changeset
844 Register rd = inv_rd(i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
845 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
846 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
847 (is_op3(i1, Assembler::jmpl_op3, Assembler::arith_op) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
848 (TraceJumps && is_op3(i1, Assembler::add_op3, Assembler::arith_op))) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
849 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
850 rd == inv_rs1(i1))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 fatal("not a jump_to instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // In LP64, the jump instruction location varies for non relocatable
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // jumps, for example is could be sethi, xor, jmp instead of the
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // 7 instructions for sethi. So let's check sethi only.
a61af66fc99e Initial load
duke
parents:
diff changeset
857 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 fatal("not a jump_to instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 void NativeJump::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, instruction_address(), jump_destination());
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Code for unit testing implementation of NativeJump class
a61af66fc99e Initial load
duke
parents:
diff changeset
870 void NativeJump::test() {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
872 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
873 CodeBuffer cb("test", 100, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 NativeJump* nj;
a61af66fc99e Initial load
duke
parents:
diff changeset
876 uint idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 int offsets[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
878 0x0,
a61af66fc99e Initial load
duke
parents:
diff changeset
879 0xffffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
880 0x7fffffff,
a61af66fc99e Initial load
duke
parents:
diff changeset
881 0x80000000,
a61af66fc99e Initial load
duke
parents:
diff changeset
882 4096,
a61af66fc99e Initial load
duke
parents:
diff changeset
883 4097,
a61af66fc99e Initial load
duke
parents:
diff changeset
884 0x20,
a61af66fc99e Initial load
duke
parents:
diff changeset
885 0x4000,
a61af66fc99e Initial load
duke
parents:
diff changeset
886 };
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 VM_Version::allow_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
889
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
890 AddressLiteral al(0x7fffbbbb, relocInfo::external_word_type);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
891 a->sethi(al, I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
892 a->jmpl(I3, al.low10(), G0, RelocationHolder::none);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
893 a->delayed()->nop();
727
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
894 a->sethi(al, I3);
6b2273dd6fa9 6822110: Add AddressLiteral class on SPARC
twisti
parents: 196
diff changeset
895 a->jmpl(I3, al.low10(), L3, RelocationHolder::none);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
896 a->delayed()->nop();
a61af66fc99e Initial load
duke
parents:
diff changeset
897
1748
3e8fbc61cee8 6978355: renaming for 6961697
twisti
parents: 1579
diff changeset
898 nj = nativeJump_at( cb.insts_begin() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
899 nj->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 nj = nativeJump_at( nj->next_instruction_address() );
a61af66fc99e Initial load
duke
parents:
diff changeset
902 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 nj->set_jump_destination( nj->instruction_address() + offsets[idx] );
a61af66fc99e Initial load
duke
parents:
diff changeset
904 assert(nj->jump_destination() == (nj->instruction_address() + offsets[idx]), "check unit test");
a61af66fc99e Initial load
duke
parents:
diff changeset
905 nj->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 VM_Version::revert();
a61af66fc99e Initial load
duke
parents:
diff changeset
909 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // End code for unit testing implementation of NativeJump class
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 void NativeJump::insert(address code_pos, address entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // MT safe inserting of a jump over an unknown instruction sequence (used by nmethod::makeZombie)
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // The problem: jump_to <dest> is a 3-word instruction (including its delay slot).
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // Atomic write can be only with 1 word.
a61af66fc99e Initial load
duke
parents:
diff changeset
921 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // Here's one way to do it: Pre-allocate a three-word jump sequence somewhere
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // in the header of the nmethod, within a short branch's span of the patch point.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // Set up the jump sequence using NativeJump::insert, and then use an annulled
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // unconditional branch at the target site (an atomic 1-word update).
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // Limitations: You can only patch nmethods, with any given nmethod patched at
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // most once, and the patch must be in the nmethod's header.
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // It's messy, but you can ask the CodeCache for the nmethod containing the
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // target address.
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // %%%%% For now, do something MT-stupid:
a61af66fc99e Initial load
duke
parents:
diff changeset
932 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 int code_size = 1 * BytesPerInstWord;
a61af66fc99e Initial load
duke
parents:
diff changeset
934 CodeBuffer cb(verified_entry, code_size + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 MacroAssembler* a = new MacroAssembler(&cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (VM_Version::v9_instructions_work()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 a->ldsw(G0, 0, O7); // "ld" must agree with code in the signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
938 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
939 a->lduw(G0, 0, O7); // "ld" must agree with code in the signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 ICache::invalidate_range(verified_entry, code_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 void NativeIllegalInstruction::insert(address code_pos) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 NativeIllegalInstruction* nii = (NativeIllegalInstruction*) nativeInstruction_at(code_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
947 nii->set_long_at(0, illegal_instruction());
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 static int illegal_instruction_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952 int NativeInstruction::illegal_instruction() {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 if (illegal_instruction_bits == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
955 char buf[40];
a61af66fc99e Initial load
duke
parents:
diff changeset
956 CodeBuffer cbuf((address)&buf[0], 20);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 MacroAssembler* a = new MacroAssembler(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
958 address ia = a->pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
959 a->trap(ST_RESERVED_FOR_USER_0 + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
960 int bits = *(int*)ia;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 assert(is_op3(bits, Assembler::trap_op3, Assembler::arith_op), "bad instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
962 illegal_instruction_bits = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
963 assert(illegal_instruction_bits != 0, "oops");
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 return illegal_instruction_bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 static int ic_miss_trap_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970 bool NativeInstruction::is_ic_miss_trap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 if (ic_miss_trap_bits == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 char buf[40];
a61af66fc99e Initial load
duke
parents:
diff changeset
974 CodeBuffer cbuf((address)&buf[0], 20);
a61af66fc99e Initial load
duke
parents:
diff changeset
975 MacroAssembler* a = new MacroAssembler(&cbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
976 address ia = a->pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
977 a->trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0 + 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 int bits = *(int*)ia;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 assert(is_op3(bits, Assembler::trap_op3, Assembler::arith_op), "bad instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
980 ic_miss_trap_bits = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
981 assert(ic_miss_trap_bits != 0, "oops");
a61af66fc99e Initial load
duke
parents:
diff changeset
982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
983 return long_at(0) == ic_miss_trap_bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 bool NativeInstruction::is_illegal() {
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (illegal_instruction_bits == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991 return long_at(0) == illegal_instruction_bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 void NativeGeneralJump::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 assert(((NativeInstruction *)this)->is_jump() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
997 ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 Assembler::Condition condition = Assembler::always;
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 int x = Assembler::op2(Assembler::br_op2) | Assembler::annul(false) |
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 Assembler::cond(condition) | Assembler::wdisp((intptr_t)entry, (intptr_t)code_pos, 22);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 NativeGeneralJump* ni = (NativeGeneralJump*) nativeInstruction_at(code_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 ni->set_long_at(0, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // MT-safe patching of a jmp instruction (and following word).
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 // First patches the second word, and then atomicly replaces
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 // the first word with the first new instruction word.
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 // Other processors might briefly see the old first word
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // followed by the new second word. This is OK if the old
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // second word is harmless, and the new second word may be
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // harmlessly executed in the delay slot of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 assert(Patching_lock->is_locked() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 SafepointSynchronize::is_at_safepoint(), "concurrent code patching");
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 assert (instr_addr != NULL, "illegal address for code patching");
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 NativeGeneralJump* h_jump = nativeGeneralJump_at (instr_addr); // checking that it is a call
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 assert(NativeGeneralJump::instruction_size == 8, "wrong instruction size; must be 8");
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 int i0 = ((int*)code_buffer)[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 int i1 = ((int*)code_buffer)[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 int* contention_addr = (int*) h_jump->addr_at(1*BytesPerInstWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 assert(inv_op(*contention_addr) == Assembler::arith_op ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 "must not interfere with original call");
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 h_jump->set_long_at(1*BytesPerInstWord, i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 h_jump->set_long_at(0*BytesPerInstWord, i0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 // NOTE: It is possible that another thread T will execute
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 // only the second patched word.
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // In other words, since the original instruction is this
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 // jmp patching_stub; nop (NativeGeneralJump)
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // and the new sequence from the buffer is this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg)
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // what T will execute is this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // jmp patching_stub; add %r, %lo(K), %r
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // thereby putting garbage into %r before calling the patching stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // This is OK, because the patching stub ignores the value of %r.
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // Make sure the first-patched instruction, which may co-exist
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // briefly with the call, will do something harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 assert(inv_op(*contention_addr) == Assembler::arith_op ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 "must not interfere with original call");
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }