annotate src/share/vm/code/relocInfo.cpp @ 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 3e8fbc61cee8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1579
jrose
parents: 1552 1563
diff changeset
2 * Copyright (c) 1997, 2010, 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: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
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: 0
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 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_relocInfo.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 const RelocationHolder RelocationHolder::none; // its type is relocInfo::none
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Implementation of relocInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
35 relocInfo::relocInfo(relocType t, int off, int f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
36 assert(t != data_prefix_tag, "cannot build a prefix this way");
a61af66fc99e Initial load
duke
parents:
diff changeset
37 assert((t & type_mask) == t, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
38 assert((f & format_mask) == f, "wrong format");
a61af66fc99e Initial load
duke
parents:
diff changeset
39 assert(off >= 0 && off < offset_limit(), "offset out off bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
40 assert((off & (offset_unit-1)) == 0, "misaligned offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
41 (*this) = relocInfo(t, RAW_BITS, off, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
42 }
a61af66fc99e Initial load
duke
parents:
diff changeset
43 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 void relocInfo::initialize(CodeSection* dest, Relocation* reloc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 relocInfo* data = this+1; // here's where the data might go
a61af66fc99e Initial load
duke
parents:
diff changeset
47 dest->set_locs_end(data); // sync end: the next call may read dest.locs_end
a61af66fc99e Initial load
duke
parents:
diff changeset
48 reloc->pack_data_to(dest); // maybe write data into locs, advancing locs_end
a61af66fc99e Initial load
duke
parents:
diff changeset
49 relocInfo* data_limit = dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
50 if (data_limit > data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 relocInfo suffix = (*this);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 data_limit = this->finish_prefix((short*) data_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Finish up with the suffix. (Hack note: pack_data_to might edit this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
54 *data_limit = suffix;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 dest->set_locs_end(data_limit+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 relocInfo* relocInfo::finish_prefix(short* prefix_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 assert(sizeof(relocInfo) == sizeof(short), "change this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
61 short* p = (short*)(this+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 assert(prefix_limit >= p, "must be a valid span of data");
a61af66fc99e Initial load
duke
parents:
diff changeset
63 int plen = prefix_limit - p;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 if (plen == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 debug_only(_value = 0xFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 return this; // no data: remove self completely
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (plen == 1 && fits_into_immediate(p[0])) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 (*this) = immediate_relocInfo(p[0]); // move data inside self
a61af66fc99e Initial load
duke
parents:
diff changeset
70 return this+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // cannot compact, so just update the count and return the limit pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
73 (*this) = prefix_relocInfo(plen); // write new datalen
a61af66fc99e Initial load
duke
parents:
diff changeset
74 assert(data() + datalen() == prefix_limit, "pointers must line up");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 return (relocInfo*)prefix_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 void relocInfo::set_type(relocType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 int old_offset = addr_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
81 int old_format = format();
a61af66fc99e Initial load
duke
parents:
diff changeset
82 (*this) = relocInfo(t, old_offset, old_format);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 assert(type()==(int)t, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
84 assert(addr_offset()==old_offset, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 assert(format()==old_format, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 void relocInfo::set_format(int f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 int old_offset = addr_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert((f & format_mask) == f, "wrong format");
a61af66fc99e Initial load
duke
parents:
diff changeset
92 _value = (_value & ~(format_mask << offset_width)) | (f << offset_width);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 assert(addr_offset()==old_offset, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 while (itr->next() && !found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 if (itr->addr() == pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
101 assert(itr->type()==old_type, "wrong relocInfo type found");
a61af66fc99e Initial load
duke
parents:
diff changeset
102 itr->current()->set_type(new_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
103 found=true;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106 assert(found, "no relocInfo found for pc");
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 change_reloc_info_for_address(itr, pc, old_type, none);
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // ----------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Implementation of RelocIterator
a61af66fc99e Initial load
duke
parents:
diff changeset
117
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
118 void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
119 initialize_misc();
a61af66fc99e Initial load
duke
parents:
diff changeset
120
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
121 if (nm == NULL && begin != NULL) {
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
122 // allow nmethod to be deduced from beginning address
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
123 CodeBlob* cb = CodeCache::find_blob(begin);
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
124 nm = cb->as_nmethod_or_null();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
126 assert(nm != NULL, "must be able to deduce nmethod from other arguments");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
128 _code = nm;
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
129 _current = nm->relocation_begin() - 1;
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
130 _end = nm->relocation_end();
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
131 _addr = (address) nm->instructions_begin();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 assert(!has_current(), "just checking");
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
134 address code_end = nm->instructions_end();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
136 assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // FIX THIS assert(limit == NULL || limit <= code_end, "in bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
138 set_limits(begin, limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 initialize_misc();
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 _current = cs->locs_start()-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 _end = cs->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
147 _addr = cs->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
148 _code = NULL; // Not cb->blob();
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 CodeBuffer* cb = cs->outer();
a61af66fc99e Initial load
duke
parents:
diff changeset
151 assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
152 for (int n = 0; n < (int)SECT_LIMIT; n++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 _section_start[n] = cb->code_section(n)->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 assert(!has_current(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert(begin == NULL || begin >= cs->start(), "in bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 assert(limit == NULL || limit <= cs->end(), "in bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
160 set_limits(begin, limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 enum { indexCardSize = 128 };
a61af66fc99e Initial load
duke
parents:
diff changeset
165 struct RelocIndexEntry {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 jint addr_offset; // offset from header_end of an addr()
a61af66fc99e Initial load
duke
parents:
diff changeset
167 jint reloc_offset; // offset from header_end of a relocInfo (prefix)
a61af66fc99e Initial load
duke
parents:
diff changeset
168 };
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 static inline int num_cards(int code_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return (code_size-1) / indexCardSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 int RelocIterator::locs_and_index_size(int code_size, int locs_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 if (!UseRelocIndex) return locs_size; // no index
a61af66fc99e Initial load
duke
parents:
diff changeset
178 code_size = round_to(code_size, oopSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 locs_size = round_to(locs_size, oopSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int index_size = num_cards(code_size) * sizeof(RelocIndexEntry);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // format of indexed relocs:
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // relocation_begin: relocInfo ...
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // index: (addr,reloc#) ...
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // indexSize :relocation_end
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return locs_size + index_size + BytesPerInt;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 void RelocIterator::create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 address relocation_begin = (address)dest_begin;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 address relocation_end = (address)dest_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 int total_size = relocation_end - relocation_begin;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 int locs_size = dest_count * sizeof(relocInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (!UseRelocIndex) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 Copy::fill_to_bytes(relocation_begin + locs_size, total_size-locs_size, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 int index_size = total_size - locs_size - BytesPerInt; // find out how much space is left
a61af66fc99e Initial load
duke
parents:
diff changeset
199 int ncards = index_size / sizeof(RelocIndexEntry);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 assert(total_size == locs_size + index_size + BytesPerInt, "checkin'");
a61af66fc99e Initial load
duke
parents:
diff changeset
201 assert(index_size >= 0 && index_size % sizeof(RelocIndexEntry) == 0, "checkin'");
a61af66fc99e Initial load
duke
parents:
diff changeset
202 jint* index_size_addr = (jint*)relocation_end - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 assert(sizeof(jint) == BytesPerInt, "change this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 *index_size_addr = index_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (index_size != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 assert(index_size > 0, "checkin'");
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 RelocIndexEntry* index = (RelocIndexEntry *)(relocation_begin + locs_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 assert(index == (RelocIndexEntry*)index_size_addr - ncards, "checkin'");
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // walk over the relocations, and fill in index entries as we go
a61af66fc99e Initial load
duke
parents:
diff changeset
214 RelocIterator iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 const address initial_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 relocInfo* const initial_current = dest_begin - 1; // biased by -1 like elsewhere
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 iter._code = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 iter._addr = initial_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 iter._limit = (address)(intptr_t)(ncards * indexCardSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 iter._current = initial_current;
a61af66fc99e Initial load
duke
parents:
diff changeset
222 iter._end = dest_begin + dest_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 address next_card_addr = (address)indexCardSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 int addr_offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
227 int reloc_offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Checkpoint the iterator before advancing it.
a61af66fc99e Initial load
duke
parents:
diff changeset
230 addr_offset = iter._addr - initial_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 reloc_offset = iter._current - initial_current;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (!iter.next()) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 while (iter.addr() >= next_card_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 index[i].addr_offset = addr_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 index[i].reloc_offset = reloc_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 next_card_addr += indexCardSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 while (i < ncards) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 index[i].addr_offset = addr_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 index[i].reloc_offset = reloc_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
243 i++;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 void RelocIterator::set_limits(address begin, address limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 int index_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 if (UseRelocIndex && _code != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 index_size = ((jint*)_end)[-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
253 _end = (relocInfo*)( (address)_end - index_size - BytesPerInt );
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 _limit = limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // the limit affects this next stuff:
a61af66fc99e Initial load
duke
parents:
diff changeset
259 if (begin != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // In ASSERT mode we do not actually use the index, but simply
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // check that its contents would have led us to the right answer.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 address addrCheck = _addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 relocInfo* infoCheck = _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
265 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
266 if (index_size > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // skip ahead
a61af66fc99e Initial load
duke
parents:
diff changeset
268 RelocIndexEntry* index = (RelocIndexEntry*)_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 assert(_addr == _code->instructions_begin(), "_addr must be unadjusted");
a61af66fc99e Initial load
duke
parents:
diff changeset
271 int card = (begin - _addr) / indexCardSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 if (card > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if (index+card-1 < index_limit) index += card-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 else index = index_limit - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
276 addrCheck = _addr + index->addr_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 infoCheck = _current + index->reloc_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Advance the iterator immediately to the last valid state
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // for the previous card. Calling "next" will then advance
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // it to the first item on the required card.
a61af66fc99e Initial load
duke
parents:
diff changeset
282 _addr += index->addr_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 _current += index->reloc_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 relocInfo* backup;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 address backup_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 backup = _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 backup_addr = _addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
293 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
294 if (backup == infoCheck) {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 assert(backup_addr == addrCheck, "must match"); addrCheck = NULL; infoCheck = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 assert(addrCheck == NULL || backup_addr <= addrCheck, "must not pass addrCheck");
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (!next() || addr() >= begin) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302 assert(addrCheck == NULL || addrCheck == backup_addr, "must have matched addrCheck");
a61af66fc99e Initial load
duke
parents:
diff changeset
303 assert(infoCheck == NULL || infoCheck == backup, "must have matched infoCheck");
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // At this point, either we are at the first matching record,
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // or else there is no such record, and !has_current().
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // In either case, revert to the immediatly preceding state.
a61af66fc99e Initial load
duke
parents:
diff changeset
307 _current = backup;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 _addr = backup_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 set_has_current(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 void RelocIterator::set_limit(address limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 address code_end = (address)code() + code()->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
316 assert(limit == NULL || limit <= code_end, "in bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
317 _limit = limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 void PatchingRelocIterator:: prepass() {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // turn breakpoints off during patching
a61af66fc99e Initial load
duke
parents:
diff changeset
323 _init_state = (*this); // save cursor
a61af66fc99e Initial load
duke
parents:
diff changeset
324 while (next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 if (type() == relocInfo::breakpoint_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 breakpoint_reloc()->set_active(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 (RelocIterator&)(*this) = _init_state; // reset cursor for client
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 void PatchingRelocIterator:: postpass() {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // turn breakpoints back on after patching
a61af66fc99e Initial load
duke
parents:
diff changeset
335 (RelocIterator&)(*this) = _init_state; // reset cursor again
a61af66fc99e Initial load
duke
parents:
diff changeset
336 while (next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 if (type() == relocInfo::breakpoint_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 breakpoint_Relocation* bpt = breakpoint_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 bpt->set_active(bpt->enabled());
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // All the strange bit-encodings are in here.
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // The idea is to encode relocation data which are small integers
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // very efficiently (a single extra halfword). Larger chunks of
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // relocation data need a halfword header to hold their size.
a61af66fc99e Initial load
duke
parents:
diff changeset
349 void RelocIterator::advance_over_prefix() {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (_current->is_datalen()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _data = (short*) _current->data();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _datalen = _current->datalen();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 _current += _datalen + 1; // skip the embedded data & header
a61af66fc99e Initial load
duke
parents:
diff changeset
354 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _databuf = _current->immediate();
a61af66fc99e Initial load
duke
parents:
diff changeset
356 _data = &_databuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
357 _datalen = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 _current++; // skip the header
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // The client will see the following relocInfo, whatever that is.
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // It is the reloc to which the preceding data applies.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 }
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 address RelocIterator::compute_section_start(int n) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // This routine not only computes a section start, but also
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // memoizes it for later.
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #define CACHE ((RelocIterator*)this)->_section_start[n]
a61af66fc99e Initial load
duke
parents:
diff changeset
369 CodeBlob* cb = code();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 guarantee(cb != NULL, "must have a code blob");
a61af66fc99e Initial load
duke
parents:
diff changeset
371 if (n == CodeBuffer::SECT_INSTS)
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return CACHE = cb->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
373 assert(cb->is_nmethod(), "only nmethods have these sections");
a61af66fc99e Initial load
duke
parents:
diff changeset
374 nmethod* nm = (nmethod*) cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 address res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 switch (n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 case CodeBuffer::SECT_STUBS:
a61af66fc99e Initial load
duke
parents:
diff changeset
378 res = nm->stub_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
379 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 case CodeBuffer::SECT_CONSTS:
a61af66fc99e Initial load
duke
parents:
diff changeset
381 res = nm->consts_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
382 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
383 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
384 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 assert(nm->contains(res) || res == nm->instructions_end(), "tame pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
387 CACHE = res;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
389 #undef CACHE
a61af66fc99e Initial load
duke
parents:
diff changeset
390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
391
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Relocation* RelocIterator::reloc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // (take the "switch" out-of-line)
a61af66fc99e Initial load
duke
parents:
diff changeset
395 relocInfo::relocType t = type();
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (false) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
397 #define EACH_TYPE(name) \
a61af66fc99e Initial load
duke
parents:
diff changeset
398 else if (t == relocInfo::name##_type) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
399 return name##_reloc(); \
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 APPLY_TO_RELOCATIONS(EACH_TYPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 #undef EACH_TYPE
a61af66fc99e Initial load
duke
parents:
diff changeset
403 assert(t == relocInfo::none, "must be padding");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 return new(_rh) Relocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 //////// Methods for flyweight Relocation types
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 RelocationHolder RelocationHolder::plus(int offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 if (offset != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 switch (type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 case relocInfo::none:
a61af66fc99e Initial load
duke
parents:
diff changeset
415 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 case relocInfo::oop_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
417 {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 oop_Relocation* r = (oop_Relocation*)reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
419 return oop_Relocation::spec(r->oop_index(), r->offset() + offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
422 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 return (*this);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 void Relocation::guarantee_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
430 guarantee(false, "Make _relocbuf bigger!");
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // some relocations can compute their own values
a61af66fc99e Initial load
duke
parents:
diff changeset
434 address Relocation::value() {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
436 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 void Relocation::set_value(address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 RelocationHolder Relocation::spec_simple(relocInfo::relocType rtype) {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 if (rtype == relocInfo::none) return RelocationHolder::none;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 relocInfo ri = relocInfo(rtype, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 RelocIterator itr;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 itr.set_current(ri);
a61af66fc99e Initial load
duke
parents:
diff changeset
450 itr.reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return itr._rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 static inline bool is_index(intptr_t index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 return 0 < index && index < os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 int32_t Relocation::runtime_address_to_index(address runtime_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 assert(!is_index((intptr_t)runtime_address), "must not look like an index");
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (runtime_address == NULL) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 StubCodeDesc* p = StubCodeDesc::desc_for(runtime_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
466 if (p != NULL && p->begin() == runtime_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 assert(is_index(p->index()), "there must not be too many stubs");
a61af66fc99e Initial load
duke
parents:
diff changeset
468 return (int32_t)p->index();
a61af66fc99e Initial load
duke
parents:
diff changeset
469 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // Known "miscellaneous" non-stub pointers:
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // os::get_polling_page(), SafepointSynchronize::address_of_state()
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (PrintRelocations) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473 tty->print_cr("random unregistered address in relocInfo: " INTPTR_FORMAT, runtime_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
476 return (int32_t) (intptr_t)runtime_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // didn't fit return non-index
a61af66fc99e Initial load
duke
parents:
diff changeset
479 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
480 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 address Relocation::index_to_runtime_address(int32_t index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if (index == 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 if (is_index(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
489 StubCodeDesc* p = StubCodeDesc::desc_for_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 assert(p != NULL, "there must be a stub for this index");
a61af66fc99e Initial load
duke
parents:
diff changeset
491 return p->begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
492 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
493 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // this only works on 32bit machines
a61af66fc99e Initial load
duke
parents:
diff changeset
495 return (address) ((intptr_t) index);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
497 fatal("Relocation::index_to_runtime_address, int32_t not pointer sized");
a61af66fc99e Initial load
duke
parents:
diff changeset
498 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
499 #endif /* _LP64 */
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 address Relocation::old_addr_for(address newa,
a61af66fc99e Initial load
duke
parents:
diff changeset
504 const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 int sect = dest->section_index_of(newa);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address");
a61af66fc99e Initial load
duke
parents:
diff changeset
507 address ostart = src->code_section(sect)->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
508 address nstart = dest->code_section(sect)->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
509 return ostart + (newa - nstart);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 address Relocation::new_addr_for(address olda,
a61af66fc99e Initial load
duke
parents:
diff changeset
513 const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 debug_only(const CodeBuffer* src0 = src);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 int sect = CodeBuffer::SECT_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // Look for olda in the source buffer, and all previous incarnations
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // if the source buffer has been expanded.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 for (; src != NULL; src = src->before_expand()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 sect = src->section_index_of(olda);
a61af66fc99e Initial load
duke
parents:
diff changeset
520 if (sect != CodeBuffer::SECT_NONE) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address");
a61af66fc99e Initial load
duke
parents:
diff changeset
523 address ostart = src->code_section(sect)->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
524 address nstart = dest->code_section(sect)->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 return nstart + (olda - ostart);
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 void Relocation::normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 address addr0 = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (addr0 == NULL || dest->allocates2(addr0)) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 CodeBuffer* cb = dest->outer();
a61af66fc99e Initial load
duke
parents:
diff changeset
532 addr = new_addr_for(addr0, cb, cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 assert(allow_other_sections || dest->contains2(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
534 "addr must be in required section");
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 void CallRelocation::set_destination(address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 pd_set_call_destination(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // Usually a self-relative reference to an external routine.
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // On some platforms, the reference is absolute (not self-relative).
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // The enhanced use of pd_call_destination sorts this all out.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 address orig_addr = old_addr_for(addr(), src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 address callee = pd_call_destination(orig_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // Reassert the callee address, this time in the new copy of the code.
a61af66fc99e Initial load
duke
parents:
diff changeset
549 pd_set_call_destination(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 //// pack/unpack methods
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 void oop_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
556 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
557 p = pack_2_ints_to(p, _oop_index, _offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
558 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 void oop_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
563 unpack_2_ints(_oop_index, _offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 void virtual_call_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
569 address point = dest->locs_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Try to make a pointer NULL first.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (_oop_limit >= point &&
a61af66fc99e Initial load
duke
parents:
diff changeset
573 _oop_limit <= point + NativeCall::instruction_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 _oop_limit = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // If the _oop_limit is NULL, it "defaults" to the end of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // See ic_call_Relocation::oop_limit() below.
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 normalize_address(_first_oop, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 normalize_address(_oop_limit, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 jint x0 = scaled_offset_null_special(_first_oop, point);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 jint x1 = scaled_offset_null_special(_oop_limit, point);
a61af66fc99e Initial load
duke
parents:
diff changeset
583 p = pack_2_ints_to(p, x0, x1);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588 void virtual_call_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 jint x0, x1; unpack_2_ints(x0, x1);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 address point = addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
591 _first_oop = x0==0? NULL: address_from_scaled_offset(x0, point);
a61af66fc99e Initial load
duke
parents:
diff changeset
592 _oop_limit = x1==0? NULL: address_from_scaled_offset(x1, point);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 void static_stub_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
598 CodeSection* insts = dest->outer()->insts();
a61af66fc99e Initial load
duke
parents:
diff changeset
599 normalize_address(_static_call, insts);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 p = pack_1_int_to(p, scaled_offset(_static_call, insts->start()));
a61af66fc99e Initial load
duke
parents:
diff changeset
601 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 void static_stub_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 address base = binding()->section_start(CodeBuffer::SECT_INSTS);
a61af66fc99e Initial load
duke
parents:
diff changeset
606 _static_call = address_from_scaled_offset(unpack_1_int(), base);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609
a61af66fc99e Initial load
duke
parents:
diff changeset
610 void external_word_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
612 int32_t index = runtime_address_to_index(_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
613 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
614 p = pack_1_int_to(p, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
616 if (is_index(index)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
617 p = pack_2_ints_to(p, index, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 jlong t = (jlong) _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
620 int32_t lo = low(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 int32_t hi = high(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 p = pack_2_ints_to(p, lo, hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 DEBUG_ONLY(jlong t1 = jlong_from(hi, lo));
a61af66fc99e Initial load
duke
parents:
diff changeset
624 assert(!is_index(t1) && (address) t1 == _target, "not symmetric");
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
627 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 void external_word_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
633 _target = index_to_runtime_address(unpack_1_int());
a61af66fc99e Initial load
duke
parents:
diff changeset
634 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
635 int32_t lo, hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 unpack_2_ints(lo, hi);
a61af66fc99e Initial load
duke
parents:
diff changeset
637 jlong t = jlong_from(hi, lo);;
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if (is_index(t)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 _target = index_to_runtime_address(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
640 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 _target = (address) t;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643 #endif /* _LP64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 void internal_word_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 normalize_address(_target, dest, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Check whether my target address is valid within this section.
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // If not, strengthen the relocation type to point to another section.
a61af66fc99e Initial load
duke
parents:
diff changeset
653 int sindex = _section;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if (sindex == CodeBuffer::SECT_NONE && _target != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
655 && (!dest->allocates(_target) || _target == dest->locs_point())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 sindex = dest->outer()->section_index_of(_target);
a61af66fc99e Initial load
duke
parents:
diff changeset
657 guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 relocInfo* base = dest->locs_end() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
659 assert(base->type() == this->type(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // Change the written type, to be section_word_type instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
661 base->set_type(relocInfo::section_word_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // Note: An internal_word relocation cannot refer to its own instruction,
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // because we reserve "0" to mean that the pointer itself is embedded
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // in the code stream. We use a section_word relocation for such cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 if (sindex == CodeBuffer::SECT_NONE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(type() == relocInfo::internal_word_type, "must be base class");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 guarantee(_target == NULL || dest->allocates2(_target), "must be within the given code section");
a61af66fc99e Initial load
duke
parents:
diff changeset
671 jint x0 = scaled_offset_null_special(_target, dest->locs_point());
a61af66fc99e Initial load
duke
parents:
diff changeset
672 assert(!(x0 == 0 && _target != NULL), "correct encoding of null target");
a61af66fc99e Initial load
duke
parents:
diff changeset
673 p = pack_1_int_to(p, x0);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 assert(_target != NULL, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
676 CodeSection* sect = dest->outer()->code_section(sindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
677 guarantee(sect->allocates2(_target), "must be in correct section");
a61af66fc99e Initial load
duke
parents:
diff changeset
678 address base = sect->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
679 jint offset = scaled_offset(_target, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 assert((uint)sindex < (uint)CodeBuffer::SECT_LIMIT, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
681 assert(CodeBuffer::SECT_LIMIT <= (1 << section_width), "section_width++");
a61af66fc99e Initial load
duke
parents:
diff changeset
682 p = pack_1_int_to(p, (offset << section_width) | sindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 void internal_word_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 jint x0 = unpack_1_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 _target = x0==0? NULL: address_from_scaled_offset(x0, addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
692 _section = CodeBuffer::SECT_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
694
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 void section_word_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 jint x = unpack_1_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
698 jint offset = (x >> section_width);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 int sindex = (x & ((1<<section_width)-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
700 address base = binding()->section_start(sindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
701
a61af66fc99e Initial load
duke
parents:
diff changeset
702 _section = sindex;
a61af66fc99e Initial load
duke
parents:
diff changeset
703 _target = address_from_scaled_offset(offset, base);
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707 void breakpoint_Relocation::pack_data_to(CodeSection* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 short* p = (short*) dest->locs_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
709 address point = dest->locs_point();
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 *p++ = _bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 assert(_target != NULL, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (internal()) normalize_address(_target, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 jint target_bits =
a61af66fc99e Initial load
duke
parents:
diff changeset
718 (jint)( internal() ? scaled_offset (_target, point)
a61af66fc99e Initial load
duke
parents:
diff changeset
719 : runtime_address_to_index(_target) );
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (settable()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // save space for set_target later
a61af66fc99e Initial load
duke
parents:
diff changeset
722 p = add_jint(p, target_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
724 p = add_var_int(p, target_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 for (int i = 0; i < instrlen(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 // put placeholder words until bytes can be saved
a61af66fc99e Initial load
duke
parents:
diff changeset
729 p = add_short(p, (short)0x7777);
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 dest->set_locs_end((relocInfo*) p);
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 void breakpoint_Relocation::unpack_data() {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 _bits = live_bits();
a61af66fc99e Initial load
duke
parents:
diff changeset
738
a61af66fc99e Initial load
duke
parents:
diff changeset
739 int targetlen = datalen() - 1 - instrlen();
a61af66fc99e Initial load
duke
parents:
diff changeset
740 jint target_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (targetlen == 0) target_bits = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 else if (targetlen == 1) target_bits = *(data()+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
743 else if (targetlen == 2) target_bits = relocInfo::jint_from_data(data()+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 else { ShouldNotReachHere(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 _target = internal() ? address_from_scaled_offset(target_bits, addr())
a61af66fc99e Initial load
duke
parents:
diff changeset
747 : index_to_runtime_address (target_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 //// miscellaneous methods
a61af66fc99e Initial load
duke
parents:
diff changeset
752 oop* oop_Relocation::oop_addr() {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 int n = _oop_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if (n == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // oop is stored in the code stream
a61af66fc99e Initial load
duke
parents:
diff changeset
756 return (oop*) pd_address_in_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
757 } else {
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
758 // oop is stored in table at nmethod::oops_begin
0
a61af66fc99e Initial load
duke
parents:
diff changeset
759 return code()->oop_addr_at(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 oop oop_Relocation::oop_value() {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 oop v = *oop_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // clean inline caches store a special pseudo-null
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if (v == (oop)Universe::non_oop_word()) v = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
768 return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 void oop_Relocation::fix_oop_relocation() {
a61af66fc99e Initial load
duke
parents:
diff changeset
773 if (!oop_is_immediate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // get the oop from the pool, and re-insert it into the instruction:
a61af66fc99e Initial load
duke
parents:
diff changeset
775 set_value(value());
a61af66fc99e Initial load
duke
parents:
diff changeset
776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
780 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
781 oop* &oop_addr, bool *is_optimized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 assert(ic_call != NULL, "ic_call address must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
783 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
784 if (nm == NULL) {
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
785 CodeBlob* code;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
786 if (ic_call != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 code = CodeCache::find_blob(ic_call);
a61af66fc99e Initial load
duke
parents:
diff changeset
788 } else if (first_oop != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
789 code = CodeCache::find_blob(first_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
790 }
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
791 nm = code->as_nmethod_or_null();
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
792 assert(nm != NULL, "address to parse must be in nmethod");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
793 }
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
794 assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod");
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
795 assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 address oop_limit = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 if (ic_call != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // search for the ic_call at the given address
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
801 RelocIterator iter(nm, ic_call, ic_call+1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
802 bool ret = iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 assert(ret == true, "relocInfo must exist at this address");
a61af66fc99e Initial load
duke
parents:
diff changeset
804 assert(iter.addr() == ic_call, "must find ic_call");
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if (iter.type() == relocInfo::virtual_call_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
806 virtual_call_Relocation* r = iter.virtual_call_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
807 first_oop = r->first_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
808 oop_limit = r->oop_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
809 *is_optimized = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
a61af66fc99e Initial load
duke
parents:
diff changeset
812 *is_optimized = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 oop_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 first_oop = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
815 return iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // search for the first_oop, to get its oop_addr
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
820 RelocIterator all_oops(nm, first_oop);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
821 RelocIterator iter = all_oops;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 iter.set_limit(first_oop+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
823 bool found_oop = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 if (iter.type() == relocInfo::oop_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 assert(iter.addr() == first_oop, "must find first_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
827 oop_addr = iter.oop_reloc()->oop_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
828 found_oop = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832 assert(found_oop, "must find first_oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 bool did_reset = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 while (ic_call == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // search forward for the ic_call matching the given first_oop
a61af66fc99e Initial load
duke
parents:
diff changeset
837 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 if (iter.type() == relocInfo::virtual_call_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 virtual_call_Relocation* r = iter.virtual_call_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (r->first_oop() == first_oop) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 ic_call = r->addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 oop_limit = r->oop_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
843 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847 guarantee(!did_reset, "cannot find ic_call");
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
848 iter = RelocIterator(nm); // search the whole nmethod
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 did_reset = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
853 all_oops.set_limit(oop_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 return all_oops;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 address virtual_call_Relocation::first_oop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
a61af66fc99e Initial load
duke
parents:
diff changeset
860 return _first_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 address virtual_call_Relocation::oop_limit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
865 if (_oop_limit == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
866 return addr() + NativeCall::instruction_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 else
a61af66fc99e Initial load
duke
parents:
diff changeset
868 return _oop_limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 void virtual_call_Relocation::clear_inline_cache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // No stubs for ICs
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // Clean IC
a61af66fc99e Initial load
duke
parents:
diff changeset
876 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
877 CompiledIC* icache = CompiledIC_at(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
878 icache->set_to_clean();
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 void opt_virtual_call_Relocation::clear_inline_cache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // No stubs for ICs
a61af66fc99e Initial load
duke
parents:
diff changeset
884 // Clean IC
a61af66fc99e Initial load
duke
parents:
diff changeset
885 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
886 CompiledIC* icache = CompiledIC_at(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 icache->set_to_clean();
a61af66fc99e Initial load
duke
parents:
diff changeset
888 }
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 address opt_virtual_call_Relocation::static_stub() {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // search for the static stub who points back to this static call
a61af66fc99e Initial load
duke
parents:
diff changeset
893 address static_call_addr = addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
894 RelocIterator iter(code());
a61af66fc99e Initial load
duke
parents:
diff changeset
895 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 if (iter.type() == relocInfo::static_stub_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
897 if (iter.static_stub_reloc()->static_call() == static_call_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 return iter.addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 void static_call_Relocation::clear_inline_cache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // Safe call site info
a61af66fc99e Initial load
duke
parents:
diff changeset
908 CompiledStaticCall* handler = compiledStaticCall_at(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
909 handler->set_to_clean();
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 address static_call_Relocation::static_stub() {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // search for the static stub who points back to this static call
a61af66fc99e Initial load
duke
parents:
diff changeset
915 address static_call_addr = addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
916 RelocIterator iter(code());
a61af66fc99e Initial load
duke
parents:
diff changeset
917 while (iter.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 if (iter.type() == relocInfo::static_stub_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 if (iter.static_stub_reloc()->static_call() == static_call_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 return iter.addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 }
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 void static_stub_Relocation::clear_inline_cache() {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // Call stub is only used when calling the interpreted code.
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // It does not really need to be cleared, except that we want to clean out the methodoop.
a61af66fc99e Initial load
duke
parents:
diff changeset
931 CompiledStaticCall::set_stub_to_clean(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 address target = _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 if (target == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // An absolute embedded reference to an external location,
a61af66fc99e Initial load
duke
parents:
diff changeset
939 // which means there is nothing to fix here.
a61af66fc99e Initial load
duke
parents:
diff changeset
940 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // Probably this reference is absolute, not relative, so the
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // following is probably a no-op.
a61af66fc99e Initial load
duke
parents:
diff changeset
944 assert(src->section_index_of(target) == CodeBuffer::SECT_NONE, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
945 set_value(target);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948
a61af66fc99e Initial load
duke
parents:
diff changeset
949 address external_word_Relocation::target() {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 address target = _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 if (target == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
952 target = pd_get_address_from_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954 return target;
a61af66fc99e Initial load
duke
parents:
diff changeset
955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957
a61af66fc99e Initial load
duke
parents:
diff changeset
958 void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
959 address target = _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
960 if (target == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if (addr_in_const()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 target = new_addr_for(*(address*)addr(), src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 target = new_addr_for(pd_get_address_from_code(), src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967 set_value(target);
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 address internal_word_Relocation::target() {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 address target = _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
973 if (target == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 target = pd_get_address_from_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976 return target;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 breakpoint_Relocation::breakpoint_Relocation(int kind, address target, bool internal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 bool active = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 bool enabled = (kind == initialization);
a61af66fc99e Initial load
duke
parents:
diff changeset
983 bool removable = (kind != safepoint);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 bool settable = (target == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
985
a61af66fc99e Initial load
duke
parents:
diff changeset
986 int bits = kind;
a61af66fc99e Initial load
duke
parents:
diff changeset
987 if (enabled) bits |= enabled_state;
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (internal) bits |= internal_attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
989 if (removable) bits |= removable_attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 if (settable) bits |= settable_attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992 _bits = bits | high_bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 _target = target;
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 assert(this->kind() == kind, "kind encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
996 assert(this->enabled() == enabled, "enabled encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
997 assert(this->active() == active, "active encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
998 assert(this->internal() == internal, "internal encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
999 assert(this->removable() == removable, "removable encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 assert(this->settable() == settable, "settable encoded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 address breakpoint_Relocation::target() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 return _target;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 void breakpoint_Relocation::set_target(address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 assert(settable(), "must be settable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 jint target_bits =
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 (jint)(internal() ? scaled_offset (x, addr())
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 : runtime_address_to_index(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 short* p = &live_bits() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 p = add_jint(p, target_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 assert(p == instrs(), "new target must fit");
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 _target = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 void breakpoint_Relocation::set_enabled(bool b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 if (enabled() == b) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 if (b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 set_bits(bits() | enabled_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 set_active(false); // remove the actual breakpoint insn, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 set_bits(bits() & ~enabled_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 void breakpoint_Relocation::set_active(bool b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 assert(!b || enabled(), "cannot activate a disabled breakpoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if (active() == b) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // %%% should probably seize a lock here (might not be the right lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 //MutexLockerEx ml_patch(Patching_lock, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 //if (active() == b) return; // recheck state after locking
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 if (b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 set_bits(bits() | active_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 if (instrlen() == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 fatal("breakpoints in original code must be undoable");
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 pd_swap_in_breakpoint (addr(), instrs(), instrlen());
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 set_bits(bits() & ~active_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 pd_swap_out_breakpoint(addr(), instrs(), instrlen());
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 //---------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // Non-product code
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 static const char* reloc_type_string(relocInfo::relocType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 #define EACH_CASE(name) \
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 case relocInfo::name##_type: \
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 return #name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 APPLY_TO_RELOCATIONS(EACH_CASE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 #undef EACH_CASE
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 case relocInfo::none:
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 return "none";
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 case relocInfo::data_prefix_tag:
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return "prefix";
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 return "UNKNOWN RELOC TYPE";
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 void RelocIterator::print_current() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if (!has_current()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 tty->print_cr("(no relocs)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 if (current()->format() != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 tty->print(" format=%d", current()->format());
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 if (datalen() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 tty->print(" data=%d", data()[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 } else if (datalen() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 tty->print(" data={");
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 for (int i = 0; i < datalen(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 tty->print("%04x", data()[i] & 0xFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 tty->print("}");
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 tty->print("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 switch (type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 case relocInfo::oop_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 oop_Relocation* r = oop_reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 oop* oop_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 oop raw_oop = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 oop oop_value = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 if (code() != NULL || r->oop_is_immediate()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 oop_addr = r->oop_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 raw_oop = *oop_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 oop_value = r->oop_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 oop_addr, (address)raw_oop, r->offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // Do not print the oop by default--we want this routine to
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // work even during GC or other inconvenient times.
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 if (WizardMode && oop_value != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 oop_value->print_value_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 case relocInfo::external_word_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 case relocInfo::internal_word_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 case relocInfo::section_word_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 DataRelocation* r = (DataRelocation*) reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 tty->print(" | [target=" INTPTR_FORMAT "]", r->value()); //value==target
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 case relocInfo::static_call_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 case relocInfo::runtime_call_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 CallRelocation* r = (CallRelocation*) reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 tty->print(" | [destination=" INTPTR_FORMAT "]", r->destination());
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 case relocInfo::virtual_call_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 tty->print(" | [destination=" INTPTR_FORMAT " first_oop=" INTPTR_FORMAT " oop_limit=" INTPTR_FORMAT "]",
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 r->destination(), r->first_oop(), r->oop_limit());
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 case relocInfo::static_stub_type:
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 static_stub_Relocation* r = (static_stub_Relocation*) reloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call());
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
a61af66fc99e Initial load
duke
parents:
diff changeset
1151
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 void RelocIterator::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 RelocIterator save_this = (*this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 relocInfo* scan = _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (!has_current()) scan += 1; // nothing to scan here!
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 bool skip_next = has_current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 bool got_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 got_next = (skip_next || next());
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 skip_next = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 tty->print(" @" INTPTR_FORMAT ": ", scan);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 relocInfo* newscan = _current+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 if (!has_current()) newscan -= 1; // nothing to scan here!
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 while (scan < newscan) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 tty->print("%04x", *(short*)scan & 0xFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 scan++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1171
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 if (!got_next) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 print_current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1175
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 (*this) = save_this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // For the debugger:
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 extern "C"
1563
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
1181 void print_blob_locs(nmethod* nm) {
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
1182 nm->print();
1a5913bf5e19 6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents: 0
diff changeset
1183 RelocIterator iter(nm);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 iter.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 extern "C"
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 void print_buf_locs(CodeBuffer* cb) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 FlagSetting fs(PrintRelocations, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 cb->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 #endif // !PRODUCT