never@1445: /* stefank@2314: * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. twisti@1611: * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. never@1445: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. never@1445: * never@1445: * This code is free software; you can redistribute it and/or modify it never@1445: * under the terms of the GNU General Public License version 2 only, as never@1445: * published by the Free Software Foundation. never@1445: * never@1445: * This code is distributed in the hope that it will be useful, but WITHOUT never@1445: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or never@1445: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License never@1445: * version 2 for more details (a copy is included in the LICENSE file that never@1445: * accompanied this code). never@1445: * never@1445: * You should have received a copy of the GNU General Public License version never@1445: * 2 along with this work; if not, write to the Free Software Foundation, never@1445: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. never@1445: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. never@1445: * never@1445: */ never@1445: stefank@2314: // no precompiled headers stefank@2314: #include "assembler_zero.inline.hpp" stefank@2314: #include "classfile/classLoader.hpp" stefank@2314: #include "classfile/systemDictionary.hpp" stefank@2314: #include "classfile/vmSymbols.hpp" stefank@2314: #include "code/icBuffer.hpp" stefank@2314: #include "code/vtableStubs.hpp" stefank@2314: #include "interpreter/interpreter.hpp" stefank@2314: #include "jvm_linux.h" stefank@2314: #include "memory/allocation.inline.hpp" stefank@2314: #include "mutex_linux.inline.hpp" stefank@2314: #include "nativeInst_zero.hpp" stefank@2314: #include "os_share_linux.hpp" stefank@2314: #include "prims/jniFastGetField.hpp" stefank@2314: #include "prims/jvm.h" stefank@2314: #include "prims/jvm_misc.hpp" stefank@2314: #include "runtime/arguments.hpp" stefank@2314: #include "runtime/extendedPC.hpp" stefank@2314: #include "runtime/frame.inline.hpp" stefank@2314: #include "runtime/interfaceSupport.hpp" stefank@2314: #include "runtime/java.hpp" stefank@2314: #include "runtime/javaCalls.hpp" stefank@2314: #include "runtime/mutexLocker.hpp" stefank@2314: #include "runtime/osThread.hpp" stefank@2314: #include "runtime/sharedRuntime.hpp" stefank@2314: #include "runtime/stubRoutines.hpp" stefank@2314: #include "runtime/timer.hpp" stefank@2314: #include "thread_linux.inline.hpp" stefank@2314: #include "utilities/events.hpp" stefank@2314: #include "utilities/vmError.hpp" stefank@2314: #ifdef COMPILER1 stefank@2314: #include "c1/c1_Runtime1.hpp" stefank@2314: #endif stefank@2314: #ifdef COMPILER2 stefank@2314: #include "opto/runtime.hpp" stefank@2314: #endif never@1445: never@1445: address os::current_stack_pointer() { never@1445: address dummy = (address) &dummy; never@1445: return dummy; never@1445: } never@1445: never@1445: frame os::get_sender_for_C_frame(frame* fr) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: frame os::current_frame() { never@1445: // The only thing that calls this is the stack printing code in never@1445: // VMError::report: never@1445: // - Step 110 (printing stack bounds) uses the sp in the frame never@1445: // to determine the amount of free space on the stack. We never@1445: // set the sp to a close approximation of the real value in never@1445: // order to allow this step to complete. never@1445: // - Step 120 (printing native stack) tries to walk the stack. never@1445: // The frame we create has a NULL pc, which is ignored as an never@1445: // invalid frame. never@1445: frame dummy = frame(); never@1445: dummy.set_sp((intptr_t *) current_stack_pointer()); never@1445: return dummy; never@1445: } never@1445: never@1445: char* os::non_memory_address_word() { never@1445: // Must never look like an address returned by reserve_memory, never@1445: // even in its subfields (as defined by the CPU immediate fields, never@1445: // if the CPU splits constants across multiple instructions). never@1445: #ifdef SPARC never@1445: // On SPARC, 0 != %hi(any real address), because there is no never@1445: // allocation in the first 1Kb of the virtual address space. never@1445: return (char *) 0; never@1445: #else never@1445: // This is the value for x86; works pretty well for PPC too. never@1445: return (char *) -1; never@1445: #endif // SPARC never@1445: } never@1445: never@1445: void os::initialize_thread() { never@1445: // Nothing to do. never@1445: } never@1445: never@1445: address os::Linux::ucontext_get_pc(ucontext_t* uc) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: ExtendedPC os::fetch_frame_from_context(void* ucVoid, never@1445: intptr_t** ret_sp, never@1445: intptr_t** ret_fp) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: frame os::fetch_frame_from_context(void* ucVoid) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: extern "C" int never@1445: JVM_handle_linux_signal(int sig, never@1445: siginfo_t* info, never@1445: void* ucVoid, never@1445: int abort_if_unrecognized) { never@1445: ucontext_t* uc = (ucontext_t*) ucVoid; never@1445: never@1445: Thread* t = ThreadLocalStorage::get_thread_slow(); never@1445: never@1445: SignalHandlerMark shm(t); never@1445: never@1445: // Note: it's not uncommon that JNI code uses signal/sigset to never@1445: // install then restore certain signal handler (e.g. to temporarily never@1445: // block SIGPIPE, or have a SIGILL handler when detecting CPU never@1445: // type). When that happens, JVM_handle_linux_signal() might be never@1445: // invoked with junk info/ucVoid. To avoid unnecessary crash when never@1445: // libjsig is not preloaded, try handle signals that do not require never@1445: // siginfo/ucontext first. never@1445: never@1445: if (sig == SIGPIPE || sig == SIGXFSZ) { never@1445: // allow chained handler to go first never@1445: if (os::Linux::chained_handler(sig, info, ucVoid)) { never@1445: return true; never@1445: } else { never@1445: if (PrintMiscellaneous && (WizardMode || Verbose)) { never@1445: char buf[64]; never@1445: warning("Ignoring %s - see bugs 4229104 or 646499219", never@1445: os::exception_name(sig, buf, sizeof(buf))); never@1445: } never@1445: return true; never@1445: } never@1445: } never@1445: never@1445: JavaThread* thread = NULL; never@1445: VMThread* vmthread = NULL; never@1445: if (os::Linux::signal_handlers_are_installed) { never@1445: if (t != NULL ){ never@1445: if(t->is_Java_thread()) { never@1445: thread = (JavaThread*)t; never@1445: } never@1445: else if(t->is_VM_thread()){ never@1445: vmthread = (VMThread *)t; never@1445: } never@1445: } never@1445: } never@1445: never@1445: if (info != NULL && thread != NULL) { never@1445: // Handle ALL stack overflow variations here never@1445: if (sig == SIGSEGV) { never@1445: address addr = (address) info->si_addr; never@1445: never@1445: // check if fault address is within thread stack never@1445: if (addr < thread->stack_base() && never@1445: addr >= thread->stack_base() - thread->stack_size()) { never@1445: // stack overflow never@1445: if (thread->in_stack_yellow_zone(addr)) { never@1445: thread->disable_stack_yellow_zone(); never@1445: ShouldNotCallThis(); never@1445: } never@1445: else if (thread->in_stack_red_zone(addr)) { never@1445: thread->disable_stack_red_zone(); never@1445: ShouldNotCallThis(); never@1445: } never@1445: else { never@1445: // Accessing stack address below sp may cause SEGV if never@1445: // current thread has MAP_GROWSDOWN stack. This should never@1445: // only happen when current thread was created by user never@1445: // code with MAP_GROWSDOWN flag and then attached to VM. never@1445: // See notes in os_linux.cpp. never@1445: if (thread->osthread()->expanding_stack() == 0) { never@1445: thread->osthread()->set_expanding_stack(); never@1445: if (os::Linux::manually_expand_stack(thread, addr)) { never@1445: thread->osthread()->clear_expanding_stack(); never@1445: return true; never@1445: } never@1445: thread->osthread()->clear_expanding_stack(); never@1445: } never@1445: else { never@1445: fatal("recursive segv. expanding stack."); never@1445: } never@1445: } never@1445: } never@1445: } never@1445: never@1445: /*if (thread->thread_state() == _thread_in_Java) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: else*/ if (thread->thread_state() == _thread_in_vm && never@1445: sig == SIGBUS && thread->doing_unsafe_access()) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: // jni_fast_GetField can trap at certain pc's if a GC never@1445: // kicks in and the heap gets shrunk before the field access. never@1445: /*if (sig == SIGSEGV || sig == SIGBUS) { never@1445: address addr = JNI_FastGetField::find_slowcase_pc(pc); never@1445: if (addr != (address)-1) { never@1445: stub = addr; never@1445: } never@1445: }*/ never@1445: never@1445: // Check to see if we caught the safepoint code in the process never@1445: // of write protecting the memory serialization page. It write never@1445: // enables the page immediately after protecting it so we can never@1445: // just return to retry the write. never@1445: if (sig == SIGSEGV && never@1445: os::is_memory_serialize_page(thread, (address) info->si_addr)) { never@1445: // Block current thread until permission is restored. never@1445: os::block_on_serialize_page_trap(); never@1445: return true; never@1445: } never@1445: } never@1445: never@1445: // signal-chaining never@1445: if (os::Linux::chained_handler(sig, info, ucVoid)) { never@1445: return true; never@1445: } never@1445: never@1445: if (!abort_if_unrecognized) { never@1445: // caller wants another chance, so give it to him never@1445: return false; never@1445: } never@1445: never@1445: #ifndef PRODUCT never@1445: if (sig == SIGSEGV) { never@1445: fatal("\n#" never@1445: "\n# /--------------------\\" never@1445: "\n# | segmentation fault |" never@1445: "\n# \\---\\ /--------------/" never@1445: "\n# /" never@1445: "\n# [-] |\\_/| " never@1445: "\n# (+)=C |o o|__ " never@1445: "\n# | | =-*-=__\\ " never@1445: "\n# OOO c_c_(___)"); never@1445: } never@1445: #endif // !PRODUCT never@1445: never@1445: const char *fmt = "caught unhandled signal %d"; never@1445: char buf[64]; never@1445: never@1445: sprintf(buf, fmt, sig); never@1445: fatal(buf); never@1445: } never@1445: never@1445: void os::Linux::init_thread_fpu_state(void) { never@1445: // Nothing to do never@1445: } never@1445: never@1445: int os::Linux::get_fpu_control_word() { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: void os::Linux::set_fpu_control_word(int fpu) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: never@1445: bool os::is_allocatable(size_t bytes) { twisti@1611: #ifdef _LP64 twisti@1611: return true; twisti@1611: #else twisti@1611: if (bytes < 2 * G) { twisti@1611: return true; twisti@1611: } twisti@1611: twisti@1611: char* addr = reserve_memory(bytes, NULL); twisti@1611: twisti@1611: if (addr != NULL) { twisti@1611: release_memory(addr, bytes); twisti@1611: } twisti@1611: twisti@1611: return addr != NULL; twisti@1611: #endif // _LP64 never@1445: } never@1445: never@1445: /////////////////////////////////////////////////////////////////////////////// never@1445: // thread stack never@1445: never@1445: size_t os::Linux::min_stack_allowed = 64 * K; never@1445: never@1445: bool os::Linux::supports_variable_stack_size() { never@1445: return true; never@1445: } never@1445: never@1445: size_t os::Linux::default_stack_size(os::ThreadType thr_type) { never@1445: #ifdef _LP64 never@1445: size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); never@1445: #else never@1445: size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); never@1445: #endif // _LP64 never@1445: return s; never@1445: } never@1445: never@1445: size_t os::Linux::default_guard_size(os::ThreadType thr_type) { never@1445: // Only enable glibc guard pages for non-Java threads never@1445: // (Java threads have HotSpot guard pages) never@1445: return (thr_type == java_thread ? 0 : page_size()); never@1445: } never@1445: never@1445: static void current_stack_region(address *bottom, size_t *size) { never@1445: pthread_attr_t attr; never@1445: int res = pthread_getattr_np(pthread_self(), &attr); never@1445: if (res != 0) { never@1445: if (res == ENOMEM) { never@1445: vm_exit_out_of_memory(0, "pthread_getattr_np"); never@1445: } never@1445: else { jcoomes@1877: fatal(err_msg("pthread_getattr_np failed with errno = %d", res)); never@1445: } never@1445: } never@1445: never@1445: address stack_bottom; never@1445: size_t stack_bytes; never@1445: res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes); never@1445: if (res != 0) { jcoomes@1877: fatal(err_msg("pthread_attr_getstack failed with errno = %d", res)); never@1445: } never@1445: address stack_top = stack_bottom + stack_bytes; never@1445: never@1445: // The block of memory returned by pthread_attr_getstack() includes never@1445: // guard pages where present. We need to trim these off. never@1445: size_t page_bytes = os::Linux::page_size(); never@1445: assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack"); never@1445: never@1445: size_t guard_bytes; never@1445: res = pthread_attr_getguardsize(&attr, &guard_bytes); never@1445: if (res != 0) { jcoomes@1877: fatal(err_msg("pthread_attr_getguardsize failed with errno = %d", res)); never@1445: } never@1445: int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes; never@1445: assert(guard_bytes == guard_pages * page_bytes, "unaligned guard"); never@1445: never@1445: #ifdef IA64 never@1445: // IA64 has two stacks sharing the same area of memory, a normal never@1445: // stack growing downwards and a register stack growing upwards. never@1445: // Guard pages, if present, are in the centre. This code splits never@1445: // the stack in two even without guard pages, though in theory never@1445: // there's nothing to stop us allocating more to the normal stack never@1445: // or more to the register stack if one or the other were found never@1445: // to grow faster. never@1445: int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes; never@1445: stack_bottom += (total_pages - guard_pages) / 2 * page_bytes; never@1445: #endif // IA64 never@1445: never@1445: stack_bottom += guard_bytes; never@1445: never@1445: pthread_attr_destroy(&attr); never@1445: never@1445: // The initial thread has a growable stack, and the size reported never@1445: // by pthread_attr_getstack is the maximum size it could possibly never@1445: // be given what currently mapped. This can be huge, so we cap it. never@1445: if (os::Linux::is_initial_thread()) { never@1445: stack_bytes = stack_top - stack_bottom; never@1445: never@1445: if (stack_bytes > JavaThread::stack_size_at_create()) never@1445: stack_bytes = JavaThread::stack_size_at_create(); never@1445: never@1445: stack_bottom = stack_top - stack_bytes; never@1445: } never@1445: never@1445: assert(os::current_stack_pointer() >= stack_bottom, "should do"); never@1445: assert(os::current_stack_pointer() < stack_top, "should do"); never@1445: never@1445: *bottom = stack_bottom; never@1445: *size = stack_top - stack_bottom; never@1445: } never@1445: never@1445: address os::current_stack_base() { never@1445: address bottom; never@1445: size_t size; never@1445: current_stack_region(&bottom, &size); never@1445: return bottom + size; never@1445: } never@1445: never@1445: size_t os::current_stack_size() { never@1445: // stack size includes normal stack and HotSpot guard pages never@1445: address bottom; never@1445: size_t size; never@1445: current_stack_region(&bottom, &size); never@1445: return size; never@1445: } never@1445: never@1445: ///////////////////////////////////////////////////////////////////////////// never@1445: // helper functions for fatal error handler never@1445: never@1445: void os::print_context(outputStream* st, void* context) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: twisti@2312: void os::print_register_info(outputStream *st, void *context) { twisti@2312: ShouldNotCallThis(); twisti@2312: } twisti@2312: never@1445: ///////////////////////////////////////////////////////////////////////////// never@1445: // Stubs for things that would be in linux_zero.s if it existed. never@1445: // You probably want to disassemble these monkeys to check they're ok. never@1445: never@1445: extern "C" { never@1445: int SpinPause() { never@1445: } never@1445: never@1445: int SafeFetch32(int *adr, int errValue) { never@1445: int value = errValue; never@1445: value = *adr; never@1445: return value; never@1445: } never@1445: intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { never@1445: intptr_t value = errValue; never@1445: value = *adr; never@1445: return value; never@1445: } never@1445: never@1445: void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { never@1445: if (from > to) { never@1445: jshort *end = from + count; never@1445: while (from < end) never@1445: *(to++) = *(from++); never@1445: } never@1445: else if (from < to) { never@1445: jshort *end = from; never@1445: from += count - 1; never@1445: to += count - 1; never@1445: while (from >= end) never@1445: *(to--) = *(from--); never@1445: } never@1445: } never@1445: void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) { never@1445: if (from > to) { never@1445: jint *end = from + count; never@1445: while (from < end) never@1445: *(to++) = *(from++); never@1445: } never@1445: else if (from < to) { never@1445: jint *end = from; never@1445: from += count - 1; never@1445: to += count - 1; never@1445: while (from >= end) never@1445: *(to--) = *(from--); never@1445: } never@1445: } never@1445: void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) { never@1445: if (from > to) { never@1445: jlong *end = from + count; never@1445: while (from < end) never@1445: os::atomic_copy64(from++, to++); never@1445: } never@1445: else if (from < to) { never@1445: jlong *end = from; never@1445: from += count - 1; never@1445: to += count - 1; never@1445: while (from >= end) never@1445: os::atomic_copy64(from--, to--); never@1445: } never@1445: } never@1445: never@1445: void _Copy_arrayof_conjoint_bytes(HeapWord* from, never@1445: HeapWord* to, never@1445: size_t count) { twisti@2084: memmove(to, from, count); never@1445: } never@1445: void _Copy_arrayof_conjoint_jshorts(HeapWord* from, never@1445: HeapWord* to, never@1445: size_t count) { twisti@2084: memmove(to, from, count * 2); never@1445: } never@1445: void _Copy_arrayof_conjoint_jints(HeapWord* from, never@1445: HeapWord* to, never@1445: size_t count) { twisti@2084: memmove(to, from, count * 4); never@1445: } never@1445: void _Copy_arrayof_conjoint_jlongs(HeapWord* from, never@1445: HeapWord* to, never@1445: size_t count) { twisti@2084: memmove(to, from, count * 8); never@1445: } never@1445: }; never@1445: never@1445: ///////////////////////////////////////////////////////////////////////////// never@1445: // Implementations of atomic operations not supported by processors. never@1445: // -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html never@1445: never@1445: #ifndef _LP64 never@1445: extern "C" { never@1445: long long unsigned int __sync_val_compare_and_swap_8( never@1445: volatile void *ptr, never@1445: long long unsigned int oldval, never@1445: long long unsigned int newval) { never@1445: ShouldNotCallThis(); never@1445: } never@1445: }; never@1445: #endif // !_LP64