# HG changeset patch # User Thomas Wuerthinger # Date 1298312253 -3600 # Node ID 0cd39a385a7236a9e3ed78fbb26723a626bed509 # Parent 5d801e6b9a80bca17f84d5fef74253d27c2d55b8# Parent 0a2ecf4cc3849ac9dcc30c52b951f20724d9d5b4 Merge. diff -r 5d801e6b9a80 -r 0cd39a385a72 .hgtags --- a/.hgtags Mon Feb 21 19:17:10 2011 +0100 +++ b/.hgtags Mon Feb 21 19:17:33 2011 +0100 @@ -148,3 +148,4 @@ 9a5762f448595794d449a8e17342abd81a3fadaf jdk7-b128 ae4b185f2ed14af7bab610738c333840598cdcc4 jdk7-b129 ae4b185f2ed14af7bab610738c333840598cdcc4 hs21-b01 +e9aa2ca89ad6c53420623d579765f9706ec523d7 jdk7-b130 diff -r 5d801e6b9a80 -r 0cd39a385a72 agent/src/share/classes/sun/jvm/hotspot/runtime/LowMemoryDetectorThread.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/LowMemoryDetectorThread.java Mon Feb 21 19:17:10 2011 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * 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. - * - */ - -package sun.jvm.hotspot.runtime; - -import java.io.*; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.types.*; - -public class LowMemoryDetectorThread extends JavaThread { - public LowMemoryDetectorThread(Address addr) { - super(addr); - } - - public boolean isJavaThread() { return false; } - public boolean isHiddenFromExternalView() { return true; } - public boolean isLowMemoryDetectorThread() { return true; } - -} diff -r 5d801e6b9a80 -r 0cd39a385a72 agent/src/share/classes/sun/jvm/hotspot/runtime/ServiceThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ServiceThread.java Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +package sun.jvm.hotspot.runtime; + +import java.io.*; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.types.*; + +public class ServiceThread extends JavaThread { + public ServiceThread(Address addr) { + super(addr); + } + + public boolean isJavaThread() { return false; } + public boolean isHiddenFromExternalView() { return true; } + public boolean isServiceThread() { return true; } + +} diff -r 5d801e6b9a80 -r 0cd39a385a72 agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java Mon Feb 21 19:17:10 2011 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Thread.java Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ public boolean isJvmtiAgentThread() { return false; } public boolean isWatcherThread() { return false; } public boolean isConcurrentMarkSweepThread() { return false; } - public boolean isLowMemoryDetectorThread() { return false; } + public boolean isServiceThread() { return false; } /** Memory operations */ public void oopsDo(AddressVisitor oopVisitor) { diff -r 5d801e6b9a80 -r 0cd39a385a72 agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Mon Feb 21 19:17:10 2011 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -107,14 +107,14 @@ // for now, use JavaThread itself. fix it later with appropriate class if needed virtualConstructor.addMapping("SurrogateLockerThread", JavaThread.class); virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class); - virtualConstructor.addMapping("LowMemoryDetectorThread", LowMemoryDetectorThread.class); + virtualConstructor.addMapping("ServiceThread", ServiceThread.class); } public Threads() { } /** NOTE: this returns objects of type JavaThread, CompilerThread, - JvmtiAgentThread, and LowMemoryDetectorThread. + JvmtiAgentThread, and ServiceThread. The latter four are subclasses of the former. Most operations (fetching the top frame, etc.) are only allowed to be performed on a "pure" JavaThread. For this reason, {@link @@ -143,7 +143,7 @@ return thread; } catch (Exception e) { throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr + - " (expected type JavaThread, CompilerThread, LowMemoryDetectorThread, JvmtiAgentThread, or SurrogateLockerThread)", e); + " (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, or SurrogateLockerThread)", e); } } diff -r 5d801e6b9a80 -r 0cd39a385a72 make/Makefile diff -r 5d801e6b9a80 -r 0cd39a385a72 make/altsrc.make --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/altsrc.make Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,92 @@ +# +# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# 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. +# +# + +# This file defines variables and macros which are used in the makefiles to +# allow distributions to augment or replace common hotspot code with +# distribution-specific source files. + +# Requires: GAMMADIR +# Provides: +# variables: HS_COMMON_SRC, HS_ALT_SRC, HS_COMMON_SRC_REL, and HS_ALT_SRC_REL +# functions: altsrc-equiv, if-has-altsrc, altsrc, altsrc-replace + +HS_COMMON_SRC_REL=src + +# This needs to be changed to a more generic location, but we keep it as this +# for now for compatibility +HS_ALT_SRC_REL=src/closed + +HS_COMMON_SRC=$(GAMMADIR)/$(HS_COMMON_SRC_REL) +HS_ALT_SRC=$(GAMMADIR)/$(HS_ALT_SRC_REL) + + +## altsrc-equiv +# +# Convert a common source path to an alternative source path +# +# Parameter: An absolute path into the common sources +# Result: The matching path to the alternate-source location +# +altsrc-equiv=$(subst $(HS_COMMON_SRC)/,$(HS_ALT_SRC)/,$(1)) + + +## if-has-altsrc +# +# Conditional macro to test for the existence of an alternate source path +# +# Parameter: An absolute path into the common sources +# Parameter: Result if the alternative-source location exists +# Parameter: Result if the alternative-source location does not exist +# Result: expands to parameter 2 or 3 depending on existence of alternate source +# +if-has-altsrc=$(if $(wildcard $(call altsrc-equiv,$(1))),$(2),$(3)) + + +## altsrc +# +# Converts common source path to alternate source path if the alternate +# path exists, otherwise evaluates to nul (empty string) +# +# Parameter: An absolute path into the common sources +# Result: The equivalent path to the alternate-source location, if such a +# location exists on the filesystem. Otherwise it expands to empty. +# +altsrc=$(call if-has-altsrc,$(1),$(call altsrc-equiv,$(1))) + +## commonsrc +# +# Returns parameter. +# +commonsrc=$(1) + + +## altsrc-replace +# +# Converts a common source path to an alternate source path if the alternate +# source path exists. Otherwise it evaluates to the input common source path. +# +# Parameter: An absolute path into the common sources +# Result: A path to either the common or alternate sources +# +altsrc-replace=$(call if-has-altsrc,$(1),$(call altsrc-equiv,$(1)),$(1)) diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/Makefile diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/adlc.make diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/arm.make --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/makefiles/arm.make Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,10 @@ +# +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. +# + +Obj_Files += linux_arm.o + +LIBS += $(EXT_LIBS_PATH)/sflt_glibc.a + +CFLAGS += -DVM_LITTLE_ENDIAN diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/buildtree.make diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/ppc.make --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/makefiles/ppc.make Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,11 @@ +# +# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. +# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. +# + +# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized +OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT) + +# Must also specify if CPU is big endian +CFLAGS += -DVM_BIG_ENDIAN + diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/rules.make diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/top.make diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/makefiles/vm.make diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/platform_arm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/platform_arm Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,17 @@ +os_family = linux + +arch = arm + +arch_model = arm + +os_arch = linux_arm + +os_arch_model = linux_arm + +lib_arch = arm + +compiler = gcc + +gnu_dis_arch = arm + +sysdefs = -DLINUX -D_GNU_SOURCE -DARM diff -r 5d801e6b9a80 -r 0cd39a385a72 make/linux/platform_ppc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/linux/platform_ppc Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,17 @@ +os_family = linux + +arch = ppc + +arch_model = ppc + +os_arch = linux_ppc + +os_arch_model = linux_ppc + +lib_arch = ppc + +compiler = gcc + +gnu_dis_arch = ppc + +sysdefs = -DLINUX -D_GNU_SOURCE -DPPC diff -r 5d801e6b9a80 -r 0cd39a385a72 make/windows/makefiles/vm.make diff -r 5d801e6b9a80 -r 0cd39a385a72 src/cpu/sparc/vm/jni_sparc.h --- a/src/cpu/sparc/vm/jni_sparc.h Mon Feb 21 19:17:10 2011 +0100 +++ b/src/cpu/sparc/vm/jni_sparc.h Mon Feb 21 19:17:33 2011 +0100 @@ -23,8 +23,13 @@ * questions. */ -#define JNIEXPORT -#define JNIIMPORT +#if defined(__GNUC__) && (__GNUC__ >= 4) + #define JNIEXPORT __attribute__((visibility("default"))) + #define JNIIMPORT __attribute__((visibility("default"))) +#else + #define JNIEXPORT + #define JNIIMPORT +#endif #define JNICALL typedef int jint; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/cpu/x86/vm/jni_x86.h --- a/src/cpu/x86/vm/jni_x86.h Mon Feb 21 19:17:10 2011 +0100 +++ b/src/cpu/x86/vm/jni_x86.h Mon Feb 21 19:17:33 2011 +0100 @@ -27,10 +27,16 @@ #define _JAVASOFT_JNI_MD_H_ #if defined(SOLARIS) || defined(LINUX) + +#if defined(__GNUC__) && (__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2) + #define JNIEXPORT __attribute__((visibility("default"))) + #define JNIIMPORT __attribute__((visibility("default"))) +#else #define JNIEXPORT #define JNIIMPORT +#endif + #define JNICALL - typedef int jint; #ifdef _LP64 diff -r 5d801e6b9a80 -r 0cd39a385a72 src/cpu/zero/vm/jni_zero.h --- a/src/cpu/zero/vm/jni_zero.h Mon Feb 21 19:17:10 2011 +0100 +++ b/src/cpu/zero/vm/jni_zero.h Mon Feb 21 19:17:33 2011 +0100 @@ -24,8 +24,14 @@ * questions. */ -#define JNIEXPORT -#define JNIIMPORT + +#if defined(__GNUC__) && (__GNUC__ >= 4) + #define JNIEXPORT __attribute__((visibility("default"))) + #define JNIIMPORT __attribute__((visibility("default"))) +#else + #define JNIEXPORT + #define JNIIMPORT +#endif #define JNICALL typedef int jint; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/linux/vm/jvm_linux.cpp --- a/src/os/linux/vm/jvm_linux.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/linux/vm/jvm_linux.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -29,11 +29,6 @@ #include -/* - * FIXME: This is temporary hack to keep Linux Runtime.exec() - * code happy. See $JDK/src/linux/native/java/lang/UnixProcess_md.c - */ -int _JVM_native_threads = 1; // sun.misc.Signal /////////////////////////////////////////////////////////// // Signal code is mostly copied from classic vm, signals_md.c 1.4 98/08/23 diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/linux/vm/osThread_linux.cpp --- a/src/os/linux/vm/osThread_linux.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/linux/vm/osThread_linux.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +#endif void OSThread::pd_initialize() { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/linux/vm/os_linux.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,6 +76,14 @@ # include "assembler_zero.inline.hpp" # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +# include "nativeInst_ppc.hpp" +#endif #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif @@ -123,6 +131,7 @@ #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) #define SEC_IN_NANOSECS 1000000000LL +#define LARGEPAGES_BIT (1 << 6) //////////////////////////////////////////////////////////////////////////////// // global variables julong os::Linux::_physical_memory = 0; @@ -2509,8 +2518,10 @@ return end; } -extern "C" void numa_warn(int number, char *where, ...) { } -extern "C" void numa_error(char *where) { } +// Something to do with the numa-aware allocator needs these symbols +extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } +extern "C" JNIEXPORT void numa_error(char *where) { } +extern "C" JNIEXPORT int fork1() { return fork(); } // If we are running with libnuma version > 2, then we should @@ -2807,6 +2818,43 @@ return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); } +/* +* Set the coredump_filter bits to include largepages in core dump (bit 6) +* +* From the coredump_filter documentation: +* +* - (bit 0) anonymous private memory +* - (bit 1) anonymous shared memory +* - (bit 2) file-backed private memory +* - (bit 3) file-backed shared memory +* - (bit 4) ELF header pages in file-backed private memory areas (it is +* effective only if the bit 2 is cleared) +* - (bit 5) hugetlb private memory +* - (bit 6) hugetlb shared memory +*/ +static void set_coredump_filter(void) { + FILE *f; + long cdm; + + if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { + return; + } + + if (fscanf(f, "%lx", &cdm) != 1) { + fclose(f); + return; + } + + rewind(f); + + if ((cdm & LARGEPAGES_BIT) == 0) { + cdm |= LARGEPAGES_BIT; + fprintf(f, "%#lx", cdm); + } + + fclose(f); +} + // Large page support static size_t _large_page_size = 0; @@ -2864,6 +2912,8 @@ _page_sizes[2] = 0; } + set_coredump_filter(); + // Large page support is available on 2.6 or newer kernel, some vendors // (e.g. Redhat) have backported it to their 2.4 based distributions. // We optimistically assume the support is available. If later it turns out @@ -3483,7 +3533,7 @@ // Note that the VM will print warnings if it detects conflicting signal // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". // -extern "C" int +extern "C" JNIEXPORT int JVM_handle_linux_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); @@ -4685,44 +4735,6 @@ } } -extern "C" { - -/** - * NOTE: the following code is to keep the green threads code - * in the libjava.so happy. Once the green threads is removed, - * these code will no longer be needed. - */ -int -jdk_waitpid(pid_t pid, int* status, int options) { - return waitpid(pid, status, options); -} - -int -fork1() { - return fork(); -} - -int -jdk_sem_init(sem_t *sem, int pshared, unsigned int value) { - return sem_init(sem, pshared, value); -} - -int -jdk_sem_post(sem_t *sem) { - return sem_post(sem); -} - -int -jdk_sem_wait(sem_t *sem) { - return sem_wait(sem); -} - -int -jdk_pthread_sigmask(int how , const sigset_t* newmask, sigset_t* oldmask) { - return pthread_sigmask(how , newmask, oldmask); -} - -} // Refer to the comments in os_solaris.cpp park-unpark. // diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/linux/vm/os_linux.inline.hpp --- a/src/os/linux/vm/os_linux.inline.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/linux/vm/os_linux.inline.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,14 @@ # include "atomic_linux_zero.inline.hpp" # include "orderAccess_linux_zero.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "atomic_linux_arm.inline.hpp" +# include "orderAccess_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "atomic_linux_ppc.inline.hpp" +# include "orderAccess_linux_ppc.inline.hpp" +#endif // System includes diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/linux/vm/thread_linux.inline.hpp --- a/src/os/linux/vm/thread_linux.inline.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/linux/vm/thread_linux.inline.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -44,6 +44,16 @@ # include "orderAccess_linux_zero.inline.hpp" # include "prefetch_linux_zero.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "atomic_linux_arm.inline.hpp" +# include "orderAccess_linux_arm.inline.hpp" +# include "prefetch_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "atomic_linux_ppc.inline.hpp" +# include "orderAccess_linux_ppc.inline.hpp" +# include "prefetch_linux_ppc.inline.hpp" +#endif // Contains inlined functions for class Thread and ThreadLocalStorage diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/posix/vm/os_posix.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/os/posix/vm/os_posix.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* 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. +* +*/ + +#include "prims/jvm.h" +#include "runtime/os.hpp" +#include "utilities/vmError.hpp" + +#include +#include + +// Check core dump limit and report possible place where core can be found +void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { + struct rlimit rlim; + static char cwd[O_BUFLEN]; + bool success; + + get_current_directory(cwd, sizeof(cwd)); + + if (getrlimit(RLIMIT_CORE, &rlim) != 0) { + jio_snprintf(buffer, bufferSize, "%s/core or core.%d (may not exist)", cwd, current_process_id()); + success = true; + } else { + switch(rlim.rlim_cur) { + case RLIM_INFINITY: + jio_snprintf(buffer, bufferSize, "%s/core or core.%d", cwd, current_process_id()); + success = true; + break; + case 0: + jio_snprintf(buffer, bufferSize, "Core dumps have been disabled. To enable core dumping, try \"ulimit -c unlimited\" before starting Java again"); + success = false; + break; + default: + jio_snprintf(buffer, bufferSize, "%s/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", cwd, current_process_id(), (unsigned long)(rlim.rlim_cur >> 10)); + success = true; + break; + } + } + VMError::report_coredump_status(buffer, success); +} + diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/solaris/vm/os_solaris.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -4221,7 +4221,9 @@ // Note that the VM will print warnings if it detects conflicting signal // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". // -extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); +extern "C" JNIEXPORT int +JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, + int abort_if_unrecognized); void signalHandler(int sig, siginfo_t* info, void* ucVoid) { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/windows/vm/os_windows.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * CopyrighT (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -915,6 +915,85 @@ } } + +static BOOL (WINAPI *_MiniDumpWriteDump) ( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, + PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION); + +void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { + HINSTANCE dbghelp; + EXCEPTION_POINTERS ep; + MINIDUMP_EXCEPTION_INFORMATION mei; + HANDLE hProcess = GetCurrentProcess(); + DWORD processId = GetCurrentProcessId(); + HANDLE dumpFile; + MINIDUMP_TYPE dumpType; + static const char* cwd; + + // If running on a client version of Windows and user has not explicitly enabled dumping + if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) { + VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false); + return; + // If running on a server version of Windows and user has explictly disabled dumping + } else if (os::win32::is_windows_server() && !FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) { + VMError::report_coredump_status("Minidump has been disabled from the command line", false); + return; + } + + dbghelp = LoadLibrary("DBGHELP.DLL"); + + if (dbghelp == NULL) { + VMError::report_coredump_status("Failed to load dbghelp.dll", false); + return; + } + + _MiniDumpWriteDump = CAST_TO_FN_PTR( + BOOL(WINAPI *)( HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, PMINIDUMP_EXCEPTION_INFORMATION, + PMINIDUMP_USER_STREAM_INFORMATION, PMINIDUMP_CALLBACK_INFORMATION), + GetProcAddress(dbghelp, "MiniDumpWriteDump")); + + if (_MiniDumpWriteDump == NULL) { + VMError::report_coredump_status("Failed to find MiniDumpWriteDump() in module dbghelp.dll", false); + return; + } + + dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory | MiniDumpWithHandleData); + +// Older versions of dbghelp.h doesn't contain all the dumptypes we want, dbghelp.h with +// API_VERSION_NUMBER 11 or higher contains the ones we want though +#if API_VERSION_NUMBER >= 11 + dumpType = (MINIDUMP_TYPE)(dumpType | MiniDumpWithFullMemoryInfo | MiniDumpWithThreadInfo | + MiniDumpWithUnloadedModules); +#endif + + cwd = get_current_directory(NULL, 0); + jio_snprintf(buffer, bufferSize, "%s\\hs_err_pid%u.mdmp",cwd, current_process_id()); + dumpFile = CreateFile(buffer, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (dumpFile == INVALID_HANDLE_VALUE) { + VMError::report_coredump_status("Failed to create file for dumping", false); + return; + } + + ep.ContextRecord = (PCONTEXT) contextRecord; + ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord; + + mei.ThreadId = GetCurrentThreadId(); + mei.ExceptionPointers = &ep; + + // Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all + // the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then. + if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, &mei, NULL, NULL) == false && + _MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, &mei, NULL, NULL) == false) { + VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false); + } else { + VMError::report_coredump_status(buffer, true); + } + + CloseHandle(dumpFile); +} + + + void os::abort(bool dump_core) { os::shutdown(); @@ -3274,7 +3353,7 @@ bool os::win32::_is_nt = false; bool os::win32::_is_windows_2003 = false; - +bool os::win32::_is_windows_server = false; void os::win32::initialize_system_info() { SYSTEM_INFO si; @@ -3293,9 +3372,9 @@ GlobalMemoryStatusEx(&ms); _physical_memory = ms.ullTotalPhys; - OSVERSIONINFO oi; - oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&oi); + OSVERSIONINFOEX oi; + oi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + GetVersionEx((OSVERSIONINFO*)&oi); switch(oi.dwPlatformId) { case VER_PLATFORM_WIN32_WINDOWS: _is_nt = false; break; case VER_PLATFORM_WIN32_NT: @@ -3305,6 +3384,10 @@ if (os_vers == 5002) { _is_windows_2003 = true; } + if (oi.wProductType == VER_NT_DOMAIN_CONTROLLER || + oi.wProductType == VER_NT_SERVER) { + _is_windows_server = true; + } } break; default: fatal("Unknown platform"); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os/windows/vm/os_windows.hpp --- a/src/os/windows/vm/os_windows.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os/windows/vm/os_windows.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ static size_t _default_stack_size; static bool _is_nt; static bool _is_windows_2003; + static bool _is_windows_server; public: // Windows-specific interface: @@ -64,6 +65,9 @@ // Tells whether the platform is NT or Windown95 static bool is_nt() { return _is_nt; } + // Tells whether this is a server version of Windows + static bool is_windows_server() { return _is_windows_server; } + // Tells whether the platform is Windows 2003 static bool is_windows_2003() { return _is_windows_2003; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -542,7 +542,7 @@ return false; } -extern "C" int +extern "C" JNIEXPORT int JVM_handle_linux_signal(int sig, siginfo_t* info, void* ucVoid, diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -216,7 +216,7 @@ extern "C" void FetchNResume () ; #endif // AMD64 -extern "C" int +extern "C" JNIEXPORT int JVM_handle_linux_signal(int sig, siginfo_t* info, void* ucVoid, diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os_cpu/linux_zero/vm/os_linux_zero.cpp --- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -116,7 +116,7 @@ ShouldNotCallThis(); } -extern "C" int +extern "C" JNIEXPORT int JVM_handle_linux_signal(int sig, siginfo_t* info, void* ucVoid, diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -317,9 +317,9 @@ extern "C" void FetchNPFI () ; extern "C" void FetchNResume () ; -extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); - -int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { +extern "C" JNIEXPORT int +JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, + int abort_if_unrecognized) { ucontext_t* uc = (ucontext_t*) ucVoid; Thread* t = ThreadLocalStorage::get_thread_slow(); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -365,8 +365,6 @@ } -extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); - extern "C" void Fetch32PFI () ; extern "C" void Fetch32Resume () ; #ifdef AMD64 @@ -374,7 +372,9 @@ extern "C" void FetchNResume () ; #endif // AMD64 -int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { +extern "C" JNIEXPORT int +JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, + int abort_if_unrecognized) { ucontext_t* uc = (ucontext_t*) ucVoid; #ifndef AMD64 diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/asm/assembler.cpp --- a/src/share/vm/asm/assembler.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/asm/assembler.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -37,6 +37,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +#endif // Implementation of AbstractAssembler diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/asm/assembler.hpp --- a/src/share/vm/asm/assembler.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/asm/assembler.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -43,6 +43,14 @@ # include "register_zero.hpp" # include "vm_version_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "register_arm.hpp" +# include "vm_version_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "register_ppc.hpp" +# include "vm_version_ppc.hpp" +#endif // This file contains platform-independent assembler declarations. @@ -395,6 +403,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.hpp" +#endif #endif // SHARE_VM_ASM_ASSEMBLER_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/asm/codeBuffer.hpp --- a/src/share/vm/asm/codeBuffer.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/asm/codeBuffer.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -566,6 +566,12 @@ #ifdef TARGET_ARCH_zero # include "codeBuffer_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "codeBuffer_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "codeBuffer_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_Defs.hpp --- a/src/share/vm/c1/c1_Defs.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_Defs.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "register_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "register_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "register_ppc.hpp" +#endif // set frame size and return address offset to these values in blobs // (if the compiled frame uses ebp as link pointer on IA; otherwise, @@ -50,6 +56,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_Defs_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_Defs_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_Defs_ppc.hpp" +#endif // native word offsets from memory address diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_FpuStackSim.hpp --- a/src/share/vm/c1/c1_FpuStackSim.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_FpuStackSim.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -38,6 +38,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_FpuStackSim_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_FpuStackSim_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_FpuStackSim_ppc.hpp" +#endif #endif // SHARE_VM_C1_C1_FPUSTACKSIM_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_FrameMap.cpp --- a/src/share/vm/c1/c1_FrameMap.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_FrameMap.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmreg_ppc.inline.hpp" +#endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_FrameMap.hpp --- a/src/share/vm/c1/c1_FrameMap.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_FrameMap.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -88,6 +88,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_FrameMap_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_FrameMap_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_FrameMap_ppc.hpp" +#endif friend class LIR_OprDesc; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_Instruction.hpp --- a/src/share/vm/c1/c1_Instruction.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_Instruction.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -316,6 +316,8 @@ return res; } + static const int no_bci = -99; + enum InstructionFlag { NeedsNullCheckFlag = 0, CanTrapFlag, diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_LIRAssembler.cpp --- a/src/share/vm/c1/c1_LIRAssembler.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -42,6 +42,14 @@ # include "nativeInst_zero.hpp" # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +# include "vmreg_ppc.inline.hpp" +#endif void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_LIRAssembler.hpp --- a/src/share/vm/c1/c1_LIRAssembler.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -252,6 +252,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_LIRAssembler_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_LIRAssembler_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_LIRAssembler_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_LinearScan.cpp --- a/src/share/vm/c1/c1_LinearScan.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_LinearScan.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,12 @@ #ifdef TARGET_ARCH_zero # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmreg_ppc.inline.hpp" +#endif #ifndef PRODUCT diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_LinearScan.hpp --- a/src/share/vm/c1/c1_LinearScan.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_LinearScan.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -972,6 +972,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_LinearScan_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_LinearScan_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_LinearScan_ppc.hpp" +#endif #endif // SHARE_VM_C1_C1_LINEARSCAN_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_MacroAssembler.hpp --- a/src/share/vm/c1/c1_MacroAssembler.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_MacroAssembler.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +#endif class CodeEmitInfo; @@ -61,6 +67,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_MacroAssembler_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_MacroAssembler_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_MacroAssembler_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/c1/c1_globals.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -32,6 +32,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_globals_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_globals_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_globals_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "c1_globals_linux.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/classfile/classFileStream.hpp --- a/src/share/vm/classfile/classFileStream.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/classfile/classFileStream.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // Input stream for reading .class file // diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/classfile/stackMapTable.hpp --- a/src/share/vm/classfile/stackMapTable.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/classfile/stackMapTable.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif class StackMapReader; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/classfile/verifier.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -51,6 +51,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif #define NOFAILOVER_MAJOR_VERSION 51 diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -108,7 +108,6 @@ template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ - template(setBootClassLoaderHook_name, "setBootClassLoaderHook") \ template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \ \ /* class file format tags */ \ diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/codeBlob.cpp --- a/src/share/vm/code/codeBlob.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/codeBlob.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -48,6 +48,12 @@ #ifdef TARGET_ARCH_zero # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +#endif #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/compiledIC.hpp --- a/src/share/vm/code/compiledIC.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/compiledIC.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -38,6 +38,12 @@ #ifdef TARGET_ARCH_zero # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +#endif //----------------------------------------------------------------------------- // The CompiledIC represents a compiled inline cache. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/icBuffer.cpp --- a/src/share/vm/code/icBuffer.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/icBuffer.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -46,6 +46,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +#endif DEF_STUB_INTERFACE(ICStub); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/nmethod.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -34,6 +34,7 @@ #include "interpreter/bytecode.hpp" #include "oops/methodDataOop.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" +#include "prims/jvmtiImpl.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/sweeper.hpp" #include "utilities/dtrace.hpp" @@ -1550,7 +1551,10 @@ } if (JvmtiExport::should_post_compiled_method_load()) { - JvmtiExport::post_compiled_method_load(this); + // Let the Service thread (which is a real Java thread) post the event + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + JvmtiDeferredEventQueue::enqueue( + JvmtiDeferredEvent::compiled_method_load_event(this)); } } @@ -1583,8 +1587,17 @@ // ref will have been cleared. if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) { assert(!unload_reported(), "already unloaded"); - HandleMark hm; - JvmtiExport::post_compiled_method_unload(_jmethod_id, insts_begin()); + JvmtiDeferredEvent event = + JvmtiDeferredEvent::compiled_method_unload_event( + _jmethod_id, insts_begin()); + if (SafepointSynchronize::is_at_safepoint()) { + // Don't want to take the queueing lock. Add it as pending and + // it will get enqueued later. + JvmtiDeferredEventQueue::add_pending_event(event); + } else { + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + JvmtiDeferredEventQueue::enqueue(event); + } } // The JVMTI CompiledMethodUnload event can be enabled or disabled at diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/nmethod.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -699,10 +699,11 @@ class nmethodLocker : public StackObj { nmethod* _nm; + public: + static void lock_nmethod(nmethod* nm); // note: nm can be NULL static void unlock_nmethod(nmethod* nm); // (ditto) - public: nmethodLocker(address pc); // derive nm from pc nmethodLocker(nmethod *nm) { _nm = nm; lock_nmethod(_nm); } nmethodLocker() { _nm = NULL; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/relocInfo.cpp --- a/src/share/vm/code/relocInfo.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/relocInfo.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,14 @@ # include "assembler_zero.inline.hpp" # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +# include "nativeInst_ppc.hpp" +#endif const RelocationHolder RelocationHolder::none; // its type is relocInfo::none diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/relocInfo.hpp --- a/src/share/vm/code/relocInfo.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/relocInfo.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -430,6 +430,12 @@ #ifdef TARGET_ARCH_zero # include "relocInfo_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "relocInfo_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "relocInfo_ppc.hpp" +#endif protected: diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/code/vmreg.hpp --- a/src/share/vm/code/vmreg.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/code/vmreg.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -36,6 +36,12 @@ #ifdef TARGET_ARCH_zero # include "register_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "register_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "register_ppc.hpp" +#endif #ifdef COMPILER2 #include "opto/adlcVMDeps.hpp" #include "utilities/ostream.hpp" @@ -51,6 +57,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/adGlobals_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/adGlobals_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/adGlobals_ppc.hpp" +#endif #endif //------------------------------VMReg------------------------------------------ @@ -164,6 +176,12 @@ #ifdef TARGET_ARCH_zero # include "vmreg_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmreg_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmreg_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1294,7 +1294,17 @@ // Should the current thread be blocked until this compilation request // has been fulfilled? bool CompileBroker::is_compile_blocking(methodHandle method, int osr_bci) { - return !BackgroundCompilation; + if (!BackgroundCompilation) { + Symbol* class_name = method->method_holder()->klass_part()->name(); + if (class_name->starts_with("java/lang/ref/Reference", 23)) { + // The reference handler thread can dead lock with the GC if compilation is blocking, + // so we avoid blocking compiles for anything in the java.lang.ref.Reference class, + // including inner classes such as ReferenceHandler. + return false; + } + return true; + } + return false; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/compiler/disassembler.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,12 @@ #ifdef TARGET_ARCH_zero # include "depChecker_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "depChecker_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "depChecker_ppc.hpp" +#endif #ifdef SHARK #include "shark/sharkEntry.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/compiler/disassembler.hpp --- a/src/share/vm/compiler/disassembler.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/compiler/disassembler.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -70,6 +70,12 @@ #ifdef TARGET_ARCH_zero # include "disassembler_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "disassembler_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "disassembler_ppc.hpp" +#endif public: diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp --- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,7 +99,7 @@ if (G1ConcRSLogCacheSize > 0) { _g1h = G1CollectedHeap::heap(); _max_n_card_counts = - (unsigned) (_g1h->g1_reserved_obj_bytes() >> CardTableModRefBS::card_shift); + (unsigned) (_g1h->max_capacity() >> CardTableModRefBS::card_shift); size_t max_card_num = ((size_t)1 << (sizeof(unsigned)*BitsPerByte-1)) - 1; guarantee(_max_n_card_counts < max_card_num, "card_num representation"); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -251,6 +251,14 @@ // Now do the remainder of the cleanup operation. _cm->completeCleanup(); + // Notify anyone who's waiting that there are no more free + // regions coming. We have to do this before we join the STS, + // otherwise we might deadlock: a GC worker could be blocked + // waiting for the notification whereas this thread will be + // blocked for the pause to finish while it's trying to join + // the STS, which is conditional on the GC workers finishing. + g1h->reset_free_regions_coming(); + _sts.join(); g1_policy->record_concurrent_mark_cleanup_completed(); _sts.leave(); @@ -262,9 +270,6 @@ gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]", cleanup_end_sec - cleanup_start_sec); } - - // We're done: no more free regions coming. - g1h->reset_free_regions_coming(); } guarantee(cm()->cleanup_list_is_empty(), "at this point there should be no regions on the cleanup list"); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -546,8 +546,11 @@ res = new_region_try_secondary_free_list(word_size); } if (res == NULL && do_expand) { - expand(word_size * HeapWordSize); - res = _free_list.remove_head_or_null(); + if (expand(word_size * HeapWordSize)) { + // The expansion succeeded and so we should have at least one + // region on the free list. + res = _free_list.remove_head(); + } } if (res != NULL) { if (G1PrintHeapRegions) { @@ -631,9 +634,22 @@ if (first == -1) { // The only thing we can do now is attempt expansion. if (fs + x_size >= num_regions) { - expand((num_regions - fs) * HeapRegion::GrainBytes); - first = humongous_obj_allocate_find_first(num_regions, word_size); - assert(first != -1, "this should have worked"); + // If the number of regions we're trying to allocate for this + // object is at most the number of regions in the free suffix, + // then the call to humongous_obj_allocate_find_first() above + // should have succeeded and we wouldn't be here. + // + // We should only be trying to expand when the free suffix is + // not sufficient for the object _and_ we have some expansion + // room available. + assert(num_regions > fs, "earlier allocation should have succeeded"); + + if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { + first = humongous_obj_allocate_find_first(num_regions, word_size); + // If the expansion was successful then the allocation + // should have been successful. + assert(first != -1, "this should have worked"); + } } } @@ -1647,16 +1663,17 @@ if (capacity_after_gc < minimum_desired_capacity) { // Don't expand unless it's significant size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; - expand(expand_bytes); - if (PrintGC && Verbose) { - gclog_or_tty->print_cr(" " - " expanding:" - " max_heap_size: %6.1fK" - " minimum_desired_capacity: %6.1fK" - " expand_bytes: %6.1fK", - (double) max_heap_size / (double) K, - (double) minimum_desired_capacity / (double) K, - (double) expand_bytes / (double) K); + if (expand(expand_bytes)) { + if (PrintGC && Verbose) { + gclog_or_tty->print_cr(" " + " expanding:" + " max_heap_size: %6.1fK" + " minimum_desired_capacity: %6.1fK" + " expand_bytes: %6.1fK", + (double) max_heap_size / (double) K, + (double) minimum_desired_capacity / (double) K, + (double) expand_bytes / (double) K); + } } // No expansion, now see if we want to shrink @@ -1757,66 +1774,84 @@ verify_region_sets_optional(); - size_t expand_bytes = word_size * HeapWordSize; - if (expand_bytes < MinHeapDeltaBytes) { - expand_bytes = MinHeapDeltaBytes; - } - expand(expand_bytes); - - verify_region_sets_optional(); - - return attempt_allocation_at_safepoint(word_size, - false /* expect_null_cur_alloc_region */); + size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); + if (expand(expand_bytes)) { + verify_region_sets_optional(); + return attempt_allocation_at_safepoint(word_size, + false /* expect_null_cur_alloc_region */); + } + return NULL; } -// FIXME: both this and shrink could probably be more efficient by -// doing one "VirtualSpace::expand_by" call rather than several. -void G1CollectedHeap::expand(size_t expand_bytes) { +bool G1CollectedHeap::expand(size_t expand_bytes) { size_t old_mem_size = _g1_storage.committed_size(); - // We expand by a minimum of 1K. - expand_bytes = MAX2(expand_bytes, (size_t)K); - size_t aligned_expand_bytes = - ReservedSpace::page_align_size_up(expand_bytes); + size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); aligned_expand_bytes = align_size_up(aligned_expand_bytes, HeapRegion::GrainBytes); - expand_bytes = aligned_expand_bytes; - while (expand_bytes > 0) { - HeapWord* base = (HeapWord*)_g1_storage.high(); - // Commit more storage. - bool successful = _g1_storage.expand_by(HeapRegion::GrainBytes); - if (!successful) { - expand_bytes = 0; - } else { - expand_bytes -= HeapRegion::GrainBytes; - // Expand the committed region. - HeapWord* high = (HeapWord*) _g1_storage.high(); - _g1_committed.set_end(high); + + if (Verbose && PrintGC) { + gclog_or_tty->print("Expanding garbage-first heap from %ldK by %ldK", + old_mem_size/K, aligned_expand_bytes/K); + } + + HeapWord* old_end = (HeapWord*)_g1_storage.high(); + bool successful = _g1_storage.expand_by(aligned_expand_bytes); + if (successful) { + HeapWord* new_end = (HeapWord*)_g1_storage.high(); + + // Expand the committed region. + _g1_committed.set_end(new_end); + + // Tell the cardtable about the expansion. + Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); + + // And the offset table as well. + _bot_shared->resize(_g1_committed.word_size()); + + expand_bytes = aligned_expand_bytes; + HeapWord* base = old_end; + + // Create the heap regions for [old_end, new_end) + while (expand_bytes > 0) { + HeapWord* high = base + HeapRegion::GrainWords; + // Create a new HeapRegion. MemRegion mr(base, high); bool is_zeroed = !_g1_max_committed.contains(base); HeapRegion* hr = new HeapRegion(_bot_shared, mr, is_zeroed); - // Now update max_committed if necessary. - _g1_max_committed.set_end(MAX2(_g1_max_committed.end(), high)); - // Add it to the HeapRegionSeq. _hrs->insert(hr); _free_list.add_as_tail(hr); + // And we used up an expansion region to create it. _expansion_regions--; - // Tell the cardtable about it. - Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); - // And the offset table as well. - _bot_shared->resize(_g1_committed.word_size()); + + expand_bytes -= HeapRegion::GrainBytes; + base += HeapRegion::GrainWords; + } + assert(base == new_end, "sanity"); + + // Now update max_committed if necessary. + _g1_max_committed.set_end(MAX2(_g1_max_committed.end(), new_end)); + + } else { + // The expansion of the virtual storage space was unsuccessful. + // Let's see if it was because we ran out of swap. + if (G1ExitOnExpansionFailure && + _g1_storage.uncommitted_size() >= aligned_expand_bytes) { + // We had head room... + vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion"); } } if (Verbose && PrintGC) { size_t new_mem_size = _g1_storage.committed_size(); - gclog_or_tty->print_cr("Expanding garbage-first heap from %ldK by %ldK to %ldK", - old_mem_size/K, aligned_expand_bytes/K, + gclog_or_tty->print_cr("...%s, expanded to %ldK", + (successful ? "Successful" : "Failed"), new_mem_size/K); } + return successful; } void G1CollectedHeap::shrink_helper(size_t shrink_bytes) @@ -2088,7 +2123,10 @@ HeapRegionRemSet::init_heap(max_regions()); // Now expand into the initial heap size. - expand(init_byte_size); + if (!expand(init_byte_size)) { + vm_exit_during_initialization("Failed to allocate initial heap."); + return JNI_ENOMEM; + } // Perform any initialization actions delegated to the policy. g1_policy()->init(); @@ -2744,7 +2782,7 @@ } size_t G1CollectedHeap::max_capacity() const { - return g1_reserved_obj_bytes(); + return _g1_reserved.byte_size(); } jlong G1CollectedHeap::millis_since_last_gc() { @@ -3538,7 +3576,12 @@ size_t expand_bytes = g1_policy()->expansion_amount(); if (expand_bytes > 0) { size_t bytes_before = capacity(); - expand(expand_bytes); + if (!expand(expand_bytes)) { + // We failed to expand the heap so let's verify that + // committed/uncommitted amount match the backing store + assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); + assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch"); + } } } @@ -3762,7 +3805,7 @@ if (alloc_region == NULL) { // we will get a new GC alloc region - alloc_region = new_gc_alloc_region(ap, 0); + alloc_region = new_gc_alloc_region(ap, HeapRegion::GrainWords); } else { // the region was retained from the last collection ++_gc_alloc_region_counts[ap]; @@ -5311,7 +5354,7 @@ size_t G1CollectedHeap::max_regions() { return - (size_t)align_size_up(g1_reserved_obj_bytes(), HeapRegion::GrainBytes) / + (size_t)align_size_up(max_capacity(), HeapRegion::GrainBytes) / HeapRegion::GrainBytes; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -619,8 +619,10 @@ public: // Expand the garbage-first heap by at least the given size (in bytes!). + // Returns true if the heap was expanded by the requested amount; + // false otherwise. // (Rounds up to a HeapRegion boundary.) - virtual void expand(size_t expand_bytes); + bool expand(size_t expand_bytes); // Do anything common to GC's. virtual void gc_prologue(bool full); @@ -981,9 +983,6 @@ // Reference Processing accessor ReferenceProcessor* ref_processor() { return _ref_processor; } - // Reserved (g1 only; super method includes perm), capacity and the used - // portion in bytes. - size_t g1_reserved_obj_bytes() const { return _g1_reserved.byte_size(); } virtual size_t capacity() const; virtual size_t used() const; // This should be called when we're not holding the heap lock. The diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -2011,7 +2011,7 @@ // space, whichever is smaller, bounded below by a minimum // expansion (unless that's all that's left.) const size_t min_expand_bytes = 1*M; - size_t reserved_bytes = _g1->g1_reserved_obj_bytes(); + size_t reserved_bytes = _g1->max_capacity(); size_t committed_bytes = _g1->capacity(); size_t uncommitted_bytes = reserved_bytes - committed_bytes; size_t expand_bytes; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -735,7 +735,7 @@ MemRegion dirtyRegion(start, end); #if CARD_REPEAT_HISTO - init_ct_freq_table(_g1->g1_reserved_obj_bytes()); + init_ct_freq_table(_g1->max_capacity()); ct_freq_note_card(_ct_bs->index_for(start)); #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/g1/g1_globals.hpp --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -301,9 +301,13 @@ develop(uintx, G1StressConcRegionFreeingDelayMillis, 0, \ "Artificial delay during concurrent region freeing") \ \ - develop(bool, ReduceInitialCardMarksForG1, false, \ + develop(bool, ReduceInitialCardMarksForG1, false, \ "When ReduceInitialCardMarks is true, this flag setting " \ - " controls whether G1 allows the RICM optimization") + " controls whether G1 allows the RICM optimization") \ + \ + develop(bool, G1ExitOnExpansionFailure, false, \ + "Raise a fatal VM exit out of memory failure in the event " \ + " that heap expansion fails due to running out of swap.") G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG) diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/shared/allocationStats.hpp --- a/src/share/vm/gc_implementation/shared/allocationStats.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/shared/allocationStats.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -116,10 +116,8 @@ _demand_rate_estimate.sample(rate); float new_rate = _demand_rate_estimate.padded_average(); ssize_t old_desired = _desired; - _desired = (ssize_t)(new_rate * (inter_sweep_estimate - + CMSExtrapolateSweep - ? intra_sweep_estimate - : 0.0)); + float delta_ise = (CMSExtrapolateSweep ? intra_sweep_estimate : 0.0); + _desired = (ssize_t)(new_rate * (inter_sweep_estimate + delta_ise)); if (PrintFLSStatistics > 1) { gclog_or_tty->print_cr("demand: %d, old_rate: %f, current_rate: %f, new_rate: %f, old_desired: %d, new_desired: %d", demand, old_rate, rate, new_rate, old_desired, _desired); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/gc_implementation/shared/gcUtil.cpp --- a/src/share/vm/gc_implementation/shared/gcUtil.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/gc_implementation/shared/gcUtil.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -106,8 +106,8 @@ } LinearLeastSquareFit::LinearLeastSquareFit(unsigned weight) : - _sum_x(0), _sum_y(0), _sum_xy(0), - _mean_x(weight), _mean_y(weight) {} + _sum_x(0), _sum_x_squared(0), _sum_y(0), _sum_xy(0), + _intercept(0), _slope(0), _mean_x(weight), _mean_y(weight) {} void LinearLeastSquareFit::update(double x, double y) { _sum_x = _sum_x + x; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/abstractInterpreter.hpp --- a/src/share/vm/interpreter/abstractInterpreter.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "interp_masm_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "interp_masm_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "interp_masm_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecode.hpp --- a/src/share/vm/interpreter/bytecode.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecode.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -37,6 +37,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif class ciBytecodeStream; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodeInterpreter.cpp --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -59,6 +59,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "orderAccess_windows_x86.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "orderAccess_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "orderAccess_linux_ppc.inline.hpp" +#endif // no precompiled headers diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodeInterpreter.hpp --- a/src/share/vm/interpreter/bytecodeInterpreter.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif #ifdef CC_INTERP @@ -587,6 +593,12 @@ #ifdef TARGET_ARCH_zero # include "bytecodeInterpreter_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytecodeInterpreter_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytecodeInterpreter_ppc.hpp" +#endif }; // BytecodeInterpreter diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodeInterpreter.inline.hpp --- a/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -52,6 +52,12 @@ #ifdef TARGET_ARCH_zero # include "bytecodeInterpreter_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytecodeInterpreter_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytecodeInterpreter_ppc.inline.hpp" +#endif #endif // CC_INTERP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodeStream.hpp --- a/src/share/vm/interpreter/bytecodeStream.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodeStream.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -37,6 +37,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // A BytecodeStream is used for fast iteration over the bytecodes // of a methodOop. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodes.cpp --- a/src/share/vm/interpreter/bytecodes.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodes.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif #if defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER < 1600)) diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/bytecodes.hpp --- a/src/share/vm/interpreter/bytecodes.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/bytecodes.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -294,6 +294,12 @@ #ifdef TARGET_ARCH_zero # include "bytecodes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytecodes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytecodes_ppc.hpp" +#endif number_of_codes diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/cppInterpreter.hpp --- a/src/share/vm/interpreter/cppInterpreter.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/cppInterpreter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -90,6 +90,12 @@ #ifdef TARGET_ARCH_zero # include "cppInterpreter_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "cppInterpreter_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "cppInterpreter_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/cppInterpreterGenerator.hpp --- a/src/share/vm/interpreter/cppInterpreterGenerator.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/cppInterpreterGenerator.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -53,6 +53,12 @@ #ifdef TARGET_ARCH_zero # include "cppInterpreterGenerator_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "cppInterpreterGenerator_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "cppInterpreterGenerator_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/interpreter.hpp --- a/src/share/vm/interpreter/interpreter.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/interpreter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -152,6 +152,12 @@ #ifdef TARGET_ARCH_zero # include "interpreter_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "interpreter_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "interpreter_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/interpreterGenerator.hpp --- a/src/share/vm/interpreter/interpreterGenerator.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/interpreterGenerator.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -50,6 +50,12 @@ #ifdef TARGET_ARCH_zero # include "interpreterGenerator_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "interpreterGenerator_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "interpreterGenerator_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -65,6 +65,12 @@ #ifdef TARGET_ARCH_zero # include "vm_version_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vm_version_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vm_version_ppc.hpp" +#endif #ifdef COMPILER2 #include "opto/runtime.hpp" #endif @@ -1178,9 +1184,7 @@ handler_index = _fingerprints->length() - 1; } } - } else { - CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); - } + // Set handler under SignatureHandlerLibrary_lock if (handler_index < 0) { // use generic signature handler method->set_signature_handler(Interpreter::slow_signature_handler()); @@ -1188,21 +1192,29 @@ // set handler method->set_signature_handler(_handlers->at(handler_index)); } + } else { + CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); + // use generic signature handler + method->set_signature_handler(Interpreter::slow_signature_handler()); + } } #ifdef ASSERT - int handler_index, fingerprint_index; + int handler_index = -1; + int fingerprint_index = -2; { // '_handlers' and '_fingerprints' are 'GrowableArray's and are NOT synchronized // in any way if accessed from multiple threads. To avoid races with another // thread which may change the arrays in the above, mutex protected block, we // have to protect this read access here with the same mutex as well! MutexLocker mu(SignatureHandlerLibrary_lock); + if (_handlers != NULL) { handler_index = _handlers->find(method->signature_handler()); fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint()); } + } assert(method->signature_handler() == Interpreter::slow_signature_handler() || handler_index == fingerprint_index, "sanity check"); -#endif +#endif // ASSERT } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/interpreterRuntime.hpp --- a/src/share/vm/interpreter/interpreterRuntime.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -157,6 +157,12 @@ #ifdef TARGET_ARCH_zero # include "interpreterRT_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "interpreterRT_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "interpreterRT_ppc.hpp" +#endif // Interpreter's frequency counter overflow diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/templateInterpreter.hpp --- a/src/share/vm/interpreter/templateInterpreter.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/templateInterpreter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -192,6 +192,12 @@ #ifdef TARGET_ARCH_zero # include "templateInterpreter_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "templateInterpreter_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "templateInterpreter_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/templateInterpreterGenerator.hpp --- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -96,6 +96,12 @@ #ifdef TARGET_ARCH_zero # include "templateInterpreterGenerator_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "templateInterpreterGenerator_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "templateInterpreterGenerator_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/interpreter/templateTable.hpp --- a/src/share/vm/interpreter/templateTable.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/interpreter/templateTable.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -40,6 +40,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "interp_masm_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "interp_masm_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "interp_masm_ppc.hpp" +#endif #ifndef CC_INTERP // All the necessary definitions used for (bytecode) template generation. Instead of @@ -364,6 +370,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "templateTable_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "templateTable_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "templateTable_ppc.hpp" +#endif }; #endif /* !CC_INTERP */ diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/oops/constantPoolOop.hpp --- a/src/share/vm/oops/constantPoolOop.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/oops/constantPoolOop.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // A constantPool is an array containing class constants as described in the // class file. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/oops/oop.inline.hpp --- a/src/share/vm/oops/oop.inline.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/oops/oop.inline.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -52,6 +52,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // Implementation of all inlined member functions defined in oop.hpp // We need a separate file to avoid circular references diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/oops/typeArrayOop.hpp --- a/src/share/vm/oops/typeArrayOop.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/oops/typeArrayOop.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -45,6 +45,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "orderAccess_windows_x86.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "orderAccess_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "orderAccess_linux_ppc.inline.hpp" +#endif // A typeArrayOop is an array containing basic types (non oop elements). // It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs} diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/buildOopMap.cpp --- a/src/share/vm/opto/buildOopMap.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/buildOopMap.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -41,6 +41,12 @@ #ifdef TARGET_ARCH_zero # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmreg_ppc.inline.hpp" +#endif // The functions in this file builds OopMaps after all scheduling is done. // diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/c2_globals.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -32,6 +32,9 @@ #ifdef TARGET_ARCH_sparc # include "c2_globals_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c2_globals_arm.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "c2_globals_linux.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/c2compiler.cpp --- a/src/share/vm/opto/c2compiler.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/c2compiler.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -37,6 +37,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif volatile int C2Compiler::_runtimes = uninitialized; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/compile.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -74,6 +74,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif // -------------------- Compile::mach_constant_base_node ----------------------- diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/gcm.cpp --- a/src/share/vm/opto/gcm.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/gcm.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -47,6 +47,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif // Portions of code courtesy of Clifford Click diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/locknode.hpp --- a/src/share/vm/opto/locknode.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/locknode.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -40,6 +40,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif //------------------------------BoxLockNode------------------------------------ class BoxLockNode : public Node { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/output.hpp --- a/src/share/vm/opto/output.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/output.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif class Arena; class Bundle; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/regmask.cpp --- a/src/share/vm/opto/regmask.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/regmask.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -37,6 +37,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif #define RM_SIZE _RM_SIZE /* a constant private to the class RegMask */ diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/regmask.hpp --- a/src/share/vm/opto/regmask.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/regmask.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -40,6 +40,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/adGlobals_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/adGlobals_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/adGlobals_ppc.hpp" +#endif // Some fun naming (textual) substitutions: // diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/opto/runtime.cpp --- a/src/share/vm/opto/runtime.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/opto/runtime.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -80,6 +80,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif // For debugging purposes: diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/forte.cpp --- a/src/share/vm/prims/forte.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/forte.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -520,6 +520,7 @@ // method_id - jmethodID of the method being executed extern "C" { +JNIEXPORT void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) { // This is if'd out because we no longer use thread suspension. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jniCheck.cpp --- a/src/share/vm/prims/jniCheck.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jniCheck.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -45,6 +45,12 @@ #ifdef TARGET_ARCH_zero # include "jniTypes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "jniTypes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "jniTypes_ppc.hpp" +#endif // Heap objects are allowed to be directly referenced only in VM code, diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jni_md.h --- a/src/share/vm/prims/jni_md.h Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jni_md.h Mon Feb 21 19:17:33 2011 +0100 @@ -33,6 +33,12 @@ #ifdef TARGET_ARCH_zero # include "jni_zero.h" #endif +#ifdef TARGET_ARCH_arm +# include "jni_arm.h" +#endif +#ifdef TARGET_ARCH_ppc +# include "jni_ppc.h" +#endif /* diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvm.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -2585,7 +2585,7 @@ } -int jio_printf(const char *fmt, ...) { +JNIEXPORT int jio_printf(const char *fmt, ...) { int len; va_list args; va_start(args, fmt); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvm.h Mon Feb 21 19:17:33 2011 +0100 @@ -1417,16 +1417,16 @@ * BE CAREFUL! The following functions do not implement the * full feature set of standard C printf formats. */ -int +JNIEXPORT int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args); -int +JNIEXPORT int jio_snprintf(char *str, size_t count, const char *fmt, ...); -int +JNIEXPORT int jio_fprintf(FILE *, const char *fmt, ...); -int +JNIEXPORT int jio_vfprintf(FILE *, const char *fmt, va_list args); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvmtiClassFileReconstituter.cpp --- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -36,6 +36,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // FIXME: add Deprecated, LVT, LVTT attributes // FIXME: fix Synthetic attribute // FIXME: per Serguei, add error return handling for constantPoolOopDesc::copy_cpool_bytes() diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvmtiExport.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -750,15 +750,12 @@ // pending CompiledMethodUnload support // -bool JvmtiExport::_have_pending_compiled_method_unload_events; -GrowableArray* JvmtiExport::_pending_compiled_method_unload_method_ids; -GrowableArray* JvmtiExport::_pending_compiled_method_unload_code_begins; -JavaThread* JvmtiExport::_current_poster; - -void JvmtiExport::post_compiled_method_unload_internal(JavaThread* self, jmethodID method, const void *code_begin) { +void JvmtiExport::post_compiled_method_unload( + jmethodID method, const void *code_begin) { + JavaThread* thread = JavaThread::current(); EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, ("JVMTI [%s] method compile unload event triggered", - JvmtiTrace::safe_get_thread_name(self))); + JvmtiTrace::safe_get_thread_name(thread))); // post the event for each environment that has this event enabled. JvmtiEnvIterator it; @@ -767,12 +764,12 @@ EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, - JvmtiTrace::safe_get_thread_name(self), method)); + JvmtiTrace::safe_get_thread_name(thread), method)); - ResourceMark rm(self); + ResourceMark rm(thread); - JvmtiEventMark jem(self); - JvmtiJavaThreadEventTransition jet(self); + JvmtiEventMark jem(thread); + JvmtiJavaThreadEventTransition jet(thread); jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; if (callback != NULL) { (*callback)(env->jvmti_external(), method, code_begin); @@ -781,90 +778,6 @@ } } -// post any pending CompiledMethodUnload events - -void JvmtiExport::post_pending_compiled_method_unload_events() { - JavaThread* self = JavaThread::current(); - assert(!self->owns_locks(), "can't hold locks"); - - // Indicates if this is the first activiation of this function. - // In theory the profiler's callback could call back into VM and provoke - // another CompiledMethodLoad event to be posted from this thread. As the - // stack rewinds we need to ensure that the original activation does the - // completion and notifies any waiters. - bool first_activation = false; - - // the jmethodID (may not be valid) to be used for a single event - jmethodID method; - const void *code_begin; - - // grab the monitor and check if another thread is already posting - // events. If there is another thread posting events then we wait - // until it completes. (In theory we could check the pending events to - // see if any of the addresses overlap with the event that we want to - // post but as it will happen so rarely we just block any thread waiting - // to post a CompiledMethodLoad or DynamicCodeGenerated event until all - // pending CompiledMethodUnload events have been posted). - // - // If another thread isn't posting we examine the list of pending jmethodIDs. - // If the list is empty then we are done. If it's not empty then this thread - // (self) becomes the pending event poster and we remove the top (last) - // event from the list. Note that this means we remove the newest event first - // but as they are all CompiledMethodUnload events the order doesn't matter. - // Once we have removed a jmethodID then we exit the monitor. Any other thread - // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will - // be forced to wait on the monitor. - { - MutexLocker mu(JvmtiPendingEvent_lock); - if (_current_poster != self) { - while (_current_poster != NULL) { - JvmtiPendingEvent_lock->wait(); - } - } - if ((_pending_compiled_method_unload_method_ids == NULL) || - (_pending_compiled_method_unload_method_ids->length() == 0)) { - return; - } - if (_current_poster == NULL) { - _current_poster = self; - first_activation = true; - } else { - // re-entrant - guarantee(_current_poster == self, "checking"); - } - method = _pending_compiled_method_unload_method_ids->pop(); - code_begin = _pending_compiled_method_unload_code_begins->pop(); - } - - // This thread is the pending event poster so it first posts the CompiledMethodUnload - // event for the jmethodID that has been removed from the list. Once posted it - // re-grabs the monitor and checks the list again. If the list is empty then and this - // is the first activation of the function then we reset the _have_pending_events - // flag, cleanup _current_poster to indicate that no thread is now servicing the - // pending events list, and finally notify any thread that might be waiting. - for (;;) { - post_compiled_method_unload_internal(self, method, code_begin); - - // event posted, now re-grab monitor and get the next event - // If there's no next event then we are done. If this is the first - // activiation of this function by this thread notify any waiters - // so that they can post. - { - MutexLocker ml(JvmtiPendingEvent_lock); - if (_pending_compiled_method_unload_method_ids->length() == 0) { - if (first_activation) { - _have_pending_compiled_method_unload_events = false; - _current_poster = NULL; - JvmtiPendingEvent_lock->notify_all(); - } - return; - } - method = _pending_compiled_method_unload_method_ids->pop(); - code_begin = _pending_compiled_method_unload_code_begins->pop(); - } - } -} - /////////////////////////////////////////////////////////////// // // JvmtiExport @@ -1830,16 +1743,7 @@ } void JvmtiExport::post_compiled_method_load(nmethod *nm) { - // If there are pending CompiledMethodUnload events then these are - // posted before this CompiledMethodLoad event. We "lock" the nmethod and - // maintain a handle to the methodOop to ensure that the nmethod isn't - // flushed or unloaded while posting the events. JavaThread* thread = JavaThread::current(); - if (have_pending_compiled_method_unload_events()) { - methodHandle mh(thread, nm->method()); - nmethodLocker nml(nm); - post_pending_compiled_method_unload_events(); - } EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD, ("JVMTI [%s] method compile load event triggered", @@ -1854,8 +1758,8 @@ JvmtiTrace::safe_get_thread_name(thread), (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(), (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string())); - ResourceMark rm(thread); + HandleMark hm(thread); // Add inlining information jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm); @@ -1899,28 +1803,6 @@ } } -// used at a safepoint to post a CompiledMethodUnload event -void JvmtiExport::post_compiled_method_unload(jmethodID mid, const void *code_begin) { - if (SafepointSynchronize::is_at_safepoint()) { - // Class unloading can cause nmethod unloading which is reported - // by the VMThread. These must be batched to be processed later. - if (_pending_compiled_method_unload_method_ids == NULL) { - // create list lazily - _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray(10,true); - _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray(10,true); - } - _pending_compiled_method_unload_method_ids->append(mid); - _pending_compiled_method_unload_code_begins->append(code_begin); - _have_pending_compiled_method_unload_events = true; - } else { - // Unloading caused by the sweeper can be reported synchronously. - if (have_pending_compiled_method_unload_events()) { - post_pending_compiled_method_unload_events(); - } - post_compiled_method_unload_internal(JavaThread::current(), mid, code_begin); - } -} - void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { JavaThread* thread = JavaThread::current(); EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, @@ -1953,9 +1835,9 @@ return; } - if (have_pending_compiled_method_unload_events()) { - post_pending_compiled_method_unload_events(); - } + // Blocks until everything now in the queue has been posted + JvmtiDeferredEventQueue::flush_queue(Thread::current()); + post_dynamic_code_generated_internal(name, code_begin, code_end); } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvmtiExport.hpp --- a/src/share/vm/prims/jvmtiExport.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvmtiExport.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -141,25 +141,6 @@ private: - // CompiledMethodUnload events are reported from the VM thread so they - // are collected in lists (of jmethodID/addresses) and the events are posted later - // from threads posting CompieldMethodLoad or DynamicCodeGenerated events. - static bool _have_pending_compiled_method_unload_events; - static GrowableArray* _pending_compiled_method_unload_method_ids; - static GrowableArray* _pending_compiled_method_unload_code_begins; - static JavaThread* _current_poster; - - // tests if there are CompiledMethodUnload events pending - inline static bool have_pending_compiled_method_unload_events() { - return _have_pending_compiled_method_unload_events; - } - - // posts any pending CompiledMethodUnload events. - static void post_pending_compiled_method_unload_events(); - - // Perform the actual notification to interested JvmtiEnvs. - static void post_compiled_method_unload_internal(JavaThread* self, jmethodID mid, const void* code_begin); - // posts a DynamicCodeGenerated event (internal/private implementation). // The public post_dynamic_code_generated* functions make use of the // internal implementation. @@ -256,7 +237,7 @@ // single stepping management methods static void at_single_stepping_point(JavaThread *thread, methodOop method, address location) KERNEL_RETURN; static void expose_single_stepping(JavaThread *thread) KERNEL_RETURN; - static bool hide_single_stepping(JavaThread *thread) KERNEL_RETURN_(return false;); + static bool hide_single_stepping(JavaThread *thread) KERNEL_RETURN_(false); // Methods that notify the debugger that something interesting has happened in the VM. static void post_vm_start (); @@ -271,20 +252,20 @@ static oop jni_GetField_probe (JavaThread *thread, jobject jobj, oop obj, klassOop klass, jfieldID fieldID, bool is_static) - KERNEL_RETURN_(return NULL;); + KERNEL_RETURN_(NULL); static oop jni_GetField_probe_nh (JavaThread *thread, jobject jobj, oop obj, klassOop klass, jfieldID fieldID, bool is_static) - KERNEL_RETURN_(return NULL;); + KERNEL_RETURN_(NULL); static void post_field_access_by_jni (JavaThread *thread, oop obj, klassOop klass, jfieldID fieldID, bool is_static) KERNEL_RETURN; static void post_field_access (JavaThread *thread, methodOop method, address location, KlassHandle field_klass, Handle object, jfieldID field) KERNEL_RETURN; static oop jni_SetField_probe (JavaThread *thread, jobject jobj, oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type, - jvalue *value) KERNEL_RETURN_(return NULL;); + jvalue *value) KERNEL_RETURN_(NULL); static oop jni_SetField_probe_nh (JavaThread *thread, jobject jobj, oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type, - jvalue *value) KERNEL_RETURN_(return NULL;); + jvalue *value) KERNEL_RETURN_(NULL); static void post_field_modification_by_jni(JavaThread *thread, oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type, jvalue *value); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvmtiImpl.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,11 +32,13 @@ #include "prims/jvmtiEventController.inline.hpp" #include "prims/jvmtiImpl.hpp" #include "prims/jvmtiRedefineClasses.hpp" +#include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/javaCalls.hpp" +#include "runtime/serviceThread.hpp" #include "runtime/signature.hpp" #include "runtime/vframe.hpp" #include "runtime/vframe_hp.hpp" @@ -910,3 +912,207 @@ tty->print_cr("]"); #endif } + +#ifndef KERNEL + +JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( + nmethod* nm) { + JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); + event.set_compiled_method_load(nm); + nmethodLocker::lock_nmethod(nm); // will be unlocked when posted + return event; +} + +JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( + jmethodID id, const void* code) { + JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); + event.set_compiled_method_unload(id, code); + return event; +} + +void JvmtiDeferredEvent::post() { + switch(_type) { + case TYPE_COMPILED_METHOD_LOAD: + JvmtiExport::post_compiled_method_load(compiled_method_load()); + nmethodLocker::unlock_nmethod(compiled_method_load()); + break; + case TYPE_COMPILED_METHOD_UNLOAD: + JvmtiExport::post_compiled_method_unload( + compiled_method_unload_method_id(), + compiled_method_unload_code_begin()); + break; + case TYPE_FLUSH: + JvmtiDeferredEventQueue::flush_complete(flush_state_addr()); + break; + default: + ShouldNotReachHere(); + } +} + +JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL; +JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL; + +volatile JvmtiDeferredEventQueue::QueueNode* + JvmtiDeferredEventQueue::_pending_list = NULL; + +bool JvmtiDeferredEventQueue::has_events() { + assert(Service_lock->owned_by_self(), "Must own Service_lock"); + return _queue_head != NULL || _pending_list != NULL; +} + +void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) { + assert(Service_lock->owned_by_self(), "Must own Service_lock"); + + process_pending_events(); + + // Events get added to the end of the queue (and are pulled off the front). + QueueNode* node = new QueueNode(event); + if (_queue_tail == NULL) { + _queue_tail = _queue_head = node; + } else { + assert(_queue_tail->next() == NULL, "Must be the last element in the list"); + _queue_tail->set_next(node); + _queue_tail = node; + } + + Service_lock->notify_all(); + assert((_queue_head == NULL) == (_queue_tail == NULL), + "Inconsistent queue markers"); +} + +JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() { + assert(Service_lock->owned_by_self(), "Must own Service_lock"); + + process_pending_events(); + + assert(_queue_head != NULL, "Nothing to dequeue"); + + if (_queue_head == NULL) { + // Just in case this happens in product; it shouldn't but let's not crash + return JvmtiDeferredEvent(); + } + + QueueNode* node = _queue_head; + _queue_head = _queue_head->next(); + if (_queue_head == NULL) { + _queue_tail = NULL; + } + + assert((_queue_head == NULL) == (_queue_tail == NULL), + "Inconsistent queue markers"); + + JvmtiDeferredEvent event = node->event(); + delete node; + return event; +} + +void JvmtiDeferredEventQueue::add_pending_event( + const JvmtiDeferredEvent& event) { + + QueueNode* node = new QueueNode(event); + + bool success = false; + QueueNode* prev_value = (QueueNode*)_pending_list; + do { + node->set_next(prev_value); + prev_value = (QueueNode*)Atomic::cmpxchg_ptr( + (void*)node, (volatile void*)&_pending_list, (void*)node->next()); + } while (prev_value != node->next()); +} + +// This method transfers any events that were added by someone NOT holding +// the lock into the mainline queue. +void JvmtiDeferredEventQueue::process_pending_events() { + assert(Service_lock->owned_by_self(), "Must own Service_lock"); + + if (_pending_list != NULL) { + QueueNode* head = + (QueueNode*)Atomic::xchg_ptr(NULL, (volatile void*)&_pending_list); + + assert((_queue_head == NULL) == (_queue_tail == NULL), + "Inconsistent queue markers"); + + if (head != NULL) { + // Since we've treated the pending list as a stack (with newer + // events at the beginning), we need to join the bottom of the stack + // with the 'tail' of the queue in order to get the events in the + // right order. We do this by reversing the pending list and appending + // it to the queue. + + QueueNode* new_tail = head; + QueueNode* new_head = NULL; + + // This reverses the list + QueueNode* prev = new_tail; + QueueNode* node = new_tail->next(); + new_tail->set_next(NULL); + while (node != NULL) { + QueueNode* next = node->next(); + node->set_next(prev); + prev = node; + node = next; + } + new_head = prev; + + // Now append the new list to the queue + if (_queue_tail != NULL) { + _queue_tail->set_next(new_head); + } else { // _queue_head == NULL + _queue_head = new_head; + } + _queue_tail = new_tail; + } + } +} + +enum { + // Random - used for debugging + FLUSHING = 0x50403020, + FLUSHED = 0x09080706 +}; + +void JvmtiDeferredEventQueue::flush_queue(Thread* thread) { + + volatile int flush_state = FLUSHING; + + JvmtiDeferredEvent flush(JvmtiDeferredEvent::TYPE_FLUSH); + flush.set_flush_state_addr((int*)&flush_state); + + if (ServiceThread::is_service_thread(thread)) { + // If we are the service thread we have to post all preceding events + // Use the flush event as a token to indicate when we can stop + JvmtiDeferredEvent event; + { + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + enqueue(flush); + event = dequeue(); + } + while (!event.is_flush_event() || + event.flush_state_addr() != &flush_state) { + event.post(); + { + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + event = dequeue(); + } + } + } else { + // Wake up the service thread so it will process events. When it gets + // to the flush event it will set 'flush_complete' and notify us. + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + enqueue(flush); + while (flush_state != FLUSHED) { + assert(flush_state == FLUSHING || flush_state == FLUSHED, + "only valid values for this"); + Service_lock->wait(Mutex::_no_safepoint_check_flag); + } + } +} + +void JvmtiDeferredEventQueue::flush_complete(int* state_addr) { + assert(state_addr != NULL && *state_addr == FLUSHING, "must be"); + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + *state_addr = FLUSHED; + Service_lock->notify_all(); +} + +#endif // ndef KERNEL diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/prims/jvmtiImpl.hpp --- a/src/share/vm/prims/jvmtiImpl.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/prims/jvmtiImpl.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -433,6 +433,149 @@ #endif // !JVMTI_KERNEL +/** + * When a thread (such as the compiler thread or VM thread) cannot post a + * JVMTI event itself because the event needs to be posted from a Java + * thread, then it can defer the event to the Service thread for posting. + * The information needed to post the event is encapsulated into this class + * and then enqueued onto the JvmtiDeferredEventQueue, where the Service + * thread will pick it up and post it. + * + * This is currently only used for posting compiled-method-load and unload + * events, which we don't want posted from the compiler thread. + */ +class JvmtiDeferredEvent VALUE_OBJ_CLASS_SPEC { + friend class JvmtiDeferredEventQueue; + private: + typedef enum { + TYPE_NONE, + TYPE_COMPILED_METHOD_LOAD, + TYPE_COMPILED_METHOD_UNLOAD, + TYPE_FLUSH // pseudo-event used to implement flush_queue() + } Type; + + Type _type; + union { + nmethod* compiled_method_load; + struct { + jmethodID method_id; + const void* code_begin; + } compiled_method_unload; + int* flush_state_addr; + } _event_data; + + JvmtiDeferredEvent(Type t) : _type(t) {} + + void set_compiled_method_load(nmethod* nm) { + assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); + _event_data.compiled_method_load = nm; + } + + nmethod* compiled_method_load() const { + assert(_type == TYPE_COMPILED_METHOD_LOAD, "must be"); + return _event_data.compiled_method_load; + } + + void set_compiled_method_unload(jmethodID id, const void* code) { + assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); + _event_data.compiled_method_unload.method_id = id; + _event_data.compiled_method_unload.code_begin = code; + } + + jmethodID compiled_method_unload_method_id() const { + assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); + return _event_data.compiled_method_unload.method_id; + } + + const void* compiled_method_unload_code_begin() const { + assert(_type == TYPE_COMPILED_METHOD_UNLOAD, "must be"); + return _event_data.compiled_method_unload.code_begin; + } + + bool is_flush_event() const { return _type == TYPE_FLUSH; } + + int* flush_state_addr() const { + assert(is_flush_event(), "must be"); + return _event_data.flush_state_addr; + } + + void set_flush_state_addr(int* flag) { + assert(is_flush_event(), "must be"); + _event_data.flush_state_addr = flag; + } + + public: + + JvmtiDeferredEvent() : _type(TYPE_NONE) {} + + // Factory methods + static JvmtiDeferredEvent compiled_method_load_event(nmethod* nm) + KERNEL_RETURN_(JvmtiDeferredEvent()); + static JvmtiDeferredEvent compiled_method_unload_event( + jmethodID id, const void* code) KERNEL_RETURN_(JvmtiDeferredEvent()); + + // Actually posts the event. + void post() KERNEL_RETURN; +}; + +/** + * Events enqueued on this queue wake up the Service thread which dequeues + * and posts the events. The Service_lock is required to be held + * when operating on the queue (except for the "pending" events). + */ +class JvmtiDeferredEventQueue : AllStatic { + friend class JvmtiDeferredEvent; + private: + class QueueNode : public CHeapObj { + private: + JvmtiDeferredEvent _event; + QueueNode* _next; + + public: + QueueNode(const JvmtiDeferredEvent& event) + : _event(event), _next(NULL) {} + + const JvmtiDeferredEvent& event() const { return _event; } + QueueNode* next() const { return _next; } + + void set_next(QueueNode* next) { _next = next; } + }; + + static QueueNode* _queue_head; // Hold Service_lock to access + static QueueNode* _queue_tail; // Hold Service_lock to access + static volatile QueueNode* _pending_list; // Uses CAS for read/update + + // Transfers events from the _pending_list to the _queue. + static void process_pending_events() KERNEL_RETURN; + + static void flush_complete(int* flush_state) KERNEL_RETURN; + + public: + // Must be holding Service_lock when calling these + static bool has_events() KERNEL_RETURN_(false); + static void enqueue(const JvmtiDeferredEvent& event) KERNEL_RETURN; + static JvmtiDeferredEvent dequeue() KERNEL_RETURN_(JvmtiDeferredEvent()); + + // This call blocks until all events enqueued prior to this call + // have been posted. The Service_lock is acquired and waited upon. + // + // Implemented by creating a "flush" event and placing it in the queue. + // When the flush event is "posted" it will call flush_complete(), which + // will release the caller. + // + // Can be called by any thread (maybe even the service thread itself). + // Not necessary for the caller to be a JavaThread. + static void flush_queue(Thread* current) KERNEL_RETURN; + + // Used to enqueue events without using a lock, for times (such as during + // safepoint) when we can't or don't want to lock the Service_lock. + // + // Events will be held off to the side until there's a call to + // dequeue(), enqueue(), or process_pending_events() (all of which require + // the holding of the Service_lock), and will be enqueued at that time. + static void add_pending_event(const JvmtiDeferredEvent&) KERNEL_RETURN; +}; + // Utility macro that checks for NULL pointers: #define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -59,6 +59,12 @@ #ifdef TARGET_ARCH_zero # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmreg_ppc.inline.hpp" +#endif #ifdef COMPILER2 #ifdef TARGET_ARCH_MODEL_x86_32 # include "adfiles/ad_x86_32.hpp" @@ -72,6 +78,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/ad_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/ad_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/ad_ppc.hpp" +#endif #endif bool DeoptimizationMarker::_is_active = false; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/dtraceJSDT.hpp --- a/src/share/vm/runtime/dtraceJSDT.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/dtraceJSDT.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +#endif class RegisteredProbes; typedef jlong OpaqueProbes; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/fprofiler.hpp --- a/src/share/vm/runtime/fprofiler.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/fprofiler.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -231,13 +231,13 @@ static void engage(JavaThread* mainThread, bool fullProfile) KERNEL_RETURN ; static void disengage() KERNEL_RETURN ; static void print(int unused) KERNEL_RETURN ; - static bool is_active() KERNEL_RETURN_(return false;) ; + static bool is_active() KERNEL_RETURN_(false) ; // This is NULL if each thread has its own thread profiler, // else this is the single thread profiler used by all threads. // In particular it makes a difference during garbage collection, // where you only want to traverse each thread profiler once. - static ThreadProfiler* get_thread_profiler() KERNEL_RETURN_(return NULL;); + static ThreadProfiler* get_thread_profiler() KERNEL_RETURN_(NULL); // Garbage Collection Support static void oops_do(OopClosure* f) KERNEL_RETURN ; @@ -246,13 +246,13 @@ // Returns the start address for a given pc // NULL is returned if the PCRecorder is inactive - static address bucket_start_for(address pc) KERNEL_RETURN_(return NULL;); + static address bucket_start_for(address pc) KERNEL_RETURN_(NULL); enum { MillisecsPerTick = 10 }; // ms per profiling ticks // Returns the number of ticks recorded for the bucket // pc belongs to. - static int bucket_count_for(address pc) KERNEL_RETURN_(return 0;); + static int bucket_count_for(address pc) KERNEL_RETURN_(0); #ifndef FPROF_KERNEL diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/frame.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -52,6 +52,12 @@ #ifdef TARGET_ARCH_zero # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +#endif RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { _thread = thread; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/frame.hpp --- a/src/share/vm/runtime/frame.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/frame.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -44,6 +44,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/adGlobals_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/adGlobals_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/adGlobals_ppc.hpp" +#endif #endif #ifdef ZERO #ifdef TARGET_ARCH_zero @@ -457,6 +463,12 @@ #ifdef TARGET_ARCH_zero # include "frame_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "frame_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "frame_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/frame.inline.hpp --- a/src/share/vm/runtime/frame.inline.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/frame.inline.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -40,6 +40,12 @@ #ifdef TARGET_ARCH_zero # include "jniTypes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "jniTypes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "jniTypes_ppc.hpp" +#endif #ifdef ZERO #ifdef TARGET_ARCH_zero # include "entryFrame_zero.hpp" @@ -88,6 +94,12 @@ #ifdef TARGET_ARCH_zero # include "frame_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "frame_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "frame_ppc.inline.hpp" +#endif #endif // SHARE_VM_RUNTIME_FRAME_INLINE_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/globals.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "globals_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "globals_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "globals_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "globals_linux.hpp" #endif @@ -62,6 +68,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "globals_windows_x86.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "globals_linux_arm.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "globals_linux_ppc.hpp" +#endif #ifdef COMPILER1 #ifdef TARGET_ARCH_x86 # include "c1_globals_x86.hpp" @@ -69,6 +81,12 @@ #ifdef TARGET_ARCH_sparc # include "c1_globals_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c1_globals_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "c1_globals_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "c1_globals_linux.hpp" #endif @@ -86,6 +104,9 @@ #ifdef TARGET_ARCH_sparc # include "c2_globals_sparc.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "c2_globals_arm.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "c2_globals_linux.hpp" #endif @@ -410,7 +431,14 @@ product_pd(bool, UseMembar, \ "(Unstable) Issues membars on thread state transitions") \ \ - /* Temporary: See 6948537 */ \ + /* Temp PPC Flag to allow disabling the use of lwsync on ppc platforms \ + * that don't support it. This will be replaced by processor detection \ + * logic. \ + */ \ + product(bool, UsePPCLWSYNC, true, \ + "Use lwsync instruction if true, else use slower sync") \ + \ + /* Temporary: See 6948537 */ \ experimental(bool, UseMemSetInBOT, true, \ "(Unstable) uses memset in BOT updates in GC code") \ \ @@ -762,6 +790,9 @@ product(bool, ShowMessageBoxOnError, false, \ "Keep process alive on VM fatal error") \ \ + product(bool, CreateMinidumpOnCrash, false, \ + "Create minidump on VM fatal error") \ + \ product_pd(bool, UseOSErrorReporting, \ "Let VM fatal error propagate to the OS (ie. WER on Windows)") \ \ @@ -1929,6 +1960,9 @@ product(bool, PrintRevisitStats, false, \ "Print revisit (klass and MDO) stack related information") \ \ + EMBEDDED_ONLY(product(bool, LowMemoryProtection, true, \ + "Enable LowMemoryProtection")) \ + \ product_pd(bool, NeverActAsServerClassMachine, \ "Never act like a server-class machine") \ \ @@ -2633,6 +2667,25 @@ product(bool, UseStringCache, false, \ "Enable String cache capabilities on String.java") \ \ + /* byte strings */ \ + product(bool, UseCompressedStrings, false, \ + "Enable byte-valued strings") \ + \ + product(bool, SpecialStringCompress, true, \ + "special version of string compress") \ + \ + product(bool, SpecialStringInflate, true, \ + "special version of string inflate") \ + \ + product(bool, SpecialStringCompareToCC, true, \ + "special version of string compareToCC") \ + \ + product(bool, SpecialStringIndexOfCC, true, \ + "special version of string indexOfCC") \ + \ + product(bool, SpecialStringEqualsCC, true, \ + "special version of string equalsCC") \ + \ /* statistics */ \ develop(bool, CountCompiledCalls, false, \ "counts method invocations") \ @@ -2854,9 +2907,13 @@ "Max. no. of lines in the stack trace for Java exceptions " \ "(0 means all)") \ \ - develop(intx, GuaranteedSafepointInterval, 1000, \ + NOT_EMBEDDED(develop(intx, GuaranteedSafepointInterval, 1000, \ "Guarantee a safepoint (at least) every so many milliseconds " \ - "(0 means none)") \ + "(0 means none)")) \ + \ + EMBEDDED_ONLY(product(intx, GuaranteedSafepointInterval, 0, \ + "Guarantee a safepoint (at least) every so many milliseconds " \ + "(0 means none)")) \ \ product(intx, SafepointTimeoutDelay, 10000, \ "Delay in milliseconds for option SafepointTimeout") \ @@ -3546,9 +3603,13 @@ \ /* flags for performance data collection */ \ \ - product(bool, UsePerfData, true, \ + NOT_EMBEDDED(product(bool, UsePerfData, true, \ "Flag to disable jvmstat instrumentation for performance testing" \ - "and problem isolation purposes.") \ + "and problem isolation purposes.")) \ + \ + EMBEDDED_ONLY(product(bool, UsePerfData, false, \ + "Flag to disable jvmstat instrumentation for performance testing" \ + "and problem isolation purposes.")) \ \ product(bool, PerfDataSaveToFile, false, \ "Save PerfData memory to hsperfdata_ file on exit") \ @@ -3600,6 +3661,12 @@ manageable(bool, PrintConcurrentLocks, false, \ "Print java.util.concurrent locks in thread dump") \ \ + product(bool, TransmitErrorReport, false, \ + "Enable error report transmission on erroneous termination") \ + \ + product(ccstr, ErrorReportServer, NULL, \ + "Override built-in error report server address") \ + \ /* Shared spaces */ \ \ product(bool, UseSharedSpaces, true, \ diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/icache.hpp --- a/src/share/vm/runtime/icache.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/icache.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -77,6 +77,12 @@ #ifdef TARGET_ARCH_zero # include "icache_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "icache_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "icache_ppc.hpp" +#endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/java.cpp --- a/src/share/vm/runtime/java.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/java.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -70,6 +70,12 @@ #ifdef TARGET_ARCH_zero # include "vm_version_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vm_version_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vm_version_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/javaCalls.hpp --- a/src/share/vm/runtime/javaCalls.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/javaCalls.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,6 +39,12 @@ #ifdef TARGET_ARCH_zero # include "jniTypes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "jniTypes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "jniTypes_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/javaFrameAnchor.hpp --- a/src/share/vm/runtime/javaFrameAnchor.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/javaFrameAnchor.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -44,6 +44,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "orderAccess_windows_x86.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "orderAccess_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "orderAccess_linux_ppc.inline.hpp" +#endif // // An object for encapsulating the machine/os dependent part of a JavaThread frame state // @@ -102,6 +108,12 @@ #ifdef TARGET_ARCH_zero # include "javaFrameAnchor_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "javaFrameAnchor_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "javaFrameAnchor_ppc.hpp" +#endif public: diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/mutexLocker.cpp --- a/src/share/vm/runtime/mutexLocker.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/mutexLocker.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -129,7 +129,7 @@ Monitor* GCTaskManager_lock = NULL; Mutex* Management_lock = NULL; -Monitor* LowMemory_lock = NULL; +Monitor* Service_lock = NULL; #define MAX_NUM_MUTEX 128 static Monitor * _mutex_array[MAX_NUM_MUTEX]; @@ -203,7 +203,7 @@ def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching. def(ObjAllocPost_lock , Monitor, special, false); - def(LowMemory_lock , Monitor, special, true ); // used for low memory detection + def(Service_lock , Monitor, special, true ); // used for service thread operations def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs. def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/mutexLocker.hpp --- a/src/share/vm/runtime/mutexLocker.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/mutexLocker.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -131,7 +131,7 @@ extern Mutex* HotCardCache_lock; // protects the hot card cache extern Mutex* Management_lock; // a lock used to serialize JVM management -extern Monitor* LowMemory_lock; // a lock used for low memory detection +extern Monitor* Service_lock; // a lock used for service thread operation // A MutexLocker provides mutual exclusion with respect to a given mutex // for the scope which contains the locker. The lock is an OS lock, not diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/os.hpp --- a/src/share/vm/runtime/os.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/os.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -614,6 +614,9 @@ // Structured OS Exception support static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread); + // On Windows this will create an actual minidump, on Linux/Solaris it will simply check core dump limits + static void check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize); + // JVMTI & JVM monitoring and management support // The thread_cpu_time() and current_thread_cpu_time() are only // supported if is_thread_cpu_time_supported() returns true. @@ -676,6 +679,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "os_windows_x86.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "os_linux_arm.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "os_linux_ppc.hpp" +#endif // debugging support (mostly used by debug.cpp but also fatal error handler) diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/registerMap.hpp --- a/src/share/vm/runtime/registerMap.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/registerMap.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -36,6 +36,12 @@ #ifdef TARGET_ARCH_zero # include "register_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "register_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "register_ppc.hpp" +#endif class JavaThread; @@ -138,6 +144,12 @@ #ifdef TARGET_ARCH_zero # include "registerMap_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "registerMap_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "registerMap_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/relocator.hpp --- a/src/share/vm/runtime/relocator.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/relocator.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -36,6 +36,12 @@ #ifdef TARGET_ARCH_zero # include "bytes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "bytes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "bytes_ppc.hpp" +#endif // This code has been converted from the 1.1E java virtual machine // Thanks to the JavaTopics group for using the code diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/safepoint.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -61,6 +61,14 @@ # include "nativeInst_zero.hpp" # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +# include "vmreg_ppc.inline.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/serviceThread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/runtime/serviceThread.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#include "precompiled.hpp" +#include "runtime/interfaceSupport.hpp" +#include "runtime/javaCalls.hpp" +#include "runtime/serviceThread.hpp" +#include "runtime/mutexLocker.hpp" +#include "prims/jvmtiImpl.hpp" + +ServiceThread* ServiceThread::_instance = NULL; + +void ServiceThread::initialize() { + EXCEPTION_MARK; + + instanceKlassHandle klass (THREAD, SystemDictionary::Thread_klass()); + instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); + + const char* name = JDK_Version::is_gte_jdk17x_version() ? + "Service Thread" : "Low Memory Detector"; + + Handle string = java_lang_String::create_from_str(name, CHECK); + + // Initialize thread_oop to put it into the system threadGroup + Handle thread_group (THREAD, Universe::system_thread_group()); + JavaValue result(T_VOID); + JavaCalls::call_special(&result, thread_oop, + klass, + vmSymbols::object_initializer_name(), + vmSymbols::threadgroup_string_void_signature(), + thread_group, + string, + CHECK); + + { + MutexLocker mu(Threads_lock); + ServiceThread* thread = new ServiceThread(&service_thread_entry); + + // At this point it may be possible that no osthread was created for the + // JavaThread due to lack of memory. We would have to throw an exception + // in that case. However, since this must work and we do not allow + // exceptions anyway, check and abort if this fails. + if (thread == NULL || thread->osthread() == NULL) { + vm_exit_during_initialization("java.lang.OutOfMemoryError", + "unable to create new native thread"); + } + + java_lang_Thread::set_thread(thread_oop(), thread); + java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); + java_lang_Thread::set_daemon(thread_oop()); + thread->set_threadObj(thread_oop()); + + Threads::add(thread); + Thread::start(thread); + + _instance = thread; + } +} + +void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { + while (true) { + bool sensors_changed = false; + bool has_jvmti_events = false; + JvmtiDeferredEvent jvmti_event; + { + // Need state transition ThreadBlockInVM so that this thread + // will be handled by safepoint correctly when this thread is + // notified at a safepoint. + + // This ThreadBlockInVM object is not also considered to be + // suspend-equivalent because ServiceThread is not visible to + // external suspension. + + ThreadBlockInVM tbivm(jt); + + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) && + !(has_jvmti_events = JvmtiDeferredEventQueue::has_events())) { + // wait until one of the sensors has pending requests, or there is a + // pending JVMTI event to post + Service_lock->wait(Mutex::_no_safepoint_check_flag); + } + + if (has_jvmti_events) { + jvmti_event = JvmtiDeferredEventQueue::dequeue(); + } + } + + if (has_jvmti_events) { + jvmti_event.post(); + } + + if (sensors_changed) { + LowMemoryDetector::process_sensor_changes(jt); + } + } +} + +bool ServiceThread::is_service_thread(Thread* thread) { + return thread == _instance; +} diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/serviceThread.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/runtime/serviceThread.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#ifndef SHARE_VM_RUNTIME_SERVICETHREAD_HPP +#define SHARE_VM_RUNTIME_SERVICETHREAD_HPP + +#include "runtime/thread.hpp" + +// A JavaThread for low memory detection support and JVMTI +// compiled-method-load events. +class ServiceThread : public JavaThread { + friend class VMStructs; + private: + + static ServiceThread* _instance; + + static void service_thread_entry(JavaThread* thread, TRAPS); + ServiceThread(ThreadFunction entry_point) : JavaThread(entry_point) {}; + + public: + static void initialize(); + + // Hide this thread from external view. + bool is_hidden_from_external_view() const { return true; } + + // Returns true if the passed thread is the service thread. + static bool is_service_thread(Thread* thread); +}; + +#endif // SHARE_VM_RUNTIME_SERVICETHREAD_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/sharedRuntime.cpp --- a/src/share/vm/runtime/sharedRuntime.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/sharedRuntime.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -68,6 +68,14 @@ # include "nativeInst_zero.hpp" # include "vmreg_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +# include "vmreg_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +# include "vmreg_ppc.inline.hpp" +#endif #ifdef COMPILER1 #include "c1/c1_Runtime1.hpp" #endif @@ -2630,6 +2638,7 @@ int jlsLen = java_lang_String::length(src); jchar* jlsPos = (jlsLen == 0) ? NULL : jlsValue->char_at_addr(jlsOffset); + assert(typeArrayKlass::cast(jlsValue->klass())->element_type() == T_CHAR, "compressed string"); (void) UNICODE::as_utf8(jlsPos, jlsLen, (char *)dst, max_dtrace_string_size); } #endif // ndef HAVE_DTRACE_H diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/stackValueCollection.cpp --- a/src/share/vm/runtime/stackValueCollection.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/stackValueCollection.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -33,6 +33,12 @@ #ifdef TARGET_ARCH_zero # include "jniTypes_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "jniTypes_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "jniTypes_ppc.hpp" +#endif jint StackValueCollection::int_at(int slot) const { intptr_t val = at(slot)->get_int(); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/statSampler.cpp --- a/src/share/vm/runtime/statSampler.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/statSampler.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -42,6 +42,12 @@ #ifdef TARGET_ARCH_zero # include "vm_version_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vm_version_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vm_version_ppc.hpp" +#endif // -------------------------------------------------------- // StatSamplerTask diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/stubCodeGenerator.cpp --- a/src/share/vm/runtime/stubCodeGenerator.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/stubCodeGenerator.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -36,6 +36,12 @@ #ifdef TARGET_ARCH_zero # include "assembler_zero.inline.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "assembler_arm.inline.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "assembler_ppc.inline.hpp" +#endif // Implementation of StubCodeDesc diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/stubRoutines.hpp --- a/src/share/vm/runtime/stubRoutines.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/stubRoutines.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -40,6 +40,12 @@ #ifdef TARGET_ARCH_zero # include "nativeInst_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "nativeInst_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "nativeInst_ppc.hpp" +#endif // StubRoutines provides entry points to assembly routines used by // compiled code and the run-time system. Platform-specific entry @@ -105,6 +111,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "stubRoutines_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "stubRoutines_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "stubRoutines_ppc.hpp" +#endif static jint _verify_oop_count; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/thread.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -962,22 +962,6 @@ vmSymbols::void_method_signature(), CHECK); } -#ifdef KERNEL -static void set_jkernel_boot_classloader_hook(TRAPS) { - klassOop k = SystemDictionary::sun_jkernel_DownloadManager_klass(); - instanceKlassHandle klass (THREAD, k); - - if (k == NULL) { - // sun.jkernel.DownloadManager may not present in the JDK; just return - return; - } - - JavaValue result(T_VOID); - JavaCalls::call_static(&result, klass, vmSymbols::setBootClassLoaderHook_name(), - vmSymbols::void_method_signature(), CHECK); -} -#endif // KERNEL - // General purpose hook into Java code, run once when the VM is initialized. // The Java library method itself may be changed independently from the VM. static void call_postVMInitHook(TRAPS) { @@ -1611,7 +1595,15 @@ uncaught_exception, // Arg 2 THREAD); } - CLEAR_PENDING_EXCEPTION; + if (HAS_PENDING_EXCEPTION) { + ResourceMark rm(this); + jio_fprintf(defaultStream::error_stream(), + "\nException: %s thrown from the UncaughtExceptionHandler" + " in thread \"%s\"\n", + Klass::cast(pending_exception()->klass())->external_name(), + get_thread_name()); + CLEAR_PENDING_EXCEPTION; + } } } @@ -3287,12 +3279,6 @@ vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION)); } -#ifdef KERNEL - if (JDK_Version::is_gte_jdk17x_version()) { - set_jkernel_boot_classloader_hook(THREAD); - } -#endif // KERNEL - #ifndef SERIALGC // Support for ConcurrentMarkSweep. This should be cleaned up // and better encapsulated. The ugly nested if test would go away diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/thread.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1602,6 +1602,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "thread_windows_x86.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "thread_linux_arm.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "thread_linux_ppc.hpp" +#endif public: @@ -1678,16 +1684,6 @@ return cur_sp > low_addr ? cur_sp - low_addr : 0; } -// A JavaThread for low memory detection support -class LowMemoryDetectorThread : public JavaThread { - friend class VMStructs; -public: - LowMemoryDetectorThread(ThreadFunction entry_point) : JavaThread(entry_point) {}; - - // Hide this thread from external view. - bool is_hidden_from_external_view() const { return true; } -}; - // A thread used for Compilation. class CompilerThread : public JavaThread { friend class VMStructs; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/threadLocalStorage.hpp --- a/src/share/vm/runtime/threadLocalStorage.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/threadLocalStorage.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -62,6 +62,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "threadLS_windows_x86.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "threadLS_linux_arm.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "threadLS_linux_ppc.hpp" +#endif public: diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -93,6 +93,7 @@ #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/perfMemory.hpp" +#include "runtime/serviceThread.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/virtualspace.hpp" @@ -108,6 +109,12 @@ #ifdef TARGET_ARCH_zero # include "vmStructs_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vmStructs_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vmStructs_ppc.hpp" +#endif #ifdef TARGET_OS_FAMILY_linux # include "thread_linux.inline.hpp" #endif @@ -135,6 +142,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "vmStructs_windows_x86.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "vmStructs_linux_arm.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "vmStructs_linux_ppc.hpp" +#endif #ifndef SERIALGC #include "gc_implementation/concurrentMarkSweep/cmsPermGen.hpp" #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" @@ -166,6 +179,12 @@ #ifdef TARGET_ARCH_MODEL_zero # include "adfiles/adGlobals_zero.hpp" #endif +#ifdef TARGET_ARCH_MODEL_arm +# include "adfiles/adGlobals_arm.hpp" +#endif +#ifdef TARGET_ARCH_MODEL_ppc +# include "adfiles/adGlobals_ppc.hpp" +#endif #endif // Note: the cross-product of (c1, c2, product, nonproduct, ...), @@ -1232,7 +1251,7 @@ declare_type(WatcherThread, Thread) \ declare_type(JavaThread, Thread) \ declare_type(JvmtiAgentThread, JavaThread) \ - declare_type(LowMemoryDetectorThread, JavaThread) \ + declare_type(ServiceThread, JavaThread) \ declare_type(CompilerThread, JavaThread) \ declare_toplevel_type(OSThread) \ declare_toplevel_type(JavaFrameAnchor) \ diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/vm_version.cpp --- a/src/share/vm/runtime/vm_version.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/vm_version.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -35,6 +35,12 @@ #ifdef TARGET_ARCH_zero # include "vm_version_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "vm_version_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "vm_version_ppc.hpp" +#endif const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release(); const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string(); @@ -220,12 +226,29 @@ #endif #endif + #ifndef FLOAT_ARCH + #if defined(__SOFTFP__) + #define FLOAT_ARCH "-sflt" + #elif defined(E500V2) + #define FLOAT_ARCH "-e500v2" + #elif defined(ARM) + #define FLOAT_ARCH "-vfp" + #elif defined(PPC) + #define FLOAT_ARCH "-hflt" + #else + #define FLOAT_ARCH "" + #endif + #endif - return VMNAME " (" VM_RELEASE ") for " OS "-" CPU + return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH " JRE (" JRE_RELEASE_VERSION "), built on " __DATE__ " " __TIME__ " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER; } +const char *Abstract_VM_Version::vm_build_user() { + return HOTSPOT_BUILD_USER; +} + unsigned int Abstract_VM_Version::jvm_version() { return ((Abstract_VM_Version::vm_major_version() & 0xFF) << 24) | ((Abstract_VM_Version::vm_minor_version() & 0xFF) << 16) | diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/runtime/vm_version.hpp --- a/src/share/vm/runtime/vm_version.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/runtime/vm_version.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -59,6 +59,7 @@ static const char* vm_info_string(); static const char* vm_release(); static const char* vm_platform_string(); + static const char* vm_build_user(); static int vm_major_version() { assert(_initialized, "not initialized"); return _vm_major_version; } static int vm_minor_version() { assert(_initialized, "not initialized"); return _vm_minor_version; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/services/attachListener.hpp --- a/src/share/vm/services/attachListener.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/services/attachListener.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -59,10 +59,10 @@ static void detachall() KERNEL_RETURN; // indicates if the Attach Listener needs to be created at startup - static bool init_at_startup() KERNEL_RETURN_(return false;); + static bool init_at_startup() KERNEL_RETURN_(false); // indicates if we have a trigger to start the Attach Listener - static bool is_init_trigger() KERNEL_RETURN_(return false;); + static bool is_init_trigger() KERNEL_RETURN_(false); #ifdef SERVICES_KERNEL static bool is_attach_supported() { return false; } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/services/lowMemoryDetector.cpp --- a/src/share/vm/services/lowMemoryDetector.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/services/lowMemoryDetector.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,55 +34,11 @@ #include "services/lowMemoryDetector.hpp" #include "services/management.hpp" -LowMemoryDetectorThread* LowMemoryDetector::_detector_thread = NULL; volatile bool LowMemoryDetector::_enabled_for_collected_pools = false; volatile jint LowMemoryDetector::_disabled_count = 0; -void LowMemoryDetector::initialize() { - EXCEPTION_MARK; - - instanceKlassHandle klass (THREAD, SystemDictionary::Thread_klass()); - instanceHandle thread_oop = klass->allocate_instance_handle(CHECK); - - const char thread_name[] = "Low Memory Detector"; - Handle string = java_lang_String::create_from_str(thread_name, CHECK); - - // Initialize thread_oop to put it into the system threadGroup - Handle thread_group (THREAD, Universe::system_thread_group()); - JavaValue result(T_VOID); - JavaCalls::call_special(&result, thread_oop, - klass, - vmSymbols::object_initializer_name(), - vmSymbols::threadgroup_string_void_signature(), - thread_group, - string, - CHECK); - - { - MutexLocker mu(Threads_lock); - _detector_thread = new LowMemoryDetectorThread(&low_memory_detector_thread_entry); - - // At this point it may be possible that no osthread was created for the - // JavaThread due to lack of memory. We would have to throw an exception - // in that case. However, since this must work and we do not allow - // exceptions anyway, check and abort if this fails. - if (_detector_thread == NULL || _detector_thread->osthread() == NULL) { - vm_exit_during_initialization("java.lang.OutOfMemoryError", - "unable to create new native thread"); - } - - java_lang_Thread::set_thread(thread_oop(), _detector_thread); - java_lang_Thread::set_priority(thread_oop(), NearMaxPriority); - java_lang_Thread::set_daemon(thread_oop()); - _detector_thread->set_threadObj(thread_oop()); - - Threads::add(_detector_thread); - Thread::start(_detector_thread); - } -} - bool LowMemoryDetector::has_pending_requests() { - assert(LowMemory_lock->owned_by_self(), "Must own LowMemory_lock"); + assert(Service_lock->owned_by_self(), "Must own Service_lock"); bool has_requests = false; int num_memory_pools = MemoryService::num_memory_pools(); for (int i = 0; i < num_memory_pools; i++) { @@ -100,47 +56,21 @@ return has_requests; } -void LowMemoryDetector::low_memory_detector_thread_entry(JavaThread* jt, TRAPS) { - while (true) { - bool sensors_changed = false; - - { - // _no_safepoint_check_flag is used here as LowMemory_lock is a - // special lock and the VMThread may acquire this lock at safepoint. - // Need state transition ThreadBlockInVM so that this thread - // will be handled by safepoint correctly when this thread is - // notified at a safepoint. - - // This ThreadBlockInVM object is not also considered to be - // suspend-equivalent because LowMemoryDetector threads are - // not visible to external suspension. - - ThreadBlockInVM tbivm(jt); +void LowMemoryDetector::process_sensor_changes(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); - while (!(sensors_changed = has_pending_requests())) { - // wait until one of the sensors has pending requests - LowMemory_lock->wait(Mutex::_no_safepoint_check_flag); - } + // No need to hold Service_lock to call out to Java + int num_memory_pools = MemoryService::num_memory_pools(); + for (int i = 0; i < num_memory_pools; i++) { + MemoryPool* pool = MemoryService::get_memory_pool(i); + SensorInfo* sensor = pool->usage_sensor(); + SensorInfo* gc_sensor = pool->gc_usage_sensor(); + if (sensor != NULL && sensor->has_pending_requests()) { + sensor->process_pending_requests(CHECK); } - - { - ResourceMark rm(THREAD); - HandleMark hm(THREAD); - - // No need to hold LowMemory_lock to call out to Java - int num_memory_pools = MemoryService::num_memory_pools(); - for (int i = 0; i < num_memory_pools; i++) { - MemoryPool* pool = MemoryService::get_memory_pool(i); - SensorInfo* sensor = pool->usage_sensor(); - SensorInfo* gc_sensor = pool->gc_usage_sensor(); - if (sensor != NULL && sensor->has_pending_requests()) { - sensor->process_pending_requests(CHECK); - } - if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { - gc_sensor->process_pending_requests(CHECK); - } - } + if (gc_sensor != NULL && gc_sensor->has_pending_requests()) { + gc_sensor->process_pending_requests(CHECK); } } } @@ -148,7 +78,7 @@ // This method could be called from any Java threads // and also VMThread. void LowMemoryDetector::detect_low_memory() { - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); bool has_pending_requests = false; int num_memory_pools = MemoryService::num_memory_pools(); @@ -166,7 +96,7 @@ } if (has_pending_requests) { - LowMemory_lock->notify_all(); + Service_lock->notify_all(); } } @@ -181,14 +111,14 @@ } { - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); MemoryUsage usage = pool->get_memory_usage(); sensor->set_gauge_sensor_level(usage, pool->usage_threshold()); if (sensor->has_pending_requests()) { // notify sensor state update - LowMemory_lock->notify_all(); + Service_lock->notify_all(); } } } @@ -203,14 +133,14 @@ } { - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); MemoryUsage usage = pool->get_last_collection_usage(); sensor->set_counter_sensor_level(usage, pool->gc_usage_threshold()); if (sensor->has_pending_requests()) { // notify sensor state update - LowMemory_lock->notify_all(); + Service_lock->notify_all(); } } } @@ -384,8 +314,8 @@ } { - // Holds LowMemory_lock and update the sensor state - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); + // Holds Service_lock and update the sensor state + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); _sensor_on = true; _sensor_count += count; _pending_trigger_count = _pending_trigger_count - count; @@ -410,8 +340,8 @@ } { - // Holds LowMemory_lock and update the sensor state - MutexLockerEx ml(LowMemory_lock, Mutex::_no_safepoint_check_flag); + // Holds Service_lock and update the sensor state + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); _sensor_on = false; _pending_clear_count = 0; _pending_trigger_count = _pending_trigger_count - count; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/services/lowMemoryDetector.hpp --- a/src/share/vm/services/lowMemoryDetector.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/services/lowMemoryDetector.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,8 @@ // // May need to deal with hysteresis effect. // +// Memory detection code runs in the Service thread (serviceThread.hpp). -class LowMemoryDetectorThread; class OopClosure; class MemoryPool; @@ -211,23 +211,22 @@ }; class LowMemoryDetector : public AllStatic { -friend class LowMemoryDetectorDisabler; + friend class LowMemoryDetectorDisabler; + friend class ServiceThread; private: // true if any collected heap has low memory detection enabled static volatile bool _enabled_for_collected_pools; // > 0 if temporary disabed static volatile jint _disabled_count; - static LowMemoryDetectorThread* _detector_thread; - static void low_memory_detector_thread_entry(JavaThread* thread, TRAPS); static void check_memory_usage(); static bool has_pending_requests(); static bool temporary_disabled() { return _disabled_count > 0; } static void disable() { Atomic::inc(&_disabled_count); } static void enable() { Atomic::dec(&_disabled_count); } + static void process_sensor_changes(TRAPS); public: - static void initialize(); static void detect_low_memory(); static void detect_low_memory(MemoryPool* pool); static void detect_after_gc_memory(MemoryPool* pool); @@ -275,7 +274,6 @@ } } } - }; class LowMemoryDetectorDisabler: public StackObj { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/services/management.cpp --- a/src/share/vm/services/management.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/services/management.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -38,6 +38,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.hpp" #include "runtime/os.hpp" +#include "runtime/serviceThread.hpp" #include "services/classLoadingService.hpp" #include "services/heapDumper.hpp" #include "services/lowMemoryDetector.hpp" @@ -112,8 +113,8 @@ } void Management::initialize(TRAPS) { - // Start the low memory detector thread - LowMemoryDetector::initialize(); + // Start the service thread + ServiceThread::initialize(); if (ManagementServer) { ResourceMark rm(THREAD); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/copy.hpp --- a/src/share/vm/utilities/copy.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/copy.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -331,6 +331,12 @@ #ifdef TARGET_ARCH_zero # include "copy_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "copy_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "copy_ppc.hpp" +#endif }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/elfSymbolTable.cpp --- a/src/share/vm/utilities/elfSymbolTable.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/elfSymbolTable.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -39,13 +39,14 @@ // try to load the string table long cur_offset = ftell(file); if (cur_offset != -1) { - m_symbols = (Elf_Sym*)NEW_C_HEAP_ARRAY(char, shdr.sh_size); + // call malloc so we can back up if memory allocation fails. + m_symbols = (Elf_Sym*)os::malloc(shdr.sh_size); if (m_symbols) { if (fseek(file, shdr.sh_offset, SEEK_SET) || fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 || fseek(file, cur_offset, SEEK_SET)) { m_status = Decoder::file_invalid; - FREE_C_HEAP_ARRAY(char, m_symbols); + os::free(m_symbols); m_symbols = NULL; } } @@ -59,7 +60,7 @@ ElfSymbolTable::~ElfSymbolTable() { if (m_symbols != NULL) { - FREE_C_HEAP_ARRAY(char, m_symbols); + os::free(m_symbols); } if (m_next != NULL) { diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/errorReporter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/errorReporter.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#include "precompiled.hpp" +#include "utilities/errorReporter.hpp" + +ErrorReporter::ErrorReporter() {} + +void ErrorReporter::call(FILE* fd, char* buffer, int length) { +} + diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/errorReporter.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/errorReporter.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + * + */ + +#ifndef SHARE_VM_UTILITIES_ERRORREPORTER_HPP +#define SHARE_VM_UTILITIES_ERRORREPORTER_HPP + +#include "utilities/globalDefinitions.hpp" + +class ErrorReporter : public StackObj { + +public: + ErrorReporter(); + ~ErrorReporter(){}; + + void call(FILE* fd, char *buffer, int length); +}; + +#endif // ndef SHARE_VM_UTILITIES_ERRORREPORTER_HPP diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/globalDefinitions.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -328,6 +328,12 @@ #ifdef TARGET_ARCH_zero # include "globalDefinitions_zero.hpp" #endif +#ifdef TARGET_ARCH_arm +# include "globalDefinitions_arm.hpp" +#endif +#ifdef TARGET_ARCH_ppc +# include "globalDefinitions_ppc.hpp" +#endif // The byte alignment to be used by Arena::Amalloc. See bugid 4169348. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/macros.hpp --- a/src/share/vm/utilities/macros.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/macros.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -46,7 +46,7 @@ #define SERVICES_KERNEL #define KERNEL_RETURN {} -#define KERNEL_RETURN_(code) { code } +#define KERNEL_RETURN_(code) { return code; } #else // KERNEL diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/ostream.cpp --- a/src/share/vm/utilities/ostream.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/ostream.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -314,6 +314,11 @@ _need_close = true; } +fileStream::fileStream(const char* file_name, const char* opentype) { + _file = fopen(file_name, opentype); + _need_close = true; +} + void fileStream::write(const char* s, size_t len) { if (_file != NULL) { // Make an unused local variable to avoid warning from gcc 4.x compiler. @@ -322,6 +327,25 @@ update_position(s, len); } +long fileStream::fileSize() { + long size = -1; + if (_file != NULL) { + long pos = ::ftell(_file); + if (::fseek(_file, 0, SEEK_END) == 0) { + size = ::ftell(_file); + } + ::fseek(_file, pos, SEEK_SET); + } + return size; +} + +char* fileStream::readln(char *data, int count ) { + char * ret = ::fgets(data, count, _file); + //Get rid of annoying \n char + data[::strlen(data)-1] = '\0'; + return ret; +} + fileStream::~fileStream() { if (_file != NULL) { if (_need_close) fclose(_file); diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/ostream.hpp --- a/src/share/vm/utilities/ostream.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/ostream.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -159,10 +159,17 @@ bool _need_close; public: fileStream(const char* file_name); + fileStream(const char* file_name, const char* opentype); fileStream(FILE* file) { _file = file; _need_close = false; } ~fileStream(); bool is_open() const { return _file != NULL; } + void set_need_close(bool b) { _need_close = b;} virtual void write(const char* c, size_t len); + size_t read(void *data, size_t size, size_t count) { return ::fread(data, size, count, _file); } + char* readln(char *data, int count); + int eof() { return feof(_file); } + long fileSize(); + void rewind() { ::rewind(_file); } void flush(); }; diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/taskqueue.hpp --- a/src/share/vm/utilities/taskqueue.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/taskqueue.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -47,6 +47,12 @@ #ifdef TARGET_OS_ARCH_windows_x86 # include "orderAccess_windows_x86.inline.hpp" #endif +#ifdef TARGET_OS_ARCH_linux_arm +# include "orderAccess_linux_arm.inline.hpp" +#endif +#ifdef TARGET_OS_ARCH_linux_ppc +# include "orderAccess_linux_ppc.inline.hpp" +#endif // Simple TaskQueue stats that are collected by default in debug builds. diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/vmError.cpp --- a/src/share/vm/utilities/vmError.cpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/vmError.cpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ #include "utilities/debug.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" +#include "utilities/errorReporter.hpp" #include "utilities/top.hpp" #include "utilities/vmError.hpp" @@ -200,6 +201,15 @@ out->print_raw_cr("#"); } +bool VMError::coredump_status; +char VMError::coredump_message[O_BUFLEN]; + +void VMError::report_coredump_status(const char* message, bool status) { + coredump_status = status; + strncpy(coredump_message, message, sizeof(coredump_message)); + coredump_message[sizeof(coredump_message)-1] = 0; +} + // Return a string to describe the error char* VMError::error_string(char* buf, int buflen) { @@ -453,6 +463,15 @@ st->cr(); st->print_cr("#"); } + STEP(63, "(printing core file information)") + st->print("# "); + if (coredump_status) { + st->print("Core dump written. Default location: %s", coredump_message); + } else { + st->print("Failed to write core dump. %s", coredump_message); + } + st->print_cr(""); + st->print_cr("#"); STEP(65, "(printing bug submit message)") @@ -769,6 +788,7 @@ // then save detailed information in log file (verbose = true). static bool out_done = false; // done printing to standard out static bool log_done = false; // done saving error log + static bool transmit_report_done = false; // done error reporting static fdStream log; // error log if (SuppressFatalErrorMessage) { @@ -790,6 +810,9 @@ ShowMessageBoxOnError = false; } + // Write a minidump on Windows, check core dump limits on Linux/Solaris + os::check_or_create_dump(_siginfo, _context, buffer, sizeof(buffer)); + // reset signal handlers or exception filter; make sure recursive crashes // are handled properly. reset_signal_handlers(); @@ -859,7 +882,7 @@ bool copy_ok = Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); if (copy_ok) { - fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); + fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); } } @@ -870,7 +893,7 @@ // so use the default name in the current directory jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log", os::file_separator(), os::current_process_id()); - fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); + fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); } if (fd == -1) { @@ -879,7 +902,7 @@ if (tmpdir != NULL && tmpdir[0] != '\0') { jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log", tmpdir, os::file_separator(), os::current_process_id()); - fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); + fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); } } @@ -892,6 +915,9 @@ } else { out.print_raw_cr("# Can not save log file, dump to screen.."); log.set_fd(defaultStream::output_fd()); + /* Error reporting currently needs dumpfile. + * Maybe implement direct streaming in the future.*/ + transmit_report_done = true; } } @@ -900,6 +926,16 @@ first_error->_current_step = 0; // reset current_step first_error->_current_step_info = ""; // reset current_step string + // Run error reporting to determine whether or not to report the crash. + if (!transmit_report_done && should_report_bug(first_error->_id)) { + transmit_report_done = true; + FILE* hs_err = ::fdopen(log.fd(), "r"); + if (NULL != hs_err) { + ErrorReporter er; + er.call(hs_err, buffer, O_BUFLEN); + } + } + if (log.fd() != defaultStream::output_fd()) { close(log.fd()); } diff -r 5d801e6b9a80 -r 0cd39a385a72 src/share/vm/utilities/vmError.hpp --- a/src/share/vm/utilities/vmError.hpp Mon Feb 21 19:17:10 2011 +0100 +++ b/src/share/vm/utilities/vmError.hpp Mon Feb 21 19:17:33 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,6 +67,14 @@ static VMError* volatile first_error; static volatile jlong first_error_tid; + // Core dump status, false if we have been unable to write a core/minidump for some reason + static bool coredump_status; + + // When coredump_status is set to true this will contain the name/path to the core/minidump, + // if coredump_status if false, this will (hopefully) contain a useful error explaining why + // no core/minidump has been written to disk + static char coredump_message[O_BUFLEN]; + // used by reporting about OOM size_t _size; @@ -106,6 +114,9 @@ // return a string to describe the error char *error_string(char* buf, int buflen); + // Report status of core/minidump + static void report_coredump_status(const char* message, bool status); + // main error reporting function void report_and_die();