aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrims <none@none>2008-11-21 16:11:03 -0800
committertrims <none@none>2008-11-21 16:11:03 -0800
commit628fb3827c4f7c2d49153a64460003f7c7a525a4 (patch)
treeaafc18cb7f4f49b6c65ebb30ebafa2dc73eb7a2a
parent14a97d494e6488d1a42bbe60815aa3acdf24c403 (diff)
parentffe2d1a801021e54d5505dc437b32221952317a7 (diff)
Merge
-rw-r--r--make/linux/makefiles/top.make4
-rw-r--r--make/solaris/makefiles/amd64.make5
-rw-r--r--make/solaris/makefiles/debug.make2
-rw-r--r--make/solaris/makefiles/dtrace.make35
-rw-r--r--make/solaris/makefiles/fastdebug.make42
-rw-r--r--make/solaris/makefiles/i486.make10
-rw-r--r--make/solaris/makefiles/jvmg.make2
-rw-r--r--make/solaris/makefiles/optimized.make6
-rw-r--r--make/solaris/makefiles/product.make6
-rw-r--r--make/solaris/makefiles/sparc.make4
-rw-r--r--make/solaris/makefiles/sparcWorks.make46
-rw-r--r--make/solaris/makefiles/sparcv9.make2
-rw-r--r--make/solaris/makefiles/top.make4
-rw-r--r--make/solaris/makefiles/vm.make2
-rw-r--r--make/windows/makefiles/adlc.make6
-rw-r--r--make/windows/makefiles/compile.make34
-rw-r--r--make/windows/makefiles/debug.make6
-rw-r--r--make/windows/makefiles/defs.make8
-rw-r--r--make/windows/makefiles/fastdebug.make7
-rw-r--r--make/windows/makefiles/product.make6
-rw-r--r--make/windows/makefiles/sa.make10
-rw-r--r--make/windows/projectfiles/common/Makefile3
-rw-r--r--src/cpu/x86/vm/register_definitions_x86.cpp3
-rw-r--r--src/os/solaris/vm/os_solaris.cpp1
-rw-r--r--src/share/vm/adlc/archDesc.cpp6
-rw-r--r--src/share/vm/c1/c1_IR.cpp13
-rw-r--r--src/share/vm/ci/ciEnv.cpp15
-rw-r--r--src/share/vm/classfile/classFileParser.cpp177
-rw-r--r--src/share/vm/classfile/classFileParser.hpp38
-rw-r--r--src/share/vm/classfile/systemDictionary.cpp28
-rw-r--r--src/share/vm/classfile/systemDictionary.hpp10
-rw-r--r--src/share/vm/classfile/verifier.cpp6
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp314
-rw-r--r--src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp167
-rw-r--r--src/share/vm/gc_implementation/g1/ptrQueue.cpp5
-rw-r--r--src/share/vm/gc_implementation/g1/ptrQueue.hpp4
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp14
-rw-r--r--src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp22
-rw-r--r--src/share/vm/includeDB_gc_parallel6
-rw-r--r--src/share/vm/memory/space.cpp4
-rw-r--r--src/share/vm/memory/space.hpp8
-rw-r--r--src/share/vm/memory/tenuredGeneration.hpp1
-rw-r--r--src/share/vm/oops/constantPoolKlass.cpp42
-rw-r--r--src/share/vm/oops/constantPoolOop.cpp29
-rw-r--r--src/share/vm/oops/constantPoolOop.hpp36
-rw-r--r--src/share/vm/oops/instanceKlass.hpp10
-rw-r--r--src/share/vm/oops/instanceKlassKlass.cpp23
-rw-r--r--src/share/vm/oops/klass.cpp18
-rw-r--r--src/share/vm/opto/c2_globals.hpp4
-rw-r--r--src/share/vm/opto/macro.cpp1
-rw-r--r--src/share/vm/opto/parse.hpp2
-rw-r--r--src/share/vm/prims/jvm.cpp3
-rw-r--r--src/share/vm/prims/jvm.h8
-rw-r--r--src/share/vm/prims/unsafe.cpp169
-rw-r--r--src/share/vm/runtime/globals.hpp9
-rw-r--r--src/share/vm/runtime/perfMemory.cpp8
-rw-r--r--src/share/vm/runtime/perfMemory.hpp7
-rw-r--r--src/share/vm/runtime/reflection.cpp22
-rw-r--r--src/share/vm/runtime/thread.cpp64
-rw-r--r--src/share/vm/runtime/thread.hpp2
-rw-r--r--src/share/vm/utilities/array.hpp39
-rw-r--r--src/share/vm/utilities/constantTag.hpp1
-rw-r--r--src/share/vm/utilities/debug.cpp20
-rw-r--r--src/share/vm/utilities/growableArray.hpp17
-rw-r--r--src/share/vm/utilities/hashtable.cpp7
65 files changed, 923 insertions, 710 deletions
diff --git a/make/linux/makefiles/top.make b/make/linux/makefiles/top.make
index 46362ca16..1c212c6d3 100644
--- a/make/linux/makefiles/top.make
+++ b/make/linux/makefiles/top.make
@@ -85,9 +85,9 @@ Incremental_Lists = $(Cached_db)
AD_Dir = $(GENERATED)/adfiles
ADLC = $(AD_Dir)/adlc
-AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
AD_Src = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
# AD_Files_If_Required/COMPILER1 = ad_stuff
diff --git a/make/solaris/makefiles/amd64.make b/make/solaris/makefiles/amd64.make
index 7ce14eae1..b05414dbd 100644
--- a/make/solaris/makefiles/amd64.make
+++ b/make/solaris/makefiles/amd64.make
@@ -26,7 +26,6 @@
CFLAGS += -DVM_LITTLE_ENDIAN
# Not included in includeDB because it has no dependencies
-# Obj_Files += solaris_amd64.o
Obj_Files += solaris_x86_64.o
#
@@ -38,8 +37,6 @@ ifeq ("${Platform_compiler}", "sparcWorks")
# _lwp_create_interpose must have a frame
OPT_CFLAGS/os_solaris_x86_64.o = -xO1
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -fast -O4
# Temporary until SS10 C++ compiler is fixed
OPT_CFLAGS/generateOptoStub.o = -xO2
@@ -51,8 +48,6 @@ ifeq ("${Platform_compiler}", "gcc")
# gcc
# The serviceability agent relies on frame pointer (%rbp) to walk thread stack
CFLAGS += -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-#OPT_CFLAGS/interpret.o = -O3
else
# error
diff --git a/make/solaris/makefiles/debug.make b/make/solaris/makefiles/debug.make
index 69eb236ad..4fdf4a746 100644
--- a/make/solaris/makefiles/debug.make
+++ b/make/solaris/makefiles/debug.make
@@ -30,7 +30,7 @@ DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
diff --git a/make/solaris/makefiles/dtrace.make b/make/solaris/makefiles/dtrace.make
index bcc7819aa..0ba875dc5 100644
--- a/make/solaris/makefiles/dtrace.make
+++ b/make/solaris/makefiles/dtrace.make
@@ -87,17 +87,16 @@ ifneq ("${ISA}","${BUILDARCH}")
XLIBJVM_DB = 64/$(LIBJVM_DB)
XLIBJVM_DTRACE = 64/$(LIBJVM_DTRACE)
-XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
- $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@
$(QUIETLY) mkdir -p 64/ ; \
- $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
+ $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
endif # ifneq ("${ISA}","${BUILDARCH}")
@@ -116,27 +115,25 @@ $(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).so
$(QUIETLY) $(LINK.CC) -z nodefs -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
./lib$(GENOFFS).so
-# $@.tmp is created first. It's to avoid empty $(JVMOFFS).h produced in error case.
+CONDITIONALLY_UPDATE_JVMOFFS_TARGET = \
+ cmp -s $@ $@.tmp; \
+ case $$? in \
+ 0) rm -f $@.tmp;; \
+ *) rm -f $@ && mv $@.tmp $@ && echo Updated $@;; \
+ esac
+
+# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
$(JVMOFFS).h: $(GENOFFS)
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS)Index.h: $(GENOFFS)
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
- $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp ; \
- if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
- then rm -f $@; mv $@.tmp $@; echo Updated $@ ; \
- else rm -f $@.tmp; \
- fi
+ $(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp
+ $(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
$(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp
$(QUIETLY) $(CCC) -c -I. -o $@ $(ARCHFLAG) -D$(TYPE) $(JVMOFFS).cpp
diff --git a/make/solaris/makefiles/fastdebug.make b/make/solaris/makefiles/fastdebug.make
index 3ac2ae212..084814d67 100644
--- a/make/solaris/makefiles/fastdebug.make
+++ b/make/solaris/makefiles/fastdebug.make
@@ -37,7 +37,7 @@ ifeq ("${Platform_compiler}", "sparcWorks")
OPT_CFLAGS/SLOWER = -xO2
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV), 5.9)
+ifeq ($(COMPILER_REV_NUMERIC), 509)
# To avoid jvm98 crash
OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
# Not clear this workaround could be skipped in some cases.
@@ -46,47 +46,41 @@ ifeq ($(COMPILER_REV), 5.9)
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
endif
-ifeq ($(COMPILER_REV), 5.5)
+ifeq ($(COMPILER_REV_NUMERIC), 505)
# CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6)
OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV == 5.5
+endif # COMPILER_REV_NUMERIC == 505
-ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \<= 504), 1)
# Compilation of *_<arch>.cpp can take an hour or more at O3. Use O2
# See comments at top of sparc.make.
-OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
-endif # COMPILER_REV <= 5.4
-
-ifeq (${COMPILER_REV}, 5.0)
-# Avoid a compiler bug caused by using -xO<level> -g<level>
-# Since the bug also occurs with -xO0, use an innocuous value (must not be null)
-OPT_CFLAGS/c1_LIROptimizer_i486.o = -c
-endif
-
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
-# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_i486.cpp.
-# CC build time is also too long for ad_i486_{gen,misc}.o
-OPT_CFLAGS/ad_i486.o = -c
-OPT_CFLAGS/ad_i486_gen.o = -c
-OPT_CFLAGS/ad_i486_misc.o = -c
-ifeq ($(Platform_arch), i486)
+OPT_CFLAGS/ad_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+OPT_CFLAGS/dfa_$(Platform_arch_model).o = $(OPT_CFLAGS/SLOWER)
+endif # COMPILER_REV_NUMERIC <= 504
+
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
+# Same problem with Solaris/x86 compiler (both 5.0 and 5.2) on ad_x86_{32,64}.cpp.
+# CC build time is also too long for ad_$(Platform_arch_model)_{gen,misc}.o
+OPT_CFLAGS/ad_$(Platform_arch_model).o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_gen.o = -c
+OPT_CFLAGS/ad_$(Platform_arch_model)_misc.o = -c
+ifeq ($(Platform_arch), x86)
# Same problem for the wrapper roosts: jni.o jvm.o
OPT_CFLAGS/jni.o = -c
OPT_CFLAGS/jvm.o = -c
# Same problem in parse2.o (probably the Big Switch over bytecodes)
OPT_CFLAGS/parse2.o = -c
-endif # Platform_arch == i486
+endif # Platform_arch == x86
endif
# Frame size > 100k if we allow inlining via -g0!
DEBUG_CFLAGS/bytecodeInterpreter.o = -g
DEBUG_CFLAGS/bytecodeInterpreterWithChecks.o = -g
-ifeq ($(Platform_arch), i486)
+ifeq ($(Platform_arch), x86)
# ube explodes on x86
OPT_CFLAGS/bytecodeInterpreter.o = -xO1
OPT_CFLAGS/bytecodeInterpreterWithChecks.o = -xO1
-endif # Platform_arch == i486
+endif # Platform_arch == x86
endif # Platform_compiler == sparcWorks
diff --git a/make/solaris/makefiles/i486.make b/make/solaris/makefiles/i486.make
index a8f92a361..320035fd4 100644
--- a/make/solaris/makefiles/i486.make
+++ b/make/solaris/makefiles/i486.make
@@ -35,17 +35,13 @@ Obj_Files += solaris_x86_32.o
ifeq ("${Platform_compiler}", "sparcWorks")
# _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -xO1
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -fast -O4
+OPT_CFLAGS/os_solaris_x86.o = -xO1
else
ifeq ("${Platform_compiler}", "gcc")
# gcc
# _lwp_create_interpose must have a frame
-OPT_CFLAGS/os_solaris_i486.o = -fno-omit-frame-pointer
-# force C++ interpreter to be full optimization
-OPT_CFLAGS/interpret.o = -O3
+OPT_CFLAGS/os_solaris_x86.o = -fno-omit-frame-pointer
#
else
# error
@@ -57,7 +53,7 @@ endif
ifeq ("${Platform_compiler}", "sparcWorks")
# ILD is gone as of SS11 (5.8), not supported in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
#
# Bug in ild causes it to fail randomly. Until we get a fix we can't
# use ild.
diff --git a/make/solaris/makefiles/jvmg.make b/make/solaris/makefiles/jvmg.make
index ada307af8..e6603005f 100644
--- a/make/solaris/makefiles/jvmg.make
+++ b/make/solaris/makefiles/jvmg.make
@@ -30,7 +30,7 @@ DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0
diff --git a/make/solaris/makefiles/optimized.make b/make/solaris/makefiles/optimized.make
index 1f91c3124..69848b736 100644
--- a/make/solaris/makefiles/optimized.make
+++ b/make/solaris/makefiles/optimized.make
@@ -33,7 +33,7 @@ OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
ifeq ("${Platform_compiler}", "sparcWorks")
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -41,9 +41,9 @@ ifeq ($(COMPILER_REV),5.9)
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8))
+ifeq ($(COMPILER_REV_NUMERIC),508))
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
endif # Platform_compiler == sparcWorks
diff --git a/make/solaris/makefiles/product.make b/make/solaris/makefiles/product.make
index 66e535367..10c6b4568 100644
--- a/make/solaris/makefiles/product.make
+++ b/make/solaris/makefiles/product.make
@@ -41,7 +41,7 @@ endif
ifeq ("${Platform_compiler}", "sparcWorks")
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
@@ -49,9 +49,9 @@ ifeq ($(COMPILER_REV),5.9)
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
-ifeq ($(COMPILER_REV),5.8)
+ifeq ($(COMPILER_REV_NUMERIC),508)
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
-endif # COMPILER_REV == 5.8
+endif # COMPILER_REV_NUMERIC == 508
endif # Platform_compiler == sparcWorks
diff --git a/make/solaris/makefiles/sparc.make b/make/solaris/makefiles/sparc.make
index 6f332cf63..e08949496 100644
--- a/make/solaris/makefiles/sparc.make
+++ b/make/solaris/makefiles/sparc.make
@@ -26,7 +26,7 @@ Obj_Files += solaris_sparc.o
ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
# For 5.2 ad_sparc file is compiled with -O2 %%%% remove when adlc is fixed
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/dfa_sparc.o = $(OPT_CFLAGS/SLOWER)
@@ -39,7 +39,7 @@ OPT_CFLAGS/carRememberedSet.o = $(OPT_CFLAGS/O2)
OPT_CFLAGS/jniHandles.o = $(OPT_CFLAGS/O2)
# CC brings an US-II to its knees compiling the vmStructs asserts under -xO4
OPT_CFLAGS/vmStructs.o = $(OPT_CFLAGS/O2)
-endif
+endif # COMPILER_REV_NUMERIC < 505
else
# Options for gcc
OPT_CFLAGS/ad_sparc.o = $(OPT_CFLAGS/SLOWER)
diff --git a/make/solaris/makefiles/sparcWorks.make b/make/solaris/makefiles/sparcWorks.make
index 5bbe70f9f..501268e3d 100644
--- a/make/solaris/makefiles/sparcWorks.make
+++ b/make/solaris/makefiles/sparcWorks.make
@@ -41,9 +41,9 @@ REORDER_FLAG = -xF
# Get the last thing on the line that looks like x.x+ (x is a digit).
COMPILER_REV := \
-$(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CPP) -V 2>&1 | sed -n 's/^.*[ ,\t]C++[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
C_COMPILER_REV := \
-$(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
+$(shell $(CC) -V 2>&1 | sed -n 's/^.*[ ,\t]C[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/p')
# Pick which compiler is validated
ifeq ($(JDK_MINOR_VERSION),6)
@@ -60,17 +60,19 @@ endif
ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
dummy_target_to_enforce_compiler_rev:=\
-$(info WARNING: You are using CC version ${COMPILER_REV} \
-and should be using version ${ENFORCE_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using CC version ${COMPILER_REV} \
+and should be using version ${ENFORCE_COMPILER_REV}. Set ENFORCE_COMPILER_REV=${COMPILER_REV} to avoid this warning.)
endif
ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
dummy_target_to_enforce_c_compiler_rev:=\
-$(info WARNING: You are using cc version ${C_COMPILER_REV} \
-and should be using version ${ENFORCE_C_COMPILER_REV})
+$(shell echo >&2 WARNING: You are using cc version ${C_COMPILER_REV} \
+and should be using version ${ENFORCE_C_COMPILER_REV}. Set ENFORCE_C_COMPILER_REV=${C_COMPILER_REV} to avoid this warning.)
endif
+COMPILER_REV_NUMERIC := $(shell echo $(COMPILER_REV) | awk -F. '{ print $$1 * 100 + $$2 }')
+
# Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04
# and newer; objects with a dependency on this symbol will not run on older
# Solaris 8.
@@ -120,7 +122,7 @@ ARCHFLAG_OLD/amd64 = -xarch=amd64
ARCHFLAG_NEW/amd64 = -m64
# Select the ARCHFLAGs and other SS12 (5.9) options
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc)
ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486)
@@ -150,7 +152,7 @@ OPT_CFLAGS/NOOPT=-xO1
# Begin current (>=5.6) Forte compiler options #
#################################################
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.6), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 506), 1)
ifeq ("${Platform_arch}", "sparc")
@@ -167,7 +169,7 @@ endif
# Begin current (>=5.5) Forte compiler options #
#################################################
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
@@ -255,7 +257,7 @@ LFLAGS += -library=%none
LFLAGS += -mt
-endif # COMPILER_REV >= 5.5
+endif # COMPILER_REV_NUMERIC >= 505
######################################
# End 5.5 Forte compiler options #
@@ -265,7 +267,7 @@ endif # COMPILER_REV >= 5.5
# Begin 5.2 Forte compiler options #
######################################
-ifeq ($(COMPILER_REV), 5.2)
+ifeq ($(COMPILER_REV_NUMERIC), 502)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
@@ -324,7 +326,7 @@ PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
LFLAGS += -library=Crun
LIBS += -library=Crun -lCrun
-endif # COMPILER_REV == 5.2
+endif # COMPILER_REV_NUMERIC == 502
##################################
# End 5.2 Forte compiler options #
@@ -333,7 +335,7 @@ endif # COMPILER_REV == 5.2
##################################
# Begin old 5.1 compiler options #
##################################
-ifeq ($(COMPILER_REV), 5.1)
+ifeq ($(COMPILER_REV_NUMERIC), 501)
_JUNK_ := $(shell echo >&2 \
"*** ERROR: sparkWorks.make incomplete for 5.1 compiler")
@@ -347,7 +349,7 @@ endif
# Begin old 5.0 compiler options #
##################################
-ifeq (${COMPILER_REV}, 5.0)
+ifeq (${COMPILER_REV_NUMERIC}, 500)
# Had to hoist this higher apparently because of other changes. Must
# come before -xarch specification.
@@ -379,7 +381,7 @@ endif # sparc
ifeq ("${Platform_arch_model}", "x86_32")
OPT_CFLAGS=-xtarget=pentium $(EXTRA_OPT_CFLAGS)
-ifeq ("${COMPILER_REV}", "5.0")
+ifeq ("${COMPILER_REV_NUMERIC}", "500")
# SC5.0 tools on x86 are flakey at -xO4
OPT_CFLAGS+=-xO3
else
@@ -405,13 +407,13 @@ PICFLAG/DEFAULT = $(PICFLAG)
PICFLAG/BETTER = $(PICFLAG/DEFAULT)
PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
-endif # COMPILER_REV = 5.0
+endif # COMPILER_REV_NUMERIC = 500
################################
# End old 5.0 compiler options #
################################
-ifeq ("${COMPILER_REV}", "4.2")
+ifeq ("${COMPILER_REV_NUMERIC}", "402")
# 4.2 COMPILERS SHOULD NO LONGER BE USED
_JUNK_ := $(shell echo >&2 \
"*** ERROR: SC4.2 compilers are not supported by this code base!")
@@ -443,7 +445,7 @@ LINK_MODE/debug =
LINK_MODE/optimized = -Bsymbolic -znodefs
# Have thread local errnos
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
CFLAGS += -mt
else
CFLAGS += -D_REENTRANT
@@ -460,7 +462,7 @@ FASTDEBUG_CFLAGS = -g0
# The -g0 setting allows the C++ frontend to inline, which is a big win.
# Special global options for SS12
-ifeq ($(COMPILER_REV),5.9)
+ifeq ($(COMPILER_REV_NUMERIC),509)
# There appears to be multiple issues with the new Dwarf2 debug format, so
# we tell the compiler to use the older 'stabs' debug format all the time.
# Note that this needs to be used in optimized compiles too to be 100%.
@@ -479,8 +481,8 @@ endif
#DEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
#FASTDEBUG_CFLAGS += -Qoption ccfe -xglobalstatic
-ifeq (${COMPILER_REV}, 5.2)
-COMPILER_DATE := $(shell $(CPP) -V 2>&1 | awk '{ print $$NF; }')
+ifeq (${COMPILER_REV_NUMERIC}, 502)
+COMPILER_DATE := $(shell $(CPP) -V 2>&1 | sed -n '/^.*[ ]C++[ ]\([1-9]\.[0-9][0-9]*\)/p' | awk '{ print $$NF; }')
ifeq (${COMPILER_DATE}, 2001/01/31)
# disable -g0 in fastdebug since SC6.1 dated 2001/01/31 seems to be buggy
# use an innocuous value because it will get -g if it's empty
@@ -493,7 +495,7 @@ endif
CFLAGS += $(CFLAGS_BROWSE)
# ILD is gone as of SS11 (5.8), not supportted in SS10 (5.7)
-ifeq ($(shell expr $(COMPILER_REV) \< 5.7), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 507), 1)
# use ild when debugging (but when optimizing we want reproducible results)
ILDFLAG = $(ILDFLAG/$(VERSION))
ILDFLAG/debug = -xildon
diff --git a/make/solaris/makefiles/sparcv9.make b/make/solaris/makefiles/sparcv9.make
index c05d04bc1..9ee08dd1b 100644
--- a/make/solaris/makefiles/sparcv9.make
+++ b/make/solaris/makefiles/sparcv9.make
@@ -26,7 +26,7 @@ Obj_Files += solaris_sparc.o
ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks")
-ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \< 505), 1)
# When optimized fully, stubGenerator_sparc.cpp
# has bogus code for the routine
# StubGenerator::generate_flush_callers_register_windows()
diff --git a/make/solaris/makefiles/top.make b/make/solaris/makefiles/top.make
index 4b235d405..6affc873c 100644
--- a/make/solaris/makefiles/top.make
+++ b/make/solaris/makefiles/top.make
@@ -83,9 +83,9 @@ Incremental_Lists =$(GENERATED)/$(Cached_db)
AD_Dir = $(GENERATED)/adfiles
ADLC = $(AD_Dir)/adlc
-AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad
+AD_Spec = $(GAMMADIR)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad
AD_Src = $(GAMMADIR)/src/share/vm/adlc
-AD_Names = ad_$(Platform_arch).hpp ad_$(Platform_arch).cpp
+AD_Names = ad_$(Platform_arch_model).hpp ad_$(Platform_arch_model).cpp
AD_Files = $(AD_Names:%=$(AD_Dir)/%)
# AD_Files_If_Required/COMPILER1 = ad_stuff
diff --git a/make/solaris/makefiles/vm.make b/make/solaris/makefiles/vm.make
index 70a11975f..32850b18b 100644
--- a/make/solaris/makefiles/vm.make
+++ b/make/solaris/makefiles/vm.make
@@ -101,7 +101,7 @@ LIBM=/usr/lib$(ISA_DIR)/libm.so.1
ifeq ("${Platform_compiler}", "sparcWorks")
# The whole megilla:
-ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
+ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 505), 1)
# Old Comment: List the libraries in the order the compiler was designed for
# Not sure what the 'designed for' comment is referring too above.
# The order may not be too significant anymore, but I have placed this
diff --git a/make/windows/makefiles/adlc.make b/make/windows/makefiles/adlc.make
index b2f8132c6..b6feb0e78 100644
--- a/make/windows/makefiles/adlc.make
+++ b/make/windows/makefiles/adlc.make
@@ -102,6 +102,12 @@ GENERATED_NAMES_IN_INCL=\
adlc.exe: main.obj adlparse.obj archDesc.obj arena.obj dfa.obj dict2.obj filebuff.obj \
forms.obj formsopt.obj formssel.obj opcodes.obj output_c.obj output_h.obj
$(LINK) $(LINK_FLAGS) /subsystem:console /out:$@ $**
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#1
+!endif
$(GENERATED_NAMES_IN_INCL): $(Platform_arch_model).ad adlc.exe includeDB.current
rm -f $(GENERATED_NAMES)
diff --git a/make/windows/makefiles/compile.make b/make/windows/makefiles/compile.make
index bf6f3be9b..ddc9ea11a 100644
--- a/make/windows/makefiles/compile.make
+++ b/make/windows/makefiles/compile.make
@@ -30,7 +30,7 @@ CPP=cl.exe
# /W3 Warning level 3
# /Zi Include debugging information
# /WX Treat any warning error as a fatal error
-# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*71.dll)
+# /MD Use dynamic multi-threaded runtime (msvcrt.dll or msvc*NN.dll)
# /MTd Use static multi-threaded runtime debug versions
# /O1 Optimize for size (/Os), skips /Oi
# /O2 Optimize for speed (/Ot), adds /Oi to /O1
@@ -80,8 +80,10 @@ CPP_FLAGS=$(CPP_FLAGS) /D "IA32"
CPP=ARCH_ERROR
!endif
-# MSC_VER is a 4 digit number that tells us what compiler is being used, it is
-# generated when the local.make file is created by the script gen_msc_ver.sh.
+# MSC_VER is a 4 digit number that tells us what compiler is being used
+# and is generated when the local.make file is created by build.make
+# via the script get_msc_ver.sh
+#
# If MSC_VER is set, it overrides the above default setting.
# But it should be set.
# Possible values:
@@ -89,13 +91,14 @@ CPP=ARCH_ERROR
# 1300 and 1310 is VS2003 or VC7
# 1399 is our fake number for the VS2005 compiler that really isn't 1400
# 1400 is for VS2005
+# 1500 is for VS2008
# Do not confuse this MSC_VER with the predefined macro _MSC_VER that the
# compiler provides, when MSC_VER==1399, _MSC_VER will be 1400.
# Normally they are the same, but a pre-release of the VS2005 compilers
# in the Windows 64bit Platform SDK said it was 1400 when it was really
# closer to VS2003 in terms of option spellings, so we use 1399 for that
# 1400 version that really isn't 1400.
-# See the file gen_msc_ver.sh for more info.
+# See the file get_msc_ver.sh for more info.
!if "x$(MSC_VER)" == "x"
COMPILER_NAME=$(DEFAULT_COMPILER_NAME)
!else
@@ -115,6 +118,9 @@ COMPILER_NAME=VS2003
!if "$(MSC_VER)" == "1400"
COMPILER_NAME=VS2005
!endif
+!if "$(MSC_VER)" == "1500"
+COMPILER_NAME=VS2008
+!endif
!endif
# Add what version of the compiler we think this is to the compile line
@@ -160,7 +166,25 @@ GX_OPTION = /EHsc
# externals at link time. Even with /GS-, you need bufferoverflowU.lib.
# NOTE: Currently we decided to not use /GS-
BUFFEROVERFLOWLIB = bufferoverflowU.lib
-LINK_FLAGS = $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+LINK_FLAGS = /manifest $(LINK_FLAGS) $(BUFFEROVERFLOWLIB)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
+!if "$(BUILDARCH)" == "i486"
+# VS2005 on x86 restricts the use of certain libc functions without this
+CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
+!endif
+!endif
+
+!if "$(COMPILER_NAME)" == "VS2008"
+PRODUCT_OPT_OPTION = /O2 /Oy-
+FASTDEBUG_OPT_OPTION = /O2 /Oy-
+DEBUG_OPT_OPTION = /Od
+GX_OPTION = /EHsc
+LINK_FLAGS = /manifest $(LINK_FLAGS)
+# Manifest Tool - used in VS2005 and later to adjust manifests stored
+# as resources inside build artifacts.
+MT=mt.exe
!if "$(BUILDARCH)" == "i486"
# VS2005 on x86 restricts the use of certain libc functions without this
CPP_FLAGS=$(CPP_FLAGS) /D _CRT_SECURE_NO_DEPRECATE
diff --git a/make/windows/makefiles/debug.make b/make/windows/makefiles/debug.make
index afd987d9c..9bb52cce2 100644
--- a/make/windows/makefiles/debug.make
+++ b/make/windows/makefiles/debug.make
@@ -50,6 +50,12 @@ $(AOUT): $(Res_Files) $(Obj_Files)
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff --git a/make/windows/makefiles/defs.make b/make/windows/makefiles/defs.make
index 4b2fc14b3..c264f9fd1 100644
--- a/make/windows/makefiles/defs.make
+++ b/make/windows/makefiles/defs.make
@@ -25,7 +25,7 @@
# The common definitions for hotspot windows builds.
# Include the top level defs.make under make directory instead of this one.
# This file is included into make/defs.make.
-# On windows it is only used to construct parameters for
+# On windows it is only used to construct parameters for
# make/windows/build.make when make/Makefile is used to build VM.
SLASH_JAVA ?= J:
@@ -69,7 +69,7 @@ endif
JDK_INCLUDE_SUBDIR=win32
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
# and added to MAKE_ARGS list in $(GAMMADIR)/make/defs.make.
# next parameters are defined in $(GAMMADIR)/make/defs.make.
@@ -125,7 +125,7 @@ ifneq ($(ALT_BUILD_WIN_SA),)
endif
ifeq ($(BUILD_WIN_SA), 1)
- ifeq ($(ARCH),ia64)
+ ifeq ($(ARCH),ia64)
BUILD_WIN_SA = 0
endif
endif
@@ -154,7 +154,7 @@ ifeq ($(BUILD_WIN_SA), 1)
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.dll
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.pdb
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.map
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
# Must pass this down to nmake.
MAKE_ARGS += BUILD_WIN_SA=1
endif
diff --git a/make/windows/makefiles/fastdebug.make b/make/windows/makefiles/fastdebug.make
index 064592bff..e15aaaae4 100644
--- a/make/windows/makefiles/fastdebug.make
+++ b/make/windows/makefiles/fastdebug.make
@@ -50,6 +50,13 @@ $(AOUT): $(Res_Files) $(Obj_Files)
$(LINK) @<<
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
+
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff --git a/make/windows/makefiles/product.make b/make/windows/makefiles/product.make
index a143d6c99..a26ffbcff 100644
--- a/make/windows/makefiles/product.make
+++ b/make/windows/makefiles/product.make
@@ -61,6 +61,12 @@ $(AOUT): $(Res_Files) $(Obj_Files)
$(LINK_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files)
<<
!endif
+!if "$(MT)" != ""
+# The previous link command created a .manifest file that we want to
+# insert into the linked artifact so we do not need to track it
+# separately. Use ";#2" for .dll and ";#1" for .exe:
+ $(MT) /manifest $@.manifest /outputresource:$@;#2
+!endif
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
diff --git a/make/windows/makefiles/sa.make b/make/windows/makefiles/sa.make
index 57fd493f8..01886c138 100644
--- a/make/windows/makefiles/sa.make
+++ b/make/windows/makefiles/sa.make
@@ -92,13 +92,18 @@ SA_LINK_FLAGS = bufferoverflowU.lib
!else
SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /ZI /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
!endif
-
+!if "$(MT)" != ""
+ SA_LINK_FLAGS = /manifest $(SA_LINK_FLAGS)
+!endif
SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
SA_LFLAGS = $(SA_LINK_FLAGS) /nologo /subsystem:console /map /debug /machine:$(MACHINE)
# Note that we do not keep sawindbj.obj around as it would then
# get included in the dumpbin command in build_vm_def.sh
+# In VS2005 or VS2008 the link command creates a .manifest file that we want
+# to insert into the linked artifact so we do not need to track it separately.
+# Use ";#2" for .dll and ";#1" for .exe in the MT command below:
$(SAWINDBG): $(SASRCFILE)
set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
$(CPP) @<<
@@ -109,6 +114,9 @@ $(SAWINDBG): $(SASRCFILE)
<<
set LIB=$(SA_LIB)$(LIB)
$(LINK) /out:$@ /DLL sawindbg.obj dbgeng.lib $(SA_LFLAGS)
+!if "$(MT)" != ""
+ $(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
+!endif
-@rm -f sawindbg.obj
cleanall :
diff --git a/make/windows/projectfiles/common/Makefile b/make/windows/projectfiles/common/Makefile
index c6793f96b..ebc3cd9be 100644
--- a/make/windows/projectfiles/common/Makefile
+++ b/make/windows/projectfiles/common/Makefile
@@ -56,7 +56,8 @@ IncludeDBs_gc=$(HOTSPOTWORKSPACE)/src/share/vm/includeDB_gc_parallel \
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_shared \
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parNew \
$(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge \
- $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep
+ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep \
+ $(HOTSPOTWORKSPACE)/src/share/vm/gc_implementation/includeDB_gc_g1
IncludeDBs_kernel =$(IncludeDBs_base) \
diff --git a/src/cpu/x86/vm/register_definitions_x86.cpp b/src/cpu/x86/vm/register_definitions_x86.cpp
index 1be2c1382..0aceac814 100644
--- a/src/cpu/x86/vm/register_definitions_x86.cpp
+++ b/src/cpu/x86/vm/register_definitions_x86.cpp
@@ -22,9 +22,6 @@
*
*/
-// make sure the defines don't screw up the declarations later on in this file
-#define DONT_USE_REGISTER_DEFINES
-
#include "incls/_precompiled.incl"
#include "incls/_register_definitions_x86.cpp.incl"
diff --git a/src/os/solaris/vm/os_solaris.cpp b/src/os/solaris/vm/os_solaris.cpp
index c4386d859..05940869e 100644
--- a/src/os/solaris/vm/os_solaris.cpp
+++ b/src/os/solaris/vm/os_solaris.cpp
@@ -3756,7 +3756,6 @@ int set_lwp_priority (int ThreadID, int lwpid, int newPrio )
int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
iaInfo->ia_uprilim = IA_NOCHANGE;
- iaInfo->ia_nice = IA_NOCHANGE;
iaInfo->ia_mode = IA_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr ("IA: [%d...%d] %d->%d\n",
diff --git a/src/share/vm/adlc/archDesc.cpp b/src/share/vm/adlc/archDesc.cpp
index 0aa15064c..9702fb477 100644
--- a/src/share/vm/adlc/archDesc.cpp
+++ b/src/share/vm/adlc/archDesc.cpp
@@ -212,9 +212,9 @@ ArchDesc::ArchDesc()
// Initialize I/O Files
_ADL_file._name = NULL; _ADL_file._fp = NULL;
// Machine dependent output files
- _DFA_file._name = "dfa_i486.cpp"; _DFA_file._fp = NULL;
- _HPP_file._name = "ad_i486.hpp"; _HPP_file._fp = NULL;
- _CPP_file._name = "ad_i486.cpp"; _CPP_file._fp = NULL;
+ _DFA_file._name = NULL; _DFA_file._fp = NULL;
+ _HPP_file._name = NULL; _HPP_file._fp = NULL;
+ _CPP_file._name = NULL; _CPP_file._fp = NULL;
_bug_file._name = "bugs.out"; _bug_file._fp = NULL;
// Initialize Register & Pipeline Form Pointers
diff --git a/src/share/vm/c1/c1_IR.cpp b/src/share/vm/c1/c1_IR.cpp
index 005114b46..ccb6abfbb 100644
--- a/src/share/vm/c1/c1_IR.cpp
+++ b/src/share/vm/c1/c1_IR.cpp
@@ -574,12 +574,23 @@ void ComputeLinearScanOrder::count_edges(BlockBegin* cur, BlockBegin* parent) {
TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));
assert(is_visited(cur), "block must be visisted when block is active");
assert(parent != NULL, "must have parent");
- assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)");
cur->set(BlockBegin::linear_scan_loop_header_flag);
cur->set(BlockBegin::backward_branch_target_flag);
parent->set(BlockBegin::linear_scan_loop_end_flag);
+
+ // When a loop header is also the start of an exception handler, then the backward branch is
+ // an exception edge. Because such edges are usually critical edges which cannot be split, the
+ // loop must be excluded here from processing.
+ if (cur->is_set(BlockBegin::exception_entry_flag)) {
+ // Make sure that dominators are correct in this weird situation
+ _iterative_dominators = true;
+ return;
+ }
+ assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
+ "loop end blocks must have one successor (critical edges are split)");
+
_loop_end_blocks.append(parent);
return;
}
diff --git a/src/share/vm/ci/ciEnv.cpp b/src/share/vm/ci/ciEnv.cpp
index 1d279540e..cb2be0f5a 100644
--- a/src/share/vm/ci/ciEnv.cpp
+++ b/src/share/vm/ci/ciEnv.cpp
@@ -484,11 +484,16 @@ ciConstant ciEnv::get_constant_by_index_impl(ciInstanceKlass* accessor,
} else if (tag.is_double()) {
return ciConstant((jdouble)cpool->double_at(index));
} else if (tag.is_string() || tag.is_unresolved_string()) {
- oop string = cpool->string_at(index, THREAD);
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- record_out_of_memory_failure();
- return ciConstant();
+ oop string = NULL;
+ if (cpool->is_pseudo_string_at(index)) {
+ string = cpool->pseudo_string_at(index);
+ } else {
+ string = cpool->string_at(index, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ record_out_of_memory_failure();
+ return ciConstant();
+ }
}
ciObject* constant = get_object(string);
assert (constant->is_instance(), "must be an instance, or not? ");
diff --git a/src/share/vm/classfile/classFileParser.cpp b/src/share/vm/classfile/classFileParser.cpp
index 7ee8ce984..45d0147fa 100644
--- a/src/share/vm/classfile/classFileParser.cpp
+++ b/src/share/vm/classfile/classFileParser.cpp
@@ -168,11 +168,23 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
// Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.
cfs->guarantee_more(utf8_length+1, CHECK); // utf8 string, tag/access_flags
cfs->skip_u1_fast(utf8_length);
+
// Before storing the symbol, make sure it's legal
if (_need_verify) {
verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);
}
+ if (AnonymousClasses && has_cp_patch_at(index)) {
+ Handle patch = clear_cp_patch_at(index);
+ guarantee_property(java_lang_String::is_instance(patch()),
+ "Illegal utf8 patch at %d in class file %s",
+ index, CHECK);
+ char* str = java_lang_String::as_utf8_string(patch());
+ // (could use java_lang_String::as_symbol instead, but might as well batch them)
+ utf8_buffer = (u1*) str;
+ utf8_length = (int) strlen(str);
+ }
+
unsigned int hash;
symbolOop result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
if (result == NULL) {
@@ -245,7 +257,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
int klass_ref_index = cp->klass_ref_index_at(index);
int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
check_property(valid_cp_range(klass_ref_index, length) &&
- cp->tag_at(klass_ref_index).is_klass_reference(),
+ is_klass_reference(cp, klass_ref_index),
"Invalid constant pool index %u in class file %s",
klass_ref_index,
CHECK_(nullHandle));
@@ -326,16 +338,46 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
} // end of switch
} // end of for
+ if (_cp_patches != NULL) {
+ // need to treat this_class specially...
+ assert(AnonymousClasses, "");
+ int this_class_index;
+ {
+ cfs->guarantee_more(8, CHECK_(nullHandle)); // flags, this_class, super_class, infs_len
+ u1* mark = cfs->current();
+ u2 flags = cfs->get_u2_fast();
+ this_class_index = cfs->get_u2_fast();
+ cfs->set_current(mark); // revert to mark
+ }
+
+ for (index = 1; index < length; index++) { // Index 0 is unused
+ if (has_cp_patch_at(index)) {
+ guarantee_property(index != this_class_index,
+ "Illegal constant pool patch to self at %d in class file %s",
+ index, CHECK_(nullHandle));
+ patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
+ }
+ }
+ // Ensure that all the patches have been used.
+ for (index = 0; index < _cp_patches->length(); index++) {
+ guarantee_property(!has_cp_patch_at(index),
+ "Unused constant pool patch at %d in class file %s",
+ index, CHECK_(nullHandle));
+ }
+ }
+
if (!_need_verify) {
return cp;
}
// second verification pass - checks the strings are of the right format.
+ // but not yet to the other entries
for (index = 1; index < length; index++) {
jbyte tag = cp->tag_at(index).value();
switch (tag) {
case JVM_CONSTANT_UnresolvedClass: {
symbolHandle class_name(THREAD, cp->unresolved_klass_at(index));
+ // check the name, even if _cp_patches will overwrite it
verify_legal_class_name(class_name, CHECK_(nullHandle));
break;
}
@@ -378,6 +420,73 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
}
+void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
+ assert(AnonymousClasses, "");
+ BasicType patch_type = T_VOID;
+ switch (cp->tag_at(index).value()) {
+
+ case JVM_CONSTANT_UnresolvedClass :
+ // Patching a class means pre-resolving it.
+ // The name in the constant pool is ignored.
+ if (patch->klass() == SystemDictionary::class_klass()) { // %%% java_lang_Class::is_instance
+ guarantee_property(!java_lang_Class::is_primitive(patch()),
+ "Illegal class patch at %d in class file %s",
+ index, CHECK);
+ cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
+ } else {
+ guarantee_property(java_lang_String::is_instance(patch()),
+ "Illegal class patch at %d in class file %s",
+ index, CHECK);
+ symbolHandle name = java_lang_String::as_symbol(patch(), CHECK);
+ cp->unresolved_klass_at_put(index, name());
+ }
+ break;
+
+ case JVM_CONSTANT_UnresolvedString :
+ // Patching a string means pre-resolving it.
+ // The spelling in the constant pool is ignored.
+ // The constant reference may be any object whatever.
+ // If it is not a real interned string, the constant is referred
+ // to as a "pseudo-string", and must be presented to the CP
+ // explicitly, because it may require scavenging.
+ cp->pseudo_string_at_put(index, patch());
+ break;
+
+ case JVM_CONSTANT_Integer : patch_type = T_INT; goto patch_prim;
+ case JVM_CONSTANT_Float : patch_type = T_FLOAT; goto patch_prim;
+ case JVM_CONSTANT_Long : patch_type = T_LONG; goto patch_prim;
+ case JVM_CONSTANT_Double : patch_type = T_DOUBLE; goto patch_prim;
+ patch_prim:
+ {
+ jvalue value;
+ BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
+ guarantee_property(value_type == patch_type,
+ "Illegal primitive patch at %d in class file %s",
+ index, CHECK);
+ switch (value_type) {
+ case T_INT: cp->int_at_put(index, value.i); break;
+ case T_FLOAT: cp->float_at_put(index, value.f); break;
+ case T_LONG: cp->long_at_put(index, value.j); break;
+ case T_DOUBLE: cp->double_at_put(index, value.d); break;
+ default: assert(false, "");
+ }
+ }
+ break;
+
+ default:
+ // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
+ guarantee_property(!has_cp_patch_at(index),
+ "Illegal unexpected patch at %d in class file %s",
+ index, CHECK);
+ return;
+ }
+
+ // On fall-through, mark the patch as used.
+ clear_cp_patch_at(index);
+}
+
+
+
class NameSigHash: public ResourceObj {
public:
symbolOop _name; // name
@@ -448,25 +557,32 @@ objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
int index;
for (index = 0; index < length; index++) {
u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
+ KlassHandle interf;
check_property(
valid_cp_range(interface_index, cp->length()) &&
- cp->tag_at(interface_index).is_unresolved_klass(),
+ is_klass_reference(cp, interface_index),
"Interface name has bad constant pool index %u in class file %s",
interface_index, CHECK_(nullHandle));
- symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
+ if (cp->tag_at(interface_index).is_klass()) {
+ interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
+ } else {
+ symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
- // Don't need to check legal name because it's checked when parsing constant pool.
- // But need to make sure it's not an array type.
- guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
- "Bad interface name in class file %s", CHECK_(nullHandle));
+ // Don't need to check legal name because it's checked when parsing constant pool.
+ // But need to make sure it's not an array type.
+ guarantee_property(unresolved_klass->byte_at(0) != JVM_SIGNATURE_ARRAY,
+ "Bad interface name in class file %s", CHECK_(nullHandle));
- vmtimer->suspend(); // do not count recursive loading twice
- // Call resolve_super so classcircularity is checked
- klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
- unresolved_klass, class_loader, protection_domain,
- false, CHECK_(nullHandle));
- KlassHandle interf (THREAD, k);
- vmtimer->resume();
+ vmtimer->suspend(); // do not count recursive loading twice
+ // Call resolve_super so classcircularity is checked
+ klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
+ unresolved_klass, class_loader, protection_domain,
+ false, CHECK_(nullHandle));
+ interf = KlassHandle(THREAD, k);
+ vmtimer->resume();
+
+ cp->klass_at_put(interface_index, interf()); // eagerly resolve
+ }
if (!Klass::cast(interf())->is_interface()) {
THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
@@ -877,8 +993,7 @@ typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
"Illegal exception table handler in class file %s", CHECK_(nullHandle));
if (catch_type_index != 0) {
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
- (cp->tag_at(catch_type_index).is_klass() ||
- cp->tag_at(catch_type_index).is_unresolved_klass()),
+ is_klass_reference(cp, catch_type_index),
"Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
}
}
@@ -1117,7 +1232,7 @@ void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_i
} else if (tag == ITEM_Object) {
u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
guarantee_property(valid_cp_range(class_index, cp->length()) &&
- cp->tag_at(class_index).is_unresolved_klass(),
+ is_klass_reference(cp, class_index),
"Bad class index %u in StackMap in class file %s",
class_index, CHECK);
} else if (tag == ITEM_Uninitialized) {
@@ -1183,7 +1298,7 @@ u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length,
checked_exception = cfs->get_u2_fast();
check_property(
valid_cp_range(checked_exception, cp->length()) &&
- cp->tag_at(checked_exception).is_klass_reference(),
+ is_klass_reference(cp, checked_exception),
"Exception name has bad type at constant pool %u in class file %s",
checked_exception, CHECK_NULL);
}
@@ -1918,7 +2033,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
check_property(
inner_class_info_index == 0 ||
(valid_cp_range(inner_class_info_index, cp_size) &&
- cp->tag_at(inner_class_info_index).is_klass_reference()),
+ is_klass_reference(cp, inner_class_info_index)),
"inner_class_info_index %u has bad constant type in class file %s",
inner_class_info_index, CHECK_0);
// Outer class index
@@ -1926,7 +2041,7 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle c
check_property(
outer_class_info_index == 0 ||
(valid_cp_range(outer_class_info_index, cp_size) &&
- cp->tag_at(outer_class_info_index).is_klass_reference()),
+ is_klass_reference(cp, outer_class_info_index)),
"outer_class_info_index %u has bad constant type in class file %s",
outer_class_info_index, CHECK_0);
// Inner class name
@@ -2088,7 +2203,7 @@ void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instance
}
// Validate the constant pool indices and types
if (!cp->is_within_bounds(class_index) ||
- !cp->tag_at(class_index).is_klass_reference()) {
+ !is_klass_reference(cp, class_index)) {
classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
}
if (method_index != 0 &&
@@ -2349,6 +2464,7 @@ void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_pt
instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
Handle class_loader,
Handle protection_domain,
+ GrowableArray<Handle>* cp_patches,
symbolHandle& parsed_name,
TRAPS) {
// So that JVMTI can cache class file in the state before retransformable agents
@@ -2380,6 +2496,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
}
}
+ _cp_patches = cp_patches;
instanceKlassHandle nullHandle;
@@ -2510,14 +2627,22 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
CHECK_(nullHandle));
} else {
check_property(valid_cp_range(super_class_index, cp_size) &&
- cp->tag_at(super_class_index).is_unresolved_klass(),
+ is_klass_reference(cp, super_class_index),
"Invalid superclass index %u in class file %s",
super_class_index,
CHECK_(nullHandle));
// The class name should be legal because it is checked when parsing constant pool.
// However, make sure it is not an array type.
+ bool is_array = false;
+ if (cp->tag_at(super_class_index).is_klass()) {
+ super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
+ if (_need_verify)
+ is_array = super_klass->oop_is_array();
+ } else if (_need_verify) {
+ is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
+ }
if (_need_verify) {
- guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
+ guarantee_property(!is_array,
"Bad superclass name in class file %s", CHECK_(nullHandle));
}
}
@@ -2557,7 +2682,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
// We check super class after class file is parsed and format is checked
- if (super_class_index > 0) {
+ if (super_class_index > 0 && super_klass.is_null()) {
symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
if (access_flags.is_interface()) {
// Before attempting to resolve the superclass, check for class format
@@ -2574,6 +2699,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
CHECK_(nullHandle));
KlassHandle kh (THREAD, k);
super_klass = instanceKlassHandle(THREAD, kh());
+ cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
+ }
+ if (super_klass.not_null()) {
if (super_klass->is_interface()) {
ResourceMark rm(THREAD);
Exceptions::fthrow(
@@ -3000,6 +3128,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
this_klass->set_method_ordering(method_ordering());
this_klass->set_initial_method_idnum(methods->length());
this_klass->set_name(cp->klass_name_at(this_class_index));
+ cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
this_klass->set_protection_domain(protection_domain());
this_klass->set_fields_annotations(fields_annotations());
this_klass->set_methods_annotations(methods_annotations());
diff --git a/src/share/vm/classfile/classFileParser.hpp b/src/share/vm/classfile/classFileParser.hpp
index a29905fc4..4a58fca55 100644
--- a/src/share/vm/classfile/classFileParser.hpp
+++ b/src/share/vm/classfile/classFileParser.hpp
@@ -33,6 +33,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
u2 _major_version;
u2 _minor_version;
symbolHandle _class_name;
+ GrowableArray<Handle>* _cp_patches; // overrides for CP entries
bool _has_finalizer;
bool _has_empty_finalizer;
@@ -203,6 +204,35 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);
char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);
+ bool has_cp_patch_at(int index) {
+ assert(AnonymousClasses, "");
+ assert(index >= 0, "oob");
+ return (_cp_patches != NULL
+ && index < _cp_patches->length()
+ && _cp_patches->adr_at(index)->not_null());
+ }
+ Handle cp_patch_at(int index) {
+ assert(has_cp_patch_at(index), "oob");
+ return _cp_patches->at(index);
+ }
+ Handle clear_cp_patch_at(int index) {
+ Handle patch = cp_patch_at(index);
+ _cp_patches->at_put(index, Handle());
+ assert(!has_cp_patch_at(index), "");
+ return patch;
+ }
+ void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
+
+ // Wrapper for constantTag.is_klass_[or_]reference.
+ // In older versions of the VM, klassOops cannot sneak into early phases of
+ // constant pool construction, but in later versions they can.
+ // %%% Let's phase out the old is_klass_reference.
+ bool is_klass_reference(constantPoolHandle cp, int index) {
+ return ((LinkWellKnownClasses || AnonymousClasses)
+ ? cp->tag_at(index).is_klass_or_reference()
+ : cp->tag_at(index).is_klass_reference());
+ }
+
public:
// Constructor
ClassFileParser(ClassFileStream* st) { set_stream(st); }
@@ -218,6 +248,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Handle class_loader,
Handle protection_domain,
symbolHandle& parsed_name,
+ TRAPS) {
+ return parseClassFile(name, class_loader, protection_domain, NULL, parsed_name, THREAD);
+ }
+ instanceKlassHandle parseClassFile(symbolHandle name,
+ Handle class_loader,
+ Handle protection_domain,
+ GrowableArray<Handle>* cp_patches,
+ symbolHandle& parsed_name,
TRAPS);
// Verifier checks
diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp
index 772716311..0908e1c87 100644
--- a/src/share/vm/classfile/systemDictionary.cpp
+++ b/src/share/vm/classfile/systemDictionary.cpp
@@ -937,6 +937,8 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
+ KlassHandle host_klass,
+ GrowableArray<Handle>* cp_patches,
TRAPS) {
symbolHandle parsed_name;
@@ -953,10 +955,10 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
class_loader,
protection_domain,
+ cp_patches,
parsed_name,
THREAD);
-
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
// data structures).
@@ -973,6 +975,30 @@ klassOop SystemDictionary::parse_stream(symbolHandle class_name,
}
}
+ if (host_klass.not_null() && k.not_null()) {
+ assert(AnonymousClasses, "");
+ // If it's anonymous, initialize it now, since nobody else will.
+ k->set_host_klass(host_klass());
+
+ {
+ MutexLocker mu_r(Compile_lock, THREAD);
+
+ // Add to class hierarchy, initialize vtables, and do possible
+ // deoptimizations.
+ add_to_hierarchy(k, CHECK_NULL); // No exception, but can block
+
+ // But, do not add to system dictionary.
+ }
+
+ k->eager_initialize(THREAD);
+
+ // notify jvmti
+ if (JvmtiExport::should_post_class_load()) {
+ assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
+ JvmtiExport::post_class_load((JavaThread *) THREAD, k());
+ }
+ }
+
return k();
}
diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp
index 38d27d848..beade180f 100644
--- a/src/share/vm/classfile/systemDictionary.hpp
+++ b/src/share/vm/classfile/systemDictionary.hpp
@@ -228,6 +228,16 @@ public:
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
+ TRAPS) {
+ KlassHandle nullHandle;
+ return parse_stream(class_name, class_loader, protection_domain, st, nullHandle, NULL, THREAD);
+ }
+ static klassOop parse_stream(symbolHandle class_name,
+ Handle class_loader,
+ Handle protection_domain,
+ ClassFileStream* st,
+ KlassHandle host_klass,
+ GrowableArray<Handle>* cp_patches,
TRAPS);
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
diff --git a/src/share/vm/classfile/verifier.cpp b/src/share/vm/classfile/verifier.cpp
index 8373f9bea..179de12ea 100644
--- a/src/share/vm/classfile/verifier.cpp
+++ b/src/share/vm/classfile/verifier.cpp
@@ -1600,7 +1600,11 @@ void ClassVerifier::verify_ldc(
types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
verify_cp_type(index, cp, types, CHECK_VERIFY(this));
}
- if (tag.is_string() || tag.is_unresolved_string()) {
+ if (tag.is_string() && cp->is_pseudo_string_at(index)) {
+ current_frame->push_stack(
+ VerificationType::reference_type(
+ vmSymbols::java_lang_Object()), CHECK_VERIFY(this));
+ } else if (tag.is_string() || tag.is_unresolved_string()) {
current_frame->push_stack(
VerificationType::reference_type(
vmSymbols::java_lang_String()), CHECK_VERIFY(this));
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp
deleted file mode 100644
index 8ed8b809e..000000000
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright 2001-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-// CopyrightVersion 1.2
-
-# include "incls/_precompiled.incl"
-# include "incls/_concurrentGCThread.cpp.incl"
-
-bool ConcurrentGCThread::_should_terminate = false;
-bool ConcurrentGCThread::_has_terminated = false;
-int ConcurrentGCThread::_CGC_flag = CGC_nil;
-
-SuspendibleThreadSet ConcurrentGCThread::_sts;
-
-ConcurrentGCThread::ConcurrentGCThread() {
- _sts.initialize();
-};
-
-void ConcurrentGCThread::stopWorldAndDo(VoidClosure* op) {
- MutexLockerEx x(Heap_lock,
- Mutex::_no_safepoint_check_flag);
- // warning("CGC: about to try stopping world");
- SafepointSynchronize::begin();
- // warning("CGC: successfully stopped world");
- op->do_void();
- SafepointSynchronize::end();
- // warning("CGC: successfully restarted world");
-}
-
-void ConcurrentGCThread::safepoint_synchronize() {
- _sts.suspend_all();
-}
-
-void ConcurrentGCThread::safepoint_desynchronize() {
- _sts.resume_all();
-}
-
-void ConcurrentGCThread::create_and_start() {
- if (os::create_thread(this, os::cgc_thread)) {
- // XXX: need to set this to low priority
- // unless "agressive mode" set; priority
- // should be just less than that of VMThread.
- os::set_priority(this, NearMaxPriority);
- if (!_should_terminate && !DisableStartThread) {
- os::start_thread(this);
- }
- }
-}
-
-void ConcurrentGCThread::initialize_in_thread() {
- this->record_stack_base_and_size();
- this->initialize_thread_local_storage();
- this->set_active_handles(JNIHandleBlock::allocate_block());
- // From this time Thread::current() should be working.
- assert(this == Thread::current(), "just checking");
-}
-
-void ConcurrentGCThread::wait_for_universe_init() {
- MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
- while (!is_init_completed() && !_should_terminate) {
- CGC_lock->wait(Mutex::_no_safepoint_check_flag, 200);
- }
-}
-
-void ConcurrentGCThread::terminate() {
- // Signal that it is terminated
- {
- MutexLockerEx mu(Terminator_lock,
- Mutex::_no_safepoint_check_flag);
- _has_terminated = true;
- Terminator_lock->notify();
- }
-
- // Thread destructor usually does this..
- ThreadLocalStorage::set_thread(NULL);
-}
-
-
-void SuspendibleThreadSet::initialize_work() {
- MutexLocker x(STS_init_lock);
- if (!_initialized) {
- _m = new Monitor(Mutex::leaf,
- "SuspendibleThreadSetLock", true);
- _async = 0;
- _async_stop = false;
- _async_stopped = 0;
- _initialized = true;
- }
-}
-
-void SuspendibleThreadSet::join() {
- initialize();
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
- _async++;
- assert(_async > 0, "Huh.");
-}
-
-void SuspendibleThreadSet::leave() {
- assert(_initialized, "Must be initialized.");
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- _async--;
- assert(_async >= 0, "Huh.");
- if (_async_stop) _m->notify_all();
-}
-
-void SuspendibleThreadSet::yield(const char* id) {
- assert(_initialized, "Must be initialized.");
- if (_async_stop) {
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- if (_async_stop) {
- _async_stopped++;
- assert(_async_stopped > 0, "Huh.");
- if (_async_stopped == _async) {
- if (ConcGCYieldTimeout > 0) {
- double now = os::elapsedTime();
- guarantee((now - _suspend_all_start) * 1000.0 <
- (double)ConcGCYieldTimeout,
- "Long delay; whodunit?");
- }
- }
- _m->notify_all();
- while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
- _async_stopped--;
- assert(_async >= 0, "Huh");
- _m->notify_all();
- }
- }
-}
-
-void SuspendibleThreadSet::suspend_all() {
- initialize(); // If necessary.
- if (ConcGCYieldTimeout > 0) {
- _suspend_all_start = os::elapsedTime();
- }
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- assert(!_async_stop, "Only one at a time.");
- _async_stop = true;
- while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
-}
-
-void SuspendibleThreadSet::resume_all() {
- assert(_initialized, "Must be initialized.");
- MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
- assert(_async_stopped == _async, "Huh.");
- _async_stop = false;
- _m->notify_all();
-}
-
-static void _sltLoop(JavaThread* thread, TRAPS) {
- SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
- slt->loop();
-}
-
-SurrogateLockerThread::SurrogateLockerThread() :
- JavaThread(&_sltLoop),
- _monitor(Mutex::nonleaf, "SLTMonitor"),
- _buffer(empty)
-{}
-
-SurrogateLockerThread* SurrogateLockerThread::make(TRAPS) {
- klassOop k =
- SystemDictionary::resolve_or_fail(vmSymbolHandles::java_lang_Thread(),
- true, CHECK_NULL);
- instanceKlassHandle klass (THREAD, k);
- instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL);
-
- const char thread_name[] = "Surrogate Locker Thread (CMS)";
- Handle string = java_lang_String::create_from_str(thread_name, CHECK_NULL);
-
- // Initialize thread_oop to put it into the system threadGroup
- Handle thread_group (THREAD, Universe::system_thread_group());
- JavaValue result(T_VOID);
- JavaCalls::call_special(&result, thread_oop,
- klass,
- vmSymbolHandles::object_initializer_name(),
- vmSymbolHandles::threadgroup_string_void_signature(),
- thread_group,
- string,
- CHECK_NULL);
-
- SurrogateLockerThread* res;
- {
- MutexLocker mu(Threads_lock);
- res = new SurrogateLockerThread();
-
- // At this point it may be possible that no osthread was created for the
- // JavaThread due to lack of memory. We would have to throw an exception
- // in that case. However, since this must work and we do not allow
- // exceptions anyway, check and abort if this fails.
- if (res == NULL || res->osthread() == NULL) {
- vm_exit_during_initialization("java.lang.OutOfMemoryError",
- "unable to create new native thread");
- }
- java_lang_Thread::set_thread(thread_oop(), res);
- java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
- java_lang_Thread::set_daemon(thread_oop());
-
- res->set_threadObj(thread_oop());
- Threads::add(res);
- Thread::start(res);
- }
- os::yield(); // This seems to help with initial start-up of SLT
- return res;
-}
-
-void SurrogateLockerThread::manipulatePLL(SLT_msg_type msg) {
- MutexLockerEx x(&_monitor, Mutex::_no_safepoint_check_flag);
- assert(_buffer == empty, "Should be empty");
- assert(msg != empty, "empty message");
- _buffer = msg;
- while (_buffer != empty) {
- _monitor.notify();
- _monitor.wait(Mutex::_no_safepoint_check_flag);
- }
-}
-
-// ======= Surrogate Locker Thread =============
-
-void SurrogateLockerThread::loop() {
- BasicLock pll_basic_lock;
- SLT_msg_type msg;
- debug_only(unsigned int owned = 0;)
-
- while (/* !isTerminated() */ 1) {
- {
- MutexLocker x(&_monitor);
- // Since we are a JavaThread, we can't be here at a safepoint.
- assert(!SafepointSynchronize::is_at_safepoint(),
- "SLT is a JavaThread");
- // wait for msg buffer to become non-empty
- while (_buffer == empty) {
- _monitor.notify();
- _monitor.wait();
- }
- msg = _buffer;
- }
- switch(msg) {
- case acquirePLL: {
- instanceRefKlass::acquire_pending_list_lock(&pll_basic_lock);
- debug_only(owned++;)
- break;
- }
- case releaseAndNotifyPLL: {
- assert(owned > 0, "Don't have PLL");
- instanceRefKlass::release_and_notify_pending_list_lock(&pll_basic_lock);
- debug_only(owned--;)
- break;
- }
- case empty:
- default: {
- guarantee(false,"Unexpected message in _buffer");
- break;
- }
- }
- {
- MutexLocker x(&_monitor);
- // Since we are a JavaThread, we can't be here at a safepoint.
- assert(!SafepointSynchronize::is_at_safepoint(),
- "SLT is a JavaThread");
- _buffer = empty;
- _monitor.notify();
- }
- }
- assert(!_monitor.owned_by_self(), "Should unlock before exit.");
-}
-
-
-// ===== STS Access From Outside CGCT =====
-
-void ConcurrentGCThread::stsYield(const char* id) {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.yield(id);
-}
-
-bool ConcurrentGCThread::stsShouldYield() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- return _sts.should_yield();
-}
-
-void ConcurrentGCThread::stsJoin() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.join();
-}
-
-void ConcurrentGCThread::stsLeave() {
- assert( Thread::current()->is_ConcurrentGC_thread(),
- "only a conc GC thread can call this" );
- _sts.leave();
-}
diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp
deleted file mode 100644
index db6cc903d..000000000
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2001-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-class VoidClosure;
-
-// A SuspendibleThreadSet is (obviously) a set of threads that can be
-// suspended. A thread can join and later leave the set, and periodically
-// yield. If some thread (not in the set) requests, via suspend_all, that
-// the threads be suspended, then the requesting thread is blocked until
-// all the threads in the set have yielded or left the set. (Threads may
-// not enter the set when an attempted suspension is in progress.) The
-// suspending thread later calls resume_all, allowing the suspended threads
-// to continue.
-
-class SuspendibleThreadSet {
- Monitor* _m;
- int _async;
- bool _async_stop;
- int _async_stopped;
- bool _initialized;
- double _suspend_all_start;
-
- void initialize_work();
-
- public:
- SuspendibleThreadSet() : _initialized(false) {}
-
- // Add the current thread to the set. May block if a suspension
- // is in progress.
- void join();
- // Removes the current thread from the set.
- void leave();
- // Returns "true" iff an suspension is in progress.
- bool should_yield() { return _async_stop; }
- // Suspends the current thread if a suspension is in progress (for
- // the duration of the suspension.)
- void yield(const char* id);
- // Return when all threads in the set are suspended.
- void suspend_all();
- // Allow suspended threads to resume.
- void resume_all();
- // Redundant initializations okay.
- void initialize() {
- // Double-check dirty read idiom.
- if (!_initialized) initialize_work();
- }
-};
-
-
-class ConcurrentGCThread: public NamedThread {
- friend class VMStructs;
-
-protected:
- static bool _should_terminate;
- static bool _has_terminated;
-
- enum CGC_flag_type {
- CGC_nil = 0x0,
- CGC_dont_suspend = 0x1,
- CGC_CGC_safepoint = 0x2,
- CGC_VM_safepoint = 0x4
- };
-
- static int _CGC_flag;
-
- static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; }
- static int set_CGC_flag(int b) { return _CGC_flag |= b; }
- static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
-
- void stopWorldAndDo(VoidClosure* op);
-
- // All instances share this one set.
- static SuspendibleThreadSet _sts;
-
- // Create and start the thread (setting it's priority high.)
- void create_and_start();
-
- // Do initialization steps in the thread: record stack base and size,
- // init thread local storage, set JNI handle block.
- void initialize_in_thread();
-
- // Wait until Universe::is_fully_initialized();
- void wait_for_universe_init();
-
- // Record that the current thread is terminating, and will do more
- // concurrent work.
- void terminate();
-
-public:
- // Constructor
-
- ConcurrentGCThread();
- ~ConcurrentGCThread() {} // Exists to call NamedThread destructor.
-
- // Tester
- bool is_ConcurrentGC_thread() const { return true; }
-
- static void safepoint_synchronize();
- static void safepoint_desynchronize();
-
- // All overridings should probably do _sts::yield, but we allow
- // overriding for distinguished debugging messages. Default is to do
- // nothing.
- virtual void yield() {}
-
- bool should_yield() { return _sts.should_yield(); }
-
- // they are prefixed by sts since there are already yield() and
- // should_yield() (non-static) methods in this class and it was an
- // easy way to differentiate them.
- static void stsYield(const char* id);
- static bool stsShouldYield();
- static void stsJoin();
- static void stsLeave();
-
-};
-
-// The SurrogateLockerThread is used by concurrent GC threads for
-// manipulating Java monitors, in particular, currently for
-// manipulating the pending_list_lock. XXX
-class SurrogateLockerThread: public JavaThread {
- friend class VMStructs;
- public:
- enum SLT_msg_type {
- empty = 0, // no message
- acquirePLL, // acquire pending list lock
- releaseAndNotifyPLL // notify and release pending list lock
- };
- private:
- // the following are shared with the CMSThread
- SLT_msg_type _buffer; // communication buffer
- Monitor _monitor; // monitor controlling buffer
- BasicLock _basicLock; // used for PLL locking
-
- public:
- static SurrogateLockerThread* make(TRAPS);
-
- SurrogateLockerThread();
-
- bool is_hidden_from_external_view() const { return true; }
-
- void loop(); // main method
-
- void manipulatePLL(SLT_msg_type msg);
-
-};
diff --git a/src/share/vm/gc_implementation/g1/ptrQueue.cpp b/src/share/vm/gc_implementation/g1/ptrQueue.cpp
index 7d1092bdc..157383237 100644
--- a/src/share/vm/gc_implementation/g1/ptrQueue.cpp
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.cpp
@@ -30,7 +30,7 @@ PtrQueue::PtrQueue(PtrQueueSet* qset_, bool perm) :
_perm(perm), _lock(NULL)
{}
-PtrQueue::~PtrQueue() {
+void PtrQueue::flush() {
if (!_perm && _buf != NULL) {
if (_index == _sz) {
// No work to do.
@@ -41,8 +41,9 @@ PtrQueue::~PtrQueue() {
_buf[byte_index_to_index((int)i)] = NULL;
}
qset()->enqueue_complete_buffer(_buf);
- _buf = NULL;
}
+ _buf = NULL;
+ _index = 0;
}
}
diff --git a/src/share/vm/gc_implementation/g1/ptrQueue.hpp b/src/share/vm/gc_implementation/g1/ptrQueue.hpp
index 307920061..899801039 100644
--- a/src/share/vm/gc_implementation/g1/ptrQueue.hpp
+++ b/src/share/vm/gc_implementation/g1/ptrQueue.hpp
@@ -62,7 +62,9 @@ public:
// given PtrQueueSet.
PtrQueue(PtrQueueSet*, bool perm = false);
// Release any contained resources.
- ~PtrQueue();
+ void flush();
+ // Calls flush() when destroyed.
+ ~PtrQueue() { flush(); }
// Associate a lock with a ptr queue.
void set_lock(Mutex* lock) { _lock = lock; }
diff --git a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
index 40fb6a1b1..310ad40d1 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
@@ -90,10 +90,10 @@ void PSMarkSweepDecorator::precompact() {
*/
bool skip_dead = ((PSMarkSweep::total_invocations() % MarkSweepAlwaysCompactCount) != 0);
- ssize_t allowed_deadspace = 0;
+ size_t allowed_deadspace = 0;
if (skip_dead) {
- int ratio = allowed_dead_ratio();
- allowed_deadspace = (space()->capacity_in_bytes() * ratio / 100) / HeapWordSize;
+ const size_t ratio = allowed_dead_ratio();
+ allowed_deadspace = space()->capacity_in_words() * ratio / 100;
}
// Fetch the current destination decorator
@@ -271,10 +271,10 @@ void PSMarkSweepDecorator::precompact() {
dest->set_compaction_top(compact_top);
}
-bool PSMarkSweepDecorator::insert_deadspace(ssize_t& allowed_deadspace_words,
- HeapWord* q, size_t deadlength) {
- allowed_deadspace_words -= deadlength;
- if (allowed_deadspace_words >= 0) {
+bool PSMarkSweepDecorator::insert_deadspace(size_t& allowed_deadspace_words,
+ HeapWord* q, size_t deadlength) {
+ if (allowed_deadspace_words >= deadlength) {
+ allowed_deadspace_words -= deadlength;
oop(q)->set_mark(markOopDesc::prototype()->set_marked());
const size_t aligned_min_int_array_size =
align_object_size(typeArrayOopDesc::header_size(T_INT));
diff --git a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
index 4c7cfdcb5..affd17edc 100644
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
@@ -39,14 +39,16 @@ class PSMarkSweepDecorator: public CHeapObj {
HeapWord* _first_dead;
HeapWord* _end_of_live;
HeapWord* _compaction_top;
- unsigned int _allowed_dead_ratio;
+ size_t _allowed_dead_ratio;
- bool insert_deadspace(ssize_t& allowed_deadspace_words, HeapWord* q, size_t word_len);
+ bool insert_deadspace(size_t& allowed_deadspace_words, HeapWord* q,
+ size_t word_len);
public:
PSMarkSweepDecorator(MutableSpace* space, ObjectStartArray* start_array,
- unsigned int allowed_dead_ratio) :
- _space(space), _start_array(start_array), _allowed_dead_ratio(allowed_dead_ratio) { }
+ size_t allowed_dead_ratio) :
+ _space(space), _start_array(start_array),
+ _allowed_dead_ratio(allowed_dead_ratio) { }
// During a compacting collection, we need to collapse objects into
// spaces in a given order. We want to fill space A, space B, and so
@@ -57,14 +59,14 @@ class PSMarkSweepDecorator: public CHeapObj {
static PSMarkSweepDecorator* destination_decorator();
// Accessors
- MutableSpace* space() { return _space; }
- ObjectStartArray* start_array() { return _start_array; }
+ MutableSpace* space() { return _space; }
+ ObjectStartArray* start_array() { return _start_array; }
- HeapWord* compaction_top() { return _compaction_top; }
- void set_compaction_top(HeapWord* value) { _compaction_top = value; }
+ HeapWord* compaction_top() { return _compaction_top; }
+ void set_compaction_top(HeapWord* value) { _compaction_top = value; }
- unsigned int allowed_dead_ratio() { return _allowed_dead_ratio; }
- void set_allowed_dead_ratio(unsigned int value) { _allowed_dead_ratio = value; }
+ size_t allowed_dead_ratio() { return _allowed_dead_ratio; }
+ void set_allowed_dead_ratio(size_t value) { _allowed_dead_ratio = value; }
// Work methods
void adjust_pointers();
diff --git a/src/share/vm/includeDB_gc_parallel b/src/share/vm/includeDB_gc_parallel
index 1120e9b6c..a03218540 100644
--- a/src/share/vm/includeDB_gc_parallel
+++ b/src/share/vm/includeDB_gc_parallel
@@ -30,6 +30,12 @@ collectorPolicy.cpp cmsGCAdaptivePolicyCounters.hpp
compiledICHolderKlass.cpp oop.pcgc.inline.hpp
+constantPoolKlass.cpp cardTableRS.hpp
+constantPoolKlass.cpp oop.pcgc.inline.hpp
+constantPoolKlass.cpp psPromotionManager.inline.hpp
+constantPoolKlass.cpp psScavenge.inline.hpp
+constantPoolKlass.cpp parOopClosures.inline.hpp
+
genCollectedHeap.cpp concurrentMarkSweepThread.hpp
genCollectedHeap.cpp vmCMSOperations.hpp
diff --git a/src/share/vm/memory/space.cpp b/src/share/vm/memory/space.cpp
index 37e6f61d2..82529444c 100644
--- a/src/share/vm/memory/space.cpp
+++ b/src/share/vm/memory/space.cpp
@@ -997,11 +997,11 @@ void OffsetTableContigSpace::serialize_block_offset_array_offsets(
}
-int TenuredSpace::allowed_dead_ratio() const {
+size_t TenuredSpace::allowed_dead_ratio() const {
return MarkSweepDeadRatio;
}
-int ContigPermSpace::allowed_dead_ratio() const {
+size_t ContigPermSpace::allowed_dead_ratio() const {
return PermMarkSweepDeadRatio;
}
diff --git a/src/share/vm/memory/space.hpp b/src/share/vm/memory/space.hpp
index 8edfd49e4..a102c5f22 100644
--- a/src/share/vm/memory/space.hpp
+++ b/src/share/vm/memory/space.hpp
@@ -421,7 +421,7 @@ public:
// The maximum percentage of objects that can be dead in the compacted
// live part of a compacted space ("deadwood" support.)
- virtual int allowed_dead_ratio() const { return 0; };
+ virtual size_t allowed_dead_ratio() const { return 0; };
// Some contiguous spaces may maintain some data structures that should
// be updated whenever an allocation crosses a boundary. This function
@@ -507,7 +507,7 @@ protected:
\
size_t allowed_deadspace = 0; \
if (skip_dead) { \
- int ratio = allowed_dead_ratio(); \
+ const size_t ratio = allowed_dead_ratio(); \
allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize; \
} \
\
@@ -1079,7 +1079,7 @@ class TenuredSpace: public OffsetTableContigSpace {
friend class VMStructs;
protected:
// Mark sweep support
- int allowed_dead_ratio() const;
+ size_t allowed_dead_ratio() const;
public:
// Constructor
TenuredSpace(BlockOffsetSharedArray* sharedOffsetArray,
@@ -1094,7 +1094,7 @@ class ContigPermSpace: public OffsetTableContigSpace {
friend class VMStructs;
protected:
// Mark sweep support
- int allowed_dead_ratio() const;
+ size_t allowed_dead_ratio() const;
public:
// Constructor
ContigPermSpace(BlockOffsetSharedArray* sharedOffsetArray, MemRegion mr) :
diff --git a/src/share/vm/memory/tenuredGeneration.hpp b/src/share/vm/memory/tenuredGeneration.hpp
index 18aa8b37f..a7c22c9bb 100644
--- a/src/share/vm/memory/tenuredGeneration.hpp
+++ b/src/share/vm/memory/tenuredGeneration.hpp
@@ -73,7 +73,6 @@ class TenuredGeneration: public OneContigSpaceCardGeneration {
// Mark sweep support
void compute_new_size();
- int allowed_dead_ratio() const;
virtual void gc_prologue(bool full);
virtual void gc_epilogue(bool full);
diff --git a/src/share/vm/oops/constantPoolKlass.cpp b/src/share/vm/oops/constantPoolKlass.cpp
index c112597ab..593b74668 100644
--- a/src/share/vm/oops/constantPoolKlass.cpp
+++ b/src/share/vm/oops/constantPoolKlass.cpp
@@ -35,6 +35,7 @@ constantPoolOop constantPoolKlass::allocate(int length, TRAPS) {
c->set_tags(NULL);
c->set_cache(NULL);
c->set_pool_holder(NULL);
+ c->set_flags(0);
// only set to non-zero if constant pool is merged by RedefineClasses
c->set_orig_length(0);
// all fields are initialized; needed for GC
@@ -261,10 +262,32 @@ constantPoolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
void constantPoolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_constantPool(), "should be constant pool");
+ constantPoolOop cp = (constantPoolOop) obj;
+ if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+ oop* base = (oop*)cp->base();
+ for (int i = 0; i < cp->length(); ++i, ++base) {
+ if (cp->tag_at(i).is_string()) {
+ if (PSScavenge::should_scavenge(base)) {
+ pm->claim_or_forward_breadth(base);
+ }
+ }
+ }
+ }
}
void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
assert(obj->is_constantPool(), "should be constant pool");
+ constantPoolOop cp = (constantPoolOop) obj;
+ if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
+ oop* base = (oop*)cp->base();
+ for (int i = 0; i < cp->length(); ++i, ++base) {
+ if (cp->tag_at(i).is_string()) {
+ if (PSScavenge::should_scavenge(base)) {
+ pm->claim_or_forward_depth(base);
+ }
+ }
+ }
+ }
}
#endif // SERIALGC
@@ -278,6 +301,11 @@ void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
assert(obj->is_constantPool(), "must be constantPool");
Klass::oop_print_on(obj, st);
constantPoolOop cp = constantPoolOop(obj);
+ if (cp->flags() != 0) {
+ st->print(" - flags : 0x%x", cp->flags());
+ if (cp->has_pseudo_string()) st->print(" has_pseudo_string");
+ st->cr();
+ }
// Temp. remove cache so we can do lookups with original indicies.
constantPoolCacheHandle cache (THREAD, cp->cache());
@@ -302,7 +330,11 @@ void constantPoolKlass::oop_print_on(oop obj, outputStream* st) {
break;
case JVM_CONSTANT_UnresolvedString :
case JVM_CONSTANT_String :
- anObj = cp->string_at(index, CATCH);
+ if (cp->is_pseudo_string_at(index)) {
+ anObj = cp->pseudo_string_at(index);
+ } else {
+ anObj = cp->string_at(index, CATCH);
+ }
anObj->print_value_on(st);
st->print(" {0x%lx}", (address)anObj);
break;
@@ -382,8 +414,12 @@ void constantPoolKlass::oop_verify_on(oop obj, outputStream* st) {
"should be symbol or instance");
}
if (cp->tag_at(i).is_string()) {
- guarantee((*base)->is_perm(), "should be in permspace");
- guarantee((*base)->is_instance(), "should be instance");
+ if (!cp->has_pseudo_string()) {
+ guarantee((*base)->is_perm(), "should be in permspace");
+ guarantee((*base)->is_instance(), "should be instance");
+ } else {
+ // can be non-perm, can be non-instance (array)
+ }
}
base++;
}
diff --git a/src/share/vm/oops/constantPoolOop.cpp b/src/share/vm/oops/constantPoolOop.cpp
index cd8a9d16f..263b7bbe4 100644
--- a/src/share/vm/oops/constantPoolOop.cpp
+++ b/src/share/vm/oops/constantPoolOop.cpp
@@ -25,6 +25,18 @@
# include "incls/_precompiled.incl"
# include "incls/_constantPoolOop.cpp.incl"
+void constantPoolOopDesc::set_flag_at(FlagBit fb) {
+ const int MAX_STATE_CHANGES = 2;
+ for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) {
+ int oflags = _flags;
+ int nflags = oflags | (1 << (int)fb);
+ if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags)
+ return;
+ }
+ assert(false, "failed to cmpxchg flags");
+ _flags |= (1 << (int)fb); // better than nothing
+}
+
klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
// A resolved constantPool entry will contain a klassOop, otherwise a symbolOop.
// It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
@@ -333,8 +345,10 @@ char* constantPoolOopDesc::string_at_noresolve(int which) {
oop entry = *(obj_at_addr(which));
if (entry->is_symbol()) {
return ((symbolOop)entry)->as_C_string();
- } else {
+ } else if (java_lang_String::is_instance(entry)) {
return java_lang_String::as_utf8_string(entry);
+ } else {
+ return (char*)"<pseudo-string>";
}
}
@@ -385,6 +399,19 @@ oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which,
}
+bool constantPoolOopDesc::is_pseudo_string_at(int which) {
+ oop entry = *(obj_at_addr(which));
+ if (entry->is_symbol())
+ // Not yet resolved, but it will resolve to a string.
+ return false;
+ else if (java_lang_String::is_instance(entry))
+ return false; // actually, it might be a non-interned or non-perm string
+ else
+ // truly pseudo
+ return true;
+}
+
+
bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k,
int which) {
// Names are interned, so we can compare symbolOops directly
diff --git a/src/share/vm/oops/constantPoolOop.hpp b/src/share/vm/oops/constantPoolOop.hpp
index 907d71dfd..562705909 100644
--- a/src/share/vm/oops/constantPoolOop.hpp
+++ b/src/share/vm/oops/constantPoolOop.hpp
@@ -41,6 +41,7 @@ class constantPoolOopDesc : public oopDesc {
typeArrayOop _tags; // the tag array describing the constant pool's contents
constantPoolCacheOop _cache; // the cache holding interpreter runtime information
klassOop _pool_holder; // the corresponding class
+ int _flags; // a few header bits to describe contents for GC
int _length; // number of elements in the array
// only set to non-zero if constant pool is merged by RedefineClasses
int _orig_length;
@@ -49,6 +50,16 @@ class constantPoolOopDesc : public oopDesc {
void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); }
void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); }
+ enum FlagBit {
+ FB_has_pseudo_string = 2
+ };
+
+ int flags() const { return _flags; }
+ void set_flags(int f) { _flags = f; }
+ bool flag_at(FlagBit fb) const { return (_flags & (1 << (int)fb)) != 0; }
+ void set_flag_at(FlagBit fb);
+ // no clear_flag_at function; they only increase
+
private:
intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); }
oop* tags_addr() { return (oop*)&_tags; }
@@ -82,6 +93,9 @@ class constantPoolOopDesc : public oopDesc {
public:
typeArrayOop tags() const { return _tags; }
+ bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); }
+ void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); }
+
// Klass holding pool
klassOop pool_holder() const { return _pool_holder; }
void set_pool_holder(klassOop k) { oop_store_without_check((oop*)&_pool_holder, (oop) k); }
@@ -272,6 +286,27 @@ class constantPoolOopDesc : public oopDesc {
return string_at_impl(h_this, which, CHECK_NULL);
}
+ // A "pseudo-string" is an non-string oop that has found is way into
+ // a String entry.
+ // Under AnonymousClasses this can happen if the user patches a live
+ // object into a CONSTANT_String entry of an anonymous class.
+ // Method oops internally created for method handles may also
+ // use pseudo-strings to link themselves to related metaobjects.
+
+ bool is_pseudo_string_at(int which);
+
+ oop pseudo_string_at(int which) {
+ assert(tag_at(which).is_string(), "Corrupted constant pool");
+ return *obj_at_addr(which);
+ }
+
+ void pseudo_string_at_put(int which, oop x) {
+ assert(AnonymousClasses, "");
+ set_pseudo_string(); // mark header
+ assert(tag_at(which).is_string() || tag_at(which).is_unresolved_string(), "Corrupted constant pool");
+ string_at_put(which, x); // this works just fine
+ }
+
// only called when we are sure a string entry is already resolved (via an
// earlier string_at call.
oop resolved_string_at(int which) {
@@ -293,6 +328,7 @@ class constantPoolOopDesc : public oopDesc {
// UTF8 char* representation was chosen to avoid conversion of
// java_lang_Strings at resolved entries into symbolOops
// or vice versa.
+ // Caller is responsible for checking for pseudo-strings.
char* string_at_noresolve(int which);
jint name_and_type_at(int which) {
diff --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp
index e96bd6bb7..8586ecba0 100644
--- a/src/share/vm/oops/instanceKlass.hpp
+++ b/src/share/vm/oops/instanceKlass.hpp
@@ -147,6 +147,10 @@ class instanceKlass: public Klass {
oop _class_loader;
// Protection domain.
oop _protection_domain;
+ // Host class, which grants its access privileges to this class also.
+ // This is only non-null for an anonymous class (AnonymousClasses enabled).
+ // The host class is either named, or a previously loaded anonymous class.
+ klassOop _host_klass;
// Class signers.
objArrayOop _signers;
// Name of source file containing this klass, NULL if not specified.
@@ -375,6 +379,11 @@ class instanceKlass: public Klass {
oop protection_domain() { return _protection_domain; }
void set_protection_domain(oop pd) { oop_store((oop*) &_protection_domain, pd); }
+ // host class
+ oop host_klass() const { return _host_klass; }
+ void set_host_klass(oop host) { oop_store((oop*) &_host_klass, host); }
+ bool is_anonymous() const { return _host_klass != NULL; }
+
// signers
objArrayOop signers() const { return _signers; }
void set_signers(objArrayOop s) { oop_store((oop*) &_signers, oop(s)); }
@@ -709,6 +718,7 @@ private:
oop* adr_constants() const { return (oop*)&this->_constants;}
oop* adr_class_loader() const { return (oop*)&this->_class_loader;}
oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
+ oop* adr_host_klass() const { return (oop*)&this->_host_klass;}
oop* adr_signers() const { return (oop*)&this->_signers;}
oop* adr_source_file_name() const { return (oop*)&this->_source_file_name;}
oop* adr_source_debug_extension() const { return (oop*)&this->_source_debug_extension;}
diff --git a/src/share/vm/oops/instanceKlassKlass.cpp b/src/share/vm/oops/instanceKlassKlass.cpp
index 66e884f39..94a6bee03 100644
--- a/src/share/vm/oops/instanceKlassKlass.cpp
+++ b/src/share/vm/oops/instanceKlassKlass.cpp
@@ -81,6 +81,7 @@ void instanceKlassKlass::oop_follow_contents(oop obj) {
MarkSweep::mark_and_push(ik->adr_source_debug_extension());
MarkSweep::mark_and_push(ik->adr_inner_classes());
MarkSweep::mark_and_push(ik->adr_protection_domain());
+ MarkSweep::mark_and_push(ik->adr_host_klass());
MarkSweep::mark_and_push(ik->adr_signers());
MarkSweep::mark_and_push(ik->adr_generic_signature());
MarkSweep::mark_and_push(ik->adr_class_annotations());
@@ -120,6 +121,7 @@ void instanceKlassKlass::oop_follow_contents(ParCompactionManager* cm,
PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
+ PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
PSParallelCompact::mark_and_push(cm, ik->adr_signers());
PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
@@ -159,6 +161,7 @@ int instanceKlassKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
blk->do_oop(ik->adr_constants());
blk->do_oop(ik->adr_class_loader());
blk->do_oop(ik->adr_protection_domain());
+ blk->do_oop(ik->adr_host_klass());
blk->do_oop(ik->adr_signers());
blk->do_oop(ik->adr_source_file_name());
blk->do_oop(ik->adr_source_debug_extension());
@@ -211,6 +214,8 @@ int instanceKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk,
if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_protection_domain();
if (mr.contains(adr)) blk->do_oop(adr);
+ adr = ik->adr_host_klass();
+ if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_signers();
if (mr.contains(adr)) blk->do_oop(adr);
adr = ik->adr_source_file_name();
@@ -260,6 +265,7 @@ int instanceKlassKlass::oop_adjust_pointers(oop obj) {
MarkSweep::adjust_pointer(ik->adr_constants());
MarkSweep::adjust_pointer(ik->adr_class_loader());
MarkSweep::adjust_pointer(ik->adr_protection_domain());
+ MarkSweep::adjust_pointer(ik->adr_host_klass());
MarkSweep::adjust_pointer(ik->adr_signers());
MarkSweep::adjust_pointer(ik->adr_source_file_name());
MarkSweep::adjust_pointer(ik->adr_source_debug_extension());
@@ -295,6 +301,11 @@ void instanceKlassKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
pm->claim_or_forward_breadth(pd_addr);
}
+ oop* hk_addr = ik->adr_host_klass();
+ if (PSScavenge::should_scavenge(hk_addr)) {
+ pm->claim_or_forward_breadth(hk_addr);
+ }
+
oop* sg_addr = ik->adr_signers();
if (PSScavenge::should_scavenge(sg_addr)) {
pm->claim_or_forward_breadth(sg_addr);
@@ -318,6 +329,11 @@ void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
pm->claim_or_forward_depth(pd_addr);
}
+ oop* hk_addr = ik->adr_host_klass();
+ if (PSScavenge::should_scavenge(hk_addr)) {
+ pm->claim_or_forward_depth(hk_addr);
+ }
+
oop* sg_addr = ik->adr_signers();
if (PSScavenge::should_scavenge(sg_addr)) {
pm->claim_or_forward_depth(sg_addr);
@@ -421,6 +437,7 @@ klassOop instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_
ik->set_constants(NULL);
ik->set_class_loader(NULL);
ik->set_protection_domain(NULL);
+ ik->set_host_klass(NULL);
ik->set_signers(NULL);
ik->set_source_file_name(NULL);
ik->set_source_debug_extension(NULL);
@@ -526,6 +543,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
st->print(" - constants: "); ik->constants()->print_value_on(st); st->cr();
st->print(" - class loader: "); ik->class_loader()->print_value_on(st); st->cr();
st->print(" - protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
+ st->print(" - host class: "); ik->host_klass()->print_value_on(st); st->cr();
st->print(" - signers: "); ik->signers()->print_value_on(st); st->cr();
if (ik->source_file_name() != NULL) {
st->print(" - source file: ");
@@ -626,7 +644,7 @@ void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) {
ik->_verify_count = Universe::verify_count();
#endif
// Verify that klass is present in SystemDictionary
- if (ik->is_loaded()) {
+ if (ik->is_loaded() && !ik->is_anonymous()) {
symbolHandle h_name (thread, ik->name());
Handle h_loader (thread, ik->class_loader());
Handle h_obj(thread, obj);
@@ -764,6 +782,9 @@ void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) {
if (ik->protection_domain() != NULL) {
guarantee(ik->protection_domain()->is_oop(), "should be oop");
}
+ if (ik->host_klass() != NULL) {
+ guarantee(ik->host_klass()->is_oop(), "should be oop");
+ }
if (ik->signers() != NULL) {
guarantee(ik->signers()->is_objArray(), "should be obj array");
}
diff --git a/src/share/vm/oops/klass.cpp b/src/share/vm/oops/klass.cpp
index 8d1fba0f4..a028f65bb 100644
--- a/src/share/vm/oops/klass.cpp
+++ b/src/share/vm/oops/klass.cpp
@@ -478,6 +478,24 @@ void Klass::with_array_klasses_do(void f(klassOop k)) {
const char* Klass::external_name() const {
+ if (oop_is_instance()) {
+ instanceKlass* ik = (instanceKlass*) this;
+ if (ik->is_anonymous()) {
+ assert(AnonymousClasses, "");
+ intptr_t hash = ik->java_mirror()->identity_hash();
+ char hash_buf[40];
+ sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
+ size_t hash_len = strlen(hash_buf);
+
+ size_t result_len = name()->utf8_length();
+ char* result = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
+ name()->as_klass_external_name(result, (int) result_len + 1);
+ assert(strlen(result) == result_len, "");
+ strcpy(result + result_len, hash_buf);
+ assert(strlen(result) == result_len + hash_len, "");
+ return result;
+ }
+ }
return name()->as_klass_external_name();
}
diff --git a/src/share/vm/opto/c2_globals.hpp b/src/share/vm/opto/c2_globals.hpp
index 134209135..844d637e5 100644
--- a/src/share/vm/opto/c2_globals.hpp
+++ b/src/share/vm/opto/c2_globals.hpp
@@ -256,10 +256,10 @@
develop(intx, PrintIdealGraphPort, 4444, \
"Ideal graph printer to network port") \
\
- develop(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
+ notproduct(ccstr, PrintIdealGraphAddress, "127.0.0.1", \
"IP address to connect to visualizer") \
\
- develop(ccstr, PrintIdealGraphFile, NULL, \
+ notproduct(ccstr, PrintIdealGraphFile, NULL, \
"File to dump ideal graph to. If set overrides the " \
"use of the network") \
\
diff --git a/src/share/vm/opto/macro.cpp b/src/share/vm/opto/macro.cpp
index 892f50183..37cee0697 100644
--- a/src/share/vm/opto/macro.cpp
+++ b/src/share/vm/opto/macro.cpp
@@ -1673,7 +1673,6 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
if (klass_node == NULL) {
Node* k_adr = basic_plus_adr(obj, oopDesc::klass_offset_in_bytes());
klass_node = transform_later( LoadKlassNode::make(_igvn, mem, k_adr, _igvn.type(k_adr)->is_ptr()) );
- klass_node->init_req(0, ctrl);
}
Node *proto_node = make_load(ctrl, mem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeX_X, TypeX_X->basic_type());
diff --git a/src/share/vm/opto/parse.hpp b/src/share/vm/opto/parse.hpp
index 0a68a3523..d33acba3e 100644
--- a/src/share/vm/opto/parse.hpp
+++ b/src/share/vm/opto/parse.hpp
@@ -175,7 +175,7 @@ class Parse : public GraphKit {
bool is_SEL_backedge(Block* pred) const{ return is_SEL_head() && pred->rpo() >= rpo(); }
bool is_invariant_local(uint i) const {
const JVMState* jvms = start_map()->jvms();
- if (!jvms->is_loc(i)) return false;
+ if (!jvms->is_loc(i) || flow()->outer()->has_irreducible_entry()) return false;
return flow()->is_invariant_local(i - jvms->locoff());
}
bool can_elide_SEL_phi(uint i) const { assert(is_SEL_head(),""); return is_invariant_local(i); }
diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp
index 81302b712..7f832341c 100644
--- a/src/share/vm/prims/jvm.cpp
+++ b/src/share/vm/prims/jvm.cpp
@@ -744,6 +744,7 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
+ if (source == NULL) source = "__JVM_DefineClass__";
// Since exceptions can be thrown, class initialization can take place
// if name is NULL no check for class name in .class stream has to be made.
@@ -782,7 +783,7 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loa
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
JVMWrapper2("JVM_DefineClass %s", name);
- return jvm_define_class_common(env, name, loader, buf, len, pd, "__JVM_DefineClass__", THREAD);
+ return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
JVM_END
diff --git a/src/share/vm/prims/jvm.h b/src/share/vm/prims/jvm.h
index 131e0ddc9..7dbc38d94 100644
--- a/src/share/vm/prims/jvm.h
+++ b/src/share/vm/prims/jvm.h
@@ -422,6 +422,14 @@ JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
const jbyte *buf, jsize len, jobject pd,
const char *source);
+/* Define a class with a source (MLVM) */
+JNIEXPORT jclass JNICALL
+JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
+ const jbyte *buf, jsize len, jobject pd,
+ const char *source,
+ // same args as JVM_DefineClassWithSource to this point
+ jobjectArray constants);
+
/*
* Reflection support functions
*/
diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp
index c17e02148..081f19fef 100644
--- a/src/share/vm/prims/unsafe.cpp
+++ b/src/share/vm/prims/unsafe.cpp
@@ -837,6 +837,163 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring na
}
UNSAFE_END
+#define DAC_Args CLS"[B["OBJ
+// define a class but do not make it known to the class loader or system dictionary
+// - host_class: supplies context for linkage, access control, protection domain, and class loader
+// - data: bytes of a class file, a raw memory address (length gives the number of bytes)
+// - cp_patches: where non-null entries exist, they replace corresponding CP entries in data
+
+// When you load an anonymous class U, it works as if you changed its name just before loading,
+// to a name that you will never use again. Since the name is lost, no other class can directly
+// link to any member of U. Just after U is loaded, the only way to use it is reflectively,
+// through java.lang.Class methods like Class.newInstance.
+
+// Access checks for linkage sites within U continue to follow the same rules as for named classes.
+// The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
+// An anonymous class also has special privileges to access any member of its host class.
+// This is the main reason why this loading operation is unsafe. The purpose of this is to
+// allow language implementations to simulate "open classes"; a host class in effect gets
+// new code when an anonymous class is loaded alongside it. A less convenient but more
+// standard way to do this is with reflection, which can also be set to ignore access
+// restrictions.
+
+// Access into an anonymous class is possible only through reflection. Therefore, there
+// are no special access rules for calling into an anonymous class. The relaxed access
+// rule for the host class is applied in the opposite direction: A host class reflectively
+// access one of its anonymous classes.
+
+// If you load the same bytecodes twice, you get two different classes. You can reload
+// the same bytecodes with or without varying CP patches.
+
+// By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
+// The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
+// The CONSTANT_Class entry for that name can be patched to refer directly to U1.
+
+// This allows, for example, U2 to use U1 as a superclass or super-interface, or as
+// an outer class (so that U2 is an anonymous inner class of anonymous U1).
+// It is not possible for a named class, or an older anonymous class, to refer by
+// name (via its CP) to a newer anonymous class.
+
+// CP patching may also be used to modify (i.e., hack) the names of methods, classes,
+// or type descriptors used in the loaded anonymous class.
+
+// Finally, CP patching may be used to introduce "live" objects into the constant pool,
+// instead of "dead" strings. A compiled statement like println((Object)"hello") can
+// be changed to println(greeting), where greeting is an arbitrary object created before
+// the anonymous class is loaded. This is useful in dynamic languages, in which
+// various kinds of metaobjects must be introduced as constants into bytecode.
+// Note the cast (Object), which tells the verifier to expect an arbitrary object,
+// not just a literal string. For such ldc instructions, the verifier uses the
+// type Object instead of String, if the loaded constant is not in fact a String.
+
+static oop
+Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
+ jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
+ HeapWord* *temp_alloc,
+ TRAPS) {
+
+ if (UsePerfData) {
+ ClassLoader::unsafe_defineClassCallCounter()->inc();
+ }
+
+ if (data == NULL) {
+ THROW_0(vmSymbols::java_lang_NullPointerException());
+ }
+
+ jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
+ jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
+ HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
+ if (body == NULL) {
+ THROW_0(vmSymbols::java_lang_OutOfMemoryError());
+ }
+
+ // caller responsible to free it:
+ (*temp_alloc) = body;
+
+ {
+ jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
+ Copy::conjoint_words((HeapWord*) array_base, body, word_length);
+ }
+
+ u1* class_bytes = (u1*) body;
+ int class_bytes_length = (int) length;
+ if (class_bytes_length < 0) class_bytes_length = 0;
+ if (class_bytes == NULL
+ || host_class == NULL
+ || length != class_bytes_length)
+ THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+
+ objArrayHandle cp_patches_h;
+ if (cp_patches_jh != NULL) {
+ oop p = JNIHandles::resolve_non_null(cp_patches_jh);
+ if (!p->is_objArray())
+ THROW_0(vmSymbols::java_lang_IllegalArgumentException());
+ cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
+ }
+
+ KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
+ const char* host_source = host_klass->external_name();
+ Handle host_loader(THREAD, host_klass->class_loader());
+ Handle host_domain(THREAD, host_klass->protection_domain());
+
+ GrowableArray<Handle>* cp_patches = NULL;
+ if (cp_patches_h.not_null()) {
+ int alen = cp_patches_h->length();
+ for (int i = alen-1; i >= 0; i--) {
+ oop p = cp_patches_h->obj_at(i);
+ if (p != NULL) {
+ Handle patch(THREAD, p);
+ if (cp_patches == NULL)
+ cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle());
+ cp_patches->at_put(i, patch);
+ }
+ }
+ }
+
+ ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
+
+ instanceKlassHandle anon_klass;
+ {
+ symbolHandle no_class_name;
+ klassOop anonk = SystemDictionary::parse_stream(no_class_name,
+ host_loader, host_domain,
+ &st, host_klass, cp_patches,
+ CHECK_NULL);
+ if (anonk == NULL) return NULL;
+ anon_klass = instanceKlassHandle(THREAD, anonk);
+ }
+
+ // let caller initialize it as needed...
+
+ return anon_klass->java_mirror();
+}
+
+UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
+{
+ UnsafeWrapper("Unsafe_DefineAnonymousClass");
+ ResourceMark rm(THREAD);
+
+ HeapWord* temp_alloc = NULL;
+
+ jobject res_jh = NULL;
+
+ { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
+ host_class, data, cp_patches_jh,
+ &temp_alloc, THREAD);
+ if (res_oop != NULL)
+ res_jh = JNIHandles::make_local(env, res_oop);
+ }
+
+ // try/finally clause:
+ if (temp_alloc != NULL) {
+ FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
+ }
+
+ return (jclass) res_jh;
+}
+UNSAFE_END
+
+
UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
UnsafeWrapper("Unsafe_MonitorEnter");
@@ -1292,6 +1449,9 @@ JNINativeMethod memcopy_methods_15[] = {
{CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
};
+JNINativeMethod anonk_methods[] = {
+ {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
+};
#undef CC
#undef FN_PTR
@@ -1354,6 +1514,15 @@ JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls))
}
}
}
+ if (AnonymousClasses) {
+ env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
+ if (env->ExceptionOccurred()) {
+ if (PrintMiscellaneous && (Verbose || WizardMode)) {
+ tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
+ }
+ env->ExceptionClear();
+ }
+ }
int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
if (PrintMiscellaneous && (Verbose || WizardMode)) {
diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
index cba2b9914..a2476f9c7 100644
--- a/src/share/vm/runtime/globals.hpp
+++ b/src/share/vm/runtime/globals.hpp
@@ -493,7 +493,7 @@ class CommandLineFlags {
develop(bool, DeoptimizeALot, false, \
"deoptimize at every exit from the runtime system") \
\
- develop(ccstrlist, DeoptimizeOnlyAt, "", \
+ notproduct(ccstrlist, DeoptimizeOnlyAt, "", \
"a comma separated list of bcis to deoptimize at") \
\
product(bool, DeoptimizeRandom, false, \
@@ -2792,7 +2792,7 @@ class CommandLineFlags {
product(intx, TargetSurvivorRatio, 50, \
"Desired percentage of survivor space used after scavenge") \
\
- product(intx, MarkSweepDeadRatio, 5, \
+ product(uintx, MarkSweepDeadRatio, 5, \
"Percentage (0-100) of the old gen allowed as dead wood." \
"Serial mark sweep treats this as both the min and max value." \
"CMS uses this value only if it falls back to mark sweep." \
@@ -2801,7 +2801,7 @@ class CommandLineFlags {
"either completely full or completely empty. Par compact also" \
"has a smaller default value; see arguments.cpp.") \
\
- product(intx, PermMarkSweepDeadRatio, 20, \
+ product(uintx, PermMarkSweepDeadRatio, 20, \
"Percentage (0-100) of the perm gen allowed as dead wood." \
"See MarkSweepDeadRatio for collector-specific comments.") \
\
@@ -3230,6 +3230,9 @@ class CommandLineFlags {
"Skip assert() and verify() which page-in unwanted shared " \
"objects. ") \
\
+ product(bool, AnonymousClasses, false, \
+ "support sun.misc.Unsafe.defineAnonymousClass") \
+ \
product(bool, TaggedStackInterpreter, false, \
"Insert tags in interpreter execution stack for oopmap generaion")\
\
diff --git a/src/share/vm/runtime/perfMemory.cpp b/src/share/vm/runtime/perfMemory.cpp
index 0ae679bdd..d48d7b508 100644
--- a/src/share/vm/runtime/perfMemory.cpp
+++ b/src/share/vm/runtime/perfMemory.cpp
@@ -25,6 +25,14 @@
# include "incls/_precompiled.incl"
# include "incls/_perfMemory.cpp.incl"
+// Prefix of performance data file.
+const char PERFDATA_NAME[] = "hsperfdata";
+
+// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
+// character will be included in the sizeof(PERFDATA_NAME) operation.
+static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
+ UINT_CHARS + 1;
+
char* PerfMemory::_start = NULL;
char* PerfMemory::_end = NULL;
char* PerfMemory::_top = NULL;
diff --git a/src/share/vm/runtime/perfMemory.hpp b/src/share/vm/runtime/perfMemory.hpp
index 812ab3bac..0909bfa0c 100644
--- a/src/share/vm/runtime/perfMemory.hpp
+++ b/src/share/vm/runtime/perfMemory.hpp
@@ -95,7 +95,7 @@ typedef struct {
} PerfDataEntry;
// Prefix of performance data file.
-static const char PERFDATA_NAME[] = "hsperfdata";
+extern const char PERFDATA_NAME[];
// UINT_CHARS contains the number of characters holding a process id
// (i.e. pid). pid is defined as unsigned "int" so the maximum possible pid value
@@ -103,11 +103,6 @@ static const char PERFDATA_NAME[] = "hsperfdata";
// string.
static const size_t UINT_CHARS = 10;
-// Add 1 for the '_' character between PERFDATA_NAME and pid. The '\0' terminating
-// character will be included in the sizeof(PERFDATA_NAME) operation.
-static const size_t PERFDATA_FILENAME_LEN = sizeof(PERFDATA_NAME) +
- UINT_CHARS + 1;
-
/* the PerfMemory class manages creation, destruction,
* and allocation of the PerfData region.
*/
diff --git a/src/share/vm/runtime/reflection.cpp b/src/share/vm/runtime/reflection.cpp
index d57b6670d..3bc1b029d 100644
--- a/src/share/vm/runtime/reflection.cpp
+++ b/src/share/vm/runtime/reflection.cpp
@@ -456,10 +456,32 @@ bool Reflection::verify_class_access(klassOop current_class, klassOop new_class,
return can_relax_access_check_for(current_class, new_class, classloader_only);
}
+static bool under_host_klass(instanceKlass* ik, klassOop host_klass) {
+ DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000);
+ for (;;) {
+ klassOop hc = (klassOop) ik->host_klass();
+ if (hc == NULL) return false;
+ if (hc == host_klass) return true;
+ ik = instanceKlass::cast(hc);
+
+ // There's no way to make a host class loop short of patching memory.
+ // Therefore there cannot be a loop here unles there's another bug.
+ // Still, let's check for it.
+ assert(--inf_loop_check > 0, "no host_klass loop");
+ }
+}
+
bool Reflection::can_relax_access_check_for(
klassOop accessor, klassOop accessee, bool classloader_only) {
instanceKlass* accessor_ik = instanceKlass::cast(accessor);
instanceKlass* accessee_ik = instanceKlass::cast(accessee);
+
+ // If either is on the other's host_klass chain, access is OK,
+ // because one is inside the other.
+ if (under_host_klass(accessor_ik, accessee) ||
+ under_host_klass(accessee_ik, accessor))
+ return true;
+
if (RelaxAccessControlCheck ||
(accessor_ik->major_version() < JAVA_1_5_VERSION &&
accessee_ik->major_version() < JAVA_1_5_VERSION)) {
diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp
index 4d97d62c6..2e4c63601 100644
--- a/src/share/vm/runtime/thread.cpp
+++ b/src/share/vm/runtime/thread.cpp
@@ -1422,6 +1422,7 @@ static void ensure_join(JavaThread* thread) {
thread->clear_pending_exception();
}
+
// For any new cleanup additions, please check to see if they need to be applied to
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
@@ -1592,39 +1593,62 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
JvmtiExport::cleanup_thread(this);
}
+#ifndef SERIALGC
+ // We must flush G1-related buffers before removing a thread from
+ // the list of active threads.
+ if (UseG1GC) {
+ flush_barrier_queues();
+ }
+#endif
+
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
Threads::remove(this);
}
+#ifndef SERIALGC
+// Flush G1-related queues.
+void JavaThread::flush_barrier_queues() {
+ satb_mark_queue().flush();
+ dirty_card_queue().flush();
+}
+#endif
+
void JavaThread::cleanup_failed_attach_current_thread() {
+ if (get_thread_profiler() != NULL) {
+ get_thread_profiler()->disengage();
+ ResourceMark rm;
+ get_thread_profiler()->print(get_thread_name());
+ }
- if (get_thread_profiler() != NULL) {
- get_thread_profiler()->disengage();
- ResourceMark rm;
- get_thread_profiler()->print(get_thread_name());
- }
+ if (active_handles() != NULL) {
+ JNIHandleBlock* block = active_handles();
+ set_active_handles(NULL);
+ JNIHandleBlock::release_block(block);
+ }
- if (active_handles() != NULL) {
- JNIHandleBlock* block = active_handles();
- set_active_handles(NULL);
- JNIHandleBlock::release_block(block);
- }
+ if (free_handle_block() != NULL) {
+ JNIHandleBlock* block = free_handle_block();
+ set_free_handle_block(NULL);
+ JNIHandleBlock::release_block(block);
+ }
- if (free_handle_block() != NULL) {
- JNIHandleBlock* block = free_handle_block();
- set_free_handle_block(NULL);
- JNIHandleBlock::release_block(block);
- }
+ if (UseTLAB) {
+ tlab().make_parsable(true); // retire TLAB, if any
+ }
- if (UseTLAB) {
- tlab().make_parsable(true); // retire TLAB, if any
- }
+#ifndef SERIALGC
+ if (UseG1GC) {
+ flush_barrier_queues();
+ }
+#endif
- Threads::remove(this);
- delete this;
+ Threads::remove(this);
+ delete this;
}
+
+
JavaThread* JavaThread::active() {
Thread* thread = ThreadLocalStorage::thread();
assert(thread != NULL, "just checking");
diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp
index 8d05504bb..1ee5c7260 100644
--- a/src/share/vm/runtime/thread.hpp
+++ b/src/share/vm/runtime/thread.hpp
@@ -793,6 +793,8 @@ class JavaThread: public Thread {
DirtyCardQueue _dirty_card_queue; // Thread-local log for dirty cards.
// Set of all such queues.
static DirtyCardQueueSet _dirty_card_queue_set;
+
+ void flush_barrier_queues();
#endif // !SERIALGC
friend class VMThread;
diff --git a/src/share/vm/utilities/array.hpp b/src/share/vm/utilities/array.hpp
index 1c229505f..7dee671cc 100644
--- a/src/share/vm/utilities/array.hpp
+++ b/src/share/vm/utilities/array.hpp
@@ -40,11 +40,18 @@ class ResourceArray: public ResourceObj {
_length = 0;
_data = NULL;
DEBUG_ONLY(init_nesting();)
+ // client may call initialize, at most once
}
ResourceArray(size_t esize, int length) {
+ DEBUG_ONLY(_data = NULL);
+ initialize(esize, length);
+ }
+
+ void initialize(size_t esize, int length) {
assert(length >= 0, "illegal length");
+ assert(_data == NULL, "must be new object");
_length = length;
_data = resource_allocate_bytes(esize * length);
DEBUG_ONLY(init_nesting();)
@@ -111,7 +118,10 @@ class CHeapArray: public CHeapObj {
/* creation */ \
array_name() : base_class() {} \
array_name(const int length) : base_class(esize, length) {} \
- array_name(const int length, const etype fx) : base_class(esize, length) { \
+ array_name(const int length, const etype fx) { initialize(length, fx); } \
+ void initialize(const int length) { base_class::initialize(esize, length); } \
+ void initialize(const int length, const etype fx) { \
+ initialize(length); \
for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \
} \
\
@@ -157,16 +167,29 @@ class CHeapArray: public CHeapObj {
\
public: \
/* creation */ \
- stack_name() : array_name() { _size = 0; } \
- stack_name(const int size) : array_name(size){ _length = 0; _size = size; } \
- stack_name(const int size, const etype fx) : array_name(size, fx) { _size = size; } \
+ stack_name() : array_name() { _size = 0; } \
+ stack_name(const int size) { initialize(size); } \
+ stack_name(const int size, const etype fx) { initialize(size, fx); } \
+ void initialize(const int size, const etype fx) { \
+ _size = size; \
+ array_name::initialize(size, fx); \
+ /* _length == size, allocation and size are the same */ \
+ } \
+ void initialize(const int size) { \
+ _size = size; \
+ array_name::initialize(size); \
+ _length = 0; /* reset length to zero; _size records the allocation */ \
+ } \
\
/* standard operations */ \
int size() const { return _size; } \
\
- void push(const etype x) { \
- if (length() >= size()) expand(esize, length(), _size); \
- ((etype*)_data)[_length++] = x; \
+ int push(const etype x) { \
+ int len = length(); \
+ if (len >= size()) expand(esize, len, _size); \
+ ((etype*)_data)[len] = x; \
+ _length = len+1; \
+ return len; \
} \
\
etype pop() { \
@@ -235,7 +258,7 @@ class CHeapArray: public CHeapObj {
int capacity() const { return size(); } \
void clear() { truncate(0); } \
void trunc_to(const int length) { truncate(length); } \
- void append(const etype x) { push(x); } \
+ int append(const etype x) { return push(x); } \
void appendAll(const stack_name* stack) { push_all(stack); } \
etype last() const { return top(); } \
}; \
diff --git a/src/share/vm/utilities/constantTag.hpp b/src/share/vm/utilities/constantTag.hpp
index b8a213f8b..07a8be76d 100644
--- a/src/share/vm/utilities/constantTag.hpp
+++ b/src/share/vm/utilities/constantTag.hpp
@@ -71,6 +71,7 @@ class constantTag VALUE_OBJ_CLASS_SPEC {
bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; }
bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); }
+ bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); }
bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); }
bool is_symbol() const { return is_utf8(); }
diff --git a/src/share/vm/utilities/debug.cpp b/src/share/vm/utilities/debug.cpp
index 10a1b1665..20241e5bd 100644
--- a/src/share/vm/utilities/debug.cpp
+++ b/src/share/vm/utilities/debug.cpp
@@ -567,7 +567,7 @@ static void find(intptr_t x, bool print_pc) {
}
// the InlineCacheBuffer is using stubs generated into a buffer blob
if (InlineCacheBuffer::contains(addr)) {
- tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr);
+ tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
return;
}
VtableStub* v = VtableStubs::stub_containing(addr);
@@ -595,7 +595,7 @@ static void find(intptr_t x, bool print_pc) {
return;
}
- if (Universe::heap()->is_in_reserved(addr)) {
+ if (Universe::heap()->is_in(addr)) {
HeapWord* p = Universe::heap()->block_start(addr);
bool print = false;
// If we couldn't find it it just may mean that heap wasn't parseable
@@ -621,24 +621,28 @@ static void find(intptr_t x, bool print_pc) {
}
return;
}
+ } else if (Universe::heap()->is_in_reserved(addr)) {
+ tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
+ return;
}
+
if (JNIHandles::is_global_handle((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
return;
}
if (JNIHandles::is_weak_global_handle((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
return;
}
if (JNIHandleBlock::any_contains((jobject) addr)) {
- tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr);
+ tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
return;
}
for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
- // Check for priviledge stack
+ // Check for privilege stack
if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
- tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread);
+ tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
return;
}
// If the addr is a java thread print information about that.
@@ -659,7 +663,7 @@ static void find(intptr_t x, bool print_pc) {
return;
}
- tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr);
+ tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
}
diff --git a/src/share/vm/utilities/growableArray.hpp b/src/share/vm/utilities/growableArray.hpp
index 208b14518..ab4eeb541 100644
--- a/src/share/vm/utilities/growableArray.hpp
+++ b/src/share/vm/utilities/growableArray.hpp
@@ -111,6 +111,12 @@ class GenericGrowableArray : public ResourceObj {
}
void* raw_allocate(int elementSize);
+
+ // some uses pass the Thread explicitly for speed (4990299 tuning)
+ void* raw_allocate(Thread* thread, int elementSize) {
+ assert(on_stack(), "fast ResourceObj path only");
+ return (void*)resource_allocate_bytes(thread, elementSize * _max);
+ }
};
template<class E> class GrowableArray : public GenericGrowableArray {
@@ -121,6 +127,11 @@ template<class E> class GrowableArray : public GenericGrowableArray {
void raw_at_put_grow(int i, const E& p, const E& fill);
void clear_and_deallocate();
public:
+ GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) {
+ _data = (E*)raw_allocate(thread, sizeof(E));
+ for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
+ }
+
GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
_data = (E*)raw_allocate(sizeof(E));
for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
@@ -159,10 +170,12 @@ template<class E> class GrowableArray : public GenericGrowableArray {
void print();
- void append(const E& elem) {
+ int append(const E& elem) {
check_nesting();
if (_len == _max) grow(_len);
- _data[_len++] = elem;
+ int idx = _len++;
+ _data[idx] = elem;
+ return idx;
}
void append_if_missing(const E& elem) {
diff --git a/src/share/vm/utilities/hashtable.cpp b/src/share/vm/utilities/hashtable.cpp
index 58d675d00..8efa44a20 100644
--- a/src/share/vm/utilities/hashtable.cpp
+++ b/src/share/vm/utilities/hashtable.cpp
@@ -43,9 +43,11 @@ BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
entry = _free_list;
_free_list = _free_list->next();
} else {
- const int block_size = 500;
- if (_first_free_entry == _end_block) {
+ if (_first_free_entry + _entry_size >= _end_block) {
+ int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries));
int len = _entry_size * block_size;
+ len = 1 << log2_intptr(len); // round down to power of 2
+ assert(len >= _entry_size, "");
_first_free_entry = NEW_C_HEAP_ARRAY(char, len);
_end_block = _first_free_entry + len;
}
@@ -53,6 +55,7 @@ BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
_first_free_entry += _entry_size;
}
+ assert(_entry_size % HeapWordSize == 0, "");
entry->set_hash(hashValue);
return entry;
}