Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
64440 views
1
/*
2
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
// no precompiled headers
27
#include "jvm.h"
28
#include "asm/assembler.inline.hpp"
29
#include "classfile/vmSymbols.hpp"
30
#include "code/icBuffer.hpp"
31
#include "code/vtableStubs.hpp"
32
#include "interpreter/interpreter.hpp"
33
#include "memory/allocation.inline.hpp"
34
#include "nativeInst_zero.hpp"
35
#include "os_share_linux.hpp"
36
#include "prims/jniFastGetField.hpp"
37
#include "prims/jvm_misc.hpp"
38
#include "runtime/arguments.hpp"
39
#include "runtime/frame.inline.hpp"
40
#include "runtime/interfaceSupport.inline.hpp"
41
#include "runtime/java.hpp"
42
#include "runtime/javaCalls.hpp"
43
#include "runtime/mutexLocker.hpp"
44
#include "runtime/osThread.hpp"
45
#include "runtime/sharedRuntime.hpp"
46
#include "runtime/stubRoutines.hpp"
47
#include "runtime/thread.inline.hpp"
48
#include "runtime/timer.hpp"
49
#include "signals_posix.hpp"
50
#include "utilities/align.hpp"
51
#include "utilities/events.hpp"
52
#include "utilities/vmError.hpp"
53
54
address os::current_stack_pointer() {
55
// return the address of the current function
56
return (address)__builtin_frame_address(0);
57
}
58
59
frame os::get_sender_for_C_frame(frame* fr) {
60
ShouldNotCallThis();
61
return frame(NULL, NULL); // silence compile warning.
62
}
63
64
frame os::current_frame() {
65
// The only thing that calls this is the stack printing code in
66
// VMError::report:
67
// - Step 110 (printing stack bounds) uses the sp in the frame
68
// to determine the amount of free space on the stack. We
69
// set the sp to a close approximation of the real value in
70
// order to allow this step to complete.
71
// - Step 120 (printing native stack) tries to walk the stack.
72
// The frame we create has a NULL pc, which is ignored as an
73
// invalid frame.
74
frame dummy = frame();
75
dummy.set_sp((intptr_t *) current_stack_pointer());
76
return dummy;
77
}
78
79
char* os::non_memory_address_word() {
80
// Must never look like an address returned by reserve_memory,
81
// even in its subfields (as defined by the CPU immediate fields,
82
// if the CPU splits constants across multiple instructions).
83
// This is the value for x86; works pretty well for PPC too.
84
return (char *) -1;
85
}
86
87
address os::Posix::ucontext_get_pc(const ucontext_t* uc) {
88
ShouldNotCallThis();
89
return NULL; // silence compile warnings
90
}
91
92
void os::Posix::ucontext_set_pc(ucontext_t * uc, address pc) {
93
ShouldNotCallThis();
94
}
95
96
address os::fetch_frame_from_context(const void* ucVoid,
97
intptr_t** ret_sp,
98
intptr_t** ret_fp) {
99
ShouldNotCallThis();
100
return NULL; // silence compile warnings
101
}
102
103
frame os::fetch_frame_from_context(const void* ucVoid) {
104
ShouldNotCallThis();
105
return frame(NULL, NULL); // silence compile warnings
106
}
107
108
bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
109
ucontext_t* uc, JavaThread* thread) {
110
111
if (info != NULL && thread != NULL) {
112
// Handle ALL stack overflow variations here
113
if (sig == SIGSEGV) {
114
address addr = (address) info->si_addr;
115
116
// check if fault address is within thread stack
117
if (thread->is_in_full_stack(addr)) {
118
StackOverflow* overflow_state = thread->stack_overflow_state();
119
// stack overflow
120
if (overflow_state->in_stack_yellow_reserved_zone(addr)) {
121
overflow_state->disable_stack_yellow_reserved_zone();
122
ShouldNotCallThis();
123
}
124
else if (overflow_state->in_stack_red_zone(addr)) {
125
overflow_state->disable_stack_red_zone();
126
ShouldNotCallThis();
127
}
128
else {
129
// Accessing stack address below sp may cause SEGV if
130
// current thread has MAP_GROWSDOWN stack. This should
131
// only happen when current thread was created by user
132
// code with MAP_GROWSDOWN flag and then attached to VM.
133
// See notes in os_linux.cpp.
134
if (thread->osthread()->expanding_stack() == 0) {
135
thread->osthread()->set_expanding_stack();
136
if (os::Linux::manually_expand_stack(thread, addr)) {
137
thread->osthread()->clear_expanding_stack();
138
return true;
139
}
140
thread->osthread()->clear_expanding_stack();
141
}
142
else {
143
fatal("recursive segv. expanding stack.");
144
}
145
}
146
}
147
}
148
149
/*if (thread->thread_state() == _thread_in_Java) {
150
ShouldNotCallThis();
151
}
152
else*/ if ((thread->thread_state() == _thread_in_vm ||
153
thread->thread_state() == _thread_in_native) &&
154
sig == SIGBUS && thread->doing_unsafe_access()) {
155
ShouldNotCallThis();
156
}
157
158
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC
159
// kicks in and the heap gets shrunk before the field access.
160
/*if (sig == SIGSEGV || sig == SIGBUS) {
161
address addr = JNI_FastGetField::find_slowcase_pc(pc);
162
if (addr != (address)-1) {
163
stub = addr;
164
}
165
}*/
166
}
167
168
return false; // Fatal error
169
170
}
171
172
void os::Linux::init_thread_fpu_state(void) {
173
// Nothing to do
174
}
175
176
int os::Linux::get_fpu_control_word() {
177
ShouldNotCallThis();
178
return -1; // silence compile warnings
179
}
180
181
void os::Linux::set_fpu_control_word(int fpu) {
182
ShouldNotCallThis();
183
}
184
185
///////////////////////////////////////////////////////////////////////////////
186
// thread stack
187
188
size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K;
189
size_t os::Posix::_java_thread_min_stack_allowed = 64 * K;
190
size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K;
191
192
size_t os::Posix::default_stack_size(os::ThreadType thr_type) {
193
#ifdef _LP64
194
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
195
#else
196
size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
197
#endif // _LP64
198
return s;
199
}
200
201
static void current_stack_region(address *bottom, size_t *size) {
202
if (os::is_primordial_thread()) {
203
// primordial thread needs special handling because pthread_getattr_np()
204
// may return bogus value.
205
address stack_bottom = os::Linux::initial_thread_stack_bottom();
206
size_t stack_bytes = os::Linux::initial_thread_stack_size();
207
208
assert(os::current_stack_pointer() >= stack_bottom, "should do");
209
assert(os::current_stack_pointer() < stack_bottom + stack_bytes, "should do");
210
211
*bottom = stack_bottom;
212
*size = stack_bytes;
213
return;
214
}
215
216
pthread_attr_t attr;
217
int res = pthread_getattr_np(pthread_self(), &attr);
218
if (res != 0) {
219
if (res == ENOMEM) {
220
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
221
}
222
else {
223
fatal("pthread_getattr_np failed with error = %d", res);
224
}
225
}
226
227
address stack_bottom;
228
size_t stack_bytes;
229
res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
230
if (res != 0) {
231
fatal("pthread_attr_getstack failed with error = %d", res);
232
}
233
address stack_top = stack_bottom + stack_bytes;
234
235
// The block of memory returned by pthread_attr_getstack() includes
236
// guard pages where present. We need to trim these off.
237
size_t page_bytes = os::Linux::page_size();
238
assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
239
240
size_t guard_bytes;
241
res = pthread_attr_getguardsize(&attr, &guard_bytes);
242
if (res != 0) {
243
fatal("pthread_attr_getguardsize failed with errno = %d", res);
244
}
245
int guard_pages = align_up(guard_bytes, page_bytes) / page_bytes;
246
assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
247
248
#ifdef IA64
249
// IA64 has two stacks sharing the same area of memory, a normal
250
// stack growing downwards and a register stack growing upwards.
251
// Guard pages, if present, are in the centre. This code splits
252
// the stack in two even without guard pages, though in theory
253
// there's nothing to stop us allocating more to the normal stack
254
// or more to the register stack if one or the other were found
255
// to grow faster.
256
int total_pages = align_down(stack_bytes, page_bytes) / page_bytes;
257
stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
258
#endif // IA64
259
260
stack_bottom += guard_bytes;
261
262
pthread_attr_destroy(&attr);
263
264
assert(os::current_stack_pointer() >= stack_bottom, "should do");
265
assert(os::current_stack_pointer() < stack_top, "should do");
266
267
*bottom = stack_bottom;
268
*size = stack_top - stack_bottom;
269
}
270
271
address os::current_stack_base() {
272
address bottom;
273
size_t size;
274
current_stack_region(&bottom, &size);
275
return bottom + size;
276
}
277
278
size_t os::current_stack_size() {
279
// stack size includes normal stack and HotSpot guard pages
280
address bottom;
281
size_t size;
282
current_stack_region(&bottom, &size);
283
return size;
284
}
285
286
/////////////////////////////////////////////////////////////////////////////
287
// helper functions for fatal error handler
288
289
void os::print_context(outputStream* st, const void* context) {
290
ShouldNotCallThis();
291
}
292
293
void os::print_register_info(outputStream *st, const void *context) {
294
ShouldNotCallThis();
295
}
296
297
/////////////////////////////////////////////////////////////////////////////
298
// Stubs for things that would be in linux_zero.s if it existed.
299
// You probably want to disassemble these monkeys to check they're ok.
300
301
extern "C" {
302
int SpinPause() {
303
return -1; // silence compile warnings
304
}
305
306
307
void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) {
308
if (from > to) {
309
const jshort *end = from + count;
310
while (from < end)
311
*(to++) = *(from++);
312
}
313
else if (from < to) {
314
const jshort *end = from;
315
from += count - 1;
316
to += count - 1;
317
while (from >= end)
318
*(to--) = *(from--);
319
}
320
}
321
void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) {
322
if (from > to) {
323
const jint *end = from + count;
324
while (from < end)
325
*(to++) = *(from++);
326
}
327
else if (from < to) {
328
const jint *end = from;
329
from += count - 1;
330
to += count - 1;
331
while (from >= end)
332
*(to--) = *(from--);
333
}
334
}
335
void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) {
336
if (from > to) {
337
const jlong *end = from + count;
338
while (from < end)
339
os::atomic_copy64(from++, to++);
340
}
341
else if (from < to) {
342
const jlong *end = from;
343
from += count - 1;
344
to += count - 1;
345
while (from >= end)
346
os::atomic_copy64(from--, to--);
347
}
348
}
349
350
void _Copy_arrayof_conjoint_bytes(const HeapWord* from,
351
HeapWord* to,
352
size_t count) {
353
memmove(to, from, count);
354
}
355
void _Copy_arrayof_conjoint_jshorts(const HeapWord* from,
356
HeapWord* to,
357
size_t count) {
358
memmove(to, from, count * 2);
359
}
360
void _Copy_arrayof_conjoint_jints(const HeapWord* from,
361
HeapWord* to,
362
size_t count) {
363
memmove(to, from, count * 4);
364
}
365
void _Copy_arrayof_conjoint_jlongs(const HeapWord* from,
366
HeapWord* to,
367
size_t count) {
368
memmove(to, from, count * 8);
369
}
370
};
371
372
/////////////////////////////////////////////////////////////////////////////
373
// Implementations of atomic operations not supported by processors.
374
// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html
375
376
#ifndef _LP64
377
extern "C" {
378
long long unsigned int __sync_val_compare_and_swap_8(
379
volatile void *ptr,
380
long long unsigned int oldval,
381
long long unsigned int newval) {
382
ShouldNotCallThis();
383
return 0; // silence compiler warnings
384
}
385
};
386
#endif // !_LP64
387
388
#ifndef PRODUCT
389
void os::verify_stack_alignment() {
390
}
391
#endif
392
393
int os::extra_bang_size_in_bytes() {
394
// Zero does not require an additional stack banging.
395
return 0;
396
}
397
398