author | chegar |
Thu, 17 Oct 2019 20:54:25 +0100 | |
branch | datagramsocketimpl-branch |
changeset 58679 | 9c3209ff7550 |
parent 58678 | 9cf78a70fa4f |
parent 57514 | 9b6d4e64778c |
permissions | -rw-r--r-- |
1 | 1 |
/* |
46630
75aa3e39d02c
8182299: Enable disabled clang warnings, build on OSX 10 + Xcode 8
jwilhelm
parents:
41685
diff
changeset
|
2 |
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
1 | 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 |
* |
|
5547
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
5403
diff
changeset
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
5403
diff
changeset
|
20 |
* or visit www.oracle.com if you need additional information or have any |
f4b087cbb361
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
5403
diff
changeset
|
21 |
* questions. |
1 | 22 |
* |
23 |
*/ |
|
24 |
||
7397 | 25 |
#include "precompiled.hpp" |
35201
996db89f378e
8139864: Improve handling of stack protection zones.
goetz
parents:
33105
diff
changeset
|
26 |
#include "asm/codeBuffer.hpp" |
14626
0cf4eccf130f
8003240: x86: move MacroAssembler into separate file
twisti
parents:
14625
diff
changeset
|
27 |
#include "asm/macroAssembler.hpp" |
0cf4eccf130f
8003240: x86: move MacroAssembler into separate file
twisti
parents:
14625
diff
changeset
|
28 |
#include "asm/macroAssembler.inline.hpp" |
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
29 |
#include "gc/shared/collectedHeap.hpp" |
54786 | 30 |
#include "memory/universe.hpp" |
54780
f8d182aedc92
8223136: Move compressed oops functions to CompressedOops class
stefank
parents:
52559
diff
changeset
|
31 |
#include "oops/compressedOops.hpp" |
40655
9f644073d3a0
8157907: Incorrect inclusion of atomic.hpp instead of atomic.inline.hpp
dholmes
parents:
35201
diff
changeset
|
32 |
#include "runtime/atomic.hpp" |
7397 | 33 |
#include "runtime/icache.hpp" |
34 |
#include "runtime/os.hpp" |
|
35201
996db89f378e
8139864: Improve handling of stack protection zones.
goetz
parents:
33105
diff
changeset
|
35 |
#include "runtime/thread.hpp" |
1 | 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. |
|
2131 | 43 |
// The code buffer is updated via set_code_end(...) after emitting a whole instruction. |
1 | 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 |
|
14625
b02f361c324e
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
14624
diff
changeset
|
49 |
if (cs->start() == NULL) { |
33105
294e48b4f704
8080775: Better argument formatting for assert() and friends
david
parents:
25351
diff
changeset
|
50 |
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "CodeCache: no room for %s", code->name()); |
1 | 51 |
} |
14625
b02f361c324e
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
14624
diff
changeset
|
52 |
_code_section = cs; |
b02f361c324e
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
14624
diff
changeset
|
53 |
_oop_recorder= code->oop_recorder(); |
b02f361c324e
8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents:
14624
diff
changeset
|
54 |
DEBUG_ONLY( _short_branch_delta = 0; ) |
1 | 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(); |
|
14624 | 88 |
assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?"); |
1 | 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 |
|
14624 | 104 |
// in section cs (insts or stubs). |
105 |
void AbstractAssembler::end_a_const(CodeSection* cs) { |
|
1 | 106 |
assert(_code_section == code()->consts(), "not in consts?"); |
14624 | 107 |
set_code_section(cs); |
1 | 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 |
||
24425 | 124 |
void AbstractAssembler::generate_stack_overflow_check(int frame_size_in_bytes) { |
1 | 125 |
if (UseStackBanging) { |
126 |
// Each code entry causes one stack bang n pages down the stack where n |
|
21528
479228ecf6ac
8026775: nsk/jvmti/RedefineClasses/StressRedefine crashes due to EXCEPTION_ACCESS_VIOLATION
mikael
parents:
17087
diff
changeset
|
127 |
// is configurable by StackShadowPages. The setting depends on the maximum |
1 | 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(); |
|
35201
996db89f378e
8139864: Improve handling of stack protection zones.
goetz
parents:
33105
diff
changeset
|
139 |
int bang_end = (int)JavaThread::stack_shadow_zone_size(); |
1 | 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 |
||
51633
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
157 |
void Label::add_patch_at(CodeBuffer* cb, int branch_loc, const char* file, int line) { |
1 | 158 |
assert(_loc == -1, "Label is unbound"); |
41685 | 159 |
// Don't add patch locations during scratch emit. |
160 |
if (cb->insts()->scratch_emit()) { return; } |
|
1 | 161 |
if (_patch_index < PatchCacheSize) { |
162 |
_patches[_patch_index] = branch_loc; |
|
51633
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
163 |
#ifdef ASSERT |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
164 |
_lines[_patch_index] = line; |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
165 |
_files[_patch_index] = file; |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
166 |
#endif |
1 | 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; |
|
51633
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
184 |
int line = 0; |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
185 |
const char* file = NULL; |
1 | 186 |
if (_patch_index >= PatchCacheSize) { |
187 |
branch_loc = _patch_overflow->pop(); |
|
188 |
} else { |
|
189 |
branch_loc = _patches[_patch_index]; |
|
51633
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
190 |
#ifdef ASSERT |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
191 |
line = _lines[_patch_index]; |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
192 |
file = _files[_patch_index]; |
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
193 |
#endif |
1 | 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. |
|
51633
21154cb84d2a
8209594: guarantee(this->is8bit(imm8)) failed: Short forward jump exceeds 8-bit offset
kvn
parents:
47634
diff
changeset
|
217 |
masm->pd_patch_instruction(branch, target, file, line); |
1 | 218 |
} |
219 |
} |
|
220 |
||
221 |
void AbstractAssembler::block_comment(const char* comment) { |
|
222 |
if (sect() == CodeBuffer::SECT_INSTS) { |
|
223 |
code_section()->outer()->block_comment(offset(), comment); |
|
224 |
} |
|
225 |
} |
|
226 |
||
16368
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
227 |
const char* AbstractAssembler::code_string(const char* str) { |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
228 |
if (sect() == CodeBuffer::SECT_INSTS || sect() == CodeBuffer::SECT_STUBS) { |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
229 |
return code_section()->outer()->code_string(str); |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
230 |
} |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
231 |
return NULL; |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
232 |
} |
713209c45a82
8008555: Debugging code in compiled method sometimes leaks memory
roland
parents:
14837
diff
changeset
|
233 |
|
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
234 |
bool MacroAssembler::uses_implicit_null_check(void* address) { |
823
9a5271881bc0
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
1
diff
changeset
|
235 |
// Exception handler checks the nmethod's implicit null checks table |
9a5271881bc0
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
1
diff
changeset
|
236 |
// only when this method returns false. |
55425
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
237 |
uintptr_t addr = reinterpret_cast<uintptr_t>(address); |
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
238 |
uintptr_t page_size = (uintptr_t)os::vm_page_size(); |
2254
f13dda645a4b
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
2148
diff
changeset
|
239 |
#ifdef _LP64 |
54780
f8d182aedc92
8223136: Move compressed oops functions to CompressedOops class
stefank
parents:
52559
diff
changeset
|
240 |
if (UseCompressedOops && CompressedOops::base() != NULL) { |
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
241 |
// A SEGV can legitimately happen in C2 code at address |
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
242 |
// (heap_base + offset) if Matcher::narrow_oop_use_complex_address |
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
243 |
// is configured to allow narrow oops field loads to be implicitly |
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
244 |
// null checked |
55425
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
245 |
uintptr_t start = (uintptr_t)CompressedOops::base(); |
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
246 |
uintptr_t end = start + page_size; |
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
247 |
if (addr >= start && addr < end) { |
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
248 |
return true; |
823
9a5271881bc0
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
1
diff
changeset
|
249 |
} |
9a5271881bc0
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
1
diff
changeset
|
250 |
} |
2254
f13dda645a4b
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
2148
diff
changeset
|
251 |
#endif |
55425
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
252 |
return addr < page_size; |
823
9a5271881bc0
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
1
diff
changeset
|
253 |
} |
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
254 |
|
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
255 |
bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { |
52559
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
256 |
// The offset -1 is used (hardcoded) in a number of places in C1 and MacroAssembler |
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
257 |
// to indicate an unknown offset. For example, TemplateTable::pop_and_check_object(Register r) |
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
258 |
// calls MacroAssembler::null_check(Register reg, int offset = -1) which gets here |
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
259 |
// with -1. Another example is GraphBuilder::access_field(...) which uses -1 as placeholder |
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
260 |
// for offsets to be patched in later. The -1 there means the offset is not yet known |
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
261 |
// and may lie outside of the zero-trapping page, and thus we need to ensure we're forcing |
55425
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
262 |
// an explicit null check for -1. |
52559
f642ede2eb07
8213795: Force explicit null check on patching placeholder offset
rkennke
parents:
52462
diff
changeset
|
263 |
|
55425
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
264 |
// Check if offset is outside of [0, os::vm_page_size()] |
7cf925f385fe
8225779: Remove unused CollectedHeap::cell_header_size()
pliden
parents:
54786
diff
changeset
|
265 |
return offset < 0 || offset >= os::vm_page_size(); |
52462
4ad404da0088
8213199: GC abstraction for Assembler::needs_explicit_null_check()
rkennke
parents:
51633
diff
changeset
|
266 |
} |