Mercurial > hg > truffle
annotate src/share/vm/asm/assembler.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 | 2f644f85485d |
rev | line source |
---|---|
0 | 1 /* |
1972 | 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:
665
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
665
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:
665
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_ASM_ASSEMBLER_HPP |
26 #define SHARE_VM_ASM_ASSEMBLER_HPP | |
27 | |
28 #include "code/oopRecorder.hpp" | |
29 #include "code/relocInfo.hpp" | |
30 #include "memory/allocation.hpp" | |
31 #include "utilities/debug.hpp" | |
32 #include "utilities/growableArray.hpp" | |
33 #include "utilities/top.hpp" | |
34 #ifdef TARGET_ARCH_x86 | |
35 # include "register_x86.hpp" | |
36 # include "vm_version_x86.hpp" | |
37 #endif | |
38 #ifdef TARGET_ARCH_sparc | |
39 # include "register_sparc.hpp" | |
40 # include "vm_version_sparc.hpp" | |
41 #endif | |
42 #ifdef TARGET_ARCH_zero | |
43 # include "register_zero.hpp" | |
44 # include "vm_version_zero.hpp" | |
45 #endif | |
46 | |
605 | 47 // This file contains platform-independent assembler declarations. |
0 | 48 |
49 class CodeBuffer; | |
50 class MacroAssembler; | |
51 class AbstractAssembler; | |
52 class Label; | |
53 | |
54 /** | |
55 * Labels represent destinations for control transfer instructions. Such | |
56 * instructions can accept a Label as their target argument. A Label is | |
57 * bound to the current location in the code stream by calling the | |
58 * MacroAssembler's 'bind' method, which in turn calls the Label's 'bind' | |
59 * method. A Label may be referenced by an instruction before it's bound | |
60 * (i.e., 'forward referenced'). 'bind' stores the current code offset | |
61 * in the Label object. | |
62 * | |
63 * If an instruction references a bound Label, the offset field(s) within | |
64 * the instruction are immediately filled in based on the Label's code | |
65 * offset. If an instruction references an unbound label, that | |
66 * instruction is put on a list of instructions that must be patched | |
67 * (i.e., 'resolved') when the Label is bound. | |
68 * | |
69 * 'bind' will call the platform-specific 'patch_instruction' method to | |
70 * fill in the offset field(s) for each unresolved instruction (if there | |
71 * are any). 'patch_instruction' lives in one of the | |
72 * cpu/<arch>/vm/assembler_<arch>* files. | |
73 * | |
74 * Instead of using a linked list of unresolved instructions, a Label has | |
75 * an array of unresolved instruction code offsets. _patch_index | |
76 * contains the total number of forward references. If the Label's array | |
77 * overflows (i.e., _patch_index grows larger than the array size), a | |
78 * GrowableArray is allocated to hold the remaining offsets. (The cache | |
79 * size is 4 for now, which handles over 99.5% of the cases) | |
80 * | |
81 * Labels may only be used within a single CodeSection. If you need | |
82 * to create references between code sections, use explicit relocations. | |
83 */ | |
84 class Label VALUE_OBJ_CLASS_SPEC { | |
85 private: | |
86 enum { PatchCacheSize = 4 }; | |
87 | |
88 // _loc encodes both the binding state (via its sign) | |
89 // and the binding locator (via its value) of a label. | |
90 // | |
91 // _loc >= 0 bound label, loc() encodes the target (jump) position | |
92 // _loc == -1 unbound label | |
93 int _loc; | |
94 | |
95 // References to instructions that jump to this unresolved label. | |
96 // These instructions need to be patched when the label is bound | |
97 // using the platform-specific patchInstruction() method. | |
98 // | |
99 // To avoid having to allocate from the C-heap each time, we provide | |
100 // a local cache and use the overflow only if we exceed the local cache | |
101 int _patches[PatchCacheSize]; | |
102 int _patch_index; | |
103 GrowableArray<int>* _patch_overflow; | |
104 | |
105 Label(const Label&) { ShouldNotReachHere(); } | |
106 | |
107 public: | |
108 | |
109 /** | |
110 * After binding, be sure 'patch_instructions' is called later to link | |
111 */ | |
112 void bind_loc(int loc) { | |
113 assert(loc >= 0, "illegal locator"); | |
114 assert(_loc == -1, "already bound"); | |
115 _loc = loc; | |
116 } | |
117 void bind_loc(int pos, int sect); // = bind_loc(locator(pos, sect)) | |
118 | |
119 #ifndef PRODUCT | |
120 // Iterates over all unresolved instructions for printing | |
121 void print_instructions(MacroAssembler* masm) const; | |
122 #endif // PRODUCT | |
123 | |
124 /** | |
125 * Returns the position of the the Label in the code buffer | |
126 * The position is a 'locator', which encodes both offset and section. | |
127 */ | |
128 int loc() const { | |
129 assert(_loc >= 0, "unbound label"); | |
130 return _loc; | |
131 } | |
132 int loc_pos() const; // == locator_pos(loc()) | |
133 int loc_sect() const; // == locator_sect(loc()) | |
134 | |
135 bool is_bound() const { return _loc >= 0; } | |
136 bool is_unbound() const { return _loc == -1 && _patch_index > 0; } | |
137 bool is_unused() const { return _loc == -1 && _patch_index == 0; } | |
138 | |
139 /** | |
140 * Adds a reference to an unresolved displacement instruction to | |
141 * this unbound label | |
142 * | |
143 * @param cb the code buffer being patched | |
144 * @param branch_loc the locator of the branch instruction in the code buffer | |
145 */ | |
146 void add_patch_at(CodeBuffer* cb, int branch_loc); | |
147 | |
148 /** | |
149 * Iterate over the list of patches, resolving the instructions | |
150 * Call patch_instruction on each 'branch_loc' value | |
151 */ | |
152 void patch_instructions(MacroAssembler* masm); | |
153 | |
154 void init() { | |
155 _loc = -1; | |
156 _patch_index = 0; | |
157 _patch_overflow = NULL; | |
158 } | |
159 | |
160 Label() { | |
161 init(); | |
162 } | |
163 }; | |
164 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
165 // A union type for code which has to assemble both constant and |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
166 // non-constant operands, when the distinction cannot be made |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
167 // statically. |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
168 class RegisterOrConstant VALUE_OBJ_CLASS_SPEC { |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
169 private: |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
170 Register _r; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
171 intptr_t _c; |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
172 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
173 public: |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
174 RegisterOrConstant(): _r(noreg), _c(0) {} |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
175 RegisterOrConstant(Register r): _r(r), _c(0) {} |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
176 RegisterOrConstant(intptr_t c): _r(noreg), _c(c) {} |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
177 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
178 Register as_register() const { assert(is_register(),""); return _r; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
179 intptr_t as_constant() const { assert(is_constant(),""); return _c; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
180 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
181 Register register_or_noreg() const { return _r; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
182 intptr_t constant_or_zero() const { return _c; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
183 |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
184 bool is_register() const { return _r != noreg; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
185 bool is_constant() const { return _r == noreg; } |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
186 }; |
0 | 187 |
188 // The Abstract Assembler: Pure assembler doing NO optimizations on the | |
189 // instruction level; i.e., what you write is what you get. | |
190 // The Assembler is generating code into a CodeBuffer. | |
191 class AbstractAssembler : public ResourceObj { | |
192 friend class Label; | |
193 | |
194 protected: | |
195 CodeSection* _code_section; // section within the code buffer | |
196 address _code_begin; // first byte of code buffer | |
197 address _code_limit; // first byte after code buffer | |
198 address _code_pos; // current code generation position | |
199 OopRecorder* _oop_recorder; // support for relocInfo::oop_type | |
200 | |
201 // Code emission & accessing | |
202 address addr_at(int pos) const { return _code_begin + pos; } | |
203 | |
204 // This routine is called with a label is used for an address. | |
205 // Labels and displacements truck in offsets, but target must return a PC. | |
206 address target(Label& L); // return _code_section->target(L) | |
207 | |
208 bool is8bit(int x) const { return -0x80 <= x && x < 0x80; } | |
209 bool isByte(int x) const { return 0 <= x && x < 0x100; } | |
210 bool isShiftCount(int x) const { return 0 <= x && x < 32; } | |
211 | |
212 void emit_byte(int x); // emit a single byte | |
213 void emit_word(int x); // emit a 16-bit word (not a wordSize word!) | |
214 void emit_long(jint x); // emit a 32-bit word (not a longSize word!) | |
215 void emit_address(address x); // emit an address (not a longSize word!) | |
216 | |
217 // Instruction boundaries (required when emitting relocatable values). | |
218 class InstructionMark: public StackObj { | |
219 private: | |
220 AbstractAssembler* _assm; | |
221 | |
222 public: | |
223 InstructionMark(AbstractAssembler* assm) : _assm(assm) { | |
224 assert(assm->inst_mark() == NULL, "overlapping instructions"); | |
225 _assm->set_inst_mark(); | |
226 } | |
227 ~InstructionMark() { | |
228 _assm->clear_inst_mark(); | |
229 } | |
230 }; | |
231 friend class InstructionMark; | |
232 #ifdef ASSERT | |
233 // Make it return true on platforms which need to verify | |
234 // instruction boundaries for some operations. | |
235 inline static bool pd_check_instruction_mark(); | |
236 #endif | |
237 | |
238 // Label functions | |
239 void print(Label& L); | |
240 | |
241 public: | |
242 | |
243 // Creation | |
244 AbstractAssembler(CodeBuffer* code); | |
245 | |
246 // save end pointer back to code buf. | |
247 void sync(); | |
248 | |
249 // ensure buf contains all code (call this before using/copying the code) | |
250 void flush(); | |
251 | |
252 // Accessors | |
253 CodeBuffer* code() const; // _code_section->outer() | |
254 CodeSection* code_section() const { return _code_section; } | |
255 int sect() const; // return _code_section->index() | |
256 address pc() const { return _code_pos; } | |
257 int offset() const { return _code_pos - _code_begin; } | |
258 int locator() const; // CodeBuffer::locator(offset(), sect()) | |
259 OopRecorder* oop_recorder() const { return _oop_recorder; } | |
260 void set_oop_recorder(OopRecorder* r) { _oop_recorder = r; } | |
261 | |
262 address inst_mark() const; | |
263 void set_inst_mark(); | |
264 void clear_inst_mark(); | |
265 | |
266 // Constants in code | |
267 void a_byte(int x); | |
268 void a_long(jint x); | |
269 void relocate(RelocationHolder const& rspec, int format = 0); | |
270 void relocate( relocInfo::relocType rtype, int format = 0) { | |
271 if (rtype != relocInfo::none) | |
272 relocate(Relocation::spec_simple(rtype), format); | |
273 } | |
274 | |
275 static int code_fill_byte(); // used to pad out odd-sized code buffers | |
276 | |
277 // Associate a comment with the current offset. It will be printed | |
278 // along with the disassembly when printing nmethods. Currently | |
279 // only supported in the instruction section of the code buffer. | |
280 void block_comment(const char* comment); | |
281 | |
282 // Label functions | |
283 void bind(Label& L); // binds an unbound label L to the current code position | |
284 | |
285 // Move to a different section in the same code buffer. | |
286 void set_code_section(CodeSection* cs); | |
287 | |
288 // Inform assembler when generating stub code and relocation info | |
289 address start_a_stub(int required_space); | |
290 void end_a_stub(); | |
291 // Ditto for constants. | |
292 address start_a_const(int required_space, int required_align = sizeof(double)); | |
293 void end_a_const(); | |
294 | |
295 // fp constants support | |
296 address double_constant(jdouble c) { | |
297 address ptr = start_a_const(sizeof(c), sizeof(c)); | |
298 if (ptr != NULL) { | |
299 *(jdouble*)ptr = c; | |
300 _code_pos = ptr + sizeof(c); | |
301 end_a_const(); | |
302 } | |
303 return ptr; | |
304 } | |
305 address float_constant(jfloat c) { | |
306 address ptr = start_a_const(sizeof(c), sizeof(c)); | |
307 if (ptr != NULL) { | |
308 *(jfloat*)ptr = c; | |
309 _code_pos = ptr + sizeof(c); | |
310 end_a_const(); | |
311 } | |
312 return ptr; | |
313 } | |
314 address address_constant(address c, RelocationHolder const& rspec) { | |
315 address ptr = start_a_const(sizeof(c), sizeof(c)); | |
316 if (ptr != NULL) { | |
317 relocate(rspec); | |
318 *(address*)ptr = c; | |
319 _code_pos = ptr + sizeof(c); | |
320 end_a_const(); | |
321 } | |
322 return ptr; | |
323 } | |
324 inline address address_constant(Label& L); | |
325 inline address address_table_constant(GrowableArray<Label*> label); | |
326 | |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
327 // Bootstrapping aid to cope with delayed determination of constants. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
328 // Returns a static address which will eventually contain the constant. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
329 // The value zero (NULL) stands instead of a constant which is still uncomputed. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
330 // Thus, the eventual value of the constant must not be zero. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
331 // This is fine, since this is designed for embedding object field |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
332 // offsets in code which must be generated before the object class is loaded. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
333 // Field offsets are never zero, since an object's header (mark word) |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
334 // is located at offset zero. |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
335 RegisterOrConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
336 return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
337 } |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
338 RegisterOrConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
339 return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
340 } |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
622
diff
changeset
|
341 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) = 0; |
622
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
342 // Last overloading is platform-dependent; look in assembler_<arch>.cpp. |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
343 static intptr_t* delayed_value_addr(int(*constant_fn)()); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
344 static intptr_t* delayed_value_addr(address(*constant_fn)()); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
345 static void update_delayed_values(); |
56aae7be60d4
6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents:
605
diff
changeset
|
346 |
0 | 347 // Bang stack to trigger StackOverflowError at a safe location |
348 // implementation delegates to machine-specific bang_stack_with_offset | |
349 void generate_stack_overflow_check( int frame_size_in_bytes ); | |
350 virtual void bang_stack_with_offset(int offset) = 0; | |
351 | |
352 | |
353 /** | |
354 * A platform-dependent method to patch a jump instruction that refers | |
355 * to this label. | |
356 * | |
357 * @param branch the location of the instruction to patch | |
358 * @param masm the assembler which generated the branch | |
359 */ | |
360 void pd_patch_instruction(address branch, address target); | |
361 | |
362 #ifndef PRODUCT | |
363 /** | |
364 * Platform-dependent method of printing an instruction that needs to be | |
365 * patched. | |
366 * | |
367 * @param branch the instruction to be patched in the buffer. | |
368 */ | |
369 static void pd_print_patched_instruction(address branch); | |
370 #endif // PRODUCT | |
371 }; | |
372 | |
1972 | 373 #ifdef TARGET_ARCH_x86 |
374 # include "assembler_x86.hpp" | |
375 #endif | |
376 #ifdef TARGET_ARCH_sparc | |
377 # include "assembler_sparc.hpp" | |
378 #endif | |
379 #ifdef TARGET_ARCH_zero | |
380 # include "assembler_zero.hpp" | |
381 #endif | |
382 | |
383 | |
384 #endif // SHARE_VM_ASM_ASSEMBLER_HPP |