annotate src/share/vm/asm/assembler.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents eb28cf662f56
children 98cb887364d3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
337
9ee9cf798b59 6754988: Update copyright year
xdono
parents: 237
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_assembler.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Implementation of AbstractAssembler
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // The AbstractAssembler is generating code into a CodeBuffer. To make code generation faster,
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // the assembler keeps a copy of the code buffers boundaries & modifies them when
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // emitting bytes rather than using the code buffers accessor functions all the time.
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // The code buffer is updated via set_code_end(...) after emiting a whole instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 AbstractAssembler::AbstractAssembler(CodeBuffer* code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 if (code == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 CodeSection* cs = code->insts();
a61af66fc99e Initial load
duke
parents:
diff changeset
39 cs->clear_mark(); // new assembler kills old mark
a61af66fc99e Initial load
duke
parents:
diff changeset
40 _code_section = cs;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _code_begin = cs->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _code_limit = cs->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _code_pos = cs->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _oop_recorder= code->oop_recorder();
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (_code_begin == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 vm_exit_out_of_memory1(0, "CodeCache: no room for %s", code->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
47 }
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 void AbstractAssembler::set_code_section(CodeSection* cs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 assert(cs->outer() == code_section()->outer(), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
52 assert(cs->is_allocated(), "need to pre-allocate this section");
a61af66fc99e Initial load
duke
parents:
diff changeset
53 cs->clear_mark(); // new assembly into this section kills old mark
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _code_section = cs;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _code_begin = cs->start();
a61af66fc99e Initial load
duke
parents:
diff changeset
56 _code_limit = cs->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _code_pos = cs->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
58 }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Inform CodeBuffer that incoming code and relocation will be for stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
61 address AbstractAssembler::start_a_stub(int required_space) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 CodeBuffer* cb = code();
a61af66fc99e Initial load
duke
parents:
diff changeset
63 CodeSection* cs = cb->stubs();
a61af66fc99e Initial load
duke
parents:
diff changeset
64 assert(_code_section == cb->insts(), "not in insts?");
a61af66fc99e Initial load
duke
parents:
diff changeset
65 sync();
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if (cs->maybe_expand_to_ensure_remaining(required_space)
a61af66fc99e Initial load
duke
parents:
diff changeset
67 && cb->blob() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 set_code_section(cs);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 return pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Inform CodeBuffer that incoming code and relocation will be code
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // Should not be called if start_a_stub() returned NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
76 void AbstractAssembler::end_a_stub() {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 assert(_code_section == code()->stubs(), "not in stubs?");
a61af66fc99e Initial load
duke
parents:
diff changeset
78 sync();
a61af66fc99e Initial load
duke
parents:
diff changeset
79 set_code_section(code()->insts());
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Inform CodeBuffer that incoming code and relocation will be for stubs
a61af66fc99e Initial load
duke
parents:
diff changeset
83 address AbstractAssembler::start_a_const(int required_space, int required_align) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 CodeBuffer* cb = code();
a61af66fc99e Initial load
duke
parents:
diff changeset
85 CodeSection* cs = cb->consts();
a61af66fc99e Initial load
duke
parents:
diff changeset
86 assert(_code_section == cb->insts(), "not in insts?");
a61af66fc99e Initial load
duke
parents:
diff changeset
87 sync();
a61af66fc99e Initial load
duke
parents:
diff changeset
88 address end = cs->end();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 int pad = -(intptr_t)end & (required_align-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
90 if (cs->maybe_expand_to_ensure_remaining(pad + required_space)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 if (cb->blob() == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 end = cs->end(); // refresh pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 if (pad > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 while (--pad >= 0) { *end++ = 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 cs->set_end(end);
a61af66fc99e Initial load
duke
parents:
diff changeset
97 }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 set_code_section(cs);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Inform CodeBuffer that incoming code and relocation will be code
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Should not be called if start_a_const() returned NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
104 void AbstractAssembler::end_a_const() {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 assert(_code_section == code()->consts(), "not in consts?");
a61af66fc99e Initial load
duke
parents:
diff changeset
106 sync();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 set_code_section(code()->insts());
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 void AbstractAssembler::flush() {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 sync();
a61af66fc99e Initial load
duke
parents:
diff changeset
113 ICache::invalidate_range(addr_at(0), offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 void AbstractAssembler::a_byte(int x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 emit_byte(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 void AbstractAssembler::a_long(jint x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 emit_long(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Labels refer to positions in the (to be) generated code. There are bound
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // and unbound
a61af66fc99e Initial load
duke
parents:
diff changeset
128 //
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Bound labels refer to known positions in the already generated code.
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // offset() is the position the label refers to.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 //
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Unbound labels refer to unknown positions in the code to be generated; it
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // may contain a list of unresolved displacements that refer to it
a61af66fc99e Initial load
duke
parents:
diff changeset
134 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
135 void AbstractAssembler::print(Label& L) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if (L.is_bound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 tty->print_cr("bound label to %d|%d", L.loc_pos(), L.loc_sect());
a61af66fc99e Initial load
duke
parents:
diff changeset
138 } else if (L.is_unbound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 L.print_instructions((MacroAssembler*)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
140 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 tty->print_cr("label in inconsistent state (loc = %d)", L.loc());
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 void AbstractAssembler::bind(Label& L) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (L.is_bound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // Assembler can bind a label more than once to the same place.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 guarantee(L.loc() == locator(), "attempt to redefine label");
a61af66fc99e Initial load
duke
parents:
diff changeset
151 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153 L.bind_loc(locator());
a61af66fc99e Initial load
duke
parents:
diff changeset
154 L.patch_instructions((MacroAssembler*)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 if (UseStackBanging) {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // Each code entry causes one stack bang n pages down the stack where n
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // is configurable by StackBangPages. The setting depends on the maximum
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // depth of VM call stack or native before going back into java code,
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // since only java code can raise a stack overflow exception using the
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // stack banging mechanism. The VM and native code does not detect stack
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // The code in JavaCalls::call() checks that there is at least n pages
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // available, so all entry code needs to do is bang once for the end of
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // this shadow zone.
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // The entry code may need to bang additional pages if the framesize
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // is greater than a page.
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 const int page_size = os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
172 int bang_end = StackShadowPages*page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // This is how far the previous frame's stack banging extended.
a61af66fc99e Initial load
duke
parents:
diff changeset
175 const int bang_end_safe = bang_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 if (frame_size_in_bytes > page_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 bang_end += frame_size_in_bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 int bang_offset = bang_end_safe;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 while (bang_offset <= bang_end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Need at least one stack bang at end of shadow zone.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 bang_stack_with_offset(bang_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 bang_offset += page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187 } // end (UseStackBanging)
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(_loc == -1, "Label is unbound");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 if (_patch_index < PatchCacheSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 _patches[_patch_index] = branch_loc;
a61af66fc99e Initial load
duke
parents:
diff changeset
194 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (_patch_overflow == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 _patch_overflow = cb->create_patch_overflow();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198 _patch_overflow->push(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 ++_patch_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202
a61af66fc99e Initial load
duke
parents:
diff changeset
203 void Label::patch_instructions(MacroAssembler* masm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 assert(is_bound(), "Label is bound");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 CodeBuffer* cb = masm->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
206 int target_sect = CodeBuffer::locator_sect(loc());
a61af66fc99e Initial load
duke
parents:
diff changeset
207 address target = cb->locator_address(loc());
a61af66fc99e Initial load
duke
parents:
diff changeset
208 while (_patch_index > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 --_patch_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 int branch_loc;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (_patch_index >= PatchCacheSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 branch_loc = _patch_overflow->pop();
a61af66fc99e Initial load
duke
parents:
diff changeset
213 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 branch_loc = _patches[_patch_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216 int branch_sect = CodeBuffer::locator_sect(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 address branch = cb->locator_address(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 if (branch_sect == CodeBuffer::SECT_CONSTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // The thing to patch is a constant word.
a61af66fc99e Initial load
duke
parents:
diff changeset
220 *(address*)branch = target;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Cross-section branches only work if the
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // intermediate section boundaries are frozen.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (target_sect != branch_sect) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 for (int n = MIN2(target_sect, branch_sect),
a61af66fc99e Initial load
duke
parents:
diff changeset
229 nlimit = (target_sect + branch_sect) - n;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 n < nlimit; n++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
231 CodeSection* cs = cb->code_section(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
232 assert(cs->is_frozen(), "cross-section branch needs stable offsets");
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Push the target offset into the branch instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 masm->pd_patch_instruction(branch, target);
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 void AbstractAssembler::block_comment(const char* comment) {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (sect() == CodeBuffer::SECT_INSTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 code_section()->outer()->block_comment(offset(), comment);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
249 bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
250 // Exception handler checks the nmethod's implicit null checks table
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
251 // only when this method returns false.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
252 if (UseCompressedOops) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
253 // The first page after heap_base is unmapped and
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
254 // the 'offset' is equal to [heap_base + offset] for
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
255 // narrow oop implicit null checks.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
256 uintptr_t heap_base = (uintptr_t)Universe::heap_base();
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
257 if ((uintptr_t)offset >= heap_base) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
258 // Normalize offset for the next check.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
259 offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
260 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
261 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
262 return offset < 0 || os::vm_page_size() <= offset;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 0
diff changeset
263 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
266 void Label::print_instructions(MacroAssembler* masm) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 CodeBuffer* cb = masm->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 for (int i = 0; i < _patch_index; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 int branch_loc;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 if (i >= PatchCacheSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 branch_loc = _patch_overflow->at(i - PatchCacheSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
272 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 branch_loc = _patches[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 int branch_pos = CodeBuffer::locator_pos(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 int branch_sect = CodeBuffer::locator_sect(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 address branch = cb->locator_address(branch_loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
278 tty->print_cr("unbound label");
a61af66fc99e Initial load
duke
parents:
diff changeset
279 tty->print("@ %d|%d ", branch_pos, branch_sect);
a61af66fc99e Initial load
duke
parents:
diff changeset
280 if (branch_sect == CodeBuffer::SECT_CONSTS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 tty->print_cr(PTR_FORMAT, *(address*)branch);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
284 masm->pd_print_patched_instruction(branch);
a61af66fc99e Initial load
duke
parents:
diff changeset
285 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 #endif // ndef PRODUCT