/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
// no precompiled headers
#include "assembler_sparc.inline.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
#include "jvm_solaris.h"
#include "memory/allocation.inline.hpp"
#include "mutex_solaris.inline.hpp"
#include "nativeInst_sparc.hpp"
#include "os_share_solaris.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "thread_solaris.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
# include <signal.h> // needed first to avoid name collision for "std" with SC 5.0
// put OS-includes here
# include <pthread.h>
# include <errno.h>
# include <dlfcn.h>
# include <stdio.h>
# include <unistd.h>
# include <sys/resource.h>
# include <thread.h>
# include <sys/systeminfo.h>
# include <pwd.h>
# include <poll.h>
// Minimum stack size for the VM. It's easier to document a constant
// but it's different for x86 and sparc because the page sizes are different.
#ifdef _LP64
#else
#endif
// We should detect this at run time. For now, filling
// in with a constant.
return 8;
}
int i;
for(i=0; i<restore_count; i++) {
}
}
// Must never look like an address returned by reserve_memory,
// even in its subfields (as defined by the CPU immediate fields,
// if the CPU splits constants across multiple instructions).
// On SPARC, 0 != %hi(any real address), because there is no
// allocation in the first 1Kb of the virtual address space.
return (char*) 0;
}
// Validate a ucontext retrieved from walking a uc_link of a ucontext.
// There are issues with libthread giving out uc_links for different threads
// on the same uc_link chain and bad or circular links.
//
return false;
}
if (thread->is_Java_thread()) {
return false;
}
return false;
}
}
return true;
}
// We will only follow one level of uc_link since there are libthread
// issues with ucontext linking and it is better to be safe and just
// let caller retry later.
ucontext_t *uc) {
// Sometimes the topmost register windows are not properly flushed.
// i.e., if the kernel would have needed to take a page fault
}
// cannot validate without uc_link so accept current ucontext
// first ucontext is valid so try the next one
// cannot validate without uc_link so accept current ucontext
// the ucontext one level down is also valid so return it
}
}
}
return retuc;
}
// Assumes ucontext is valid
// set npc to zero to avoid using it for safepoint, good for profiling only
return ExtendedPC(pc);
}
// Assumes ucontext is valid
}
// Solaris X86 only
return NULL;
}
}
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
// is currently interrupted by SIGPROF.
//
// ret_fp parameter is only used by Solaris X86.
//
// The difference between this and os::fetch_frame_from_context() is that
// here we try to skip nested signal frames.
}
// ret_fp parameter is only used by Solaris X86.
} else {
// construct empty ExtendedPC for return value checking
}
return epc;
}
}
}
// Returns an estimate of the current stack pointer. Result must be guaranteed to
// point into the calling threads stack, and be no lower than the current stack
// pointer.
volatile int dummy;
return sp;
}
// stack is not walkable
} else {
}
}
static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
return (err);
*lwp);
perror("thr_mutator_status: open lwpstatus");
return (EINVAL);
}
sizeof (lwpstatus_t)) {
perror("thr_mutator_status: read lwpstatus");
return (EINVAL);
}
}
return (0);
}
#ifdef _LP64
return true;
#else
#endif
}
extern "C" void Fetch32PFI () ;
extern "C" void Fetch32Resume () ;
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
extern "C" JNIEXPORT int
int abort_if_unrecognized) {
SignalHandlerMark shm(t);
return true;
} else {
warning("Ignoring %s - see 4229104 or 6499219",
}
return true;
}
}
if (t != NULL ){
if(t->is_Java_thread()) {
thread = (JavaThread*)t;
}
else if(t->is_VM_thread()){
}
}
}
guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
return true;
return true;
} else {
// If os::Solaris::SIGasync not chained, and this is a non-vm and
// non-java thread
return true;
}
}
// can't decode this kind of signal
} else {
}
// decide if this trap can be handled by a stub
//%note os_trap_1
// factor me: getPCfromContext
// SafeFetch() support
// Implemented with either a fixed set of addresses such
// as Fetch32*, or with Thread._OnTrap.
return true ;
}
return true ;
}
// Handle ALL stack overflow variations here
// Sometimes the register windows are not properly flushed.
}
// Throw a stack overflow exception. Guard pages will be reenabled
// while unwinding the stack.
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
} else {
// Thread was in the vm or native code. Return and try to finish.
return true;
}
// Fatal red zone violation. Disable the guard pages and fall through
// to handle_unexpected_exception way down below.
// Sometimes the register windows are not properly flushed.
}
}
}
}
}
// Java thread running in Java code => find exception handler if any
// a fault inside compiled code, the interpreter, or a stub
// Support Safepoint Polling
}
// Not needed on x86 solaris because verify_oops doesn't generate
}
// This is not factored because on x86 solaris the patching for
// zombies does not generate a SEGV.
// zombie method (ld [%g0],%o7 instruction)
// At the stub it needs to look like a call from the caller of this
// method (not a call from the segv site).
}
// BugId 4454115: A read from a MappedByteBuffer can fault
// here if the underlying file has been truncated.
// Do not crash the VM in such a case.
}
}
// integer divide by zero
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
}
// floating-point divide by zero
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
}
#ifdef COMPILER2
#ifdef ASSERT
#ifdef TIERED
#endif // TIERED
#endif // ASSERT
// Inline cache missed and user trap "Tne G0+ST_RESERVED_FOR_USER_0+2" taken.
// At the stub it needs to look like a call from the caller of this
// method (not a call from the segv site).
}
#endif // COMPILER2
else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
// Determination of interpreter/vtable stub/compiled code null exception
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
}
}
// jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
// and the heap gets shrunk before the field access.
}
}
// Check to see if we caught the safepoint code in the
// process of write protecting the memory serialization page.
// It write enables the page immediately after protecting it
// so just return.
// Block current thread until the memory serialize page permission restored.
return true;
}
}
// save all thread context in case we need to restore it
// simulate a branch to the stub (a "call" in the safepoint stub case)
// factor me: setPC
#ifndef PRODUCT
#endif /* PRODUCT */
return true;
}
// signal-chaining
return true;
}
if (!abort_if_unrecognized) {
// caller wants another chance, so give it to him
return false;
}
warning("Unexpected Signal %d occurred under user-defined signal handler " INTPTR_FORMAT, sig, (intptr_t)sighand);
}
}
}
// Sometimes the register windows are not properly flushed.
}
// unmask current signal
// Determine which sort of error to throw. Out of swap may signal
// on the thread stack, which could get a mapping error when touched.
vm_exit_out_of_memory(0, "Out of swap space to map in thread stack.");
}
}
// Note: it may be unsafe to inspect memory near pc. For example, pc may
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
}
// this is only for the "general purpose" registers
}
// Nothing needed on Sparc.
}
// These routines are the initial value of atomic_xchg_entry(),
// atomic_cmpxchg_entry(), atomic_add_entry() and fence_entry()
// until initialization is complete.
// TODO - remove when the VM drops support for V8.
// try to use the stub:
}
*dest = exchange_value;
return old_value;
}
// try to use the stub:
}
if (old_value == compare_value)
*dest = exchange_value;
return old_value;
}
jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
// try to use the stub:
cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry());
}
if (old_value == compare_value)
*dest = exchange_value;
return old_value;
}
// try to use the stub:
}
}
#endif // !_LP64 && !COMPILER2
// For compiler1 the architecture is v8 and frps isn't present in v8
}
#endif //defined(__sparc) && defined(COMPILER2)
#ifndef PRODUCT
}
#endif