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