annotate src/share/vm/code/relocInfo.hpp @ 3992:d1bdeef3e3e2

7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76 Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing. Reviewed-by: tonyp, brutisso, ysr
author johnc
date Wed, 12 Oct 2011 10:25:51 -0700
parents 6c97c830fb6f
children da91efe96a93
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2426
1d1603768966 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 2375
diff changeset
2 * Copyright (c) 1997, 2011, 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: 337
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 337
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: 337
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: 1762
diff changeset
25 #ifndef SHARE_VM_CODE_RELOCINFO_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
26 #define SHARE_VM_CODE_RELOCINFO_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
28 #include "memory/allocation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
29 #include "utilities/top.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
30
0
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Types in this file:
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // relocInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // One element of an array of halfwords encoding compressed relocations.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Also, the source of relocation types (relocInfo::oop_type, ...).
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // Relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // A flyweight object representing a single relocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // It is fully unpacked from the compressed relocation array.
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // oop_Relocation, ... (subclasses of Relocation)
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // The location of some type-specific operations (oop_addr, ...).
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Also, the source of relocation specs (oop_Relocation::spec, ...).
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // RelocationHolder
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // A ValueObj type which acts as a union holding a Relocation object.
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // Represents a relocation spec passed into a CodeBuffer during assembly.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // RelocIterator
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // A StackObj which iterates over the relocations associated with
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // a range of code addresses. Can be used to operate a copy of code.
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // PatchingRelocIterator
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // Specialized subtype of RelocIterator which removes breakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // temporarily during iteration, then restores them.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // BoundRelocation
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // An _internal_ type shared by packers and unpackers of relocations.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // It pastes together a RelocationHolder with some pointers into
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // code and relocInfo streams.
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // Notes on relocType:
a61af66fc99e Initial load
duke
parents:
diff changeset
57 //
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // These hold enough information to read or write a value embedded in
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // the instructions of an CodeBlob. They're used to update:
a61af66fc99e Initial load
duke
parents:
diff changeset
60 //
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // 1) embedded oops (isOop() == true)
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // 2) inline caches (isIC() == true)
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // 3) runtime calls (isRuntimeCall() == true)
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // 4) internal word ref (isInternalWord() == true)
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // 5) external word ref (isExternalWord() == true)
a61af66fc99e Initial load
duke
parents:
diff changeset
66 //
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // when objects move (GC) or if code moves (compacting the code heap).
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // They are also used to patch the code (if a call site must change)
a61af66fc99e Initial load
duke
parents:
diff changeset
69 //
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // A relocInfo is represented in 16 bits:
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // 4 bits indicating the relocation type
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // 12 bits indicating the offset from the previous relocInfo address
a61af66fc99e Initial load
duke
parents:
diff changeset
73 //
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // The offsets accumulate along the relocInfo stream to encode the
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // address within the CodeBlob, which is named RelocIterator::addr().
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // The address of a particular relocInfo always points to the first
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // byte of the relevant instruction (and not to any of its subfields
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // or embedded immediate constants).
a61af66fc99e Initial load
duke
parents:
diff changeset
79 //
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // The offset value is scaled appropriately for the target machine.
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // (See relocInfo_<arch>.hpp for the offset scaling.)
a61af66fc99e Initial load
duke
parents:
diff changeset
82 //
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // On some machines, there may also be a "format" field which may provide
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // additional information about the format of the instruction stream
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // at the corresponding code address. The format value is usually zero.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // Any machine (such as Intel) whose instructions can sometimes contain
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // more than one relocatable constant needs format codes to distinguish
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // which operand goes with a given relocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 //
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // If the target machine needs N format bits, the offset has 12-N bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // the format is encoded between the offset and the type, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // relocInfo_<arch>.hpp file has manifest constants for the format codes.
a61af66fc99e Initial load
duke
parents:
diff changeset
93 //
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // If the type is "data_prefix_tag" then the offset bits are further encoded,
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // and in fact represent not a code-stream offset but some inline data.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // The data takes the form of a counted sequence of halfwords, which
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // precedes the actual relocation record. (Clients never see it directly.)
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // The interpetation of this extra data depends on the relocation type.
a61af66fc99e Initial load
duke
parents:
diff changeset
99 //
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // On machines that have 32-bit immediate fields, there is usually
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // little need for relocation "prefix" data, because the instruction stream
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // is a perfectly reasonable place to store the value. On machines in
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // which 32-bit values must be "split" across instructions, the relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // data is the "true" specification of the value, which is then applied
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // to some field of the instruction (22 or 13 bits, on SPARC).
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Whenever the location of the CodeBlob changes, any PC-relative
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // relocations, and any internal_word_type relocations, must be reapplied.
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // After the GC runs, oop_type relocations must be reapplied.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 //
a61af66fc99e Initial load
duke
parents:
diff changeset
111 //
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Here are meanings of the types:
a61af66fc99e Initial load
duke
parents:
diff changeset
113 //
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // relocInfo::none -- a filler record
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // Value: none
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Instruction: The corresponding code address is ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Data: Any data prefix and format code are ignored
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // (This means that any relocInfo can be disabled by setting
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // its type to none. See relocInfo::remove.)
a61af66fc99e Initial load
duke
parents:
diff changeset
120 //
a61af66fc99e Initial load
duke
parents:
diff changeset
121 // relocInfo::oop_type -- a reference to an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Value: an oop, or else the address (handle) of an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Instruction types: memory (load), set (load address)
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Data: [] an oop stored in 4 bytes of instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // [n] n is the index of an oop in the CodeBlob's oop pool
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // [[N]n l] and l is a byte offset to be applied to the oop
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // [Nn Ll] both index and offset may be 32 bits if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Here is a special hack, used only by the old compiler:
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // [[N]n 00] the value is the __address__ of the nth oop in the pool
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // (Note that the offset allows optimal references to class variables.)
a61af66fc99e Initial load
duke
parents:
diff changeset
131 //
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // relocInfo::internal_word_type -- an address within the same CodeBlob
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // relocInfo::section_word_type -- same, but can refer to another section
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // Value: an address in the CodeBlob's code or constants section
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Instruction types: memory (load), set (load address)
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Data: [] stored in 4 bytes of instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // [[L]l] a relative offset (see [About Offsets] below)
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // In the case of section_word_type, the offset is relative to a section
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // base address, and the section number (e.g., SECT_INSTS) is encoded
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // into the low two bits of the offset L.
a61af66fc99e Initial load
duke
parents:
diff changeset
141 //
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // relocInfo::external_word_type -- a fixed address in the runtime system
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Value: an address
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Instruction types: memory (load), set (load address)
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Data: [] stored in 4 bytes of instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // [n] the index of a "well-known" stub (usual case on RISC)
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // [Ll] a 32-bit address
a61af66fc99e Initial load
duke
parents:
diff changeset
148 //
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // relocInfo::runtime_call_type -- a fixed subroutine in the runtime system
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // Value: an address
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // Instruction types: PC-relative call (or a PC-relative branch)
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // Data: [] stored in 4 bytes of instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
153 //
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // relocInfo::static_call_type -- a static call
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Value: an CodeBlob, a stub, or a fixup routine
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Instruction types: a call
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Data: []
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // The identity of the callee is extracted from debugging information.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // //%note reloc_3
a61af66fc99e Initial load
duke
parents:
diff changeset
160 //
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // relocInfo::virtual_call_type -- a virtual call site (which includes an inline
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // cache)
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Value: an CodeBlob, a stub, the interpreter, or a fixup routine
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Instruction types: a call, plus some associated set-oop instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Data: [] the associated set-oops are adjacent to the call
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // [n] n is a relative offset to the first set-oop
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // [[N]n l] and l is a limit within which the set-oops occur
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // [Nn Ll] both n and l may be 32 bits if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // The identity of the callee is extracted from debugging information.
a61af66fc99e Initial load
duke
parents:
diff changeset
170 //
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // relocInfo::opt_virtual_call_type -- a virtual call site that is statically bound
a61af66fc99e Initial load
duke
parents:
diff changeset
172 //
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // Same info as a static_call_type. We use a special type, so the handling of
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // virtuals and statics are separated.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 //
a61af66fc99e Initial load
duke
parents:
diff changeset
176 //
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // The offset n points to the first set-oop. (See [About Offsets] below.)
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // In turn, the set-oop instruction specifies or contains an oop cell devoted
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // exclusively to the IC call, which can be patched along with the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 //
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // The locations of any other set-oops are found by searching the relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // information starting at the first set-oop, and continuing until all
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // relocations up through l have been inspected. The value l is another
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // relative offset. (Both n and l are relative to the call's first byte.)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 //
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // The limit l of the search is exclusive. However, if it points within
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // the call (e.g., offset zero), it is adjusted to point after the call and
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // any associated machine-specific delay slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 //
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Since the offsets could be as wide as 32-bits, these conventions
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // put no restrictions whatever upon code reorganization.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 //
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // The compiler is responsible for ensuring that transition from a clean
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // state to a monomorphic compiled state is MP-safe. This implies that
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // the system must respond well to intermediate states where a random
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // subset of the set-oops has been correctly from the clean state
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // upon entry to the VEP of the compiled method. In the case of a
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // machine (Intel) with a single set-oop instruction, the 32-bit
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // immediate field must not straddle a unit of memory coherence.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // //%note reloc_3
a61af66fc99e Initial load
duke
parents:
diff changeset
201 //
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // relocInfo::breakpoint_type -- a conditional breakpoint in the code
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // Value: none
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // Instruction types: any whatsoever
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Data: [b [T]t i...]
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // The b is a bit-packed word representing the breakpoint's attributes.
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // The t is a target address which the breakpoint calls (when it is enabled).
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // The i... is a place to store one or two instruction words overwritten
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // by a trap, so that the breakpoint may be subsequently removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
210 //
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // relocInfo::static_stub_type -- an extra stub for each static_call_type
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // Value: none
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Instruction types: a virtual call: { set_oop; jump; }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Data: [[N]n] the offset of the associated static_call reloc
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // This stub becomes the target of a static call which must be upgraded
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // to a virtual call (because the callee is interpreted).
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // See [About Offsets] below.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // //%note reloc_2
a61af66fc99e Initial load
duke
parents:
diff changeset
219 //
a61af66fc99e Initial load
duke
parents:
diff changeset
220 // For example:
a61af66fc99e Initial load
duke
parents:
diff changeset
221 //
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // INSTRUCTIONS RELOC: TYPE PREFIX DATA
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // ------------ ---- -----------
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // sethi %hi(myObject), R oop_type [n(myObject)]
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // ld [R+%lo(myObject)+fldOffset], R2 oop_type [n(myObject) fldOffset]
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // add R2, 1, R2
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // st R2, [R+%lo(myObject)+fldOffset] oop_type [n(myObject) fldOffset]
a61af66fc99e Initial load
duke
parents:
diff changeset
228 //%note reloc_1
a61af66fc99e Initial load
duke
parents:
diff changeset
229 //
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // This uses 4 instruction words, 8 relocation halfwords,
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // and an entry (which is sharable) in the CodeBlob's oop pool,
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // for a total of 36 bytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
233 //
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Note that the compiler is responsible for ensuring the "fldOffset" when
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // added to "%lo(myObject)" does not overflow the immediate fields of the
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // memory instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
237 //
a61af66fc99e Initial load
duke
parents:
diff changeset
238 //
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // [About Offsets] Relative offsets are supplied to this module as
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // positive byte offsets, but they may be internally stored scaled
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // and/or negated, depending on what is most compact for the target
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // system. Since the object pointed to by the offset typically
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // precedes the relocation address, it is profitable to store
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // these negative offsets as positive numbers, but this decision
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // is internal to the relocation information abstractions.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 //
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 class Relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 class CodeBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 class CodeSection;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 class relocInfo VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
256 enum relocType {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 none = 0, // Used when no relocation should be generated
a61af66fc99e Initial load
duke
parents:
diff changeset
258 oop_type = 1, // embedded oop
a61af66fc99e Initial load
duke
parents:
diff changeset
259 virtual_call_type = 2, // a standard inline cache call for a virtual send
a61af66fc99e Initial load
duke
parents:
diff changeset
260 opt_virtual_call_type = 3, // a virtual call that has been statically bound (i.e., no IC cache)
a61af66fc99e Initial load
duke
parents:
diff changeset
261 static_call_type = 4, // a static send
a61af66fc99e Initial load
duke
parents:
diff changeset
262 static_stub_type = 5, // stub-entry for static send (takes care of interpreter case)
a61af66fc99e Initial load
duke
parents:
diff changeset
263 runtime_call_type = 6, // call to fixed external routine
a61af66fc99e Initial load
duke
parents:
diff changeset
264 external_word_type = 7, // reference to fixed external address
a61af66fc99e Initial load
duke
parents:
diff changeset
265 internal_word_type = 8, // reference within the current code blob
a61af66fc99e Initial load
duke
parents:
diff changeset
266 section_word_type = 9, // internal, but a cross-section reference
a61af66fc99e Initial load
duke
parents:
diff changeset
267 poll_type = 10, // polling instruction for safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
268 poll_return_type = 11, // polling instruction for safepoints at return
a61af66fc99e Initial load
duke
parents:
diff changeset
269 breakpoint_type = 12, // an initialization barrier or safepoint
a61af66fc99e Initial load
duke
parents:
diff changeset
270 yet_unused_type = 13, // Still unused
a61af66fc99e Initial load
duke
parents:
diff changeset
271 yet_unused_type_2 = 14, // Still unused
a61af66fc99e Initial load
duke
parents:
diff changeset
272 data_prefix_tag = 15, // tag for a prefix (carries data arguments)
a61af66fc99e Initial load
duke
parents:
diff changeset
273 type_mask = 15 // A mask which selects only the above values
a61af66fc99e Initial load
duke
parents:
diff changeset
274 };
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
277 unsigned short _value;
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 enum RawBitsToken { RAW_BITS };
a61af66fc99e Initial load
duke
parents:
diff changeset
280 relocInfo(relocType type, RawBitsToken ignore, int bits)
a61af66fc99e Initial load
duke
parents:
diff changeset
281 : _value((type << nontype_width) + bits) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 relocInfo(relocType type, RawBitsToken ignore, int off, int f)
a61af66fc99e Initial load
duke
parents:
diff changeset
284 : _value((type << nontype_width) + (off / (unsigned)offset_unit) + (f << offset_width)) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
288 relocInfo(relocType type, int offset, int format = 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
289 #ifndef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
290 {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 (*this) = relocInfo(type, RAW_BITS, offset, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Put a bunch of assertions out-of-line.
a61af66fc99e Initial load
duke
parents:
diff changeset
295 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 #define APPLY_TO_RELOCATIONS(visitor) \
a61af66fc99e Initial load
duke
parents:
diff changeset
299 visitor(oop) \
a61af66fc99e Initial load
duke
parents:
diff changeset
300 visitor(virtual_call) \
a61af66fc99e Initial load
duke
parents:
diff changeset
301 visitor(opt_virtual_call) \
a61af66fc99e Initial load
duke
parents:
diff changeset
302 visitor(static_call) \
a61af66fc99e Initial load
duke
parents:
diff changeset
303 visitor(static_stub) \
a61af66fc99e Initial load
duke
parents:
diff changeset
304 visitor(runtime_call) \
a61af66fc99e Initial load
duke
parents:
diff changeset
305 visitor(external_word) \
a61af66fc99e Initial load
duke
parents:
diff changeset
306 visitor(internal_word) \
a61af66fc99e Initial load
duke
parents:
diff changeset
307 visitor(poll) \
a61af66fc99e Initial load
duke
parents:
diff changeset
308 visitor(poll_return) \
a61af66fc99e Initial load
duke
parents:
diff changeset
309 visitor(breakpoint) \
a61af66fc99e Initial load
duke
parents:
diff changeset
310 visitor(section_word) \
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
314 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 value_width = sizeof(unsigned short) * BitsPerByte,
a61af66fc99e Initial load
duke
parents:
diff changeset
316 type_width = 4, // == log2(type_mask+1)
a61af66fc99e Initial load
duke
parents:
diff changeset
317 nontype_width = value_width - type_width,
a61af66fc99e Initial load
duke
parents:
diff changeset
318 datalen_width = nontype_width-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
319 datalen_tag = 1 << datalen_width, // or-ed into _value
a61af66fc99e Initial load
duke
parents:
diff changeset
320 datalen_limit = 1 << datalen_width,
a61af66fc99e Initial load
duke
parents:
diff changeset
321 datalen_mask = (1 << datalen_width)-1
a61af66fc99e Initial load
duke
parents:
diff changeset
322 };
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
325 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
326 relocType type() const { return (relocType)((unsigned)_value >> nontype_width); }
a61af66fc99e Initial load
duke
parents:
diff changeset
327 int format() const { return format_mask==0? 0: format_mask &
a61af66fc99e Initial load
duke
parents:
diff changeset
328 ((unsigned)_value >> offset_width); }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 int addr_offset() const { assert(!is_prefix(), "must have offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return (_value & offset_mask)*offset_unit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
333 const short* data() const { assert(is_datalen(), "must have data");
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return (const short*)(this + 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
335 int datalen() const { assert(is_datalen(), "must have data");
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return (_value & datalen_mask); }
a61af66fc99e Initial load
duke
parents:
diff changeset
337 int immediate() const { assert(is_immediate(), "must have immed");
a61af66fc99e Initial load
duke
parents:
diff changeset
338 return (_value & datalen_mask); }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
340 static int addr_unit() { return offset_unit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 static int offset_limit() { return (1 << offset_width) * offset_unit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 void set_type(relocType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 void set_format(int format);
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 void remove() { set_type(none); }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
349 bool is_none() const { return type() == none; }
a61af66fc99e Initial load
duke
parents:
diff changeset
350 bool is_prefix() const { return type() == data_prefix_tag; }
a61af66fc99e Initial load
duke
parents:
diff changeset
351 bool is_datalen() const { assert(is_prefix(), "must be prefix");
a61af66fc99e Initial load
duke
parents:
diff changeset
352 return (_value & datalen_tag) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 bool is_immediate() const { assert(is_prefix(), "must be prefix");
a61af66fc99e Initial load
duke
parents:
diff changeset
354 return (_value & datalen_tag) == 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // Occasionally records of type relocInfo::none will appear in the stream.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // We do not bother to filter these out, but clients should ignore them.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // These records serve as "filler" in three ways:
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // - to skip large spans of unrelocated code (this is rare)
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // - to pad out the relocInfo array to the required oop alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // - to disable old relocation information which is no longer applicable
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 inline friend relocInfo filler_relocInfo();
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // Every non-prefix relocation may be preceded by at most one prefix,
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // which supplies 1 or more halfwords of associated data. Conventionally,
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // an int is represented by 0, 1, or 2 halfwords, depending on how
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // many bits are required to represent the value. (In addition,
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // if the sole halfword is a 10-bit unsigned number, it is made
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // "immediate" in the prefix header word itself. This optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // is invisible outside this module.)
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 inline friend relocInfo prefix_relocInfo(int datalen = 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // an immediate relocInfo optimizes a prefix with one 10-bit unsigned value
a61af66fc99e Initial load
duke
parents:
diff changeset
378 static relocInfo immediate_relocInfo(int data0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 assert(fits_into_immediate(data0), "data0 in limits");
a61af66fc99e Initial load
duke
parents:
diff changeset
380 return relocInfo(relocInfo::data_prefix_tag, RAW_BITS, data0);
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382 static bool fits_into_immediate(int data0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 return (data0 >= 0 && data0 < datalen_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // Support routines for compilers.
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // This routine takes an infant relocInfo (unprefixed) and
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // edits in its prefix, if any. It also updates dest.locs_end.
a61af66fc99e Initial load
duke
parents:
diff changeset
391 void initialize(CodeSection* dest, Relocation* reloc);
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // This routine updates a prefix and returns the limit pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // It tries to compress the prefix from 32 to 16 bits, and if
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // successful returns a reduced "prefix_limit" pointer.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 relocInfo* finish_prefix(short* prefix_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // bit-packers for the data array:
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // As it happens, the bytes within the shorts are ordered natively,
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // but the shorts within the word are ordered big-endian.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // This is an arbitrary choice, made this way mainly to ease debugging.
a61af66fc99e Initial load
duke
parents:
diff changeset
403 static int data0_from_int(jint x) { return x >> value_width; }
a61af66fc99e Initial load
duke
parents:
diff changeset
404 static int data1_from_int(jint x) { return (short)x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
405 static jint jint_from_data(short* data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 return (data[0] << value_width) + (unsigned short)data[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 static jint short_data_at(int n, short* data, int datalen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 return datalen > n ? data[n] : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 static jint jint_data_at(int n, short* data, int datalen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 return datalen > n+1 ? jint_from_data(&data[n]) : short_data_at(n, data, datalen);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Update methods for relocation information
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // (since code is dynamically patched, we also need to dynamically update the relocation info)
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // Both methods takes old_type, so it is able to performe sanity checks on the information removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 static void change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 static void remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // Machine dependent stuff
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
424 #ifdef TARGET_ARCH_x86
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
425 # include "relocInfo_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
426 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
427 #ifdef TARGET_ARCH_sparc
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
428 # include "relocInfo_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
429 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
430 #ifdef TARGET_ARCH_zero
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
431 # include "relocInfo_zero.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
432 #endif
2192
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
433 #ifdef TARGET_ARCH_arm
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
434 # include "relocInfo_arm.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
435 #endif
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
436 #ifdef TARGET_ARCH_ppc
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
437 # include "relocInfo_ppc.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 1972
diff changeset
438 #endif
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
439
0
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Derived constant, based on format_width which is PD:
a61af66fc99e Initial load
duke
parents:
diff changeset
443 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 offset_width = nontype_width - format_width,
a61af66fc99e Initial load
duke
parents:
diff changeset
445 offset_mask = (1<<offset_width) - 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
446 format_mask = (1<<format_width) - 1
a61af66fc99e Initial load
duke
parents:
diff changeset
447 };
a61af66fc99e Initial load
duke
parents:
diff changeset
448 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
449 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Conservatively large estimate of maximum length (in shorts)
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // of any relocation record (probably breakpoints are largest).
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Extended format is length prefix, data words, and tag/offset suffix.
a61af66fc99e Initial load
duke
parents:
diff changeset
453 length_limit = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
454 have_format = format_width > 0
a61af66fc99e Initial load
duke
parents:
diff changeset
455 };
a61af66fc99e Initial load
duke
parents:
diff changeset
456 };
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 #define FORWARD_DECLARE_EACH_CLASS(name) \
a61af66fc99e Initial load
duke
parents:
diff changeset
459 class name##_Relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 APPLY_TO_RELOCATIONS(FORWARD_DECLARE_EACH_CLASS)
a61af66fc99e Initial load
duke
parents:
diff changeset
461 #undef FORWARD_DECLARE_EACH_CLASS
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 inline relocInfo filler_relocInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 return relocInfo(relocInfo::none, relocInfo::offset_limit() - relocInfo::offset_unit);
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 inline relocInfo prefix_relocInfo(int datalen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 assert(relocInfo::fits_into_immediate(datalen), "datalen in limits");
a61af66fc99e Initial load
duke
parents:
diff changeset
471 return relocInfo(relocInfo::data_prefix_tag, relocInfo::RAW_BITS, relocInfo::datalen_tag | datalen);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Holder for flyweight relocation objects.
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Although the flyweight subclasses are of varying sizes,
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // the holder is "one size fits all".
a61af66fc99e Initial load
duke
parents:
diff changeset
478 class RelocationHolder VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 friend class Relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 friend class CodeSection;
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // this preallocated memory must accommodate all subclasses of Relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // (this number is assertion-checked in Relocation::operator new)
a61af66fc99e Initial load
duke
parents:
diff changeset
485 enum { _relocbuf_size = 5 };
a61af66fc99e Initial load
duke
parents:
diff changeset
486 void* _relocbuf[ _relocbuf_size ];
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
489 Relocation* reloc() const { return (Relocation*) &_relocbuf[0]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 inline relocInfo::relocType type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Add a constant offset to a relocation. Helper for class Address.
a61af66fc99e Initial load
duke
parents:
diff changeset
493 RelocationHolder plus(int offset) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 inline RelocationHolder(); // initializes type to none
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 inline RelocationHolder(Relocation* r); // make a copy
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 static const RelocationHolder none;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 };
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // A RelocIterator iterates through the relocation information of a CodeBlob.
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // It is a variable BoundRelocation which is able to take on successive
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // values as it is advanced through a code stream.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // Usage:
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // RelocIterator iter(nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // iter.reloc()->some_operation();
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // or:
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // RelocIterator iter(nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // switch (iter.type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // case relocInfo::oop_type :
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // case relocInfo::ic_type :
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // case relocInfo::prim_type :
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // case relocInfo::uncommon_type :
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // case relocInfo::runtime_call_type :
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // case relocInfo::internal_word_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // case relocInfo::external_word_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 class RelocIterator : public StackObj {
1762
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
526 enum { SECT_LIMIT = 3 }; // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor
0
a61af66fc99e Initial load
duke
parents:
diff changeset
527 friend class Relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
528 friend class relocInfo; // for change_reloc_info_for_address only
a61af66fc99e Initial load
duke
parents:
diff changeset
529 typedef relocInfo::relocType relocType;
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
532 address _limit; // stop producing relocations after this _addr
a61af66fc99e Initial load
duke
parents:
diff changeset
533 relocInfo* _current; // the current relocation information
a61af66fc99e Initial load
duke
parents:
diff changeset
534 relocInfo* _end; // end marker; we're done iterating when _current == _end
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
535 nmethod* _code; // compiled method containing _addr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
536 address _addr; // instruction to which the relocation applies
a61af66fc99e Initial load
duke
parents:
diff changeset
537 short _databuf; // spare buffer for compressed data
a61af66fc99e Initial load
duke
parents:
diff changeset
538 short* _data; // pointer to the relocation's data
a61af66fc99e Initial load
duke
parents:
diff changeset
539 short _datalen; // number of halfwords in _data
a61af66fc99e Initial load
duke
parents:
diff changeset
540 char _format; // position within the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Base addresses needed to compute targets of section_word_type relocs.
a61af66fc99e Initial load
duke
parents:
diff changeset
543 address _section_start[SECT_LIMIT];
1762
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
544 address _section_end [SECT_LIMIT];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 void set_has_current(bool b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 _datalen = !b ? -1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 debug_only(_data = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550 void set_current(relocInfo& ri) {
a61af66fc99e Initial load
duke
parents:
diff changeset
551 _current = &ri;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 set_has_current(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 RelocationHolder _rh; // where the current relocation is allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 relocInfo* current() const { assert(has_current(), "must have current");
a61af66fc99e Initial load
duke
parents:
diff changeset
558 return _current; }
a61af66fc99e Initial load
duke
parents:
diff changeset
559
a61af66fc99e Initial load
duke
parents:
diff changeset
560 void set_limits(address begin, address limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 void advance_over_prefix(); // helper method
a61af66fc99e Initial load
duke
parents:
diff changeset
563
1762
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
564 void initialize_misc();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
565
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
566 void initialize(nmethod* nm, address begin, address limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 friend class PatchingRelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // make an uninitialized one, for PatchingRelocIterator:
a61af66fc99e Initial load
duke
parents:
diff changeset
570 RelocIterator() { initialize_misc(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // constructor
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
574 RelocIterator(nmethod* nm, address begin = NULL, address limit = NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
575 RelocIterator(CodeSection* cb, address begin = NULL, address limit = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // get next reloc info, return !eos
a61af66fc99e Initial load
duke
parents:
diff changeset
578 bool next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 _current++;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 assert(_current <= _end, "must not overrun relocInfo");
a61af66fc99e Initial load
duke
parents:
diff changeset
581 if (_current == _end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
582 set_has_current(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
583 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 set_has_current(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 if (_current->is_prefix()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 advance_over_prefix();
a61af66fc99e Initial load
duke
parents:
diff changeset
589 assert(!current()->is_prefix(), "only one prefix at a time");
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 _addr += _current->addr_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 if (_limit != NULL && _addr >= _limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 set_has_current(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (relocInfo::have_format) _format = current()->format();
a61af66fc99e Initial load
duke
parents:
diff changeset
600 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
604 address limit() const { return _limit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
605 void set_limit(address x);
a61af66fc99e Initial load
duke
parents:
diff changeset
606 relocType type() const { return current()->type(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
607 int format() const { return (relocInfo::have_format) ? current()->format() : 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
608 address addr() const { return _addr; }
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
609 nmethod* code() const { return _code; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
610 short* data() const { return _data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
611 int datalen() const { return _datalen; }
a61af66fc99e Initial load
duke
parents:
diff changeset
612 bool has_current() const { return _datalen >= 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 void set_addr(address addr) { _addr = addr; }
1762
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
615 bool addr_in_const() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 address section_start(int n) const {
1762
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
618 assert(_section_start[n], "must be initialized");
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
619 return _section_start[n];
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
620 }
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
621 address section_end(int n) const {
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
622 assert(_section_end[n], "must be initialized");
0878d7bae69f 6961697: move nmethod constants section before instruction section
twisti
parents: 1579
diff changeset
623 return _section_end[n];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // The address points to the affected displacement part of the instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // For RISC, this is just the whole instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // For Intel, this is an unaligned 32-bit word.
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // type-specific relocation accessors: oop_Relocation* oop_reloc(), etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
631 #define EACH_TYPE(name) \
a61af66fc99e Initial load
duke
parents:
diff changeset
632 inline name##_Relocation* name##_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
633 APPLY_TO_RELOCATIONS(EACH_TYPE)
a61af66fc99e Initial load
duke
parents:
diff changeset
634 #undef EACH_TYPE
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // generic relocation accessor; switches on type to call the above
a61af66fc99e Initial load
duke
parents:
diff changeset
636 Relocation* reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // CodeBlob's have relocation indexes for faster random access:
a61af66fc99e Initial load
duke
parents:
diff changeset
639 static int locs_and_index_size(int code_size, int locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // Store an index into [dest_start+dest_count..dest_end).
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // At dest_start[0..dest_count] is the actual relocation information.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // Everything else up to dest_end is free space for the index.
a61af66fc99e Initial load
duke
parents:
diff changeset
643 static void create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
646 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
647 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
648 void print_current();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
650 };
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // A Relocation is a flyweight object allocated within a RelocationHolder.
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // It represents the relocation data of relocation record.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // So, the RelocIterator unpacks relocInfos into Relocations.
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 class Relocation VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
658 friend class RelocationHolder;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
662 static void guarantee_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // When a relocation has been created by a RelocIterator,
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // this field is non-null. It allows the relocation to know
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // its context, such as the address to which it applies.
a61af66fc99e Initial load
duke
parents:
diff changeset
667 RelocIterator* _binding;
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
670 RelocIterator* binding() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
671 assert(_binding != NULL, "must be bound");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 return _binding;
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674 void set_binding(RelocIterator* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 assert(_binding == NULL, "must be unbound");
a61af66fc99e Initial load
duke
parents:
diff changeset
676 _binding = b;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 assert(_binding != NULL, "must now be bound");
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 Relocation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 _binding = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 static RelocationHolder newHolder() {
a61af66fc99e Initial load
duke
parents:
diff changeset
685 return RelocationHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
689 void* operator new(size_t size, const RelocationHolder& holder) {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 if (size > sizeof(holder._relocbuf)) guarantee_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree");
a61af66fc99e Initial load
duke
parents:
diff changeset
692 return holder.reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // make a generic relocation for a given type (if possible)
a61af66fc99e Initial load
duke
parents:
diff changeset
696 static RelocationHolder spec_simple(relocInfo::relocType rtype);
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // here is the type-specific hook which writes relocation data:
a61af66fc99e Initial load
duke
parents:
diff changeset
699 virtual void pack_data_to(CodeSection* dest) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // here is the type-specific hook which reads (unpacks) relocation data:
a61af66fc99e Initial load
duke
parents:
diff changeset
702 virtual void unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
703 assert(datalen()==0 || type()==relocInfo::none, "no data here");
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
2455
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
706 static bool is_reloc_index(intptr_t index) {
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
707 return 0 < index && index < os::vm_page_size();
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
708 }
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
709
0
a61af66fc99e Initial load
duke
parents:
diff changeset
710 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // Helper functions for pack_data_to() and unpack_data().
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // Most of the compression logic is confined here.
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // (The "immediate data" mechanism of relocInfo works independently
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // of this stuff, and acts to further compress most 1-word data prefixes.)
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // A variable-width int is encoded as a short if it will fit in 16 bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // The decoder looks at datalen to decide whether to unpack short or jint.
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // Most relocation records are quite simple, containing at most two ints.
a61af66fc99e Initial load
duke
parents:
diff changeset
720
a61af66fc99e Initial load
duke
parents:
diff changeset
721 static bool is_short(jint x) { return x == (short)x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
722 static short* add_short(short* p, int x) { *p++ = x; return p; }
a61af66fc99e Initial load
duke
parents:
diff changeset
723 static short* add_jint (short* p, jint x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 *p++ = relocInfo::data0_from_int(x); *p++ = relocInfo::data1_from_int(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727 static short* add_var_int(short* p, jint x) { // add a variable-width int
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (is_short(x)) p = add_short(p, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 else p = add_jint (p, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
730 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 static short* pack_1_int_to(short* p, jint x0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // Format is one of: [] [x] [Xx]
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (x0 != 0) p = add_var_int(p, x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 int unpack_1_int() {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 assert(datalen() <= 2, "too much data");
a61af66fc99e Initial load
duke
parents:
diff changeset
740 return relocInfo::jint_data_at(0, data(), datalen());
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // With two ints, the short form is used only if both ints are short.
a61af66fc99e Initial load
duke
parents:
diff changeset
744 short* pack_2_ints_to(short* p, jint x0, jint x1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Format is one of: [] [x y?] [Xx Y?y]
a61af66fc99e Initial load
duke
parents:
diff changeset
746 if (x0 == 0 && x1 == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // no halfwords needed to store zeroes
a61af66fc99e Initial load
duke
parents:
diff changeset
748 } else if (is_short(x0) && is_short(x1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // 1-2 halfwords needed to store shorts
a61af66fc99e Initial load
duke
parents:
diff changeset
750 p = add_short(p, x0); if (x1!=0) p = add_short(p, x1);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // 3-4 halfwords needed to store jints
a61af66fc99e Initial load
duke
parents:
diff changeset
753 p = add_jint(p, x0); p = add_var_int(p, x1);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
755 return p;
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757 void unpack_2_ints(jint& x0, jint& x1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 int dlen = datalen();
a61af66fc99e Initial load
duke
parents:
diff changeset
759 short* dp = data();
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (dlen <= 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 x0 = relocInfo::short_data_at(0, dp, dlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 x1 = relocInfo::short_data_at(1, dp, dlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 assert(dlen <= 4, "too much data");
a61af66fc99e Initial load
duke
parents:
diff changeset
765 x0 = relocInfo::jint_data_at(0, dp, dlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 x1 = relocInfo::jint_data_at(2, dp, dlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // platform-dependent utilities for decoding and patching instructions
2375
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
772 void pd_set_data_value (address x, intptr_t off, bool verify_only = false); // a set or mem-ref
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
773 void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
774 address pd_call_destination (address orig_addr = NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
775 void pd_set_call_destination (address x);
a61af66fc99e Initial load
duke
parents:
diff changeset
776 void pd_swap_in_breakpoint (address x, short* instrs, int instrlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 void pd_swap_out_breakpoint (address x, short* instrs, int instrlen);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 static int pd_breakpoint_size ();
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // this extracts the address of an address in the code stream instead of the reloc data
a61af66fc99e Initial load
duke
parents:
diff changeset
781 address* pd_address_in_code ();
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // this extracts an address from the code stream instead of the reloc data
a61af66fc99e Initial load
duke
parents:
diff changeset
784 address pd_get_address_from_code ();
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // these convert from byte offsets, to scaled offsets, to addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
787 static jint scaled_offset(address x, address base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 int byte_offset = x - base;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 int offset = -byte_offset / relocInfo::addr_unit();
a61af66fc99e Initial load
duke
parents:
diff changeset
790 assert(address_from_scaled_offset(offset, base) == x, "just checkin'");
a61af66fc99e Initial load
duke
parents:
diff changeset
791 return offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
793 static jint scaled_offset_null_special(address x, address base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
794 // Some relocations treat offset=0 as meaning NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // Handle this extra convention carefully.
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if (x == NULL) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
797 assert(x != base, "offset must not be zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
798 return scaled_offset(x, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
800 static address address_from_scaled_offset(jint offset, address base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
801 int byte_offset = -( offset * relocInfo::addr_unit() );
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return base + byte_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // these convert between indexes and addresses in the runtime system
a61af66fc99e Initial load
duke
parents:
diff changeset
806 static int32_t runtime_address_to_index(address runtime_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
807 static address index_to_runtime_address(int32_t index);
a61af66fc99e Initial load
duke
parents:
diff changeset
808
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // helpers for mapping between old and new addresses after a move or resize
a61af66fc99e Initial load
duke
parents:
diff changeset
810 address old_addr_for(address newa, const CodeBuffer* src, CodeBuffer* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
811 address new_addr_for(address olda, const CodeBuffer* src, CodeBuffer* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 void normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // accessors which only make sense for a bound Relocation
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
816 address addr() const { return binding()->addr(); }
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
817 nmethod* code() const { return binding()->code(); }
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
818 bool addr_in_const() const { return binding()->addr_in_const(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
819 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
820 short* data() const { return binding()->data(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
821 int datalen() const { return binding()->datalen(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
822 int format() const { return binding()->format(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
825 virtual relocInfo::relocType type() { return relocInfo::none; }
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // is it a call instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
828 virtual bool is_call() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
829
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // is it a data movement instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
831 virtual bool is_data() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // some relocations can compute their own values
a61af66fc99e Initial load
duke
parents:
diff changeset
834 virtual address value();
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // all relocations are able to reassert their values
a61af66fc99e Initial load
duke
parents:
diff changeset
837 virtual void set_value(address x);
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 virtual void clear_inline_cache() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // This method assumes that all virtual/static (inline) caches are cleared (since for static_call_type and
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // probably a reasonable assumption, since empty caches simplifies code reloacation.
a61af66fc99e Initial load
duke
parents:
diff changeset
844 virtual void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
847 };
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // certain inlines must be deferred until class Relocation is defined:
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 inline RelocationHolder::RelocationHolder() {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // initialize the vtbl, just to keep things type-safe
a61af66fc99e Initial load
duke
parents:
diff changeset
854 new(*this) Relocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 inline RelocationHolder::RelocationHolder(Relocation* r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 // wordwise copy from r (ok if it copies garbage after r)
a61af66fc99e Initial load
duke
parents:
diff changeset
860 for (int i = 0; i < _relocbuf_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 _relocbuf[i] = ((void**)r)[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 relocInfo::relocType RelocationHolder::type() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
867 return reloc()->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // A DataRelocation always points at a memory or load-constant instruction..
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // It is absolute on most machines, and the constant is split on RISCs.
a61af66fc99e Initial load
duke
parents:
diff changeset
872 // The specific subtypes are oop, external_word, and internal_word.
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // By convention, the "value" does not include a separately reckoned "offset".
a61af66fc99e Initial load
duke
parents:
diff changeset
874 class DataRelocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
875 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
876 bool is_data() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // both target and offset must be computed somehow from relocation data
a61af66fc99e Initial load
duke
parents:
diff changeset
879 virtual int offset() { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
880 address value() = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
881 void set_value(address x) { set_value(x, offset()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
882 void set_value(address x, intptr_t o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 if (addr_in_const())
a61af66fc99e Initial load
duke
parents:
diff changeset
884 *(address*)addr() = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
885 else
a61af66fc99e Initial load
duke
parents:
diff changeset
886 pd_set_data_value(x, o);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 }
2375
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
888 void verify_value(address x) {
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
889 if (addr_in_const())
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
890 assert(*(address*)addr() == x, "must agree");
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
891 else
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
892 pd_verify_data_value(x, offset());
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
893 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // The "o" (displacement) argument is relevant only to split relocations
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // on RISC machines. In some CPUs (SPARC), the set-hi and set-lo ins'ns
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // can encode more than 32 bits between them. This allows compilers to
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // share set-hi instructions between addresses that differ by a small
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // offset (e.g., different static variables in the same class).
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // On such machines, the "x" argument to set_value on all set-lo
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // instructions must be the same as the "x" argument for the
a61af66fc99e Initial load
duke
parents:
diff changeset
902 // corresponding set-hi instructions. The "o" arguments for the
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // set-hi instructions are ignored, and must not affect the high-half
a61af66fc99e Initial load
duke
parents:
diff changeset
904 // immediate constant. The "o" arguments for the set-lo instructions are
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // added into the low-half immediate constant, and must not overflow it.
a61af66fc99e Initial load
duke
parents:
diff changeset
906 };
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // A CallRelocation always points at a call instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // It is PC-relative on most machines.
a61af66fc99e Initial load
duke
parents:
diff changeset
910 class CallRelocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
912 bool is_call() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 address destination() { return pd_call_destination(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
915 void set_destination(address x); // pd_set_call_destination
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 address value() { return destination(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
919 void set_value(address x) { set_destination(x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
920 };
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 class oop_Relocation : public DataRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 relocInfo::relocType type() { return relocInfo::oop_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // encode in one of these formats: [] [n] [n l] [Nn l] [Nn Ll]
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // an oop in the CodeBlob's oop pool
a61af66fc99e Initial load
duke
parents:
diff changeset
928 static RelocationHolder spec(int oop_index, int offset = 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 assert(oop_index > 0, "must be a pool-resident oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
930 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 new(rh) oop_Relocation(oop_index, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // an oop in the instruction stream
a61af66fc99e Initial load
duke
parents:
diff changeset
935 static RelocationHolder spec_for_immediate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 const int oop_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 const int offset = 0; // if you want an offset, use the oop pool
a61af66fc99e Initial load
duke
parents:
diff changeset
938 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
939 new(rh) oop_Relocation(oop_index, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
940 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
944 jint _oop_index; // if > 0, index into CodeBlob::oop_at
a61af66fc99e Initial load
duke
parents:
diff changeset
945 jint _offset; // byte offset to apply to the oop itself
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 oop_Relocation(int oop_index, int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 _oop_index = oop_index; _offset = offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
952 oop_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
955 int oop_index() { return _oop_index; }
a61af66fc99e Initial load
duke
parents:
diff changeset
956 int offset() { return _offset; }
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // data is packed in "2_ints" format: [i o] or [Ii Oo]
a61af66fc99e Initial load
duke
parents:
diff changeset
959 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
960 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 void fix_oop_relocation(); // reasserts oop value
a61af66fc99e Initial load
duke
parents:
diff changeset
963
2375
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
964 void verify_oop_relocation();
d673ef06fe96 7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents: 2192
diff changeset
965
0
a61af66fc99e Initial load
duke
parents:
diff changeset
966 address value() { return (address) *oop_addr(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 bool oop_is_immediate() { return oop_index() == 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970 oop* oop_addr(); // addr or &pool[jint_data]
a61af66fc99e Initial load
duke
parents:
diff changeset
971 oop oop_value(); // *oop_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // Note: oop_value transparently converts Universe::non_oop_word to NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
973 };
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 class virtual_call_Relocation : public CallRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 relocInfo::relocType type() { return relocInfo::virtual_call_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // "first_oop" points to the first associated set-oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // The oop_limit helps find the last associated set-oop.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // (See comments at the top of this file.)
a61af66fc99e Initial load
duke
parents:
diff changeset
982 static RelocationHolder spec(address first_oop, address oop_limit = NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
984 new(rh) virtual_call_Relocation(first_oop, oop_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
985 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 virtual_call_Relocation(address first_oop, address oop_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 _first_oop = first_oop; _oop_limit = oop_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 assert(first_oop != NULL, "first oop address must be specified");
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
994 address _first_oop; // location of first set-oop instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
995 address _oop_limit; // search limit for set-oop instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 virtual_call_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 address first_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 address oop_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // data is packed as scaled offsets in "2_ints" format: [f l] or [Ff Ll]
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 // oop_limit is set to 0 if the limit falls somewhere within the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // When unpacking, a zero oop_limit is taken to refer to the end of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 // (This has the effect of bringing in the call's delay slot on SPARC.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 void clear_inline_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
1013
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // Figure out where an ic_call is hiding, given a set-oop or call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // Either ic_call or first_oop must be non-null; the other is deduced.
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1016 // Code if non-NULL must be the nmethod, else it is deduced.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // The address of the patchable oop is also deduced.
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 // The returned iterator will enumerate over the oops and the ic_call,
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 // as well as any other relocations that happen to be in that span of code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 // Recognize relevant set_oops with: oop_reloc()->oop_addr() == oop_addr.
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1021 static RelocIterator parse_ic(nmethod* &nm, address &ic_call, address &first_oop, oop* &oop_addr, bool *is_optimized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 class opt_virtual_call_Relocation : public CallRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 static RelocationHolder spec() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 new(rh) opt_virtual_call_Relocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 opt_virtual_call_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 void clear_inline_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 // find the matching static_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 address static_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 class static_call_Relocation : public CallRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 relocInfo::relocType type() { return relocInfo::static_call_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 static RelocationHolder spec() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 new(rh) static_call_Relocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 static_call_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 void clear_inline_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
1063
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 // find the matching static_stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 address static_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 class static_stub_Relocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 relocInfo::relocType type() { return relocInfo::static_stub_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 static RelocationHolder spec(address static_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 new(rh) static_stub_Relocation(static_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 address _static_call; // location of corresponding static_call
a61af66fc99e Initial load
duke
parents:
diff changeset
1080
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 static_stub_Relocation(address static_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 _static_call = static_call;
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 static_stub_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 void clear_inline_cache();
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 address static_call() { return _static_call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // data is packed as a scaled offset in "1_int" format: [c] or [Cc]
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 class runtime_call_Relocation : public CallRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 relocInfo::relocType type() { return relocInfo::runtime_call_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 static RelocationHolder spec() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 new(rh) runtime_call_Relocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 runtime_call_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1114
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 class external_word_Relocation : public DataRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 relocInfo::relocType type() { return relocInfo::external_word_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 static RelocationHolder spec(address target) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 assert(target != NULL, "must not be null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 new(rh) external_word_Relocation(target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Use this one where all 32/64 bits of the target live in the code stream.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // The target must be an intptr_t, and must be absolute (not relative).
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 static RelocationHolder spec_for_immediate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 new(rh) external_word_Relocation(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1133
2455
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1134 // Some address looking values aren't safe to treat as relocations
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1135 // and should just be treated as constants.
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1136 static bool can_be_relocated(address target) {
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1137 return target != NULL && !is_reloc_index((intptr_t)target);
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1138 }
479b4b4b6950 6777083: assert(target != __null,"must not be null")
never
parents: 2375
diff changeset
1139
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 address _target; // address in runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 external_word_Relocation(address target) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 _target = target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 external_word_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // data is packed as a well-known address in "1_int" format: [a] or [Aa]
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // The function runtime_address_to_index is used to turn full addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // to short indexes, if they are pre-registered by the stub mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // If the "a" value is 0 (i.e., _target is NULL), the address is stored
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // in the code stream. See external_word_Relocation::target().
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 address target(); // if _target==NULL, fetch addr from code stream
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 address value() { return target(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1163
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 class internal_word_Relocation : public DataRelocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 relocInfo::relocType type() { return relocInfo::internal_word_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1166
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 static RelocationHolder spec(address target) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 assert(target != NULL, "must not be null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 new(rh) internal_word_Relocation(target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // use this one where all the bits of the target can fit in the code stream:
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 static RelocationHolder spec_for_immediate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 new(rh) internal_word_Relocation(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 internal_word_Relocation(address target) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 _target = target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 _section = -1; // self-relative
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 address _target; // address in CodeBlob
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 int _section; // section providing base address, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 internal_word_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // bit-width of LSB field in packed offset, if section >= 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 enum { section_width = 2 }; // must equal CodeBuffer::sect_bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1196
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // data is packed as a scaled offset in "1_int" format: [o] or [Oo]
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // If the "o" value is 0 (i.e., _target is NULL), the offset is stored
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // in the code stream. See internal_word_Relocation::target().
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // If _section is not -1, it is appended to the low bits of the offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1204
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 address target(); // if _target==NULL, fetch addr from code stream
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 int section() { return _section; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 address value() { return target(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 class section_word_Relocation : public internal_word_Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 relocInfo::relocType type() { return relocInfo::section_word_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 static RelocationHolder spec(address target, int section) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 new(rh) section_word_Relocation(target, section);
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1220
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 section_word_Relocation(address target, int section) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 assert(target != NULL, "must not be null");
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 assert(section >= 0, "must be a valid section");
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 _target = target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 _section = section;
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 //void pack_data_to -- inherited
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1230
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 section_word_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 class poll_Relocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 bool is_data() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 relocInfo::relocType type() { return relocInfo::poll_type; }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1240 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1242
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 class poll_return_Relocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 bool is_data() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 relocInfo::relocType type() { return relocInfo::poll_return_type; }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1246 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 class breakpoint_Relocation : public Relocation {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 relocInfo::relocType type() { return relocInfo::breakpoint_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // attributes which affect the interpretation of the data:
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 removable_attr = 0x0010, // buffer [i...] allows for undoing the trap
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 internal_attr = 0x0020, // the target is an internal addr (local stub)
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 settable_attr = 0x0040, // the target is settable
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // states which can change over time:
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 enabled_state = 0x0100, // breakpoint must be active in running code
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 active_state = 0x0200, // breakpoint instruction actually in code
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 kind_mask = 0x000F, // mask for extracting kind
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 high_bit = 0x4000 // extra bit which is always set
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1266
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // kinds:
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 initialization = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 safepoint = 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1273
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // If target is NULL, 32 bits are reserved for a later set_target().
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 static RelocationHolder spec(int kind, address target = NULL, bool internal_target = false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 RelocationHolder rh = newHolder();
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 new(rh) breakpoint_Relocation(kind, target, internal_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 return rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // We require every bits value to NOT to fit into relocInfo::datalen_width,
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // because we are going to actually store state in the reloc, and so
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // cannot allow it to be compressed (and hence copied by the iterator).
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 short _bits; // bit-encoded kind, attrs, & state
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 address _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 breakpoint_Relocation(int kind, address target, bool internal_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
1290
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 friend class RelocIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 breakpoint_Relocation() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1293
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 short bits() const { return _bits; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 short& live_bits() const { return data()[0]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 short* instrs() const { return data() + datalen() - instrlen(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 int instrlen() const { return removable() ? pd_breakpoint_size() : 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1298
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 void set_bits(short x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 assert(live_bits() == _bits, "must be the only mutator of reloc info");
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 live_bits() = _bits = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 address target() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 void set_target(address x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 int kind() const { return bits() & kind_mask; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 bool enabled() const { return (bits() & enabled_state) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 bool active() const { return (bits() & active_state) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 bool internal() const { return (bits() & internal_attr) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 bool removable() const { return (bits() & removable_attr) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 bool settable() const { return (bits() & settable_attr) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1314
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 void set_enabled(bool b); // to activate, you must also say set_active
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 void set_active(bool b); // actually inserts bpt (must be enabled 1st)
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // data is packed as 16 bits, followed by the target (1 or 2 words), followed
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // if necessary by empty storage for saving away original instruction bytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 void pack_data_to(CodeSection* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 void unpack_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // during certain operations, breakpoints must be out of the way:
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 assert(!active(), "cannot perform relocation on enabled breakpoints");
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // We know all the xxx_Relocation classes, so now we can define these:
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 #define EACH_CASE(name) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 inline name##_Relocation* RelocIterator::name##_reloc() { \
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 assert(type() == relocInfo::name##_type, "type must agree"); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 /* The purpose of the placed "new" is to re-use the same */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 /* stack storage for each new iteration. */ \
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 name##_Relocation* r = new(_rh) name##_Relocation(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 r->set_binding(this); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 r->name##_Relocation::unpack_data(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 return r; \
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 APPLY_TO_RELOCATIONS(EACH_CASE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 #undef EACH_CASE
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1344 inline RelocIterator::RelocIterator(nmethod* nm, address begin, address limit) {
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1345 initialize(nm, begin, limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // if you are going to patch code, you should use this subclass of
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 // RelocIterator
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 class PatchingRelocIterator : public RelocIterator {
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 RelocIterator _init_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 void prepass(); // deactivates all breakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 void postpass(); // reactivates all enabled breakpoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1356
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // do not copy these puppies; it would have unpredictable side effects
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 // these are private and have no bodies defined because they should not be called
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 PatchingRelocIterator(const RelocIterator&);
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 void operator=(const RelocIterator&);
a61af66fc99e Initial load
duke
parents:
diff changeset
1361
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 public:
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1363 PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL)
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 337
diff changeset
1364 : RelocIterator(nm, begin, limit) { prepass(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 ~PatchingRelocIterator() { postpass(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
1368
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1762
diff changeset
1369 #endif // SHARE_VM_CODE_RELOCINFO_HPP