Merge
This commit is contained in:
commit
9d85b8e187
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 2012, 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
|
||||
@ -133,8 +133,10 @@ $(GENERATEDFILES): refresh_adfiles
|
||||
# Note that product files are updated via "mv", which is atomic.
|
||||
TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
|
||||
|
||||
# Debuggable by default
|
||||
CFLAGS += -g
|
||||
ifneq ($(DEBUG_BINARIES), true)
|
||||
# Debuggable by default (unless already done by DEBUG_BINARIES)
|
||||
CFLAGS += -g
|
||||
endif
|
||||
|
||||
# Pass -D flags into ADLC.
|
||||
ADLCFLAGS += $(SYSDEFS)
|
||||
|
@ -215,45 +215,44 @@ AOUT_FLAGS += -Xlinker -export-dynamic
|
||||
#------------------------------------------------------------------------
|
||||
# Debug flags
|
||||
|
||||
# Use the stabs format for debugging information (this is the default
|
||||
# on gcc-2.91). It's good enough, has all the information about line
|
||||
# numbers and local variables, and libjvm_g.so is only about 16M.
|
||||
# Change this back to "-g" if you want the most expressive format.
|
||||
# (warning: that could easily inflate libjvm_g.so to 150M!)
|
||||
# Note: The Itanium gcc compiler crashes when using -gstabs.
|
||||
DEBUG_CFLAGS/ia64 = -g
|
||||
DEBUG_CFLAGS/amd64 = -g
|
||||
DEBUG_CFLAGS/arm = -g
|
||||
DEBUG_CFLAGS/ppc = -g
|
||||
DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
FASTDEBUG_CFLAGS/ia64 = -g
|
||||
FASTDEBUG_CFLAGS/amd64 = -g
|
||||
FASTDEBUG_CFLAGS/arm = -g
|
||||
FASTDEBUG_CFLAGS/ppc = -g
|
||||
FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
FASTDEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
|
||||
OPT_CFLAGS/ia64 = -g
|
||||
OPT_CFLAGS/amd64 = -g
|
||||
OPT_CFLAGS/arm = -g
|
||||
OPT_CFLAGS/ppc = -g
|
||||
OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
|
||||
OPT_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
|
||||
# DEBUG_BINARIES overrides everything, use full -g debug information
|
||||
# DEBUG_BINARIES uses full -g debug information for all configs
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
DEBUG_CFLAGS = -g
|
||||
CFLAGS += $(DEBUG_CFLAGS)
|
||||
CFLAGS += -g
|
||||
else
|
||||
# Use the stabs format for debugging information (this is the default
|
||||
# on gcc-2.91). It's good enough, has all the information about line
|
||||
# numbers and local variables, and libjvm_g.so is only about 16M.
|
||||
# Change this back to "-g" if you want the most expressive format.
|
||||
# (warning: that could easily inflate libjvm_g.so to 150M!)
|
||||
# Note: The Itanium gcc compiler crashes when using -gstabs.
|
||||
DEBUG_CFLAGS/ia64 = -g
|
||||
DEBUG_CFLAGS/amd64 = -g
|
||||
DEBUG_CFLAGS/arm = -g
|
||||
DEBUG_CFLAGS/ppc = -g
|
||||
DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
FASTDEBUG_CFLAGS/ia64 = -g
|
||||
FASTDEBUG_CFLAGS/amd64 = -g
|
||||
FASTDEBUG_CFLAGS/arm = -g
|
||||
FASTDEBUG_CFLAGS/ppc = -g
|
||||
FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
FASTDEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
|
||||
OPT_CFLAGS/ia64 = -g
|
||||
OPT_CFLAGS/amd64 = -g
|
||||
OPT_CFLAGS/arm = -g
|
||||
OPT_CFLAGS/ppc = -g
|
||||
OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
|
||||
OPT_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# If we are building HEADLESS, pass on to VM
|
||||
|
@ -188,14 +188,22 @@ ifdef COOKED_BUILD_NUMBER
|
||||
MAKE_ARGS += JDK_BUILD_NUMBER=$(COOKED_BUILD_NUMBER)
|
||||
endif
|
||||
|
||||
NMAKE= MAKEFLAGS= MFLAGS= nmake /NOLOGO
|
||||
NMAKE= MAKEFLAGS= MFLAGS= nmake -NOLOGO
|
||||
ifndef SYSTEM_UNAME
|
||||
SYSTEM_UNAME := $(shell uname)
|
||||
export SYSTEM_UNAME
|
||||
endif
|
||||
|
||||
# Check for CYGWIN
|
||||
ifneq (,$(findstring CYGWIN,$(shell uname)))
|
||||
ifneq (,$(findstring CYGWIN,$(SYSTEM_UNAME)))
|
||||
USING_CYGWIN=true
|
||||
else
|
||||
USING_CYGWIN=false
|
||||
endif
|
||||
# Check for MinGW
|
||||
ifneq (,$(findstring MINGW,$(SYSTEM_UNAME)))
|
||||
USING_MINGW=true
|
||||
endif
|
||||
# FIXUP: The subdirectory for a debug build is NOT the same on all platforms
|
||||
VM_DEBUG=debug
|
||||
|
||||
@ -208,11 +216,16 @@ ifeq ($(USING_CYGWIN), true)
|
||||
ABS_BOOTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)"))
|
||||
ABS_GAMMADIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)"))
|
||||
ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make
|
||||
else
|
||||
ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD)))
|
||||
ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
|
||||
ABS_GAMMADIR := $(subst /,\\,$(shell $(CD) $(GAMMADIR);$(PWD)))
|
||||
ABS_OS_MAKEFILE := $(subst /,\\,$(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make)
|
||||
else ifeq ($(USING_MINGW), true)
|
||||
ABS_OUTPUTDIR := $(shell $(CD) $(OUTPUTDIR);$(PWD))
|
||||
ABS_BOOTDIR := $(shell $(CD) $(BOOTDIR);$(PWD))
|
||||
ABS_GAMMADIR := $(shell $(CD) $(GAMMADIR);$(PWD))
|
||||
ABS_OS_MAKEFILE := $(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make
|
||||
else
|
||||
ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD)))
|
||||
ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
|
||||
ABS_GAMMADIR := $(subst /,\\,$(shell $(CD) $(GAMMADIR);$(PWD)))
|
||||
ABS_OS_MAKEFILE := $(subst /,\\,$(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make)
|
||||
endif
|
||||
|
||||
# Disable building SA on windows until we are sure
|
||||
|
@ -23,14 +23,15 @@
|
||||
#
|
||||
|
||||
# These are the commands used externally to compile and run.
|
||||
|
||||
# The \ are used here for traditional Windows apps and " quoted to get
|
||||
# past the Unix-like shell:
|
||||
!ifdef BootStrapDir
|
||||
RUN_JAVA=$(BootStrapDir)\bin\java
|
||||
RUN_JAVAP=$(BootStrapDir)\bin\javap
|
||||
RUN_JAVAH=$(BootStrapDir)\bin\javah
|
||||
RUN_JAR=$(BootStrapDir)\bin\jar
|
||||
COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
COMPILE_RMIC=$(BootStrapDir)\bin\rmic
|
||||
RUN_JAVA="$(BootStrapDir)\bin\java"
|
||||
RUN_JAVAP="$(BootStrapDir)\bin\javap"
|
||||
RUN_JAVAH="$(BootStrapDir)\bin\javah"
|
||||
RUN_JAR="$(BootStrapDir)\bin\jar"
|
||||
COMPILE_JAVAC="$(BootStrapDir)\bin\javac" $(BOOTSTRAP_JAVAC_FLAGS)
|
||||
COMPILE_RMIC="$(BootStrapDir)\bin\rmic"
|
||||
BOOT_JAVA_HOME=$(BootStrapDir)
|
||||
!else
|
||||
RUN_JAVA=java
|
||||
|
@ -36,37 +36,37 @@ checkAndBuildSA::
|
||||
!include $(WorkSpace)/make/windows/makefiles/rules.make
|
||||
!include $(WorkSpace)/make/sa.files
|
||||
|
||||
GENERATED = ..\generated
|
||||
GENERATED = ../generated
|
||||
|
||||
# tools.jar is needed by the JDI - SA binding
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)\lib\tools.jar
|
||||
SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar
|
||||
|
||||
SA_CLASSDIR = $(GENERATED)\saclasses
|
||||
SA_CLASSDIR = $(GENERATED)/saclasses
|
||||
|
||||
SA_BUILD_VERSION_PROP = sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)
|
||||
|
||||
SA_PROPERTIES = $(SA_CLASSDIR)\sa.properties
|
||||
SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
|
||||
|
||||
default:: $(GENERATED)\sa-jdi.jar
|
||||
default:: $(GENERATED)/sa-jdi.jar
|
||||
|
||||
# Remove the space between $(SA_BUILD_VERSION_PROP) and > below as it adds a white space
|
||||
# at the end of SA version string and causes a version mismatch with the target VM version.
|
||||
|
||||
$(GENERATED)\sa-jdi.jar: $(AGENT_FILES:/=\)
|
||||
@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
|
||||
@echo ...Building sa-jdi.jar
|
||||
$(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
|
||||
$(QUIETLY) mkdir -p $(SA_CLASSDIR)
|
||||
@echo ...Building sa-jdi.jar into $(SA_CLASSDIR)
|
||||
@echo ...$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
|
||||
@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES:/=\)
|
||||
@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES)
|
||||
$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
|
||||
$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
|
||||
$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
|
||||
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql
|
||||
$(QUIETLY) rm -rf $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources
|
||||
$(QUIETLY) mkdir $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
|
||||
$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
|
||||
$(RUN_JAR) cf $@ -C $(SA_CLASSDIR) .
|
||||
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
|
||||
$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
|
||||
$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext
|
||||
@ -85,27 +85,27 @@ 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" -YX -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
|
||||
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
|
||||
!else
|
||||
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 -Gm $(GX_OPTION) -Od -D "WIN32" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -GZ -c
|
||||
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
|
||||
SA_CFLAGS = $(SA_CFLAGS) /ZI
|
||||
SA_CFLAGS = $(SA_CFLAGS) -ZI
|
||||
!endif
|
||||
!endif
|
||||
!if "$(MT)" != ""
|
||||
SA_LD_FLAGS = /manifest $(SA_LD_FLAGS)
|
||||
SA_LD_FLAGS = -manifest $(SA_LD_FLAGS)
|
||||
!endif
|
||||
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
|
||||
SA_LFLAGS = $(SA_LD_FLAGS) /nologo /subsystem:console /machine:$(MACHINE)
|
||||
SA_LFLAGS = $(SA_LD_FLAGS) -nologo -subsystem:console -machine:$(MACHINE)
|
||||
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
|
||||
SA_LFLAGS = $(SA_LFLAGS) /map /debug
|
||||
SA_LFLAGS = $(SA_LFLAGS) -map -debug
|
||||
!endif
|
||||
|
||||
# Note that we do not keep sawindbj.obj around as it would then
|
||||
@ -117,15 +117,15 @@ SA_LFLAGS = $(SA_LFLAGS) /map /debug
|
||||
$(SAWINDBG): $(SASRCFILE)
|
||||
set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
|
||||
$(CXX) @<<
|
||||
/I"$(BootStrapDir)/include" /I"$(BootStrapDir)/include/win32"
|
||||
/I"$(GENERATED)" $(SA_CFLAGS)
|
||||
-I"$(BootStrapDir)/include" -I"$(BootStrapDir)/include/win32"
|
||||
-I"$(GENERATED)" $(SA_CFLAGS)
|
||||
$(SASRCFILE)
|
||||
/out:$*.obj
|
||||
-out:$*.obj
|
||||
<<
|
||||
set LIB=$(SA_LIB)$(LIB)
|
||||
$(LD) /out:$@ /DLL $*.obj dbgeng.lib $(SA_LFLAGS)
|
||||
$(LD) -out:$@ -DLL $*.obj dbgeng.lib $(SA_LFLAGS)
|
||||
!if "$(MT)" != ""
|
||||
$(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
|
||||
$(MT) -manifest $(@F).manifest -outputresource:$(@F);#2
|
||||
!endif
|
||||
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
|
||||
!if "$(ZIP_DEBUGINFO_FILES)" == "1"
|
||||
@ -136,6 +136,6 @@ $(SAWINDBG): $(SASRCFILE)
|
||||
-@rm -f $*.obj
|
||||
|
||||
cleanall :
|
||||
rm -rf $(GENERATED:\=/)/saclasses
|
||||
rm -rf $(GENERATED:\=/)/sa-jdi.jar
|
||||
rm -rf $(GENERATED)/saclasses
|
||||
rm -rf $(GENERATED)/sa-jdi.jar
|
||||
!endif
|
||||
|
@ -36,11 +36,12 @@ CXX=cl.exe
|
||||
|
||||
|
||||
!ifdef SUBDIRS
|
||||
# \ is used below because $(MAKE) is nmake here, which expects Windows paths
|
||||
$(SUBDIRS): FORCE
|
||||
@if not exist $@ mkdir $@
|
||||
@if not exist $@\local.make echo # Empty > $@\local.make
|
||||
@echo nmake $(ACTION) in $(DIR)\$@
|
||||
cd $@ && $(MAKE) /NOLOGO /f $(WorkSpace)\make\windows\makefiles\$@.make $(ACTION) DIR=$(DIR)\$@ BUILD_FLAVOR=$(BUILD_FLAVOR)
|
||||
@if not exist $@/local.make echo # Empty > $@/local.make
|
||||
@echo nmake $(ACTION) in $(DIR)/$@
|
||||
cd $@ && $(MAKE) -NOLOGO -f $(WorkSpace)\make\windows\makefiles\$@.make $(ACTION) DIR=$(DIR)\$@ BUILD_FLAVOR=$(BUILD_FLAVOR)
|
||||
!endif
|
||||
|
||||
# Creates the needed directory
|
||||
|
@ -108,7 +108,7 @@ ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) \
|
||||
-define HOTSPOT_VM_DISTRO=\\\"$(HOTSPOT_VM_DISTRO)\\\"
|
||||
|
||||
$(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
|
||||
@$(RUN_JAVA) -Djava.class.path=$(HOTSPOTBUILDSPACE)/classes ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
|
||||
@$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
|
||||
|
||||
clean:
|
||||
@rm -rf $(HOTSPOTBUILDSPACE)/classes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2012, 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
|
||||
@ -626,45 +626,6 @@ static void printDOF(void* dof) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
|
||||
* <hex-address>: 8 * <hex-halfword> <ascii translation>
|
||||
* example:
|
||||
* 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000 .DOF............
|
||||
* 0000010: 0000 0000 0000 0040 0000 0020 0000 0005 .......@... ....
|
||||
* 0000020: 0000 0000 0000 0040 0000 0000 0000 015d .......@.......]
|
||||
* ...
|
||||
*/
|
||||
static void printDOFRawData(void* dof) {
|
||||
size_t size = ((dof_hdr_t*)dof)->dofh_loadsz;
|
||||
size_t limit = (size + 16) / 16 * 16;
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
if (i % 16 == 0) {
|
||||
tty->print("%07x:", i);
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
tty->print(" ");
|
||||
}
|
||||
if (i < size) {
|
||||
tty->print("%02x", ((unsigned char*)dof)[i]);
|
||||
} else {
|
||||
tty->print(" ");
|
||||
}
|
||||
if ((i + 1) % 16 == 0) {
|
||||
tty->print(" ");
|
||||
for (size_t j = 0; j < 16; ++j) {
|
||||
size_t idx = i + j - 15;
|
||||
char c = ((char*)dof)[idx];
|
||||
if (idx < size) {
|
||||
tty->print("%c", c >= 32 && c <= 126 ? c : '.');
|
||||
}
|
||||
}
|
||||
tty->print_cr("");
|
||||
}
|
||||
}
|
||||
tty->print_cr("");
|
||||
}
|
||||
|
||||
static void printDOFHelper(dof_helper_t* helper) {
|
||||
tty->print_cr("// dof_helper_t {");
|
||||
tty->print_cr("// dofhp_mod = \"%s\"", helper->dofhp_mod);
|
||||
@ -672,7 +633,8 @@ static void printDOFHelper(dof_helper_t* helper) {
|
||||
tty->print_cr("// dofhp_dof = 0x%016llx", helper->dofhp_dof);
|
||||
printDOF((void*)helper->dofhp_dof);
|
||||
tty->print_cr("// }");
|
||||
printDOFRawData((void*)helper->dofhp_dof);
|
||||
size_t len = ((dof_hdr_t*)helper)->dofh_loadsz;
|
||||
tty->print_data((void*)helper->dofhp_dof, len, true);
|
||||
}
|
||||
|
||||
#else // ndef HAVE_DTRACE_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,9 +32,9 @@
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) :
|
||||
_offset(0), _locals_size(0), _stack_size(0), _flags(0),
|
||||
_max_locals(max_locals), _max_stack(max_stack),
|
||||
_verifier(v) {
|
||||
_offset(0), _locals_size(0), _stack_size(0),
|
||||
_stack_mark(0), _flags(0), _max_locals(max_locals),
|
||||
_max_stack(max_stack), _verifier(v) {
|
||||
Thread* thr = v->thread();
|
||||
_locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals);
|
||||
_stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack);
|
||||
@ -157,17 +157,17 @@ void StackMapFrame::copy_stack(const StackMapFrame* src) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool StackMapFrame::is_assignable_to(
|
||||
// Returns the location of the first mismatch, or 'len' if there are no
|
||||
// mismatches
|
||||
int StackMapFrame::is_assignable_to(
|
||||
VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
|
||||
for (int32_t i = 0; i < len; i++) {
|
||||
bool subtype = to[i].is_assignable_from(
|
||||
from[i], verifier(), THREAD);
|
||||
if (!subtype) {
|
||||
return false;
|
||||
int32_t i = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return i;
|
||||
}
|
||||
|
||||
bool StackMapFrame::has_flag_match_exception(
|
||||
@ -209,50 +209,84 @@ bool StackMapFrame::has_flag_match_exception(
|
||||
}
|
||||
|
||||
bool StackMapFrame::is_assignable_to(
|
||||
const StackMapFrame* target, bool is_exception_handler, TRAPS) const {
|
||||
if (_max_locals != target->max_locals() ||
|
||||
_stack_size != target->stack_size()) {
|
||||
const StackMapFrame* target, bool is_exception_handler,
|
||||
ErrorContext* ctx, TRAPS) const {
|
||||
if (_max_locals != target->max_locals()) {
|
||||
*ctx = ErrorContext::locals_size_mismatch(
|
||||
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
|
||||
return false;
|
||||
}
|
||||
if (_stack_size != target->stack_size()) {
|
||||
*ctx = ErrorContext::stack_size_mismatch(
|
||||
_offset, (StackMapFrame*)this, (StackMapFrame*)target);
|
||||
return false;
|
||||
}
|
||||
// Only need to compare type elements up to target->locals() or target->stack().
|
||||
// The remaining type elements in this state can be ignored because they are
|
||||
// assignable to bogus type.
|
||||
bool match_locals = is_assignable_to(
|
||||
_locals, target->locals(), target->locals_size(), CHECK_false);
|
||||
bool match_stack = is_assignable_to(
|
||||
_stack, target->stack(), _stack_size, CHECK_false);
|
||||
bool match_flags = (_flags | target->flags()) == target->flags();
|
||||
int mismatch_loc;
|
||||
mismatch_loc = is_assignable_to(
|
||||
_locals, target->locals(), target->locals_size(), THREAD);
|
||||
if (mismatch_loc != target->locals_size()) {
|
||||
*ctx = ErrorContext::bad_type(target->offset(),
|
||||
TypeOrigin::local(mismatch_loc, (StackMapFrame*)this),
|
||||
TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target));
|
||||
return false;
|
||||
}
|
||||
mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD);
|
||||
if (mismatch_loc != _stack_size) {
|
||||
*ctx = ErrorContext::bad_type(target->offset(),
|
||||
TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
|
||||
TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
|
||||
return false;
|
||||
}
|
||||
|
||||
return match_locals && match_stack &&
|
||||
(match_flags || (is_exception_handler && has_flag_match_exception(target)));
|
||||
bool match_flags = (_flags | target->flags()) == target->flags();
|
||||
if (match_flags || is_exception_handler && has_flag_match_exception(target)) {
|
||||
return true;
|
||||
} else {
|
||||
*ctx = ErrorContext::bad_flags(target->offset(),
|
||||
(StackMapFrame*)this, (StackMapFrame*)target);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
|
||||
if (_stack_size <= 0) {
|
||||
verifier()->verify_error(_offset, "Operand stack underflow");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::stack_underflow(_offset, this),
|
||||
"Operand stack underflow");
|
||||
return VerificationType::bogus_type();
|
||||
}
|
||||
VerificationType top = _stack[--_stack_size];
|
||||
bool subtype = type.is_assignable_from(
|
||||
top, verifier(), CHECK_(VerificationType::bogus_type()));
|
||||
if (!subtype) {
|
||||
verifier()->verify_error(_offset, "Bad type on operand stack");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_type(_offset, stack_top_ctx(),
|
||||
TypeOrigin::implicit(type)),
|
||||
"Bad type on operand stack");
|
||||
return VerificationType::bogus_type();
|
||||
}
|
||||
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
|
||||
return top;
|
||||
}
|
||||
|
||||
VerificationType StackMapFrame::get_local(
|
||||
int32_t index, VerificationType type, TRAPS) {
|
||||
if (index >= _max_locals) {
|
||||
verifier()->verify_error(_offset, "Local variable table overflow");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_local_index(_offset, index),
|
||||
"Local variable table overflow");
|
||||
return VerificationType::bogus_type();
|
||||
}
|
||||
bool subtype = type.is_assignable_from(_locals[index],
|
||||
verifier(), CHECK_(VerificationType::bogus_type()));
|
||||
if (!subtype) {
|
||||
verifier()->verify_error(_offset, "Bad local variable type");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_type(_offset,
|
||||
TypeOrigin::local(index, this),
|
||||
TypeOrigin::implicit(type)),
|
||||
"Bad local variable type");
|
||||
return VerificationType::bogus_type();
|
||||
}
|
||||
if(index >= _locals_size) { _locals_size = index + 1; }
|
||||
@ -264,23 +298,37 @@ void StackMapFrame::get_local_2(
|
||||
assert(type1.is_long() || type1.is_double(), "must be long/double");
|
||||
assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
|
||||
if (index >= _locals_size - 1) {
|
||||
verifier()->verify_error(_offset, "get long/double overflows locals");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_local_index(_offset, index),
|
||||
"get long/double overflows locals");
|
||||
return;
|
||||
}
|
||||
bool subtype1 = type1.is_assignable_from(
|
||||
_locals[index], verifier(), CHECK);
|
||||
bool subtype2 = type2.is_assignable_from(
|
||||
_locals[index+1], verifier(), CHECK);
|
||||
if (!subtype1 || !subtype2) {
|
||||
verifier()->verify_error(_offset, "Bad local variable type");
|
||||
return;
|
||||
bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
|
||||
if (!subtype) {
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_type(_offset,
|
||||
TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
|
||||
"Bad local variable type");
|
||||
} else {
|
||||
subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
|
||||
if (!subtype) {
|
||||
/* Unreachable? All local store routines convert a split long or double
|
||||
* into a TOP during the store. So we should never end up seeing an
|
||||
* orphaned half. */
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_type(_offset,
|
||||
TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)),
|
||||
"Bad local variable type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) {
|
||||
assert(!type.is_check(), "Must be a real type");
|
||||
if (index >= _max_locals) {
|
||||
verifier()->verify_error("Local variable table overflow", _offset);
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_local_index(_offset, index),
|
||||
"Local variable table overflow");
|
||||
return;
|
||||
}
|
||||
// If type at index is double or long, set the next location to be unusable
|
||||
@ -310,7 +358,9 @@ void StackMapFrame::set_local_2(
|
||||
assert(type1.is_long() || type1.is_double(), "must be long/double");
|
||||
assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
|
||||
if (index >= _max_locals - 1) {
|
||||
verifier()->verify_error("Local variable table overflow", _offset);
|
||||
verifier()->verify_error(
|
||||
ErrorContext::bad_local_index(_offset, index),
|
||||
"Local variable table overflow");
|
||||
return;
|
||||
}
|
||||
// If type at index+1 is double or long, set the next location to be unusable
|
||||
@ -336,21 +386,30 @@ void StackMapFrame::set_local_2(
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
void StackMapFrame::print() const {
|
||||
tty->print_cr("stackmap_frame[%d]:", _offset);
|
||||
tty->print_cr("flags = 0x%x", _flags);
|
||||
tty->print("locals[%d] = { ", _locals_size);
|
||||
for (int32_t i = 0; i < _locals_size; i++) {
|
||||
_locals[i].print_on(tty);
|
||||
}
|
||||
tty->print_cr(" }");
|
||||
tty->print("stack[%d] = { ", _stack_size);
|
||||
for (int32_t j = 0; j < _stack_size; j++) {
|
||||
_stack[j].print_on(tty);
|
||||
}
|
||||
tty->print_cr(" }");
|
||||
TypeOrigin StackMapFrame::stack_top_ctx() {
|
||||
return TypeOrigin::stack(_stack_size, this);
|
||||
}
|
||||
|
||||
#endif
|
||||
void StackMapFrame::print_on(outputStream* str) const {
|
||||
str->indent().print_cr("bci: @%d", _offset);
|
||||
str->indent().print_cr("flags: {%s }",
|
||||
flag_this_uninit() ? " flagThisUninit" : "");
|
||||
str->indent().print("locals: {");
|
||||
for (int32_t i = 0; i < _locals_size; ++i) {
|
||||
str->print(" ");
|
||||
_locals[i].print_on(str);
|
||||
if (i != _locals_size - 1) {
|
||||
str->print(",");
|
||||
}
|
||||
}
|
||||
str->print_cr(" }");
|
||||
str->indent().print("stack: {");
|
||||
for (int32_t j = 0; j < _stack_size; ++j) {
|
||||
str->print(" ");
|
||||
_stack[j].print_on(str);
|
||||
if (j != _stack_size - 1) {
|
||||
str->print(",");
|
||||
}
|
||||
}
|
||||
str->print_cr(" }");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,8 @@
|
||||
|
||||
// A StackMapFrame represents one frame in the stack map attribute.
|
||||
|
||||
class TypeContext;
|
||||
|
||||
enum {
|
||||
FLAG_THIS_UNINIT = 0x01
|
||||
};
|
||||
@ -47,6 +49,10 @@ class StackMapFrame : public ResourceObj {
|
||||
int32_t _locals_size; // number of valid type elements in _locals
|
||||
int32_t _stack_size; // number of valid type elements in _stack
|
||||
|
||||
int32_t _stack_mark; // Records the size of the stack prior to an
|
||||
// instruction modification, to allow rewinding
|
||||
// when/if an error occurs.
|
||||
|
||||
int32_t _max_locals;
|
||||
int32_t _max_stack;
|
||||
|
||||
@ -56,6 +62,31 @@ class StackMapFrame : public ResourceObj {
|
||||
|
||||
ClassVerifier* _verifier; // the verifier verifying this method
|
||||
|
||||
StackMapFrame(const StackMapFrame& cp) :
|
||||
_offset(cp._offset), _locals_size(cp._locals_size),
|
||||
_stack_size(cp._stack_size), _stack_mark(cp._stack_mark),
|
||||
_max_locals(cp._max_locals), _max_stack(cp._max_stack),
|
||||
_flags(cp._flags) {
|
||||
_locals = NEW_RESOURCE_ARRAY(VerificationType, _max_locals);
|
||||
for (int i = 0; i < _max_locals; ++i) {
|
||||
if (i < _locals_size) {
|
||||
_locals[i] = cp._locals[i];
|
||||
} else {
|
||||
_locals[i] = VerificationType::bogus_type();
|
||||
}
|
||||
}
|
||||
int ss = MAX2(_stack_size, _stack_mark);
|
||||
_stack = NEW_RESOURCE_ARRAY(VerificationType, _max_stack);
|
||||
for (int i = 0; i < _max_stack; ++i) {
|
||||
if (i < ss) {
|
||||
_stack[i] = cp._stack[i];
|
||||
} else {
|
||||
_stack[i] = VerificationType::bogus_type();
|
||||
}
|
||||
}
|
||||
_verifier = NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
// constructors
|
||||
|
||||
@ -77,16 +108,21 @@ class StackMapFrame : public ResourceObj {
|
||||
ClassVerifier* v) : _offset(offset), _flags(flags),
|
||||
_locals_size(locals_size),
|
||||
_stack_size(stack_size),
|
||||
_stack_mark(-1),
|
||||
_max_locals(max_locals),
|
||||
_max_stack(max_stack),
|
||||
_locals(locals), _stack(stack),
|
||||
_verifier(v) { }
|
||||
|
||||
static StackMapFrame* copy(StackMapFrame* smf) {
|
||||
return new StackMapFrame(*smf);
|
||||
}
|
||||
|
||||
inline void set_offset(int32_t offset) { _offset = offset; }
|
||||
inline void set_verifier(ClassVerifier* v) { _verifier = v; }
|
||||
inline void set_flags(u1 flags) { _flags = flags; }
|
||||
inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; }
|
||||
inline void set_stack_size(u2 stack_size) { _stack_size = stack_size; }
|
||||
inline void set_stack_size(u2 stack_size) { _stack_size = _stack_mark = stack_size; }
|
||||
inline void clear_stack() { _stack_size = 0; }
|
||||
inline int32_t offset() const { return _offset; }
|
||||
inline ClassVerifier* verifier() const { return _verifier; }
|
||||
@ -134,14 +170,37 @@ class StackMapFrame : public ResourceObj {
|
||||
void copy_stack(const StackMapFrame* src);
|
||||
|
||||
// Return true if this stack map frame is assignable to target.
|
||||
bool is_assignable_to(const StackMapFrame* target,
|
||||
bool is_exception_handler, TRAPS) const;
|
||||
bool is_assignable_to(
|
||||
const StackMapFrame* target, bool is_exception_handler,
|
||||
ErrorContext* ctx, TRAPS) const;
|
||||
|
||||
inline void set_mark() {
|
||||
#ifdef DEBUG
|
||||
// Put bogus type to indicate it's no longer valid.
|
||||
if (_stack_mark != -1) {
|
||||
for (int i = _stack_mark; i >= _stack_size; --i) {
|
||||
_stack[i] = VerificationType::bogus_type();
|
||||
}
|
||||
}
|
||||
#endif // def DEBUG
|
||||
_stack_mark = _stack_size;
|
||||
}
|
||||
|
||||
// Used when an error occurs and we want to reset the stack to the state
|
||||
// it was before operands were popped off.
|
||||
void restore() {
|
||||
if (_stack_mark != -1) {
|
||||
_stack_size = _stack_mark;
|
||||
}
|
||||
}
|
||||
|
||||
// Push type into stack type array.
|
||||
inline void push_stack(VerificationType type, TRAPS) {
|
||||
assert(!type.is_check(), "Must be a real type");
|
||||
if (_stack_size >= _max_stack) {
|
||||
verifier()->verify_error(_offset, "Operand stack overflow");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::stack_overflow(_offset, this),
|
||||
"Operand stack overflow");
|
||||
return;
|
||||
}
|
||||
_stack[_stack_size++] = type;
|
||||
@ -152,7 +211,9 @@ class StackMapFrame : public ResourceObj {
|
||||
assert(type1.is_long() || type1.is_double(), "must be long/double");
|
||||
assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
|
||||
if (_stack_size >= _max_stack - 1) {
|
||||
verifier()->verify_error(_offset, "Operand stack overflow");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::stack_overflow(_offset, this),
|
||||
"Operand stack overflow");
|
||||
return;
|
||||
}
|
||||
_stack[_stack_size++] = type1;
|
||||
@ -162,13 +223,12 @@ class StackMapFrame : public ResourceObj {
|
||||
// Pop and return the top type on stack without verifying.
|
||||
inline VerificationType pop_stack(TRAPS) {
|
||||
if (_stack_size <= 0) {
|
||||
verifier()->verify_error(_offset, "Operand stack underflow");
|
||||
verifier()->verify_error(
|
||||
ErrorContext::stack_underflow(_offset, this),
|
||||
"Operand stack underflow");
|
||||
return VerificationType::bogus_type();
|
||||
}
|
||||
// Put bogus type to indicate it's no longer valid.
|
||||
// Added to make it consistent with the other pop_stack method.
|
||||
VerificationType top = _stack[--_stack_size];
|
||||
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
|
||||
return top;
|
||||
}
|
||||
|
||||
@ -180,8 +240,7 @@ class StackMapFrame : public ResourceObj {
|
||||
bool subtype = type.is_assignable_from(
|
||||
top, verifier(), CHECK_(VerificationType::bogus_type()));
|
||||
if (subtype) {
|
||||
_stack_size --;
|
||||
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
|
||||
--_stack_size;
|
||||
return top;
|
||||
}
|
||||
}
|
||||
@ -199,8 +258,6 @@ class StackMapFrame : public ResourceObj {
|
||||
bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
|
||||
if (subtype1 && subtype2) {
|
||||
_stack_size -= 2;
|
||||
NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
|
||||
NOT_PRODUCT( _stack[_stack_size+1] = VerificationType::bogus_type(); )
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -208,6 +265,14 @@ class StackMapFrame : public ResourceObj {
|
||||
pop_stack_ex(type2, THREAD);
|
||||
}
|
||||
|
||||
VerificationType local_at(int index) {
|
||||
return _locals[index];
|
||||
}
|
||||
|
||||
VerificationType stack_at(int index) {
|
||||
return _stack[index];
|
||||
}
|
||||
|
||||
// Uncommon case that throws exceptions.
|
||||
VerificationType pop_stack_ex(VerificationType type, TRAPS);
|
||||
|
||||
@ -226,13 +291,14 @@ class StackMapFrame : public ResourceObj {
|
||||
|
||||
// Private auxiliary method used only in is_assignable_to(StackMapFrame).
|
||||
// Returns true if src is assignable to target.
|
||||
bool is_assignable_to(
|
||||
int is_assignable_to(
|
||||
VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
|
||||
|
||||
bool has_flag_match_exception(const StackMapFrame* target) const;
|
||||
|
||||
// Debugging
|
||||
void print() const PRODUCT_RETURN;
|
||||
TypeOrigin stack_top_ctx();
|
||||
|
||||
void print_on(outputStream* str) const;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, 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
|
||||
@ -46,7 +46,9 @@ StackMapTable::StackMapTable(StackMapReader* reader, StackMapFrame* init_frame,
|
||||
_frame_array[i] = frame;
|
||||
int offset = frame->offset();
|
||||
if (offset >= code_len || code_data[offset] == 0) {
|
||||
frame->verifier()->verify_error("StackMapTable error: bad offset");
|
||||
frame->verifier()->verify_error(
|
||||
ErrorContext::bad_stackmap(i, frame),
|
||||
"StackMapTable error: bad offset");
|
||||
return;
|
||||
}
|
||||
pre_frame = frame;
|
||||
@ -68,12 +70,9 @@ int StackMapTable::get_index_from_offset(int32_t offset) const {
|
||||
|
||||
bool StackMapTable::match_stackmap(
|
||||
StackMapFrame* frame, int32_t target,
|
||||
bool match, bool update, TRAPS) const {
|
||||
bool match, bool update, ErrorContext* ctx, TRAPS) const {
|
||||
int index = get_index_from_offset(target);
|
||||
|
||||
return match_stackmap(
|
||||
frame, target, index, match,
|
||||
update, CHECK_VERIFY_(frame->verifier(), false));
|
||||
return match_stackmap(frame, target, index, match, update, ctx, THREAD);
|
||||
}
|
||||
|
||||
// Match and/or update current_frame to the frame in stackmap table with
|
||||
@ -88,23 +87,23 @@ bool StackMapTable::match_stackmap(
|
||||
// unconditional branch: true true
|
||||
bool StackMapTable::match_stackmap(
|
||||
StackMapFrame* frame, int32_t target, int32_t frame_index,
|
||||
bool match, bool update, TRAPS) const {
|
||||
bool match, bool update, ErrorContext* ctx, TRAPS) const {
|
||||
if (frame_index < 0 || frame_index >= _frame_count) {
|
||||
frame->verifier()->verify_error(frame->offset(),
|
||||
"Expecting a stackmap frame at branch target %d", target);
|
||||
*ctx = ErrorContext::missing_stackmap(frame->offset());
|
||||
frame->verifier()->verify_error(
|
||||
*ctx, "Expecting a stackmap frame at branch target %d", target);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
StackMapFrame *stackmap_frame = _frame_array[frame_index];
|
||||
bool result = true;
|
||||
if (match) {
|
||||
// when checking handler target, match == true && update == false
|
||||
bool is_exception_handler = !update;
|
||||
// Has direct control flow from last instruction, need to match the two
|
||||
// frames.
|
||||
result = frame->is_assignable_to(
|
||||
stackmap_frame, is_exception_handler,
|
||||
CHECK_VERIFY_(frame->verifier(), false));
|
||||
result = frame->is_assignable_to(stackmap_frame, is_exception_handler,
|
||||
ctx, CHECK_VERIFY_(frame->verifier(), result));
|
||||
}
|
||||
if (update) {
|
||||
// Use the frame in stackmap table as current frame
|
||||
@ -125,11 +124,12 @@ bool StackMapTable::match_stackmap(
|
||||
|
||||
void StackMapTable::check_jump_target(
|
||||
StackMapFrame* frame, int32_t target, TRAPS) const {
|
||||
ErrorContext ctx;
|
||||
bool match = match_stackmap(
|
||||
frame, target, true, false, CHECK_VERIFY(frame->verifier()));
|
||||
frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
|
||||
if (!match || (target < 0 || target >= _code_length)) {
|
||||
frame->verifier()->verify_error(frame->offset(),
|
||||
"Inconsistent stackmap frames at branch target %d", target);
|
||||
frame->verifier()->verify_error(ctx,
|
||||
"Inconsistent stackmap frames at branch target %d", target);
|
||||
return;
|
||||
}
|
||||
// check if uninitialized objects exist on backward branches
|
||||
@ -139,25 +139,25 @@ void StackMapTable::check_jump_target(
|
||||
void StackMapTable::check_new_object(
|
||||
const StackMapFrame* frame, int32_t target, TRAPS) const {
|
||||
if (frame->offset() > target && frame->has_new_object()) {
|
||||
frame->verifier()->verify_error(frame->offset(),
|
||||
"Uninitialized object exists on backward branch %d", target);
|
||||
frame->verifier()->verify_error(
|
||||
ErrorContext::bad_code(frame->offset()),
|
||||
"Uninitialized object exists on backward branch %d", target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
void StackMapTable::print() const {
|
||||
tty->print_cr("StackMapTable: frame_count = %d", _frame_count);
|
||||
tty->print_cr("table = { ");
|
||||
for (int32_t i = 0; i < _frame_count; i++) {
|
||||
_frame_array[i]->print();
|
||||
void StackMapTable::print_on(outputStream* str) const {
|
||||
str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
|
||||
str->indent().print_cr("table = { ");
|
||||
{
|
||||
streamIndentor si(str);
|
||||
for (int32_t i = 0; i < _frame_count; ++i) {
|
||||
_frame_array[i]->print_on(str);
|
||||
}
|
||||
}
|
||||
tty->print_cr(" }");
|
||||
str->print_cr(" }");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int32_t StackMapReader::chop(
|
||||
VerificationType* locals, int32_t length, int32_t chops) {
|
||||
if (locals == NULL) return -1;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, 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,6 +26,7 @@
|
||||
#define SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP
|
||||
|
||||
#include "classfile/stackMapFrame.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "oops/constantPoolOop.hpp"
|
||||
#include "oops/methodOop.hpp"
|
||||
@ -73,12 +74,12 @@ class StackMapTable : public StackObj {
|
||||
// specified offset. Return true if the two frames match.
|
||||
bool match_stackmap(
|
||||
StackMapFrame* current_frame, int32_t offset,
|
||||
bool match, bool update, TRAPS) const;
|
||||
bool match, bool update, ErrorContext* ctx, TRAPS) const;
|
||||
// Match and/or update current_frame to the frame in stackmap table with
|
||||
// specified offset and frame index. Return true if the two frames match.
|
||||
bool match_stackmap(
|
||||
StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
|
||||
bool match, bool update, TRAPS) const;
|
||||
bool match, bool update, ErrorContext* ctx, TRAPS) const;
|
||||
|
||||
// Check jump instructions. Make sure there are no uninitialized
|
||||
// instances on backward branch.
|
||||
@ -93,8 +94,7 @@ class StackMapTable : public StackObj {
|
||||
void check_new_object(
|
||||
const StackMapFrame* frame, int32_t target, TRAPS) const;
|
||||
|
||||
// Debugging
|
||||
void print() const PRODUCT_RETURN;
|
||||
void print_on(outputStream* str) const;
|
||||
};
|
||||
|
||||
class StackMapStream : StackObj {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2012, 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
|
||||
@ -135,7 +135,6 @@ class verification_type_info {
|
||||
!is_object() && !is_uninitialized()));
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) {
|
||||
switch (tag()) {
|
||||
case ITEM_Top: st->print("Top"); break;
|
||||
@ -154,14 +153,13 @@ class verification_type_info {
|
||||
assert(false, "Bad verification_type_info");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
|
||||
macro(same_frame, arg1, arg2) \
|
||||
macro(same_frame_extended, arg1, arg2) \
|
||||
macro(same_frame_1_stack_item_frame, arg1, arg2) \
|
||||
macro(same_frame_1_stack_item_extended, arg1, arg2) \
|
||||
macro(same_locals_1_stack_item_frame, arg1, arg2) \
|
||||
macro(same_locals_1_stack_item_extended, arg1, arg2) \
|
||||
macro(chop_frame, arg1, arg2) \
|
||||
macro(append_frame, arg1, arg2) \
|
||||
macro(full_frame, arg1, arg2)
|
||||
@ -203,9 +201,8 @@ class stack_map_frame {
|
||||
// that we don't read past a particular memory limit. It returns false
|
||||
// if any part of the data structure is outside the specified memory bounds.
|
||||
inline bool verify(address start, address end) const;
|
||||
#ifdef ASSERT
|
||||
inline void print_on(outputStream* st) const;
|
||||
#endif
|
||||
|
||||
inline void print_on(outputStream* st, int current_offset) const;
|
||||
|
||||
// Create as_xxx and is_xxx methods for the subtypes
|
||||
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
|
||||
@ -263,11 +260,9 @@ class same_frame : public stack_map_frame {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("same_frame(%d)", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("same_frame(@%d)", offset_delta() + current_offset);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class same_frame_extended : public stack_map_frame {
|
||||
@ -311,14 +306,12 @@ class same_frame_extended : public stack_map_frame {
|
||||
return frame_type_addr() + size() <= end;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("same_frame_extended(%d)", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class same_frame_1_stack_item_frame : public stack_map_frame {
|
||||
class same_locals_1_stack_item_frame : public stack_map_frame {
|
||||
private:
|
||||
address type_addr() const { return frame_type_addr() + sizeof(u1); }
|
||||
|
||||
@ -332,14 +325,14 @@ class same_frame_1_stack_item_frame : public stack_map_frame {
|
||||
return tag >= 64 && tag < 128;
|
||||
}
|
||||
|
||||
static same_frame_1_stack_item_frame* at(address addr) {
|
||||
static same_locals_1_stack_item_frame* at(address addr) {
|
||||
assert(is_frame_type(*addr), "Wrong frame id");
|
||||
return (same_frame_1_stack_item_frame*)addr;
|
||||
return (same_locals_1_stack_item_frame*)addr;
|
||||
}
|
||||
|
||||
static same_frame_1_stack_item_frame* create_at(
|
||||
static same_locals_1_stack_item_frame* create_at(
|
||||
address addr, int offset_delta, verification_type_info* vti) {
|
||||
same_frame_1_stack_item_frame* sm = (same_frame_1_stack_item_frame*)addr;
|
||||
same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
|
||||
sm->set_offset_delta(offset_delta);
|
||||
if (vti != NULL) {
|
||||
sm->set_type(vti);
|
||||
@ -382,16 +375,15 @@ class same_frame_1_stack_item_frame : public stack_map_frame {
|
||||
return types()->verify(start, end);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("same_frame_1_stack_item_frame(%d,", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("same_locals_1_stack_item_frame(@%d,",
|
||||
offset_delta() + current_offset);
|
||||
types()->print_on(st);
|
||||
st->print(")");
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class same_frame_1_stack_item_extended : public stack_map_frame {
|
||||
class same_locals_1_stack_item_extended : public stack_map_frame {
|
||||
private:
|
||||
address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
|
||||
address type_addr() const { return offset_delta_addr() + sizeof(u2); }
|
||||
@ -403,15 +395,15 @@ class same_frame_1_stack_item_extended : public stack_map_frame {
|
||||
return tag == _frame_id;
|
||||
}
|
||||
|
||||
static same_frame_1_stack_item_extended* at(address addr) {
|
||||
static same_locals_1_stack_item_extended* at(address addr) {
|
||||
assert(is_frame_type(*addr), "Wrong frame id");
|
||||
return (same_frame_1_stack_item_extended*)addr;
|
||||
return (same_locals_1_stack_item_extended*)addr;
|
||||
}
|
||||
|
||||
static same_frame_1_stack_item_extended* create_at(
|
||||
static same_locals_1_stack_item_extended* create_at(
|
||||
address addr, int offset_delta, verification_type_info* vti) {
|
||||
same_frame_1_stack_item_extended* sm =
|
||||
(same_frame_1_stack_item_extended*)addr;
|
||||
same_locals_1_stack_item_extended* sm =
|
||||
(same_locals_1_stack_item_extended*)addr;
|
||||
sm->set_frame_type(_frame_id);
|
||||
sm->set_offset_delta(offset_delta);
|
||||
if (vti != NULL) {
|
||||
@ -448,13 +440,12 @@ class same_frame_1_stack_item_extended : public stack_map_frame {
|
||||
return type_addr() < end && types()->verify(start, end);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("same_frame_1_stack_item_extended(%d,", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("same_locals_1_stack_item_extended(@%d,",
|
||||
offset_delta() + current_offset);
|
||||
types()->print_on(st);
|
||||
st->print(")");
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class chop_frame : public stack_map_frame {
|
||||
@ -517,11 +508,9 @@ class chop_frame : public stack_map_frame {
|
||||
return frame_type_addr() + size() <= end;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("chop_frame(%d,%d)", offset_delta(), chops());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class append_frame : public stack_map_frame {
|
||||
@ -618,9 +607,8 @@ class append_frame : public stack_map_frame {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("append_frame(%d,", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("append_frame(@%d,", offset_delta() + current_offset);
|
||||
verification_type_info* vti = types();
|
||||
for (int i = 0; i < number_of_types(); ++i) {
|
||||
vti->print_on(st);
|
||||
@ -631,7 +619,6 @@ class append_frame : public stack_map_frame {
|
||||
}
|
||||
st->print(")");
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class full_frame : public stack_map_frame {
|
||||
@ -774,9 +761,8 @@ class full_frame : public stack_map_frame {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* st) const {
|
||||
st->print("full_frame(%d,{", offset_delta());
|
||||
void print_on(outputStream* st, int current_offset = -1) const {
|
||||
st->print("full_frame(@%d,{", offset_delta() + current_offset);
|
||||
verification_type_info* vti = locals();
|
||||
for (int i = 0; i < num_locals(); ++i) {
|
||||
vti->print_on(st);
|
||||
@ -798,7 +784,6 @@ class full_frame : public stack_map_frame {
|
||||
}
|
||||
st->print("})");
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
|
||||
@ -852,11 +837,9 @@ bool stack_map_frame::verify(address start, address end) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void stack_map_frame::print_on(outputStream* st) const {
|
||||
FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st));
|
||||
void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
|
||||
FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef VIRTUAL_DISPATCH
|
||||
#undef VOID_VIRTUAL_DISPATCH
|
||||
@ -873,16 +856,46 @@ stack_frame_type* stack_map_frame::as_##stack_frame_type() const { \
|
||||
FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
|
||||
#undef AS_SUBTYPE_DEF
|
||||
|
||||
class stack_map_table {
|
||||
private:
|
||||
address number_of_entries_addr() const {
|
||||
return (address)this;
|
||||
}
|
||||
address entries_addr() const {
|
||||
return number_of_entries_addr() + sizeof(u2);
|
||||
}
|
||||
|
||||
protected:
|
||||
// No constructors - should be 'private', but GCC issues a warning if it is
|
||||
stack_map_table() {}
|
||||
stack_map_table(const stack_map_table&) {}
|
||||
|
||||
public:
|
||||
|
||||
static stack_map_table* at(address addr) {
|
||||
return (stack_map_table*)addr;
|
||||
}
|
||||
|
||||
u2 number_of_entries() const {
|
||||
return Bytes::get_Java_u2(number_of_entries_addr());
|
||||
}
|
||||
stack_map_frame* entries() const {
|
||||
return stack_map_frame::at(entries_addr());
|
||||
}
|
||||
|
||||
void set_number_of_entries(u2 num) {
|
||||
Bytes::put_Java_u2(number_of_entries_addr(), num);
|
||||
}
|
||||
};
|
||||
|
||||
class stack_map_table_attribute {
|
||||
private:
|
||||
address name_index_addr() const {
|
||||
return (address)this; }
|
||||
address attribute_length_addr() const {
|
||||
return name_index_addr() + sizeof(u2); }
|
||||
address number_of_entries_addr() const {
|
||||
address stack_map_table_addr() const {
|
||||
return attribute_length_addr() + sizeof(u4); }
|
||||
address entries_addr() const {
|
||||
return number_of_entries_addr() + sizeof(u2); }
|
||||
|
||||
protected:
|
||||
// No constructors - should be 'private', but GCC issues a warning if it is
|
||||
@ -896,17 +909,11 @@ class stack_map_table_attribute {
|
||||
}
|
||||
|
||||
u2 name_index() const {
|
||||
return Bytes::get_Java_u2(name_index_addr()); }
|
||||
return Bytes::get_Java_u2(name_index_addr()); }
|
||||
u4 attribute_length() const {
|
||||
return Bytes::get_Java_u4(attribute_length_addr()); }
|
||||
u2 number_of_entries() const {
|
||||
return Bytes::get_Java_u2(number_of_entries_addr()); }
|
||||
stack_map_frame* entries() const {
|
||||
return stack_map_frame::at(entries_addr());
|
||||
}
|
||||
|
||||
static size_t header_size() {
|
||||
return sizeof(u2) + sizeof(u4);
|
||||
return Bytes::get_Java_u4(attribute_length_addr()); }
|
||||
stack_map_table* table() const {
|
||||
return stack_map_table::at(stack_map_table_addr());
|
||||
}
|
||||
|
||||
void set_name_index(u2 idx) {
|
||||
@ -915,9 +922,8 @@ class stack_map_table_attribute {
|
||||
void set_attribute_length(u4 len) {
|
||||
Bytes::put_Java_u4(attribute_length_addr(), len);
|
||||
}
|
||||
void set_number_of_entries(u2 num) {
|
||||
Bytes::put_Java_u2(number_of_entries_addr(), num);
|
||||
}
|
||||
};
|
||||
|
||||
#undef FOR_EACH_STACKMAP_FRAME_TYPE
|
||||
|
||||
#endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, 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
|
||||
@ -110,34 +110,34 @@ VerificationType VerificationType::get_component(ClassVerifier *context, TRAPS)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
void VerificationType::print_on(outputStream* st) const {
|
||||
switch (_u._data) {
|
||||
case Bogus: st->print(" bogus "); break;
|
||||
case Category1: st->print(" category1 "); break;
|
||||
case Category2: st->print(" category2 "); break;
|
||||
case Category2_2nd: st->print(" category2_2nd "); break;
|
||||
case Boolean: st->print(" boolean "); break;
|
||||
case Byte: st->print(" byte "); break;
|
||||
case Short: st->print(" short "); break;
|
||||
case Char: st->print(" char "); break;
|
||||
case Integer: st->print(" integer "); break;
|
||||
case Float: st->print(" float "); break;
|
||||
case Long: st->print(" long "); break;
|
||||
case Double: st->print(" double "); break;
|
||||
case Long_2nd: st->print(" long_2nd "); break;
|
||||
case Double_2nd: st->print(" double_2nd "); break;
|
||||
case Null: st->print(" null "); break;
|
||||
case Bogus: st->print("top"); break;
|
||||
case Category1: st->print("category1"); break;
|
||||
case Category2: st->print("category2"); break;
|
||||
case Category2_2nd: st->print("category2_2nd"); break;
|
||||
case Boolean: st->print("boolean"); break;
|
||||
case Byte: st->print("byte"); break;
|
||||
case Short: st->print("short"); break;
|
||||
case Char: st->print("char"); break;
|
||||
case Integer: st->print("integer"); break;
|
||||
case Float: st->print("float"); break;
|
||||
case Long: st->print("long"); break;
|
||||
case Double: st->print("double"); break;
|
||||
case Long_2nd: st->print("long_2nd"); break;
|
||||
case Double_2nd: st->print("double_2nd"); break;
|
||||
case Null: st->print("null"); break;
|
||||
case ReferenceQuery: st->print("reference type"); break;
|
||||
case Category1Query: st->print("category1 type"); break;
|
||||
case Category2Query: st->print("category2 type"); break;
|
||||
case Category2_2ndQuery: st->print("category2_2nd type"); break;
|
||||
default:
|
||||
if (is_uninitialized_this()) {
|
||||
st->print(" uninitializedThis ");
|
||||
st->print("uninitializedThis");
|
||||
} else if (is_uninitialized()) {
|
||||
st->print(" uninitialized %d ", bci());
|
||||
st->print("uninitialized %d", bci());
|
||||
} else {
|
||||
st->print(" class %s ", name()->as_klass_external_name());
|
||||
name()->print_value_on(st);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, 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
|
||||
@ -157,7 +157,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
// For reference types, store the actual Symbol
|
||||
static VerificationType reference_type(Symbol* sh) {
|
||||
assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned");
|
||||
assert(((uintptr_t)sh & 0x3) == 0, "Symbols must be aligned");
|
||||
// If the above assert fails in the future because oop* isn't aligned,
|
||||
// then this type encoding system will have to change to have a tag value
|
||||
// to descriminate between oops and primitives.
|
||||
@ -303,7 +303,7 @@ class VerificationType VALUE_OBJ_CLASS_SPEC {
|
||||
return index;
|
||||
}
|
||||
|
||||
void print_on(outputStream* st) const PRODUCT_RETURN;
|
||||
void print_on(outputStream* st) const;
|
||||
|
||||
private:
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2012, 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
|
||||
@ -88,18 +88,178 @@ class StackMapTable;
|
||||
#define CHECK_VERIFY_(verifier, result) \
|
||||
CHECK_(result)); if ((verifier)->has_error()) return (result); (0
|
||||
|
||||
class TypeOrigin VALUE_OBJ_CLASS_SPEC {
|
||||
private:
|
||||
typedef enum {
|
||||
CF_LOCALS, // Comes from the current frame locals
|
||||
CF_STACK, // Comes from the current frame expression stack
|
||||
SM_LOCALS, // Comes from stackmap locals
|
||||
SM_STACK, // Comes from stackmap expression stack
|
||||
CONST_POOL, // Comes from the constant pool
|
||||
SIG, // Comes from method signature
|
||||
IMPLICIT, // Comes implicitly from code or context
|
||||
BAD_INDEX, // No type, but the index is bad
|
||||
FRAME_ONLY, // No type, context just contains the frame
|
||||
NONE
|
||||
} Origin;
|
||||
|
||||
Origin _origin;
|
||||
u2 _index; // local, stack, or constant pool index
|
||||
StackMapFrame* _frame; // source frame if CF or SM
|
||||
VerificationType _type; // The actual type
|
||||
|
||||
TypeOrigin(
|
||||
Origin origin, u2 index, StackMapFrame* frame, VerificationType type)
|
||||
: _origin(origin), _index(index), _frame(frame), _type(type) {}
|
||||
|
||||
public:
|
||||
TypeOrigin() : _origin(NONE), _index(0), _frame(NULL) {}
|
||||
|
||||
static TypeOrigin null();
|
||||
static TypeOrigin local(u2 index, StackMapFrame* frame);
|
||||
static TypeOrigin stack(u2 index, StackMapFrame* frame);
|
||||
static TypeOrigin sm_local(u2 index, StackMapFrame* frame);
|
||||
static TypeOrigin sm_stack(u2 index, StackMapFrame* frame);
|
||||
static TypeOrigin cp(u2 index, VerificationType vt);
|
||||
static TypeOrigin signature(VerificationType vt);
|
||||
static TypeOrigin bad_index(u2 index);
|
||||
static TypeOrigin implicit(VerificationType t);
|
||||
static TypeOrigin frame(StackMapFrame* frame);
|
||||
|
||||
void reset_frame();
|
||||
void details(outputStream* ss) const;
|
||||
void print_frame(outputStream* ss) const;
|
||||
const StackMapFrame* frame() const { return _frame; }
|
||||
bool is_valid() const { return _origin != NONE; }
|
||||
u2 index() const { return _index; }
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* str) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ErrorContext VALUE_OBJ_CLASS_SPEC {
|
||||
private:
|
||||
typedef enum {
|
||||
INVALID_BYTECODE, // There was a problem with the bytecode
|
||||
WRONG_TYPE, // Type value was not as expected
|
||||
FLAGS_MISMATCH, // Frame flags are not assignable
|
||||
BAD_CP_INDEX, // Invalid constant pool index
|
||||
BAD_LOCAL_INDEX, // Invalid local index
|
||||
LOCALS_SIZE_MISMATCH, // Frames have differing local counts
|
||||
STACK_SIZE_MISMATCH, // Frames have different stack sizes
|
||||
STACK_OVERFLOW, // Attempt to push onto a full expression stack
|
||||
STACK_UNDERFLOW, // Attempt to pop and empty expression stack
|
||||
MISSING_STACKMAP, // No stackmap for this location and there should be
|
||||
BAD_STACKMAP, // Format error in stackmap
|
||||
NO_FAULT, // No error
|
||||
UNKNOWN
|
||||
} FaultType;
|
||||
|
||||
int _bci;
|
||||
FaultType _fault;
|
||||
TypeOrigin _type;
|
||||
TypeOrigin _expected;
|
||||
|
||||
ErrorContext(int bci, FaultType fault) :
|
||||
_bci(bci), _fault(fault) {}
|
||||
ErrorContext(int bci, FaultType fault, TypeOrigin type) :
|
||||
_bci(bci), _fault(fault), _type(type) {}
|
||||
ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
|
||||
_bci(bci), _fault(fault), _type(type), _expected(exp) {}
|
||||
|
||||
public:
|
||||
ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
|
||||
|
||||
static ErrorContext bad_code(u2 bci) {
|
||||
return ErrorContext(bci, INVALID_BYTECODE);
|
||||
}
|
||||
static ErrorContext bad_type(u2 bci, TypeOrigin type) {
|
||||
return ErrorContext(bci, WRONG_TYPE, type);
|
||||
}
|
||||
static ErrorContext bad_type(u2 bci, TypeOrigin type, TypeOrigin exp) {
|
||||
return ErrorContext(bci, WRONG_TYPE, type, exp);
|
||||
}
|
||||
static ErrorContext bad_flags(u2 bci, StackMapFrame* frame) {
|
||||
return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
|
||||
}
|
||||
static ErrorContext bad_flags(u2 bci, StackMapFrame* cur, StackMapFrame* sm) {
|
||||
return ErrorContext(bci, FLAGS_MISMATCH,
|
||||
TypeOrigin::frame(cur), TypeOrigin::frame(sm));
|
||||
}
|
||||
static ErrorContext bad_cp_index(u2 bci, u2 index) {
|
||||
return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
|
||||
}
|
||||
static ErrorContext bad_local_index(u2 bci, u2 index) {
|
||||
return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
|
||||
}
|
||||
static ErrorContext locals_size_mismatch(
|
||||
u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
|
||||
return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
|
||||
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
|
||||
}
|
||||
static ErrorContext stack_size_mismatch(
|
||||
u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
|
||||
return ErrorContext(bci, STACK_SIZE_MISMATCH,
|
||||
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
|
||||
}
|
||||
static ErrorContext stack_overflow(u2 bci, StackMapFrame* frame) {
|
||||
return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
|
||||
}
|
||||
static ErrorContext stack_underflow(u2 bci, StackMapFrame* frame) {
|
||||
return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
|
||||
}
|
||||
static ErrorContext missing_stackmap(u2 bci) {
|
||||
return ErrorContext(bci, MISSING_STACKMAP);
|
||||
}
|
||||
static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
|
||||
return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
|
||||
}
|
||||
|
||||
bool is_valid() const { return _fault != NO_FAULT; }
|
||||
int bci() const { return _bci; }
|
||||
|
||||
void reset_frames() {
|
||||
_type.reset_frame();
|
||||
_expected.reset_frame();
|
||||
}
|
||||
|
||||
void details(outputStream* ss, methodOop method) const;
|
||||
|
||||
#ifdef ASSERT
|
||||
void print_on(outputStream* str) const {
|
||||
str->print("error_context(%d, %d,", _bci, _fault);
|
||||
_type.print_on(str);
|
||||
str->print(",");
|
||||
_expected.print_on(str);
|
||||
str->print(")");
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void location_details(outputStream* ss, methodOop method) const;
|
||||
void reason_details(outputStream* ss) const;
|
||||
void frame_details(outputStream* ss) const;
|
||||
void bytecode_details(outputStream* ss, methodOop method) const;
|
||||
void handler_details(outputStream* ss, methodOop method) const;
|
||||
void stackmap_details(outputStream* ss, methodOop method) const;
|
||||
};
|
||||
|
||||
// A new instance of this class is created for each class being verified
|
||||
class ClassVerifier : public StackObj {
|
||||
private:
|
||||
Thread* _thread;
|
||||
GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
|
||||
|
||||
Symbol* _exception_type;
|
||||
char* _message;
|
||||
size_t _message_buffer_len;
|
||||
GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
|
||||
|
||||
ErrorContext _error_context; // contains information about an error
|
||||
|
||||
void verify_method(methodHandle method, TRAPS);
|
||||
char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
|
||||
void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS);
|
||||
void verify_exception_handler_table(u4 code_length, char* code_data,
|
||||
int& min, int& max, TRAPS);
|
||||
void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
|
||||
|
||||
VerificationType cp_ref_index_to_type(
|
||||
@ -111,10 +271,10 @@ class ClassVerifier : public StackObj {
|
||||
instanceKlassHandle this_class, klassOop target_class,
|
||||
Symbol* field_name, Symbol* field_sig, bool is_method);
|
||||
|
||||
void verify_cp_index(constantPoolHandle cp, int index, TRAPS);
|
||||
void verify_cp_type(
|
||||
int index, constantPoolHandle cp, unsigned int types, TRAPS);
|
||||
void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS);
|
||||
void verify_cp_index(u2 bci, constantPoolHandle cp, int index, TRAPS);
|
||||
void verify_cp_type(u2 bci, int index, constantPoolHandle cp,
|
||||
unsigned int types, TRAPS);
|
||||
void verify_cp_class_type(u2 bci, int index, constantPoolHandle cp, TRAPS);
|
||||
|
||||
u2 verify_stackmap_table(
|
||||
u2 stackmap_index, u2 bci, StackMapFrame* current_frame,
|
||||
@ -137,7 +297,7 @@ class ClassVerifier : public StackObj {
|
||||
constantPoolHandle cp, TRAPS);
|
||||
|
||||
void verify_invoke_init(
|
||||
RawBytecodeStream* bcs, VerificationType ref_class_type,
|
||||
RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
|
||||
StackMapFrame* current_frame, u4 code_length, bool* this_uninit,
|
||||
constantPoolHandle cp, TRAPS);
|
||||
|
||||
@ -147,10 +307,11 @@ class ClassVerifier : public StackObj {
|
||||
constantPoolHandle cp, TRAPS);
|
||||
|
||||
VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
|
||||
void verify_anewarray(
|
||||
u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS);
|
||||
void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
|
||||
StackMapFrame* current_frame, TRAPS);
|
||||
void verify_return_value(
|
||||
VerificationType return_type, VerificationType type, u2 offset, TRAPS);
|
||||
VerificationType return_type, VerificationType type, u2 offset,
|
||||
StackMapFrame* current_frame, TRAPS);
|
||||
|
||||
void verify_iload (u2 index, StackMapFrame* current_frame, TRAPS);
|
||||
void verify_lload (u2 index, StackMapFrame* current_frame, TRAPS);
|
||||
@ -189,7 +350,7 @@ class ClassVerifier : public StackObj {
|
||||
};
|
||||
|
||||
// constructor
|
||||
ClassVerifier(instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
|
||||
ClassVerifier(instanceKlassHandle klass, TRAPS);
|
||||
|
||||
// destructor
|
||||
~ClassVerifier();
|
||||
@ -207,13 +368,17 @@ class ClassVerifier : public StackObj {
|
||||
// Return status modes
|
||||
Symbol* result() const { return _exception_type; }
|
||||
bool has_error() const { return result() != NULL; }
|
||||
char* exception_message() {
|
||||
stringStream ss;
|
||||
ss.print(_message);
|
||||
_error_context.details(&ss, _method());
|
||||
return ss.as_string();
|
||||
}
|
||||
|
||||
// Called when verify or class format errors are encountered.
|
||||
// May throw an exception based upon the mode.
|
||||
void verify_error(u2 offset, const char* fmt, ...);
|
||||
void verify_error(const char* fmt, ...);
|
||||
void verify_error(ErrorContext ctx, const char* fmt, ...);
|
||||
void class_format_error(const char* fmt, ...);
|
||||
void format_error_message(const char* fmt, int offset, va_list args);
|
||||
|
||||
klassOop load_class(Symbol* name, TRAPS);
|
||||
|
||||
@ -228,10 +393,11 @@ class ClassVerifier : public StackObj {
|
||||
// their reference counts need to be decrememented when the verifier object
|
||||
// goes out of scope. Since these symbols escape the scope in which they're
|
||||
// created, we can't use a TempNewSymbol.
|
||||
Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
|
||||
Symbol* create_temporary_symbol(
|
||||
const Symbol* s, int begin, int end, TRAPS);
|
||||
Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
|
||||
|
||||
static bool _verify_verbose; // for debugging
|
||||
TypeOrigin ref_ctx(const char* str, TRAPS);
|
||||
};
|
||||
|
||||
inline int ClassVerifier::change_sig_to_verificationType(
|
||||
|
@ -829,6 +829,9 @@ class CommandLineFlags {
|
||||
product(bool, PrintGCApplicationStoppedTime, false, \
|
||||
"Print the time the application has been stopped") \
|
||||
\
|
||||
diagnostic(bool, VerboseVerification, false, \
|
||||
"Display detailed verification details") \
|
||||
\
|
||||
notproduct(uintx, ErrorHandlerTest, 0, \
|
||||
"If > 0, provokes an error after VM initialization; the value" \
|
||||
"determines which error to provoke. See test_error_handler()" \
|
||||
|
@ -465,13 +465,12 @@ static typeArrayOop insert_hole_at(
|
||||
void Relocator::adjust_stack_map_table(int bci, int delta) {
|
||||
if (method()->has_stackmap_table()) {
|
||||
typeArrayOop data = method()->stackmap_data();
|
||||
// The data in the array is a classfile representation of the stackmap
|
||||
// table attribute, less the initial u2 tag and u4 attribute_length fields.
|
||||
stack_map_table_attribute* attr = stack_map_table_attribute::at(
|
||||
(address)data->byte_at_addr(0) - (sizeof(u2) + sizeof(u4)));
|
||||
// The data in the array is a classfile representation of the stackmap table
|
||||
stack_map_table* sm_table =
|
||||
stack_map_table::at((address)data->byte_at_addr(0));
|
||||
|
||||
int count = attr->number_of_entries();
|
||||
stack_map_frame* frame = attr->entries();
|
||||
int count = sm_table->number_of_entries();
|
||||
stack_map_frame* frame = sm_table->entries();
|
||||
int bci_iter = -1;
|
||||
bool offset_adjusted = false; // only need to adjust one offset
|
||||
|
||||
@ -486,7 +485,7 @@ void Relocator::adjust_stack_map_table(int bci, int delta) {
|
||||
frame->set_offset_delta(new_offset_delta);
|
||||
} else {
|
||||
assert(frame->is_same_frame() ||
|
||||
frame->is_same_frame_1_stack_item_frame(),
|
||||
frame->is_same_locals_1_stack_item_frame(),
|
||||
"Frame must be one of the compressed forms");
|
||||
// The new delta exceeds the capacity of the 'same_frame' or
|
||||
// 'same_frame_1_stack_item_frame' frame types. We need to
|
||||
@ -513,7 +512,7 @@ void Relocator::adjust_stack_map_table(int bci, int delta) {
|
||||
if (frame->is_same_frame()) {
|
||||
same_frame_extended::create_at(frame_addr, new_offset_delta);
|
||||
} else {
|
||||
same_frame_1_stack_item_extended::create_at(
|
||||
same_locals_1_stack_item_extended::create_at(
|
||||
frame_addr, new_offset_delta, NULL);
|
||||
// the verification_info_type should already be at the right spot
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "services/memTracker.hpp"
|
||||
|
||||
volatile jint SequenceGenerator::_seq_number = 1;
|
||||
DEBUG_ONLY(jint SequenceGenerator::_max_seq_number = 1;)
|
||||
NOT_PRODUCT(jint SequenceGenerator::_max_seq_number = 1;)
|
||||
DEBUG_ONLY(volatile unsigned long SequenceGenerator::_generation = 0;)
|
||||
|
||||
jint SequenceGenerator::next() {
|
||||
@ -36,7 +36,7 @@ jint SequenceGenerator::next() {
|
||||
MemTracker::shutdown(MemTracker::NMT_sequence_overflow);
|
||||
}
|
||||
assert(seq > 0, "counter overflow");
|
||||
DEBUG_ONLY(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
|
||||
NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
|
||||
return seq;
|
||||
}
|
||||
|
||||
|
@ -51,11 +51,11 @@ class SequenceGenerator : AllStatic {
|
||||
};
|
||||
|
||||
DEBUG_ONLY(static unsigned long current_generation() { return (unsigned long)_generation; })
|
||||
DEBUG_ONLY(static jint max_seq_num() { return _max_seq_number; })
|
||||
NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
|
||||
|
||||
private:
|
||||
static volatile jint _seq_number;
|
||||
DEBUG_ONLY(static jint _max_seq_number; )
|
||||
NOT_PRODUCT(static jint _max_seq_number; )
|
||||
DEBUG_ONLY(static volatile unsigned long _generation; )
|
||||
};
|
||||
|
||||
|
@ -59,7 +59,7 @@ class MemPointerArray : public CHeapObj<mtNMT> {
|
||||
virtual size_t instance_size() const = 0;
|
||||
virtual bool shrink() = 0;
|
||||
|
||||
debug_only(virtual int capacity() const = 0;)
|
||||
NOT_PRODUCT(virtual int capacity() const = 0;)
|
||||
};
|
||||
|
||||
// Iterator interface
|
||||
@ -205,7 +205,7 @@ template <class E> class MemPointerArrayImpl : public MemPointerArray {
|
||||
return _size;
|
||||
}
|
||||
|
||||
debug_only(int capacity() const { return _max_size; })
|
||||
NOT_PRODUCT(int capacity() const { return _max_size; })
|
||||
|
||||
void clear() {
|
||||
assert(_data != NULL, "Just check");
|
||||
|
@ -73,7 +73,7 @@ template <class E, int SIZE> class FixedSizeMemPointerArray :
|
||||
return sizeof(FixedSizeMemPointerArray<E, SIZE>);
|
||||
}
|
||||
|
||||
debug_only(int capacity() const { return SIZE; })
|
||||
NOT_PRODUCT(int capacity() const { return SIZE; })
|
||||
|
||||
public:
|
||||
// implementation of public interface
|
||||
|
@ -338,15 +338,13 @@ void MemSnapshot::promote() {
|
||||
vm_itr.insert_after(cur_vm);
|
||||
}
|
||||
} else {
|
||||
#ifdef ASSERT
|
||||
// In theory, we should assert without conditions. However, in case of native
|
||||
// thread stack, NMT explicitly releases the thread stack in Thread's destructor,
|
||||
// due to platform dependent behaviors. On some platforms, we see uncommit/release
|
||||
// native thread stack, but some, we don't.
|
||||
if (!cur_vm->is_uncommit_record() && !cur_vm->is_deallocation_record()) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
#endif
|
||||
assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record(),
|
||||
err_msg("Should not reach here, pointer addr = [" INTPTR_FORMAT "], flags = [%x]",
|
||||
cur_vm->addr(), cur_vm->flags()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -406,7 +404,7 @@ void MemSnapshot::promote() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef ASSERT
|
||||
#ifndef PRODUCT
|
||||
void MemSnapshot::print_snapshot_stats(outputStream* st) {
|
||||
st->print_cr("Snapshot:");
|
||||
st->print_cr("\tMalloced: %d/%d [%5.2f%%] %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(),
|
||||
@ -434,6 +432,20 @@ void MemSnapshot::check_malloc_pointers() {
|
||||
}
|
||||
}
|
||||
|
||||
bool MemSnapshot::has_allocation_record(address addr) {
|
||||
MemPointerArrayIteratorImpl itr(_staging_area);
|
||||
MemPointerRecord* cur = (MemPointerRecord*)itr.current();
|
||||
while (cur != NULL) {
|
||||
if (cur->addr() == addr && cur->is_allocation_record()) {
|
||||
return true;
|
||||
}
|
||||
cur = (MemPointerRecord*)itr.next();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
#ifdef ASSERT
|
||||
void MemSnapshot::check_staging_data() {
|
||||
MemPointerArrayIteratorImpl itr(_staging_area);
|
||||
MemPointerRecord* cur = (MemPointerRecord*)itr.current();
|
||||
@ -447,17 +459,5 @@ void MemSnapshot::check_staging_data() {
|
||||
next = (MemPointerRecord*)itr.next();
|
||||
}
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
bool MemSnapshot::has_allocation_record(address addr) {
|
||||
MemPointerArrayIteratorImpl itr(_staging_area);
|
||||
MemPointerRecord* cur = (MemPointerRecord*)itr.current();
|
||||
while (cur != NULL) {
|
||||
if (cur->addr() == addr && cur->is_allocation_record()) {
|
||||
return true;
|
||||
}
|
||||
cur = (MemPointerRecord*)itr.next();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -63,13 +63,13 @@ class MemPointerIterator : public MemPointerArrayIteratorImpl {
|
||||
MemPointer* p1 = (MemPointer*)ptr;
|
||||
MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
|
||||
assert(!is_dup_pointer(p1, p2),
|
||||
"dup pointer");
|
||||
err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
|
||||
}
|
||||
if (_pos < _array->length() -1) {
|
||||
MemPointer* p1 = (MemPointer*)ptr;
|
||||
MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
|
||||
assert(!is_dup_pointer(p1, p2),
|
||||
"dup pointer");
|
||||
err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
|
||||
}
|
||||
return _array->insert_at(ptr, _pos);
|
||||
}
|
||||
@ -79,14 +79,14 @@ class MemPointerIterator : public MemPointerArrayIteratorImpl {
|
||||
MemPointer* p1 = (MemPointer*)ptr;
|
||||
MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
|
||||
assert(!is_dup_pointer(p1, p2),
|
||||
"dup pointer");
|
||||
err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
|
||||
}
|
||||
if (_pos < _array->length() - 1) {
|
||||
MemPointer* p1 = (MemPointer*)ptr;
|
||||
MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
|
||||
|
||||
assert(!is_dup_pointer(p1, p2),
|
||||
"dup pointer");
|
||||
err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
|
||||
}
|
||||
if (_array->insert_at(ptr, _pos + 1)) {
|
||||
_pos ++;
|
||||
|
@ -99,9 +99,11 @@ void MemTrackWorker::run() {
|
||||
}
|
||||
if (rec != NULL) {
|
||||
// merge the recorder into staging area
|
||||
bool result = snapshot->merge(rec);
|
||||
assert(result, "merge failed");
|
||||
debug_only(_merge_count ++;)
|
||||
if (!snapshot->merge(rec)) {
|
||||
MemTracker::shutdown(MemTracker::NMT_out_of_memory);
|
||||
} else {
|
||||
NOT_PRODUCT(_merge_count ++;)
|
||||
}
|
||||
MemTracker::release_thread_recorder(rec);
|
||||
} else {
|
||||
// no more recorder to merge, promote staging area
|
||||
@ -129,7 +131,7 @@ void MemTrackWorker::run() {
|
||||
}
|
||||
assert(MemTracker::shutdown_in_progress(), "just check");
|
||||
|
||||
// transites to final shutdown
|
||||
// transits to final shutdown
|
||||
MemTracker::final_shutdown();
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ MemTracker::ShutdownReason MemTracker::_reason = NMT_shutdown_none;
|
||||
int MemTracker::_thread_count = 255;
|
||||
volatile jint MemTracker::_pooled_recorder_count = 0;
|
||||
debug_only(intx MemTracker::_main_thread_tid = 0;)
|
||||
debug_only(volatile jint MemTracker::_pending_recorder_count = 0;)
|
||||
NOT_PRODUCT(volatile jint MemTracker::_pending_recorder_count = 0;)
|
||||
|
||||
void MemTracker::init_tracking_options(const char* option_line) {
|
||||
_tracking_level = NMT_off;
|
||||
@ -291,7 +291,7 @@ MemRecorder* MemTracker::get_pending_recorders() {
|
||||
(void*)cur_head)) {
|
||||
cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
|
||||
}
|
||||
debug_only(Atomic::store(0, &_pending_recorder_count));
|
||||
NOT_PRODUCT(Atomic::store(0, &_pending_recorder_count));
|
||||
return cur_head;
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ void MemTracker::enqueue_pending_recorder(MemRecorder* rec) {
|
||||
cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
|
||||
rec->set_next(cur_head);
|
||||
}
|
||||
debug_only(Atomic::inc(&_pending_recorder_count);)
|
||||
NOT_PRODUCT(Atomic::inc(&_pending_recorder_count);)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -184,7 +184,6 @@ class MemTracker : AllStatic {
|
||||
// record a 'malloc' call
|
||||
static inline void record_malloc(address addr, size_t size, MEMFLAGS flags,
|
||||
address pc = 0, Thread* thread = NULL) {
|
||||
assert(is_on(), "check by caller");
|
||||
if (NMT_CAN_TRACK(flags)) {
|
||||
create_memory_record(addr, (flags|MemPointerRecord::malloc_tag()), size, pc, thread);
|
||||
}
|
||||
@ -285,7 +284,6 @@ class MemTracker : AllStatic {
|
||||
|
||||
// retrieve global snapshot
|
||||
static MemSnapshot* get_snapshot() {
|
||||
assert(is_on(), "native memory tracking is off");
|
||||
if (shutdown_in_progress()) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -237,8 +237,9 @@ void outputStream::date_stamp(bool guard,
|
||||
return;
|
||||
}
|
||||
|
||||
void outputStream::indent() {
|
||||
outputStream& outputStream::indent() {
|
||||
while (_position < _indentation) sp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void outputStream::print_jlong(jlong value) {
|
||||
@ -251,6 +252,47 @@ void outputStream::print_julong(julong value) {
|
||||
print(os::julong_format_specifier(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
|
||||
* <hex-address>: 8 * <hex-halfword> <ascii translation (optional)>
|
||||
* example:
|
||||
* 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000 .DOF............
|
||||
* 0000010: 0000 0000 0000 0040 0000 0020 0000 0005 .......@... ....
|
||||
* 0000020: 0000 0000 0000 0040 0000 0000 0000 015d .......@.......]
|
||||
* ...
|
||||
*
|
||||
* indent is applied to each line. Ends with a CR.
|
||||
*/
|
||||
void outputStream::print_data(void* data, size_t len, bool with_ascii) {
|
||||
size_t limit = (len + 16) / 16 * 16;
|
||||
for (size_t i = 0; i < limit; ++i) {
|
||||
if (i % 16 == 0) {
|
||||
indent().print("%07x:", i);
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
print(" ");
|
||||
}
|
||||
if (i < len) {
|
||||
print("%02x", ((unsigned char*)data)[i]);
|
||||
} else {
|
||||
print(" ");
|
||||
}
|
||||
if ((i + 1) % 16 == 0) {
|
||||
if (with_ascii) {
|
||||
print(" ");
|
||||
for (size_t j = 0; j < 16; ++j) {
|
||||
size_t idx = i + j - 15;
|
||||
if (idx < len) {
|
||||
char c = ((char*)data)[idx];
|
||||
print("%c", c >= 32 && c <= 126 ? c : '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
print_cr("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stringStream::stringStream(size_t initial_size) : outputStream() {
|
||||
buffer_length = initial_size;
|
||||
buffer = NEW_RESOURCE_ARRAY(char, buffer_length);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, 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
|
||||
@ -59,9 +59,11 @@ class outputStream : public ResourceObj {
|
||||
outputStream(int width, bool has_time_stamps);
|
||||
|
||||
// indentation
|
||||
void indent();
|
||||
outputStream& indent();
|
||||
void inc() { _indentation++; };
|
||||
void dec() { _indentation--; };
|
||||
void inc(int n) { _indentation += n; };
|
||||
void dec(int n) { _indentation -= n; };
|
||||
int indentation() const { return _indentation; }
|
||||
void set_indentation(int i) { _indentation = i; }
|
||||
void fill_to(int col);
|
||||
@ -84,6 +86,7 @@ class outputStream : public ResourceObj {
|
||||
void print_raw(const char* str, int len) { write(str, len); }
|
||||
void print_raw_cr(const char* str) { write(str, strlen(str)); cr(); }
|
||||
void print_raw_cr(const char* str, int len){ write(str, len); cr(); }
|
||||
void print_data(void* data, size_t len, bool with_ascii);
|
||||
void put(char ch);
|
||||
void sp(int count = 1);
|
||||
void cr();
|
||||
@ -122,6 +125,19 @@ class outputStream : public ResourceObj {
|
||||
extern outputStream* tty; // tty output
|
||||
extern outputStream* gclog_or_tty; // stream for gc log if -Xloggc:<f>, or tty
|
||||
|
||||
class streamIndentor : public StackObj {
|
||||
private:
|
||||
outputStream* _str;
|
||||
int _amount;
|
||||
|
||||
public:
|
||||
streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) {
|
||||
_str->inc(_amount);
|
||||
}
|
||||
~streamIndentor() { _str->dec(_amount); }
|
||||
};
|
||||
|
||||
|
||||
// advisory locking for the shared tty stream:
|
||||
class ttyLocker: StackObj {
|
||||
friend class ttyUnlocker;
|
||||
|
@ -21,7 +21,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
|
@ -9,7 +9,7 @@
|
||||
## skip on windows
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
|
@ -49,7 +49,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
|
@ -28,7 +28,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
|
@ -27,17 +27,10 @@ case "$OS" in
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
SunOS | Windows_* | *BSD)
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
* )
|
||||
echo "Test passed; only valid for Linux"
|
||||
exit 0;
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# Choose arch: i386 or amd64 (test is Linux-specific)
|
||||
|
@ -43,7 +43,7 @@ fi
|
||||
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
FS="/"
|
||||
;;
|
||||
Windows_* )
|
||||
|
@ -37,7 +37,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
FS="/"
|
||||
RM=/bin/rm
|
||||
CP=/bin/cp
|
||||
|
486
hotspot/test/runtime/7116786/Test7116786.java
Normal file
486
hotspot/test/runtime/7116786/Test7116786.java
Normal file
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 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 Test7116786
|
||||
* @summary verify that VerifyError messages are as expected
|
||||
* @library testcases.jar
|
||||
* @run main/othervm -Xverify:all Test7116786
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* This class contains information regarding when a VerifyError is thrown
|
||||
* in the verifier. Most of the data is informational-only, and can be
|
||||
* used to track down where and why VerifyErrors are thrown. As such it
|
||||
* is possible the information may go out-of-date.
|
||||
*
|
||||
* The only fields used for the purpose of testing is the 'caseName' and
|
||||
* the 'message'. The 'caseName' corresponds to a classfile which exhibits
|
||||
* the VerifyError, and the 'message' is a regular expression which we expect
|
||||
* to match the verify error message. If the 'message' doesn't match what
|
||||
* we expect, it warrents investigation to see if we are still triggering
|
||||
* the VerifyError that we expect. It could simply just be that the message
|
||||
* changed, which is fine.
|
||||
*
|
||||
* Some cases are not testable, either because the code is probably unreachable
|
||||
* or the test classfile would be too onerous to create. These cases are
|
||||
* marked with 'testable' == false, and the test runner will skip them.
|
||||
*/
|
||||
class Case {
|
||||
private String caseName; // Name of the case
|
||||
private String file; // Source file where VerifyError is thrown
|
||||
private String location; // enclosing function or switch case
|
||||
private String description; // What causes this VerifyError
|
||||
private String message; // The VerifyError message used.
|
||||
|
||||
private boolean testable; // Whether this case is testable or not.
|
||||
|
||||
public Case(String caseName, String file, boolean testable,
|
||||
String location, String description, String message) {
|
||||
this.caseName = caseName;
|
||||
this.file = file;
|
||||
this.testable = testable;
|
||||
this.location = location;
|
||||
this.description = description;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
String getCaseName() { return this.caseName; }
|
||||
String getFile() { return this.file; }
|
||||
String getLocation() { return this.location; }
|
||||
String getDescription() { return this.description; }
|
||||
String getMessage() { return this.message; }
|
||||
|
||||
boolean isTestable() { return this.testable; }
|
||||
}
|
||||
|
||||
/**
|
||||
* These are the locations in the source code where VerifyErrors are thrown
|
||||
* as of today, 2012/07/18. These may change as the verification code is
|
||||
* modified, which is ok. This test is trying to provide coverage for all
|
||||
* VerifyErrors (just to make sure there are no crashes) and it's probably
|
||||
* not necessary to update it every time the VM changes.
|
||||
*/
|
||||
class VerifyErrorCases {
|
||||
public static final Case[] cases = {
|
||||
|
||||
new Case("case00", "stackMapFrame.cpp", true, "pop_stack_ex",
|
||||
"stack underflow",
|
||||
"Operand stack underflow"),
|
||||
|
||||
new Case("case01", "stackMapFrame.cpp", true, "pop_stack_ex",
|
||||
"stack pop not assignable to expected",
|
||||
"Bad type on operand stack"),
|
||||
|
||||
new Case("case02", "stackMapFrame.cpp", true, "get_local",
|
||||
"local index out-of-bounds",
|
||||
"Local variable table overflow"),
|
||||
|
||||
new Case("case03", "stackMapFrame.cpp", true, "get_local",
|
||||
"local not assignable to expected",
|
||||
"Bad local variable type"),
|
||||
|
||||
new Case("case04", "stackMapFrame.cpp", true, "get_local_2",
|
||||
"local index out-of-bounds [type2]",
|
||||
"get long/double overflows locals"),
|
||||
|
||||
new Case("case05", "stackMapFrame.cpp", true, "get_local_2",
|
||||
"local not assignabled to expected [type2]",
|
||||
"Bad local variable type"),
|
||||
|
||||
/* Unreachable: Can't split long/double on stack */
|
||||
new Case("case06", "stackMapFrame.cpp", false, "get_local_2",
|
||||
"local second-word not assignabled to expected",
|
||||
"Bad local variable type"),
|
||||
|
||||
new Case("case07", "stackMapFrame.cpp", true, "set_local",
|
||||
"local index out-of-bounds",
|
||||
"Local variable table overflow"),
|
||||
|
||||
new Case("case08", "stackMapFrame.cpp", true, "set_local_2",
|
||||
"local index out-of-bounds [type2]",
|
||||
"Local variable table overflow"),
|
||||
|
||||
new Case("case09", "stackMapFrame.hpp", true, "push_stack",
|
||||
"stack overflow",
|
||||
"Operand stack overflow"),
|
||||
|
||||
new Case("case10", "stackMapFrame.hpp", true, "push_stack_2",
|
||||
"stack overflow [type2]",
|
||||
"Operand stack overflow"),
|
||||
|
||||
new Case("case11", "stackMapFrame.hpp", true, "pop_stack",
|
||||
"stack underflow",
|
||||
"Operand stack underflow"),
|
||||
|
||||
new Case("case12", "stackMapTable.cpp", true, "StackMapTable ctor",
|
||||
"stackmap offset beyond code size",
|
||||
"StackMapTable error: bad offset"),
|
||||
|
||||
new Case("case13", "stackMapTable.cpp", true, "match_stackmap",
|
||||
"no stackmap frame at expected location",
|
||||
"Expecting a stackmap frame at branch target "),
|
||||
|
||||
new Case("case14", "stackMapTable.cpp", true, "check_jump_target",
|
||||
"no stackmap frame at jump location or bad jump",
|
||||
"Inconsistent stackmap frames at branch target "),
|
||||
|
||||
new Case("case15", "stackMapTable.cpp", true, "check_new_object",
|
||||
"backward jump with uninit",
|
||||
"Uninitialized object exists on backward branch "),
|
||||
|
||||
/* Unreachable: wide instructions verified during bytecode analysis */
|
||||
new Case("case16", "verifier.cpp", false, "loop header",
|
||||
"bad op in wide instruction",
|
||||
"Bad wide instruction"),
|
||||
|
||||
new Case("case17", "verifier.cpp", true, "case iaload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in iaload"),
|
||||
|
||||
new Case("case18", "verifier.cpp", true, "case baload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in baload"),
|
||||
|
||||
new Case("case19", "verifier.cpp", true, "case caload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in caload"),
|
||||
|
||||
new Case("case20", "verifier.cpp", true, "case saload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in saload"),
|
||||
|
||||
new Case("case21", "verifier.cpp", true, "case laload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in laload"),
|
||||
|
||||
new Case("case22", "verifier.cpp", true, "case faload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in faload"),
|
||||
|
||||
new Case("case23", "verifier.cpp", true, "case daload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in daload"),
|
||||
|
||||
new Case("case24", "verifier.cpp", true, "case aaload",
|
||||
"TOS not X array",
|
||||
"Bad type on operand stack in aaload"),
|
||||
|
||||
new Case("case25", "verifier.cpp", true, "case iastore",
|
||||
"TOS not int array",
|
||||
"Bad type on operand stack in iastore"),
|
||||
|
||||
new Case("case26", "verifier.cpp", true, "case bastore",
|
||||
"TOS not byte array",
|
||||
"Bad type on operand stack in bastore"),
|
||||
|
||||
new Case("case27", "verifier.cpp", true, "case castore",
|
||||
"TOS not char array",
|
||||
"Bad type on operand stack in castore"),
|
||||
|
||||
new Case("case28", "verifier.cpp", true, "case sastore",
|
||||
"TOS not short array",
|
||||
"Bad type on operand stack in sastore"),
|
||||
|
||||
new Case("case29", "verifier.cpp", true, "case lastore",
|
||||
"TOS not long array",
|
||||
"Bad type on operand stack in lastore"),
|
||||
|
||||
new Case("case30", "verifier.cpp", true, "case fastore",
|
||||
"TOS not float array",
|
||||
"Bad type on operand stack in fastore"),
|
||||
|
||||
new Case("case31", "verifier.cpp", true, "case dastore",
|
||||
"TOS not double array",
|
||||
"Bad type on operand stack in dastore"),
|
||||
|
||||
new Case("case32", "verifier.cpp", true, "case aastore",
|
||||
"TOS not object array",
|
||||
"Bad type on operand stack in aastore"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at TOS which is not possible. */
|
||||
new Case("case33", "verifier.cpp", false, "case pop2",
|
||||
"TOS is category2_1st (would split)",
|
||||
"Bad type on operand stack in pop2"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at stack depth 2 with category_1 on TOS which is not
|
||||
* possible. */
|
||||
new Case("case34", "verifier.cpp", false, "case dup_x2",
|
||||
"TOS-1 is category2_1st (would split)",
|
||||
"Bad type on operand stack in dup_x2"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at TOS which is not possible. */
|
||||
new Case("case35", "verifier.cpp", false, "case dup2",
|
||||
"TOS-1 is category2_1st (would split)",
|
||||
"Bad type on operand stack in dup2"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at TOS which is not possible. */
|
||||
new Case("case36", "verifier.cpp", false, "case dup2_x1",
|
||||
"TOS-1 is category2_1st (would split)",
|
||||
"Bad type on operand stack in dup2_x1"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at TOS which is not possible. */
|
||||
new Case("case37", "verifier.cpp", false, "case dup2_x2",
|
||||
"TOS-1 is category2_1st (would split)",
|
||||
"Bad type on operand stack in dup2_x2"),
|
||||
|
||||
/* Unreachable: In order to hit this case, we would need a
|
||||
* category2_1st at stack depth 3 with either 2 category_1 or 1
|
||||
* category_2 on TOS, which is not possible. */
|
||||
new Case("case38", "verifier.cpp", false, "case dup2_x2",
|
||||
"TOS-3 is category2_1st (would split)",
|
||||
"Bad type on operand stack in dup2_x2"),
|
||||
|
||||
new Case("case39", "verifier.cpp", true, "case return",
|
||||
"return type of method is not void",
|
||||
"Method expects a return value"),
|
||||
|
||||
new Case("case40", "verifier.cpp", true, "case return",
|
||||
"return with uninitialized this ",
|
||||
"Constructor must call super() or this() before return"),
|
||||
|
||||
new Case("case41", "verifier.cpp", true, "case new",
|
||||
"cp index not a class type",
|
||||
"Illegal new instruction"),
|
||||
|
||||
new Case("case42", "verifier.cpp", true, "case arraylength",
|
||||
"TOS is not an array",
|
||||
"Bad type on operand stack in arraylength"),
|
||||
|
||||
new Case("case43", "verifier.cpp", true, "case multianewarray",
|
||||
"CP index does not refer to array type",
|
||||
"Illegal constant pool index in multianewarray instruction"),
|
||||
|
||||
new Case("case44", "verifier.cpp", true, "case multianewarray",
|
||||
"Bad dimension (<1) or does not match CP signature",
|
||||
"Illegal dimension in multianewarray instruction: "),
|
||||
|
||||
new Case("case45", "verifier.cpp", true, "case default",
|
||||
"Unrecognized bytecode",
|
||||
"Bad instruction: "),
|
||||
|
||||
new Case("case46", "verifier.cpp", true, "loop end",
|
||||
"control flow falls off method",
|
||||
"Control flow falls through code end"),
|
||||
|
||||
new Case("case47", "verifier.cpp", true, "generate_code_data",
|
||||
"illegal bytecode via RawBytecodeStream (breakpoint)",
|
||||
"Bad instruction"),
|
||||
|
||||
new Case("case48", "verifier.cpp", true, "generate_code_data",
|
||||
"illegal bytecode via RawBytecodeStream (other illegal)",
|
||||
"Bad instruction"),
|
||||
|
||||
new Case("case49", "verifier.cpp", true,
|
||||
"verify_exception_handler_table",
|
||||
"catch_type is not throwable",
|
||||
"Catch type is not a subclass of Throwable in " +
|
||||
"exception handler "),
|
||||
|
||||
new Case("case50", "verifier.cpp", true, "verify_stackmap_table",
|
||||
"missing a stack map frame @ target location (mid table)",
|
||||
"Expecting a stack map frame"),
|
||||
|
||||
new Case("case51", "verifier.cpp", true, "verify_stackmap_table",
|
||||
"stack map does not match?",
|
||||
"Instruction type does not match stack map"),
|
||||
|
||||
new Case("case52", "verifier.cpp", true, "verify_stackmap_table",
|
||||
"missing a stack map frame @ target location (end of table)",
|
||||
"Expecting a stack map frame"),
|
||||
|
||||
new Case("case53", "verifier.cpp", true,
|
||||
"verify_exception_handler_targets",
|
||||
"stackmap mismatch at exception handler",
|
||||
"Stack map does not match the one at exception handler "),
|
||||
|
||||
new Case("case54", "verifier.cpp", true, "verify_cp_index",
|
||||
"constant pool index is out-of-bounds",
|
||||
"Illegal constant pool index "),
|
||||
|
||||
new Case("case55", "verifier.cpp", true, "verify_cp_type",
|
||||
"constant pool entry is not expected type",
|
||||
"Illegal type at constant pool entry "),
|
||||
|
||||
new Case("case56", "verifier.cpp", true, "verify_cp_class_type",
|
||||
"constant pool entry is not an object type",
|
||||
"Illegal type at constant pool entry "),
|
||||
|
||||
/* Unreachable: verify_cp_type gates this case */
|
||||
new Case("case57", "verifier.cpp", false, "verify_ldc",
|
||||
"invalid constant pool index in ldc",
|
||||
"Invalid index in ldc"),
|
||||
|
||||
new Case("case58", "verifier.cpp", true, "verify_switch",
|
||||
"bad switch padding",
|
||||
"Nonzero padding byte in lookswitch or tableswitch"),
|
||||
|
||||
new Case("case59", "verifier.cpp", true, "verify_switch",
|
||||
"tableswitch low is greater than high",
|
||||
"low must be less than or equal to high in tableswitch"),
|
||||
|
||||
/* Unreachable on 64-bit? Only way to get here is to overflow
|
||||
* the 'keys' variable which can't happen on 64-bit since we're dealing
|
||||
* with 32-bit values. Perhaps reachable on 32-bit but the
|
||||
* triggering class would be quite large */
|
||||
new Case("case60", "verifier.cpp", false, "verify_switch",
|
||||
"high - low + 1 < 0 (overflow?)",
|
||||
"too many keys in tableswitch"),
|
||||
|
||||
/* Would have to create a 16G classfile to trip this. Possible but
|
||||
* not reasonable to do in a test. */
|
||||
new Case("case61", "verifier.cpp", false, "verify_switch",
|
||||
"lookupswitch keys < 0",
|
||||
"number of keys in lookupswitch less than 0"),
|
||||
|
||||
new Case("case62", "verifier.cpp", true, "verify_switch",
|
||||
"lookupswitch keys out-of-order",
|
||||
"Bad lookupswitch instruction"),
|
||||
|
||||
/* Unreachable: Class file parser verifies Fieldref contents */
|
||||
new Case("case63", "verifier.cpp", false, "verify_field_instructions",
|
||||
"referenced class is not an CP object",
|
||||
"Expecting reference to class in class "),
|
||||
|
||||
new Case("case64", "verifier.cpp", true, "verify_field_instructions",
|
||||
"TOS not assignable to field type in putfield",
|
||||
"Bad type on operand stack in putfield"),
|
||||
|
||||
new Case("case65", "verifier.cpp", true, "verify_field_instructions",
|
||||
"TOS not assignable to class when accessing protected field",
|
||||
"Bad access to protected data in getfield"),
|
||||
|
||||
new Case("case66", "verifier.cpp", true, "verify_invoke_init",
|
||||
"Uninit_this is not of the current type or it's supertype",
|
||||
"Bad <init> method call"),
|
||||
|
||||
/* Unreachable: Stack map parsing ensures valid type and new
|
||||
* instructions have a valid BCI. */
|
||||
new Case("case67", "verifier.cpp", false, "verify_invoke_init",
|
||||
"Uninit type with bad new instruction index",
|
||||
"Expecting new instruction"),
|
||||
|
||||
new Case("case68", "verifier.cpp", true, "verify_invoke_init",
|
||||
"calling other class's <init> method",
|
||||
"Call to wrong <init> method"),
|
||||
|
||||
new Case("case69", "verifier.cpp", true, "verify_invoke_init",
|
||||
"Calling protected <init> and type unassignable from current",
|
||||
"Bad access to protected <init> method"),
|
||||
|
||||
new Case("case70", "verifier.cpp", true, "verify_invoke_init",
|
||||
"TOS is not an uninitialized (or Uninit_this) type",
|
||||
"Bad operand type when invoking <init>"),
|
||||
|
||||
new Case("case71", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"Arg count in instruction doesn't match signature",
|
||||
"Inconsistent args count operand in invokeinterface"),
|
||||
|
||||
new Case("case72", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"Non-zero pad in invokeinterface",
|
||||
"Fourth operand byte of invokeinterface must be zero"),
|
||||
|
||||
new Case("case73", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"Non-zero pad in invokedynamic",
|
||||
"Third and fourth operand bytes of " +
|
||||
"invokedynamic must be zero"),
|
||||
|
||||
new Case("case74", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"Non-invokespecial trying to invoke a '<' method",
|
||||
"Illegal call to internal method"),
|
||||
|
||||
new Case("case75", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"invokespecial and current unassignable from referenced type",
|
||||
"Bad invokespecial instruction: current class isn't " +
|
||||
"assignable to reference class."),
|
||||
|
||||
new Case("case76", "verifier.cpp", true, "verify_invoke_instructions",
|
||||
"TOS not assignable to current when calling protected method",
|
||||
"Bad access to protected data in invokevirtual"),
|
||||
|
||||
/* Unreachable: class file parser enforces void signature */
|
||||
new Case("case77", "verifier.cpp", false, "verify_invoke_instructions",
|
||||
"<init> method is not void return",
|
||||
"Return type must be void in <init> method"),
|
||||
|
||||
new Case("case78", "verifier.cpp", true, "get_newarray_type",
|
||||
"newarray type invalid",
|
||||
"Illegal newarray instruction"),
|
||||
|
||||
new Case("case79", "verifier.cpp", true, "verify_return_value",
|
||||
"void return from method which has a return value",
|
||||
"Method expects a return value"),
|
||||
|
||||
new Case("case80", "verifier.cpp", true, "verify_return_value",
|
||||
"TOS type does not match signature",
|
||||
"Bad return type"),
|
||||
|
||||
new Case("case81", "verifier.cpp", true, "verify_stackmap_table",
|
||||
"stack map does not match (flags)",
|
||||
"Instruction type does not match stack map")
|
||||
};
|
||||
}
|
||||
|
||||
public class Test7116786 {
|
||||
public static void main(String argv[]) throws Exception {
|
||||
for (Case c : VerifyErrorCases.cases) {
|
||||
System.out.println("******** " + c.getCaseName() + " ********");
|
||||
if (c.isTestable()) {
|
||||
try {
|
||||
ClassLoader cl = Test7116786.class.getClassLoader();
|
||||
Class<?> cls = Class.forName(c.getCaseName(), true, cl);
|
||||
throw new RuntimeException(
|
||||
"++ FAIL: No verify error encountered");
|
||||
} catch (VerifyError ve) {
|
||||
String message = c.getMessage();
|
||||
String veMessage = ve.getMessage();
|
||||
System.out.print(veMessage);
|
||||
if (!veMessage.startsWith(message)) {
|
||||
// We're not seeing the message we expect. Could be
|
||||
// that we've gotten the wrong VerifyError case, or
|
||||
// maybe the message changed.
|
||||
System.out.println("++ FAIL? " +
|
||||
"Message does not match what was expected: " +
|
||||
message);
|
||||
continue;
|
||||
}
|
||||
if (!veMessage.contains("Exception Details:") &&
|
||||
!veMessage.contains("Reason:")) {
|
||||
System.out.println("++ FAIL: No details found");
|
||||
throw new RuntimeException("FAIL: No details found");
|
||||
}
|
||||
System.out.println("++ PASS");
|
||||
}
|
||||
} else {
|
||||
System.out.println("++ SKIPPED");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
hotspot/test/runtime/7116786/testcases.jar
Normal file
BIN
hotspot/test/runtime/7116786/testcases.jar
Normal file
Binary file not shown.
@ -46,7 +46,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
@ -67,13 +67,13 @@ CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
|
||||
|
||||
THIS_DIR=`pwd`
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java -fullversion
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}InternTest.java
|
||||
|
||||
cp ${TESTSRC}${FS}badstrings.txt .
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java -XX:+PrintStringTableStatistics -XX:+TraceSafepointCleanupTime InternTest bad > test.out 2>&1 &
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -XX:+PrintStringTableStatistics -XX:+TraceSafepointCleanupTime InternTest bad > test.out 2>&1 &
|
||||
C_PID=$!
|
||||
|
||||
sleep 60
|
||||
|
@ -21,7 +21,7 @@ fi
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
SunOS | Linux | Darwin)
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
@ -52,30 +52,7 @@ ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}javac -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar *.java
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out 2>&1 &
|
||||
|
||||
P_PID=$!
|
||||
|
||||
sleep 60
|
||||
STATUS=0
|
||||
|
||||
case "$OS" in
|
||||
SunOS | Linux )
|
||||
ps -ef | grep $P_PID | grep -v grep > ${NULL}
|
||||
if [ $? = 0 ]; then
|
||||
kill -9 $P_PID
|
||||
STATUS=1
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
ps | grep -i "FieldMonitor" | grep -v grep > ${NULL}
|
||||
if [ $? = 0 ]; then
|
||||
C_PID=`ps | grep -i "FieldMonitor" | awk '{print $1}'`
|
||||
kill -s 9 $C_PID
|
||||
STATUS=1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out
|
||||
|
||||
grep "A fatal error has been detected" test.out > ${NULL}
|
||||
if [ $? = 0 ]; then
|
||||
|
Loading…
Reference in New Issue
Block a user