Mercurial > hg > truffle
annotate src/share/vm/asm/codeBuffer.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 | 0e35fa8ebccd |
children | 3e8fbc61cee8 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
diff
changeset
|
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
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:
579
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_codeBuffer.cpp.incl" | |
27 | |
28 // The structure of a CodeSection: | |
29 // | |
30 // _start -> +----------------+ | |
31 // | machine code...| | |
32 // _end -> |----------------| | |
33 // | | | |
34 // | (empty) | | |
35 // | | | |
36 // | | | |
37 // +----------------+ | |
38 // _limit -> | | | |
39 // | |
40 // _locs_start -> +----------------+ | |
41 // |reloc records...| | |
42 // |----------------| | |
43 // _locs_end -> | | | |
44 // | | | |
45 // | (empty) | | |
46 // | | | |
47 // | | | |
48 // +----------------+ | |
49 // _locs_limit -> | | | |
50 // The _end (resp. _limit) pointer refers to the first | |
51 // unused (resp. unallocated) byte. | |
52 | |
53 // The structure of the CodeBuffer while code is being accumulated: | |
54 // | |
55 // _total_start -> \ | |
56 // _insts._start -> +----------------+ | |
57 // | | | |
58 // | Code | | |
59 // | | | |
60 // _stubs._start -> |----------------| | |
61 // | | | |
62 // | Stubs | (also handlers for deopt/exception) | |
63 // | | | |
64 // _consts._start -> |----------------| | |
65 // | | | |
66 // | Constants | | |
67 // | | | |
68 // +----------------+ | |
69 // + _total_size -> | | | |
70 // | |
71 // When the code and relocations are copied to the code cache, | |
72 // the empty parts of each section are removed, and everything | |
73 // is copied into contiguous locations. | |
74 | |
75 typedef CodeBuffer::csize_t csize_t; // file-local definition | |
76 | |
77 // external buffer, in a predefined CodeBlob or other buffer area | |
78 // Important: The code_start must be taken exactly, and not realigned. | |
79 CodeBuffer::CodeBuffer(address code_start, csize_t code_size) { | |
80 assert(code_start != NULL, "sanity"); | |
81 initialize_misc("static buffer"); | |
82 initialize(code_start, code_size); | |
83 assert(verify_section_allocation(), "initial use of buffer OK"); | |
84 } | |
85 | |
86 void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) { | |
87 // Compute maximal alignment. | |
88 int align = _insts.alignment(); | |
89 // Always allow for empty slop around each section. | |
90 int slop = (int) CodeSection::end_slop(); | |
91 | |
92 assert(blob() == NULL, "only once"); | |
93 set_blob(BufferBlob::create(_name, code_size + (align+slop) * (SECT_LIMIT+1))); | |
94 if (blob() == NULL) { | |
95 // The assembler constructor will throw a fatal on an empty CodeBuffer. | |
96 return; // caller must test this | |
97 } | |
98 | |
99 // Set up various pointers into the blob. | |
100 initialize(_total_start, _total_size); | |
101 | |
102 assert((uintptr_t)code_begin() % CodeEntryAlignment == 0, "instruction start not code entry aligned"); | |
103 | |
104 pd_initialize(); | |
105 | |
106 if (locs_size != 0) { | |
107 _insts.initialize_locs(locs_size / sizeof(relocInfo)); | |
108 } | |
109 | |
110 assert(verify_section_allocation(), "initial use of blob is OK"); | |
111 } | |
112 | |
113 | |
114 CodeBuffer::~CodeBuffer() { | |
115 // If we allocate our code buffer from the CodeCache | |
116 // via a BufferBlob, and it's not permanent, then | |
117 // free the BufferBlob. | |
118 // The rest of the memory will be freed when the ResourceObj | |
119 // is released. | |
120 assert(verify_section_allocation(), "final storage configuration still OK"); | |
121 for (CodeBuffer* cb = this; cb != NULL; cb = cb->before_expand()) { | |
122 // Previous incarnations of this buffer are held live, so that internal | |
123 // addresses constructed before expansions will not be confused. | |
124 cb->free_blob(); | |
125 } | |
561
5bfdb08ea692
6782260: Memory leak in CodeBuffer::create_patch_overflow
never
parents:
196
diff
changeset
|
126 |
5bfdb08ea692
6782260: Memory leak in CodeBuffer::create_patch_overflow
never
parents:
196
diff
changeset
|
127 // free any overflow storage |
5bfdb08ea692
6782260: Memory leak in CodeBuffer::create_patch_overflow
never
parents:
196
diff
changeset
|
128 delete _overflow_arena; |
5bfdb08ea692
6782260: Memory leak in CodeBuffer::create_patch_overflow
never
parents:
196
diff
changeset
|
129 |
0 | 130 #ifdef ASSERT |
1685 | 131 // Save allocation type to execute assert in ~ResourceObj() |
132 // which is called after this destructor. | |
133 ResourceObj::allocation_type at = _default_oop_recorder.get_allocation_type(); | |
0 | 134 Copy::fill_to_bytes(this, sizeof(*this), badResourceValue); |
1685 | 135 ResourceObj::set_allocation_type((address)(&_default_oop_recorder), at); |
0 | 136 #endif |
137 } | |
138 | |
139 void CodeBuffer::initialize_oop_recorder(OopRecorder* r) { | |
140 assert(_oop_recorder == &_default_oop_recorder && _default_oop_recorder.is_unused(), "do this once"); | |
141 DEBUG_ONLY(_default_oop_recorder.oop_size()); // force unused OR to be frozen | |
142 _oop_recorder = r; | |
143 } | |
144 | |
145 void CodeBuffer::initialize_section_size(CodeSection* cs, csize_t size) { | |
146 assert(cs != &_insts, "insts is the memory provider, not the consumer"); | |
147 #ifdef ASSERT | |
148 for (int n = (int)SECT_INSTS+1; n < (int)SECT_LIMIT; n++) { | |
149 CodeSection* prevCS = code_section(n); | |
150 if (prevCS == cs) break; | |
151 assert(!prevCS->is_allocated(), "section allocation must be in reverse order"); | |
152 } | |
153 #endif | |
154 csize_t slop = CodeSection::end_slop(); // margin between sections | |
155 int align = cs->alignment(); | |
156 assert(is_power_of_2(align), "sanity"); | |
157 address start = _insts._start; | |
158 address limit = _insts._limit; | |
159 address middle = limit - size; | |
160 middle -= (intptr_t)middle & (align-1); // align the division point downward | |
161 guarantee(middle - slop > start, "need enough space to divide up"); | |
162 _insts._limit = middle - slop; // subtract desired space, plus slop | |
163 cs->initialize(middle, limit - middle); | |
164 assert(cs->start() == middle, "sanity"); | |
165 assert(cs->limit() == limit, "sanity"); | |
166 // give it some relocations to start with, if the main section has them | |
167 if (_insts.has_locs()) cs->initialize_locs(1); | |
168 } | |
169 | |
170 void CodeBuffer::freeze_section(CodeSection* cs) { | |
171 CodeSection* next_cs = (cs == consts())? NULL: code_section(cs->index()+1); | |
172 csize_t frozen_size = cs->size(); | |
173 if (next_cs != NULL) { | |
174 frozen_size = next_cs->align_at_start(frozen_size); | |
175 } | |
176 address old_limit = cs->limit(); | |
177 address new_limit = cs->start() + frozen_size; | |
178 relocInfo* old_locs_limit = cs->locs_limit(); | |
179 relocInfo* new_locs_limit = cs->locs_end(); | |
180 // Patch the limits. | |
181 cs->_limit = new_limit; | |
182 cs->_locs_limit = new_locs_limit; | |
183 cs->_frozen = true; | |
184 if (!next_cs->is_allocated() && !next_cs->is_frozen()) { | |
185 // Give remaining buffer space to the following section. | |
186 next_cs->initialize(new_limit, old_limit - new_limit); | |
187 next_cs->initialize_shared_locs(new_locs_limit, | |
188 old_locs_limit - new_locs_limit); | |
189 } | |
190 } | |
191 | |
192 void CodeBuffer::set_blob(BufferBlob* blob) { | |
193 _blob = blob; | |
194 if (blob != NULL) { | |
195 address start = blob->instructions_begin(); | |
196 address end = blob->instructions_end(); | |
197 // Round up the starting address. | |
198 int align = _insts.alignment(); | |
199 start += (-(intptr_t)start) & (align-1); | |
200 _total_start = start; | |
201 _total_size = end - start; | |
202 } else { | |
203 #ifdef ASSERT | |
204 // Clean out dangling pointers. | |
205 _total_start = badAddress; | |
206 _insts._start = _insts._end = badAddress; | |
207 _stubs._start = _stubs._end = badAddress; | |
208 _consts._start = _consts._end = badAddress; | |
209 #endif //ASSERT | |
210 } | |
211 } | |
212 | |
213 void CodeBuffer::free_blob() { | |
214 if (_blob != NULL) { | |
215 BufferBlob::free(_blob); | |
216 set_blob(NULL); | |
217 } | |
218 } | |
219 | |
220 const char* CodeBuffer::code_section_name(int n) { | |
221 #ifdef PRODUCT | |
222 return NULL; | |
223 #else //PRODUCT | |
224 switch (n) { | |
225 case SECT_INSTS: return "insts"; | |
226 case SECT_STUBS: return "stubs"; | |
227 case SECT_CONSTS: return "consts"; | |
228 default: return NULL; | |
229 } | |
230 #endif //PRODUCT | |
231 } | |
232 | |
233 int CodeBuffer::section_index_of(address addr) const { | |
234 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
235 const CodeSection* cs = code_section(n); | |
236 if (cs->allocates(addr)) return n; | |
237 } | |
238 return SECT_NONE; | |
239 } | |
240 | |
241 int CodeBuffer::locator(address addr) const { | |
242 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
243 const CodeSection* cs = code_section(n); | |
244 if (cs->allocates(addr)) { | |
245 return locator(addr - cs->start(), n); | |
246 } | |
247 } | |
248 return -1; | |
249 } | |
250 | |
251 address CodeBuffer::locator_address(int locator) const { | |
252 if (locator < 0) return NULL; | |
253 address start = code_section(locator_sect(locator))->start(); | |
254 return start + locator_pos(locator); | |
255 } | |
256 | |
257 address CodeBuffer::decode_begin() { | |
258 address begin = _insts.start(); | |
259 if (_decode_begin != NULL && _decode_begin > begin) | |
260 begin = _decode_begin; | |
261 return begin; | |
262 } | |
263 | |
264 | |
265 GrowableArray<int>* CodeBuffer::create_patch_overflow() { | |
266 if (_overflow_arena == NULL) { | |
267 _overflow_arena = new Arena(); | |
268 } | |
269 return new (_overflow_arena) GrowableArray<int>(_overflow_arena, 8, 0, 0); | |
270 } | |
271 | |
272 | |
273 // Helper function for managing labels and their target addresses. | |
274 // Returns a sensible address, and if it is not the label's final | |
275 // address, notes the dependency (at 'branch_pc') on the label. | |
276 address CodeSection::target(Label& L, address branch_pc) { | |
277 if (L.is_bound()) { | |
278 int loc = L.loc(); | |
279 if (index() == CodeBuffer::locator_sect(loc)) { | |
280 return start() + CodeBuffer::locator_pos(loc); | |
281 } else { | |
282 return outer()->locator_address(loc); | |
283 } | |
284 } else { | |
285 assert(allocates2(branch_pc), "sanity"); | |
286 address base = start(); | |
287 int patch_loc = CodeBuffer::locator(branch_pc - base, index()); | |
288 L.add_patch_at(outer(), patch_loc); | |
289 | |
290 // Need to return a pc, doesn't matter what it is since it will be | |
291 // replaced during resolution later. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
292 // Don't return NULL or badAddress, since branches shouldn't overflow. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
293 // Don't return base either because that could overflow displacements |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
294 // for shorter branches. It will get checked when bound. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
100
diff
changeset
|
295 return branch_pc; |
0 | 296 } |
297 } | |
298 | |
299 void CodeSection::relocate(address at, RelocationHolder const& spec, int format) { | |
300 Relocation* reloc = spec.reloc(); | |
301 relocInfo::relocType rtype = (relocInfo::relocType) reloc->type(); | |
302 if (rtype == relocInfo::none) return; | |
303 | |
304 // The assertion below has been adjusted, to also work for | |
305 // relocation for fixup. Sometimes we want to put relocation | |
306 // information for the next instruction, since it will be patched | |
307 // with a call. | |
308 assert(start() <= at && at <= end()+1, | |
309 "cannot relocate data outside code boundaries"); | |
310 | |
311 if (!has_locs()) { | |
312 // no space for relocation information provided => code cannot be | |
313 // relocated. Make sure that relocate is only called with rtypes | |
314 // that can be ignored for this kind of code. | |
315 assert(rtype == relocInfo::none || | |
316 rtype == relocInfo::runtime_call_type || | |
317 rtype == relocInfo::internal_word_type|| | |
318 rtype == relocInfo::section_word_type || | |
319 rtype == relocInfo::external_word_type, | |
320 "code needs relocation information"); | |
321 // leave behind an indication that we attempted a relocation | |
322 DEBUG_ONLY(_locs_start = _locs_limit = (relocInfo*)badAddress); | |
323 return; | |
324 } | |
325 | |
326 // Advance the point, noting the offset we'll have to record. | |
327 csize_t offset = at - locs_point(); | |
328 set_locs_point(at); | |
329 | |
330 // Test for a couple of overflow conditions; maybe expand the buffer. | |
331 relocInfo* end = locs_end(); | |
332 relocInfo* req = end + relocInfo::length_limit; | |
333 // Check for (potential) overflow | |
334 if (req >= locs_limit() || offset >= relocInfo::offset_limit()) { | |
335 req += (uint)offset / (uint)relocInfo::offset_limit(); | |
336 if (req >= locs_limit()) { | |
337 // Allocate or reallocate. | |
338 expand_locs(locs_count() + (req - end)); | |
339 // reload pointer | |
340 end = locs_end(); | |
341 } | |
342 } | |
343 | |
344 // If the offset is giant, emit filler relocs, of type 'none', but | |
345 // each carrying the largest possible offset, to advance the locs_point. | |
346 while (offset >= relocInfo::offset_limit()) { | |
347 assert(end < locs_limit(), "adjust previous paragraph of code"); | |
348 *end++ = filler_relocInfo(); | |
349 offset -= filler_relocInfo().addr_offset(); | |
350 } | |
351 | |
352 // If it's a simple reloc with no data, we'll just write (rtype | offset). | |
353 (*end) = relocInfo(rtype, offset, format); | |
354 | |
355 // If it has data, insert the prefix, as (data_prefix_tag | data1), data2. | |
356 end->initialize(this, reloc); | |
357 } | |
358 | |
359 void CodeSection::initialize_locs(int locs_capacity) { | |
360 assert(_locs_start == NULL, "only one locs init step, please"); | |
361 // Apply a priori lower limits to relocation size: | |
362 csize_t min_locs = MAX2(size() / 16, (csize_t)4); | |
363 if (locs_capacity < min_locs) locs_capacity = min_locs; | |
364 relocInfo* locs_start = NEW_RESOURCE_ARRAY(relocInfo, locs_capacity); | |
365 _locs_start = locs_start; | |
366 _locs_end = locs_start; | |
367 _locs_limit = locs_start + locs_capacity; | |
368 _locs_own = true; | |
369 } | |
370 | |
371 void CodeSection::initialize_shared_locs(relocInfo* buf, int length) { | |
372 assert(_locs_start == NULL, "do this before locs are allocated"); | |
373 // Internal invariant: locs buf must be fully aligned. | |
374 // See copy_relocations_to() below. | |
375 while ((uintptr_t)buf % HeapWordSize != 0 && length > 0) { | |
376 ++buf; --length; | |
377 } | |
378 if (length > 0) { | |
379 _locs_start = buf; | |
380 _locs_end = buf; | |
381 _locs_limit = buf + length; | |
382 _locs_own = false; | |
383 } | |
384 } | |
385 | |
386 void CodeSection::initialize_locs_from(const CodeSection* source_cs) { | |
387 int lcount = source_cs->locs_count(); | |
388 if (lcount != 0) { | |
389 initialize_shared_locs(source_cs->locs_start(), lcount); | |
390 _locs_end = _locs_limit = _locs_start + lcount; | |
391 assert(is_allocated(), "must have copied code already"); | |
392 set_locs_point(start() + source_cs->locs_point_off()); | |
393 } | |
394 assert(this->locs_count() == source_cs->locs_count(), "sanity"); | |
395 } | |
396 | |
397 void CodeSection::expand_locs(int new_capacity) { | |
398 if (_locs_start == NULL) { | |
399 initialize_locs(new_capacity); | |
400 return; | |
401 } else { | |
402 int old_count = locs_count(); | |
403 int old_capacity = locs_capacity(); | |
404 if (new_capacity < old_capacity * 2) | |
405 new_capacity = old_capacity * 2; | |
406 relocInfo* locs_start; | |
407 if (_locs_own) { | |
408 locs_start = REALLOC_RESOURCE_ARRAY(relocInfo, _locs_start, old_capacity, new_capacity); | |
409 } else { | |
410 locs_start = NEW_RESOURCE_ARRAY(relocInfo, new_capacity); | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
411 Copy::conjoint_jbytes(_locs_start, locs_start, old_capacity * sizeof(relocInfo)); |
0 | 412 _locs_own = true; |
413 } | |
414 _locs_start = locs_start; | |
415 _locs_end = locs_start + old_count; | |
416 _locs_limit = locs_start + new_capacity; | |
417 } | |
418 } | |
419 | |
420 | |
421 /// Support for emitting the code to its final location. | |
422 /// The pattern is the same for all functions. | |
423 /// We iterate over all the sections, padding each to alignment. | |
424 | |
425 csize_t CodeBuffer::total_code_size() const { | |
426 csize_t code_size_so_far = 0; | |
427 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
428 const CodeSection* cs = code_section(n); | |
429 if (cs->is_empty()) continue; // skip trivial section | |
430 code_size_so_far = cs->align_at_start(code_size_so_far); | |
431 code_size_so_far += cs->size(); | |
432 } | |
433 return code_size_so_far; | |
434 } | |
435 | |
436 void CodeBuffer::compute_final_layout(CodeBuffer* dest) const { | |
437 address buf = dest->_total_start; | |
438 csize_t buf_offset = 0; | |
439 assert(dest->_total_size >= total_code_size(), "must be big enough"); | |
440 | |
441 { | |
442 // not sure why this is here, but why not... | |
443 int alignSize = MAX2((intx) sizeof(jdouble), CodeEntryAlignment); | |
444 assert( (dest->_total_start - _insts.start()) % alignSize == 0, "copy must preserve alignment"); | |
445 } | |
446 | |
447 const CodeSection* prev_cs = NULL; | |
448 CodeSection* prev_dest_cs = NULL; | |
449 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
450 // figure compact layout of each section | |
451 const CodeSection* cs = code_section(n); | |
452 address cstart = cs->start(); | |
453 address cend = cs->end(); | |
454 csize_t csize = cend - cstart; | |
455 | |
456 CodeSection* dest_cs = dest->code_section(n); | |
457 if (!cs->is_empty()) { | |
458 // Compute initial padding; assign it to the previous non-empty guy. | |
459 // Cf. figure_expanded_capacities. | |
460 csize_t padding = cs->align_at_start(buf_offset) - buf_offset; | |
461 if (padding != 0) { | |
462 buf_offset += padding; | |
463 assert(prev_dest_cs != NULL, "sanity"); | |
464 prev_dest_cs->_limit += padding; | |
465 } | |
466 #ifdef ASSERT | |
467 if (prev_cs != NULL && prev_cs->is_frozen() && n < SECT_CONSTS) { | |
468 // Make sure the ends still match up. | |
469 // This is important because a branch in a frozen section | |
470 // might target code in a following section, via a Label, | |
471 // and without a relocation record. See Label::patch_instructions. | |
472 address dest_start = buf+buf_offset; | |
473 csize_t start2start = cs->start() - prev_cs->start(); | |
474 csize_t dest_start2start = dest_start - prev_dest_cs->start(); | |
475 assert(start2start == dest_start2start, "cannot stretch frozen sect"); | |
476 } | |
477 #endif //ASSERT | |
478 prev_dest_cs = dest_cs; | |
479 prev_cs = cs; | |
480 } | |
481 | |
482 debug_only(dest_cs->_start = NULL); // defeat double-initialization assert | |
483 dest_cs->initialize(buf+buf_offset, csize); | |
484 dest_cs->set_end(buf+buf_offset+csize); | |
485 assert(dest_cs->is_allocated(), "must always be allocated"); | |
486 assert(cs->is_empty() == dest_cs->is_empty(), "sanity"); | |
487 | |
488 buf_offset += csize; | |
489 } | |
490 | |
491 // Done calculating sections; did it come out to the right end? | |
492 assert(buf_offset == total_code_size(), "sanity"); | |
493 assert(dest->verify_section_allocation(), "final configuration works"); | |
494 } | |
495 | |
496 csize_t CodeBuffer::total_offset_of(address addr) const { | |
497 csize_t code_size_so_far = 0; | |
498 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
499 const CodeSection* cs = code_section(n); | |
500 if (!cs->is_empty()) { | |
501 code_size_so_far = cs->align_at_start(code_size_so_far); | |
502 } | |
503 if (cs->contains2(addr)) { | |
504 return code_size_so_far + (addr - cs->start()); | |
505 } | |
506 code_size_so_far += cs->size(); | |
507 } | |
508 #ifndef PRODUCT | |
509 tty->print_cr("Dangling address " PTR_FORMAT " in:", addr); | |
510 ((CodeBuffer*)this)->print(); | |
511 #endif | |
512 ShouldNotReachHere(); | |
513 return -1; | |
514 } | |
515 | |
516 csize_t CodeBuffer::total_relocation_size() const { | |
517 csize_t lsize = copy_relocations_to(NULL); // dry run only | |
518 csize_t csize = total_code_size(); | |
519 csize_t total = RelocIterator::locs_and_index_size(csize, lsize); | |
520 return (csize_t) align_size_up(total, HeapWordSize); | |
521 } | |
522 | |
523 csize_t CodeBuffer::copy_relocations_to(CodeBlob* dest) const { | |
524 address buf = NULL; | |
525 csize_t buf_offset = 0; | |
526 csize_t buf_limit = 0; | |
527 if (dest != NULL) { | |
528 buf = (address)dest->relocation_begin(); | |
529 buf_limit = (address)dest->relocation_end() - buf; | |
530 assert((uintptr_t)buf % HeapWordSize == 0, "buf must be fully aligned"); | |
531 assert(buf_limit % HeapWordSize == 0, "buf must be evenly sized"); | |
532 } | |
533 // if dest == NULL, this is just the sizing pass | |
534 | |
535 csize_t code_end_so_far = 0; | |
536 csize_t code_point_so_far = 0; | |
537 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
538 // pull relocs out of each section | |
539 const CodeSection* cs = code_section(n); | |
540 assert(!(cs->is_empty() && cs->locs_count() > 0), "sanity"); | |
541 if (cs->is_empty()) continue; // skip trivial section | |
542 relocInfo* lstart = cs->locs_start(); | |
543 relocInfo* lend = cs->locs_end(); | |
544 csize_t lsize = (csize_t)( (address)lend - (address)lstart ); | |
545 csize_t csize = cs->size(); | |
546 code_end_so_far = cs->align_at_start(code_end_so_far); | |
547 | |
548 if (lsize > 0) { | |
549 // Figure out how to advance the combined relocation point | |
550 // first to the beginning of this section. | |
551 // We'll insert one or more filler relocs to span that gap. | |
552 // (Don't bother to improve this by editing the first reloc's offset.) | |
553 csize_t new_code_point = code_end_so_far; | |
554 for (csize_t jump; | |
555 code_point_so_far < new_code_point; | |
556 code_point_so_far += jump) { | |
557 jump = new_code_point - code_point_so_far; | |
558 relocInfo filler = filler_relocInfo(); | |
559 if (jump >= filler.addr_offset()) { | |
560 jump = filler.addr_offset(); | |
561 } else { // else shrink the filler to fit | |
562 filler = relocInfo(relocInfo::none, jump); | |
563 } | |
564 if (buf != NULL) { | |
565 assert(buf_offset + (csize_t)sizeof(filler) <= buf_limit, "filler in bounds"); | |
566 *(relocInfo*)(buf+buf_offset) = filler; | |
567 } | |
568 buf_offset += sizeof(filler); | |
569 } | |
570 | |
571 // Update code point and end to skip past this section: | |
572 csize_t last_code_point = code_end_so_far + cs->locs_point_off(); | |
573 assert(code_point_so_far <= last_code_point, "sanity"); | |
574 code_point_so_far = last_code_point; // advance past this guy's relocs | |
575 } | |
576 code_end_so_far += csize; // advance past this guy's instructions too | |
577 | |
578 // Done with filler; emit the real relocations: | |
579 if (buf != NULL && lsize != 0) { | |
580 assert(buf_offset + lsize <= buf_limit, "target in bounds"); | |
581 assert((uintptr_t)lstart % HeapWordSize == 0, "sane start"); | |
582 if (buf_offset % HeapWordSize == 0) { | |
583 // Use wordwise copies if possible: | |
584 Copy::disjoint_words((HeapWord*)lstart, | |
585 (HeapWord*)(buf+buf_offset), | |
586 (lsize + HeapWordSize-1) / HeapWordSize); | |
587 } else { | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
588 Copy::conjoint_jbytes(lstart, buf+buf_offset, lsize); |
0 | 589 } |
590 } | |
591 buf_offset += lsize; | |
592 } | |
593 | |
594 // Align end of relocation info in target. | |
595 while (buf_offset % HeapWordSize != 0) { | |
596 if (buf != NULL) { | |
597 relocInfo padding = relocInfo(relocInfo::none, 0); | |
598 assert(buf_offset + (csize_t)sizeof(padding) <= buf_limit, "padding in bounds"); | |
599 *(relocInfo*)(buf+buf_offset) = padding; | |
600 } | |
601 buf_offset += sizeof(relocInfo); | |
602 } | |
603 | |
604 assert(code_end_so_far == total_code_size(), "sanity"); | |
605 | |
606 // Account for index: | |
607 if (buf != NULL) { | |
608 RelocIterator::create_index(dest->relocation_begin(), | |
609 buf_offset / sizeof(relocInfo), | |
610 dest->relocation_end()); | |
611 } | |
612 | |
613 return buf_offset; | |
614 } | |
615 | |
616 void CodeBuffer::copy_code_to(CodeBlob* dest_blob) { | |
617 #ifndef PRODUCT | |
618 if (PrintNMethods && (WizardMode || Verbose)) { | |
619 tty->print("done with CodeBuffer:"); | |
620 ((CodeBuffer*)this)->print(); | |
621 } | |
622 #endif //PRODUCT | |
623 | |
624 CodeBuffer dest(dest_blob->instructions_begin(), | |
625 dest_blob->instructions_size()); | |
626 assert(dest_blob->instructions_size() >= total_code_size(), "good sizing"); | |
627 this->compute_final_layout(&dest); | |
628 relocate_code_to(&dest); | |
629 | |
630 // transfer comments from buffer to blob | |
631 dest_blob->set_comments(_comments); | |
632 | |
633 // Done moving code bytes; were they the right size? | |
634 assert(round_to(dest.total_code_size(), oopSize) == dest_blob->instructions_size(), "sanity"); | |
635 | |
636 // Flush generated code | |
637 ICache::invalidate_range(dest_blob->instructions_begin(), | |
638 dest_blob->instructions_size()); | |
639 } | |
640 | |
641 // Move all my code into another code buffer. | |
642 // Consult applicable relocs to repair embedded addresses. | |
643 void CodeBuffer::relocate_code_to(CodeBuffer* dest) const { | |
644 DEBUG_ONLY(address dest_end = dest->_total_start + dest->_total_size); | |
645 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
646 // pull code out of each section | |
647 const CodeSection* cs = code_section(n); | |
648 if (cs->is_empty()) continue; // skip trivial section | |
649 CodeSection* dest_cs = dest->code_section(n); | |
650 assert(cs->size() == dest_cs->size(), "sanity"); | |
651 csize_t usize = dest_cs->size(); | |
652 csize_t wsize = align_size_up(usize, HeapWordSize); | |
653 assert(dest_cs->start() + wsize <= dest_end, "no overflow"); | |
654 // Copy the code as aligned machine words. | |
655 // This may also include an uninitialized partial word at the end. | |
656 Copy::disjoint_words((HeapWord*)cs->start(), | |
657 (HeapWord*)dest_cs->start(), | |
658 wsize / HeapWordSize); | |
659 | |
660 if (dest->blob() == NULL) { | |
661 // Destination is a final resting place, not just another buffer. | |
662 // Normalize uninitialized bytes in the final padding. | |
663 Copy::fill_to_bytes(dest_cs->end(), dest_cs->remaining(), | |
664 Assembler::code_fill_byte()); | |
665 } | |
666 | |
667 assert(cs->locs_start() != (relocInfo*)badAddress, | |
668 "this section carries no reloc storage, but reloc was attempted"); | |
669 | |
670 // Make the new code copy use the old copy's relocations: | |
671 dest_cs->initialize_locs_from(cs); | |
672 | |
673 { // Repair the pc relative information in the code after the move | |
674 RelocIterator iter(dest_cs); | |
675 while (iter.next()) { | |
676 iter.reloc()->fix_relocation_after_move(this, dest); | |
677 } | |
678 } | |
679 } | |
680 } | |
681 | |
682 csize_t CodeBuffer::figure_expanded_capacities(CodeSection* which_cs, | |
683 csize_t amount, | |
684 csize_t* new_capacity) { | |
685 csize_t new_total_cap = 0; | |
686 | |
687 int prev_n = -1; | |
688 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
689 const CodeSection* sect = code_section(n); | |
690 | |
691 if (!sect->is_empty()) { | |
692 // Compute initial padding; assign it to the previous non-empty guy. | |
693 // Cf. compute_final_layout. | |
694 csize_t padding = sect->align_at_start(new_total_cap) - new_total_cap; | |
695 if (padding != 0) { | |
696 new_total_cap += padding; | |
697 assert(prev_n >= 0, "sanity"); | |
698 new_capacity[prev_n] += padding; | |
699 } | |
700 prev_n = n; | |
701 } | |
702 | |
703 csize_t exp = sect->size(); // 100% increase | |
704 if ((uint)exp < 4*K) exp = 4*K; // minimum initial increase | |
705 if (sect == which_cs) { | |
706 if (exp < amount) exp = amount; | |
707 if (StressCodeBuffers) exp = amount; // expand only slightly | |
708 } else if (n == SECT_INSTS) { | |
709 // scale down inst increases to a more modest 25% | |
710 exp = 4*K + ((exp - 4*K) >> 2); | |
711 if (StressCodeBuffers) exp = amount / 2; // expand only slightly | |
712 } else if (sect->is_empty()) { | |
713 // do not grow an empty secondary section | |
714 exp = 0; | |
715 } | |
716 // Allow for inter-section slop: | |
717 exp += CodeSection::end_slop(); | |
718 csize_t new_cap = sect->size() + exp; | |
719 if (new_cap < sect->capacity()) { | |
720 // No need to expand after all. | |
721 new_cap = sect->capacity(); | |
722 } | |
723 new_capacity[n] = new_cap; | |
724 new_total_cap += new_cap; | |
725 } | |
726 | |
727 return new_total_cap; | |
728 } | |
729 | |
730 void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) { | |
731 #ifndef PRODUCT | |
732 if (PrintNMethods && (WizardMode || Verbose)) { | |
733 tty->print("expanding CodeBuffer:"); | |
734 this->print(); | |
735 } | |
736 | |
737 if (StressCodeBuffers && blob() != NULL) { | |
738 static int expand_count = 0; | |
739 if (expand_count >= 0) expand_count += 1; | |
740 if (expand_count > 100 && is_power_of_2(expand_count)) { | |
741 tty->print_cr("StressCodeBuffers: have expanded %d times", expand_count); | |
742 // simulate an occasional allocation failure: | |
743 free_blob(); | |
744 } | |
745 } | |
746 #endif //PRODUCT | |
747 | |
748 // Resizing must be allowed | |
749 { | |
750 if (blob() == NULL) return; // caller must check for blob == NULL | |
751 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
752 guarantee(!code_section(n)->is_frozen(), "resizing not allowed when frozen"); | |
753 } | |
754 } | |
755 | |
756 // Figure new capacity for each section. | |
757 csize_t new_capacity[SECT_LIMIT]; | |
758 csize_t new_total_cap | |
759 = figure_expanded_capacities(which_cs, amount, new_capacity); | |
760 | |
761 // Create a new (temporary) code buffer to hold all the new data | |
762 CodeBuffer cb(name(), new_total_cap, 0); | |
763 if (cb.blob() == NULL) { | |
764 // Failed to allocate in code cache. | |
765 free_blob(); | |
766 return; | |
767 } | |
768 | |
769 // Create an old code buffer to remember which addresses used to go where. | |
770 // This will be useful when we do final assembly into the code cache, | |
771 // because we will need to know how to warp any internal address that | |
772 // has been created at any time in this CodeBuffer's past. | |
773 CodeBuffer* bxp = new CodeBuffer(_total_start, _total_size); | |
774 bxp->take_over_code_from(this); // remember the old undersized blob | |
775 DEBUG_ONLY(this->_blob = NULL); // silence a later assert | |
776 bxp->_before_expand = this->_before_expand; | |
777 this->_before_expand = bxp; | |
778 | |
779 // Give each section its required (expanded) capacity. | |
780 for (int n = (int)SECT_LIMIT-1; n >= SECT_INSTS; n--) { | |
781 CodeSection* cb_sect = cb.code_section(n); | |
782 CodeSection* this_sect = code_section(n); | |
783 if (new_capacity[n] == 0) continue; // already nulled out | |
784 if (n > SECT_INSTS) { | |
785 cb.initialize_section_size(cb_sect, new_capacity[n]); | |
786 } | |
787 assert(cb_sect->capacity() >= new_capacity[n], "big enough"); | |
788 address cb_start = cb_sect->start(); | |
789 cb_sect->set_end(cb_start + this_sect->size()); | |
790 if (this_sect->mark() == NULL) { | |
791 cb_sect->clear_mark(); | |
792 } else { | |
793 cb_sect->set_mark(cb_start + this_sect->mark_off()); | |
794 } | |
795 } | |
796 | |
797 // Move all the code and relocations to the new blob: | |
798 relocate_code_to(&cb); | |
799 | |
800 // Copy the temporary code buffer into the current code buffer. | |
801 // Basically, do {*this = cb}, except for some control information. | |
802 this->take_over_code_from(&cb); | |
803 cb.set_blob(NULL); | |
804 | |
805 // Zap the old code buffer contents, to avoid mistakenly using them. | |
806 debug_only(Copy::fill_to_bytes(bxp->_total_start, bxp->_total_size, | |
807 badCodeHeapFreeVal)); | |
808 | |
809 _decode_begin = NULL; // sanity | |
810 | |
811 // Make certain that the new sections are all snugly inside the new blob. | |
812 assert(verify_section_allocation(), "expanded allocation is ship-shape"); | |
813 | |
814 #ifndef PRODUCT | |
815 if (PrintNMethods && (WizardMode || Verbose)) { | |
816 tty->print("expanded CodeBuffer:"); | |
817 this->print(); | |
818 } | |
819 #endif //PRODUCT | |
820 } | |
821 | |
822 void CodeBuffer::take_over_code_from(CodeBuffer* cb) { | |
823 // Must already have disposed of the old blob somehow. | |
824 assert(blob() == NULL, "must be empty"); | |
825 #ifdef ASSERT | |
826 | |
827 #endif | |
828 // Take the new blob away from cb. | |
829 set_blob(cb->blob()); | |
830 // Take over all the section pointers. | |
831 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
832 CodeSection* cb_sect = cb->code_section(n); | |
833 CodeSection* this_sect = code_section(n); | |
834 this_sect->take_over_code_from(cb_sect); | |
835 } | |
836 _overflow_arena = cb->_overflow_arena; | |
837 // Make sure the old cb won't try to use it or free it. | |
838 DEBUG_ONLY(cb->_blob = (BufferBlob*)badAddress); | |
839 } | |
840 | |
841 #ifdef ASSERT | |
842 bool CodeBuffer::verify_section_allocation() { | |
843 address tstart = _total_start; | |
844 if (tstart == badAddress) return true; // smashed by set_blob(NULL) | |
845 address tend = tstart + _total_size; | |
846 if (_blob != NULL) { | |
847 assert(tstart >= _blob->instructions_begin(), "sanity"); | |
848 assert(tend <= _blob->instructions_end(), "sanity"); | |
849 } | |
850 address tcheck = tstart; // advancing pointer to verify disjointness | |
851 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
852 CodeSection* sect = code_section(n); | |
853 if (!sect->is_allocated()) continue; | |
854 assert(sect->start() >= tcheck, "sanity"); | |
855 tcheck = sect->start(); | |
856 assert((intptr_t)tcheck % sect->alignment() == 0 | |
857 || sect->is_empty() || _blob == NULL, | |
858 "start is aligned"); | |
859 assert(sect->end() >= tcheck, "sanity"); | |
860 assert(sect->end() <= tend, "sanity"); | |
861 } | |
862 return true; | |
863 } | |
864 #endif //ASSERT | |
865 | |
866 #ifndef PRODUCT | |
867 | |
868 void CodeSection::dump() { | |
869 address ptr = start(); | |
870 for (csize_t step; ptr < end(); ptr += step) { | |
871 step = end() - ptr; | |
872 if (step > jintSize * 4) step = jintSize * 4; | |
873 tty->print(PTR_FORMAT ": ", ptr); | |
874 while (step > 0) { | |
875 tty->print(" " PTR32_FORMAT, *(jint*)ptr); | |
876 ptr += jintSize; | |
877 } | |
878 tty->cr(); | |
879 } | |
880 } | |
881 | |
882 | |
883 void CodeSection::decode() { | |
884 Disassembler::decode(start(), end()); | |
885 } | |
886 | |
887 | |
888 void CodeBuffer::block_comment(intptr_t offset, const char * comment) { | |
889 _comments.add_comment(offset, comment); | |
890 } | |
891 | |
892 | |
893 class CodeComment: public CHeapObj { | |
894 private: | |
895 friend class CodeComments; | |
896 intptr_t _offset; | |
897 const char * _comment; | |
898 CodeComment* _next; | |
899 | |
900 ~CodeComment() { | |
901 assert(_next == NULL, "wrong interface for freeing list"); | |
902 os::free((void*)_comment); | |
903 } | |
904 | |
905 public: | |
906 CodeComment(intptr_t offset, const char * comment) { | |
907 _offset = offset; | |
908 _comment = os::strdup(comment); | |
909 _next = NULL; | |
910 } | |
911 | |
912 intptr_t offset() const { return _offset; } | |
913 const char * comment() const { return _comment; } | |
914 CodeComment* next() { return _next; } | |
915 | |
916 void set_next(CodeComment* next) { _next = next; } | |
917 | |
918 CodeComment* find(intptr_t offset) { | |
919 CodeComment* a = this; | |
920 while (a != NULL && a->_offset != offset) { | |
921 a = a->_next; | |
922 } | |
923 return a; | |
924 } | |
925 }; | |
926 | |
927 | |
928 void CodeComments::add_comment(intptr_t offset, const char * comment) { | |
929 CodeComment* c = new CodeComment(offset, comment); | |
930 CodeComment* insert = NULL; | |
931 if (_comments != NULL) { | |
932 CodeComment* c = _comments->find(offset); | |
933 insert = c; | |
934 while (c && c->offset() == offset) { | |
935 insert = c; | |
936 c = c->next(); | |
937 } | |
938 } | |
939 if (insert) { | |
940 // insert after comments with same offset | |
941 c->set_next(insert->next()); | |
942 insert->set_next(c); | |
943 } else { | |
944 c->set_next(_comments); | |
945 _comments = c; | |
946 } | |
947 } | |
948 | |
949 | |
950 void CodeComments::assign(CodeComments& other) { | |
951 assert(_comments == NULL, "don't overwrite old value"); | |
952 _comments = other._comments; | |
953 } | |
954 | |
955 | |
956 void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) { | |
957 if (_comments != NULL) { | |
958 CodeComment* c = _comments->find(offset); | |
959 while (c && c->offset() == offset) { | |
100
c7c777385a15
6667042: PrintAssembly option does not work without special plugin
jrose
parents:
0
diff
changeset
|
960 stream->bol(); |
0 | 961 stream->print(" ;; "); |
962 stream->print_cr(c->comment()); | |
963 c = c->next(); | |
964 } | |
965 } | |
966 } | |
967 | |
968 | |
969 void CodeComments::free() { | |
970 CodeComment* n = _comments; | |
971 while (n) { | |
972 // unlink the node from the list saving a pointer to the next | |
973 CodeComment* p = n->_next; | |
974 n->_next = NULL; | |
975 delete n; | |
976 n = p; | |
977 } | |
978 _comments = NULL; | |
979 } | |
980 | |
981 | |
982 | |
983 void CodeBuffer::decode() { | |
984 Disassembler::decode(decode_begin(), code_end()); | |
985 _decode_begin = code_end(); | |
986 } | |
987 | |
988 | |
989 void CodeBuffer::skip_decode() { | |
990 _decode_begin = code_end(); | |
991 } | |
992 | |
993 | |
994 void CodeBuffer::decode_all() { | |
995 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
996 // dump contents of each section | |
997 CodeSection* cs = code_section(n); | |
998 tty->print_cr("! %s:", code_section_name(n)); | |
999 if (cs != consts()) | |
1000 cs->decode(); | |
1001 else | |
1002 cs->dump(); | |
1003 } | |
1004 } | |
1005 | |
1006 | |
1007 void CodeSection::print(const char* name) { | |
1008 csize_t locs_size = locs_end() - locs_start(); | |
1009 tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)%s", | |
1010 name, start(), end(), limit(), size(), capacity(), | |
1011 is_frozen()? " [frozen]": ""); | |
1012 tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d", | |
1013 name, locs_start(), locs_end(), locs_limit(), locs_size, locs_capacity(), locs_point_off()); | |
1014 if (PrintRelocations) { | |
1015 RelocIterator iter(this); | |
1016 iter.print(); | |
1017 } | |
1018 } | |
1019 | |
1020 void CodeBuffer::print() { | |
1021 if (this == NULL) { | |
1022 tty->print_cr("NULL CodeBuffer pointer"); | |
1023 return; | |
1024 } | |
1025 | |
1026 tty->print_cr("CodeBuffer:"); | |
1027 for (int n = 0; n < (int)SECT_LIMIT; n++) { | |
1028 // print each section | |
1029 CodeSection* cs = code_section(n); | |
1030 cs->print(code_section_name(n)); | |
1031 } | |
1032 } | |
1033 | |
1034 #endif // PRODUCT |