annotate src/share/vm/code/relocInfo.hpp @ 1721:413ad0331a0c

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