Merge
This commit is contained in:
commit
dcafa9c646
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, 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
|
||||
@ -26,7 +26,7 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
#include <JavaVM/jni.h>
|
||||
#include <jni.h>
|
||||
|
||||
#import <mach/mach.h>
|
||||
#import <mach/mach_types.h>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2002, 2014, 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
|
||||
@ -50,9 +50,9 @@ SOURCES = symtab.c \
|
||||
ps_core.c
|
||||
OBJS = $(SOURCES:.c=.o)
|
||||
OBJSPLUS = MacosxDebuggerLocal.o sadis.o $(OBJS)
|
||||
EXTINCLUDE = -I/System/Library/Frameworks/JavaVM.framework/Headers -I.
|
||||
EXTINCLUDE = -I.
|
||||
EXTCFLAGS = -m64 -D__APPLE__ -framework JavaNativeFoundation
|
||||
FOUNDATIONFLAGS = -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation
|
||||
FOUNDATIONFLAGS = -framework Foundation -framework JavaNativeFoundation -framework Security -framework CoreFoundation
|
||||
LIBSA = $(ARCH)/libsaproc.dylib
|
||||
endif # Darwin
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "libproc_md.h"
|
||||
#endif
|
||||
|
||||
#include <linux/ptrace.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
/************************************************************************************
|
||||
|
||||
|
@ -263,7 +263,7 @@ static bool add_new_thread(struct ps_prochandle* ph, pthread_t pthread_id, lwpid
|
||||
|
||||
static bool read_lib_info(struct ps_prochandle* ph) {
|
||||
char fname[32];
|
||||
char buf[256];
|
||||
char buf[PATH_MAX];
|
||||
FILE *fp = NULL;
|
||||
|
||||
sprintf(fname, "/proc/%d/maps", ph->pid);
|
||||
@ -273,10 +273,41 @@ static bool read_lib_info(struct ps_prochandle* ph) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while(fgets_no_cr(buf, 256, fp)){
|
||||
char * word[6];
|
||||
int nwords = split_n_str(buf, 6, word, ' ', '\0');
|
||||
if (nwords > 5 && find_lib(ph, word[5]) == false) {
|
||||
while(fgets_no_cr(buf, PATH_MAX, fp)){
|
||||
char * word[7];
|
||||
int nwords = split_n_str(buf, 7, word, ' ', '\0');
|
||||
|
||||
if (nwords < 6) {
|
||||
// not a shared library entry. ignore.
|
||||
continue;
|
||||
}
|
||||
|
||||
// SA does not handle the lines with patterns:
|
||||
// "[stack]", "[heap]", "[vdso]", "[vsyscall]", etc.
|
||||
if (word[5][0] == '[') {
|
||||
// not a shared library entry. ignore.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nwords > 6) {
|
||||
// prelink altered mapfile when the program is running.
|
||||
// Entries like one below have to be skipped
|
||||
// /lib64/libc-2.15.so (deleted)
|
||||
// SO name in entries like one below have to be stripped.
|
||||
// /lib64/libpthread-2.15.so.#prelink#.EECVts
|
||||
char *s = strstr(word[5],".#prelink#");
|
||||
if (s == NULL) {
|
||||
// No prelink keyword. skip deleted library
|
||||
print_debug("skip shared object %s deleted by prelink\n", word[5]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fall through
|
||||
print_debug("rectifying shared object name %s changed by prelink\n", word[5]);
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
if (find_lib(ph, word[5]) == false) {
|
||||
intptr_t base;
|
||||
lib_info* lib;
|
||||
#ifdef _LP64
|
||||
|
@ -64,9 +64,23 @@ ifeq ($(OS_VENDOR), FreeBSD)
|
||||
else
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
SASRCFILES = $(DARWIN_NON_STUB_SASRCFILES)
|
||||
SALIBS = -g -framework Foundation -F/System/Library/Frameworks/JavaVM.framework/Frameworks -framework JavaNativeFoundation -framework Security -framework CoreFoundation
|
||||
SALIBS = -g \
|
||||
-framework Foundation \
|
||||
-framework JavaNativeFoundation \
|
||||
-framework Security \
|
||||
-framework CoreFoundation
|
||||
#objc compiler blows up on -march=i586, perhaps it should not be included in the macosx intel 32-bit C++ compiles?
|
||||
SAARCH = $(subst -march=i586,,$(ARCHFLAG))
|
||||
|
||||
# This is needed to locate JavaNativeFoundation.framework
|
||||
ifeq ($(SYSROOT_CFLAGS),)
|
||||
# this will happen when building without spec.gmk, set SDKROOT to a valid SDK
|
||||
# path if your system does not have headers installed in the system frameworks
|
||||
SA_SYSROOT_FLAGS = -F"$(SDKROOT)/System/Library/Frameworks/JavaVM.framework/Frameworks"
|
||||
else
|
||||
# Just use SYSROOT_CFLAGS
|
||||
SA_SYSROOT_FLAGS=$(SYSROOT_CFLAGS)
|
||||
endif
|
||||
else
|
||||
SASRCFILES = $(SASRCDIR)/StubDebuggerLocal.c
|
||||
SALIBS =
|
||||
@ -100,14 +114,8 @@ SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE))
|
||||
endif
|
||||
SA_LFLAGS += $(LDFLAGS_HASH_STYLE)
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
BOOT_JAVA_INCLUDES = -I$(BOOT_JAVA_HOME)/include \
|
||||
-I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]") \
|
||||
-I/System/Library/Frameworks/JavaVM.framework/Headers
|
||||
else
|
||||
BOOT_JAVA_INCLUDES = -I$(BOOT_JAVA_HOME)/include \
|
||||
-I$(BOOT_JAVA_HOME)/include/$(shell uname -s | tr "[:upper:]" "[:lower:]")
|
||||
endif
|
||||
|
||||
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
|
||||
@ -116,6 +124,7 @@ $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
|
||||
fi
|
||||
@echo Making SA debugger back-end...
|
||||
$(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \
|
||||
$(SA_SYSROOT_FLAGS) \
|
||||
$(SYMFLAG) $(SAARCH) $(SHARED_FLAG) $(PICFLAG) \
|
||||
-I$(SASRCDIR) \
|
||||
-I$(GENERATED) \
|
||||
|
@ -295,6 +295,7 @@ endif
|
||||
$(PRECOMPILED_HEADER):
|
||||
$(QUIETLY) echo Generating precompiled header $@
|
||||
$(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR)
|
||||
$(QUIETLY) rm -f $@
|
||||
$(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE)
|
||||
|
||||
# making the library:
|
||||
|
@ -290,6 +290,7 @@ LINK_VM = $(LINK_LIB.CC)
|
||||
$(PRECOMPILED_HEADER):
|
||||
$(QUIETLY) echo Generating precompiled header $@
|
||||
$(QUIETLY) mkdir -p $(PRECOMPILED_HEADER_DIR)
|
||||
$(QUIETLY) rm -f $@
|
||||
$(QUIETLY) $(COMPILE.CXX) $(DEPFLAGS) -x c++-header $(PRECOMPILED_HEADER_SRC) -o $@ $(COMPILE_DONE)
|
||||
|
||||
# making the library:
|
||||
|
@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
REM
|
||||
REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
REM Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
REM
|
||||
REM This code is free software; you can redistribute it and/or modify it
|
||||
@ -81,33 +81,8 @@ REM figure out MSC version
|
||||
for /F %%i in ('sh %HotSpotWorkSpace%/make/windows/get_msc_ver.sh') do set %%i
|
||||
|
||||
echo **************************************************************
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.vcproj
|
||||
echo MSC_VER = "%MSC_VER%"
|
||||
if "%MSC_VER%" == "1200" (
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.dsp
|
||||
echo Will generate VC6 project {unsupported}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1400" (
|
||||
echo Will generate VC8 {Visual Studio 2005}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1500" (
|
||||
echo Will generate VC9 {Visual Studio 2008}
|
||||
) else (
|
||||
if "%MSC_VER%" == "1600" (
|
||||
echo Will generate VC10 {Visual Studio 2010}
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
|
||||
) else (
|
||||
if "%MSC_VER%" == "1700" (
|
||||
echo Will generate VC10 {compatible with Visual Studio 2012}
|
||||
echo After opening in VS 2012, click "Update" when prompted.
|
||||
set ProjectFile=%HotSpotBuildSpace%\jvm.vcxproj
|
||||
) else (
|
||||
echo Will generate VC7 project {Visual Studio 2003 .NET}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
echo %ProjectFile%
|
||||
echo **************************************************************
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1997, 2014, 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
|
||||
@ -63,28 +63,20 @@ CXX_FLAGS=$(CXX_FLAGS) /Zi
|
||||
# Based on BUILDARCH we add some flags and select the default compiler name
|
||||
!if "$(BUILDARCH)" == "ia64"
|
||||
MACHINE=IA64
|
||||
DEFAULT_COMPILER_NAME=VS2003
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "CC_INTERP" /D "_LP64" /D "IA64"
|
||||
!endif
|
||||
|
||||
!if "$(BUILDARCH)" == "amd64"
|
||||
MACHINE=AMD64
|
||||
DEFAULT_COMPILER_NAME=VS2005
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "_LP64" /D "AMD64"
|
||||
LP64=1
|
||||
!endif
|
||||
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
MACHINE=I386
|
||||
DEFAULT_COMPILER_NAME=VS2003
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "IA32"
|
||||
!endif
|
||||
|
||||
# Sanity check, this is the default if not amd64, ia64, or i486
|
||||
!ifndef DEFAULT_COMPILER_NAME
|
||||
CXX=ARCH_ERROR
|
||||
!endif
|
||||
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "WIN32" /D "_WINDOWS"
|
||||
# Must specify this for sharedRuntimeTrig.cpp
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "VM_LITTLE_ENDIAN"
|
||||
@ -112,6 +104,7 @@ CXX_FLAGS=$(CXX_FLAGS) /D TARGET_COMPILER_visCPP
|
||||
# 1500 is for VS2008
|
||||
# 1600 is for VS2010
|
||||
# 1700 is for VS2012
|
||||
# 1800 is for VS2013
|
||||
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
|
||||
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
|
||||
# Normally they are the same, but a pre-release of the VS2005 compilers
|
||||
@ -119,35 +112,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D TARGET_COMPILER_visCPP
|
||||
# closer to VS2003 in terms of option spellings, so we use 1399 for that
|
||||
# 1400 version that really isn't 1400.
|
||||
# See the file get_msc_ver.sh for more info.
|
||||
!if "x$(MSC_VER)" == "x"
|
||||
COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
|
||||
!else
|
||||
!if "$(MSC_VER)" == "1200"
|
||||
COMPILER_NAME=VC6
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1300"
|
||||
COMPILER_NAME=VS2003
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1310"
|
||||
COMPILER_NAME=VS2003
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1399"
|
||||
# Compiler might say 1400, but if it's 14.00.30701, it isn't really VS2005
|
||||
COMPILER_NAME=VS2003
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1400"
|
||||
COMPILER_NAME=VS2005
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1500"
|
||||
COMPILER_NAME=VS2008
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1600"
|
||||
COMPILER_NAME=VS2010
|
||||
!endif
|
||||
!if "$(MSC_VER)" == "1700"
|
||||
COMPILER_NAME=VS2012
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# By default, we do not want to use the debug version of the msvcrt.dll file
|
||||
# but if MFC_DEBUG is defined in the environment it will be used.
|
||||
@ -165,60 +129,6 @@ MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION)
|
||||
!endif
|
||||
CXX_FLAGS=$(CXX_FLAGS) $(MS_RUNTIME_OPTION)
|
||||
|
||||
# How /GX option is spelled
|
||||
GX_OPTION = /GX
|
||||
|
||||
# Optimization settings for various versions of the compilers and types of
|
||||
# builds. Three basic sets of settings: product, fastdebug, and debug.
|
||||
# These get added into CXX_FLAGS as needed by other makefiles.
|
||||
!if "$(COMPILER_NAME)" == "VC6"
|
||||
PRODUCT_OPT_OPTION = /Ox /Os /Gy /GF
|
||||
FASTDEBUG_OPT_OPTION = /Ox /Os /Gy /GF
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2003"
|
||||
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
SAFESEH_FLAG = /SAFESEH
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2005"
|
||||
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
GX_OPTION = /EHsc
|
||||
# This VS2005 compiler has /GS as a default and requires bufferoverflowU.lib
|
||||
# on the link command line, otherwise we get missing __security_check_cookie
|
||||
# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
|
||||
# NOTE: Currently we decided to not use /GS-
|
||||
BUFFEROVERFLOWLIB = bufferoverflowU.lib
|
||||
LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB)
|
||||
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||
# as resources inside build artifacts.
|
||||
!if "x$(MT)" == "x"
|
||||
MT=mt.exe
|
||||
!endif
|
||||
SAFESEH_FLAG = /SAFESEH
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2008"
|
||||
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
GX_OPTION = /EHsc
|
||||
LD_FLAGS = /manifest $(LD_FLAGS)
|
||||
MP_FLAG = /MP
|
||||
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||
# as resources inside build artifacts.
|
||||
!if "x$(MT)" == "x"
|
||||
MT=mt.exe
|
||||
!endif
|
||||
SAFESEH_FLAG = /SAFESEH
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2010"
|
||||
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
@ -233,26 +143,6 @@ MT=mt.exe
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
LD_FLAGS = /SAFESEH $(LD_FLAGS)
|
||||
!endif
|
||||
!endif
|
||||
|
||||
!if "$(COMPILER_NAME)" == "VS2012"
|
||||
PRODUCT_OPT_OPTION = /O2 /Oy-
|
||||
FASTDEBUG_OPT_OPTION = /O2 /Oy-
|
||||
DEBUG_OPT_OPTION = /Od
|
||||
GX_OPTION = /EHsc
|
||||
LD_FLAGS = /manifest $(LD_FLAGS)
|
||||
MP_FLAG = /MP
|
||||
# Manifest Tool - used in VS2005 and later to adjust manifests stored
|
||||
# as resources inside build artifacts.
|
||||
!if "x$(MT)" == "x"
|
||||
MT=mt.exe
|
||||
!endif
|
||||
SAFESEH_FLAG = /SAFESEH
|
||||
!endif
|
||||
|
||||
!if "$(BUILDARCH)" == "i486"
|
||||
LD_FLAGS = $(SAFESEH_FLAG) $(LD_FLAGS)
|
||||
!endif
|
||||
|
||||
CXX_FLAGS = $(CXX_FLAGS) $(MP_FLAG)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2003, 2014, 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
|
||||
@ -49,35 +49,8 @@ BOOT_TARGET_CLASS_VERSION=6
|
||||
JAVAC_FLAGS=-g -encoding ascii
|
||||
BOOTSTRAP_JAVAC_FLAGS=$(JAVAC_FLAGS) -source $(BOOT_SOURCE_LANGUAGE_VERSION) -target $(BOOT_TARGET_CLASS_VERSION)
|
||||
|
||||
ProjectFile=jvm.vcproj
|
||||
|
||||
!if "$(MSC_VER)" == "1200"
|
||||
|
||||
VcVersion=VC6
|
||||
ProjectFile=jvm.dsp
|
||||
|
||||
!elseif "$(MSC_VER)" == "1400"
|
||||
|
||||
VcVersion=VC8
|
||||
|
||||
!elseif "$(MSC_VER)" == "1500"
|
||||
|
||||
VcVersion=VC9
|
||||
|
||||
!elseif "$(MSC_VER)" == "1600"
|
||||
|
||||
VcVersion=VC10
|
||||
ProjectFile=jvm.vcxproj
|
||||
|
||||
!elseif "$(MSC_VER)" == "1700"
|
||||
# This is VS2012, but it loads VS10 projects just fine (and will
|
||||
# VS2012 and VS2013 loads VS10 projects just fine (and will
|
||||
# upgrade them automatically to VS2012 format).
|
||||
|
||||
VcVersion=VC10
|
||||
ProjectFile=jvm.vcxproj
|
||||
|
||||
!else
|
||||
|
||||
VcVersion=VC7
|
||||
|
||||
!endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2003, 2014, 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
|
||||
@ -85,14 +85,9 @@ checkAndBuildSA:: $(SAWINDBG)
|
||||
# will be useful to have the assertion checks in place
|
||||
|
||||
!if "$(BUILDARCH)" == "ia64"
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -c
|
||||
!elseif "$(BUILDARCH)" == "amd64"
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
|
||||
!if "$(COMPILER_NAME)" == "VS2005"
|
||||
# On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line,
|
||||
# otherwise we get missing __security_check_cookie externals at link time.
|
||||
SA_LD_FLAGS = bufferoverflowU.lib
|
||||
!endif
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -c
|
||||
!else
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -FD -RTC1 -c
|
||||
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 2014, 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
|
||||
@ -27,9 +27,9 @@
|
||||
all: checkCL checkLink
|
||||
|
||||
checkCL:
|
||||
@ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" \
|
||||
echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection.
|
||||
@ if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" if "$(MSC_VER)" NEQ "1800" \
|
||||
echo *** WARNING *** Unsupported cl.exe version detected: $(MSC_VER) ($(RAW_MSC_VER)), only 1600/1700/1800 (Visual Studio 2010/2012/2013) are supported.
|
||||
|
||||
checkLink:
|
||||
@ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" \
|
||||
echo *** WARNING *** unrecognized link.exe version $(LD_VER) ($(RAW_LD_VER)). Use FORCE_LD_VER to override automatic detection.
|
||||
@ if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" if "$(LD_VER)" NEQ "1200" \
|
||||
echo *** WARNING *** Unsupported link.exe version detected: $(LD_VER) ($(RAW_LD_VER)), only 1000/1100/1200 (Visual Studio 2010/2012/2013) are supported.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1997, 2014, 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
|
||||
@ -132,7 +132,7 @@ CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER
|
||||
|
||||
!if "$(USE_PRECOMPILED_HEADER)" != "0"
|
||||
CXX_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp"
|
||||
!if "$(COMPILER_NAME)" == "VS2012"
|
||||
!if "$(MSC_VER)" > "1600"
|
||||
# VS2012 requires this object file to be listed:
|
||||
LD_FLAGS=$(LD_FLAGS) _build_pch_file.obj
|
||||
!endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2014, 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
|
||||
@ -120,7 +120,6 @@ ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -def
|
||||
ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions)
|
||||
|
||||
$(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
|
||||
@if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long'
|
||||
@$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
|
||||
|
||||
clean:
|
||||
|
@ -625,6 +625,7 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||
__ lea(rscratch1, polling_page);
|
||||
offset = __ offset();
|
||||
add_debug_info_for_branch(info);
|
||||
__ relocate(relocInfo::poll_type);
|
||||
__ testl(rax, Address(rscratch1, 0));
|
||||
} else {
|
||||
add_debug_info_for_branch(info);
|
||||
|
@ -2987,6 +2987,9 @@ void ClassFileParser::parse_classfile_attributes(ClassFileParser::ClassAnnotatio
|
||||
} else {
|
||||
parsed_enclosingmethod_attribute = true;
|
||||
}
|
||||
guarantee_property(attribute_length == 4,
|
||||
"Wrong EnclosingMethod attribute length %u in class file %s",
|
||||
attribute_length, CHECK);
|
||||
cfs->guarantee_more(4, CHECK); // class_index, method_index
|
||||
enclosing_method_class_index = cfs->get_u2_fast();
|
||||
enclosing_method_method_index = cfs->get_u2_fast();
|
||||
@ -4067,6 +4070,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
this_klass->set_major_version(major_version);
|
||||
this_klass->set_has_default_methods(has_default_methods);
|
||||
|
||||
if (!host_klass.is_null()) {
|
||||
assert (this_klass->is_anonymous(), "should be the same");
|
||||
this_klass->set_host_klass(host_klass());
|
||||
}
|
||||
|
||||
// Set up Method*::intrinsic_id as soon as we know the names of methods.
|
||||
// (We used to do this lazily, but now we query it in Rewriter,
|
||||
// which is eagerly done for every method, so we might as well do it now,
|
||||
@ -4664,9 +4672,7 @@ bool ClassFileParser::has_illegal_visibility(jint flags) {
|
||||
}
|
||||
|
||||
bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
|
||||
u2 max_version =
|
||||
JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION :
|
||||
(JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION);
|
||||
u2 max_version = JAVA_MAX_SUPPORTED_VERSION;
|
||||
return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
|
||||
(major <= max_version) &&
|
||||
((major != max_version) ||
|
||||
|
@ -1126,7 +1126,7 @@ void ClassLoader::verify() {
|
||||
|
||||
|
||||
// JDK 1.3 version
|
||||
typedef struct real_jzentry13 { /* Zip file entry */
|
||||
typedef struct real_jzentry { /* Zip file entry */
|
||||
char *name; /* entry name */
|
||||
jint time; /* modification time */
|
||||
jint size; /* size of uncompressed data */
|
||||
@ -1135,9 +1135,9 @@ typedef struct real_jzentry13 { /* Zip file entry */
|
||||
char *comment; /* optional zip file comment */
|
||||
jbyte *extra; /* optional extra data */
|
||||
jint pos; /* position of LOC header (if negative) or data */
|
||||
} real_jzentry13;
|
||||
} real_jzentry;
|
||||
|
||||
typedef struct real_jzfile13 { /* Zip file */
|
||||
typedef struct real_jzfile { /* Zip file */
|
||||
char *name; /* zip file name */
|
||||
jint refs; /* number of active references */
|
||||
jint fd; /* open file descriptor */
|
||||
@ -1148,42 +1148,14 @@ typedef struct real_jzfile13 { /* Zip file */
|
||||
jint total; /* total number of entries */
|
||||
unsigned short *table; /* Hash chain heads: indexes into entries */
|
||||
jint tablelen; /* number of hash eads */
|
||||
real_jzfile13 *next; /* next zip file in search list */
|
||||
real_jzfile *next; /* next zip file in search list */
|
||||
jzentry *cache; /* we cache the most recently freed jzentry */
|
||||
/* Information on metadata names in META-INF directory */
|
||||
char **metanames; /* array of meta names (may have null names) */
|
||||
jint metacount; /* number of slots in metanames array */
|
||||
/* If there are any per-entry comments, they are in the comments array */
|
||||
char **comments;
|
||||
} real_jzfile13;
|
||||
|
||||
// JDK 1.2 version
|
||||
typedef struct real_jzentry12 { /* Zip file entry */
|
||||
char *name; /* entry name */
|
||||
jint time; /* modification time */
|
||||
jint size; /* size of uncompressed data */
|
||||
jint csize; /* size of compressed data (zero if uncompressed) */
|
||||
jint crc; /* crc of uncompressed data */
|
||||
char *comment; /* optional zip file comment */
|
||||
jbyte *extra; /* optional extra data */
|
||||
jint pos; /* position of LOC header (if negative) or data */
|
||||
struct real_jzentry12 *next; /* next entry in hash table */
|
||||
} real_jzentry12;
|
||||
|
||||
typedef struct real_jzfile12 { /* Zip file */
|
||||
char *name; /* zip file name */
|
||||
jint refs; /* number of active references */
|
||||
jint fd; /* open file descriptor */
|
||||
void *lock; /* read lock */
|
||||
char *comment; /* zip file comment */
|
||||
char *msg; /* zip error message */
|
||||
real_jzentry12 *entries; /* array of zip entries */
|
||||
jint total; /* total number of entries */
|
||||
real_jzentry12 **table; /* hash table of entries */
|
||||
jint tablelen; /* number of buckets */
|
||||
jzfile *next; /* next zip file in search list */
|
||||
} real_jzfile12;
|
||||
|
||||
} real_jzfile;
|
||||
|
||||
void ClassPathDirEntry::compile_the_world(Handle loader, TRAPS) {
|
||||
// For now we only compile all methods in all classes in zip/jar files
|
||||
@ -1197,10 +1169,14 @@ bool ClassPathDirEntry::is_rt_jar() {
|
||||
}
|
||||
|
||||
void ClassPathZipEntry::compile_the_world(Handle loader, TRAPS) {
|
||||
if (JDK_Version::is_jdk12x_version()) {
|
||||
compile_the_world12(loader, THREAD);
|
||||
} else {
|
||||
compile_the_world13(loader, THREAD);
|
||||
real_jzfile* zip = (real_jzfile*) _zip;
|
||||
tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
|
||||
tty->cr();
|
||||
// Iterate over all entries in zip file
|
||||
for (int n = 0; ; n++) {
|
||||
real_jzentry * ze = (real_jzentry *)((*GetNextEntry)(_zip, n));
|
||||
if (ze == NULL) break;
|
||||
ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
|
||||
}
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
|
||||
@ -1213,54 +1189,8 @@ void ClassPathZipEntry::compile_the_world(Handle loader, TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
// Version that works for JDK 1.3.x
|
||||
void ClassPathZipEntry::compile_the_world13(Handle loader, TRAPS) {
|
||||
real_jzfile13* zip = (real_jzfile13*) _zip;
|
||||
tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
|
||||
tty->cr();
|
||||
// Iterate over all entries in zip file
|
||||
for (int n = 0; ; n++) {
|
||||
real_jzentry13 * ze = (real_jzentry13 *)((*GetNextEntry)(_zip, n));
|
||||
if (ze == NULL) break;
|
||||
ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Version that works for JDK 1.2.x
|
||||
void ClassPathZipEntry::compile_the_world12(Handle loader, TRAPS) {
|
||||
real_jzfile12* zip = (real_jzfile12*) _zip;
|
||||
tty->print_cr("CompileTheWorld : Compiling all classes in %s", zip->name);
|
||||
tty->cr();
|
||||
// Iterate over all entries in zip file
|
||||
for (int n = 0; ; n++) {
|
||||
real_jzentry12 * ze = (real_jzentry12 *)((*GetNextEntry)(_zip, n));
|
||||
if (ze == NULL) break;
|
||||
ClassLoader::compile_the_world_in(ze->name, loader, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassPathZipEntry::is_rt_jar() {
|
||||
if (JDK_Version::is_jdk12x_version()) {
|
||||
return is_rt_jar12();
|
||||
} else {
|
||||
return is_rt_jar13();
|
||||
}
|
||||
}
|
||||
|
||||
// JDK 1.3 version
|
||||
bool ClassPathZipEntry::is_rt_jar13() {
|
||||
real_jzfile13* zip = (real_jzfile13*) _zip;
|
||||
int len = (int)strlen(zip->name);
|
||||
// Check whether zip name ends in "rt.jar"
|
||||
// This will match other archives named rt.jar as well, but this is
|
||||
// only used for debugging.
|
||||
return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0);
|
||||
}
|
||||
|
||||
// JDK 1.2 version
|
||||
bool ClassPathZipEntry::is_rt_jar12() {
|
||||
real_jzfile12* zip = (real_jzfile12*) _zip;
|
||||
real_jzfile* zip = (real_jzfile*) _zip;
|
||||
int len = (int)strlen(zip->name);
|
||||
// Check whether zip name ends in "rt.jar"
|
||||
// This will match other archives named rt.jar as well, but this is
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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,11 +111,7 @@ class ClassPathZipEntry: public ClassPathEntry {
|
||||
void contents_do(void f(const char* name, void* context), void* context);
|
||||
// Debugging
|
||||
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
|
||||
NOT_PRODUCT(void compile_the_world12(Handle loader, TRAPS);) // JDK 1.2 version
|
||||
NOT_PRODUCT(void compile_the_world13(Handle loader, TRAPS);) // JDK 1.3 version
|
||||
NOT_PRODUCT(bool is_rt_jar();)
|
||||
NOT_PRODUCT(bool is_rt_jar12();)
|
||||
NOT_PRODUCT(bool is_rt_jar13();)
|
||||
};
|
||||
|
||||
|
||||
|
@ -624,6 +624,12 @@ void ClassLoaderDataGraph::always_strong_oops_do(OopClosure* f, KlassClosure* kl
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::cld_do(CLDClosure* cl) {
|
||||
for (ClassLoaderData* cld = _head; cl != NULL && cld != NULL; cld = cld->next()) {
|
||||
cl->do_cld(cld);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
|
||||
cld->classes_do(klass_closure);
|
||||
|
@ -77,6 +77,7 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static void oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim);
|
||||
static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
|
||||
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
|
||||
static void cld_do(CLDClosure* cl);
|
||||
static void classes_do(KlassClosure* klass_closure);
|
||||
static void classes_do(void f(Klass* const));
|
||||
static void methods_do(void f(Method*));
|
||||
|
167
hotspot/src/share/vm/classfile/classLoaderStats.cpp
Normal file
167
hotspot/src/share/vm/classfile/classLoaderStats.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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 "classfile/classLoaderStats.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
|
||||
class ClassStatsClosure : public KlassClosure {
|
||||
public:
|
||||
int _num_classes;
|
||||
|
||||
ClassStatsClosure() :
|
||||
_num_classes(0) {
|
||||
}
|
||||
|
||||
virtual void do_klass(Klass* k) {
|
||||
_num_classes++;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) {
|
||||
oop cl = cld->class_loader();
|
||||
ClassLoaderStats* cls;
|
||||
|
||||
// The hashtable key is the ClassLoader oop since we want to account
|
||||
// for "real" classes and anonymous classes together
|
||||
ClassLoaderStats** cls_ptr = _stats->get(cl);
|
||||
if (cls_ptr == NULL) {
|
||||
cls = new ClassLoaderStats();
|
||||
_stats->put(cl, cls);
|
||||
_total_loaders++;
|
||||
} else {
|
||||
cls = *cls_ptr;
|
||||
}
|
||||
|
||||
if (!cld->is_anonymous()) {
|
||||
cls->_cld = cld;
|
||||
}
|
||||
|
||||
cls->_class_loader = cl;
|
||||
if (cl != NULL) {
|
||||
cls->_parent = java_lang_ClassLoader::parent(cl);
|
||||
addEmptyParents(cls->_parent);
|
||||
}
|
||||
|
||||
ClassStatsClosure csc;
|
||||
cld->classes_do(&csc);
|
||||
if(cld->is_anonymous()) {
|
||||
cls->_anon_classes_count += csc._num_classes;
|
||||
} else {
|
||||
cls->_classes_count = csc._num_classes;
|
||||
}
|
||||
_total_classes += csc._num_classes;
|
||||
|
||||
Metaspace* ms = cld->metaspace_or_null();
|
||||
if (ms != NULL) {
|
||||
if(cld->is_anonymous()) {
|
||||
cls->_anon_chunk_sz += ms->allocated_chunks_bytes();
|
||||
cls->_anon_block_sz += ms->allocated_blocks_bytes();
|
||||
} else {
|
||||
cls->_chunk_sz = ms->allocated_chunks_bytes();
|
||||
cls->_block_sz = ms->allocated_blocks_bytes();
|
||||
}
|
||||
_total_chunk_sz += ms->allocated_chunks_bytes();
|
||||
_total_block_sz += ms->allocated_blocks_bytes();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Handles the difference in pointer width on 32 and 64 bit platforms
|
||||
#ifdef _LP64
|
||||
#define SPACE "%8s"
|
||||
#else
|
||||
#define SPACE "%s"
|
||||
#endif
|
||||
|
||||
|
||||
bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls) {
|
||||
Klass* class_loader_klass = (cls->_class_loader == NULL ? NULL : cls->_class_loader->klass());
|
||||
Klass* parent_klass = (cls->_parent == NULL ? NULL : cls->_parent->klass());
|
||||
|
||||
_out->print(INTPTR_FORMAT " " INTPTR_FORMAT " " INTPTR_FORMAT " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ",
|
||||
p2i(class_loader_klass), p2i(parent_klass), p2i(cls->_cld),
|
||||
cls->_classes_count,
|
||||
cls->_chunk_sz, cls->_block_sz);
|
||||
if (class_loader_klass != NULL) {
|
||||
_out->print("%s", class_loader_klass->external_name());
|
||||
} else {
|
||||
_out->print("<boot class loader>");
|
||||
}
|
||||
_out->cr();
|
||||
if (cls->_anon_classes_count > 0) {
|
||||
_out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + unsafe anonymous classes",
|
||||
"", "", "",
|
||||
cls->_anon_classes_count,
|
||||
cls->_anon_chunk_sz, cls->_anon_block_sz);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassLoaderStatsClosure::print() {
|
||||
_out->print_cr("ClassLoader" SPACE " Parent" SPACE " CLD*" SPACE " Classes ChunkSz BlockSz Type", "", "", "");
|
||||
_stats->iterate(this);
|
||||
_out->print("Total = " UINTX_FORMAT_W(-6), _total_loaders);
|
||||
_out->print(SPACE SPACE SPACE " ", "", "", "");
|
||||
_out->print_cr(UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " ",
|
||||
_total_classes,
|
||||
_total_chunk_sz,
|
||||
_total_block_sz);
|
||||
_out->print_cr("ChunkSz: Total size of all allocated metaspace chunks");
|
||||
_out->print_cr("BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)");
|
||||
}
|
||||
|
||||
|
||||
void ClassLoaderStatsClosure::addEmptyParents(oop cl) {
|
||||
while (cl != NULL && java_lang_ClassLoader::loader_data(cl) == NULL) {
|
||||
// This classloader has not loaded any classes
|
||||
ClassLoaderStats** cls_ptr = _stats->get(cl);
|
||||
if (cls_ptr == NULL) {
|
||||
// It does not exist in our table - add it
|
||||
ClassLoaderStats* cls = new ClassLoaderStats();
|
||||
cls->_class_loader = cl;
|
||||
cls->_parent = java_lang_ClassLoader::parent(cl);
|
||||
_stats->put(cl, cls);
|
||||
_total_loaders++;
|
||||
}
|
||||
|
||||
cl = java_lang_ClassLoader::parent(cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ClassLoaderStatsVMOperation::doit() {
|
||||
ClassLoaderStatsClosure clsc (_out);
|
||||
ClassLoaderDataGraph::cld_do(&clsc);
|
||||
clsc.print();
|
||||
}
|
||||
|
||||
|
||||
void ClassLoaderStatsDCmd::execute(DCmdSource source, TRAPS) {
|
||||
ClassLoaderStatsVMOperation op(output());
|
||||
VMThread::execute(&op);
|
||||
}
|
152
hotspot/src/share/vm/classfile/classLoaderStats.hpp
Normal file
152
hotspot/src/share/vm/classfile/classLoaderStats.hpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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_CLASSFILE_CLASSLOADERSTATS_HPP
|
||||
#define SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
|
||||
|
||||
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "runtime/vm_operations.hpp"
|
||||
#include "services/diagnosticCommand.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
|
||||
class ClassLoaderStatsDCmd : public DCmd {
|
||||
public:
|
||||
ClassLoaderStatsDCmd(outputStream* output, bool heap) :
|
||||
DCmd(output, heap) {
|
||||
}
|
||||
|
||||
static const char* name() {
|
||||
return "VM.classloader_stats";
|
||||
}
|
||||
|
||||
static const char* description() {
|
||||
return "Print statistics about all ClassLoaders.";
|
||||
}
|
||||
|
||||
static const char* impact() {
|
||||
return "Low";
|
||||
}
|
||||
|
||||
virtual void execute(DCmdSource source, TRAPS);
|
||||
|
||||
static int num_arguments() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const JavaPermission permission() {
|
||||
JavaPermission p = {"java.lang.management.ManagementPermission",
|
||||
"monitor", NULL};
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ClassLoaderStats : public ResourceObj {
|
||||
public:
|
||||
ClassLoaderData* _cld;
|
||||
oop _class_loader;
|
||||
oop _parent;
|
||||
|
||||
size_t _chunk_sz;
|
||||
size_t _block_sz;
|
||||
uintx _classes_count;
|
||||
|
||||
size_t _anon_chunk_sz;
|
||||
size_t _anon_block_sz;
|
||||
uintx _anon_classes_count;
|
||||
|
||||
ClassLoaderStats() :
|
||||
_cld(0),
|
||||
_class_loader(0),
|
||||
_parent(0),
|
||||
_chunk_sz(0),
|
||||
_block_sz(0),
|
||||
_classes_count(0),
|
||||
_anon_block_sz(0),
|
||||
_anon_chunk_sz(0),
|
||||
_anon_classes_count(0) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class ClassLoaderStatsClosure : public CLDClosure {
|
||||
protected:
|
||||
static bool oop_equals(oop const& s1, oop const& s2) {
|
||||
return s1 == s2;
|
||||
}
|
||||
|
||||
static unsigned oop_hash(oop const& s1) {
|
||||
unsigned hash = (unsigned)((uintptr_t)&s1);
|
||||
return hash ^ (hash >> LogMinObjAlignment);
|
||||
}
|
||||
|
||||
typedef ResourceHashtable<oop, ClassLoaderStats*,
|
||||
ClassLoaderStatsClosure::oop_hash, ClassLoaderStatsClosure::oop_equals> StatsTable;
|
||||
|
||||
outputStream* _out;
|
||||
StatsTable* _stats;
|
||||
uintx _total_loaders;
|
||||
uintx _total_classes;
|
||||
size_t _total_chunk_sz;
|
||||
size_t _total_block_sz;
|
||||
|
||||
public:
|
||||
ClassLoaderStatsClosure(outputStream* out) :
|
||||
_out(out),
|
||||
_total_loaders(0),
|
||||
_total_block_sz(0),
|
||||
_total_chunk_sz(0),
|
||||
_total_classes(0),
|
||||
_stats(new StatsTable()) {
|
||||
}
|
||||
|
||||
virtual void do_cld(ClassLoaderData* cld);
|
||||
virtual bool do_entry(oop const& key, ClassLoaderStats* const& cls);
|
||||
void print();
|
||||
|
||||
private:
|
||||
void addEmptyParents(oop cl);
|
||||
};
|
||||
|
||||
|
||||
class ClassLoaderStatsVMOperation : public VM_Operation {
|
||||
outputStream* _out;
|
||||
|
||||
public:
|
||||
ClassLoaderStatsVMOperation(outputStream* out) :
|
||||
_out(out) {
|
||||
}
|
||||
|
||||
VMOp_Type type() const {
|
||||
return VMOp_ClassLoaderStatsOperation;
|
||||
}
|
||||
|
||||
void doit();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_CLASSFILE_CLASSLOADERSTATS_HPP
|
@ -857,9 +857,7 @@ void java_lang_Class::compute_offsets() {
|
||||
}
|
||||
|
||||
int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
|
||||
if (!JDK_Version::is_gte_jdk15x_version()
|
||||
|| classRedefinedCount_offset == -1) {
|
||||
// The classRedefinedCount field is only present starting in 1.5.
|
||||
if (classRedefinedCount_offset == -1) {
|
||||
// If we don't have an offset for it then just return -1 as a marker.
|
||||
return -1;
|
||||
}
|
||||
@ -868,9 +866,7 @@ int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
|
||||
}
|
||||
|
||||
void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) {
|
||||
if (!JDK_Version::is_gte_jdk15x_version()
|
||||
|| classRedefinedCount_offset == -1) {
|
||||
// The classRedefinedCount field is only present starting in 1.5.
|
||||
if (classRedefinedCount_offset == -1) {
|
||||
// If we don't have an offset for it then nothing to set.
|
||||
return;
|
||||
}
|
||||
@ -1000,9 +996,7 @@ oop java_lang_Thread::inherited_access_control_context(oop java_thread) {
|
||||
|
||||
|
||||
jlong java_lang_Thread::stackSize(oop java_thread) {
|
||||
// The stackSize field is only present starting in 1.4
|
||||
if (_stackSize_offset > 0) {
|
||||
assert(JDK_Version::is_gte_jdk14x_version(), "sanity check");
|
||||
return java_thread->long_field(_stackSize_offset);
|
||||
} else {
|
||||
return 0;
|
||||
@ -1078,7 +1072,7 @@ bool java_lang_Thread::set_park_event(oop java_thread, jlong ptr) {
|
||||
|
||||
|
||||
const char* java_lang_Thread::thread_status_name(oop java_thread) {
|
||||
assert(JDK_Version::is_gte_jdk15x_version() && _thread_status_offset != 0, "Must have thread status");
|
||||
assert(_thread_status_offset != 0, "Must have thread status");
|
||||
ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset);
|
||||
switch (status) {
|
||||
case NEW : return "NEW";
|
||||
@ -1217,7 +1211,6 @@ void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) {
|
||||
}
|
||||
|
||||
void java_lang_Throwable::clear_stacktrace(oop throwable) {
|
||||
assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
|
||||
set_stacktrace(throwable, NULL);
|
||||
}
|
||||
|
||||
@ -1548,12 +1541,9 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle met
|
||||
// Start out by clearing the backtrace for this object, in case the VM
|
||||
// runs out of memory while allocating the stack trace
|
||||
set_backtrace(throwable(), NULL);
|
||||
if (JDK_Version::is_gte_jdk14x_version()) {
|
||||
// New since 1.4, clear lazily constructed Java level stacktrace if
|
||||
// refilling occurs
|
||||
// Clear lazily constructed Java level stacktrace if refilling occurs
|
||||
// This is unnecessary in 1.7+ but harmless
|
||||
clear_stacktrace(throwable());
|
||||
}
|
||||
|
||||
int max_depth = MaxJavaStackTraceDepth;
|
||||
JavaThread* thread = (JavaThread*)THREAD;
|
||||
@ -1739,14 +1729,10 @@ void java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle t
|
||||
if (chunk_count >= max_chunks) break;
|
||||
}
|
||||
|
||||
// For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support
|
||||
// was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround
|
||||
// can be removed in a JDK using this JVM version
|
||||
if (JDK_Version::is_gte_jdk17x_version()) {
|
||||
// We support the Throwable immutability protocol defined for Java 7.
|
||||
java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
|
||||
assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) {
|
||||
@ -3022,8 +3008,7 @@ bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
|
||||
// based on non-null field
|
||||
// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
|
||||
bool java_lang_ClassLoader::parallelCapable(oop class_loader) {
|
||||
if (!JDK_Version::is_gte_jdk17x_version()
|
||||
|| parallelCapable_offset == -1) {
|
||||
if (parallelCapable_offset == -1) {
|
||||
// Default for backward compatibility is false
|
||||
return false;
|
||||
}
|
||||
@ -3219,7 +3204,6 @@ void java_nio_Buffer::compute_offsets() {
|
||||
void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
|
||||
if (_owner_offset != 0) return;
|
||||
|
||||
assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later");
|
||||
SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK);
|
||||
Klass* k = SystemDictionary::abstract_ownable_synchronizer_klass();
|
||||
compute_offset(_owner_offset, k,
|
||||
@ -3309,14 +3293,9 @@ void JavaClasses::compute_offsets() {
|
||||
java_lang_reflect_Method::compute_offsets();
|
||||
java_lang_reflect_Constructor::compute_offsets();
|
||||
java_lang_reflect_Field::compute_offsets();
|
||||
if (JDK_Version::is_gte_jdk14x_version()) {
|
||||
java_nio_Buffer::compute_offsets();
|
||||
}
|
||||
if (JDK_Version::is_gte_jdk15x_version()) {
|
||||
sun_reflect_ConstantPool::compute_offsets();
|
||||
sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
|
||||
}
|
||||
if (JDK_Version::is_gte_jdk18x_version())
|
||||
java_lang_reflect_Parameter::compute_offsets();
|
||||
|
||||
// generated interpreter code wants to know about the offsets we just computed:
|
||||
@ -3502,7 +3481,7 @@ void JavaClasses::check_offsets() {
|
||||
// into merlin "for some time." Without it, the vm will fail with early
|
||||
// merlin builds.
|
||||
|
||||
if (CheckAssertionStatusDirectives && JDK_Version::is_gte_jdk14x_version()) {
|
||||
if (CheckAssertionStatusDirectives) {
|
||||
const char* nm = "java/lang/AssertionStatusDirectives";
|
||||
const char* sig = "[Ljava/lang/String;";
|
||||
CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classes, sig);
|
||||
|
@ -997,7 +997,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
|
||||
|
||||
|
||||
if (host_klass.not_null() && k.not_null()) {
|
||||
k->set_host_klass(host_klass());
|
||||
// If it's anonymous, initialize it now, since nobody else will.
|
||||
|
||||
{
|
||||
@ -1754,8 +1753,6 @@ void SystemDictionary::methods_do(void f(Method*)) {
|
||||
// Lazily load klasses
|
||||
|
||||
void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
|
||||
assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later");
|
||||
|
||||
// if multiple threads calling this function, only one thread will load
|
||||
// the class. The other threads will find the loaded version once the
|
||||
// class is loaded.
|
||||
|
@ -139,14 +139,13 @@ class Ticks;
|
||||
do_klass(reflect_Constructor_klass, java_lang_reflect_Constructor, Pre ) \
|
||||
\
|
||||
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
|
||||
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
|
||||
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
|
||||
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
|
||||
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
|
||||
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
|
||||
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Pre ) \
|
||||
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Pre ) \
|
||||
do_klass(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt ) \
|
||||
do_klass(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt_Only_JDK15 ) \
|
||||
do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15 ) \
|
||||
do_klass(reflect_ConstantPool_klass, sun_reflect_ConstantPool, Opt ) \
|
||||
do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt ) \
|
||||
do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \
|
||||
\
|
||||
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
|
||||
@ -169,7 +168,6 @@ class Ticks;
|
||||
\
|
||||
/* It's NULL in non-1.4 JDKs. */ \
|
||||
do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \
|
||||
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
|
||||
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
|
||||
do_klass(nio_Buffer_klass, java_nio_Buffer, Opt ) \
|
||||
\
|
||||
@ -209,10 +207,8 @@ class SystemDictionary : AllStatic {
|
||||
// Options after this point will use resolve_or_null instead.
|
||||
|
||||
Opt, // preload tried; NULL if not present
|
||||
Opt_Only_JDK14NewRef, // preload tried; use only with NewReflection
|
||||
Opt_Only_JDK15, // preload tried; use only with JDK1.5+
|
||||
OPTION_LIMIT,
|
||||
CEIL_LG_OPTION_LIMIT = 4 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
|
||||
CEIL_LG_OPTION_LIMIT = 2 // OPTION_LIMIT <= (1<<CEIL_LG_OPTION_LIMIT)
|
||||
};
|
||||
|
||||
|
||||
@ -385,15 +381,6 @@ public:
|
||||
|
||||
static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
|
||||
static Klass* check_klass_Opt( Klass* k) { return k; }
|
||||
static Klass* check_klass_Opt_Only_JDK15(Klass* k) {
|
||||
assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
|
||||
return k;
|
||||
}
|
||||
static Klass* check_klass_Opt_Only_JDK14NewRef(Klass* k) {
|
||||
assert(JDK_Version::is_gte_jdk14x_version(), "JDK 1.4 only");
|
||||
// despite the optional loading, if you use this it must be present:
|
||||
return check_klass(k);
|
||||
}
|
||||
|
||||
static bool initialize_wk_klass(WKID id, int init_opt, TRAPS);
|
||||
static void initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS);
|
||||
|
@ -320,7 +320,6 @@
|
||||
template(reference_discovered_name, "discovered") \
|
||||
template(run_finalization_name, "runFinalization") \
|
||||
template(run_finalizers_on_exit_name, "runFinalizersOnExit") \
|
||||
template(uncaughtException_name, "uncaughtException") \
|
||||
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
|
||||
template(initializeSystemClass_name, "initializeSystemClass") \
|
||||
template(loadClass_name, "loadClass") \
|
||||
|
@ -475,7 +475,7 @@ MethodLivenessResult MethodLiveness::get_liveness_at(int entry_bci) {
|
||||
bci = 0;
|
||||
}
|
||||
|
||||
MethodLivenessResult answer((uintptr_t*)NULL,0);
|
||||
MethodLivenessResult answer((BitMap::bm_word_t*)NULL,0);
|
||||
|
||||
if (_block_count > 0) {
|
||||
if (TimeLivenessAnalysis) _time_total.start();
|
||||
@ -1000,7 +1000,7 @@ bool MethodLiveness::BasicBlock::merge_exception(BitMap other) {
|
||||
}
|
||||
|
||||
MethodLivenessResult MethodLiveness::BasicBlock::get_liveness_at(ciMethod* method, int bci) {
|
||||
MethodLivenessResult answer(NEW_RESOURCE_ARRAY(uintptr_t, _analyzer->bit_map_size_words()),
|
||||
MethodLivenessResult answer(NEW_RESOURCE_ARRAY(BitMap::bm_word_t, _analyzer->bit_map_size_words()),
|
||||
_analyzer->bit_map_size_bits());
|
||||
answer.set_is_valid();
|
||||
|
||||
|
@ -127,7 +127,7 @@ bool CMBitMap::allocate(ReservedSpace heap_rs) {
|
||||
}
|
||||
assert(_virtual_space.committed_size() == brs.size(),
|
||||
"didn't reserve backing store for all of concurrent marking bit map?");
|
||||
_bm.set_map((uintptr_t*)_virtual_space.low());
|
||||
_bm.set_map((BitMap::bm_word_t*)_virtual_space.low());
|
||||
assert(_virtual_space.committed_size() << (_shifter + LogBitsPerByte) >=
|
||||
_bmWordSize, "inconsistency in bit map sizing");
|
||||
_bm.set_size(_bmWordSize >> _shifter);
|
||||
|
@ -433,14 +433,6 @@ HeapRegion* G1CollectedHeap::pop_dirty_cards_region()
|
||||
return hr;
|
||||
}
|
||||
|
||||
void G1CollectedHeap::stop_conc_gc_threads() {
|
||||
_cg1r->stop();
|
||||
_cmThread->stop();
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
G1StringDedup::stop();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// A region is added to the collection set as it is retired
|
||||
// so an address p can point to a region which will be in the
|
||||
@ -2174,20 +2166,14 @@ jint G1CollectedHeap::initialize() {
|
||||
}
|
||||
|
||||
void G1CollectedHeap::stop() {
|
||||
#if 0
|
||||
// Stopping concurrent worker threads is currently disabled until
|
||||
// some bugs in concurrent mark has been resolve. Without fixing
|
||||
// those bugs first we risk haning during VM exit when trying to
|
||||
// stop these threads.
|
||||
|
||||
// Abort any ongoing concurrent root region scanning and stop all
|
||||
// concurrent threads. We do this to make sure these threads do
|
||||
// not continue to execute and access resources (e.g. gclog_or_tty)
|
||||
// Stop all concurrent threads. We do this to make sure these threads
|
||||
// do not continue to execute and access resources (e.g. gclog_or_tty)
|
||||
// that are destroyed during shutdown.
|
||||
_cm->root_regions()->abort();
|
||||
_cm->root_regions()->wait_until_scan_finished();
|
||||
stop_conc_gc_threads();
|
||||
#endif
|
||||
_cg1r->stop();
|
||||
_cmThread->stop();
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
G1StringDedup::stop();
|
||||
}
|
||||
}
|
||||
|
||||
size_t G1CollectedHeap::conservative_max_heap_alignment() {
|
||||
|
@ -1684,8 +1684,6 @@ public:
|
||||
void print_all_rsets() PRODUCT_RETURN;
|
||||
|
||||
public:
|
||||
void stop_conc_gc_threads();
|
||||
|
||||
size_t pending_card_num();
|
||||
size_t cards_scanned();
|
||||
|
||||
|
@ -71,7 +71,7 @@ ParMarkBitMap::initialize(MemRegion covered_region)
|
||||
if (_virtual_space != NULL && _virtual_space->expand_by(_reserved_byte_size)) {
|
||||
_region_start = covered_region.start();
|
||||
_region_size = covered_region.word_size();
|
||||
idx_t* map = (idx_t*)_virtual_space->reserved_low_addr();
|
||||
BitMap::bm_word_t* map = (BitMap::bm_word_t*)_virtual_space->reserved_low_addr();
|
||||
_beg_bits.set_map(map);
|
||||
_beg_bits.set_size(bits / 2);
|
||||
_end_bits.set_map(map + words / 2);
|
||||
|
@ -945,12 +945,8 @@ void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method
|
||||
Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ?
|
||||
current_klass() :
|
||||
InstanceKlass::cast(current_klass())->host_klass();
|
||||
// As of the fix for 4486457 we disable verification for all of the
|
||||
// dynamically-generated bytecodes associated with the 1.4
|
||||
// reflection implementation, not just those associated with
|
||||
// sun/reflect/SerializationConstructorAccessor.
|
||||
bool is_reflect = JDK_Version::is_gte_jdk14x_version() &&
|
||||
klass_to_check->is_subclass_of(
|
||||
// Disable verification for the dynamically-generated reflection bytecodes.
|
||||
bool is_reflect = klass_to_check->is_subclass_of(
|
||||
SystemDictionary::reflect_MagicAccessorImpl_klass());
|
||||
|
||||
if (!is_reflect &&
|
||||
|
161
hotspot/src/share/vm/memory/guardedMemory.cpp
Normal file
161
hotspot/src/share/vm/memory/guardedMemory.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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 "memory/allocation.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/guardedMemory.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
void* GuardedMemory::wrap_copy(const void* ptr, const size_t len, const void* tag) {
|
||||
size_t total_sz = GuardedMemory::get_total_size(len);
|
||||
void* outerp = os::malloc(total_sz, mtInternal);
|
||||
if (outerp != NULL) {
|
||||
GuardedMemory guarded(outerp, len, tag);
|
||||
void* innerp = guarded.get_user_ptr();
|
||||
memcpy(innerp, ptr, len);
|
||||
return innerp;
|
||||
}
|
||||
return NULL; // OOM
|
||||
}
|
||||
|
||||
bool GuardedMemory::free_copy(void* p) {
|
||||
if (p == NULL) {
|
||||
return true;
|
||||
}
|
||||
GuardedMemory guarded((u_char*)p);
|
||||
bool verify_ok = guarded.verify_guards();
|
||||
|
||||
/* always attempt to free, pass problem on to any nested memchecker */
|
||||
os::free(guarded.release_for_freeing());
|
||||
|
||||
return verify_ok;
|
||||
}
|
||||
|
||||
void GuardedMemory::print_on(outputStream* st) const {
|
||||
if (_base_addr == NULL) {
|
||||
st->print_cr("GuardedMemory(" PTR_FORMAT ") not associated to any memory", p2i(this));
|
||||
return;
|
||||
}
|
||||
st->print_cr("GuardedMemory(" PTR_FORMAT ") base_addr=" PTR_FORMAT
|
||||
" tag=" PTR_FORMAT " user_size=" SIZE_FORMAT " user_data=" PTR_FORMAT,
|
||||
p2i(this), p2i(_base_addr), p2i(get_tag()), get_user_size(), p2i(get_user_ptr()));
|
||||
|
||||
Guard* guard = get_head_guard();
|
||||
st->print_cr(" Header guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
|
||||
guard = get_tail_guard();
|
||||
st->print_cr(" Trailer guard @" PTR_FORMAT " is %s", p2i(guard), (guard->verify() ? "OK" : "BROKEN"));
|
||||
|
||||
u_char udata = *get_user_ptr();
|
||||
switch (udata) {
|
||||
case uninitBlockPad:
|
||||
st->print_cr(" User data appears unused");
|
||||
break;
|
||||
case freeBlockPad:
|
||||
st->print_cr(" User data appears to have been freed");
|
||||
break;
|
||||
default:
|
||||
st->print_cr(" User data appears to be in use");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// test code...
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
|
||||
assert(p != NULL, "NULL pointer given to check");
|
||||
u_char* c = (u_char*) p;
|
||||
GuardedMemory guarded(c);
|
||||
assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
|
||||
assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
|
||||
assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
|
||||
assert(guarded.verify_guards(), "Guard broken");
|
||||
}
|
||||
|
||||
void GuardedMemory::test_guarded_memory() {
|
||||
// Test the basic characteristics...
|
||||
size_t total_sz = GuardedMemory::get_total_size(1);
|
||||
assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
|
||||
u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
|
||||
|
||||
GuardedMemory guarded(basep, 1, (void*)0xf000f000);
|
||||
|
||||
assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
|
||||
u_char* userp = guarded.get_user_ptr();
|
||||
assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
|
||||
guarded_memory_test_check(userp, 1, (void*)0xf000f000);
|
||||
|
||||
void* freep = guarded.release_for_freeing();
|
||||
assert((u_char*)freep == basep, "Expected the same pointer guard was ");
|
||||
assert(*userp == freeBlockPad, "Expected user data to be free block padded");
|
||||
assert(!guarded.verify_guards(), "Expected failed");
|
||||
os::free(freep);
|
||||
|
||||
// Test a number of odd sizes...
|
||||
size_t sz = 0;
|
||||
do {
|
||||
void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
|
||||
void* up = guarded.wrap_with_guards(p, sz, (void*)1);
|
||||
memset(up, 0, sz);
|
||||
guarded_memory_test_check(up, sz, (void*)1);
|
||||
os::free(guarded.release_for_freeing());
|
||||
sz = (sz << 4) + 1;
|
||||
} while (sz < (256 * 1024));
|
||||
|
||||
// Test buffer overrun into head...
|
||||
basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
|
||||
guarded.wrap_with_guards(basep, 1);
|
||||
*basep = 0;
|
||||
assert(!guarded.verify_guards(), "Expected failure");
|
||||
os::free(basep);
|
||||
|
||||
// Test buffer overrun into tail with a number of odd sizes...
|
||||
sz = 1;
|
||||
do {
|
||||
void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
|
||||
void* up = guarded.wrap_with_guards(p, sz, (void*)1);
|
||||
memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
|
||||
assert(!guarded.verify_guards(), "Guard was not broken as expected");
|
||||
os::free(guarded.release_for_freeing());
|
||||
sz = (sz << 4) + 1;
|
||||
} while (sz < (256 * 1024));
|
||||
|
||||
// Test wrap_copy/wrap_free...
|
||||
assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
|
||||
|
||||
const char* str = "Check my bounds out";
|
||||
size_t str_sz = strlen(str) + 1;
|
||||
char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
|
||||
guarded_memory_test_check(str_copy, str_sz, NULL);
|
||||
assert(strcmp(str, str_copy) == 0, "Not identical copy");
|
||||
assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
|
||||
|
||||
void* no_data = NULL;
|
||||
void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
|
||||
assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
|
||||
}
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
326
hotspot/src/share/vm/memory/guardedMemory.hpp
Normal file
326
hotspot/src/share/vm/memory/guardedMemory.hpp
Normal file
@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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_MEMORY_GUARDED_MEMORY_HPP
|
||||
#define SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
/**
|
||||
* Guarded memory for detecting buffer overrun.
|
||||
*
|
||||
* Allows allocations to be wrapped with padded bytes of a known byte pattern,
|
||||
* that is a "guard". Guard patterns may be verified to detect buffer overruns.
|
||||
*
|
||||
* Primarily used by "debug malloc" and "checked JNI".
|
||||
*
|
||||
* Memory layout:
|
||||
*
|
||||
* |Offset | Content | Description |
|
||||
* |------------------------------------------------------------
|
||||
* |base_addr | 0xABABABABABABABAB | Head guard |
|
||||
* |+16 | <size_t:user_size> | User data size |
|
||||
* |+sizeof(uintptr_t) | <tag> | Tag word |
|
||||
* |+sizeof(void*) | 0xF1 <user_data> ( | User data |
|
||||
* |+user_size | 0xABABABABABABABAB | Tail guard |
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* Where:
|
||||
* - guard padding uses "badResourceValue" (0xAB)
|
||||
* - tag word is general purpose
|
||||
* - user data
|
||||
* -- initially padded with "uninitBlockPad" (0xF1),
|
||||
* -- to "freeBlockPad" (0xBA), when freed
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* * Allocations: one may wrap allocations with guard memory:
|
||||
* <code>
|
||||
* Thing* alloc_thing() {
|
||||
* void* mem = user_alloc_fn(GuardedMemory::get_total_size(sizeof(thing)));
|
||||
* GuardedMemory guarded(mem, sizeof(thing));
|
||||
* return (Thing*) guarded.get_user_ptr();
|
||||
* }
|
||||
* </code>
|
||||
* * Verify: memory guards are still in tact
|
||||
* <code>
|
||||
* bool verify_thing(Thing* thing) {
|
||||
* GuardedMemory guarded((void*)thing);
|
||||
* return guarded.verify_guards();
|
||||
* }
|
||||
* </code>
|
||||
* * Free: one may mark bytes as freed (further debugging support)
|
||||
* <code>
|
||||
* void free_thing(Thing* thing) {
|
||||
* GuardedMemory guarded((void*)thing);
|
||||
* assert(guarded.verify_guards(), "Corrupt thing");
|
||||
* user_free_fn(guards.release_for_freeing();
|
||||
* }
|
||||
* </code>
|
||||
*/
|
||||
class GuardedMemory : StackObj { // Wrapper on stack
|
||||
|
||||
// Private inner classes for memory layout...
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Guard class for header and trailer known pattern to test for overwrites.
|
||||
*/
|
||||
class Guard { // Class for raw memory (no vtbl allowed)
|
||||
friend class GuardedMemory;
|
||||
protected:
|
||||
enum {
|
||||
GUARD_SIZE = 16
|
||||
};
|
||||
|
||||
u_char _guard[GUARD_SIZE];
|
||||
|
||||
public:
|
||||
|
||||
void build() {
|
||||
u_char* c = _guard; // Possibly unaligned if tail guard
|
||||
u_char* end = c + GUARD_SIZE;
|
||||
while (c < end) {
|
||||
*c = badResourceValue;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
bool verify() const {
|
||||
u_char* c = (u_char*) _guard;
|
||||
u_char* end = c + GUARD_SIZE;
|
||||
while (c < end) {
|
||||
if (*c != badResourceValue) {
|
||||
return false;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // GuardedMemory::Guard
|
||||
|
||||
/**
|
||||
* Header guard and size
|
||||
*/
|
||||
class GuardHeader : Guard {
|
||||
friend class GuardedMemory;
|
||||
protected:
|
||||
// Take care in modifying fields here, will effect alignment
|
||||
// e.g. x86 ABI 16 byte stack alignment
|
||||
union {
|
||||
uintptr_t __unused_full_word1;
|
||||
size_t _user_size;
|
||||
};
|
||||
void* _tag;
|
||||
public:
|
||||
void set_user_size(const size_t usz) { _user_size = usz; }
|
||||
size_t get_user_size() const { return _user_size; }
|
||||
|
||||
void set_tag(const void* tag) { _tag = (void*) tag; }
|
||||
void* get_tag() const { return _tag; }
|
||||
|
||||
}; // GuardedMemory::GuardHeader
|
||||
|
||||
// Guarded Memory...
|
||||
|
||||
protected:
|
||||
u_char* _base_addr;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create new guarded memory.
|
||||
*
|
||||
* Wraps, starting at the given "base_ptr" with guards. Use "get_user_ptr()"
|
||||
* to return a pointer suitable for user data.
|
||||
*
|
||||
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
|
||||
* @param user_size the size of the user data to be wrapped.
|
||||
* @param tag optional general purpose tag.
|
||||
*/
|
||||
GuardedMemory(void* base_ptr, const size_t user_size, const void* tag = NULL) {
|
||||
wrap_with_guards(base_ptr, user_size, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap existing guarded memory.
|
||||
*
|
||||
* To use this constructor, one must have created guarded memory with
|
||||
* "GuardedMemory(void*, size_t, void*)" (or indirectly via helper, e.g. "wrap_copy()").
|
||||
*
|
||||
* @param user_p existing wrapped memory.
|
||||
*/
|
||||
GuardedMemory(void* userp) {
|
||||
u_char* user_ptr = (u_char*) userp;
|
||||
assert((uintptr_t)user_ptr > (sizeof(GuardHeader) + 0x1000), "Invalid pointer");
|
||||
_base_addr = (user_ptr - sizeof(GuardHeader));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new guarded memory.
|
||||
*
|
||||
* Wraps, starting at the given "base_ptr" with guards. Allows reuse of stack allocated helper.
|
||||
*
|
||||
* @param base_ptr allocation wishing to be wrapped, must be at least "GuardedMemory::get_total_size()" bytes.
|
||||
* @param user_size the size of the user data to be wrapped.
|
||||
* @param tag optional general purpose tag.
|
||||
*
|
||||
* @return user data pointer (inner pointer to supplied "base_ptr").
|
||||
*/
|
||||
void* wrap_with_guards(void* base_ptr, size_t user_size, const void* tag = NULL) {
|
||||
assert(base_ptr != NULL, "Attempt to wrap NULL with memory guard");
|
||||
_base_addr = (u_char*)base_ptr;
|
||||
get_head_guard()->build();
|
||||
get_head_guard()->set_user_size(user_size);
|
||||
get_tail_guard()->build();
|
||||
set_tag(tag);
|
||||
set_user_bytes(uninitBlockPad);
|
||||
assert(verify_guards(), "Expected valid memory guards");
|
||||
return get_user_ptr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify head and tail guards.
|
||||
*
|
||||
* @return true if guards are intact, false would indicate a buffer overrun.
|
||||
*/
|
||||
bool verify_guards() const {
|
||||
if (_base_addr != NULL) {
|
||||
return (get_head_guard()->verify() && get_tail_guard()->verify());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the general purpose tag.
|
||||
*
|
||||
* @param tag general purpose tag.
|
||||
*/
|
||||
void set_tag(const void* tag) { get_head_guard()->set_tag(tag); }
|
||||
|
||||
/**
|
||||
* Return the general purpose tag.
|
||||
*
|
||||
* @return the general purpose tag, defaults to NULL.
|
||||
*/
|
||||
void* get_tag() const { return get_head_guard()->get_tag(); }
|
||||
|
||||
/**
|
||||
* Return the size of the user data.
|
||||
*
|
||||
* @return the size of the user data.
|
||||
*/
|
||||
size_t get_user_size() const {
|
||||
assert(_base_addr != NULL, "Not wrapping any memory");
|
||||
return get_head_guard()->get_user_size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user data pointer.
|
||||
*
|
||||
* @return the user data pointer.
|
||||
*/
|
||||
u_char* get_user_ptr() const {
|
||||
assert(_base_addr != NULL, "Not wrapping any memory");
|
||||
return _base_addr + sizeof(GuardHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the wrapped pointer for resource freeing.
|
||||
*
|
||||
* Pads the user data with "freeBlockPad", and dis-associates the helper.
|
||||
*
|
||||
* @return the original base pointer used to wrap the data.
|
||||
*/
|
||||
void* release_for_freeing() {
|
||||
set_user_bytes(freeBlockPad);
|
||||
return release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dis-associate the help from the original base address.
|
||||
*
|
||||
* @return the original base pointer used to wrap the data.
|
||||
*/
|
||||
void* release() {
|
||||
void* p = (void*) _base_addr;
|
||||
_base_addr = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
virtual void print_on(outputStream* st) const;
|
||||
|
||||
protected:
|
||||
GuardHeader* get_head_guard() const { return (GuardHeader*) _base_addr; }
|
||||
Guard* get_tail_guard() const { return (Guard*) (get_user_ptr() + get_user_size()); };
|
||||
void set_user_bytes(u_char ch) {
|
||||
memset(get_user_ptr(), ch, get_user_size());
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Return the total size required for wrapping the given user size.
|
||||
*
|
||||
* @return the total size required for wrapping the given user size.
|
||||
*/
|
||||
static size_t get_total_size(size_t user_size) {
|
||||
size_t total_size = sizeof(GuardHeader) + user_size + sizeof(Guard);
|
||||
assert(total_size > user_size, "Unexpected wrap-around");
|
||||
return total_size;
|
||||
}
|
||||
|
||||
// Helper functions...
|
||||
|
||||
/**
|
||||
* Wrap a copy of size "len" of "ptr".
|
||||
*
|
||||
* @param ptr the memory to be copied
|
||||
* @param len the length of the copy
|
||||
* @param tag optional general purpose tag (see GuardedMemory::get_tag())
|
||||
*
|
||||
* @return guarded wrapped memory pointer to the user area, or NULL if OOM.
|
||||
*/
|
||||
static void* wrap_copy(const void* p, const size_t len, const void* tag = NULL);
|
||||
|
||||
/**
|
||||
* Free wrapped copy.
|
||||
*
|
||||
* Frees memory copied with "wrap_copy()".
|
||||
*
|
||||
* @param p memory returned by "wrap_copy()".
|
||||
*
|
||||
* @return true if guards were verified as intact. false indicates a buffer overrun.
|
||||
*/
|
||||
static bool free_copy(void* p);
|
||||
|
||||
// Testing...
|
||||
#ifndef PRODUCT
|
||||
static void test_guarded_memory(void);
|
||||
#endif
|
||||
}; // GuardedMemory
|
||||
|
||||
#endif // SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
|
@ -697,6 +697,7 @@ class SpaceManager : public CHeapObj<mtClass> {
|
||||
size_t allocated_blocks_words() const { return _allocated_blocks_words; }
|
||||
size_t allocated_blocks_bytes() const { return _allocated_blocks_words * BytesPerWord; }
|
||||
size_t allocated_chunks_words() const { return _allocated_chunks_words; }
|
||||
size_t allocated_chunks_bytes() const { return _allocated_chunks_words * BytesPerWord; }
|
||||
size_t allocated_chunks_count() const { return _allocated_chunks_count; }
|
||||
|
||||
bool is_humongous(size_t word_size) { return word_size > medium_chunk_size(); }
|
||||
@ -3365,6 +3366,16 @@ size_t Metaspace::capacity_bytes_slow(MetadataType mdtype) const {
|
||||
return capacity_words_slow(mdtype) * BytesPerWord;
|
||||
}
|
||||
|
||||
size_t Metaspace::allocated_blocks_bytes() const {
|
||||
return vsm()->allocated_blocks_bytes() +
|
||||
(using_class_space() ? class_vsm()->allocated_blocks_bytes() : 0);
|
||||
}
|
||||
|
||||
size_t Metaspace::allocated_chunks_bytes() const {
|
||||
return vsm()->allocated_chunks_bytes() +
|
||||
(using_class_space() ? class_vsm()->allocated_chunks_bytes() : 0);
|
||||
}
|
||||
|
||||
void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
|
||||
assert(!SafepointSynchronize::is_at_safepoint()
|
||||
|| Thread::current()->is_VM_thread(), "should be the VM thread");
|
||||
|
@ -226,6 +226,9 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||
size_t used_bytes_slow(MetadataType mdtype) const;
|
||||
size_t capacity_bytes_slow(MetadataType mdtype) const;
|
||||
|
||||
size_t allocated_blocks_bytes() const;
|
||||
size_t allocated_chunks_bytes() const;
|
||||
|
||||
static MetaWord* allocate(ClassLoaderData* loader_data, size_t word_size,
|
||||
bool read_only, MetaspaceObj::Type type, TRAPS);
|
||||
void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
|
||||
|
@ -1000,9 +1000,6 @@ void universe2_init() {
|
||||
}
|
||||
|
||||
|
||||
// This function is defined in JVM.cpp
|
||||
extern void initialize_converter_functions();
|
||||
|
||||
bool universe_post_init() {
|
||||
assert(!is_init_completed(), "Error: initialization not yet completed!");
|
||||
Universe::_fully_initialized = true;
|
||||
@ -1144,11 +1141,6 @@ bool universe_post_init() {
|
||||
SystemDictionary::ProtectionDomain_klass(), m);;
|
||||
}
|
||||
|
||||
// The following is initializing converter functions for serialization in
|
||||
// JVM.cpp. If we clean up the StrictMath code above we may want to find
|
||||
// a better solution for this as well.
|
||||
initialize_converter_functions();
|
||||
|
||||
// This needs to be done before the first scavenge/gc, since
|
||||
// it's an input to soft ref clearing policy.
|
||||
{
|
||||
|
@ -1023,8 +1023,7 @@ bool Method::is_ignored_by_security_stack_walk() const {
|
||||
// This is Method.invoke() -- ignore it
|
||||
return true;
|
||||
}
|
||||
if (JDK_Version::is_gte_jdk14x_version() &&
|
||||
method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
|
||||
if (method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
|
||||
// This is an auxilary frame -- ignore it
|
||||
return true;
|
||||
}
|
||||
|
@ -3858,6 +3858,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/heapRegionRemSet.hpp"
|
||||
#endif
|
||||
#include "memory/guardedMemory.hpp"
|
||||
#include "utilities/quickSort.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#if INCLUDE_VM_STRUCTS
|
||||
@ -3901,6 +3902,7 @@ void execute_internal_vm_tests() {
|
||||
run_unit_test(arrayOopDesc::test_max_array_length());
|
||||
run_unit_test(CollectedHeap::test_is_in());
|
||||
run_unit_test(QuickSort::test_quick_sort());
|
||||
run_unit_test(GuardedMemory::test_guarded_memory());
|
||||
run_unit_test(AltHashing::test_alt_hash());
|
||||
run_unit_test(test_loggc_filename());
|
||||
run_unit_test(TestNewSize_test());
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3923,50 +3923,6 @@ JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
|
||||
}
|
||||
|
||||
|
||||
// Support for Serialization
|
||||
|
||||
typedef jfloat (JNICALL *IntBitsToFloatFn )(JNIEnv* env, jclass cb, jint value);
|
||||
typedef jdouble (JNICALL *LongBitsToDoubleFn)(JNIEnv* env, jclass cb, jlong value);
|
||||
typedef jint (JNICALL *FloatToIntBitsFn )(JNIEnv* env, jclass cb, jfloat value);
|
||||
typedef jlong (JNICALL *DoubleToLongBitsFn)(JNIEnv* env, jclass cb, jdouble value);
|
||||
|
||||
static IntBitsToFloatFn int_bits_to_float_fn = NULL;
|
||||
static LongBitsToDoubleFn long_bits_to_double_fn = NULL;
|
||||
static FloatToIntBitsFn float_to_int_bits_fn = NULL;
|
||||
static DoubleToLongBitsFn double_to_long_bits_fn = NULL;
|
||||
|
||||
|
||||
void initialize_converter_functions() {
|
||||
if (JDK_Version::is_gte_jdk14x_version()) {
|
||||
// These functions only exist for compatibility with 1.3.1 and earlier
|
||||
return;
|
||||
}
|
||||
|
||||
// called from universe_post_init()
|
||||
assert(
|
||||
int_bits_to_float_fn == NULL &&
|
||||
long_bits_to_double_fn == NULL &&
|
||||
float_to_int_bits_fn == NULL &&
|
||||
double_to_long_bits_fn == NULL ,
|
||||
"initialization done twice"
|
||||
);
|
||||
// initialize
|
||||
int_bits_to_float_fn = CAST_TO_FN_PTR(IntBitsToFloatFn , NativeLookup::base_library_lookup("java/lang/Float" , "intBitsToFloat" , "(I)F"));
|
||||
long_bits_to_double_fn = CAST_TO_FN_PTR(LongBitsToDoubleFn, NativeLookup::base_library_lookup("java/lang/Double", "longBitsToDouble", "(J)D"));
|
||||
float_to_int_bits_fn = CAST_TO_FN_PTR(FloatToIntBitsFn , NativeLookup::base_library_lookup("java/lang/Float" , "floatToIntBits" , "(F)I"));
|
||||
double_to_long_bits_fn = CAST_TO_FN_PTR(DoubleToLongBitsFn, NativeLookup::base_library_lookup("java/lang/Double", "doubleToLongBits", "(D)J"));
|
||||
// verify
|
||||
assert(
|
||||
int_bits_to_float_fn != NULL &&
|
||||
long_bits_to_double_fn != NULL &&
|
||||
float_to_int_bits_fn != NULL &&
|
||||
double_to_long_bits_fn != NULL ,
|
||||
"initialization failed"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
|
||||
|
||||
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS) {
|
||||
|
@ -185,64 +185,7 @@ jint Unsafe_invocation_key_to_method_slot(jint key) {
|
||||
|
||||
// Get/SetObject must be special-cased, since it works with handles.
|
||||
|
||||
// The xxx140 variants for backward compatibility do not allow a full-width offset.
|
||||
UNSAFE_ENTRY(jobject, Unsafe_GetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset))
|
||||
UnsafeWrapper("Unsafe_GetObject");
|
||||
if (obj == NULL) THROW_0(vmSymbols::java_lang_NullPointerException());
|
||||
GET_OOP_FIELD(obj, offset, v)
|
||||
jobject ret = JNIHandles::make_local(env, v);
|
||||
#if INCLUDE_ALL_GCS
|
||||
// We could be accessing the referent field in a reference
|
||||
// object. If G1 is enabled then we need to register a non-null
|
||||
// referent with the SATB barrier.
|
||||
if (UseG1GC) {
|
||||
bool needs_barrier = false;
|
||||
|
||||
if (ret != NULL) {
|
||||
if (offset == java_lang_ref_Reference::referent_offset) {
|
||||
oop o = JNIHandles::resolve_non_null(obj);
|
||||
Klass* k = o->klass();
|
||||
if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
|
||||
assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
|
||||
needs_barrier = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_barrier) {
|
||||
oop referent = JNIHandles::resolve(ret);
|
||||
G1SATBCardTableModRefBS::enqueue(referent);
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
return ret;
|
||||
UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_SetObject140(JNIEnv *env, jobject unsafe, jobject obj, jint offset, jobject x_h))
|
||||
UnsafeWrapper("Unsafe_SetObject");
|
||||
if (obj == NULL) THROW(vmSymbols::java_lang_NullPointerException());
|
||||
oop x = JNIHandles::resolve(x_h);
|
||||
//SET_FIELD(obj, offset, oop, x);
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
if (UseCompressedOops) {
|
||||
if (x != NULL) {
|
||||
// If there is a heap base pointer, we are obliged to emit a store barrier.
|
||||
oop_store((narrowOop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
} else {
|
||||
narrowOop n = oopDesc::encode_heap_oop_not_null(x);
|
||||
*(narrowOop*)index_oop_from_field_offset_long(p, offset) = n;
|
||||
}
|
||||
} else {
|
||||
if (x != NULL) {
|
||||
// If there is a heap base pointer, we are obliged to emit a store barrier.
|
||||
oop_store((oop*)index_oop_from_field_offset_long(p, offset), x);
|
||||
} else {
|
||||
*(oop*)index_oop_from_field_offset_long(p, offset) = x;
|
||||
}
|
||||
}
|
||||
UNSAFE_END
|
||||
|
||||
// The normal variants allow a null base pointer with an arbitrary address.
|
||||
// These functions allow a null base pointer with an arbitrary address.
|
||||
// But if the base pointer is non-null, the offset should make some sense.
|
||||
// That is, it should be in the range [0, MAX_OBJECT_SIZE].
|
||||
UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
|
||||
@ -1350,9 +1293,6 @@ UNSAFE_END
|
||||
|
||||
// These are the methods for 1.4.0
|
||||
static JNINativeMethod methods_140[] = {
|
||||
{CC"getObject", CC"("OBJ"I)"OBJ"", FN_PTR(Unsafe_GetObject140)},
|
||||
{CC"putObject", CC"("OBJ"I"OBJ")V", FN_PTR(Unsafe_SetObject140)},
|
||||
|
||||
DECLARE_GETSETOOP_140(Boolean, Z),
|
||||
DECLARE_GETSETOOP_140(Byte, B),
|
||||
DECLARE_GETSETOOP_140(Short, S),
|
||||
|
@ -222,10 +222,8 @@ void Arguments::init_version_specific_system_properties() {
|
||||
const char* spec_vendor = "Sun Microsystems Inc.";
|
||||
uint32_t spec_version = 0;
|
||||
|
||||
if (JDK_Version::is_gte_jdk17x_version()) {
|
||||
spec_vendor = "Oracle Corporation";
|
||||
spec_version = JDK_Version::current().major_version();
|
||||
}
|
||||
jio_snprintf(buffer, bufsz, "1." UINT32_FORMAT, spec_version);
|
||||
|
||||
PropertyList_add(&_system_properties,
|
||||
@ -2455,6 +2453,8 @@ bool Arguments::check_vm_args_consistency() {
|
||||
warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
|
||||
}
|
||||
|
||||
status &= check_vm_args_consistency_ext();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -3699,14 +3699,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
PrintGC = true;
|
||||
}
|
||||
|
||||
if (!JDK_Version::is_gte_jdk18x_version()) {
|
||||
// To avoid changing the log format for 7 updates this flag is only
|
||||
// true by default in JDK8 and above.
|
||||
if (FLAG_IS_DEFAULT(PrintGCCause)) {
|
||||
FLAG_SET_DEFAULT(PrintGCCause, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Set object alignment values.
|
||||
set_object_alignment();
|
||||
|
||||
|
@ -462,6 +462,7 @@ class Arguments : AllStatic {
|
||||
static void check_deprecated_gc_flags();
|
||||
// Check consistency or otherwise of VM argument settings
|
||||
static bool check_vm_args_consistency();
|
||||
static bool check_vm_args_consistency_ext();
|
||||
// Check stack pages settings
|
||||
static bool check_stack_pages();
|
||||
// Used by os_solaris
|
||||
|
30
hotspot/src/share/vm/runtime/arguments_ext.cpp
Normal file
30
hotspot/src/share/vm/runtime/arguments_ext.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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/arguments.hpp"
|
||||
|
||||
bool Arguments::check_vm_args_consistency_ext() {
|
||||
return true;
|
||||
}
|
@ -501,9 +501,6 @@ void before_exit(JavaThread * thread) {
|
||||
os::infinite_sleep();
|
||||
}
|
||||
|
||||
// Stop any ongoing concurrent GC work
|
||||
Universe::heap()->stop();
|
||||
|
||||
// Terminate watcher thread - must before disenrolling any periodic task
|
||||
if (PeriodicTask::num_tasks() > 0)
|
||||
WatcherThread::stop();
|
||||
@ -518,10 +515,8 @@ void before_exit(JavaThread * thread) {
|
||||
StatSampler::disengage();
|
||||
StatSampler::destroy();
|
||||
|
||||
// We do not need to explicitly stop concurrent GC threads because the
|
||||
// JVM will be taken down at a safepoint when such threads are inactive --
|
||||
// except for some concurrent G1 threads, see (comment in)
|
||||
// Threads::destroy_vm().
|
||||
// Stop concurrent GC threads
|
||||
Universe::heap()->stop();
|
||||
|
||||
// Print GC/heap related information.
|
||||
if (PrintGCDetails) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -197,58 +197,6 @@ class JDK_Version VALUE_OBJ_CLASS_SPEC {
|
||||
_runtime_version = version;
|
||||
}
|
||||
|
||||
// Convenience methods for queries on the current major/minor version
|
||||
static bool is_jdk12x_version() {
|
||||
return current().compare_major(2) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk13x_version() {
|
||||
return current().compare_major(3) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk14x_version() {
|
||||
return current().compare_major(4) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk15x_version() {
|
||||
return current().compare_major(5) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk16x_version() {
|
||||
return current().compare_major(6) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk17x_version() {
|
||||
return current().compare_major(7) == 0;
|
||||
}
|
||||
|
||||
static bool is_jdk18x_version() {
|
||||
return current().compare_major(8) == 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk13x_version() {
|
||||
return current().compare_major(3) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk14x_version() {
|
||||
return current().compare_major(4) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk15x_version() {
|
||||
return current().compare_major(5) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk16x_version() {
|
||||
return current().compare_major(6) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk17x_version() {
|
||||
return current().compare_major(7) >= 0;
|
||||
}
|
||||
|
||||
static bool is_gte_jdk18x_version() {
|
||||
return current().compare_major(8) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_RUNTIME_JAVA_HPP
|
||||
|
@ -298,6 +298,7 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
|
||||
block->_top = 0;
|
||||
block->_next = NULL;
|
||||
block->_pop_frame_link = NULL;
|
||||
block->_planned_capacity = block_size_in_oops;
|
||||
// _last, _free_list & _allocate_before_rebuild initialized in allocate_handle
|
||||
debug_only(block->_last = NULL);
|
||||
debug_only(block->_free_list = NULL);
|
||||
@ -531,6 +532,12 @@ int JNIHandleBlock::length() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
const size_t JNIHandleBlock::get_number_of_live_handles() {
|
||||
CountHandleClosure counter;
|
||||
oops_do(&counter);
|
||||
return counter.count();
|
||||
}
|
||||
|
||||
// This method is not thread-safe, i.e., must be called while holding a lock on the
|
||||
// structure.
|
||||
long JNIHandleBlock::memory_usage() const {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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
|
||||
@ -112,6 +112,9 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
|
||||
oop* _free_list; // Handle free list
|
||||
int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
|
||||
|
||||
// Check JNI, "planned capacity" for current frame (or push/ensure)
|
||||
size_t _planned_capacity;
|
||||
|
||||
#ifndef PRODUCT
|
||||
JNIHandleBlock* _block_list_link; // Link for list below
|
||||
static JNIHandleBlock* _block_list; // List of all allocated blocks (for debugging only)
|
||||
@ -152,6 +155,11 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
|
||||
// Traversal of weak handles. Unreachable oops are cleared.
|
||||
void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
|
||||
|
||||
// Checked JNI support
|
||||
void set_planned_capacity(size_t planned_capacity) { _planned_capacity = planned_capacity; }
|
||||
const size_t get_planned_capacity() { return _planned_capacity; }
|
||||
const size_t get_number_of_live_handles();
|
||||
|
||||
// Debugging
|
||||
bool chain_contains(jobject handle) const; // Does this block or following blocks contain handle
|
||||
bool contains(jobject handle) const; // Does this block contain handle
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include "gc_implementation/shared/vmGCOperations.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#ifdef ASSERT
|
||||
#include "memory/guardedMemory.hpp"
|
||||
#endif
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/jvm.h"
|
||||
#include "prims/jvm_misc.hpp"
|
||||
@ -523,121 +526,20 @@ char *os::strdup(const char *str, MEMFLAGS flags) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef ASSERT
|
||||
#define space_before (MallocCushion + sizeof(double))
|
||||
#define space_after MallocCushion
|
||||
#define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t))
|
||||
#define size_addr_from_obj(p) ((size_t*)p - 1)
|
||||
// MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly
|
||||
// NB: cannot be debug variable, because these aren't set from the command line until
|
||||
// *after* the first few allocs already happened
|
||||
#define MallocCushion 16
|
||||
#else
|
||||
#define space_before 0
|
||||
#define space_after 0
|
||||
#define size_addr_from_base(p) should not use w/o ASSERT
|
||||
#define size_addr_from_obj(p) should not use w/o ASSERT
|
||||
#define MallocCushion 0
|
||||
#endif
|
||||
#define paranoid 0 /* only set to 1 if you suspect checking code has bug */
|
||||
|
||||
#ifdef ASSERT
|
||||
inline size_t get_size(void* obj) {
|
||||
size_t size = *size_addr_from_obj(obj);
|
||||
if (size < 0) {
|
||||
fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten ("
|
||||
SIZE_FORMAT ")", obj, size));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
u_char* find_cushion_backwards(u_char* start) {
|
||||
u_char* p = start;
|
||||
while (p[ 0] != badResourceValue || p[-1] != badResourceValue ||
|
||||
p[-2] != badResourceValue || p[-3] != badResourceValue) p--;
|
||||
// ok, we have four consecutive marker bytes; find start
|
||||
u_char* q = p - 4;
|
||||
while (*q == badResourceValue) q--;
|
||||
return q + 1;
|
||||
}
|
||||
|
||||
u_char* find_cushion_forwards(u_char* start) {
|
||||
u_char* p = start;
|
||||
while (p[0] != badResourceValue || p[1] != badResourceValue ||
|
||||
p[2] != badResourceValue || p[3] != badResourceValue) p++;
|
||||
// ok, we have four consecutive marker bytes; find end of cushion
|
||||
u_char* q = p + 4;
|
||||
while (*q == badResourceValue) q++;
|
||||
return q - MallocCushion;
|
||||
}
|
||||
|
||||
void print_neighbor_blocks(void* ptr) {
|
||||
// find block allocated before ptr (not entirely crash-proof)
|
||||
if (MallocCushion < 4) {
|
||||
tty->print_cr("### cannot find previous block (MallocCushion < 4)");
|
||||
return;
|
||||
}
|
||||
u_char* start_of_this_block = (u_char*)ptr - space_before;
|
||||
u_char* end_of_prev_block_data = start_of_this_block - space_after -1;
|
||||
// look for cushion in front of prev. block
|
||||
u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data);
|
||||
ptrdiff_t size = *size_addr_from_base(start_of_prev_block);
|
||||
u_char* obj = start_of_prev_block + space_before;
|
||||
if (size <= 0 ) {
|
||||
// start is bad; may have been confused by OS data in between objects
|
||||
// search one more backwards
|
||||
start_of_prev_block = find_cushion_backwards(start_of_prev_block);
|
||||
size = *size_addr_from_base(start_of_prev_block);
|
||||
obj = start_of_prev_block + space_before;
|
||||
}
|
||||
|
||||
if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
|
||||
tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
|
||||
} else {
|
||||
tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
|
||||
}
|
||||
|
||||
// now find successor block
|
||||
u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
|
||||
start_of_next_block = find_cushion_forwards(start_of_next_block);
|
||||
u_char* next_obj = start_of_next_block + space_before;
|
||||
ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
|
||||
if (start_of_next_block[0] == badResourceValue &&
|
||||
start_of_next_block[1] == badResourceValue &&
|
||||
start_of_next_block[2] == badResourceValue &&
|
||||
start_of_next_block[3] == badResourceValue) {
|
||||
tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
|
||||
} else {
|
||||
tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void report_heap_error(void* memblock, void* bad, const char* where) {
|
||||
static void verify_memory(void* ptr) {
|
||||
GuardedMemory guarded(ptr);
|
||||
if (!guarded.verify_guards()) {
|
||||
tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
|
||||
tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
|
||||
print_neighbor_blocks(memblock);
|
||||
tty->print_cr("## memory stomp:");
|
||||
guarded.print_on(tty);
|
||||
fatal("memory stomping error");
|
||||
}
|
||||
}
|
||||
|
||||
void verify_block(void* memblock) {
|
||||
size_t size = get_size(memblock);
|
||||
if (MallocCushion) {
|
||||
u_char* ptr = (u_char*)memblock - space_before;
|
||||
for (int i = 0; i < MallocCushion; i++) {
|
||||
if (ptr[i] != badResourceValue) {
|
||||
report_heap_error(memblock, ptr+i, "in front of");
|
||||
}
|
||||
}
|
||||
u_char* end = (u_char*)memblock + size + space_after;
|
||||
for (int j = -MallocCushion; j < 0; j++) {
|
||||
if (end[j] != badResourceValue) {
|
||||
report_heap_error(memblock, end+j, "after");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -686,16 +588,18 @@ void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
|
||||
size = 1;
|
||||
}
|
||||
|
||||
const size_t alloc_size = size + space_before + space_after;
|
||||
|
||||
#ifndef ASSERT
|
||||
const size_t alloc_size = size;
|
||||
#else
|
||||
const size_t alloc_size = GuardedMemory::get_total_size(size);
|
||||
if (size > alloc_size) { // Check for rollover.
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
|
||||
|
||||
u_char* ptr;
|
||||
|
||||
if (MallocMaxTestWords > 0) {
|
||||
ptr = testMalloc(alloc_size);
|
||||
} else {
|
||||
@ -703,28 +607,26 @@ void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
if (ptr == NULL) return NULL;
|
||||
if (MallocCushion) {
|
||||
for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue;
|
||||
u_char* end = ptr + space_before + size;
|
||||
for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad;
|
||||
for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue;
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// put size just before data
|
||||
*size_addr_from_base(ptr) = size;
|
||||
// Wrap memory with guard
|
||||
GuardedMemory guarded(ptr, size);
|
||||
ptr = guarded.get_user_ptr();
|
||||
#endif
|
||||
u_char* memblock = ptr + space_before;
|
||||
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
||||
tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
|
||||
if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
|
||||
tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
|
||||
breakpoint();
|
||||
}
|
||||
debug_only(if (paranoid) verify_block(memblock));
|
||||
if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
|
||||
debug_only(if (paranoid) verify_memory(ptr));
|
||||
if (PrintMalloc && tty != NULL) {
|
||||
tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
|
||||
}
|
||||
|
||||
// we do not track MallocCushion memory
|
||||
MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
|
||||
// we do not track guard memory
|
||||
MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller);
|
||||
|
||||
return memblock;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
@ -743,27 +645,32 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller
|
||||
return ptr;
|
||||
#else
|
||||
if (memblock == NULL) {
|
||||
return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
|
||||
return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
|
||||
}
|
||||
if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
|
||||
tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
|
||||
breakpoint();
|
||||
}
|
||||
verify_block(memblock);
|
||||
verify_memory(memblock);
|
||||
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
|
||||
if (size == 0) return NULL;
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// always move the block
|
||||
void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
|
||||
if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
|
||||
void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
|
||||
if (PrintMalloc) {
|
||||
tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
|
||||
}
|
||||
// Copy to new memory if malloc didn't fail
|
||||
if ( ptr != NULL ) {
|
||||
memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
|
||||
if (paranoid) verify_block(ptr);
|
||||
GuardedMemory guarded(memblock);
|
||||
memcpy(ptr, memblock, MIN2(size, guarded.get_user_size()));
|
||||
if (paranoid) verify_memory(ptr);
|
||||
if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
|
||||
tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
|
||||
breakpoint();
|
||||
}
|
||||
free(memblock);
|
||||
os::free(memblock);
|
||||
}
|
||||
return ptr;
|
||||
#endif
|
||||
@ -771,6 +678,7 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller
|
||||
|
||||
|
||||
void os::free(void *memblock, MEMFLAGS memflags) {
|
||||
address trackp = (address) memblock;
|
||||
NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
|
||||
#ifdef ASSERT
|
||||
if (memblock == NULL) return;
|
||||
@ -778,34 +686,20 @@ void os::free(void *memblock, MEMFLAGS memflags) {
|
||||
if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
|
||||
breakpoint();
|
||||
}
|
||||
verify_block(memblock);
|
||||
verify_memory(memblock);
|
||||
NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
|
||||
// Added by detlefs.
|
||||
if (MallocCushion) {
|
||||
u_char* ptr = (u_char*)memblock - space_before;
|
||||
for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
|
||||
guarantee(*p == badResourceValue,
|
||||
"Thing freed should be malloc result.");
|
||||
*p = (u_char)freeBlockPad;
|
||||
}
|
||||
size_t size = get_size(memblock);
|
||||
|
||||
GuardedMemory guarded(memblock);
|
||||
size_t size = guarded.get_user_size();
|
||||
inc_stat_counter(&free_bytes, size);
|
||||
u_char* end = ptr + space_before + size;
|
||||
for (u_char* q = end; q < end + MallocCushion; q++) {
|
||||
guarantee(*q == badResourceValue,
|
||||
"Thing freed should be malloc result.");
|
||||
*q = (u_char)freeBlockPad;
|
||||
}
|
||||
if (PrintMalloc && tty != NULL)
|
||||
memblock = guarded.release_for_freeing();
|
||||
if (PrintMalloc && tty != NULL) {
|
||||
fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
|
||||
} else if (PrintMalloc && tty != NULL) {
|
||||
// tty->print_cr("os::free %p", memblock);
|
||||
fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
|
||||
}
|
||||
#endif
|
||||
MemTracker::record_free((address)memblock, memflags);
|
||||
MemTracker::record_free(trackp, memflags);
|
||||
|
||||
::free((char*)memblock - space_before);
|
||||
::free(memblock);
|
||||
}
|
||||
|
||||
void os::init_random(long initval) {
|
||||
|
@ -410,49 +410,6 @@ oop Reflection::array_component_type(oop mirror, TRAPS) {
|
||||
}
|
||||
|
||||
|
||||
bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) {
|
||||
// field_class : declaring class
|
||||
// acc : declared field access
|
||||
// target_class : for protected
|
||||
|
||||
// Check if field or method is accessible to client. Throw an
|
||||
// IllegalAccessException and return false if not.
|
||||
|
||||
// The "client" is the class associated with the nearest real frame
|
||||
// getCallerClass already skips Method.invoke frames, so pass 0 in
|
||||
// that case (same as classic).
|
||||
ResourceMark rm(THREAD);
|
||||
assert(THREAD->is_Java_thread(), "sanity check");
|
||||
Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1);
|
||||
|
||||
if (client_class != field_class) {
|
||||
if (!verify_class_access(client_class, field_class, false)
|
||||
|| !verify_field_access(client_class,
|
||||
field_class,
|
||||
field_class,
|
||||
acc,
|
||||
false)) {
|
||||
THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Additional test for protected members: JLS 6.6.2
|
||||
|
||||
if (acc.is_protected()) {
|
||||
if (target_class != client_class) {
|
||||
if (!is_same_class_package(client_class, field_class)) {
|
||||
if (!target_class->is_subclass_of(client_class)) {
|
||||
THROW_(vmSymbols::java_lang_IllegalAccessException(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Passed all tests
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
|
||||
// Verify that current_class can access new_class. If the classloader_only
|
||||
// flag is set, we automatically allow any accesses in which current_class
|
||||
@ -463,10 +420,9 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo
|
||||
is_same_class_package(current_class, new_class)) {
|
||||
return true;
|
||||
}
|
||||
// New (1.4) reflection implementation. Allow all accesses from
|
||||
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
|
||||
if ( JDK_Version::is_gte_jdk14x_version()
|
||||
&& current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
|
||||
// Allow all accesses from sun/reflect/MagicAccessorImpl subclasses to
|
||||
// succeed trivially.
|
||||
if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -567,10 +523,9 @@ bool Reflection::verify_field_access(Klass* current_class,
|
||||
return true;
|
||||
}
|
||||
|
||||
// New (1.4) reflection implementation. Allow all accesses from
|
||||
// sun/reflect/MagicAccessorImpl subclasses to succeed trivially.
|
||||
if ( JDK_Version::is_gte_jdk14x_version()
|
||||
&& current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
|
||||
// Allow all accesses from sun/reflect/MagicAccessorImpl subclasses to
|
||||
// succeed trivially.
|
||||
if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -707,12 +662,10 @@ Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) {
|
||||
|
||||
|
||||
oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) {
|
||||
// In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert.
|
||||
// Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
|
||||
// Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
|
||||
assert(!method()->is_initializer() ||
|
||||
(for_constant_pool_access && method()->is_static()) ||
|
||||
(method()->name() == vmSymbols::class_initializer_name()
|
||||
&& method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead");
|
||||
(for_constant_pool_access && method()->is_static()),
|
||||
"should call new_constructor instead");
|
||||
instanceKlassHandle holder (THREAD, method->method_holder());
|
||||
int slot = method->method_idnum();
|
||||
|
||||
@ -978,22 +931,6 @@ oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
|
||||
reflected_method->signature()));
|
||||
}
|
||||
|
||||
// In the JDK 1.4 reflection implementation, the security check is
|
||||
// done at the Java level
|
||||
if (!JDK_Version::is_gte_jdk14x_version()) {
|
||||
|
||||
// Access checking (unless overridden by Method)
|
||||
if (!override) {
|
||||
if (!(klass->is_public() && reflected_method->is_public())) {
|
||||
bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL);
|
||||
if (!access) {
|
||||
return NULL; // exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // !Universe::is_gte_jdk14x_version()
|
||||
|
||||
assert(ptypes->is_objArray(), "just checking");
|
||||
int args_len = args.is_null() ? 0 : args->length();
|
||||
// Check number of arguments
|
||||
|
@ -44,9 +44,6 @@ class FieldStream;
|
||||
|
||||
class Reflection: public AllStatic {
|
||||
private:
|
||||
// Access checking
|
||||
static bool reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS);
|
||||
|
||||
// Conversion
|
||||
static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS);
|
||||
static oop basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, 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,16 +76,11 @@ void FilteredFieldsMap::initialize() {
|
||||
int offset;
|
||||
offset = java_lang_Throwable::get_backtrace_offset();
|
||||
_filtered_fields->append(new FilteredField(SystemDictionary::Throwable_klass(), offset));
|
||||
// The latest version of vm may be used with old jdk.
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
// The following class fields do not exist in
|
||||
// previous version of jdk.
|
||||
offset = sun_reflect_ConstantPool::oop_offset();
|
||||
_filtered_fields->append(new FilteredField(SystemDictionary::reflect_ConstantPool_klass(), offset));
|
||||
offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
|
||||
_filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
|
||||
}
|
||||
}
|
||||
|
||||
int FilteredFieldStream::field_count() {
|
||||
int numflds = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2014, 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
|
||||
@ -41,8 +41,7 @@ void ServiceThread::initialize() {
|
||||
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";
|
||||
const char* name = "Service Thread";
|
||||
|
||||
Handle string = java_lang_String::create_from_str(name, CHECK);
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "prims/jni.h"
|
||||
#include "runtime/interfaceSupport.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/sharedRuntimeMath.hpp"
|
||||
|
||||
// This file contains copies of the fdlibm routines used by
|
||||
// StrictMath. It turns out that it is almost always required to use
|
||||
@ -36,35 +37,6 @@
|
||||
// pointer out to libjava.so in SharedRuntime speeds these routines up
|
||||
// by roughly 15% on both Win32/x86 and Solaris/SPARC.
|
||||
|
||||
// Enabling optimizations in this file causes incorrect code to be
|
||||
// generated; can not figure out how to turn down optimization for one
|
||||
// file in the IDE on Windows
|
||||
#ifdef WIN32
|
||||
# pragma optimize ( "", off )
|
||||
#endif
|
||||
|
||||
/* The above workaround now causes more problems with the latest MS compiler.
|
||||
* Visual Studio 2010's /GS option tries to guard against buffer overruns.
|
||||
* /GS is on by default if you specify optimizations, which we do globally
|
||||
* via /W3 /O2. However the above selective turning off of optimizations means
|
||||
* that /GS issues a warning "4748". And since we treat warnings as errors (/WX)
|
||||
* then the compilation fails. There are several possible solutions
|
||||
* (1) Remove that pragma above as obsolete with VS2010 - requires testing.
|
||||
* (2) Stop treating warnings as errors - would be a backward step
|
||||
* (3) Disable /GS - may help performance but you lose the security checks
|
||||
* (4) Disable the warning with "#pragma warning( disable : 4748 )"
|
||||
* (5) Disable planting the code with __declspec(safebuffers)
|
||||
* I've opted for (5) although we should investigate the local performance
|
||||
* benefits of (1) and global performance benefit of (3).
|
||||
*/
|
||||
#if defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1600))
|
||||
#define SAFEBUF __declspec(safebuffers)
|
||||
#else
|
||||
#define SAFEBUF
|
||||
#endif
|
||||
|
||||
#include "runtime/sharedRuntimeMath.hpp"
|
||||
|
||||
/*
|
||||
* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
|
||||
* double x[],y[]; int e0,nx,prec; int ipio2[];
|
||||
@ -201,7 +173,7 @@ one = 1.0,
|
||||
two24B = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
|
||||
twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
|
||||
|
||||
static SAFEBUF int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) {
|
||||
static int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) {
|
||||
int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
|
||||
double z,fw,f[20],fq[20],q[20];
|
||||
|
||||
@ -417,7 +389,7 @@ pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
|
||||
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
|
||||
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
|
||||
|
||||
static SAFEBUF int __ieee754_rem_pio2(double x, double *y) {
|
||||
static int __ieee754_rem_pio2(double x, double *y) {
|
||||
double z,w,t,r,fn;
|
||||
double tx[3];
|
||||
int e0,i,j,nx,n,ix,hx,i0;
|
||||
@ -916,8 +888,3 @@ JRT_LEAF(jdouble, SharedRuntime::dtan(jdouble x))
|
||||
-1 -- n odd */
|
||||
}
|
||||
JRT_END
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
# pragma optimize ( "", on )
|
||||
#endif
|
||||
|
@ -1448,6 +1448,7 @@ void JavaThread::initialize() {
|
||||
_thread_stat = new ThreadStatistics();
|
||||
_blocked_on_compilation = false;
|
||||
_jni_active_critical = 0;
|
||||
_pending_jni_exception_check_fn = NULL;
|
||||
_do_not_unlock_if_synchronized = false;
|
||||
_cached_monitor_info = NULL;
|
||||
_parker = Parker::Allocate(this);
|
||||
@ -1738,28 +1739,11 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
}
|
||||
// FIXIT: The is_null check is only so it works better on JDK1.2 VM's. This
|
||||
// has to be fixed by a runtime query method
|
||||
if (!destroy_vm || JDK_Version::is_jdk12x_version()) {
|
||||
// JSR-166: change call from from ThreadGroup.uncaughtException to
|
||||
// java.lang.Thread.dispatchUncaughtException
|
||||
if (!destroy_vm) {
|
||||
if (uncaught_exception.not_null()) {
|
||||
Handle group(this, java_lang_Thread::threadGroup(threadObj()));
|
||||
{
|
||||
EXCEPTION_MARK;
|
||||
// Check if the method Thread.dispatchUncaughtException() exists. If so
|
||||
// call it. Otherwise we have an older library without the JSR-166 changes,
|
||||
// so call ThreadGroup.uncaughtException()
|
||||
KlassHandle recvrKlass(THREAD, threadObj->klass());
|
||||
CallInfo callinfo;
|
||||
// Call method Thread.dispatchUncaughtException().
|
||||
KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass());
|
||||
LinkResolver::resolve_virtual_call(callinfo, threadObj, recvrKlass, thread_klass,
|
||||
vmSymbols::dispatchUncaughtException_name(),
|
||||
vmSymbols::throwable_void_signature(),
|
||||
KlassHandle(), false, false, THREAD);
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
methodHandle method = callinfo.selected_method();
|
||||
if (method.not_null()) {
|
||||
JavaValue result(T_VOID);
|
||||
JavaCalls::call_virtual(&result,
|
||||
threadObj, thread_klass,
|
||||
@ -1767,17 +1751,6 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||
vmSymbols::throwable_void_signature(),
|
||||
uncaught_exception,
|
||||
THREAD);
|
||||
} else {
|
||||
KlassHandle thread_group(THREAD, SystemDictionary::ThreadGroup_klass());
|
||||
JavaValue result(T_VOID);
|
||||
JavaCalls::call_virtual(&result,
|
||||
group, thread_group,
|
||||
vmSymbols::uncaughtException_name(),
|
||||
vmSymbols::thread_throwable_void_signature(),
|
||||
threadObj, // Arg 1
|
||||
uncaught_exception, // Arg 2
|
||||
THREAD);
|
||||
}
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
ResourceMark rm(this);
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
@ -1788,7 +1761,6 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called before the java thread exit since we want to read info
|
||||
// from java_lang_Thread object
|
||||
@ -2848,7 +2820,7 @@ void JavaThread::print_on(outputStream *st) const {
|
||||
Thread::print_on(st);
|
||||
// print guess for valid stack memory region (assume 4K pages); helps lock debugging
|
||||
st->print_cr("[" INTPTR_FORMAT "]", (intptr_t)last_Java_sp() & ~right_n_bits(12));
|
||||
if (thread_oop != NULL && JDK_Version::is_gte_jdk15x_version()) {
|
||||
if (thread_oop != NULL) {
|
||||
st->print_cr(" java.lang.Thread.State: %s", java_lang_Thread::thread_status_name(thread_oop));
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
@ -3948,15 +3920,8 @@ bool Threads::destroy_vm() {
|
||||
}
|
||||
os::wait_for_keypress_at_exit();
|
||||
|
||||
if (JDK_Version::is_jdk12x_version()) {
|
||||
// We are the last thread running, so check if finalizers should be run.
|
||||
// For 1.3 or later this is done in thread->invoke_shutdown_hooks()
|
||||
HandleMark rm(thread);
|
||||
Universe::run_finalizers_on_exit();
|
||||
} else {
|
||||
// run Java level shutdown hooks
|
||||
thread->invoke_shutdown_hooks();
|
||||
}
|
||||
|
||||
before_exit(thread);
|
||||
|
||||
@ -3968,14 +3933,8 @@ bool Threads::destroy_vm() {
|
||||
// GC vm_operations can get caught at the safepoint, and the
|
||||
// heap is unparseable if they are caught. Grab the Heap_lock
|
||||
// to prevent this. The GC vm_operations will not be able to
|
||||
// queue until after the vm thread is dead.
|
||||
// After this point, we'll never emerge out of the safepoint before
|
||||
// the VM exits, so concurrent GC threads do not need to be explicitly
|
||||
// stopped; they remain inactive until the process exits.
|
||||
// Note: some concurrent G1 threads may be running during a safepoint,
|
||||
// but these will not be accessing the heap, just some G1-specific side
|
||||
// data structures that are not accessed by any other threads but them
|
||||
// after this point in a terminal safepoint.
|
||||
// queue until after the vm thread is dead. After this point,
|
||||
// we'll never emerge out of the safepoint before the VM exits.
|
||||
|
||||
MutexLocker ml(Heap_lock);
|
||||
|
||||
|
@ -915,6 +915,9 @@ class JavaThread: public Thread {
|
||||
// support for JNI critical regions
|
||||
jint _jni_active_critical; // count of entries into JNI critical region
|
||||
|
||||
// Checked JNI: function name requires exception check
|
||||
char* _pending_jni_exception_check_fn;
|
||||
|
||||
// For deadlock detection.
|
||||
int _depth_first_number;
|
||||
|
||||
@ -1400,6 +1403,12 @@ class JavaThread: public Thread {
|
||||
assert(_jni_active_critical >= 0,
|
||||
"JNI critical nesting problem?"); }
|
||||
|
||||
// Checked JNI, is the programmer required to check for exceptions, specify which function name
|
||||
bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; }
|
||||
void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; }
|
||||
const char* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; }
|
||||
void set_pending_jni_exception_check(const char* fn_name) { _pending_jni_exception_check_fn = (char*) fn_name; }
|
||||
|
||||
// For deadlock detection
|
||||
int depth_first_number() { return _depth_first_number; }
|
||||
void set_depth_first_number(int dfn) { _depth_first_number = dfn; }
|
||||
|
@ -480,9 +480,8 @@ void vframeStreamCommon::skip_prefixed_method_and_wrappers() {
|
||||
|
||||
void vframeStreamCommon::skip_reflection_related_frames() {
|
||||
while (!at_end() &&
|
||||
(JDK_Version::is_gte_jdk14x_version() &&
|
||||
(method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) ||
|
||||
method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) {
|
||||
method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass()))) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
@ -184,9 +184,7 @@ bool VM_PrintThreads::doit_prologue() {
|
||||
assert(Thread::current()->is_Java_thread(), "just checking");
|
||||
|
||||
// Make sure AbstractOwnableSynchronizer is loaded
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
|
||||
}
|
||||
|
||||
// Get Heap_lock if concurrent locks will be dumped
|
||||
if (_print_concurrent_locks) {
|
||||
@ -225,7 +223,7 @@ bool VM_FindDeadlocks::doit_prologue() {
|
||||
assert(Thread::current()->is_Java_thread(), "just checking");
|
||||
|
||||
// Load AbstractOwnableSynchronizer class
|
||||
if (_concurrent_locks && JDK_Version::is_gte_jdk16x_version()) {
|
||||
if (_concurrent_locks) {
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
|
||||
}
|
||||
|
||||
@ -283,9 +281,7 @@ bool VM_ThreadDump::doit_prologue() {
|
||||
assert(Thread::current()->is_Java_thread(), "just checking");
|
||||
|
||||
// Load AbstractOwnableSynchronizer class before taking thread snapshots
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(JavaThread::current());
|
||||
}
|
||||
|
||||
if (_with_locked_synchronizers) {
|
||||
// Acquire Heap_lock to dump concurrent locks
|
||||
|
@ -98,6 +98,7 @@
|
||||
template(LinuxDllLoad) \
|
||||
template(RotateGCLog) \
|
||||
template(WhiteBoxOperation) \
|
||||
template(ClassLoaderStatsOperation) \
|
||||
|
||||
class VM_Operation: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
|
@ -160,8 +160,7 @@ const char* Abstract_VM_Version::vm_vendor() {
|
||||
#ifdef VENDOR
|
||||
return XSTR(VENDOR);
|
||||
#else
|
||||
return JDK_Version::is_gte_jdk17x_version() ?
|
||||
"Oracle Corporation" : "Sun Microsystems Inc.";
|
||||
return "Oracle Corporation";
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -222,20 +221,12 @@ const char* Abstract_VM_Version::internal_vm_info_string() {
|
||||
|
||||
#ifndef HOTSPOT_BUILD_COMPILER
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER == 1100
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 5.0"
|
||||
#elif _MSC_VER == 1200
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 6.0"
|
||||
#elif _MSC_VER == 1310
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 7.1 (VS2003)"
|
||||
#elif _MSC_VER == 1400
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 8.0 (VS2005)"
|
||||
#elif _MSC_VER == 1500
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 9.0 (VS2008)"
|
||||
#elif _MSC_VER == 1600
|
||||
#if _MSC_VER == 1600
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 10.0 (VS2010)"
|
||||
#elif _MSC_VER == 1700
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 11.0 (VS2012)"
|
||||
#elif _MSC_VER == 1800
|
||||
#define HOTSPOT_BUILD_COMPILER "MS VC++ 12.0 (VS2013)"
|
||||
#else
|
||||
#define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderStats.hpp"
|
||||
#include "gc_implementation/shared/vmGCOperations.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
@ -58,6 +59,7 @@ void DCmdRegistrant::register_dcmds(){
|
||||
#endif // INCLUDE_SERVICES
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
|
||||
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassLoaderStatsDCmd>(full_export, true, false));
|
||||
|
||||
// Enhanced JMX Agent Support
|
||||
// These commands won't be exported via the DiagnosticCommandMBean until an
|
||||
|
@ -1229,10 +1229,8 @@ JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jo
|
||||
"The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
|
||||
}
|
||||
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
|
||||
}
|
||||
|
||||
// Must use ThreadDumpResult to store the ThreadSnapshot.
|
||||
// GC may occur after the thread snapshots are taken but before
|
||||
@ -1303,10 +1301,8 @@ JVM_END
|
||||
JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers))
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
// make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
|
||||
java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
|
||||
}
|
||||
|
||||
typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
|
||||
int num_threads = (ta != NULL ? ta->length() : 0);
|
||||
|
@ -665,7 +665,6 @@ void ConcurrentLocksDump::dump_at_safepoint() {
|
||||
// dump all locked concurrent locks
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "all threads are stopped");
|
||||
|
||||
if (JDK_Version::is_gte_jdk16x_version()) {
|
||||
ResourceMark rm;
|
||||
|
||||
GrowableArray<oop>* aos_objects = new GrowableArray<oop>(INITIAL_ARRAY_SIZE);
|
||||
@ -676,7 +675,6 @@ void ConcurrentLocksDump::dump_at_safepoint() {
|
||||
// Build a map of thread to its owned AQS locks
|
||||
build_map(aos_objects);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build a map of JavaThread to all its owned AbstractOwnableSynchronizer
|
||||
|
115
hotspot/test/runtime/EnclosingMethodAttr/EnclMethTest.jcod
Normal file
115
hotspot/test/runtime/EnclosingMethodAttr/EnclMethTest.jcod
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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 test has a EnclosingMethod attribute with an illegal
|
||||
* attribute_length field value of 6. This should cause a
|
||||
* java.lang.ClassFormatError exception to be thrown.
|
||||
*/
|
||||
|
||||
class EnclMethTest {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
52; // version
|
||||
[22] { // Constant Pool
|
||||
; // first element is empty
|
||||
Field #3 #14; // #1 at 0x0A
|
||||
Method #4 #15; // #2 at 0x0F
|
||||
class #16; // #3 at 0x14
|
||||
class #19; // #4 at 0x17
|
||||
Utf8 "this$0"; // #5 at 0x1A
|
||||
Utf8 "La;"; // #6 at 0x23
|
||||
Utf8 "Synthetic"; // #7 at 0x29
|
||||
Utf8 "<init>"; // #8 at 0x35
|
||||
Utf8 "(Ljava/lang/Object;)V"; // #9 at 0x3E
|
||||
Utf8 "Code"; // #10 at 0x56
|
||||
Utf8 "LineNumberTable"; // #11 at 0x5D
|
||||
Utf8 "SourceFile"; // #12 at 0x6F
|
||||
Utf8 "a.java"; // #13 at 0x7C
|
||||
NameAndType #5 #6; // #14 at 0x85
|
||||
NameAndType #8 #20; // #15 at 0x8A
|
||||
Utf8 "EnclMethTest"; // #16 at 0x8F
|
||||
Utf8 "Loc"; // #17 at 0x9E
|
||||
Utf8 "InnerClasses"; // #18 at 0xA4
|
||||
Utf8 "java/lang/Object"; // #19 at 0xB3
|
||||
Utf8 "()V"; // #20 at 0xC6
|
||||
Utf8 "EnclosingMethod"; // #21 at 0xCC
|
||||
} // Constant Pool
|
||||
|
||||
0x0000; // access
|
||||
#3;// this_cpx
|
||||
#4;// super_cpx
|
||||
|
||||
[0] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[1] { // fields
|
||||
{ // Member at 0xE8
|
||||
0x0000; // access
|
||||
#5; // name_cpx
|
||||
#6; // sig_cpx
|
||||
[1] { // Attributes
|
||||
Attr(#7, 0) { // Synthetic at 0xF0
|
||||
} // end Synthetic
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // fields
|
||||
|
||||
[1] { // methods
|
||||
{ // Member at 0xF8
|
||||
0x0001; // access
|
||||
#8; // name_cpx
|
||||
#20; // sig_cpx
|
||||
[1] { // Attributes
|
||||
Attr(#10, 17) { // Code at 0x0100
|
||||
2; // max_stack
|
||||
2; // max_locals
|
||||
Bytes[5]{
|
||||
0x2AB70002B1;
|
||||
};
|
||||
[0] { // Traps
|
||||
} // end Traps
|
||||
[0] { // Attributes
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[3] { // Attributes
|
||||
Attr(#12, 2) { // SourceFile at 0x0119
|
||||
#13;
|
||||
} // end SourceFile
|
||||
;
|
||||
Attr(#18, 10) { // InnerClasses at 0x0121
|
||||
[1] { // InnerClasses
|
||||
#3 #0 #17 0; // at 0x0131
|
||||
}
|
||||
} // end InnerClasses
|
||||
;
|
||||
Attr(#21, 6) { // EnclosingMethod at 0x0131
|
||||
// invalid length of EnclosingMethod attr: 6 (should be 4) !!
|
||||
0x0004000F;
|
||||
} // end EnclosingMethod
|
||||
} // Attributes
|
||||
} // end class EnclMethTest
|
47
hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java
Normal file
47
hotspot/test/runtime/EnclosingMethodAttr/EnclMethodAttr.java
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8044738
|
||||
* @library /testlibrary
|
||||
* @summary Check attribute_length of EnclosingMethod attribute
|
||||
* @run main EnclMethodAttr
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import com.oracle.java.testlibrary.*;
|
||||
|
||||
public class EnclMethodAttr {
|
||||
|
||||
static final String testsrc = System.getProperty("test.src");
|
||||
|
||||
public static void main(String args[]) throws Throwable {
|
||||
System.out.println("Regression test for bug 8044738");
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-jar", testsrc + File.separator + "enclMethodAttr.jar");
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("java.lang.ClassFormatError: Wrong EnclosingMethod");
|
||||
}
|
||||
}
|
||||
|
BIN
hotspot/test/runtime/EnclosingMethodAttr/enclMethodAttr.jar
Normal file
BIN
hotspot/test/runtime/EnclosingMethodAttr/enclMethodAttr.jar
Normal file
Binary file not shown.
@ -24,6 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 8036823
|
||||
* @bug 8046287
|
||||
* @summary Creates two threads contending for the same lock and checks
|
||||
* whether jstack reports "locked" by more than one thread.
|
||||
*
|
||||
@ -52,10 +53,13 @@ public class TestThreadDumpMonitorContention {
|
||||
// looking for header lines with these patterns:
|
||||
// "ContendingThread-1" #19 prio=5 os_prio=64 tid=0x000000000079c000 nid=0x23 runnable [0xffff80ffb8b87000]
|
||||
// "ContendingThread-2" #21 prio=5 os_prio=64 tid=0x0000000000780000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
|
||||
// "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
|
||||
final static Pattern HEADER_PREFIX_PATTERN = Pattern.compile(
|
||||
"^\"ContendingThread-.*");
|
||||
final static Pattern HEADER_WAITING_PATTERN = Pattern.compile(
|
||||
final static Pattern HEADER_WAITING_PATTERN1 = Pattern.compile(
|
||||
"^\"ContendingThread-.* waiting for monitor entry .*");
|
||||
final static Pattern HEADER_WAITING_PATTERN2 = Pattern.compile(
|
||||
"^\"ContendingThread-.* waiting on condition .*");
|
||||
final static Pattern HEADER_RUNNABLE_PATTERN = Pattern.compile(
|
||||
"^\"ContendingThread-.* runnable .*");
|
||||
|
||||
@ -80,17 +84,34 @@ public class TestThreadDumpMonitorContention {
|
||||
final static Pattern WAITING_PATTERN = Pattern.compile(
|
||||
".* waiting to lock \\<.*\\(a TestThreadDumpMonitorContention.*");
|
||||
|
||||
final static Object barrier = new Object();
|
||||
volatile static boolean done = false;
|
||||
|
||||
static int barrier_cnt = 0;
|
||||
static int blank_line_match_cnt = 0;
|
||||
static int error_cnt = 0;
|
||||
static String header_line = null;
|
||||
static boolean have_header_line = false;
|
||||
static boolean have_thread_state_line = false;
|
||||
static int match_cnt = 0;
|
||||
static String[] match_list = new String[2];
|
||||
static String header_line = null;
|
||||
static int header_prefix_match_cnt = 0;
|
||||
static int locked_line_match_cnt = 0;
|
||||
static String[] locked_match_list = new String[2];
|
||||
static int n_samples = 15;
|
||||
static int sum_both_running_cnt = 0;
|
||||
static int sum_both_waiting_cnt = 0;
|
||||
static int sum_contended_cnt = 0;
|
||||
static int sum_locked_hdr_runnable_cnt = 0;
|
||||
static int sum_locked_hdr_waiting1_cnt = 0;
|
||||
static int sum_locked_hdr_waiting2_cnt = 0;
|
||||
static int sum_locked_thr_state_blocked_cnt = 0;
|
||||
static int sum_locked_thr_state_runnable_cnt = 0;
|
||||
static int sum_one_waiting_cnt = 0;
|
||||
static int sum_uncontended_cnt = 0;
|
||||
static int sum_waiting_hdr_waiting1_cnt = 0;
|
||||
static int sum_waiting_thr_state_blocked_cnt = 0;
|
||||
static String thread_state_line = null;
|
||||
static boolean verbose = false;
|
||||
static int waiting_line_match_cnt = 0;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length != 0) {
|
||||
@ -110,6 +131,11 @@ public class TestThreadDumpMonitorContention {
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
synchronized (barrier) {
|
||||
// let the main thread know we're running
|
||||
barrier_cnt++;
|
||||
barrier.notify();
|
||||
}
|
||||
while (!done) {
|
||||
synchronized (this) { }
|
||||
}
|
||||
@ -118,9 +144,17 @@ public class TestThreadDumpMonitorContention {
|
||||
Thread[] thread_list = new Thread[2];
|
||||
thread_list[0] = new Thread(runnable, "ContendingThread-1");
|
||||
thread_list[1] = new Thread(runnable, "ContendingThread-2");
|
||||
synchronized (barrier) {
|
||||
thread_list[0].start();
|
||||
thread_list[1].start();
|
||||
|
||||
// Wait until the contending threads are running so that
|
||||
// we don't sample any thread init states.
|
||||
while (barrier_cnt < 2) {
|
||||
barrier.wait();
|
||||
}
|
||||
}
|
||||
|
||||
doSamples();
|
||||
|
||||
done = true;
|
||||
@ -143,11 +177,12 @@ public class TestThreadDumpMonitorContention {
|
||||
// Example:
|
||||
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
|
||||
// java.lang.Thread.State: RUNNABLE
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
|
||||
// at java.lang.Thread.run(Thread.java:745)
|
||||
//
|
||||
static boolean checkBlankLine(String line) {
|
||||
if (line.length() == 0) {
|
||||
blank_line_match_cnt++;
|
||||
have_header_line = false;
|
||||
have_thread_state_line = false;
|
||||
return true;
|
||||
@ -161,49 +196,73 @@ public class TestThreadDumpMonitorContention {
|
||||
// Example 1:
|
||||
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f runnable [0xfffffd7fc1111000]
|
||||
// java.lang.Thread.State: RUNNABLE
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
|
||||
// - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
|
||||
// at java.lang.Thread.run(Thread.java:745)
|
||||
//
|
||||
// Example 2:
|
||||
// "ContendingThread-1" #21 prio=5 os_prio=64 tid=0x00000000007b9000 nid=0x2f waiting for monitor entry [0xfffffd7fc1111000]
|
||||
// java.lang.Thread.State: BLOCKED (on object monitor)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
|
||||
// - locked <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
|
||||
// at java.lang.Thread.run(Thread.java:745)
|
||||
//
|
||||
// Example 3:
|
||||
// "ContendingThread-2" #24 prio=5 os_prio=64 tid=0x0000000000ec8800 nid=0x31 waiting on condition [0xfffffd7bbfffe000]
|
||||
// java.lang.Thread.State: RUNNABLE
|
||||
// JavaThread state: _thread_blocked
|
||||
// Thread: 0x0000000000ec8800 [0x31] State: _at_safepoint _has_called_back 0 _at_poll_safepoint 0
|
||||
// JavaThread state: _thread_blocked
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
|
||||
// - locked <0xfffffd7e6d03eb28> (a TestThreadDumpMonitorContention$1)
|
||||
// at java.lang.Thread.run(Thread.java:745)
|
||||
//
|
||||
static boolean checkLockedLine(String line) {
|
||||
Matcher matcher = LOCK_PATTERN.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
if (verbose) {
|
||||
System.out.println("locked_line='" + line + "'");
|
||||
}
|
||||
match_list[match_cnt] = new String(line);
|
||||
match_cnt++;
|
||||
locked_match_list[locked_line_match_cnt] = new String(line);
|
||||
locked_line_match_cnt++;
|
||||
|
||||
matcher = HEADER_RUNNABLE_PATTERN.matcher(header_line);
|
||||
if (!matcher.matches()) {
|
||||
if (matcher.matches()) {
|
||||
sum_locked_hdr_runnable_cnt++;
|
||||
} else {
|
||||
// It's strange, but a locked line can also
|
||||
// match the HEADER_WAITING_PATTERN.
|
||||
matcher = HEADER_WAITING_PATTERN.matcher(header_line);
|
||||
if (!matcher.matches()) {
|
||||
// match the HEADER_WAITING_PATTERN{1,2}.
|
||||
matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
|
||||
if (matcher.matches()) {
|
||||
sum_locked_hdr_waiting1_cnt++;
|
||||
} else {
|
||||
matcher = HEADER_WAITING_PATTERN2.matcher(header_line);
|
||||
if (matcher.matches()) {
|
||||
sum_locked_hdr_waiting2_cnt++;
|
||||
} else {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: header line does " +
|
||||
"not match runnable or waiting patterns.");
|
||||
System.err.println("ERROR: header_line='" +
|
||||
header_line + "'");
|
||||
System.err.println("ERROR: locked_line='" + line + "'");
|
||||
System.err.println("ERROR: locked_line='" + line +
|
||||
"'");
|
||||
error_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matcher = THREAD_STATE_RUNNABLE_PATTERN.matcher(thread_state_line);
|
||||
if (!matcher.matches()) {
|
||||
if (matcher.matches()) {
|
||||
sum_locked_thr_state_runnable_cnt++;
|
||||
} else {
|
||||
// It's strange, but a locked line can also
|
||||
// match the THREAD_STATE_BLOCKED_PATTERN.
|
||||
matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(
|
||||
thread_state_line);
|
||||
if (!matcher.matches()) {
|
||||
if (matcher.matches()) {
|
||||
sum_locked_thr_state_blocked_cnt++;
|
||||
} else {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: thread state line does not " +
|
||||
"match runnable or waiting patterns.");
|
||||
@ -229,19 +288,22 @@ public class TestThreadDumpMonitorContention {
|
||||
// Example:
|
||||
// "ContendingThread-2" #22 prio=5 os_prio=64 tid=0x00000000007b9800 nid=0x30 waiting for monitor entry [0xfffffd7fc1010000]
|
||||
// java.lang.Thread.State: BLOCKED (on object monitor)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:67)
|
||||
// at TestThreadDumpMonitorContention$1.run(TestThreadDumpMonitorContention.java:140)
|
||||
// - waiting to lock <0xfffffd7e6a2912f8> (a TestThreadDumpMonitorContention$1)
|
||||
// at java.lang.Thread.run(Thread.java:745)
|
||||
//
|
||||
static boolean checkWaitingLine(String line) {
|
||||
Matcher matcher = WAITING_PATTERN.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
waiting_line_match_cnt++;
|
||||
if (verbose) {
|
||||
System.out.println("waiting_line='" + line + "'");
|
||||
}
|
||||
|
||||
matcher = HEADER_WAITING_PATTERN.matcher(header_line);
|
||||
if (!matcher.matches()) {
|
||||
matcher = HEADER_WAITING_PATTERN1.matcher(header_line);
|
||||
if (matcher.matches()) {
|
||||
sum_waiting_hdr_waiting1_cnt++;
|
||||
} else {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: header line does " +
|
||||
"not match a waiting pattern.");
|
||||
@ -251,7 +313,9 @@ public class TestThreadDumpMonitorContention {
|
||||
}
|
||||
|
||||
matcher = THREAD_STATE_BLOCKED_PATTERN.matcher(thread_state_line);
|
||||
if (!matcher.matches()) {
|
||||
if (matcher.matches()) {
|
||||
sum_waiting_thr_state_blocked_cnt++;
|
||||
} else {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: thread state line " +
|
||||
"does not match a waiting pattern.");
|
||||
@ -273,7 +337,10 @@ public class TestThreadDumpMonitorContention {
|
||||
|
||||
static void doSamples() throws Exception {
|
||||
for (int count = 0; count < n_samples; count++) {
|
||||
match_cnt = 0;
|
||||
blank_line_match_cnt = 0;
|
||||
header_prefix_match_cnt = 0;
|
||||
locked_line_match_cnt = 0;
|
||||
waiting_line_match_cnt = 0;
|
||||
// verbose mode or an error has a lot of output so add more space
|
||||
if (verbose || error_cnt > 0) System.out.println();
|
||||
System.out.println("Sample #" + count);
|
||||
@ -290,12 +357,12 @@ public class TestThreadDumpMonitorContention {
|
||||
// a failure and we report it
|
||||
// - for a stack trace that matches LOCKED_PATTERN, we verify:
|
||||
// - the header line matches HEADER_RUNNABLE_PATTERN
|
||||
// or HEADER_WAITING_PATTERN
|
||||
// or HEADER_WAITING_PATTERN{1,2}
|
||||
// - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
|
||||
// or THREAD_STATE_RUNNABLE_PATTERN
|
||||
// - we report any mismatches as failures
|
||||
// - for a stack trace that matches WAITING_PATTERN, we verify:
|
||||
// - the header line matches HEADER_WAITING_PATTERN
|
||||
// - the header line matches HEADER_WAITING_PATTERN1
|
||||
// - the thread state line matches THREAD_STATE_BLOCKED_PATTERN
|
||||
// - we report any mismatches as failures
|
||||
// - the stack traces that match HEADER_PREFIX_PATTERN may
|
||||
@ -324,6 +391,7 @@ public class TestThreadDumpMonitorContention {
|
||||
if (!have_header_line) {
|
||||
matcher = HEADER_PREFIX_PATTERN.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
header_prefix_match_cnt++;
|
||||
if (verbose) {
|
||||
System.out.println();
|
||||
System.out.println("header='" + line + "'");
|
||||
@ -366,19 +434,80 @@ public class TestThreadDumpMonitorContention {
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
if (match_cnt == 2) {
|
||||
if (match_list[0].equals(match_list[1])) {
|
||||
if (header_prefix_match_cnt != 2) {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: should match exactly two headers.");
|
||||
System.err.println("ERROR: header_prefix_match_cnt=" +
|
||||
header_prefix_match_cnt);
|
||||
error_cnt++;
|
||||
}
|
||||
|
||||
if (locked_line_match_cnt == 2) {
|
||||
if (locked_match_list[0].equals(locked_match_list[1])) {
|
||||
System.err.println();
|
||||
System.err.println("ERROR: matching lock lines:");
|
||||
System.err.println("ERROR: line[0]'" + match_list[0] + "'");
|
||||
System.err.println("ERROR: line[1]'" + match_list[1] + "'");
|
||||
System.err.println("ERROR: line[0]'" +
|
||||
locked_match_list[0] + "'");
|
||||
System.err.println("ERROR: line[1]'" +
|
||||
locked_match_list[1] + "'");
|
||||
error_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
if (locked_line_match_cnt == 1) {
|
||||
// one thread has the lock
|
||||
if (waiting_line_match_cnt == 1) {
|
||||
// and the other contended for it
|
||||
sum_contended_cnt++;
|
||||
} else {
|
||||
// and the other is just running
|
||||
sum_uncontended_cnt++;
|
||||
}
|
||||
} else if (waiting_line_match_cnt == 1) {
|
||||
// one thread is waiting
|
||||
sum_one_waiting_cnt++;
|
||||
} else if (waiting_line_match_cnt == 2) {
|
||||
// both threads are waiting
|
||||
sum_both_waiting_cnt++;
|
||||
} else {
|
||||
// both threads are running
|
||||
sum_both_running_cnt++;
|
||||
}
|
||||
|
||||
// slight delay between jstack launches
|
||||
Thread.sleep(500);
|
||||
}
|
||||
|
||||
if (error_cnt != 0) {
|
||||
// skip summary info since there were errors
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("INFO: Summary for all samples:");
|
||||
System.out.println("INFO: both_running_cnt=" + sum_both_running_cnt);
|
||||
System.out.println("INFO: both_waiting_cnt=" + sum_both_waiting_cnt);
|
||||
System.out.println("INFO: contended_cnt=" + sum_contended_cnt);
|
||||
System.out.println("INFO: one_waiting_cnt=" + sum_one_waiting_cnt);
|
||||
System.out.println("INFO: uncontended_cnt=" + sum_uncontended_cnt);
|
||||
System.out.println("INFO: locked_hdr_runnable_cnt=" +
|
||||
sum_locked_hdr_runnable_cnt);
|
||||
System.out.println("INFO: locked_hdr_waiting1_cnt=" +
|
||||
sum_locked_hdr_waiting1_cnt);
|
||||
System.out.println("INFO: locked_hdr_waiting2_cnt=" +
|
||||
sum_locked_hdr_waiting2_cnt);
|
||||
System.out.println("INFO: locked_thr_state_blocked_cnt=" +
|
||||
sum_locked_thr_state_blocked_cnt);
|
||||
System.out.println("INFO: locked_thr_state_runnable_cnt=" +
|
||||
sum_locked_thr_state_runnable_cnt);
|
||||
System.out.println("INFO: waiting_hdr_waiting1_cnt=" +
|
||||
sum_waiting_hdr_waiting1_cnt);
|
||||
System.out.println("INFO: waiting_thr_state_blocked_cnt=" +
|
||||
sum_waiting_thr_state_blocked_cnt);
|
||||
|
||||
if (sum_contended_cnt == 0) {
|
||||
System.err.println("WARNING: the primary scenario for 8036823" +
|
||||
" has not been exercised by this test run.");
|
||||
}
|
||||
}
|
||||
|
||||
// This helper relies on RuntimeMXBean.getName() returning a string
|
||||
|
155
hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java
Normal file
155
hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
*
|
||||
* @build ClassLoaderStatsTest DcmdUtil
|
||||
* @run main ClassLoaderStatsTest
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ClassLoaderStatsTest {
|
||||
|
||||
// ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
|
||||
// 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
|
||||
// 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
|
||||
// 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
|
||||
// 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
|
||||
// 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
|
||||
// 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
|
||||
// 455 1210368 672848 + unsafe anonymous classes
|
||||
// 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
|
||||
// 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
|
||||
// ...
|
||||
|
||||
static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
|
||||
static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
|
||||
|
||||
public static DummyClassLoader dummyloader;
|
||||
|
||||
public static void main(String arg[]) throws Exception {
|
||||
|
||||
// create a classloader and load our special class
|
||||
dummyloader = new DummyClassLoader();
|
||||
Class<?> c = Class.forName("TestClass", true, dummyloader);
|
||||
if (c.getClassLoader() != dummyloader) {
|
||||
throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
|
||||
}
|
||||
|
||||
String result = DcmdUtil.executeDcmd("VM.classloader_stats");
|
||||
BufferedReader r = new BufferedReader(new StringReader(result));
|
||||
String line;
|
||||
while((line = r.readLine()) != null) {
|
||||
Matcher m = clLine.matcher(line);
|
||||
if (m.matches()) {
|
||||
// verify that DummyClassLoader has loaded 1 class and 1 anonymous class
|
||||
if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
|
||||
System.out.println("line: " + line);
|
||||
if (!m.group(1).equals("1")) {
|
||||
throw new Exception("Should have loaded 1 class: " + line);
|
||||
}
|
||||
checkPositiveInt(m.group(2));
|
||||
checkPositiveInt(m.group(3));
|
||||
|
||||
String next = r.readLine();
|
||||
System.out.println("next: " + next);
|
||||
Matcher m1 = anonLine.matcher(next);
|
||||
m1.matches();
|
||||
if (!m1.group(1).equals("1")) {
|
||||
throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
|
||||
}
|
||||
checkPositiveInt(m1.group(2));
|
||||
checkPositiveInt(m1.group(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkPositiveInt(String s) throws Exception {
|
||||
if (Integer.parseInt(s) <= 0) {
|
||||
throw new Exception("Value should have been > 0: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DummyClassLoader extends ClassLoader {
|
||||
|
||||
public static final String CLASS_NAME = "TestClass";
|
||||
|
||||
static ByteBuffer readClassFile(String name)
|
||||
{
|
||||
File f = new File(System.getProperty("test.classes", "."),
|
||||
name);
|
||||
try (FileInputStream fin = new FileInputStream(f);
|
||||
FileChannel fc = fin.getChannel())
|
||||
{
|
||||
return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Can't open file: " + name, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Class<?> loadClass(String name, boolean resolve)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
Class<?> c;
|
||||
if (!"TestClass".equals(name)) {
|
||||
c = super.loadClass(name, resolve);
|
||||
} else {
|
||||
// should not delegate to the system class loader
|
||||
c = findClass(name);
|
||||
if (resolve) {
|
||||
resolveClass(c);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
protected Class<?> findClass(String name)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
if (!"TestClass".equals(name)) {
|
||||
throw new ClassNotFoundException("Unexpected class: " + name);
|
||||
}
|
||||
return defineClass(name, readClassFile(name + ".class"), null);
|
||||
}
|
||||
} /* DummyClassLoader */
|
||||
|
||||
}
|
||||
|
||||
class TestClass {
|
||||
static {
|
||||
// force creation of anonymous class (for the lambdaform)
|
||||
Runnable r = () -> System.out.println("Hello");
|
||||
r.run();
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
* @bug 8028623
|
||||
* @summary Test hashing of extended characters in Serviceability Agent.
|
||||
* @library /testlibrary
|
||||
* @ignore 8044416
|
||||
* @build com.oracle.java.testlibrary.*
|
||||
* @compile -encoding utf8 Test8028623.java
|
||||
* @run main Test8028623
|
||||
|
Loading…
x
Reference in New Issue
Block a user