1 | /* |
2 | * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
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 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "asm/codeBuffer.hpp" |
27 | #include "asm/macroAssembler.hpp" |
28 | #include "asm/macroAssembler.inline.hpp" |
29 | #include "gc/shared/collectedHeap.hpp" |
30 | #include "memory/universe.hpp" |
31 | #include "oops/compressedOops.hpp" |
32 | #include "runtime/atomic.hpp" |
33 | #include "runtime/icache.hpp" |
34 | #include "runtime/os.hpp" |
35 | #include "runtime/thread.hpp" |
36 | |
37 | |
38 | // Implementation of AbstractAssembler |
39 | // |
40 | // The AbstractAssembler is generating code into a CodeBuffer. To make code generation faster, |
41 | // the assembler keeps a copy of the code buffers boundaries & modifies them when |
42 | // emitting bytes rather than using the code buffers accessor functions all the time. |
43 | // The code buffer is updated via set_code_end(...) after emitting a whole instruction. |
44 | |
45 | AbstractAssembler::AbstractAssembler(CodeBuffer* code) { |
46 | if (code == NULL) return; |
47 | CodeSection* cs = code->insts(); |
48 | cs->clear_mark(); // new assembler kills old mark |
49 | if (cs->start() == NULL) { |
50 | vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "CodeCache: no room for %s" , code->name()); |
51 | } |
52 | _code_section = cs; |
53 | _oop_recorder= code->oop_recorder(); |
54 | DEBUG_ONLY( _short_branch_delta = 0; ) |
55 | } |
56 | |
57 | void AbstractAssembler::set_code_section(CodeSection* cs) { |
58 | assert(cs->outer() == code_section()->outer(), "sanity" ); |
59 | assert(cs->is_allocated(), "need to pre-allocate this section" ); |
60 | cs->clear_mark(); // new assembly into this section kills old mark |
61 | _code_section = cs; |
62 | } |
63 | |
64 | // Inform CodeBuffer that incoming code and relocation will be for stubs |
65 | address AbstractAssembler::start_a_stub(int required_space) { |
66 | CodeBuffer* cb = code(); |
67 | CodeSection* cs = cb->stubs(); |
68 | assert(_code_section == cb->insts(), "not in insts?" ); |
69 | if (cs->maybe_expand_to_ensure_remaining(required_space) |
70 | && cb->blob() == NULL) { |
71 | return NULL; |
72 | } |
73 | set_code_section(cs); |
74 | return pc(); |
75 | } |
76 | |
77 | // Inform CodeBuffer that incoming code and relocation will be code |
78 | // Should not be called if start_a_stub() returned NULL |
79 | void AbstractAssembler::end_a_stub() { |
80 | assert(_code_section == code()->stubs(), "not in stubs?" ); |
81 | set_code_section(code()->insts()); |
82 | } |
83 | |
84 | // Inform CodeBuffer that incoming code and relocation will be for stubs |
85 | address AbstractAssembler::start_a_const(int required_space, int required_align) { |
86 | CodeBuffer* cb = code(); |
87 | CodeSection* cs = cb->consts(); |
88 | assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?" ); |
89 | address end = cs->end(); |
90 | int pad = -(intptr_t)end & (required_align-1); |
91 | if (cs->maybe_expand_to_ensure_remaining(pad + required_space)) { |
92 | if (cb->blob() == NULL) return NULL; |
93 | end = cs->end(); // refresh pointer |
94 | } |
95 | if (pad > 0) { |
96 | while (--pad >= 0) { *end++ = 0; } |
97 | cs->set_end(end); |
98 | } |
99 | set_code_section(cs); |
100 | return end; |
101 | } |
102 | |
103 | // Inform CodeBuffer that incoming code and relocation will be code |
104 | // in section cs (insts or stubs). |
105 | void AbstractAssembler::end_a_const(CodeSection* cs) { |
106 | assert(_code_section == code()->consts(), "not in consts?" ); |
107 | set_code_section(cs); |
108 | } |
109 | |
110 | void AbstractAssembler::flush() { |
111 | ICache::invalidate_range(addr_at(0), offset()); |
112 | } |
113 | |
114 | void AbstractAssembler::bind(Label& L) { |
115 | if (L.is_bound()) { |
116 | // Assembler can bind a label more than once to the same place. |
117 | guarantee(L.loc() == locator(), "attempt to redefine label" ); |
118 | return; |
119 | } |
120 | L.bind_loc(locator()); |
121 | L.patch_instructions((MacroAssembler*)this); |
122 | } |
123 | |
124 | void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) { |
125 | if (UseStackBanging) { |
126 | // Each code entry causes one stack bang n pages down the stack where n |
127 | // is configurable by StackShadowPages. The setting depends on the maximum |
128 | // depth of VM call stack or native before going back into java code, |
129 | // since only java code can raise a stack overflow exception using the |
130 | // stack banging mechanism. The VM and native code does not detect stack |
131 | // overflow. |
132 | // The code in JavaCalls::call() checks that there is at least n pages |
133 | // available, so all entry code needs to do is bang once for the end of |
134 | // this shadow zone. |
135 | // The entry code may need to bang additional pages if the framesize |
136 | // is greater than a page. |
137 | |
138 | const int page_size = os::vm_page_size(); |
139 | int bang_end = (int)JavaThread::stack_shadow_zone_size(); |
140 | |
141 | // This is how far the previous frame's stack banging extended. |
142 | const int bang_end_safe = bang_end; |
143 | |
144 | if (frame_size_in_bytes > page_size) { |
145 | bang_end += frame_size_in_bytes; |
146 | } |
147 | |
148 | int bang_offset = bang_end_safe; |
149 | while (bang_offset <= bang_end) { |
150 | // Need at least one stack bang at end of shadow zone. |
151 | bang_stack_with_offset(bang_offset); |
152 | bang_offset += page_size; |
153 | } |
154 | } // end (UseStackBanging) |
155 | } |
156 | |
157 | void Label::add_patch_at(CodeBuffer* cb, int branch_loc, const char* file, int line) { |
158 | assert(_loc == -1, "Label is unbound" ); |
159 | // Don't add patch locations during scratch emit. |
160 | if (cb->insts()->scratch_emit()) { return; } |
161 | if (_patch_index < PatchCacheSize) { |
162 | _patches[_patch_index] = branch_loc; |
163 | #ifdef ASSERT |
164 | _lines[_patch_index] = line; |
165 | _files[_patch_index] = file; |
166 | #endif |
167 | } else { |
168 | if (_patch_overflow == NULL) { |
169 | _patch_overflow = cb->create_patch_overflow(); |
170 | } |
171 | _patch_overflow->push(branch_loc); |
172 | } |
173 | ++_patch_index; |
174 | } |
175 | |
176 | void Label::patch_instructions(MacroAssembler* masm) { |
177 | assert(is_bound(), "Label is bound" ); |
178 | CodeBuffer* cb = masm->code(); |
179 | int target_sect = CodeBuffer::locator_sect(loc()); |
180 | address target = cb->locator_address(loc()); |
181 | while (_patch_index > 0) { |
182 | --_patch_index; |
183 | int branch_loc; |
184 | int line = 0; |
185 | const char* file = NULL; |
186 | if (_patch_index >= PatchCacheSize) { |
187 | branch_loc = _patch_overflow->pop(); |
188 | } else { |
189 | branch_loc = _patches[_patch_index]; |
190 | #ifdef ASSERT |
191 | line = _lines[_patch_index]; |
192 | file = _files[_patch_index]; |
193 | #endif |
194 | } |
195 | int branch_sect = CodeBuffer::locator_sect(branch_loc); |
196 | address branch = cb->locator_address(branch_loc); |
197 | if (branch_sect == CodeBuffer::SECT_CONSTS) { |
198 | // The thing to patch is a constant word. |
199 | *(address*)branch = target; |
200 | continue; |
201 | } |
202 | |
203 | #ifdef ASSERT |
204 | // Cross-section branches only work if the |
205 | // intermediate section boundaries are frozen. |
206 | if (target_sect != branch_sect) { |
207 | for (int n = MIN2(target_sect, branch_sect), |
208 | nlimit = (target_sect + branch_sect) - n; |
209 | n < nlimit; n++) { |
210 | CodeSection* cs = cb->code_section(n); |
211 | assert(cs->is_frozen(), "cross-section branch needs stable offsets" ); |
212 | } |
213 | } |
214 | #endif //ASSERT |
215 | |
216 | // Push the target offset into the branch instruction. |
217 | masm->pd_patch_instruction(branch, target, file, line); |
218 | } |
219 | } |
220 | |
221 | struct DelayedConstant { |
222 | typedef void (*value_fn_t)(); |
223 | BasicType type; |
224 | intptr_t value; |
225 | value_fn_t value_fn; |
226 | // This limit of 20 is generous for initial uses. |
227 | // The limit needs to be large enough to store the field offsets |
228 | // into classes which do not have statically fixed layouts. |
229 | // (Initial use is for method handle object offsets.) |
230 | // Look for uses of "delayed_value" in the source code |
231 | // and make sure this number is generous enough to handle all of them. |
232 | enum { DC_LIMIT = 20 }; |
233 | static DelayedConstant delayed_constants[DC_LIMIT]; |
234 | static DelayedConstant* add(BasicType type, value_fn_t value_fn); |
235 | bool match(BasicType t, value_fn_t cfn) { |
236 | return type == t && value_fn == cfn; |
237 | } |
238 | static void update_all(); |
239 | }; |
240 | |
241 | DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT]; |
242 | // Default C structure initialization rules have the following effect here: |
243 | // = { { (BasicType)0, (intptr_t)NULL }, ... }; |
244 | |
245 | DelayedConstant* DelayedConstant::add(BasicType type, |
246 | DelayedConstant::value_fn_t cfn) { |
247 | for (int i = 0; i < DC_LIMIT; i++) { |
248 | DelayedConstant* dcon = &delayed_constants[i]; |
249 | if (dcon->match(type, cfn)) |
250 | return dcon; |
251 | if (dcon->value_fn == NULL) { |
252 | dcon->value_fn = cfn; |
253 | dcon->type = type; |
254 | return dcon; |
255 | } |
256 | } |
257 | // If this assert is hit (in pre-integration testing!) then re-evaluate |
258 | // the comment on the definition of DC_LIMIT. |
259 | guarantee(false, "too many delayed constants" ); |
260 | return NULL; |
261 | } |
262 | |
263 | void DelayedConstant::update_all() { |
264 | for (int i = 0; i < DC_LIMIT; i++) { |
265 | DelayedConstant* dcon = &delayed_constants[i]; |
266 | if (dcon->value_fn != NULL && dcon->value == 0) { |
267 | typedef int (*int_fn_t)(); |
268 | typedef address (*address_fn_t)(); |
269 | switch (dcon->type) { |
270 | case T_INT: dcon->value = (intptr_t) ((int_fn_t) dcon->value_fn)(); break; |
271 | case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break; |
272 | default: break; |
273 | } |
274 | } |
275 | } |
276 | } |
277 | |
278 | RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) { |
279 | intptr_t val = (intptr_t) (*value_fn)(); |
280 | if (val != 0) return val + offset; |
281 | return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); |
282 | } |
283 | RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) { |
284 | intptr_t val = (intptr_t) (*value_fn)(); |
285 | if (val != 0) return val + offset; |
286 | return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset); |
287 | } |
288 | intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) { |
289 | DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn); |
290 | return &dcon->value; |
291 | } |
292 | intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) { |
293 | DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn); |
294 | return &dcon->value; |
295 | } |
296 | void AbstractAssembler::update_delayed_values() { |
297 | DelayedConstant::update_all(); |
298 | } |
299 | |
300 | void AbstractAssembler::(const char* ) { |
301 | if (sect() == CodeBuffer::SECT_INSTS) { |
302 | code_section()->outer()->block_comment(offset(), comment); |
303 | } |
304 | } |
305 | |
306 | const char* AbstractAssembler::code_string(const char* str) { |
307 | if (sect() == CodeBuffer::SECT_INSTS || sect() == CodeBuffer::SECT_STUBS) { |
308 | return code_section()->outer()->code_string(str); |
309 | } |
310 | return NULL; |
311 | } |
312 | |
313 | bool MacroAssembler::uses_implicit_null_check(void* address) { |
314 | // Exception handler checks the nmethod's implicit null checks table |
315 | // only when this method returns false. |
316 | intptr_t int_address = reinterpret_cast<intptr_t>(address); |
317 | intptr_t = Universe::heap()->cell_header_size(); |
318 | size_t region_size = os::vm_page_size() + cell_header_size; |
319 | #ifdef _LP64 |
320 | if (UseCompressedOops && CompressedOops::base() != NULL) { |
321 | // A SEGV can legitimately happen in C2 code at address |
322 | // (heap_base + offset) if Matcher::narrow_oop_use_complex_address |
323 | // is configured to allow narrow oops field loads to be implicitly |
324 | // null checked |
325 | intptr_t start = ((intptr_t)CompressedOops::base()) - cell_header_size; |
326 | intptr_t end = start + region_size; |
327 | if (int_address >= start && int_address < end) { |
328 | return true; |
329 | } |
330 | } |
331 | #endif |
332 | intptr_t start = -cell_header_size; |
333 | intptr_t end = start + region_size; |
334 | return int_address >= start && int_address < end; |
335 | } |
336 | |
337 | bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { |
338 | // The offset -1 is used (hardcoded) in a number of places in C1 and MacroAssembler |
339 | // to indicate an unknown offset. For example, TemplateTable::pop_and_check_object(Register r) |
340 | // calls MacroAssembler::null_check(Register reg, int offset = -1) which gets here |
341 | // with -1. Another example is GraphBuilder::access_field(...) which uses -1 as placeholder |
342 | // for offsets to be patched in later. The -1 there means the offset is not yet known |
343 | // and may lie outside of the zero-trapping page, and thus we need to ensure we're forcing |
344 | // an explicit null check for -1, even if it may otherwise be in the range |
345 | // [-cell_header_size, os::vm_page_size). |
346 | // TODO: Find and replace all relevant uses of -1 with a reasonably named constant. |
347 | if (offset == -1) return true; |
348 | |
349 | // Check if offset is outside of [-cell_header_size, os::vm_page_size) |
350 | return offset < -Universe::heap()->cell_header_size() || |
351 | offset >= os::vm_page_size(); |
352 | } |
353 | |