/*
* 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_linux.h"
#include "memory/allocation.inline.hpp"
#include "mutex_linux.inline.hpp"
#include "nativeInst_sparc.hpp"
#include "os_share_linux.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_linux.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
// different between 32 and 64 bits
#ifdef _LP64
#else
#endif
// those are to reference registers in sigcontext
enum {
CON_G0 = 0,
};
}
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF.
// os::Solaris::fetch_frame_from_ucontext() tries to skip nested
// signal frames. Currently we don't do that on Linux, so it's the
// same as os::fetch_frame_from_context().
ucontext_t* uc,
}
if (ret_sp) {
}
if (ret_fp) {
}
} else {
// construct empty ExtendedPC for return value checking
if (ret_sp) {
}
if (ret_fp) {
}
}
return epc;
}
}
}
// stack is not walkable
} else {
}
}
}
// initial thread needs special handling because pthread_getattr_np()
// may return bogus value.
} else {
// JVM needs to know exact stack location, abort if it fails
if (rslt != 0) {
vm_exit_out_of_memory(0, "pthread_getattr_np");
} else {
}
}
fatal("Can not locate current stack attributes!");
}
}
}
}
// stack size includes normal stack and HotSpot guard pages
return size;
}
char* os::non_memory_address_word() {
// 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;
}
// 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
}
}
return (intptr_t*)
}
// not used on Sparc
return NULL;
}
// Utility functions
extern "C" void Fetch32PFI();
extern "C" void Fetch32Resume();
extern "C" void FetchNPFI();
extern "C" void FetchNResume();
return true;
}
return true;
}
return false;
}
// check if fault address is within thread stack
// stack overflow
// Throw a stack overflow exception. Guard pages will be reenabled
// while unwinding the stack.
*stub =
pc,
} 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.
// This is a likely cause, but hard to verify. Let's just print
// it as a hint.
"enabled executable stack (see man page execstack(8))");
} else {
// Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when
// current thread was created by user code with MAP_GROWSDOWN flag
// and then attached to VM. See notes in os_linux.cpp.
return true;
}
} else {
fatal("recursive segv. expanding stack.");
}
}
}
return false;
}
return true;
}
return false;
}
// 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.
return true;
}
return false;
}
warning("fixed up memory fault in +VerifyOops at address "
return true;
}
return false;
}
*stub =
pc,
return true;
}
return false;
}
// Determination of interpreter/vtable stub/compiled code null
// exception
*stub =
return true;
}
return false;
}
return true;
}
return false;
}
}
// 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).
return true;
}
return false;
}
#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).
return true;
}
#endif // COMPILER2
return false;
}
extern "C" JNIEXPORT int
void* ucVoid,
int abort_if_unrecognized) {
// in fact this isn't ucontext_t* at all, but struct sigcontext*
// but Linux porting layer uses ucontext_t, so to minimize code change
// we cast as needed
SignalHandlerMark shm(t);
// then restore certain signal handler (e.g. to temporarily block SIGPIPE,
// or have a SIGILL handler when detecting CPU type). When that happens,
// avoid unnecessary crash when libjsig is not preloaded, try handle signals
// allow chained handler to go first
return true;
} else {
warning("Ignoring %s - see bugs 4229104 or 646499219",
}
return true;
}
}
if (t != NULL ){
if(t->is_Java_thread()) {
thread = (JavaThread*)t;
}
else if(t->is_VM_thread()){
}
}
}
// decide if this trap can be handled by a stub
//%note os_trap_1
// 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 we can just return to retry the write.
// Block current thread until the memory serialize page permission restored.
return 1;
}
return 1;
}
// Handle ALL stack overflow variations here
return 1;
}
}
thread->doing_unsafe_access()) {
}
do {
// Java thread running in Java code => find exception handler if any
// a fault inside compiled code, the interpreter, or a stub
break;
}
break;
}
break;
}
break;
}
break;
}
break;
}
break;
}
} while (0);
// 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.
}
}
// save all thread context in case we need to restore it
return true;
}
}
// signal-chaining
return true;
}
if (!abort_if_unrecognized) {
// caller wants another chance, so give it to him
return false;
}
}
// unmask current signal
}
// Nothing to do
}
return 0;
}
// nothing
}
#ifdef _LP64
return true;
#else
if (bytes < 2 * G) {
return true;
}
}
#endif // _LP64
}
///////////////////////////////////////////////////////////////////////////////
// thread stack
// pthread on Ubuntu is always in floating stack mode
// return default stack size for thr_type
// default stack size (compiler thread needs larger stack)
return s;
}
// Creating guard page is very expensive. Java thread has HotSpot
// guard page, only enable glibc guard page for non-Java threads.
}
#ifndef PRODUCT
}
#endif