Mercurial > hg > truffle
annotate src/share/vm/asm/codeBuffer.hpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | 44ce519bc3d1 |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2192
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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 // ensure sections are disjoint, ordered, and contained in the blob | |
4059
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
366 void verify_section_allocation(); |
0 | 367 |
368 // copies combined relocations to the blob, returns bytes copied | |
369 // (if target is null, it is a dry run only, just for sizing) | |
370 csize_t copy_relocations_to(CodeBlob* blob) const; | |
371 | |
372 // copies combined code to the blob (assumes relocs are already in there) | |
373 void copy_code_to(CodeBlob* blob); | |
374 | |
375 // moves code sections to new buffer (assumes relocs are already in there) | |
376 void relocate_code_to(CodeBuffer* cb) const; | |
377 | |
378 // set up a model of the final layout of my contents | |
379 void compute_final_layout(CodeBuffer* dest) const; | |
380 | |
381 // Expand the given section so at least 'amount' is remaining. | |
382 // Creates a new, larger BufferBlob, and rewrites the code & relocs. | |
383 void expand(CodeSection* which_cs, csize_t amount); | |
384 | |
385 // Helper for expand. | |
386 csize_t figure_expanded_capacities(CodeSection* which_cs, csize_t amount, csize_t* new_capacity); | |
387 | |
388 public: | |
389 // (1) code buffer referring to pre-allocated instruction memory | |
1748 | 390 CodeBuffer(address code_start, csize_t code_size) { |
391 assert(code_start != NULL, "sanity"); | |
392 initialize_misc("static buffer"); | |
393 initialize(code_start, code_size); | |
4059
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
394 verify_section_allocation(); |
1748 | 395 } |
0 | 396 |
1748 | 397 // (2) CodeBuffer referring to pre-allocated CodeBlob. |
398 CodeBuffer(CodeBlob* blob); | |
399 | |
400 // (3) code buffer allocating codeBlob memory for code & relocation | |
0 | 401 // info but with lazy initialization. The name must be something |
402 // informative. | |
403 CodeBuffer(const char* name) { | |
404 initialize_misc(name); | |
405 } | |
406 | |
407 | |
1748 | 408 // (4) code buffer allocating codeBlob memory for code & relocation |
0 | 409 // info. The name must be something informative and code_size must |
410 // include both code and stubs sizes. | |
411 CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) { | |
412 initialize_misc(name); | |
413 initialize(code_size, locs_size); | |
414 } | |
415 | |
416 ~CodeBuffer(); | |
417 | |
1748 | 418 // Initialize a CodeBuffer constructed using constructor 3. Using |
419 // constructor 4 is equivalent to calling constructor 3 and then | |
0 | 420 // calling this method. It's been factored out for convenience of |
421 // construction. | |
422 void initialize(csize_t code_size, csize_t locs_size); | |
423 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
424 CodeSection* consts() { return &_consts; } |
0 | 425 CodeSection* insts() { return &_insts; } |
426 CodeSection* stubs() { return &_stubs; } | |
427 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
428 // present sections in order; return NULL at end; consts is #0, etc. |
0 | 429 CodeSection* code_section(int n) { |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
430 // This makes the slightly questionable but portable assumption |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
431 // that the various members (_consts, _insts, _stubs, etc.) are |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
432 // adjacent in the layout of CodeBuffer. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
433 CodeSection* cs = &_consts + n; |
0 | 434 assert(cs->index() == n || !cs->is_allocated(), "sanity"); |
435 return cs; | |
436 } | |
437 const CodeSection* code_section(int n) const { // yucky const stuff | |
438 return ((CodeBuffer*)this)->code_section(n); | |
439 } | |
440 static const char* code_section_name(int n); | |
441 int section_index_of(address addr) const; | |
442 bool contains(address addr) const { | |
443 // handy for debugging | |
444 return section_index_of(addr) > SECT_NONE; | |
445 } | |
446 | |
447 // A stable mapping between 'locators' (small ints) and addresses. | |
448 static int locator_pos(int locator) { return locator >> sect_bits; } | |
449 static int locator_sect(int locator) { return locator & sect_mask; } | |
450 static int locator(int pos, int sect) { return (pos << sect_bits) | sect; } | |
451 int locator(address addr) const; | |
452 address locator_address(int locator) const; | |
453 | |
454 // Properties | |
455 const char* name() const { return _name; } | |
456 CodeBuffer* before_expand() const { return _before_expand; } | |
457 BufferBlob* blob() const { return _blob; } | |
458 void set_blob(BufferBlob* blob); | |
459 void free_blob(); // Free the blob, if we own one. | |
460 | |
461 // Properties relative to the insts section: | |
1748 | 462 address insts_begin() const { return _insts.start(); } |
463 address insts_end() const { return _insts.end(); } | |
464 void set_insts_end(address end) { _insts.set_end(end); } | |
465 address insts_limit() const { return _insts.limit(); } | |
466 address insts_mark() const { return _insts.mark(); } | |
467 void set_insts_mark() { _insts.set_mark(); } | |
468 void clear_insts_mark() { _insts.clear_mark(); } | |
0 | 469 |
470 // is there anything in the buffer other than the current section? | |
1748 | 471 bool is_pure() const { return insts_size() == total_content_size(); } |
0 | 472 |
473 // size in bytes of output so far in the insts sections | |
1748 | 474 csize_t insts_size() const { return _insts.size(); } |
0 | 475 |
1748 | 476 // same as insts_size(), except that it asserts there is no non-code here |
477 csize_t pure_insts_size() const { assert(is_pure(), "no non-code"); | |
478 return insts_size(); } | |
0 | 479 // capacity in bytes of the insts sections |
1748 | 480 csize_t insts_capacity() const { return _insts.capacity(); } |
0 | 481 |
482 // number of bytes remaining in the insts section | |
1748 | 483 csize_t insts_remaining() const { return _insts.remaining(); } |
0 | 484 |
485 // is a given address in the insts section? (2nd version is end-inclusive) | |
1748 | 486 bool insts_contains(address pc) const { return _insts.contains(pc); } |
487 bool insts_contains2(address pc) const { return _insts.contains2(pc); } | |
0 | 488 |
1748 | 489 // Allocated size in all sections, when aligned and concatenated |
490 // (this is the eventual state of the content in its final | |
491 // CodeBlob). | |
492 csize_t total_content_size() const; | |
0 | 493 |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
494 // Combined offset (relative to start of first section) of given |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
495 // section, as eventually found in the final CodeBlob. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
496 csize_t total_offset_of(CodeSection* cs) const; |
0 | 497 |
498 // allocated size of all relocation data, including index, rounded up | |
499 csize_t total_relocation_size() const; | |
500 | |
501 // allocated size of any and all recorded oops | |
502 csize_t total_oop_size() const { | |
503 OopRecorder* recorder = oop_recorder(); | |
504 return (recorder == NULL)? 0: recorder->oop_size(); | |
505 } | |
506 | |
507 // Configuration functions, called immediately after the CB is constructed. | |
508 // The section sizes are subtracted from the original insts section. | |
509 // Note: Call them in reverse section order, because each steals from insts. | |
510 void initialize_consts_size(csize_t size) { initialize_section_size(&_consts, size); } | |
511 void initialize_stubs_size(csize_t size) { initialize_section_size(&_stubs, size); } | |
512 // Override default oop recorder. | |
513 void initialize_oop_recorder(OopRecorder* r); | |
514 | |
515 OopRecorder* oop_recorder() const { return _oop_recorder; } | |
516 CodeComments& comments() { return _comments; } | |
517 | |
518 // Code generation | |
519 void relocate(address at, RelocationHolder const& rspec, int format = 0) { | |
520 _insts.relocate(at, rspec, format); | |
521 } | |
522 void relocate(address at, relocInfo::relocType rtype, int format = 0) { | |
523 _insts.relocate(at, rtype, format); | |
524 } | |
525 | |
526 // Management of overflow storage for binding of Labels. | |
527 GrowableArray<int>* create_patch_overflow(); | |
528 | |
529 // NMethod generation | |
530 void copy_code_and_locs_to(CodeBlob* blob) { | |
531 assert(blob != NULL, "sane"); | |
532 copy_relocations_to(blob); | |
533 copy_code_to(blob); | |
534 } | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1378
diff
changeset
|
535 void copy_oops_to(nmethod* nm) { |
0 | 536 if (!oop_recorder()->is_unused()) { |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1378
diff
changeset
|
537 oop_recorder()->copy_to(nm); |
0 | 538 } |
539 } | |
540 | |
541 // Transform an address from the code in this code buffer to a specified code buffer | |
542 address transform_address(const CodeBuffer &cb, address addr) const; | |
543 | |
544 void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; | |
545 | |
4059
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
546 // Log a little info about section usage in the CodeBuffer |
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
547 void log_section_sizes(const char* name); |
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
548 |
0 | 549 #ifndef PRODUCT |
550 public: | |
551 // Printing / Decoding | |
552 // decodes from decode_begin() to code_end() and sets decode_begin to end | |
553 void decode(); | |
554 void decode_all(); // decodes all the code | |
555 void skip_decode(); // sets decode_begin to code_end(); | |
556 void print(); | |
557 #endif | |
558 | |
559 | |
560 // The following header contains architecture-specific implementations | |
1972 | 561 #ifdef TARGET_ARCH_x86 |
562 # include "codeBuffer_x86.hpp" | |
563 #endif | |
564 #ifdef TARGET_ARCH_sparc | |
565 # include "codeBuffer_sparc.hpp" | |
566 #endif | |
567 #ifdef TARGET_ARCH_zero | |
568 # include "codeBuffer_zero.hpp" | |
569 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
570 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
571 # include "codeBuffer_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
572 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
573 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
574 # include "codeBuffer_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
575 #endif |
1972 | 576 |
0 | 577 }; |
578 | |
579 | |
580 inline void CodeSection::freeze() { | |
581 _outer->freeze_section(this); | |
582 } | |
583 | |
584 inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) { | |
585 if (remaining() < amount) { _outer->expand(this, amount); return true; } | |
586 return false; | |
587 } | |
1972 | 588 |
589 #endif // SHARE_VM_ASM_CODEBUFFER_HPP |