This commit is contained in:
Daniel D. Daugherty 2012-08-17 11:57:46 -07:00
commit 9d85b8e187
41 changed files with 1757 additions and 594 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(" }");
}

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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()" \

View File

@ -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
}

View File

@ -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;
}

View File

@ -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; )
};

View File

@ -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");

View File

@ -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

View File

@ -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

View File

@ -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 ++;

View File

@ -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();
}

View File

@ -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);)
}
/*

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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="/"

View File

@ -9,7 +9,7 @@
## skip on windows
OS=`uname -s`
case "$OS" in
SunOS | Linux )
SunOS | Linux | Darwin )
NULL=/dev/null
PS=":"
FS="/"

View File

@ -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="/"

View File

@ -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="/"

View File

@ -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)

View File

@ -43,7 +43,7 @@ fi
OS=`uname -s`
case "$OS" in
SunOS | Linux )
SunOS | Linux | Darwin )
FS="/"
;;
Windows_* )

View File

@ -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

View 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");
}
}
}
}

Binary file not shown.

View File

@ -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

View File

@ -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