Mercurial > hg > truffle
annotate src/share/vm/asm/codeBuffer.hpp @ 20543:e7d0505c8a30
8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso
author | tschatzl |
---|---|
date | Fri, 10 Oct 2014 15:51:58 +0200 |
parents | 094cbdffa87d |
children |
rev | line source |
---|---|
0 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12146
diff
changeset
|
2 * Copyright (c) 1997, 2014, 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 "code/oopRecorder.hpp" | |
29 #include "code/relocInfo.hpp" | |
20435 | 30 #include "utilities/debug.hpp" |
1972 | 31 |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
32 class CodeStrings; |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
33 class PhaseCFG; |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
34 class Compile; |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
35 class BufferBlob; |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
36 class CodeBuffer; |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
37 class Label; |
0 | 38 |
39 class CodeOffsets: public StackObj { | |
40 public: | |
41 enum Entries { Entry, | |
42 Verified_Entry, | |
43 Frame_Complete, // Offset in the code where the frame setup is (for forte stackwalks) is complete | |
44 OSR_Entry, | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
0
diff
changeset
|
45 Dtrace_trap = OSR_Entry, // dtrace probes can never have an OSR entry so reuse it |
0 | 46 Exceptions, // Offset where exception handler lives |
47 Deopt, // Offset where deopt handler lives | |
1204 | 48 DeoptMH, // Offset where MethodHandle deopt handler lives |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
49 UnwindHandler, // Offset to default unwind handler |
0 | 50 max_Entries }; |
51 | |
52 // special value to note codeBlobs where profile (forte) stack walking is | |
53 // always dangerous and suspect. | |
54 | |
55 enum { frame_never_safe = -1 }; | |
56 | |
57 private: | |
58 int _values[max_Entries]; | |
59 | |
60 public: | |
61 CodeOffsets() { | |
1204 | 62 _values[Entry ] = 0; |
0 | 63 _values[Verified_Entry] = 0; |
64 _values[Frame_Complete] = frame_never_safe; | |
1204 | 65 _values[OSR_Entry ] = 0; |
66 _values[Exceptions ] = -1; | |
67 _values[Deopt ] = -1; | |
68 _values[DeoptMH ] = -1; | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1204
diff
changeset
|
69 _values[UnwindHandler ] = -1; |
0 | 70 } |
71 | |
72 int value(Entries e) { return _values[e]; } | |
73 void set_value(Entries e, int val) { _values[e] = val; } | |
74 }; | |
75 | |
76 // This class represents a stream of code and associated relocations. | |
77 // There are a few in each CodeBuffer. | |
78 // They are filled concurrently, and concatenated at the end. | |
79 class CodeSection VALUE_OBJ_CLASS_SPEC { | |
80 friend class CodeBuffer; | |
81 public: | |
82 typedef int csize_t; // code size type; would be size_t except for history | |
83 | |
84 private: | |
85 address _start; // first byte of contents (instructions) | |
86 address _mark; // user mark, usually an instruction beginning | |
87 address _end; // current end address | |
88 address _limit; // last possible (allocated) end address | |
89 relocInfo* _locs_start; // first byte of relocation information | |
90 relocInfo* _locs_end; // first byte after relocation information | |
91 relocInfo* _locs_limit; // first byte after relocation information buf | |
92 address _locs_point; // last relocated position (grows upward) | |
93 bool _locs_own; // did I allocate the locs myself? | |
94 bool _frozen; // no more expansion of this section | |
95 char _index; // my section number (SECT_INST, etc.) | |
96 CodeBuffer* _outer; // enclosing CodeBuffer | |
97 | |
98 // (Note: _locs_point used to be called _last_reloc_offset.) | |
99 | |
100 CodeSection() { | |
101 _start = NULL; | |
102 _mark = NULL; | |
103 _end = NULL; | |
104 _limit = NULL; | |
105 _locs_start = NULL; | |
106 _locs_end = NULL; | |
107 _locs_limit = NULL; | |
108 _locs_point = NULL; | |
109 _locs_own = false; | |
110 _frozen = false; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
111 debug_only(_index = (char)-1); |
0 | 112 debug_only(_outer = (CodeBuffer*)badAddress); |
113 } | |
114 | |
115 void initialize_outer(CodeBuffer* outer, int index) { | |
116 _outer = outer; | |
117 _index = index; | |
118 } | |
119 | |
120 void initialize(address start, csize_t size = 0) { | |
121 assert(_start == NULL, "only one init step, please"); | |
122 _start = start; | |
123 _mark = NULL; | |
124 _end = start; | |
125 | |
126 _limit = start + size; | |
127 _locs_point = start; | |
128 } | |
129 | |
130 void initialize_locs(int locs_capacity); | |
131 void expand_locs(int new_capacity); | |
132 void initialize_locs_from(const CodeSection* source_cs); | |
133 | |
134 // helper for CodeBuffer::expand() | |
135 void take_over_code_from(CodeSection* cs) { | |
136 _start = cs->_start; | |
137 _mark = cs->_mark; | |
138 _end = cs->_end; | |
139 _limit = cs->_limit; | |
140 _locs_point = cs->_locs_point; | |
141 } | |
142 | |
143 public: | |
144 address start() const { return _start; } | |
145 address mark() const { return _mark; } | |
146 address end() const { return _end; } | |
147 address limit() const { return _limit; } | |
148 csize_t size() const { return (csize_t)(_end - _start); } | |
149 csize_t mark_off() const { assert(_mark != NULL, "not an offset"); | |
150 return (csize_t)(_mark - _start); } | |
151 csize_t capacity() const { return (csize_t)(_limit - _start); } | |
152 csize_t remaining() const { return (csize_t)(_limit - _end); } | |
153 | |
154 relocInfo* locs_start() const { return _locs_start; } | |
155 relocInfo* locs_end() const { return _locs_end; } | |
156 int locs_count() const { return (int)(_locs_end - _locs_start); } | |
157 relocInfo* locs_limit() const { return _locs_limit; } | |
158 address locs_point() const { return _locs_point; } | |
159 csize_t locs_point_off() const{ return (csize_t)(_locs_point - _start); } | |
160 csize_t locs_capacity() const { return (csize_t)(_locs_limit - _locs_start); } | |
161 csize_t locs_remaining()const { return (csize_t)(_locs_limit - _locs_end); } | |
162 | |
163 int index() const { return _index; } | |
164 bool is_allocated() const { return _start != NULL; } | |
165 bool is_empty() const { return _start == _end; } | |
166 bool is_frozen() const { return _frozen; } | |
167 bool has_locs() const { return _locs_end != NULL; } | |
168 | |
169 CodeBuffer* outer() const { return _outer; } | |
170 | |
171 // is a given address in this section? (2nd version is end-inclusive) | |
172 bool contains(address pc) const { return pc >= _start && pc < _end; } | |
173 bool contains2(address pc) const { return pc >= _start && pc <= _end; } | |
174 bool allocates(address pc) const { return pc >= _start && pc < _limit; } | |
175 bool allocates2(address pc) const { return pc >= _start && pc <= _limit; } | |
176 | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
12146
diff
changeset
|
177 void set_end(address pc) { assert(allocates2(pc), err_msg("not in CodeBuffer memory: " PTR_FORMAT " <= " PTR_FORMAT " <= " INTPTR_FORMAT, p2i(_start), p2i(pc), p2i(_limit))); _end = pc; } |
1846 | 178 void set_mark(address pc) { assert(contains2(pc), "not in codeBuffer"); |
0 | 179 _mark = pc; } |
180 void set_mark_off(int offset) { assert(contains2(offset+_start),"not in codeBuffer"); | |
181 _mark = offset + _start; } | |
182 void set_mark() { _mark = _end; } | |
183 void clear_mark() { _mark = NULL; } | |
184 | |
185 void set_locs_end(relocInfo* p) { | |
186 assert(p <= locs_limit(), "locs data fits in allocated buffer"); | |
187 _locs_end = p; | |
188 } | |
189 void set_locs_point(address pc) { | |
190 assert(pc >= locs_point(), "relocation addr may not decrease"); | |
191 assert(allocates2(pc), "relocation addr must be in this section"); | |
192 _locs_point = pc; | |
193 } | |
194 | |
1748 | 195 // Code emission |
7198
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
196 void emit_int8 ( int8_t x) { *((int8_t*) end()) = x; set_end(end() + sizeof(int8_t)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
197 void emit_int16( int16_t x) { *((int16_t*) end()) = x; set_end(end() + sizeof(int16_t)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
198 void emit_int32( int32_t x) { *((int32_t*) end()) = x; set_end(end() + sizeof(int32_t)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
199 void emit_int64( int64_t x) { *((int64_t*) end()) = x; set_end(end() + sizeof(int64_t)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
200 |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
201 void emit_float( jfloat x) { *((jfloat*) end()) = x; set_end(end() + sizeof(jfloat)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
202 void emit_double(jdouble x) { *((jdouble*) end()) = x; set_end(end() + sizeof(jdouble)); } |
6ab62ad83507
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
6796
diff
changeset
|
203 void emit_address(address x) { *((address*) end()) = x; set_end(end() + sizeof(address)); } |
1748 | 204 |
0 | 205 // Share a scratch buffer for relocinfo. (Hacky; saves a resource allocation.) |
206 void initialize_shared_locs(relocInfo* buf, int length); | |
207 | |
208 // Manage labels and their addresses. | |
209 address target(Label& L, address branch_pc); | |
210 | |
211 // Emit a relocation. | |
212 void relocate(address at, RelocationHolder const& rspec, int format = 0); | |
213 void relocate(address at, relocInfo::relocType rtype, int format = 0) { | |
214 if (rtype != relocInfo::none) | |
215 relocate(at, Relocation::spec_simple(rtype), format); | |
216 } | |
217 | |
218 // alignment requirement for starting offset | |
219 // Requirements are that the instruction area and the | |
220 // stubs area must start on CodeEntryAlignment, and | |
221 // the ctable on sizeof(jdouble) | |
222 int alignment() const { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); } | |
223 | |
224 // Slop between sections, used only when allocating temporary BufferBlob buffers. | |
225 static csize_t end_slop() { return MAX2((int)sizeof(jdouble), (int)CodeEntryAlignment); } | |
226 | |
227 csize_t align_at_start(csize_t off) const { return (csize_t) align_size_up(off, alignment()); } | |
228 | |
229 // Mark a section frozen. Assign its remaining space to | |
230 // the following section. It will never expand after this point. | |
231 inline void freeze(); // { _outer->freeze_section(this); } | |
232 | |
233 // Ensure there's enough space left in the current section. | |
234 // Return true if there was an expansion. | |
235 bool maybe_expand_to_ensure_remaining(csize_t amount); | |
236 | |
237 #ifndef PRODUCT | |
238 void decode(); | |
239 void dump(); | |
240 void print(const char* name); | |
241 #endif //PRODUCT | |
242 }; | |
243 | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
244 class CodeString; |
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
245 class CodeStrings VALUE_OBJ_CLASS_SPEC { |
0 | 246 private: |
247 #ifndef PRODUCT | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
248 CodeString* _strings; |
20435 | 249 #ifdef ASSERT |
250 // Becomes true after copy-out, forbids further use. | |
251 bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env | |
252 #endif | |
0 | 253 #endif |
254 | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
255 CodeString* find(intptr_t offset) const; |
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
256 CodeString* find_last(intptr_t offset) const; |
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
257 |
20435 | 258 void set_null_and_invalidate() { |
259 #ifndef PRODUCT | |
260 _strings = NULL; | |
261 #ifdef ASSERT | |
262 _defunct = true; | |
263 #endif | |
264 #endif | |
265 } | |
266 | |
0 | 267 public: |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
268 CodeStrings() { |
0 | 269 #ifndef PRODUCT |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
270 _strings = NULL; |
20435 | 271 #ifdef ASSERT |
272 _defunct = false; | |
273 #endif | |
274 #endif | |
275 } | |
276 | |
277 bool is_null() { | |
278 #ifdef ASSERT | |
279 return _strings == NULL; | |
280 #else | |
281 return true; | |
0 | 282 #endif |
283 } | |
284 | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
285 const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;); |
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
286 |
0 | 287 void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; |
6796
b31471cdc53e
7200163: add CodeComments functionality to assember stubs
kvn
parents:
6725
diff
changeset
|
288 void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN; |
20435 | 289 // MOVE strings from other to this; invalidate other. |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
290 void assign(CodeStrings& other) PRODUCT_RETURN; |
20435 | 291 // COPY strings from other to this; leave other valid. |
292 void copy(CodeStrings& other) PRODUCT_RETURN; | |
0 | 293 void free() PRODUCT_RETURN; |
20435 | 294 // Guarantee that _strings are used at most once; assign invalidates a buffer. |
295 inline void check_valid() const { | |
296 #ifdef ASSERT | |
297 assert(!_defunct, "Use of invalid CodeStrings"); | |
298 #endif | |
299 } | |
0 | 300 }; |
301 | |
302 // A CodeBuffer describes a memory space into which assembly | |
303 // code is generated. This memory space usually occupies the | |
304 // interior of a single BufferBlob, but in some cases it may be | |
305 // an arbitrary span of memory, even outside the code cache. | |
306 // | |
307 // A code buffer comes in two variants: | |
308 // | |
309 // (1) A CodeBuffer referring to an already allocated piece of memory: | |
310 // This is used to direct 'static' code generation (e.g. for interpreter | |
311 // or stubroutine generation, etc.). This code comes with NO relocation | |
312 // information. | |
313 // | |
314 // (2) A CodeBuffer referring to a piece of memory allocated when the | |
315 // CodeBuffer is allocated. This is used for nmethod generation. | |
316 // | |
317 // The memory can be divided up into several parts called sections. | |
318 // Each section independently accumulates code (or data) an relocations. | |
319 // Sections can grow (at the expense of a reallocation of the BufferBlob | |
320 // and recopying of all active sections). When the buffered code is finally | |
321 // written to an nmethod (or other CodeBlob), the contents (code, data, | |
322 // and relocations) of the sections are padded to an alignment and concatenated. | |
323 // Instructions and data in one section can contain relocatable references to | |
324 // addresses in a sibling section. | |
325 | |
326 class CodeBuffer: public StackObj { | |
327 friend class CodeSection; | |
328 | |
329 private: | |
330 // CodeBuffers must be allocated on the stack except for a single | |
331 // special case during expansion which is handled internally. This | |
332 // is done to guarantee proper cleanup of resources. | |
12146
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
8767
diff
changeset
|
333 void* operator new(size_t size) throw() { return ResourceObj::operator new(size); } |
9758d9f36299
8021954: VM SIGSEGV during classloading on MacOS; hs_err_pid file produced
coleenp
parents:
8767
diff
changeset
|
334 void operator delete(void* p) { ShouldNotCallThis(); } |
0 | 335 |
336 public: | |
337 typedef int csize_t; // code size type; would be size_t except for history | |
338 enum { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
339 // 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
|
340 // the final layout. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
341 SECT_FIRST = 0, |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
342 SECT_CONSTS = SECT_FIRST, // Non-instruction data: Floats, jump tables, etc. |
0 | 343 SECT_INSTS, // Executable instructions. |
344 SECT_STUBS, // Outbound trampolines for supporting call sites. | |
345 SECT_LIMIT, SECT_NONE = -1 | |
346 }; | |
347 | |
348 private: | |
349 enum { | |
350 sect_bits = 2, // assert (SECT_LIMIT <= (1<<sect_bits)) | |
351 sect_mask = (1<<sect_bits)-1 | |
352 }; | |
353 | |
354 const char* _name; | |
355 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
356 CodeSection _consts; // constants, jump tables |
0 | 357 CodeSection _insts; // instructions (the main section) |
358 CodeSection _stubs; // stubs (call site support), deopt, exception handling | |
359 | |
360 CodeBuffer* _before_expand; // dead buffer, from before the last expansion | |
361 | |
362 BufferBlob* _blob; // optional buffer in CodeCache for generated code | |
363 address _total_start; // first address of combined memory buffer | |
364 csize_t _total_size; // size in bytes of combined memory buffer | |
365 | |
366 OopRecorder* _oop_recorder; | |
20435 | 367 CodeStrings _code_strings; |
0 | 368 OopRecorder _default_oop_recorder; // override with initialize_oop_recorder |
369 Arena* _overflow_arena; | |
370 | |
371 address _decode_begin; // start address for decode | |
372 address decode_begin(); | |
373 | |
374 void initialize_misc(const char * name) { | |
375 // all pointers other than code_start/end and those inside the sections | |
376 assert(name != NULL, "must have a name"); | |
377 _name = name; | |
378 _before_expand = NULL; | |
379 _blob = NULL; | |
380 _oop_recorder = NULL; | |
381 _decode_begin = NULL; | |
382 _overflow_arena = NULL; | |
383 } | |
384 | |
385 void initialize(address code_start, csize_t code_size) { | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
386 _consts.initialize_outer(this, SECT_CONSTS); |
0 | 387 _insts.initialize_outer(this, SECT_INSTS); |
388 _stubs.initialize_outer(this, SECT_STUBS); | |
389 _total_start = code_start; | |
390 _total_size = code_size; | |
391 // Initialize the main section: | |
392 _insts.initialize(code_start, code_size); | |
393 assert(!_stubs.is_allocated(), "no garbage here"); | |
394 assert(!_consts.is_allocated(), "no garbage here"); | |
395 _oop_recorder = &_default_oop_recorder; | |
396 } | |
397 | |
398 void initialize_section_size(CodeSection* cs, csize_t size); | |
399 | |
400 void freeze_section(CodeSection* cs); | |
401 | |
402 // helper for CodeBuffer::expand() | |
403 void take_over_code_from(CodeBuffer* cs); | |
404 | |
405 // 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
|
406 void verify_section_allocation(); |
0 | 407 |
408 // copies combined relocations to the blob, returns bytes copied | |
409 // (if target is null, it is a dry run only, just for sizing) | |
410 csize_t copy_relocations_to(CodeBlob* blob) const; | |
411 | |
412 // copies combined code to the blob (assumes relocs are already in there) | |
413 void copy_code_to(CodeBlob* blob); | |
414 | |
415 // moves code sections to new buffer (assumes relocs are already in there) | |
416 void relocate_code_to(CodeBuffer* cb) const; | |
417 | |
418 // set up a model of the final layout of my contents | |
419 void compute_final_layout(CodeBuffer* dest) const; | |
420 | |
421 // Expand the given section so at least 'amount' is remaining. | |
422 // Creates a new, larger BufferBlob, and rewrites the code & relocs. | |
423 void expand(CodeSection* which_cs, csize_t amount); | |
424 | |
425 // Helper for expand. | |
426 csize_t figure_expanded_capacities(CodeSection* which_cs, csize_t amount, csize_t* new_capacity); | |
427 | |
428 public: | |
429 // (1) code buffer referring to pre-allocated instruction memory | |
1748 | 430 CodeBuffer(address code_start, csize_t code_size) { |
431 assert(code_start != NULL, "sanity"); | |
432 initialize_misc("static buffer"); | |
433 initialize(code_start, code_size); | |
4059
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
434 verify_section_allocation(); |
1748 | 435 } |
0 | 436 |
1748 | 437 // (2) CodeBuffer referring to pre-allocated CodeBlob. |
438 CodeBuffer(CodeBlob* blob); | |
439 | |
440 // (3) code buffer allocating codeBlob memory for code & relocation | |
0 | 441 // info but with lazy initialization. The name must be something |
442 // informative. | |
443 CodeBuffer(const char* name) { | |
444 initialize_misc(name); | |
445 } | |
446 | |
447 | |
1748 | 448 // (4) code buffer allocating codeBlob memory for code & relocation |
0 | 449 // info. The name must be something informative and code_size must |
450 // include both code and stubs sizes. | |
451 CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) { | |
452 initialize_misc(name); | |
453 initialize(code_size, locs_size); | |
454 } | |
455 | |
456 ~CodeBuffer(); | |
457 | |
1748 | 458 // Initialize a CodeBuffer constructed using constructor 3. Using |
459 // constructor 4 is equivalent to calling constructor 3 and then | |
0 | 460 // calling this method. It's been factored out for convenience of |
461 // construction. | |
462 void initialize(csize_t code_size, csize_t locs_size); | |
463 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
464 CodeSection* consts() { return &_consts; } |
0 | 465 CodeSection* insts() { return &_insts; } |
466 CodeSection* stubs() { return &_stubs; } | |
467 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
468 // present sections in order; return NULL at end; consts is #0, etc. |
0 | 469 CodeSection* code_section(int n) { |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
470 // This makes the slightly questionable but portable assumption |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
471 // that the various members (_consts, _insts, _stubs, etc.) are |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
472 // adjacent in the layout of CodeBuffer. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
473 CodeSection* cs = &_consts + n; |
0 | 474 assert(cs->index() == n || !cs->is_allocated(), "sanity"); |
475 return cs; | |
476 } | |
477 const CodeSection* code_section(int n) const { // yucky const stuff | |
478 return ((CodeBuffer*)this)->code_section(n); | |
479 } | |
480 static const char* code_section_name(int n); | |
481 int section_index_of(address addr) const; | |
482 bool contains(address addr) const { | |
483 // handy for debugging | |
484 return section_index_of(addr) > SECT_NONE; | |
485 } | |
486 | |
487 // A stable mapping between 'locators' (small ints) and addresses. | |
488 static int locator_pos(int locator) { return locator >> sect_bits; } | |
489 static int locator_sect(int locator) { return locator & sect_mask; } | |
490 static int locator(int pos, int sect) { return (pos << sect_bits) | sect; } | |
491 int locator(address addr) const; | |
492 address locator_address(int locator) const; | |
493 | |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
494 // Heuristic for pre-packing the taken/not-taken bit of a predicted branch. |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
495 bool is_backward_branch(Label& L); |
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
7198
diff
changeset
|
496 |
0 | 497 // Properties |
498 const char* name() const { return _name; } | |
499 CodeBuffer* before_expand() const { return _before_expand; } | |
500 BufferBlob* blob() const { return _blob; } | |
501 void set_blob(BufferBlob* blob); | |
502 void free_blob(); // Free the blob, if we own one. | |
503 | |
504 // Properties relative to the insts section: | |
1748 | 505 address insts_begin() const { return _insts.start(); } |
506 address insts_end() const { return _insts.end(); } | |
507 void set_insts_end(address end) { _insts.set_end(end); } | |
508 address insts_limit() const { return _insts.limit(); } | |
509 address insts_mark() const { return _insts.mark(); } | |
510 void set_insts_mark() { _insts.set_mark(); } | |
511 void clear_insts_mark() { _insts.clear_mark(); } | |
0 | 512 |
513 // is there anything in the buffer other than the current section? | |
1748 | 514 bool is_pure() const { return insts_size() == total_content_size(); } |
0 | 515 |
516 // size in bytes of output so far in the insts sections | |
1748 | 517 csize_t insts_size() const { return _insts.size(); } |
0 | 518 |
1748 | 519 // same as insts_size(), except that it asserts there is no non-code here |
520 csize_t pure_insts_size() const { assert(is_pure(), "no non-code"); | |
521 return insts_size(); } | |
0 | 522 // capacity in bytes of the insts sections |
1748 | 523 csize_t insts_capacity() const { return _insts.capacity(); } |
0 | 524 |
525 // number of bytes remaining in the insts section | |
1748 | 526 csize_t insts_remaining() const { return _insts.remaining(); } |
0 | 527 |
528 // is a given address in the insts section? (2nd version is end-inclusive) | |
1748 | 529 bool insts_contains(address pc) const { return _insts.contains(pc); } |
530 bool insts_contains2(address pc) const { return _insts.contains2(pc); } | |
0 | 531 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
532 // Record any extra oops required to keep embedded metadata alive |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
533 void finalize_oop_references(methodHandle method); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
534 |
1748 | 535 // Allocated size in all sections, when aligned and concatenated |
536 // (this is the eventual state of the content in its final | |
537 // CodeBlob). | |
538 csize_t total_content_size() const; | |
0 | 539 |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
540 // Combined offset (relative to start of first section) of given |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
541 // section, as eventually found in the final CodeBlob. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
542 csize_t total_offset_of(CodeSection* cs) const; |
0 | 543 |
544 // allocated size of all relocation data, including index, rounded up | |
545 csize_t total_relocation_size() const; | |
546 | |
547 // allocated size of any and all recorded oops | |
548 csize_t total_oop_size() const { | |
549 OopRecorder* recorder = oop_recorder(); | |
550 return (recorder == NULL)? 0: recorder->oop_size(); | |
551 } | |
552 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
553 // allocated size of any and all recorded metadata |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
554 csize_t total_metadata_size() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
555 OopRecorder* recorder = oop_recorder(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
556 return (recorder == NULL)? 0: recorder->metadata_size(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
557 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
558 |
0 | 559 // Configuration functions, called immediately after the CB is constructed. |
560 // The section sizes are subtracted from the original insts section. | |
561 // Note: Call them in reverse section order, because each steals from insts. | |
562 void initialize_consts_size(csize_t size) { initialize_section_size(&_consts, size); } | |
563 void initialize_stubs_size(csize_t size) { initialize_section_size(&_stubs, size); } | |
564 // Override default oop recorder. | |
565 void initialize_oop_recorder(OopRecorder* r); | |
566 | |
567 OopRecorder* oop_recorder() const { return _oop_recorder; } | |
20435 | 568 CodeStrings& strings() { return _code_strings; } |
569 | |
570 void free_strings() { | |
571 if (!_code_strings.is_null()) { | |
572 _code_strings.free(); // sets _strings Null as a side-effect. | |
573 } | |
574 } | |
0 | 575 |
576 // Code generation | |
577 void relocate(address at, RelocationHolder const& rspec, int format = 0) { | |
578 _insts.relocate(at, rspec, format); | |
579 } | |
580 void relocate(address at, relocInfo::relocType rtype, int format = 0) { | |
581 _insts.relocate(at, rtype, format); | |
582 } | |
583 | |
584 // Management of overflow storage for binding of Labels. | |
585 GrowableArray<int>* create_patch_overflow(); | |
586 | |
587 // NMethod generation | |
588 void copy_code_and_locs_to(CodeBlob* blob) { | |
589 assert(blob != NULL, "sane"); | |
590 copy_relocations_to(blob); | |
591 copy_code_to(blob); | |
592 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
593 void copy_values_to(nmethod* nm) { |
0 | 594 if (!oop_recorder()->is_unused()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4059
diff
changeset
|
595 oop_recorder()->copy_values_to(nm); |
0 | 596 } |
597 } | |
598 | |
599 // Transform an address from the code in this code buffer to a specified code buffer | |
600 address transform_address(const CodeBuffer &cb, address addr) const; | |
601 | |
602 void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; | |
8767
a5de0cc2f91c
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
7199
diff
changeset
|
603 const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;); |
0 | 604 |
4059
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
605 // 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
|
606 void log_section_sizes(const char* name); |
44ce519bc3d1
7104960: JSR 292: +VerifyMethodHandles in product JVM can overflow buffer
never
parents:
2426
diff
changeset
|
607 |
0 | 608 #ifndef PRODUCT |
609 public: | |
610 // Printing / Decoding | |
611 // decodes from decode_begin() to code_end() and sets decode_begin to end | |
612 void decode(); | |
613 void decode_all(); // decodes all the code | |
614 void skip_decode(); // sets decode_begin to code_end(); | |
615 void print(); | |
616 #endif | |
617 | |
618 | |
619 // The following header contains architecture-specific implementations | |
1972 | 620 #ifdef TARGET_ARCH_x86 |
621 # include "codeBuffer_x86.hpp" | |
622 #endif | |
623 #ifdef TARGET_ARCH_sparc | |
624 # include "codeBuffer_sparc.hpp" | |
625 #endif | |
626 #ifdef TARGET_ARCH_zero | |
627 # include "codeBuffer_zero.hpp" | |
628 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
629 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
630 # include "codeBuffer_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
631 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
632 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
633 # include "codeBuffer_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
1972
diff
changeset
|
634 #endif |
1972 | 635 |
0 | 636 }; |
637 | |
638 | |
639 inline void CodeSection::freeze() { | |
640 _outer->freeze_section(this); | |
641 } | |
642 | |
643 inline bool CodeSection::maybe_expand_to_ensure_remaining(csize_t amount) { | |
644 if (remaining() < amount) { _outer->expand(this, amount); return true; } | |
645 return false; | |
646 } | |
1972 | 647 |
648 #endif // SHARE_VM_ASM_CODEBUFFER_HPP |