Mercurial > hg > truffle
annotate src/share/vm/asm/codeBuffer.hpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | b92c45f2bc75 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
diff
changeset
|
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1378
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:
1378
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_ASM_CODEBUFFER_HPP |
26 #define SHARE_VM_ASM_CODEBUFFER_HPP | |
27 | |
28 #include "asm/assembler.hpp" | |
29 #include "code/oopRecorder.hpp" | |
30 #include "code/relocInfo.hpp" | |
31 | |
0 | 32 class CodeComments; |
33 class AbstractAssembler; | |
34 class MacroAssembler; | |
35 class PhaseCFG; | |
36 class Compile; | |
37 class BufferBlob; | |
38 class CodeBuffer; | |
39 | |
40 class CodeOffsets: public StackObj { | |
41 public: | |
42 enum Entries { Entry, | |
43 Verified_Entry, | |
44 Frame_Complete, // Offset in the code where the frame setup is (for forte stackwalks) is complete | |
45 OSR_Entry, | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
46 Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it |
0 | 47 Exceptions, // Offset where exception handler lives |
48 Deopt, // Offset where deopt handler lives | |
1204 | 49 DeoptMH, // Offset where MethodHandle deopt handler lives |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
50 UnwindHandler, // Offset to default unwind handler |
0 | 51 max_Entries }; |
52 | |
53 // special value to note codeBlobs where profile (forte) stack walking is | |
54 // always dangerous and suspect. | |
55 | |
56 enum { frame_never_safe = -1 }; | |
57 | |
58 private: | |
59 int _values[max_Entries]; | |
60 | |
61 public: | |
62 CodeOffsets() { | |
1204 | 63 _values[Entry ] = 0; |
0 | 64 _values[Verified_Entry] = 0; |
65 _values[Frame_Complete] = frame_never_safe; | |
1204 | 66 _values[OSR_Entry ] = 0; |
67 _values[Exceptions ] = -1; | |
68 _values[Deopt ] = -1; | |
69 _values[DeoptMH ] = -1; | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
70 _values[UnwindHandler ] = -1; |
0 | 71 } |
72 | |
73 int value(Entries e) { return _values[e]; } | |
74 void set_value(Entries e, int val) { _values[e] = val; } | |
75 }; | |
76 | |
77 // This class represents a stream of code and associated relocations. | |
78 // There are a few in each CodeBuffer. | |
79 // They are filled concurrently, and concatenated at the end. | |
80 class CodeSection VALUE_OBJ_CLASS_SPEC { | |
81 friend class CodeBuffer; | |
82 public: | |
83 typedef int csize_t; // code size type; would be size_t except for history | |
84 | |
85 private: | |
86 address _start; // first byte of contents (instructions) | |
87 address _mark; // user mark, usually an instruction beginning | |
88 address _end; // current end address | |
89 address _limit; // last possible (allocated) end address | |
90 relocInfo* _locs_start; // first byte of relocation information | |
91 relocInfo* _locs_end; // first byte after relocation information | |
92 relocInfo* _locs_limit; // first byte after relocation information buf | |
93 address _locs_point; // last relocated position (grows upward) | |
94 bool _locs_own; // did I allocate the locs myself? | |
95 bool _frozen; // no more expansion of this section | |
96 char _index; // my section number (SECT_INST, etc.) | |
97 CodeBuffer* _outer; // enclosing CodeBuffer | |
98 | |
99 // (Note: _locs_point used to be called _last_reloc_offset.) | |
100 | |
101 CodeSection() { | |
102 _start = NULL; | |
103 _mark = NULL; | |
104 _end = NULL; | |
105 _limit = NULL; | |
106 _locs_start = NULL; | |
107 _locs_end = NULL; | |
108 _locs_limit = NULL; | |
109 _locs_point = NULL; | |
110 _locs_own = false; | |
111 _frozen = false; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
112 debug_only(_index = (char)-1); |
0 | 113 debug_only(_outer = (CodeBuffer*)badAddress); |
114 } | |
115 | |
116 void initialize_outer(CodeBuffer* outer, int index) { | |
117 _outer = outer; | |
118 _index = index; | |
119 } | |
120 | |
121 void initialize(address start, csize_t size = 0) { | |
122 assert(_start == NULL, "only one init step, please"); | |
123 _start = start; | |
124 _mark = NULL; | |
125 _end = start; | |
126 | |
127 _limit = start + size; | |
128 _locs_point = start; | |
129 } | |
130 | |
131 void initialize_locs(int locs_capacity); | |
132 void expand_locs(int new_capacity); | |
133 void initialize_locs_from(const CodeSection* source_cs); | |
134 | |
135 // helper for CodeBuffer::expand() | |
136 void take_over_code_from(CodeSection* cs) { | |
137 _start = cs->_start; | |
138 _mark = cs->_mark; | |
139 _end = cs->_end; | |
140 _limit = cs->_limit; | |
141 _locs_point = cs->_locs_point; | |
142 } | |
143 | |
144 public: | |
145 address start() const { return _start; } | |
146 address mark() const { return _mark; } | |
147 address end() const { return _end; } | |
148 address limit() const { return _limit; } | |
149 csize_t size() const { return (csize_t)(_end - _start); } | |
150 csize_t mark_off() const { assert(_mark != NULL, "not an offset"); | |
151 return (csize_t)(_mark - _start); } | |
152 csize_t capacity() const { return (csize_t)(_limit - _start); } | |
153 csize_t remaining() const { return (csize_t)(_limit - _end); } | |
154 | |
155 relocInfo* locs_start() const { return _locs_start; } | |
156 relocInfo* locs_end() const { return _locs_end; } | |
157 int locs_count() const { return (int)(_locs_end - _locs_start); } | |
158 relocInfo* locs_limit() const { return _locs_limit; } | |
159 address locs_point() const { return _locs_point; } | |
160 csize_t locs_point_off() const{ return (csize_t)(_locs_point - _start); } | |
161 csize_t locs_capacity() const { return (csize_t)(_locs_limit - _locs_start); } | |
162 csize_t locs_remaining()const { return (csize_t)(_locs_limit - _locs_end); } | |
163 | |
164 int index() const { return _index; } | |
165 bool is_allocated() const { return _start != NULL; } | |
166 bool is_empty() const { return _start == _end; } | |
167 bool is_frozen() const { return _frozen; } | |
168 bool has_locs() const { return _locs_end != NULL; } | |
169 | |
170 CodeBuffer* outer() const { return _outer; } | |
171 | |
172 // is a given address in this section? (2nd version is end-inclusive) | |
173 bool contains(address pc) const { return pc >= _start && pc < _end; } | |
174 bool contains2(address pc) const { return pc >= _start && pc <= _end; } | |
175 bool allocates(address pc) const { return pc >= _start && pc < _limit; } | |
176 bool allocates2(address pc) const { return pc >= _start && pc <= _limit; } | |
177 | |
1846 | 178 void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT, _start, pc, _limit)); _end = pc; } |
179 void set_mark(address pc) { assert(contains2(pc), "not in codeBuffer"); | |
0 | 180 _mark = pc; } |
181 void set_mark_off(int offset) { assert(contains2(offset+_start),"not in codeBuffer"); | |
182 _mark = offset + _start; } | |
183 void set_mark() { _mark = _end; } | |
184 void clear_mark() { _mark = NULL; } | |
185 | |
186 void set_locs_end(relocInfo* p) { | |
187 assert(p <= locs_limit(), "locs data fits in allocated buffer"); | |
188 _locs_end = p; | |
189 } | |
190 void set_locs_point(address pc) { | |
191 assert(pc >= locs_point(), "relocation addr may not decrease"); | |
192 assert(allocates2(pc), "relocation addr must be in this section"); | |
193 _locs_point = pc; | |
194 } | |
195 | |
1748 | 196 // Code emission |
197 void emit_int8 (int8_t x) { *((int8_t*) end()) = x; set_end(end() + 1); } | |
198 void emit_int16(int16_t x) { *((int16_t*) end()) = x; set_end(end() + 2); } | |
199 void emit_int32(int32_t x) { *((int32_t*) end()) = x; set_end(end() + 4); } | |
200 void emit_int64(int64_t x) { *((int64_t*) end()) = x; set_end(end() + 8); } | |
201 | |
0 | 202 // Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.) |
203 void initialize_shared_locs(relocInfo* buf, int length); | |
204 | |
205 // Manage labels and their addresses. | |
206 address target(Label& L, address branch_pc); | |
207 | |
208 // Emit a relocation. | |
209 void relocate(address at, RelocationHolder const& rspec, int format = 0); | |
210 void relocate(address at, relocInfo::relocType rtype, int format = 0) { | |
211 if (rtype != relocInfo::none) | |
212 relocate(at, Relocation::spec_simple(rtype), format); | |
213 } | |
214 | |
215 // alignment requirement for starting offset | |
216 // Requirements are that the instruction area and the | |
217 // stubs area must start on CodeEntryAlignment, and | |
218 // the ctable on sizeof(jdouble) | |
219 int alignment() const { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); } | |
220 | |
221 // Slop between sections, used only when allocating temporary BufferBlob buffers. | |
222 static csize_t end_slop() { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); } | |
223 | |
224 csize_t align_at_start(csize_t off) const { return (csize_t) align_size_up(off, alignment()); } | |
225 | |
226 // Mark a section frozen. Assign its remaining space to | |
227 // the following section. It will never expand after this point. | |
228 inline void freeze(); // { _outer->freeze_section(this); } | |
229 | |
230 // Ensure there's enough space left in the current section. | |
231 // Return true if there was an expansion. | |
232 bool maybe_expand_to_ensure_remaining(csize_t amount); | |
233 | |
234 #ifndef PRODUCT | |
235 void decode(); | |
236 void dump(); | |
237 void print(const char* name); | |
238 #endif //PRODUCT | |
239 }; | |
240 | |
241 class CodeComment; | |
242 class CodeComments VALUE_OBJ_CLASS_SPEC { | |
243 private: | |
244 #ifndef PRODUCT | |
245 CodeComment* _comments; | |
246 #endif | |
247 | |
248 public: | |
249 CodeComments() { | |
250 #ifndef PRODUCT | |
251 _comments = NULL; | |
252 #endif | |
253 } | |
254 | |
255 void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; | |
256 void print_block_comment(outputStream* stream, intptr_t offset) PRODUCT_RETURN; | |
257 void assign(CodeComments& other) PRODUCT_RETURN; | |
258 void free() PRODUCT_RETURN; | |
259 }; | |
260 | |
261 | |
262 // A CodeBuffer describes a memory space into which assembly | |
263 // code is generated. This memory space usually occupies the | |
264 // interior of a single BufferBlob, but in some cases it may be | |
265 // an arbitrary span of memory, even outside the code cache. | |
266 // | |
267 // A code buffer comes in two variants: | |
268 // | |
269 // (1) A CodeBuffer referring to an already allocated piece of memory: | |
270 // This is used to direct 'static' code generation (e.g. for interpreter | |
271 // or stubroutine generation, etc.). This code comes with NO relocation | |
272 // information. | |
273 // | |
274 // (2) A CodeBuffer referring to a piece of memory allocated when the | |
275 // CodeBuffer is allocated. This is used for nmethod generation. | |
276 // | |
277 // The memory can be divided up into several parts called sections. | |
278 // Each section independently accumulates code (or data) an relocations. | |
279 // Sections can grow (at the expense of a reallocation of the BufferBlob | |
280 // and recopying of all active sections). When the buffered code is finally | |
281 // written to an nmethod (or other CodeBlob), the contents (code, data, | |
282 // and relocations) of the sections are padded to an alignment and concatenated. | |
283 // Instructions and data in one section can contain relocatable references to | |
284 // addresses in a sibling section. | |
285 | |
286 class CodeBuffer: public StackObj { | |
287 friend class CodeSection; | |
288 | |
289 private: | |
290 // CodeBuffers must be allocated on the stack except for a single | |
291 // special case during expansion which is handled internally. This | |
292 // is done to guarantee proper cleanup of resources. | |
293 void* operator new(size_t size) { return ResourceObj::operator new(size); } | |
1685 | 294 void operator delete(void* p) { ShouldNotCallThis(); } |
0 | 295 |
296 public: | |
297 typedef int csize_t; // code size type; would be size_t except for history | |
298 enum { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
299 // Here is the list of all possible sections. The order reflects |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
300 // the final layout. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
301 SECT_FIRST = 0, |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
302 SECT_CONSTS = SECT_FIRST, // Non-instruction data: Floats, jump tables, etc. |
0 | 303 SECT_INSTS, // Executable instructions. |
304 SECT_STUBS, // Outbound trampolines for supporting call sites. | |
305 SECT_LIMIT, SECT_NONE = -1 | |
306 }; | |
307 | |
308 private: | |
309 enum { | |
310 sect_bits = 2, // assert (SECT_LIMIT <= (1<<sect_bits)) | |
311 sect_mask = (1<<sect_bits)-1 | |
312 }; | |
313 | |
314 const char* _name; | |
315 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
316 CodeSection _consts; // constants, jump tables |
0 | 317 CodeSection _insts; // instructions (the main section) |
318 CodeSection _stubs; // stubs (call site support), deopt, exception handling | |
319 | |
320 CodeBuffer* _before_expand; // dead buffer, from before the last expansion | |
321 | |
322 BufferBlob* _blob; // optional buffer in CodeCache for generated code | |
323 address _total_start; // first address of combined memory buffer | |
324 csize_t _total_size; // size in bytes of combined memory buffer | |
325 | |
326 OopRecorder* _oop_recorder; | |
327 CodeComments _comments; | |
328 OopRecorder _default_oop_recorder; // override with initialize_oop_recorder | |
329 Arena* _overflow_arena; | |
330 | |
331 address _decode_begin; // start address for decode | |
332 address decode_begin(); | |
333 | |
334 void initialize_misc(const char * name) { | |
335 // all pointers other than code_start/end and those inside the sections | |
336 assert(name != NULL, "must have a name"); | |
337 _name = name; | |
338 _before_expand = NULL; | |
339 _blob = NULL; | |
340 _oop_recorder = NULL; | |
341 _decode_begin = NULL; | |
342 _overflow_arena = NULL; | |
343 } | |
344 | |
345 void initialize(address code_start, csize_t code_size) { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
346 _consts.initialize_outer(this, SECT_CONSTS); |
0 | 347 _insts.initialize_outer(this, SECT_INSTS); |
348 _stubs.initialize_outer(this, SECT_STUBS); | |
349 _total_start = code_start; | |
350 _total_size = code_size; | |
351 // Initialize the main section: | |
352 _insts.initialize(code_start, code_size); | |
353 assert(!_stubs.is_allocated(), "no garbage here"); | |
354 assert(!_consts.is_allocated(), "no garbage here"); | |
355 _oop_recorder = &_default_oop_recorder; | |
356 } | |
357 | |
358 void initialize_section_size(CodeSection* cs, csize_t size); | |
359 | |
360 void freeze_section(CodeSection* cs); | |
361 | |
362 // helper for CodeBuffer::expand() | |
363 void take_over_code_from(CodeBuffer* cs); | |
364 | |
365 #ifdef ASSERT | |
366 // ensure sections are disjoint, ordered, and contained in the blob | |
367 bool verify_section_allocation(); | |
368 #endif | |
369 | |
370 // copies combined relocations to the blob, returns bytes copied | |
371 // (if target is null, it is a dry run only, just for sizing) | |
372 csize_t copy_relocations_to(CodeBlob* blob) const; | |
373 | |
374 // copies combined code to the blob (assumes relocs are already in there) | |
375 void copy_code_to(CodeBlob* blob); | |
376 | |
377 // moves code sections to new buffer (assumes relocs are already in there) | |
378 void relocate_code_to(CodeBuffer* cb) const; | |
379 | |
380 // set up a model of the final layout of my contents | |
381 void compute_final_layout(CodeBuffer* dest) const; | |
382 | |
383 // Expand the given section so at least 'amount' is remaining. | |
384 // Creates a new, larger BufferBlob, and rewrites the code & relocs. | |
385 void expand(CodeSection* which_cs, csize_t amount); | |
386 | |
387 // Helper for expand. | |
388 csize_t figure_expanded_capacities(CodeSection* which_cs, csize_t amount, csize_t* new_capacity); | |
389 | |
390 public: | |
391 // (1) code buffer referring to pre-allocated instruction memory | |
1748 | 392 CodeBuffer(address code_start, csize_t code_size) { |
393 assert(code_start != NULL, "sanity"); | |
394 initialize_misc("static buffer"); | |
395 initialize(code_start, code_size); | |
396 assert(verify_section_allocation(), "initial use of buffer OK"); | |
397 } | |
0 | 398 |
1748 | 399 // (2) CodeBuffer referring to pre-allocated CodeBlob. |
400 CodeBuffer(CodeBlob* blob); | |
401 | |
402 // (3) code buffer allocating codeBlob memory for code & relocation | |
0 | 403 // info but with lazy initialization. The name must be something |
404 // informative. | |
405 CodeBuffer(const char* name) { | |
406 initialize_misc(name); | |
407 } | |
408 | |
409 | |
1748 | 410 // (4) code buffer allocating codeBlob memory for code & relocation |
0 | 411 // info. The name must be something informative and code_size must |
412 // include both code and stubs sizes. | |
413 CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) { | |
414 initialize_misc(name); | |
415 initialize(code_size, locs_size); | |
416 } | |
417 | |
418 ~CodeBuffer(); | |
419 | |
1748 | 420 // Initialize a CodeBuffer constructed using constructor 3. Using |
421 // constructor 4 is equivalent to calling constructor 3 and then | |
0 | 422 // calling this method. It's been factored out for convenience of |
423 // construction. | |
424 void initialize(csize_t code_size, csize_t locs_size); | |
425 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
426 CodeSection* consts() { return &_consts; } |
0 | 427 CodeSection* insts() { return &_insts; } |
428 CodeSection* stubs() { return &_stubs; } | |
429 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
430 // present sections in order; return NULL at end; consts is #0, etc. |
0 | 431 CodeSection* code_section(int n) { |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
432 // This makes the slightly questionable but portable assumption |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
433 // that the various members (_consts, _insts, _stubs, etc.) are |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
434 // adjacent in the layout of CodeBuffer. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
435 CodeSection* cs = &_consts + n; |
0 | 436 assert(cs->index() == n || !cs->is_allocated(), "sanity"); |
437 return cs; | |
438 } | |
439 const CodeSection* code_section(int n) const { // yucky const stuff | |
440 return ((CodeBuffer*)this)->code_section(n); | |
441 } | |
442 static const char* code_section_name(int n); | |
443 int section_index_of(address addr) const; | |
444 bool contains(address addr) const { | |
445 // handy for debugging | |
446 return section_index_of(addr) > SECT_NONE; | |
447 } | |
448 | |
449 // A stable mapping between 'locators' (small ints) and addresses. | |
450 static int locator_pos(int locator) { return locator >> sect_bits; } | |
451 static int locator_sect(int locator) { return locator & sect_mask; } | |
452 static int locator(int pos, int sect) { return (pos << sect_bits) | sect; } | |
453 int locator(address addr) const; | |
454 address locator_address(int locator) const; | |
455 | |
456 // Properties | |
457 const char* name() const { return _name; } | |
458 CodeBuffer* before_expand() const { return _before_expand; } | |
459 BufferBlob* blob() const { return _blob; } | |
460 void set_blob(BufferBlob* blob); | |
461 void free_blob(); // Free the blob, if we own one. | |
462 | |
463 // Properties relative to the insts section: | |
1748 | 464 address insts_begin() const { return _insts.start(); } |
465 address insts_end() const { return _insts.end(); } | |
466 void set_insts_end(address end) { _insts.set_end(end); } | |
467 address insts_limit() const { return _insts.limit(); } | |
468 address insts_mark() const { return _insts.mark(); } | |
469 void set_insts_mark() { _insts.set_mark(); } | |
470 void clear_insts_mark() { _insts.clear_mark(); } | |
0 | 471 |
472 // is there anything in the buffer other than the current section? | |
1748 | 473 bool is_pure() const { return insts_size() == total_content_size(); } |
0 | 474 |
475 // size in bytes of output so far in the insts sections | |
1748 | 476 csize_t insts_size() const { return _insts.size(); } |
0 | 477 |
1748 | 478 // same as insts_size(), except that it asserts there is no non-code here |
479 csize_t pure_insts_size() const { assert(is_pure(), "no non-code"); | |
480 return insts_size(); } | |
0 | 481 // capacity in bytes of the insts sections |
1748 | 482 csize_t insts_capacity() const { return _insts.capacity(); } |
0 | 483 |
484 // number of bytes remaining in the insts section | |
1748 | 485 csize_t insts_remaining() const { return _insts.remaining(); } |
0 | 486 |
487 // is a given address in the insts section? (2nd version is end-inclusive) | |
1748 | 488 bool insts_contains(address pc) const { return _insts.contains(pc); } |
489 bool insts_contains2(address pc) const { return _insts.contains2(pc); } | |
0 | 490 |
1748 | 491 // Allocated size in all sections, when aligned and concatenated |
492 // (this is the eventual state of the content in its final | |
493 // CodeBlob). | |
494 csize_t total_content_size() const; | |
0 | 495 |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
496 // Combined offset (relative to start of first section) of given |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
497 // section, as eventually found in the final CodeBlob. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
498 csize_t total_offset_of(CodeSection* cs) const; |
0 | 499 |
500 // allocated size of all relocation data, including index, rounded up | |
501 csize_t total_relocation_size() const; | |
502 | |
503 // allocated size of any and all recorded oops | |
504 csize_t total_oop_size() const { | |
505 OopRecorder* recorder = oop_recorder(); | |
506 return (recorder == NULL)? 0: recorder->oop_size(); | |
507 } | |
508 | |
509 // Configuration functions, called immediately after the CB is constructed. | |
510 // The section sizes are subtracted from the original insts section. | |
511 // Note: Call them in reverse section order, because each steals from insts. | |
512 void initialize_consts_size(csize_t size) { initialize_section_size(&_consts, size); } | |
513 void initialize_stubs_size(csize_t size) { initialize_section_size(&_stubs, size); } | |
514 // Override default oop recorder. | |
515 void initialize_oop_recorder(OopRecorder* r); | |
516 | |
517 OopRecorder* oop_recorder() const { return _oop_recorder; } | |
518 CodeComments& comments() { return _comments; } | |
519 | |
520 // Code generation | |
521 void relocate(address at, RelocationHolder const& rspec, int format = 0) { | |
522 _insts.relocate(at, rspec, format); | |
523 } | |
524 void relocate(address at, relocInfo::relocType rtype, int format = 0) { | |
525 _insts.relocate(at, rtype, format); | |
526 } | |
527 | |
528 // Management of overflow storage for binding of Labels. | |
529 GrowableArray<int>* create_patch_overflow(); | |
530 | |
531 // NMethod generation | |
532 void copy_code_and_locs_to(CodeBlob* blob) { | |
533 assert(blob != NULL, "sane"); | |
534 copy_relocations_to(blob); | |
535 copy_code_to(blob); | |
536 } | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1378
diff
changeset
|
537 void copy_oops_to(nmethod* nm) { |
0 | 538 if (!oop_recorder()->is_unused()) { |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1378
diff
changeset
|
539 oop_recorder()->copy_to(nm); |
0 | 540 } |
541 } | |
542 | |
543 // Transform an address from the code in this code buffer to a specified code buffer | |
544 address transform_address(const CodeBuffer &cb, address addr) const; | |
545 | |
546 void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; | |
547 | |
548 #ifndef PRODUCT | |
549 public: | |
550 // Printing / Decoding | |
551 // decodes from decode_begin() to code_end() and sets decode_begin to end | |
552 void decode(); | |
553 void decode_all(); // decodes all the code | |
554 void skip_decode(); // sets decode_begin to code_end(); | |
555 void print(); | |
556 #endif | |
557 | |
558 | |
559 // The following header contains architecture-specific implementations | |
1972 | 560 #ifdef TARGET_ARCH_x86 |
561 # include "codeBuffer_x86.hpp" | |
562 #endif | |
563 #ifdef TARGET_ARCH_sparc | |
564 # include "codeBuffer_sparc.hpp" | |
565 #endif | |
566 #ifdef TARGET_ARCH_zero | |
567 # include "codeBuffer_zero.hpp" | |
568 #endif | |
569 | |
0 | 570 }; |
571 | |
572 | |
573 inline void CodeSection::freeze() { | |
574 _outer->freeze_section(this); | |
575 } | |
576 | |
577 inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) { | |
578 if (remaining() < amount) { _outer->expand(this, amount); return true; } | |
579 return false; | |
580 } | |
1972 | 581 |
582 #endif // SHARE_VM_ASM_CODEBUFFER_HPP |