mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8076185: Provide SafeFetchX implementation for zero
Implement SafeFetchX for zero using setjmp/longjmp and Posix TLS Reviewed-by: sgehwolf, dholmes
This commit is contained in:
parent
38c3337610
commit
1afbc04d56
4 changed files with 79 additions and 8 deletions
|
@ -45,6 +45,18 @@
|
|||
#include "opto/runtime.hpp"
|
||||
#endif
|
||||
|
||||
// For SafeFetch we need POSIX tls and setjmp
|
||||
#include <setjmp.h>
|
||||
#include <pthread.h>
|
||||
static pthread_key_t g_jmpbuf_key;
|
||||
|
||||
// return the currently active jump buffer for this thread
|
||||
// - if there is any, NULL otherwise. Called from
|
||||
// zero signal handlers.
|
||||
extern sigjmp_buf* get_jmp_buf_for_continuation() {
|
||||
return (sigjmp_buf*) pthread_getspecific(g_jmpbuf_key);
|
||||
}
|
||||
|
||||
// Declaration and definition of StubGenerator (no .hpp file).
|
||||
// For a more detailed description of the stub routine structure
|
||||
// see the comment in stubRoutines.hpp
|
||||
|
@ -176,17 +188,55 @@ class StubGenerator: public StubCodeGenerator {
|
|||
StubRoutines::_oop_arraycopy;
|
||||
}
|
||||
|
||||
// NYI: SafeFetch for Zero isn't actually safe.
|
||||
static int SafeFetch32(int *adr, int errValue) {
|
||||
|
||||
// set up a jump buffer; anchor the pointer to the jump buffer in tls; then
|
||||
// do the pointer access. If pointer is invalid, we crash; in signal
|
||||
// handler, we retrieve pointer to jmp buffer from tls, and jump back.
|
||||
//
|
||||
// Note: the jump buffer itself - which can get pretty large depending on
|
||||
// the architecture - lives on the stack and that is fine, because we will
|
||||
// not rewind the stack: either we crash, in which case signal handler
|
||||
// frame is below us, or we don't crash, in which case it does not matter.
|
||||
sigjmp_buf jb;
|
||||
if (sigsetjmp(jb, 1)) {
|
||||
// we crashed. clean up tls and return default value.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
return errValue;
|
||||
} else {
|
||||
// preparation phase
|
||||
pthread_setspecific(g_jmpbuf_key, &jb);
|
||||
}
|
||||
|
||||
int value = errValue;
|
||||
value = *adr;
|
||||
|
||||
// all went well. clean tls.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
|
||||
|
||||
sigjmp_buf jb;
|
||||
if (sigsetjmp(jb, 1)) {
|
||||
// we crashed. clean up tls and return default value.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
return errValue;
|
||||
} else {
|
||||
// preparation phase
|
||||
pthread_setspecific(g_jmpbuf_key, &jb);
|
||||
}
|
||||
|
||||
intptr_t value = errValue;
|
||||
value = *adr;
|
||||
|
||||
// all went well. clean tls.
|
||||
pthread_setspecific(g_jmpbuf_key, NULL);
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
void generate_initial() {
|
||||
|
@ -241,6 +291,7 @@ class StubGenerator: public StubCodeGenerator {
|
|||
generate_arraycopy_stubs();
|
||||
|
||||
// Safefetch stubs.
|
||||
pthread_key_create(&g_jmpbuf_key, NULL);
|
||||
StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32);
|
||||
StubRoutines::_safefetch32_fault_pc = NULL;
|
||||
StubRoutines::_safefetch32_continuation_pc = NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue