--- a/.hgtags-top-repo Thu Oct 15 16:40:16 2009 -0700
+++ b/.hgtags-top-repo Wed Jul 05 17:02:18 2017 +0200
@@ -48,3 +48,4 @@
4c36e9853dda27bdac5ef4839a610509fbe31d34 jdk7-b71
0d7e03b426df27c21dcc44ffb9178eacd1b04f10 jdk7-b72
3ac6dcf7823205546fbbc3d4ea59f37358d0b0d4 jdk7-b73
+2c88089b6e1c053597418099a14232182c387edc jdk7-b74
--- a/hotspot/.hgtags Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/.hgtags Wed Jul 05 17:02:18 2017 +0200
@@ -48,3 +48,4 @@
50a95aa4a247f0cbbf66df285a8b1d78ffb153d9 jdk7-b71
a94714c550658fd6741793ef036cb9625dc2ab1a jdk7-b72
faf94d94786b621f8e13cbcc941ca69c6d967c3f jdk7-b73
+f4b900403d6e4b0af51447bd13bbe23fe3a1dac7 jdk7-b74
--- a/hotspot/make/Makefile Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/Makefile Wed Jul 05 17:02:18 2017 +0200
@@ -84,6 +84,7 @@
C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
+ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
# JDK directory list
JDK_DIRS=bin include jre lib demo
@@ -94,6 +95,12 @@
all_debug: jvmg jvmg1 jvmgkernel docs export_debug
all_optimized: optimized optimized1 optimizedkernel docs export_optimized
+allzero: all_productzero all_fastdebugzero
+all_productzero: productzero docs export_product
+all_fastdebugzero: fastdebugzero docs export_fastdebug
+all_debugzero: jvmgzero docs export_debug
+all_optimizedzero: optimizedzero docs export_optimized
+
# Do everything
world: all create_jdk
@@ -120,6 +127,10 @@
$(CD) $(GAMMADIR)/make; \
$(MAKE) VM_TARGET=$@ generic_buildkernel $(ALT_OUT)
+$(ZERO_VM_TARGETS):
+ $(CD) $(GAMMADIR)/make; \
+ $(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
+
# Build compiler1 (client) rule, different for platforms
generic_build1:
$(MKDIR) -p $(OUTPUTDIR)
@@ -180,6 +191,12 @@
@$(ECHO) "No kernel ($(VM_TARGET)) for OS_NAME=$(OSNAME)"
endif
+generic_buildzero:
+ $(MKDIR) -p $(OUTPUTDIR)
+ $(CD) $(OUTPUTDIR); \
+ $(MAKE) -f $(ABS_OS_MAKEFILE) \
+ $(MAKE_ARGS) $(VM_TARGET)
+
# Export file rule
generic_export: $(EXPORT_LIST)
export_product:
@@ -210,11 +227,17 @@
C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
+ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
+ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
# Misc files and generated files need to come from C1 or C2 area
+ifeq ($(ZERO_BUILD), true)
+ MISC_DIR=$(ZERO_DIR)
+ GEN_DIR=$(ZERO_BASE_DIR)/generated
+else
ifeq ($(ARCH_DATA_MODEL), 32)
MISC_DIR=$(C1_DIR)
GEN_DIR=$(C1_BASE_DIR)/generated
@@ -222,6 +245,7 @@
MISC_DIR=$(C2_DIR)
GEN_DIR=$(C2_BASE_DIR)/generated
endif
+endif
# Bin files (windows)
ifeq ($(OSNAME),windows)
@@ -265,6 +289,12 @@
# Shared Library
ifneq ($(OSNAME),windows)
+ ifeq ($(ZERO_BUILD), true)
+$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so
+ $(install-file)
+$(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so
+ $(install-file)
+ else
$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C2_DIR)/%.so
$(install-file)
$(EXPORT_CLIENT_DIR)/%.so: $(C1_DIR)/%.so
@@ -275,6 +305,7 @@
$(install-file)
$(EXPORT_SERVER_DIR)/64/%.so: $(C2_DIR)/%.so
$(install-file)
+ endif
endif
# Jar file (sa-jdi.jar)
@@ -313,6 +344,7 @@
$(RM) -r $(C1_DIR)
$(RM) -r $(C2_DIR)
$(RM) -r $(KERNEL_DIR)
+ $(RM) -r $(ZERO_DIR)
clean_export:
$(RM) -r $(EXPORT_PATH)
clean_jdk:
@@ -335,8 +367,10 @@
($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
test_jdk:
- ifeq ($(ARCH_DATA_MODEL), 32)
+ ifneq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 32)
$(JDK_IMAGE_DIR)/bin/java -client -version
+ endif
endif
$(JDK_IMAGE_DIR)/bin/java -server -version
--- a/hotspot/make/defs.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/defs.make Wed Jul 05 17:02:18 2017 +0200
@@ -192,13 +192,14 @@
# Use uname output for SRCARCH, but deal with platform differences. If ARCH
# is not explicitly listed below, it is treated as x86.
- SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64,$(ARCH)))
+ SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 zero,$(ARCH)))
ARCH/ = x86
ARCH/sparc = sparc
ARCH/sparc64= sparc
ARCH/ia64 = ia64
ARCH/amd64 = x86
ARCH/x86_64 = x86
+ ARCH/zero = zero
# BUILDARCH is usually the same as SRCARCH, except for sparcv9
BUILDARCH = $(SRCARCH)
@@ -222,8 +223,9 @@
LIBARCH/sparc = sparc
LIBARCH/sparcv9 = sparcv9
LIBARCH/ia64 = ia64
+ LIBARCH/zero = $(ZERO_LIBARCH)
- LP64_ARCH = sparcv9 amd64 ia64
+ LP64_ARCH = sparcv9 amd64 ia64 zero
endif
# Required make macro settings for all platforms
--- a/hotspot/make/hotspot_version Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 17:02:18 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=17
HS_MINOR_VER=0
-HS_BUILD_NUMBER=03
+HS_BUILD_NUMBER=04
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/make/jprt.gmk Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/jprt.gmk Wed Jul 05 17:02:18 2017 +0200
@@ -29,17 +29,24 @@
MILESTONE=$(JPRT_BUILD_VERSION)
endif
+ifeq ($(OSNAME),windows)
+ ZIPFLAGS=-q
+else
+ # store symbolic links as the link
+ ZIPFLAGS=-q -y
+endif
+
jprt_build_product: all_product copy_product_jdk export_product_jdk
( $(CD) $(JDK_IMAGE_DIR) && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
jprt_build_fastdebug: all_fastdebug copy_fastdebug_jdk export_fastdebug_jdk
( $(CD) $(JDK_IMAGE_DIR)/fastdebug && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
jprt_build_debug: all_debug copy_debug_jdk export_debug_jdk
( $(CD) $(JDK_IMAGE_DIR)/debug && \
- $(ZIPEXE) -q -r $(JPRT_ARCHIVE_BUNDLE) . )
+ $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug
--- a/hotspot/make/linux/Makefile Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/Makefile Wed Jul 05 17:02:18 2017 +0200
@@ -132,6 +132,9 @@
endif
+# BUILDARCH is set to "zero" for Zero builds. VARIANTARCH
+# is used to give the build directories meaningful names.
+VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
# There is a (semi-) regular correspondence between make targets and actions:
#
@@ -158,6 +161,13 @@
# profiledcore core <os>_<arch>_core/profiled
# productcore core <os>_<arch>_core/product
#
+# debugzero zero <os>_<arch>_zero/debug
+# fastdebugzero zero <os>_<arch>_zero/fastdebug
+# jvmgzero zero <os>_<arch>_zero/jvmg
+# optimizedzero zero <os>_<arch>_zero/optimized
+# profiledzero zero <os>_<arch>_zero/profiled
+# productzero zero <os>_<arch>_zero/product
+#
# What you get with each target:
#
# debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher
@@ -171,16 +181,22 @@
# in the build.sh script:
TARGETS = debug jvmg fastdebug optimized profiled product
-SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
+ifeq ($(ZERO_BUILD), true)
+ SUBDIR_DOCS = $(OSNAME)_$(VARIANTARCH)_docs
+else
+ SUBDIR_DOCS = $(OSNAME)_$(BUILDARCH)_docs
+endif
SUBDIRS_C1 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler1/,$(TARGETS))
SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
+SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
TARGETS_C2 = $(TARGETS)
TARGETS_C1 = $(addsuffix 1,$(TARGETS))
TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
TARGETS_CORE = $(addsuffix core,$(TARGETS))
+TARGETS_ZERO = $(addsuffix zero,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
@@ -196,6 +212,7 @@
@echo " $(TARGETS_C2)"
@echo " $(TARGETS_C1)"
@echo " $(TARGETS_CORE)"
+ @echo " $(TARGETS_ZERO)"
checks: check_os_version check_j2se_version
@@ -245,6 +262,13 @@
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
$(BUILDTREE) VARIANT=core
+$(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
+ $(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
+ $(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
+
+platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
+ $(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
+
# Define INSTALL=y at command line to automatically copy JVM into JAVA_HOME
$(TARGETS_C2): $(SUBDIRS_C2)
@@ -275,10 +299,18 @@
cd $(OSNAME)_$(BUILDARCH)_core/$(patsubst %core,%,$@) && $(MAKE) $(MFLAGS) install
endif
+$(TARGETS_ZERO): $(SUBDIRS_ZERO)
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS)
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && ./test_gamma
+ifdef INSTALL
+ cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
+endif
+
# Just build the tree, and nothing else:
tree: $(SUBDIRS_C2)
tree1: $(SUBDIRS_C1)
treecore: $(SUBDIRS_CORE)
+treezero: $(SUBDIRS_ZERO)
# Doc target. This is the same for all build options.
# Hence create a docs directory beside ...$(ARCH)_[...]
@@ -293,20 +325,22 @@
core: jvmgcore productcore
+zero: jvmgzero productzero
+
clean_docs:
rm -rf $(SUBDIR_DOCS)
-clean_compiler1 clean_compiler2 clean_core:
+clean_compiler1 clean_compiler2 clean_core clean_zero:
rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
-clean: clean_compiler2 clean_compiler1 clean_core clean_docs
+clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs
include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make
#-------------------------------------------------------------------------------
-.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE)
-.PHONY: tree tree1 treecore
-.PHONY: all compiler1 compiler2 core
-.PHONY: clean clean_compiler1 clean_compiler2 clean_core docs clean_docs
+.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO)
+.PHONY: tree tree1 treecore treezero
+.PHONY: all compiler1 compiler2 core zero
+.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs
.PHONY: checks check_os_version check_j2se_version
--- a/hotspot/make/linux/makefiles/buildtree.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/buildtree.make Wed Jul 05 17:02:18 2017 +0200
@@ -63,20 +63,30 @@
# For now, until the compiler is less wobbly:
TESTFLAGS = -Xbatch -showversion
-ifdef USE_SUNCC
-PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+ifeq ($(ZERO_BUILD), true)
+ PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
else
-PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
+ ifdef USE_SUNCC
+ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH).suncc
+ else
+ PLATFORM_FILE = $(GAMMADIR)/make/$(OS_FAMILY)/platform_$(BUILDARCH)
+ endif
+endif
+
+# Allow overriding of the arch part of the directory but default
+# to BUILDARCH if nothing is specified
+ifeq ($(VARIANTARCH),)
+ VARIANTARCH=$(BUILDARCH)
endif
ifdef FORCE_TIERED
ifeq ($(VARIANT),tiered)
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_compiler2
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_compiler2
else
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT)
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
endif
else
-PLATFORM_DIR = $(OS_FAMILY)_$(BUILDARCH)_$(VARIANT)
+PLATFORM_DIR = $(OS_FAMILY)_$(VARIANTARCH)_$(VARIANT)
endif
#
@@ -321,6 +331,7 @@
DATA_MODE/sparcv9 = 64
DATA_MODE/amd64 = 64
DATA_MODE/ia64 = 64
+DATA_MODE/zero = $(ARCH_DATA_MODEL)
JAVA_FLAG/32 = -d32
JAVA_FLAG/64 = -d64
--- a/hotspot/make/linux/makefiles/defs.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/defs.make Wed Jul 05 17:02:18 2017 +0200
@@ -37,6 +37,17 @@
ARCH_DATA_MODEL ?= 32
endif
+# zero
+ifeq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 64)
+ MAKE_ARGS += LP64=1
+ endif
+ PLATFORM = linux-zero
+ VM_PLATFORM = linux_$(subst i386,i486,$(ZERO_LIBARCH))
+ HS_ARCH = zero
+ ARCH = zero
+endif
+
# ia64
ifeq ($(ARCH), ia64)
ARCH_DATA_MODEL = 64
@@ -93,21 +104,25 @@
VM_DEBUG=jvmg
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+# client and server subdirectories have symbolic links to ../libjsig.so
+EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
+
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
-ifeq ($(ARCH_DATA_MODEL), 32)
- EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
- EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
-else
- ifeq ($(ARCH),ia64)
- else
- EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
- EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ifneq ($(ZERO_BUILD), true)
+ ifeq ($(ARCH_DATA_MODEL), 32)
+ EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
+ else
+ ifeq ($(ARCH),ia64)
+ else
+ EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.so
+ EXPORT_LIST += $(EXPORT_LIB_DIR)/sa-jdi.jar
endif
+ endif
endif
--- a/hotspot/make/linux/makefiles/gcc.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make Wed Jul 05 17:02:18 2017 +0200
@@ -52,6 +52,9 @@
VM_PICFLAG/AOUT =
VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
+ifeq ($(ZERO_BUILD), true)
+CFLAGS += $(LIBFFI_CFLAGS)
+endif
CFLAGS += $(VM_PICFLAG)
CFLAGS += -fno-rtti
CFLAGS += -fno-exceptions
@@ -64,6 +67,7 @@
ARCHFLAG/ia64 =
ARCHFLAG/sparc = -m32 -mcpu=v9
ARCHFLAG/sparcv9 = -m64 -mcpu=v9
+ARCHFLAG/zero = $(ZERO_ARCHFLAG)
CFLAGS += $(ARCHFLAG)
AOUT_FLAGS += $(ARCHFLAG)
--- a/hotspot/make/linux/makefiles/sa.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/sa.make Wed Jul 05 17:02:18 2017 +0200
@@ -52,10 +52,10 @@
SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium.
+# also, we don't build SA on Itanium or zero.
all:
- if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \
+ if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
$(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
fi
--- a/hotspot/make/linux/makefiles/saproc.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/saproc.make Wed Jul 05 17:02:18 2017 +0200
@@ -49,10 +49,10 @@
endif
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium.
+# also, we don't build SA on Itanium or zero.
checkAndBuildSA:
- $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" ] ; then \
+ $(QUIETLY) if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" -a "$(SRCARCH)" != "zero" ] ; then \
$(MAKE) -f vm.make $(LIBSAPROC); \
fi
--- a/hotspot/make/linux/makefiles/top.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/top.make Wed Jul 05 17:02:18 2017 +0200
@@ -74,6 +74,7 @@
Include_DBs/COMPILER1 = $(Include_DBs/CORE) $(VM)/includeDB_compiler1
Include_DBs/COMPILER2 = $(Include_DBs/CORE) $(VM)/includeDB_compiler2
Include_DBs/TIERED = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2
+Include_DBs/ZERO = $(Include_DBs/CORE) $(VM)/includeDB_zero
Include_DBs = $(Include_DBs/$(TYPE))
Cached_plat = $(GENERATED)/platform.current
--- a/hotspot/make/linux/makefiles/vm.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Wed Jul 05 17:02:18 2017 +0200
@@ -40,7 +40,11 @@
include $(GENERATED)/Dependencies
# read machine-specific adjustments (%%% should do this via buildtree.make?)
-include $(MAKEFILES_DIR)/$(BUILDARCH).make
+ifeq ($(ZERO_BUILD), true)
+ include $(MAKEFILES_DIR)/zeroshark.make
+else
+ include $(MAKEFILES_DIR)/$(BUILDARCH).make
+endif
# set VPATH so make knows where to look for source files
# Src_Dirs is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
@@ -124,7 +128,11 @@
rm -f $@
cat $^ > $@
-STATIC_CXX = true
+ifeq ($(ZERO_LIBARCH), ppc64)
+ STATIC_CXX = false
+else
+ STATIC_CXX = true
+endif
ifeq ($(LINK_INTO),AOUT)
LIBJVM.o =
@@ -148,6 +156,9 @@
LIBS_VM += $(LIBS)
endif
+ifeq ($(ZERO_BUILD), true)
+ LIBS_VM += $(LIBFFI_LIBS)
+endif
LINK_VM = $(LINK_LIB.c)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/zero.make Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,32 @@
+#
+# Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2009 Red Hat, Inc.
+# 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.
+#
+#
+
+# Setup for Zero (non-Shark) version of VM
+
+# Select which includeDB files to use (in top.make)
+TYPE = ZERO
+
+# Install libjvm.so, etc in in server directory.
+VM_SUBDIR = server
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/zeroshark.make Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2007, 2008 Red Hat, Inc.
+# 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.
+#
+#
+
+# Setup common to Zero (non-Shark) and Shark versions of VM
+
+# The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
+OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
+# The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
+OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
+
+# Specify that the CPU is little endian, if necessary
+ifeq ($(ZERO_ENDIANNESS), little)
+ CFLAGS += -DVM_LITTLE_ENDIAN
+endif
+
+# Specify that the CPU is 64 bit, if necessary
+ifeq ($(ARCH_DATA_MODEL), 64)
+ CFLAGS += -D_LP64=1
+endif
+
+OPT_CFLAGS/compactingPermGenGen.o = -O1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/platform_zero.in Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,17 @@
+os_family = linux
+
+arch = zero
+
+arch_model = zero
+
+os_arch = linux_zero
+
+os_arch_model = linux_zero
+
+lib_arch = zero
+
+compiler = gcc
+
+gnu_dis_arch = zero
+
+sysdefs = -DLINUX -D_GNU_SOURCE -DCC_INTERP -DZERO -D@ZERO_ARCHDEF@ -DZERO_LIBARCH=\"@ZERO_LIBARCH@\"
--- a/hotspot/make/solaris/makefiles/defs.make Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/make/solaris/makefiles/defs.make Wed Jul 05 17:02:18 2017 +0200
@@ -65,16 +65,18 @@
VM_DEBUG=jvmg
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+
+# client and server subdirectories have symbolic links to ../libjsig.so
+EXPORT_LIST += $(EXPORT_JRE_LIB_ARCH_DIR)/libjsig.so
+
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.so
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.so
ifeq ($(ARCH_DATA_MODEL), 32)
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
- EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjsig.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.so
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.so
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -2631,13 +2631,13 @@
(src.is_register() && src.as_register() == G0)) {
// do nothing
} else if (dest.is_register()) {
- add(dest.as_register(), ensure_rs2(src, temp), dest.as_register());
+ add(dest.as_register(), ensure_simm13_or_reg(src, temp), dest.as_register());
} else if (src.is_constant()) {
intptr_t res = dest.as_constant() + src.as_constant();
dest = RegisterOrConstant(res); // side effect seen by caller
} else {
assert(temp != noreg, "cannot handle constant += register");
- add(src.as_register(), ensure_rs2(dest, temp), temp);
+ add(src.as_register(), ensure_simm13_or_reg(dest, temp), temp);
dest = RegisterOrConstant(temp); // side effect seen by caller
}
}
@@ -2710,7 +2710,7 @@
RegisterOrConstant itable_offset = itable_index;
regcon_sll_ptr(itable_offset, exact_log2(itableMethodEntry::size() * wordSize));
regcon_inc_ptr(itable_offset, itableMethodEntry::method_offset_in_bytes());
- add(recv_klass, ensure_rs2(itable_offset, sethi_temp), recv_klass);
+ add(recv_klass, ensure_simm13_or_reg(itable_offset, sethi_temp), recv_klass);
// for (scan = klass->itable(); scan->interface() != NULL; scan += scan_step) {
// if (scan->interface() == intf) {
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -1279,6 +1279,7 @@
// 171
+ inline void ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d);
inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d);
inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder());
@@ -1535,7 +1536,8 @@
// pp 222
- inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2 );
+ inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2);
+ inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2);
inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a);
inline void stf( FloatRegisterImpl::Width w, FloatRegister d, const Address& a, int offset = 0);
@@ -2049,12 +2051,13 @@
Register temp = noreg );
void regcon_sll_ptr( RegisterOrConstant& dest, RegisterOrConstant src,
Register temp = noreg );
- RegisterOrConstant ensure_rs2(RegisterOrConstant rs2, Register sethi_temp) {
- guarantee(sethi_temp != noreg, "constant offset overflow");
- if (is_simm13(rs2.constant_or_zero()))
- return rs2; // register or short constant
- set(rs2.as_constant(), sethi_temp);
- return sethi_temp;
+
+ RegisterOrConstant ensure_simm13_or_reg(RegisterOrConstant roc, Register Rtemp) {
+ guarantee(Rtemp != noreg, "constant offset overflow");
+ if (is_simm13(roc.constant_or_zero()))
+ return roc; // register or short constant
+ set(roc.as_constant(), Rtemp);
+ return RegisterOrConstant(Rtemp);
}
// --------------------------------------------------
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -99,6 +99,11 @@
inline void Assembler::jmpl( Register s1, Register s2, Register d ) { emit_long( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec ) { emit_data( op(arith_op) | rd(d) | op3(jmpl_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); has_delay_slot(); }
+inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, RegisterOrConstant s2, FloatRegister d) {
+ if (s2.is_register()) ldf(w, s1, s2.as_register(), d);
+ else ldf(w, s1, s2.as_constant(), d);
+}
+
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); }
@@ -224,6 +229,11 @@
// pp 222
+inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, RegisterOrConstant s2) {
+ if (s2.is_register()) stf(w, d, s1, s2.as_register());
+ else stf(w, d, s1, s2.as_constant());
+}
+
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_long( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
@@ -284,6 +294,7 @@
inline void Assembler::stb(Register d, Register s1, RegisterOrConstant s2) { stb(d, Address(s1, s2)); }
inline void Assembler::sth(Register d, Register s1, RegisterOrConstant s2) { sth(d, Address(s1, s2)); }
+inline void Assembler::stw(Register d, Register s1, RegisterOrConstant s2) { stw(d, Address(s1, s2)); }
inline void Assembler::stx(Register d, Register s1, RegisterOrConstant s2) { stx(d, Address(s1, s2)); }
inline void Assembler::std(Register d, Register s1, RegisterOrConstant s2) { std(d, Address(s1, s2)); }
inline void Assembler::st( Register d, Register s1, RegisterOrConstant s2) { st( d, Address(s1, s2)); }
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -107,7 +107,7 @@
// are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
// (as the stub's I's) when the runtime routine called by the stub creates its frame.
int i;
- // Always make the frame size 16 bytr aligned.
+ // Always make the frame size 16 byte aligned.
int frame_size = round_to(additional_frame_words + register_save_size, 16);
// OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words
int frame_size_in_slots = frame_size / sizeof(jint);
@@ -201,15 +201,14 @@
__ stx(G5, SP, ccr_offset+STACK_BIAS);
__ stxfsr(SP, fsr_offset+STACK_BIAS);
- // Save all the FP registers
+ // Save all the FP registers: 32 doubles (32 floats correspond to the 2 halves of the first 16 doubles)
int offset = d00_offset;
- for( int i=0; i<64; i+=2 ) {
+ for( int i=0; i<FloatRegisterImpl::number_of_registers; i+=2 ) {
FloatRegister f = as_FloatRegister(i);
__ stf(FloatRegisterImpl::D, f, SP, offset+STACK_BIAS);
+ // Record as callee saved both halves of double registers (2 float registers).
map->set_callee_saved(VMRegImpl::stack2reg(offset>>2), f->as_VMReg());
- if (true) {
- map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next());
- }
+ map->set_callee_saved(VMRegImpl::stack2reg((offset + sizeof(float))>>2), f->as_VMReg()->next());
offset += sizeof(double);
}
@@ -224,7 +223,7 @@
void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
// Restore all the FP registers
- for( int i=0; i<64; i+=2 ) {
+ for( int i=0; i<FloatRegisterImpl::number_of_registers; i+=2 ) {
__ ldf(FloatRegisterImpl::D, SP, d00_offset+i*sizeof(float)+STACK_BIAS, as_FloatRegister(i));
}
@@ -540,14 +539,12 @@
}
-// Helper class mostly to avoid passing masm everywhere, and handle store
-// displacement overflow logic for LP64
+// Helper class mostly to avoid passing masm everywhere, and handle
+// store displacement overflow logic.
class AdapterGenerator {
MacroAssembler *masm;
-#ifdef _LP64
Register Rdisp;
void set_Rdisp(Register r) { Rdisp = r; }
-#endif // _LP64
void patch_callers_callsite();
void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch);
@@ -558,15 +555,18 @@
return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes();
}
-#ifdef _LP64
- // On _LP64 argument slot values are loaded first into a register
- // because they might not fit into displacement.
- Register arg_slot(const int st_off);
- Register next_arg_slot(const int st_off);
-#else
- int arg_slot(const int st_off) { return arg_offset(st_off); }
- int next_arg_slot(const int st_off) { return next_arg_offset(st_off); }
-#endif // _LP64
+ int tag_offset(const int st_off) { return st_off + Interpreter::tag_offset_in_bytes(); }
+ int next_tag_offset(const int st_off) {
+ return st_off - Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes();
+ }
+
+ // Argument slot values may be loaded first into a register because
+ // they might not fit into displacement.
+ RegisterOrConstant arg_slot(const int st_off);
+ RegisterOrConstant next_arg_slot(const int st_off);
+
+ RegisterOrConstant tag_slot(const int st_off);
+ RegisterOrConstant next_tag_slot(const int st_off);
// Stores long into offset pointed to by base
void store_c2i_long(Register r, Register base,
@@ -656,44 +656,42 @@
void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off,
Register scratch) {
if (TaggedStackInterpreter) {
- int tag_off = st_off + Interpreter::tag_offset_in_bytes();
-#ifdef _LP64
- Register tag_slot = Rdisp;
- __ set(tag_off, tag_slot);
-#else
- int tag_slot = tag_off;
-#endif // _LP64
+ RegisterOrConstant slot = tag_slot(st_off);
// have to store zero because local slots can be reused (rats!)
if (t == frame::TagValue) {
- __ st_ptr(G0, base, tag_slot);
+ __ st_ptr(G0, base, slot);
} else if (t == frame::TagCategory2) {
- __ st_ptr(G0, base, tag_slot);
- int next_tag_off = st_off - Interpreter::stackElementSize() +
- Interpreter::tag_offset_in_bytes();
-#ifdef _LP64
- __ set(next_tag_off, tag_slot);
-#else
- tag_slot = next_tag_off;
-#endif // _LP64
- __ st_ptr(G0, base, tag_slot);
+ __ st_ptr(G0, base, slot);
+ __ st_ptr(G0, base, next_tag_slot(st_off));
} else {
__ mov(t, scratch);
- __ st_ptr(scratch, base, tag_slot);
+ __ st_ptr(scratch, base, slot);
}
}
}
-#ifdef _LP64
-Register AdapterGenerator::arg_slot(const int st_off) {
- __ set( arg_offset(st_off), Rdisp);
- return Rdisp;
+
+RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) {
+ RegisterOrConstant roc(arg_offset(st_off));
+ return __ ensure_simm13_or_reg(roc, Rdisp);
+}
+
+RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) {
+ RegisterOrConstant roc(next_arg_offset(st_off));
+ return __ ensure_simm13_or_reg(roc, Rdisp);
}
-Register AdapterGenerator::next_arg_slot(const int st_off){
- __ set( next_arg_offset(st_off), Rdisp);
- return Rdisp;
+
+RegisterOrConstant AdapterGenerator::tag_slot(const int st_off) {
+ RegisterOrConstant roc(tag_offset(st_off));
+ return __ ensure_simm13_or_reg(roc, Rdisp);
}
-#endif // _LP64
+
+RegisterOrConstant AdapterGenerator::next_tag_slot(const int st_off) {
+ RegisterOrConstant roc(next_tag_offset(st_off));
+ return __ ensure_simm13_or_reg(roc, Rdisp);
+}
+
// Stores long into offset pointed to by base
void AdapterGenerator::store_c2i_long(Register r, Register base,
@@ -1052,9 +1050,7 @@
// Load in argument order going down.
const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize();
-#ifdef _LP64
set_Rdisp(G1_scratch);
-#endif // _LP64
VMReg r_1 = regs[i].first();
VMReg r_2 = regs[i].second();
@@ -1074,7 +1070,7 @@
#ifdef _LP64
// In V9, longs are given 2 64-bit slots in the interpreter, but the
// data is passed in only 1 slot.
- Register slot = (sig_bt[i]==T_LONG) ?
+ RegisterOrConstant slot = (sig_bt[i] == T_LONG) ?
next_arg_slot(ld_off) : arg_slot(ld_off);
__ ldx(Gargs, slot, r);
#else
@@ -1092,7 +1088,7 @@
// data is passed in only 1 slot. This code also handles longs that
// are passed on the stack, but need a stack-to-stack move through a
// spare float register.
- Register slot = (sig_bt[i]==T_LONG || sig_bt[i] == T_DOUBLE) ?
+ RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ?
next_arg_slot(ld_off) : arg_slot(ld_off);
__ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister());
#else
@@ -1109,8 +1105,9 @@
// Convert stack slot to an SP offset
int st_off = reg2offset(regs[i].first()) + STACK_BIAS;
// Store down the shuffled stack word. Target address _is_ aligned.
- if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, st_off);
- else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, st_off);
+ RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp);
+ if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot);
+ else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot);
}
}
bool made_space = false;
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 17:02:18 2017 +0200
@@ -193,38 +193,38 @@
// I believe we can't handle callee-save doubles D32 and up until
// the place in the sparc stack crawler that asserts on the 255 is
// fixed up.
-reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg());
-reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg()->next());
-reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg());
-reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg()->next());
-reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg());
-reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg()->next());
-reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg());
-reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg()->next());
-reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg());
-reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg()->next());
-reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg());
-reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg()->next());
-reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg());
-reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg()->next());
-reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg());
-reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg()->next());
-reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg());
-reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg()->next());
-reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg());
-reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg()->next());
-reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg());
-reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg()->next());
-reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg());
-reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg()->next());
-reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg());
-reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg()->next());
-reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg());
-reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg()->next());
-reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg());
-reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg()->next());
-reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg());
-reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg()->next());
+reg_def R_D32 (SOC, SOC, Op_RegD, 1, F32->as_VMReg());
+reg_def R_D32x(SOC, SOC, Op_RegD,255, F32->as_VMReg()->next());
+reg_def R_D34 (SOC, SOC, Op_RegD, 3, F34->as_VMReg());
+reg_def R_D34x(SOC, SOC, Op_RegD,255, F34->as_VMReg()->next());
+reg_def R_D36 (SOC, SOC, Op_RegD, 5, F36->as_VMReg());
+reg_def R_D36x(SOC, SOC, Op_RegD,255, F36->as_VMReg()->next());
+reg_def R_D38 (SOC, SOC, Op_RegD, 7, F38->as_VMReg());
+reg_def R_D38x(SOC, SOC, Op_RegD,255, F38->as_VMReg()->next());
+reg_def R_D40 (SOC, SOC, Op_RegD, 9, F40->as_VMReg());
+reg_def R_D40x(SOC, SOC, Op_RegD,255, F40->as_VMReg()->next());
+reg_def R_D42 (SOC, SOC, Op_RegD, 11, F42->as_VMReg());
+reg_def R_D42x(SOC, SOC, Op_RegD,255, F42->as_VMReg()->next());
+reg_def R_D44 (SOC, SOC, Op_RegD, 13, F44->as_VMReg());
+reg_def R_D44x(SOC, SOC, Op_RegD,255, F44->as_VMReg()->next());
+reg_def R_D46 (SOC, SOC, Op_RegD, 15, F46->as_VMReg());
+reg_def R_D46x(SOC, SOC, Op_RegD,255, F46->as_VMReg()->next());
+reg_def R_D48 (SOC, SOC, Op_RegD, 17, F48->as_VMReg());
+reg_def R_D48x(SOC, SOC, Op_RegD,255, F48->as_VMReg()->next());
+reg_def R_D50 (SOC, SOC, Op_RegD, 19, F50->as_VMReg());
+reg_def R_D50x(SOC, SOC, Op_RegD,255, F50->as_VMReg()->next());
+reg_def R_D52 (SOC, SOC, Op_RegD, 21, F52->as_VMReg());
+reg_def R_D52x(SOC, SOC, Op_RegD,255, F52->as_VMReg()->next());
+reg_def R_D54 (SOC, SOC, Op_RegD, 23, F54->as_VMReg());
+reg_def R_D54x(SOC, SOC, Op_RegD,255, F54->as_VMReg()->next());
+reg_def R_D56 (SOC, SOC, Op_RegD, 25, F56->as_VMReg());
+reg_def R_D56x(SOC, SOC, Op_RegD,255, F56->as_VMReg()->next());
+reg_def R_D58 (SOC, SOC, Op_RegD, 27, F58->as_VMReg());
+reg_def R_D58x(SOC, SOC, Op_RegD,255, F58->as_VMReg()->next());
+reg_def R_D60 (SOC, SOC, Op_RegD, 29, F60->as_VMReg());
+reg_def R_D60x(SOC, SOC, Op_RegD,255, F60->as_VMReg()->next());
+reg_def R_D62 (SOC, SOC, Op_RegD, 31, F62->as_VMReg());
+reg_def R_D62x(SOC, SOC, Op_RegD,255, F62->as_VMReg()->next());
// ----------------------------
@@ -3016,7 +3016,7 @@
// return true if the same array
__ cmp(ary1_reg, ary2_reg);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
+ __ brx(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->add(G0, 1, result_reg); // equal
__ br_null(ary1_reg, true, Assembler::pn, Ldone);
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -8634,8 +8634,10 @@
if (is_array_equ) {
// Need additional checks for arrays_equals.
- andptr(ary1, ary2);
- jcc(Assembler::zero, FALSE_LABEL); // One pointer is NULL
+ testptr(ary1, ary1);
+ jcc(Assembler::zero, FALSE_LABEL);
+ testptr(ary2, ary2);
+ jcc(Assembler::zero, FALSE_LABEL);
// Check the lengths
movl(limit, Address(ary1, length_offset));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/assembler_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_assembler_zero.cpp.incl"
+
+int AbstractAssembler::code_fill_byte() {
+ return 0;
+}
+
+void Assembler::pd_patch_instruction(address branch, address target) {
+ ShouldNotCallThis();
+}
+
+#ifndef PRODUCT
+void Assembler::pd_print_patched_instruction(address branch) {
+ ShouldNotCallThis();
+}
+#endif // PRODUCT
+
+void MacroAssembler::align(int modulus) {
+ while (offset() % modulus != 0)
+ emit_byte(AbstractAssembler::code_fill_byte());
+}
+
+void MacroAssembler::bang_stack_with_offset(int offset) {
+ ShouldNotCallThis();
+}
+
+void MacroAssembler::advance(int bytes) {
+ _code_pos += bytes;
+ sync();
+}
+
+RegisterOrConstant MacroAssembler::delayed_value_impl(
+ intptr_t* delayed_value_addr, Register tmpl, int offset) {
+ ShouldNotCallThis();
+}
+
+void MacroAssembler::store_oop(jobject obj) {
+ code_section()->relocate(pc(), oop_Relocation::spec_for_immediate());
+ emit_address((address) obj);
+}
+
+static void should_not_call() {
+ report_should_not_call(__FILE__, __LINE__);
+}
+
+address ShouldNotCallThisStub() {
+ return (address) should_not_call;
+}
+
+address ShouldNotCallThisEntry() {
+ return (address) should_not_call;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/assembler_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// In normal, CPU-specific ports of HotSpot these two classes are used
+// for generating assembly language. We don't do any of this in zero,
+// of course, but we do sneak entry points around in CodeBuffers so we
+// generate those here.
+
+class Assembler : public AbstractAssembler {
+ public:
+ Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
+
+ public:
+ void pd_patch_instruction(address branch, address target);
+#ifndef PRODUCT
+ static void pd_print_patched_instruction(address branch);
+#endif // PRODUCT
+};
+
+class MacroAssembler : public Assembler {
+ public:
+ MacroAssembler(CodeBuffer* code) : Assembler(code) {}
+
+ public:
+ void align(int modulus);
+ void bang_stack_with_offset(int offset);
+ bool needs_explicit_null_check(intptr_t offset);
+ RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
+ Register tmp, int offset);
+ public:
+ void advance(int bytes);
+ void store_oop(jobject obj);
+};
+
+#ifdef ASSERT
+inline bool AbstractAssembler::pd_check_instruction_mark() {
+ ShouldNotCallThis();
+}
+#endif
+
+address ShouldNotCallThisStub();
+address ShouldNotCallThisEntry();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/assembler_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_cppInterpreter_zero.cpp.incl"
+
+#ifdef CC_INTERP
+
+const char *BytecodeInterpreter::name_of_field_at_address(address addr) {
+#define DO(member) {if (addr == (address) &(member)) return XSTR(member);}
+ DO(_thread);
+ DO(_bcp);
+ DO(_locals);
+ DO(_constants);
+ DO(_method);
+ DO(_mdx);
+ DO(_stack);
+ DO(_msg);
+ DO(_result);
+ DO(_prev_link);
+ DO(_oop_temp);
+ DO(_stack_base);
+ DO(_stack_limit);
+ DO(_monitor_base);
+ DO(_self_link);
+#undef DO
+ if (addr > (address) &_result && addr < (address) (&_result + 1))
+ return "_result)";
+ return NULL;
+}
+
+#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Platform specific for C++ based Interpreter
+
+#if defined(PPC) || defined(SPARC) || defined(IA64)
+#define LOTS_OF_REGS // Use plenty of registers
+#else
+#undef LOTS_OF_REGS // Loser platforms
+#endif
+
+ private:
+ interpreterState _self_link;
+
+ public:
+ inline void set_locals(intptr_t* new_locals) {
+ _locals = new_locals;
+ }
+ inline void set_method(methodOop new_method) {
+ _method = new_method;
+ }
+ inline interpreterState self_link() {
+ return _self_link;
+ }
+ inline void set_self_link(interpreterState new_self_link) {
+ _self_link = new_self_link;
+ }
+ inline interpreterState prev_link() {
+ return _prev_link;
+ }
+ inline void set_prev_link(interpreterState new_prev_link) {
+ _prev_link = new_prev_link;
+ }
+ inline void set_stack_limit(intptr_t* new_stack_limit) {
+ _stack_limit = new_stack_limit;
+ }
+ inline void set_stack_base(intptr_t* new_stack_base) {
+ _stack_base = new_stack_base;
+ }
+ inline void set_monitor_base(BasicObjectLock *new_monitor_base) {
+ _monitor_base = new_monitor_base;
+ }
+ inline void set_thread(JavaThread* new_thread) {
+ _thread = new_thread;
+ }
+ inline void set_constants(constantPoolCacheOop new_constants) {
+ _constants = new_constants;
+ }
+ inline oop oop_temp() {
+ return _oop_temp;
+ }
+ inline oop *oop_temp_addr() {
+ return &_oop_temp;
+ }
+ inline void set_oop_temp(oop new_oop_temp) {
+ _oop_temp = new_oop_temp;
+ }
+ inline address callee_entry_point() {
+ return _result._to_call._callee_entry_point;
+ }
+ inline address osr_buf() {
+ return _result._osr._osr_buf;
+ }
+ inline address osr_entry() {
+ return _result._osr._osr_entry;
+ }
+
+ public:
+ const char *name_of_field_at_address(address addr);
+
+// The frame manager handles this
+#define SET_LAST_JAVA_FRAME()
+#define RESET_LAST_JAVA_FRAME()
+
+// ZeroStack Implementation
+
+#undef STACK_INT
+#undef STACK_FLOAT
+#undef STACK_ADDR
+#undef STACK_OBJECT
+#undef STACK_DOUBLE
+#undef STACK_LONG
+
+#define GET_STACK_SLOT(offset) (*((intptr_t*) &topOfStack[-(offset)]))
+#define STACK_SLOT(offset) ((address) &topOfStack[-(offset)])
+#define STACK_ADDR(offset) (*((address *) &topOfStack[-(offset)]))
+#define STACK_INT(offset) (*((jint*) &topOfStack[-(offset)]))
+#define STACK_FLOAT(offset) (*((jfloat *) &topOfStack[-(offset)]))
+#define STACK_OBJECT(offset) (*((oop *) &topOfStack [-(offset)]))
+#define STACK_DOUBLE(offset) (((VMJavaVal64*) &topOfStack[-(offset)])->d)
+#define STACK_LONG(offset) (((VMJavaVal64 *) &topOfStack[-(offset)])->l)
+
+#define SET_STACK_SLOT(value, offset) (*(intptr_t*)&topOfStack[-(offset)] = *(intptr_t*)(value))
+#define SET_STACK_ADDR(value, offset) (*((address *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_INT(value, offset) (*((jint *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_FLOAT(value, offset) (*((jfloat *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_OBJECT(value, offset) (*((oop *)&topOfStack[-(offset)]) = (value))
+#define SET_STACK_DOUBLE(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = (value))
+#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->d = \
+ ((VMJavaVal64*)(addr))->d)
+#define SET_STACK_LONG(value, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = (value))
+#define SET_STACK_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&topOfStack[-(offset)])->l = \
+ ((VMJavaVal64*)(addr))->l)
+// JavaLocals implementation
+
+#define LOCALS_SLOT(offset) ((intptr_t*)&locals[-(offset)])
+#define LOCALS_ADDR(offset) ((address)locals[-(offset)])
+#define LOCALS_INT(offset) (*((jint*)&locals[-(offset)]))
+#define LOCALS_FLOAT(offset) (*((jfloat*)&locals[-(offset)]))
+#define LOCALS_OBJECT(offset) ((oop)locals[-(offset)])
+#define LOCALS_DOUBLE(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->d)
+#define LOCALS_LONG(offset) (((VMJavaVal64*)&locals[-((offset) + 1)])->l)
+#define LOCALS_LONG_AT(offset) (((address)&locals[-((offset) + 1)]))
+#define LOCALS_DOUBLE_AT(offset) (((address)&locals[-((offset) + 1)]))
+
+#define SET_LOCALS_SLOT(value, offset) (*(intptr_t*)&locals[-(offset)] = *(intptr_t *)(value))
+#define SET_LOCALS_ADDR(value, offset) (*((address *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_INT(value, offset) (*((jint *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_FLOAT(value, offset) (*((jfloat *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_OBJECT(value, offset) (*((oop *)&locals[-(offset)]) = (value))
+#define SET_LOCALS_DOUBLE(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = (value))
+#define SET_LOCALS_LONG(value, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = (value))
+#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->d = \
+ ((VMJavaVal64*)(addr))->d)
+#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) (((VMJavaVal64*)&locals[-((offset)+1)])->l = \
+ ((VMJavaVal64*)(addr))->l)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Inline interpreter functions for zero
+
+inline jfloat BytecodeInterpreter::VMfloatAdd(jfloat op1, jfloat op2) {
+ return op1 + op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatSub(jfloat op1, jfloat op2) {
+ return op1 - op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatMul(jfloat op1, jfloat op2) {
+ return op1 * op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatDiv(jfloat op1, jfloat op2) {
+ return op1 / op2;
+}
+
+inline jfloat BytecodeInterpreter::VMfloatRem(jfloat op1, jfloat op2) {
+ return fmod(op1, op2);
+}
+
+inline jfloat BytecodeInterpreter::VMfloatNeg(jfloat op) {
+ return -op;
+}
+
+inline int32_t BytecodeInterpreter::VMfloatCompare(jfloat op1,
+ jfloat op2,
+ int32_t direction) {
+ return ( op1 < op2 ? -1 :
+ op1 > op2 ? 1 :
+ op1 == op2 ? 0 :
+ (direction == -1 || direction == 1) ? direction : 0);
+
+}
+
+inline void BytecodeInterpreter::VMmemCopy64(uint32_t to[2],
+ const uint32_t from[2]) {
+ *(uint64_t *) to = *(uint64_t *) from;
+}
+
+inline jlong BytecodeInterpreter::VMlongAdd(jlong op1, jlong op2) {
+ return op1 + op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongAnd(jlong op1, jlong op2) {
+ return op1 & op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongDiv(jlong op1, jlong op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return op1;
+ else return op1 / op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongMul(jlong op1, jlong op2) {
+ return op1 * op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongOr(jlong op1, jlong op2) {
+ return op1 | op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongSub(jlong op1, jlong op2) {
+ return op1 - op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongXor(jlong op1, jlong op2) {
+ return op1 ^ op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongRem(jlong op1, jlong op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jlong) 0x8000000000000000LL && op2 == -1) return 0;
+ else return op1 % op2;
+}
+
+inline jlong BytecodeInterpreter::VMlongUshr(jlong op1, jint op2) {
+ return ((unsigned long long) op1) >> (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongShr(jlong op1, jint op2) {
+ return op1 >> (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongShl(jlong op1, jint op2) {
+ return op1 << (op2 & 0x3F);
+}
+
+inline jlong BytecodeInterpreter::VMlongNeg(jlong op) {
+ return -op;
+}
+
+inline jlong BytecodeInterpreter::VMlongNot(jlong op) {
+ return ~op;
+}
+
+inline int32_t BytecodeInterpreter::VMlongLtz(jlong op) {
+ return (op <= 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGez(jlong op) {
+ return (op >= 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongEqz(jlong op) {
+ return (op == 0);
+}
+
+inline int32_t BytecodeInterpreter::VMlongEq(jlong op1, jlong op2) {
+ return (op1 == op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongNe(jlong op1, jlong op2) {
+ return (op1 != op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGe(jlong op1, jlong op2) {
+ return (op1 >= op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongLe(jlong op1, jlong op2) {
+ return (op1 <= op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongLt(jlong op1, jlong op2) {
+ return (op1 < op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongGt(jlong op1, jlong op2) {
+ return (op1 > op2);
+}
+
+inline int32_t BytecodeInterpreter::VMlongCompare(jlong op1, jlong op2) {
+ return (VMlongLt(op1, op2) ? -1 : VMlongGt(op1, op2) ? 1 : 0);
+}
+
+// Long conversions
+
+inline jdouble BytecodeInterpreter::VMlong2Double(jlong val) {
+ return (jdouble) val;
+}
+
+inline jfloat BytecodeInterpreter::VMlong2Float(jlong val) {
+ return (jfloat) val;
+}
+
+inline jint BytecodeInterpreter::VMlong2Int(jlong val) {
+ return (jint) val;
+}
+
+// Double Arithmetic
+
+inline jdouble BytecodeInterpreter::VMdoubleAdd(jdouble op1, jdouble op2) {
+ return op1 + op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleDiv(jdouble op1, jdouble op2) {
+ // Divide by zero... QQQ
+ return op1 / op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleMul(jdouble op1, jdouble op2) {
+ return op1 * op2;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleNeg(jdouble op) {
+ return -op;
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleRem(jdouble op1, jdouble op2) {
+ return fmod(op1, op2);
+}
+
+inline jdouble BytecodeInterpreter::VMdoubleSub(jdouble op1, jdouble op2) {
+ return op1 - op2;
+}
+
+inline int32_t BytecodeInterpreter::VMdoubleCompare(jdouble op1,
+ jdouble op2,
+ int32_t direction) {
+ return ( op1 < op2 ? -1 :
+ op1 > op2 ? 1 :
+ op1 == op2 ? 0 :
+ (direction == -1 || direction == 1) ? direction : 0);
+}
+
+// Double Conversions
+
+inline jfloat BytecodeInterpreter::VMdouble2Float(jdouble val) {
+ return (jfloat) val;
+}
+
+// Float Conversions
+
+inline jdouble BytecodeInterpreter::VMfloat2Double(jfloat op) {
+ return (jdouble) op;
+}
+
+// Integer Arithmetic
+
+inline jint BytecodeInterpreter::VMintAdd(jint op1, jint op2) {
+ return op1 + op2;
+}
+
+inline jint BytecodeInterpreter::VMintAnd(jint op1, jint op2) {
+ return op1 & op2;
+}
+
+inline jint BytecodeInterpreter::VMintDiv(jint op1, jint op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jint) 0x80000000 && op2 == -1) return op1;
+ else return op1 / op2;
+}
+
+inline jint BytecodeInterpreter::VMintMul(jint op1, jint op2) {
+ return op1 * op2;
+}
+
+inline jint BytecodeInterpreter::VMintNeg(jint op) {
+ return -op;
+}
+
+inline jint BytecodeInterpreter::VMintOr(jint op1, jint op2) {
+ return op1 | op2;
+}
+
+inline jint BytecodeInterpreter::VMintRem(jint op1, jint op2) {
+ /* it's possible we could catch this special case implicitly */
+ if (op1 == (jint) 0x80000000 && op2 == -1) return 0;
+ else return op1 % op2;
+}
+
+inline jint BytecodeInterpreter::VMintShl(jint op1, jint op2) {
+ return op1 << (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintShr(jint op1, jint op2) {
+ return op1 >> (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintSub(jint op1, jint op2) {
+ return op1 - op2;
+}
+
+inline jint BytecodeInterpreter::VMintUshr(jint op1, jint op2) {
+ return ((juint) op1) >> (op2 & 0x1F);
+}
+
+inline jint BytecodeInterpreter::VMintXor(jint op1, jint op2) {
+ return op1 ^ op2;
+}
+
+inline jdouble BytecodeInterpreter::VMint2Double(jint val) {
+ return (jdouble) val;
+}
+
+inline jfloat BytecodeInterpreter::VMint2Float(jint val) {
+ return (jfloat) val;
+}
+
+inline jlong BytecodeInterpreter::VMint2Long(jint val) {
+ return (jlong) val;
+}
+
+inline jchar BytecodeInterpreter::VMint2Char(jint val) {
+ return (jchar) val;
+}
+
+inline jshort BytecodeInterpreter::VMint2Short(jint val) {
+ return (jshort) val;
+}
+
+inline jbyte BytecodeInterpreter::VMint2Byte(jint val) {
+ return (jbyte) val;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_bytecodes_zero.cpp.incl"
+
+void Bytecodes::pd_initialize() {
+ // No zero specific initialization
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/bytes_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+typedef union unaligned {
+ u4 u;
+ u2 us;
+ u8 ul;
+} __attribute__((packed)) unaligned;
+
+class Bytes: AllStatic {
+ public:
+ // Returns true if the byte ordering used by Java is different
+ // from the native byte ordering of the underlying machine.
+ static inline bool is_Java_byte_ordering_different() {
+#ifdef VM_LITTLE_ENDIAN
+ return true;
+#else
+ return false;
+#endif
+ }
+
+ // Efficient reading and writing of unaligned unsigned data in
+ // platform-specific byte ordering.
+ static inline u2 get_native_u2(address p){
+ unaligned *up = (unaligned *) p;
+ return up->us;
+ }
+
+ static inline u4 get_native_u4(address p) {
+ unaligned *up = (unaligned *) p;
+ return up->u;
+ }
+
+ static inline u8 get_native_u8(address p) {
+ unaligned *up = (unaligned *) p;
+ return up->ul;
+ }
+
+ static inline void put_native_u2(address p, u2 x) {
+ unaligned *up = (unaligned *) p;
+ up->us = x;
+ }
+
+ static inline void put_native_u4(address p, u4 x) {
+ unaligned *up = (unaligned *) p;
+ up->u = x;
+ }
+
+ static inline void put_native_u8(address p, u8 x) {
+ unaligned *up = (unaligned *) p;
+ up->ul = x;
+ }
+
+ // Efficient reading and writing of unaligned unsigned data in Java
+ // byte ordering (i.e. big-endian ordering).
+#ifdef VM_LITTLE_ENDIAN
+ // Byte-order reversal is needed
+ static inline u2 get_Java_u2(address p) {
+ return (u2(p[0]) << 8) |
+ (u2(p[1]) );
+ }
+ static inline u4 get_Java_u4(address p) {
+ return (u4(p[0]) << 24) |
+ (u4(p[1]) << 16) |
+ (u4(p[2]) << 8) |
+ (u4(p[3]) );
+ }
+ static inline u8 get_Java_u8(address p) {
+ u4 hi, lo;
+ hi = (u4(p[0]) << 24) |
+ (u4(p[1]) << 16) |
+ (u4(p[2]) << 8) |
+ (u4(p[3]) );
+ lo = (u4(p[4]) << 24) |
+ (u4(p[5]) << 16) |
+ (u4(p[6]) << 8) |
+ (u4(p[7]) );
+ return u8(lo) | (u8(hi) << 32);
+ }
+
+ static inline void put_Java_u2(address p, u2 x) {
+ p[0] = x >> 8;
+ p[1] = x;
+ }
+ static inline void put_Java_u4(address p, u4 x) {
+ p[0] = x >> 24;
+ p[1] = x >> 16;
+ p[2] = x >> 8;
+ p[3] = x;
+ }
+ static inline void put_Java_u8(address p, u8 x) {
+ u4 hi, lo;
+ lo = x;
+ hi = x >> 32;
+ p[0] = hi >> 24;
+ p[1] = hi >> 16;
+ p[2] = hi >> 8;
+ p[3] = hi;
+ p[4] = lo >> 24;
+ p[5] = lo >> 16;
+ p[6] = lo >> 8;
+ p[7] = lo;
+ }
+
+ // Efficient swapping of byte ordering
+ static inline u2 swap_u2(u2 x);
+ static inline u4 swap_u4(u4 x);
+ static inline u8 swap_u8(u8 x);
+#else
+ // No byte-order reversal is needed
+ static inline u2 get_Java_u2(address p) {
+ return get_native_u2(p);
+ }
+ static inline u4 get_Java_u4(address p) {
+ return get_native_u4(p);
+ }
+ static inline u8 get_Java_u8(address p) {
+ return get_native_u8(p);
+ }
+
+ static inline void put_Java_u2(address p, u2 x) {
+ put_native_u2(p, x);
+ }
+ static inline void put_Java_u4(address p, u4 x) {
+ put_native_u4(p, x);
+ }
+ static inline void put_Java_u8(address p, u8 x) {
+ put_native_u8(p, x);
+ }
+
+ // No byte-order reversal is needed
+ static inline u2 swap_u2(u2 x) { return x; }
+ static inline u4 swap_u4(u4 x) { return x; }
+ static inline u8 swap_u8(u8 x) { return x; }
+#endif // VM_LITTLE_ENDIAN
+};
+
+#ifdef VM_LITTLE_ENDIAN
+// The following header contains the implementations of swap_u2,
+// swap_u4, and swap_u8
+#include "incls/_bytes_pd.inline.hpp.incl"
+#endif // VM_LITTLE_ENDIAN
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/codeBuffer_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ private:
+ void pd_initialize() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/copy_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Inline functions for memory copy and fill.
+
+static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default:
+ memcpy(to, from, count * HeapWordSize);
+ break;
+ }
+}
+
+static void pd_disjoint_words_atomic(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ switch (count) {
+ case 8: to[7] = from[7];
+ case 7: to[6] = from[6];
+ case 6: to[5] = from[5];
+ case 5: to[4] = from[4];
+ case 4: to[3] = from[3];
+ case 3: to[2] = from[2];
+ case 2: to[1] = from[1];
+ case 1: to[0] = from[0];
+ case 0: break;
+ default:
+ while (count-- > 0) {
+ *to++ = *from++;
+ }
+ break;
+ }
+}
+
+static void pd_aligned_conjoint_words(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ memmove(to, from, count * HeapWordSize);
+}
+
+static void pd_aligned_disjoint_words(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ pd_disjoint_words(from, to, count);
+}
+
+static void pd_conjoint_bytes(void* from, void* to, size_t count) {
+ memmove(to, from, count);
+}
+
+static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
+ memmove(to, from, count);
+}
+
+static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ _Copy_conjoint_jshorts_atomic(from, to, count);
+}
+
+static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ _Copy_conjoint_jints_atomic(from, to, count);
+}
+
+static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+ _Copy_conjoint_jlongs_atomic(from, to, count);
+}
+
+static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
+#ifdef _LP64
+ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
+ _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
+#else
+ assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size");
+ _Copy_conjoint_jints_atomic((jint*)from, (jint*)to, count);
+#endif // _LP64
+}
+
+static void pd_arrayof_conjoint_bytes(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_bytes(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jshorts(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jshorts(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jints(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jints(from, to, count);
+}
+
+static void pd_arrayof_conjoint_jlongs(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ _Copy_arrayof_conjoint_jlongs(from, to, count);
+}
+
+static void pd_arrayof_conjoint_oops(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+#ifdef _LP64
+ assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
+ _Copy_arrayof_conjoint_jlongs(from, to, count);
+#else
+ assert(BytesPerInt == BytesPerOop, "jints and oops must be the same size");
+ _Copy_arrayof_conjoint_jints(from, to, count);
+#endif // _LP64
+}
+
+static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
+#ifdef _LP64
+ julong* to = (julong*) tohw;
+ julong v = ((julong) value << 32) | value;
+#else
+ juint* to = (juint*) tohw;
+ juint v = value;
+#endif // _LP64
+
+ while (count-- > 0) {
+ *to++ = v;
+ }
+}
+
+static void pd_fill_to_aligned_words(HeapWord* tohw,
+ size_t count,
+ juint value) {
+ pd_fill_to_words(tohw, count, value);
+}
+
+static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
+ memset(to, value, count);
+}
+
+static void pd_zero_to_words(HeapWord* tohw, size_t count) {
+ pd_fill_to_words(tohw, count, 0);
+}
+
+static void pd_zero_to_bytes(void* to, size_t count) {
+ memset(to, 0, count);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ protected:
+ MacroAssembler* assembler() const {
+ return _masm;
+ }
+
+ protected:
+ address generate_entry(address entry_point) {
+ ZeroEntry *entry = (ZeroEntry *) assembler()->pc();
+ assembler()->advance(sizeof(ZeroEntry));
+ entry->set_entry_point(entry_point);
+ return (address) entry;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,946 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_cppInterpreter_zero.cpp.incl"
+
+#ifdef CC_INTERP
+
+#define fixup_after_potential_safepoint() \
+ method = istate->method()
+
+#define CALL_VM_NOCHECK(func) \
+ thread->set_last_Java_frame(); \
+ func; \
+ thread->reset_last_Java_frame(); \
+ fixup_after_potential_safepoint()
+
+void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Adjust the caller's stack frame to accomodate any additional
+ // local variables we have contiguously with our parameters.
+ int extra_locals = method->max_locals() - method->size_of_parameters();
+ if (extra_locals > 0) {
+ if (extra_locals > stack->available_words()) {
+ Unimplemented();
+ }
+ for (int i = 0; i < extra_locals; i++)
+ stack->push(0);
+ }
+
+ // Allocate and initialize our frame.
+ InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread);
+ thread->push_zero_frame(frame);
+
+ // Execute those bytecodes!
+ main_loop(0, THREAD);
+}
+
+void CppInterpreter::main_loop(int recurse, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // If we are entering from a deopt we may need to call
+ // ourself a few times in order to get to our frame.
+ if (recurse)
+ main_loop(recurse - 1, THREAD);
+
+ InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
+ interpreterState istate = frame->interpreter_state();
+ methodOop method = istate->method();
+
+ intptr_t *result = NULL;
+ int result_slots = 0;
+
+ // Check we're not about to run out of stack
+ if (stack_overflow_imminent(thread)) {
+ CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread));
+ goto unwind_and_return;
+ }
+
+ while (true) {
+ // We can set up the frame anchor with everything we want at
+ // this point as we are thread_in_Java and no safepoints can
+ // occur until we go to vm mode. We do have to clear flags
+ // on return from vm but that is it.
+ thread->set_last_Java_frame();
+
+ // Call the interpreter
+ if (JvmtiExport::can_post_interpreter_events())
+ BytecodeInterpreter::runWithChecks(istate);
+ else
+ BytecodeInterpreter::run(istate);
+ fixup_after_potential_safepoint();
+
+ // Clear the frame anchor
+ thread->reset_last_Java_frame();
+
+ // Examine the message from the interpreter to decide what to do
+ if (istate->msg() == BytecodeInterpreter::call_method) {
+ methodOop callee = istate->callee();
+
+ // Trim back the stack to put the parameters at the top
+ stack->set_sp(istate->stack() + 1);
+
+ // Make the call
+ Interpreter::invoke_method(callee, istate->callee_entry_point(), THREAD);
+ fixup_after_potential_safepoint();
+
+ // Convert the result
+ istate->set_stack(stack->sp() - 1);
+
+ // Restore the stack
+ stack->set_sp(istate->stack_limit() + 1);
+
+ // Resume the interpreter
+ istate->set_msg(BytecodeInterpreter::method_resume);
+ }
+ else if (istate->msg() == BytecodeInterpreter::more_monitors) {
+ int monitor_words = frame::interpreter_frame_monitor_size();
+
+ // Allocate the space
+ if (monitor_words > stack->available_words()) {
+ Unimplemented();
+ }
+ stack->alloc(monitor_words * wordSize);
+
+ // Move the expression stack contents
+ for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++)
+ *(p - monitor_words) = *p;
+
+ // Move the expression stack pointers
+ istate->set_stack_limit(istate->stack_limit() - monitor_words);
+ istate->set_stack(istate->stack() - monitor_words);
+ istate->set_stack_base(istate->stack_base() - monitor_words);
+
+ // Zero the new monitor so the interpreter can find it.
+ ((BasicObjectLock *) istate->stack_base())->set_obj(NULL);
+
+ // Resume the interpreter
+ istate->set_msg(BytecodeInterpreter::got_monitors);
+ }
+ else if (istate->msg() == BytecodeInterpreter::return_from_method) {
+ // Copy the result into the caller's frame
+ result_slots = type2size[method->result_type()];
+ assert(result_slots >= 0 && result_slots <= 2, "what?");
+ result = istate->stack() + result_slots;
+ break;
+ }
+ else if (istate->msg() == BytecodeInterpreter::throwing_exception) {
+ assert(HAS_PENDING_EXCEPTION, "should do");
+ break;
+ }
+ else if (istate->msg() == BytecodeInterpreter::do_osr) {
+ // Unwind the current frame
+ thread->pop_zero_frame();
+
+ // Remove any extension of the previous frame
+ int extra_locals = method->max_locals() - method->size_of_parameters();
+ stack->set_sp(stack->sp() + extra_locals);
+
+ // Jump into the OSR method
+ Interpreter::invoke_osr(
+ method, istate->osr_entry(), istate->osr_buf(), THREAD);
+ return;
+ }
+ else {
+ ShouldNotReachHere();
+ }
+ }
+
+ unwind_and_return:
+
+ // Unwind the current frame
+ thread->pop_zero_frame();
+
+ // Pop our local variables
+ stack->set_sp(stack->sp() + method->max_locals());
+
+ // Push our result
+ for (int i = 0; i < result_slots; i++)
+ stack->push(result[-i]);
+}
+
+void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ // Make sure method is native and not abstract
+ assert(method->is_native() && !method->is_abstract(), "should be");
+
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Allocate and initialize our frame
+ InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread);
+ thread->push_zero_frame(frame);
+ interpreterState istate = frame->interpreter_state();
+ intptr_t *locals = istate->locals();
+
+ // Check we're not about to run out of stack
+ if (stack_overflow_imminent(thread)) {
+ CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread));
+ goto unwind_and_return;
+ }
+
+ // Lock if necessary
+ BasicObjectLock *monitor;
+ monitor = NULL;
+ if (method->is_synchronized()) {
+ monitor = (BasicObjectLock*) istate->stack_base();
+ oop lockee = monitor->obj();
+ markOop disp = lockee->mark()->set_unlocked();
+
+ monitor->lock()->set_displaced_header(disp);
+ if (Atomic::cmpxchg_ptr(monitor, lockee->mark_addr(), disp) != disp) {
+ if (thread->is_lock_owned((address) disp->clear_lock_bits())) {
+ monitor->lock()->set_displaced_header(NULL);
+ }
+ else {
+ CALL_VM_NOCHECK(InterpreterRuntime::monitorenter(thread, monitor));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+ }
+ }
+ }
+
+ // Get the signature handler
+ InterpreterRuntime::SignatureHandler *handler; {
+ address handlerAddr = method->signature_handler();
+ if (handlerAddr == NULL) {
+ CALL_VM_NOCHECK(InterpreterRuntime::prepare_native_call(thread, method));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+
+ handlerAddr = method->signature_handler();
+ assert(handlerAddr != NULL, "eh?");
+ }
+ if (handlerAddr == (address) InterpreterRuntime::slow_signature_handler) {
+ CALL_VM_NOCHECK(handlerAddr =
+ InterpreterRuntime::slow_signature_handler(thread, method, NULL,NULL));
+ if (HAS_PENDING_EXCEPTION)
+ goto unwind_and_return;
+ }
+ handler = \
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
+ }
+
+ // Get the native function entry point
+ address function;
+ function = method->native_function();
+ assert(function != NULL, "should be set if signature handler is");
+
+ // Build the argument list
+ if (handler->argument_count() * 2 > stack->available_words()) {
+ Unimplemented();
+ }
+ void **arguments;
+ void *mirror; {
+ arguments =
+ (void **) stack->alloc(handler->argument_count() * sizeof(void **));
+ void **dst = arguments;
+
+ void *env = thread->jni_environment();
+ *(dst++) = &env;
+
+ if (method->is_static()) {
+ istate->set_oop_temp(
+ method->constants()->pool_holder()->klass_part()->java_mirror());
+ mirror = istate->oop_temp_addr();
+ *(dst++) = &mirror;
+ }
+
+ intptr_t *src = locals;
+ for (int i = dst - arguments; i < handler->argument_count(); i++) {
+ ffi_type *type = handler->argument_type(i);
+ if (type == &ffi_type_pointer) {
+ if (*src) {
+ stack->push((intptr_t) src);
+ *(dst++) = stack->sp();
+ }
+ else {
+ *(dst++) = src;
+ }
+ src--;
+ }
+ else if (type->size == 4) {
+ *(dst++) = src--;
+ }
+ else if (type->size == 8) {
+ src--;
+ *(dst++) = src--;
+ }
+ else {
+ ShouldNotReachHere();
+ }
+ }
+ }
+
+ // Set up the Java frame anchor
+ thread->set_last_Java_frame();
+
+ // Change the thread state to _thread_in_native
+ ThreadStateTransition::transition_from_java(thread, _thread_in_native);
+
+ // Make the call
+ intptr_t result[4 - LogBytesPerWord];
+ ffi_call(handler->cif(), (void (*)()) function, result, arguments);
+
+ // Change the thread state back to _thread_in_Java.
+ // ThreadStateTransition::transition_from_native() cannot be used
+ // here because it does not check for asynchronous exceptions.
+ // We have to manage the transition ourself.
+ thread->set_thread_state(_thread_in_native_trans);
+
+ // Make sure new state is visible in the GC thread
+ if (os::is_MP()) {
+ if (UseMembar) {
+ OrderAccess::fence();
+ }
+ else {
+ InterfaceSupport::serialize_memory(thread);
+ }
+ }
+
+ // Handle safepoint operations, pending suspend requests,
+ // and pending asynchronous exceptions.
+ if (SafepointSynchronize::do_call_back() ||
+ thread->has_special_condition_for_native_trans()) {
+ JavaThread::check_special_condition_for_native_trans(thread);
+ CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops());
+ }
+
+ // Finally we can change the thread state to _thread_in_Java.
+ thread->set_thread_state(_thread_in_Java);
+ fixup_after_potential_safepoint();
+
+ // Clear the frame anchor
+ thread->reset_last_Java_frame();
+
+ // If the result was an oop then unbox it and store it in
+ // oop_temp where the garbage collector can see it before
+ // we release the handle it might be protected by.
+ if (handler->result_type() == &ffi_type_pointer) {
+ if (result[0])
+ istate->set_oop_temp(*(oop *) result[0]);
+ else
+ istate->set_oop_temp(NULL);
+ }
+
+ // Reset handle block
+ thread->active_handles()->clear();
+
+ // Unlock if necessary. It seems totally wrong that this
+ // is skipped in the event of an exception but apparently
+ // the template interpreter does this so we do too.
+ if (monitor && !HAS_PENDING_EXCEPTION) {
+ BasicLock *lock = monitor->lock();
+ markOop header = lock->displaced_header();
+ oop rcvr = monitor->obj();
+ monitor->set_obj(NULL);
+
+ if (header != NULL) {
+ if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) {
+ monitor->set_obj(rcvr); {
+ HandleMark hm(thread);
+ CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(thread, monitor));
+ }
+ }
+ }
+ }
+
+ unwind_and_return:
+
+ // Unwind the current activation
+ thread->pop_zero_frame();
+
+ // Pop our parameters
+ stack->set_sp(stack->sp() + method->size_of_parameters());
+
+ // Push our result
+ if (!HAS_PENDING_EXCEPTION) {
+ stack->set_sp(stack->sp() - type2size[method->result_type()]);
+
+ switch (method->result_type()) {
+ case T_VOID:
+ break;
+
+ case T_BOOLEAN:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerByte);
+#endif
+ SET_LOCALS_INT(*(jboolean *) result != 0, 0);
+ break;
+
+ case T_CHAR:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerShort);
+#endif
+ SET_LOCALS_INT(*(jchar *) result, 0);
+ break;
+
+ case T_BYTE:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerByte);
+#endif
+ SET_LOCALS_INT(*(jbyte *) result, 0);
+ break;
+
+ case T_SHORT:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerShort);
+#endif
+ SET_LOCALS_INT(*(jshort *) result, 0);
+ break;
+
+ case T_INT:
+#ifndef VM_LITTLE_ENDIAN
+ result[0] <<= (BitsPerWord - BitsPerInt);
+#endif
+ SET_LOCALS_INT(*(jint *) result, 0);
+ break;
+
+ case T_LONG:
+ SET_LOCALS_LONG(*(jlong *) result, 0);
+ break;
+
+ case T_FLOAT:
+ SET_LOCALS_FLOAT(*(jfloat *) result, 0);
+ break;
+
+ case T_DOUBLE:
+ SET_LOCALS_DOUBLE(*(jdouble *) result, 0);
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ SET_LOCALS_OBJECT(istate->oop_temp(), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+}
+
+void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+ intptr_t *locals = stack->sp();
+
+ // Drop into the slow path if we need a safepoint check
+ if (SafepointSynchronize::do_call_back()) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Load the object pointer and drop into the slow path
+ // if we have a NullPointerException
+ oop object = LOCALS_OBJECT(0);
+ if (object == NULL) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Read the field index from the bytecode, which looks like this:
+ // 0: aload_0
+ // 1: getfield
+ // 2: index
+ // 3: index
+ // 4: ireturn/areturn
+ // NB this is not raw bytecode: index is in machine order
+ u1 *code = method->code_base();
+ assert(code[0] == Bytecodes::_aload_0 &&
+ code[1] == Bytecodes::_getfield &&
+ (code[4] == Bytecodes::_ireturn ||
+ code[4] == Bytecodes::_areturn), "should do");
+ u2 index = Bytes::get_native_u2(&code[2]);
+
+ // Get the entry from the constant pool cache, and drop into
+ // the slow path if it has not been resolved
+ constantPoolCacheOop cache = method->constants()->cache();
+ ConstantPoolCacheEntry* entry = cache->entry_at(index);
+ if (!entry->is_resolved(Bytecodes::_getfield)) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Get the result and push it onto the stack
+ switch (entry->flag_state()) {
+ case ltos:
+ case dtos:
+ if (stack->available_words() < 1) {
+ Unimplemented();
+ }
+ stack->alloc(wordSize);
+ break;
+ }
+ if (entry->is_volatile()) {
+ switch (entry->flag_state()) {
+ case ctos:
+ SET_LOCALS_INT(object->char_field_acquire(entry->f2()), 0);
+ break;
+
+ case btos:
+ SET_LOCALS_INT(object->byte_field_acquire(entry->f2()), 0);
+ break;
+
+ case stos:
+ SET_LOCALS_INT(object->short_field_acquire(entry->f2()), 0);
+ break;
+
+ case itos:
+ SET_LOCALS_INT(object->int_field_acquire(entry->f2()), 0);
+ break;
+
+ case ltos:
+ SET_LOCALS_LONG(object->long_field_acquire(entry->f2()), 0);
+ break;
+
+ case ftos:
+ SET_LOCALS_FLOAT(object->float_field_acquire(entry->f2()), 0);
+ break;
+
+ case dtos:
+ SET_LOCALS_DOUBLE(object->double_field_acquire(entry->f2()), 0);
+ break;
+
+ case atos:
+ SET_LOCALS_OBJECT(object->obj_field_acquire(entry->f2()), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+ else {
+ switch (entry->flag_state()) {
+ case ctos:
+ SET_LOCALS_INT(object->char_field(entry->f2()), 0);
+ break;
+
+ case btos:
+ SET_LOCALS_INT(object->byte_field(entry->f2()), 0);
+ break;
+
+ case stos:
+ SET_LOCALS_INT(object->short_field(entry->f2()), 0);
+ break;
+
+ case itos:
+ SET_LOCALS_INT(object->int_field(entry->f2()), 0);
+ break;
+
+ case ltos:
+ SET_LOCALS_LONG(object->long_field(entry->f2()), 0);
+ break;
+
+ case ftos:
+ SET_LOCALS_FLOAT(object->float_field(entry->f2()), 0);
+ break;
+
+ case dtos:
+ SET_LOCALS_DOUBLE(object->double_field(entry->f2()), 0);
+ break;
+
+ case atos:
+ SET_LOCALS_OBJECT(object->obj_field(entry->f2()), 0);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ }
+}
+
+void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Drop into the slow path if we need a safepoint check
+ if (SafepointSynchronize::do_call_back()) {
+ normal_entry(method, 0, THREAD);
+ return;
+ }
+
+ // Pop our parameters
+ stack->set_sp(stack->sp() + method->size_of_parameters());
+}
+
+bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) {
+ // How is the ABI stack?
+ address stack_top = thread->stack_base() - thread->stack_size();
+ int free_stack = os::current_stack_pointer() - stack_top;
+ if (free_stack < StackShadowPages * os::vm_page_size()) {
+ return true;
+ }
+
+ // How is the Zero stack?
+ // Throwing a StackOverflowError involves a VM call, which means
+ // we need a frame on the stack. We should be checking here to
+ // ensure that methods we call have enough room to install the
+ // largest possible frame, but that's more than twice the size
+ // of the entire Zero stack we get by default, so we just check
+ // we have *some* space instead...
+ free_stack = thread->zero_stack()->available_words() * wordSize;
+ if (free_stack < StackShadowPages * os::vm_page_size()) {
+ return true;
+ }
+
+ return false;
+}
+
+InterpreterFrame *InterpreterFrame::build(ZeroStack* stack,
+ const methodOop method,
+ JavaThread* thread) {
+ int monitor_words =
+ method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0;
+ int stack_words = method->is_native() ? 0 : method->max_stack();
+
+ if (header_words + monitor_words + stack_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ intptr_t *locals;
+ if (method->is_native())
+ locals = stack->sp() + (method->size_of_parameters() - 1);
+ else
+ locals = stack->sp() + (method->max_locals() - 1);
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(INTERPRETER_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ interpreterState istate =
+ (interpreterState) stack->alloc(sizeof(BytecodeInterpreter));
+ assert(fp - stack->sp() == istate_off, "should be");
+
+ istate->set_locals(locals);
+ istate->set_method(method);
+ istate->set_self_link(istate);
+ istate->set_prev_link(NULL);
+ istate->set_thread(thread);
+ istate->set_bcp(method->is_native() ? NULL : method->code_base());
+ istate->set_constants(method->constants()->cache());
+ istate->set_msg(BytecodeInterpreter::method_entry);
+ istate->set_oop_temp(NULL);
+ istate->set_mdx(NULL);
+ istate->set_callee(NULL);
+
+ istate->set_monitor_base((BasicObjectLock *) stack->sp());
+ if (method->is_synchronized()) {
+ BasicObjectLock *monitor =
+ (BasicObjectLock *) stack->alloc(monitor_words * wordSize);
+ oop object;
+ if (method->is_static())
+ object = method->constants()->pool_holder()->klass_part()->java_mirror();
+ else
+ object = (oop) locals[0];
+ monitor->set_obj(object);
+ }
+
+ istate->set_stack_base(stack->sp());
+ istate->set_stack(stack->sp() - 1);
+ if (stack_words)
+ stack->alloc(stack_words * wordSize);
+ istate->set_stack_limit(stack->sp() - 1);
+
+ return (InterpreterFrame *) fp;
+}
+
+int AbstractInterpreter::BasicType_as_index(BasicType type) {
+ int i = 0;
+ switch (type) {
+ case T_BOOLEAN: i = 0; break;
+ case T_CHAR : i = 1; break;
+ case T_BYTE : i = 2; break;
+ case T_SHORT : i = 3; break;
+ case T_INT : i = 4; break;
+ case T_LONG : i = 5; break;
+ case T_VOID : i = 6; break;
+ case T_FLOAT : i = 7; break;
+ case T_DOUBLE : i = 8; break;
+ case T_OBJECT : i = 9; break;
+ case T_ARRAY : i = 9; break;
+ default : ShouldNotReachHere();
+ }
+ assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers,
+ "index out of bounds");
+ return i;
+}
+
+address InterpreterGenerator::generate_empty_entry() {
+ if (!UseFastEmptyMethods)
+ return NULL;
+
+ return generate_entry((address) CppInterpreter::empty_entry);
+}
+
+address InterpreterGenerator::generate_accessor_entry() {
+ if (!UseFastAccessorMethods)
+ return NULL;
+
+ return generate_entry((address) CppInterpreter::accessor_entry);
+}
+
+address InterpreterGenerator::generate_native_entry(bool synchronized) {
+ assert(synchronized == false, "should be");
+
+ return generate_entry((address) CppInterpreter::native_entry);
+}
+
+address InterpreterGenerator::generate_normal_entry(bool synchronized) {
+ assert(synchronized == false, "should be");
+
+ return generate_entry((address) CppInterpreter::normal_entry);
+}
+
+address AbstractInterpreterGenerator::generate_method_entry(
+ AbstractInterpreter::MethodKind kind) {
+ address entry_point = NULL;
+
+ switch (kind) {
+ case Interpreter::zerolocals:
+ case Interpreter::zerolocals_synchronized:
+ break;
+
+ case Interpreter::native:
+ entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
+ break;
+
+ case Interpreter::native_synchronized:
+ entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false);
+ break;
+
+ case Interpreter::empty:
+ entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();
+ break;
+
+ case Interpreter::accessor:
+ entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();
+ break;
+
+ case Interpreter::abstract:
+ entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();
+ break;
+
+ case Interpreter::method_handle:
+ entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();
+ break;
+
+ case Interpreter::java_lang_math_sin:
+ case Interpreter::java_lang_math_cos:
+ case Interpreter::java_lang_math_tan:
+ case Interpreter::java_lang_math_abs:
+ case Interpreter::java_lang_math_log:
+ case Interpreter::java_lang_math_log10:
+ case Interpreter::java_lang_math_sqrt:
+ entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ if (entry_point == NULL)
+ entry_point = ((InterpreterGenerator*) this)->generate_normal_entry(false);
+
+ return entry_point;
+}
+
+InterpreterGenerator::InterpreterGenerator(StubQueue* code)
+ : CppInterpreterGenerator(code) {
+ generate_all();
+}
+
+// Deoptimization helpers
+
+InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) {
+ int size_in_words = size >> LogBytesPerWord;
+ assert(size_in_words * wordSize == size, "unaligned");
+ assert(size_in_words >= header_words, "too small");
+
+ if (size_in_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(INTERPRETER_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ interpreterState istate =
+ (interpreterState) stack->alloc(sizeof(BytecodeInterpreter));
+ assert(fp - stack->sp() == istate_off, "should be");
+ istate->set_self_link(NULL); // mark invalid
+
+ stack->alloc((size_in_words - header_words) * wordSize);
+
+ return (InterpreterFrame *) fp;
+}
+
+int AbstractInterpreter::layout_activation(methodOop method,
+ int tempcount,
+ int popframe_extra_args,
+ int moncount,
+ int callee_param_count,
+ int callee_locals,
+ frame* caller,
+ frame* interpreter_frame,
+ bool is_top_frame) {
+ assert(popframe_extra_args == 0, "what to do?");
+ assert(!is_top_frame || (!callee_locals && !callee_param_count),
+ "top frame should have no caller")
+
+ // This code must exactly match what InterpreterFrame::build
+ // does (the full InterpreterFrame::build, that is, not the
+ // one that creates empty frames for the deoptimizer).
+ //
+ // If interpreter_frame is not NULL then it will be filled in.
+ // It's size is determined by a previous call to this method,
+ // so it should be correct.
+ //
+ // Note that tempcount is the current size of the expression
+ // stack. For top most frames we will allocate a full sized
+ // expression stack and not the trimmed version that non-top
+ // frames have.
+
+ int header_words = InterpreterFrame::header_words;
+ int monitor_words = moncount * frame::interpreter_frame_monitor_size();
+ int stack_words = is_top_frame ? method->max_stack() : tempcount;
+ int callee_extra_locals = callee_locals - callee_param_count;
+
+ if (interpreter_frame) {
+ intptr_t *locals = interpreter_frame->sp() + method->max_locals();
+ interpreterState istate = interpreter_frame->get_interpreterState();
+ intptr_t *monitor_base = (intptr_t*) istate;
+ intptr_t *stack_base = monitor_base - monitor_words;
+ intptr_t *stack = stack_base - tempcount - 1;
+
+ BytecodeInterpreter::layout_interpreterState(istate,
+ caller,
+ NULL,
+ method,
+ locals,
+ stack,
+ stack_base,
+ monitor_base,
+ NULL,
+ is_top_frame);
+ }
+ return header_words + monitor_words + stack_words + callee_extra_locals;
+}
+
+void BytecodeInterpreter::layout_interpreterState(interpreterState istate,
+ frame* caller,
+ frame* current,
+ methodOop method,
+ intptr_t* locals,
+ intptr_t* stack,
+ intptr_t* stack_base,
+ intptr_t* monitor_base,
+ intptr_t* frame_bottom,
+ bool is_top_frame) {
+ istate->set_locals(locals);
+ istate->set_method(method);
+ istate->set_self_link(istate);
+ istate->set_prev_link(NULL);
+ // thread will be set by a hacky repurposing of frame::patch_pc()
+ // bcp will be set by vframeArrayElement::unpack_on_stack()
+ istate->set_constants(method->constants()->cache());
+ istate->set_msg(BytecodeInterpreter::method_resume);
+ istate->set_bcp_advance(0);
+ istate->set_oop_temp(NULL);
+ istate->set_mdx(NULL);
+ if (caller->is_interpreted_frame()) {
+ interpreterState prev = caller->get_interpreterState();
+ prev->set_callee(method);
+ if (*prev->bcp() == Bytecodes::_invokeinterface)
+ prev->set_bcp_advance(5);
+ else
+ prev->set_bcp_advance(3);
+ }
+ istate->set_callee(NULL);
+ istate->set_monitor_base((BasicObjectLock *) monitor_base);
+ istate->set_stack_base(stack_base);
+ istate->set_stack(stack);
+ istate->set_stack_limit(stack_base - method->max_stack() - 1);
+}
+
+address CppInterpreter::return_entry(TosState state, int length) {
+ ShouldNotCallThis();
+}
+
+address CppInterpreter::deopt_entry(TosState state, int length) {
+ return NULL;
+}
+
+// Helper for (runtime) stack overflow checks
+
+int AbstractInterpreter::size_top_interpreter_activation(methodOop method) {
+ return 0;
+}
+
+// Helper for figuring out if frames are interpreter frames
+
+bool CppInterpreter::contains(address pc) {
+#ifdef PRODUCT
+ ShouldNotCallThis();
+#else
+ return false; // make frame::print_value_on work
+#endif // !PRODUCT
+}
+
+// Result handlers and convertors
+
+address CppInterpreterGenerator::generate_result_handler_for(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_tosca_to_stack_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_stack_to_stack_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+address CppInterpreterGenerator::generate_stack_to_native_abi_converter(
+ BasicType type) {
+ assembler()->advance(1);
+ return ShouldNotCallThisStub();
+}
+
+#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ protected:
+ // Size of interpreter code
+ const static int InterpreterCodeSize = 6 * K;
+
+ public:
+ // Method entries
+ static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void native_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
+ static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
+
+ public:
+ // Main loop of normal_entry
+ static void main_loop(int recurse, TRAPS);
+
+ private:
+ // Stack overflow checks
+ static bool stack_overflow_imminent(JavaThread *thread);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/debug_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_debug_zero.cpp.incl"
+
+void pd_ps(frame f) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/depChecker_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/depChecker_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/disassembler_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// The disassembler prints out zero code annotated
+// with Java specific information.
+
+ static int pd_instruction_alignment() {
+ ShouldNotCallThis();
+ }
+
+ static const char* pd_cpu_opts() {
+ ShouldNotCallThis();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/dump_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_dump_zero.cpp.incl"
+
+void CompactingPermGenGen::generate_vtable_methods(void** vtbl_list,
+ void** vtable,
+ char** md_top,
+ char* md_end,
+ char** mc_top,
+ char* mc_end) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/entryFrame_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | parameter n-1 | low addresses
+// | ... |
+// | parameter 0 |
+// | call_wrapper |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class EntryFrame : public ZeroFrame {
+ private:
+ EntryFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ call_wrapper_off = jf_header_words,
+ header_words
+ };
+
+ public:
+ static EntryFrame *build(ZeroStack* stack,
+ const intptr_t* parameters,
+ int parameter_words,
+ JavaCallWrapper* call_wrapper);
+ public:
+ JavaCallWrapper *call_wrapper() const {
+ return (JavaCallWrapper *) value_of_word(call_wrapper_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/entry_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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 ZeroEntry {
+ public:
+ ZeroEntry() {
+ ShouldNotCallThis();
+ }
+
+ private:
+ address _entry_point;
+
+ public:
+ address entry_point() const {
+ return _entry_point;
+ }
+ void set_entry_point(address entry_point) {
+ _entry_point = entry_point;
+ }
+
+ private:
+ typedef void (*NormalEntryFunc)(methodOop method,
+ intptr_t base_pc,
+ TRAPS);
+ typedef void (*OSREntryFunc)(methodOop method,
+ address osr_buf,
+ intptr_t base_pc,
+ TRAPS);
+
+ public:
+ void invoke(methodOop method, TRAPS) const {
+ ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD);
+ }
+ void invoke_osr(methodOop method, address osr_buf, TRAPS) const {
+ ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD);
+ }
+
+ public:
+ static ByteSize entry_point_offset() {
+ return byte_offset_of(ZeroEntry, _entry_point);
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/fakeStubFrame_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | frame_type | low addresses
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class FakeStubFrame : public ZeroFrame {
+ private:
+ FakeStubFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ header_words = jf_header_words
+ };
+
+ public:
+ static FakeStubFrame *build(ZeroStack* stack);
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {}
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_frame_zero.cpp.incl"
+
+#ifdef ASSERT
+void RegisterMap::check_location_valid() {
+ ShouldNotCallThis();
+}
+#endif
+
+bool frame::is_interpreted_frame() const {
+ return zeroframe()->is_interpreter_frame();
+}
+
+bool frame::is_fake_stub_frame() const {
+ return zeroframe()->is_fake_stub_frame();
+}
+
+frame frame::sender_for_entry_frame(RegisterMap *map) const {
+ assert(map != NULL, "map must be set");
+ assert(!entry_frame_is_first(), "next Java fp must be non zero");
+ assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),
+ "sender should be next Java frame");
+ map->clear();
+ assert(map->include_argument_oops(), "should be set by clear");
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender_for_interpreter_frame(RegisterMap *map) const {
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender_for_compiled_frame(RegisterMap *map) const {
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender_for_fake_stub_frame(RegisterMap *map) const {
+ return frame(sender_sp(), sp() + 1);
+}
+
+frame frame::sender(RegisterMap* map) const {
+ // Default is not to follow arguments; the various
+ // sender_for_xxx methods update this accordingly.
+ map->set_include_argument_oops(false);
+
+ if (is_entry_frame())
+ return sender_for_entry_frame(map);
+
+ if (is_interpreted_frame())
+ return sender_for_interpreter_frame(map);
+
+ if (is_compiled_frame())
+ return sender_for_compiled_frame(map);
+
+ if (is_fake_stub_frame())
+ return sender_for_fake_stub_frame(map);
+
+ ShouldNotReachHere();
+}
+
+#ifdef CC_INTERP
+BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
+ return get_interpreterState()->monitor_base();
+}
+
+BasicObjectLock* frame::interpreter_frame_monitor_end() const {
+ return (BasicObjectLock*) get_interpreterState()->stack_base();
+}
+#endif // CC_INTERP
+
+void frame::patch_pc(Thread* thread, address pc) {
+ // We borrow this call to set the thread pointer in the interpreter
+ // state; the hook to set up deoptimized frames isn't supplied it.
+ assert(pc == NULL, "should be");
+ get_interpreterState()->set_thread((JavaThread *) thread);
+}
+
+bool frame::safe_for_sender(JavaThread *thread) {
+ ShouldNotCallThis();
+}
+
+void frame::pd_gc_epilog() {
+}
+
+bool frame::is_interpreted_frame_valid(JavaThread *thread) const {
+ ShouldNotCallThis();
+}
+
+BasicType frame::interpreter_frame_result(oop* oop_result,
+ jvalue* value_result) {
+ assert(is_interpreted_frame(), "interpreted frame expected");
+ methodOop method = interpreter_frame_method();
+ BasicType type = method->result_type();
+ intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();
+ oop obj;
+
+ switch (type) {
+ case T_VOID:
+ break;
+ case T_BOOLEAN:
+ value_result->z = *(jboolean *) tos_addr;
+ break;
+ case T_BYTE:
+ value_result->b = *(jbyte *) tos_addr;
+ break;
+ case T_CHAR:
+ value_result->c = *(jchar *) tos_addr;
+ break;
+ case T_SHORT:
+ value_result->s = *(jshort *) tos_addr;
+ break;
+ case T_INT:
+ value_result->i = *(jint *) tos_addr;
+ break;
+ case T_LONG:
+ value_result->j = *(jlong *) tos_addr;
+ break;
+ case T_FLOAT:
+ value_result->f = *(jfloat *) tos_addr;
+ break;
+ case T_DOUBLE:
+ value_result->d = *(jdouble *) tos_addr;
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ if (method->is_native()) {
+ obj = get_interpreterState()->oop_temp();
+ }
+ else {
+ oop* obj_p = (oop *) tos_addr;
+ obj = (obj_p == NULL) ? (oop) NULL : *obj_p;
+ }
+ assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");
+ *oop_result = obj;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ return type;
+}
+
+int frame::frame_size(RegisterMap* map) const {
+#ifdef PRODUCT
+ ShouldNotCallThis();
+#else
+ return 0; // make javaVFrame::print_value work
+#endif // PRODUCT
+}
+
+intptr_t* frame::interpreter_frame_tos_at(jint offset) const {
+ int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);
+ return &interpreter_frame_tos_address()[index];
+}
+
+void frame::zero_print_on_error(int frame_index,
+ outputStream* st,
+ char* buf,
+ int buflen) const {
+ // Divide the buffer between the field and the value
+ buflen >>= 1;
+ char *fieldbuf = buf;
+ char *valuebuf = buf + buflen;
+
+ // Print each word of the frame
+ for (intptr_t *addr = fp(); addr <= sp(); addr++) {
+ int offset = sp() - addr;
+
+ // Fill in default values, then try and improve them
+ snprintf(fieldbuf, buflen, "word[%d]", offset);
+ snprintf(valuebuf, buflen, PTR_FORMAT, *addr);
+ zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);
+ fieldbuf[buflen - 1] = '\0';
+ valuebuf[buflen - 1] = '\0';
+
+ // Print the result
+ st->print_cr(" " PTR_FORMAT ": %-21s = %s", addr, fieldbuf, valuebuf);
+ }
+}
+
+void ZeroFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ switch (offset) {
+ case next_frame_off:
+ strncpy(fieldbuf, "next_frame", buflen);
+ break;
+
+ case frame_type_off:
+ strncpy(fieldbuf, "frame_type", buflen);
+ if (is_entry_frame())
+ strncpy(valuebuf, "ENTRY_FRAME", buflen);
+ else if (is_interpreter_frame())
+ strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
+ else if (is_shark_frame())
+ strncpy(valuebuf, "SHARK_FRAME", buflen);
+ else if (is_fake_stub_frame())
+ strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
+ break;
+
+ default:
+ if (is_entry_frame()) {
+ as_entry_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_interpreter_frame()) {
+ as_interpreter_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_shark_frame()) {
+ as_shark_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ else if (is_fake_stub_frame()) {
+ as_fake_stub_frame()->identify_word(
+ frame_index, offset, fieldbuf, valuebuf, buflen);
+ }
+ }
+}
+
+void EntryFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ switch (offset) {
+ case call_wrapper_off:
+ strncpy(fieldbuf, "call_wrapper", buflen);
+ break;
+
+ default:
+ snprintf(fieldbuf, buflen, "local[%d]", offset - 3);
+ }
+}
+
+void InterpreterFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ interpreterState istate = interpreter_state();
+ bool is_valid = istate->self_link() == istate;
+ intptr_t *addr = addr_of_word(offset);
+
+ // Fixed part
+ if (addr >= (intptr_t *) istate) {
+ const char *field = istate->name_of_field_at_address((address) addr);
+ if (field) {
+ if (is_valid && !strcmp(field, "_method")) {
+ istate->method()->name_and_sig_as_C_string(valuebuf, buflen);
+ }
+ else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {
+ snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
+ (intptr_t) istate->bcp(),
+ istate->method()->bci_from(istate->bcp()));
+ }
+ snprintf(fieldbuf, buflen, "%sistate->%s",
+ field[strlen(field) - 1] == ')' ? "(": "", field);
+ }
+ else if (addr == (intptr_t *) istate) {
+ strncpy(fieldbuf, "(vtable for istate)", buflen);
+ }
+ return;
+ }
+
+ // Variable part
+ if (!is_valid)
+ return;
+
+ // JNI stuff
+ if (istate->method()->is_native() && addr < istate->stack_base()) {
+ address hA = istate->method()->signature_handler();
+ if (hA != NULL) {
+ if (hA != (address) InterpreterRuntime::slow_signature_handler) {
+ InterpreterRuntime::SignatureHandler *handler =
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);
+
+ intptr_t *params = istate->stack_base() - handler->argument_count();
+ if (addr >= params) {
+ int param = addr - params;
+ const char *desc = "";
+ if (param == 0)
+ desc = " (JNIEnv)";
+ else if (param == 1) {
+ if (istate->method()->is_static())
+ desc = " (mirror)";
+ else
+ desc = " (this)";
+ }
+ snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);
+ return;
+ }
+
+ for (int i = 0; i < handler->argument_count(); i++) {
+ if (params[i] == (intptr_t) addr) {
+ snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);
+ return;
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ // Monitors and stack
+ identify_vp_word(frame_index, addr,
+ (intptr_t *) istate->monitor_base(),
+ istate->stack_base(),
+ fieldbuf, buflen);
+}
+
+void SharkFrame::identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const {
+ // Fixed part
+ switch (offset) {
+ case pc_off:
+ strncpy(fieldbuf, "pc", buflen);
+ if (method()->is_oop()) {
+ nmethod *code = method()->code();
+ if (code && code->pc_desc_at(pc())) {
+ SimpleScopeDesc ssd(code, pc());
+ snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
+ (intptr_t) pc(), ssd.bci());
+ }
+ }
+ return;
+
+ case unextended_sp_off:
+ strncpy(fieldbuf, "unextended_sp", buflen);
+ return;
+
+ case method_off:
+ strncpy(fieldbuf, "method", buflen);
+ if (method()->is_oop()) {
+ method()->name_and_sig_as_C_string(valuebuf, buflen);
+ }
+ return;
+
+ case oop_tmp_off:
+ strncpy(fieldbuf, "oop_tmp", buflen);
+ return;
+ }
+
+ // Variable part
+ if (method()->is_oop()) {
+ identify_vp_word(frame_index, addr_of_word(offset),
+ addr_of_word(header_words + 1),
+ unextended_sp() + method()->max_stack(),
+ fieldbuf, buflen);
+ }
+}
+
+void ZeroFrame::identify_vp_word(int frame_index,
+ intptr_t* addr,
+ intptr_t* monitor_base,
+ intptr_t* stack_base,
+ char* fieldbuf,
+ int buflen) const {
+ // Monitors
+ if (addr >= stack_base && addr < monitor_base) {
+ int monitor_size = frame::interpreter_frame_monitor_size();
+ int last_index = (monitor_base - stack_base) / monitor_size - 1;
+ int index = last_index - (addr - stack_base) / monitor_size;
+ intptr_t monitor = (intptr_t) (
+ (BasicObjectLock *) monitor_base - 1 - index);
+ intptr_t offset = (intptr_t) addr - monitor;
+
+ if (offset == BasicObjectLock::obj_offset_in_bytes())
+ snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);
+ else if (offset == BasicObjectLock::lock_offset_in_bytes())
+ snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);
+
+ return;
+ }
+
+ // Expression stack
+ if (addr < stack_base) {
+ snprintf(fieldbuf, buflen, "%s[%d]",
+ frame_index == 0 ? "stack_word" : "local",
+ (int) (stack_base - addr - 1));
+ return;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// A frame represents a physical stack frame on the Zero stack.
+
+ public:
+ enum {
+ pc_return_offset = 0
+ };
+
+ // Constructor
+ public:
+ frame(intptr_t* sp, intptr_t* fp);
+
+ // The sp of a Zero frame is the address of the highest word in
+ // that frame. We keep track of the lowest address too, so the
+ // boundaries of the frame are available for debug printing.
+ private:
+ intptr_t* _fp;
+
+ public:
+ intptr_t* fp() const {
+ return _fp;
+ }
+
+#ifdef CC_INTERP
+ inline interpreterState get_interpreterState() const;
+#endif // CC_INTERP
+
+ public:
+ const ZeroFrame *zeroframe() const {
+ return (ZeroFrame *) sp();
+ }
+
+ const EntryFrame *zero_entryframe() const {
+ return zeroframe()->as_entry_frame();
+ }
+ const InterpreterFrame *zero_interpreterframe() const {
+ return zeroframe()->as_interpreter_frame();
+ }
+ const SharkFrame *zero_sharkframe() const {
+ return zeroframe()->as_shark_frame();
+ }
+
+ public:
+ bool is_fake_stub_frame() const;
+
+ public:
+ frame sender_for_fake_stub_frame(RegisterMap* map) const;
+
+ public:
+ void zero_print_on_error(int index,
+ outputStream* st,
+ char* buf,
+ int buflen) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Constructors
+
+inline frame::frame() {
+ _sp = NULL;
+ _fp = NULL;
+ _pc = NULL;
+ _cb = NULL;
+ _deopt_state = unknown;
+}
+
+inline frame::frame(intptr_t* sp, intptr_t* fp) {
+ _sp = sp;
+ _fp = fp;
+ switch (zeroframe()->type()) {
+ case ZeroFrame::ENTRY_FRAME:
+ _pc = StubRoutines::call_stub_return_pc();
+ _cb = NULL;
+ break;
+
+ case ZeroFrame::INTERPRETER_FRAME:
+ _pc = NULL;
+ _cb = NULL;
+ break;
+
+ case ZeroFrame::SHARK_FRAME:
+ _pc = zero_sharkframe()->pc();
+ _cb = CodeCache::find_blob_unsafe(pc());
+ break;
+
+ case ZeroFrame::FAKE_STUB_FRAME:
+ _pc = NULL;
+ _cb = NULL;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ _deopt_state = not_deoptimized;
+}
+
+// Accessors
+
+inline intptr_t* frame::sender_sp() const {
+ return (intptr_t *) zeroframe()->next();
+}
+
+inline intptr_t* frame::link() const {
+ ShouldNotCallThis();
+}
+
+#ifdef CC_INTERP
+inline interpreterState frame::get_interpreterState() const {
+ return zero_interpreterframe()->interpreter_state();
+}
+
+inline intptr_t** frame::interpreter_frame_locals_addr() const {
+ return &(get_interpreterState()->_locals);
+}
+
+inline intptr_t* frame::interpreter_frame_bcx_addr() const {
+ return (intptr_t*) &(get_interpreterState()->_bcp);
+}
+
+inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const {
+ return &(get_interpreterState()->_constants);
+}
+
+inline methodOop* frame::interpreter_frame_method_addr() const {
+ return &(get_interpreterState()->_method);
+}
+
+inline intptr_t* frame::interpreter_frame_mdx_addr() const {
+ return (intptr_t*) &(get_interpreterState()->_mdx);
+}
+
+inline intptr_t* frame::interpreter_frame_tos_address() const {
+ return get_interpreterState()->_stack + 1;
+}
+#endif // CC_INTERP
+
+inline int frame::interpreter_frame_monitor_size() {
+ return BasicObjectLock::size();
+}
+
+inline intptr_t* frame::interpreter_frame_expression_stack() const {
+ intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
+ return monitor_end - 1;
+}
+
+inline jint frame::interpreter_frame_expression_stack_direction() {
+ return -1;
+}
+
+// Return a unique id for this frame. The id must have a value where
+// we can distinguish identity and younger/older relationship. NULL
+// represents an invalid (incomparable) frame.
+inline intptr_t* frame::id() const {
+ return sp();
+}
+
+inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+ return zero_entryframe()->call_wrapper();
+}
+
+inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
+ ShouldNotCallThis();
+}
+
+inline oop frame::saved_oop_result(RegisterMap* map) const {
+ ShouldNotCallThis();
+}
+
+inline bool frame::is_older(intptr_t* id) const {
+ ShouldNotCallThis();
+}
+
+inline intptr_t* frame::entry_frame_argument_at(int offset) const {
+ ShouldNotCallThis();
+}
+
+inline intptr_t* frame::unextended_sp() const {
+ if (zeroframe()->is_shark_frame())
+ return zero_sharkframe()->unextended_sp();
+ else
+ return (intptr_t *) -1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/globalDefinitions_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include <ffi.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+//
+// Set the default values for platform dependent flags used by the
+// runtime system. See globals.hpp for details of what they do.
+//
+
+define_pd_global(bool, ConvertSleepToYield, true);
+define_pd_global(bool, ShareVtableStubs, true);
+define_pd_global(bool, CountInterpCalls, true);
+define_pd_global(bool, NeedsDeoptSuspend, false);
+
+define_pd_global(bool, ImplicitNullChecks, true);
+define_pd_global(bool, UncommonNullCast, true);
+
+define_pd_global(intx, CodeEntryAlignment, 32);
+define_pd_global(uintx, TLABSize, 0);
+#ifdef _LP64
+define_pd_global(uintx, NewSize, ScaleForWordSize(2048 * K));
+#else
+define_pd_global(uintx, NewSize, ScaleForWordSize(1024 * K));
+#endif // _LP64
+define_pd_global(intx, InlineFrequencyCount, 100);
+define_pd_global(intx, InlineSmallCode, 1000);
+define_pd_global(intx, PreInflateSpin, 10);
+
+define_pd_global(intx, StackYellowPages, 2);
+define_pd_global(intx, StackRedPages, 1);
+define_pd_global(intx, StackShadowPages, 3 LP64_ONLY(+3) DEBUG_ONLY(+3));
+
+define_pd_global(bool, RewriteBytecodes, true);
+define_pd_global(bool, RewriteFrequentPairs, true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/icBuffer_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_icBuffer_zero.cpp.incl"
+
+int InlineCacheBuffer::ic_stub_code_size() {
+ // NB set this once the functions below are implemented
+ return 4;
+}
+
+void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin,
+ oop cached_oop,
+ address entry_point) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
+
+address InlineCacheBuffer::ic_buffer_entry_point(address code_begin) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
+
+oop InlineCacheBuffer::ic_buffer_cached_oop(address code_begin) {
+ // NB ic_stub_code_size() must return the size of the code we generate
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/icache_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_icache_zero.cpp.incl"
+
+void ICacheStubGenerator::generate_icache_flush(
+ ICache::flush_icache_stub_t* flush_icache_stub) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/icache_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Interface for updating the instruction cache. Whenever the VM
+// modifies code, part of the processor instruction cache potentially
+// has to be flushed. This implementation is empty: Zero never deals
+// with code, and LLVM handles cache flushing for Shark.
+
+class ICache : public AbstractICache {
+ public:
+ static void initialize() {}
+ static void invalidate_word(address addr) {}
+ static void invalidate_range(address start, int nbytes) {}
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interp_masm_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file specializes the assember with interpreter-specific macros
+
+class InterpreterMacroAssembler : public MacroAssembler {
+ public:
+ InterpreterMacroAssembler(CodeBuffer* code) : MacroAssembler(code) {}
+
+ public:
+ RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
+ Register tmp,
+ int offset) {
+ ShouldNotCallThis();
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreterFrame_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#ifdef CC_INTERP
+// | ... |
+// +--------------------+ ------------------
+// | stack slot n-1 | low addresses
+// | ... |
+// | stack slot 0 |
+// | monitor 0 (maybe) |
+// | ... |
+// | interpreter state |
+// | ... |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class InterpreterFrame : public ZeroFrame {
+ friend class AbstractInterpreter;
+
+ private:
+ InterpreterFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ istate_off = jf_header_words +
+ (align_size_up_(sizeof(BytecodeInterpreter),
+ wordSize) >> LogBytesPerWord) - 1,
+ header_words
+ };
+
+ public:
+ static InterpreterFrame *build(ZeroStack* stack,
+ const methodOop method,
+ JavaThread* thread);
+ static InterpreterFrame *build(ZeroStack* stack, int size);
+
+ public:
+ interpreterState interpreter_state() const {
+ return (interpreterState) addr_of_word(istate_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
+#endif // CC_INTERP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // Generation of Interpreter
+ //
+ friend class AbstractInterpreterGenerator;
+
+ private:
+ address generate_normal_entry(bool synchronized);
+ address generate_native_entry(bool synchronized);
+ address generate_abstract_entry();
+ address generate_math_entry(AbstractInterpreter::MethodKind kind);
+ address generate_empty_entry();
+ address generate_accessor_entry();
+ address generate_method_handle_entry();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_interpreterRT_zero.cpp.incl"
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_int() {
+ push(T_INT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_long() {
+ push(T_LONG);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_float() {
+ push(T_FLOAT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_double() {
+ push(T_DOUBLE);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::pass_object() {
+ push(T_OBJECT);
+ _cif->nargs++;
+}
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::push(BasicType type) {
+ ffi_type *ftype;
+ switch (type) {
+ case T_VOID:
+ ftype = &ffi_type_void;
+ break;
+
+ case T_BOOLEAN:
+ ftype = &ffi_type_uint8;
+ break;
+
+ case T_CHAR:
+ ftype = &ffi_type_uint16;
+ break;
+
+ case T_BYTE:
+ ftype = &ffi_type_sint8;
+ break;
+
+ case T_SHORT:
+ ftype = &ffi_type_sint16;
+ break;
+
+ case T_INT:
+ ftype = &ffi_type_sint32;
+ break;
+
+ case T_LONG:
+ ftype = &ffi_type_sint64;
+ break;
+
+ case T_FLOAT:
+ ftype = &ffi_type_float;
+ break;
+
+ case T_DOUBLE:
+ ftype = &ffi_type_double;
+ break;
+
+ case T_OBJECT:
+ case T_ARRAY:
+ ftype = &ffi_type_pointer;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+ push((intptr_t) ftype);
+}
+
+// For fast signature handlers the "signature handler" is generated
+// into a temporary buffer. It is then copied to its final location,
+// and pd_set_handler is called on it. We have this two stage thing
+// to accomodate this.
+
+void InterpreterRuntime::SignatureHandlerGeneratorBase::generate(
+ uint64_t fingerprint) {
+
+ // Build the argument types list
+ pass_object();
+ if (method()->is_static())
+ pass_object();
+ iterate(fingerprint);
+
+ // Tack on the result type
+ push(method()->result_type());
+}
+
+void InterpreterRuntime::SignatureHandler::finalize() {
+ ffi_status status =
+ ffi_prep_cif(cif(),
+ FFI_DEFAULT_ABI,
+ argument_count(),
+ result_type(),
+ argument_types());
+
+ assert(status == FFI_OK, "should be");
+}
+
+IRT_ENTRY(address,
+ InterpreterRuntime::slow_signature_handler(JavaThread* thread,
+ methodOop method,
+ intptr_t* unused1,
+ intptr_t* unused2))
+ ZeroStack *stack = thread->zero_stack();
+
+ int required_words =
+ (align_size_up(sizeof(ffi_cif), wordSize) >> LogBytesPerWord) +
+ (method->is_static() ? 2 : 1) + method->size_of_parameters() + 1;
+ if (required_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
+ SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf);
+ sshg.generate(UCONST64(-1));
+
+ SignatureHandler *handler = sshg.handler();
+ handler->finalize();
+
+ return (address) handler;
+IRT_END
+
+void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) {
+ InterpreterRuntime::SignatureHandler *handler =
+ InterpreterRuntime::SignatureHandler::from_handlerAddr(handlerAddr);
+
+ handler->finalize();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreterRT_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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 SignatureHandler {
+ public:
+ static SignatureHandler *from_handlerAddr(address handlerAddr) {
+ return (SignatureHandler *) handlerAddr;
+ }
+
+ public:
+ ffi_cif* cif() const {
+ return (ffi_cif *) this;
+ }
+
+ int argument_count() const {
+ return cif()->nargs;
+ }
+
+ ffi_type** argument_types() const {
+ return (ffi_type**) (cif() + 1);
+ }
+
+ ffi_type* argument_type(int i) const {
+ return argument_types()[i];
+ }
+
+ ffi_type* result_type() const {
+ return *(argument_types() + argument_count());
+ }
+
+ protected:
+ friend class InterpreterRuntime;
+ friend class SignatureHandlerLibrary;
+
+ void finalize();
+};
+
+class SignatureHandlerGeneratorBase : public NativeSignatureIterator {
+ private:
+ ffi_cif* _cif;
+
+ protected:
+ SignatureHandlerGeneratorBase(methodHandle method, ffi_cif *cif)
+ : NativeSignatureIterator(method), _cif(cif) {
+ _cif->nargs = 0;
+ }
+
+ ffi_cif *cif() const {
+ return _cif;
+ }
+
+ public:
+ void generate(uint64_t fingerprint);
+
+ private:
+ void pass_int();
+ void pass_long();
+ void pass_float();
+ void pass_double();
+ void pass_object();
+
+ private:
+ void push(BasicType type);
+ virtual void push(intptr_t value) = 0;
+};
+
+class SignatureHandlerGenerator : public SignatureHandlerGeneratorBase {
+ private:
+ CodeBuffer* _cb;
+
+ public:
+ SignatureHandlerGenerator(methodHandle method, CodeBuffer* buffer)
+ : SignatureHandlerGeneratorBase(method, (ffi_cif *) buffer->code_end()),
+ _cb(buffer) {
+ _cb->set_code_end((address) (cif() + 1));
+ }
+
+ private:
+ void push(intptr_t value) {
+ intptr_t *dst = (intptr_t *) _cb->code_end();
+ _cb->set_code_end((address) (dst + 1));
+ *dst = value;
+ }
+};
+
+class SlowSignatureHandlerGenerator : public SignatureHandlerGeneratorBase {
+ private:
+ intptr_t *_dst;
+
+ public:
+ SlowSignatureHandlerGenerator(methodHandle method, intptr_t* buf)
+ : SignatureHandlerGeneratorBase(method, (ffi_cif *) buf) {
+ _dst = (intptr_t *) (cif() + 1);
+ }
+
+ private:
+ void push(intptr_t value) {
+ *(_dst++) = value;
+ }
+
+ public:
+ SignatureHandler *handler() const {
+ return (SignatureHandler *) cif();
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_interpreter_zero.cpp.incl"
+
+address AbstractInterpreterGenerator::generate_slow_signature_handler() {
+ _masm->advance(1);
+ return (address) InterpreterRuntime::slow_signature_handler;
+}
+
+address InterpreterGenerator::generate_math_entry(
+ AbstractInterpreter::MethodKind kind) {
+ if (!InlineIntrinsics)
+ return NULL;
+
+ Unimplemented();
+}
+
+address InterpreterGenerator::generate_abstract_entry() {
+ return ShouldNotCallThisEntry();
+}
+
+address InterpreterGenerator::generate_method_handle_entry() {
+ return ShouldNotCallThisEntry();
+}
+
+int AbstractInterpreter::size_activation(methodOop method,
+ int tempcount,
+ int popframe_extra_args,
+ int moncount,
+ int callee_param_count,
+ int callee_locals,
+ bool is_top_frame) {
+ return layout_activation(method,
+ tempcount,
+ popframe_extra_args,
+ moncount,
+ callee_param_count,
+ callee_locals,
+ (frame*) NULL,
+ (frame*) NULL,
+ is_top_frame);
+}
+
+void Deoptimization::unwind_callee_save_values(frame* f,
+ vframeArray* vframe_array) {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ public:
+ static void invoke_method(methodOop method, address entry_point, TRAPS) {
+ ((ZeroEntry *) entry_point)->invoke(method, THREAD);
+ }
+ static void invoke_osr(methodOop method,
+ address entry_point,
+ address osr_buf,
+ TRAPS) {
+ ((ZeroEntry *) entry_point)->invoke_osr(method, osr_buf, THREAD);
+ }
+
+ public:
+ static int expr_index_at(int i) {
+ return stackElementWords() * i;
+ }
+ static int expr_tag_index_at(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
+
+ static int expr_offset_in_bytes(int i) {
+ return stackElementSize() * i;
+ }
+ static int expr_tag_offset_in_bytes(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
+
+ static int local_index_at(int i) {
+ assert(i <= 0, "local direction already negated");
+ return stackElementWords() * i + (value_offset_in_bytes() / wordSize);
+ }
+ static int local_tag_index_at(int i) {
+ assert(TaggedStackInterpreter, "should not call this");
+ Unimplemented();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/javaFrameAnchor_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ public:
+ // Each arch must define reset, save, restore
+ // These are used by objects that only care about:
+ // 1 - initializing a new state (thread creation, javaCalls)
+ // 2 - saving a current state (javaCalls)
+ // 3 - restoring an old state (javaCalls)
+
+ void clear() {
+ // clearing _last_Java_sp must be first
+ _last_Java_sp = NULL;
+ // fence?
+ _last_Java_pc = NULL;
+ }
+
+ void copy(JavaFrameAnchor* src) {
+ // In order to make sure the transition state is valid for "this"
+ // We must clear _last_Java_sp before copying the rest of the new
+ // data
+ //
+ // Hack Alert: Temporary bugfix for 4717480/4721647 To act like
+ // previous version (pd_cache_state) don't NULL _last_Java_sp
+ // unless the value is changing
+ //
+ if (_last_Java_sp != src->_last_Java_sp)
+ _last_Java_sp = NULL;
+
+ _last_Java_pc = src->_last_Java_pc;
+ // Must be last so profiler will always see valid frame if
+ // has_last_frame() is true
+ _last_Java_sp = src->_last_Java_sp;
+ }
+
+ bool walkable() {
+ return true;
+ }
+
+ void make_walkable(JavaThread* thread) {
+ // nothing to do
+ }
+
+ intptr_t* last_Java_sp() const {
+ return _last_Java_sp;
+ }
+
+ void set_last_Java_sp(intptr_t* sp) {
+ _last_Java_sp = sp;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/jniFastGetField_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_jniFastGetField_zero.cpp.incl"
+
+address JNI_FastGetField::generate_fast_get_boolean_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_byte_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_char_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_short_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_int_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_long_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_float_field() {
+ return (address) -1;
+}
+
+address JNI_FastGetField::generate_fast_get_double_field() {
+ return (address) -1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/jniTypes_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1998-2002 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.
+ *
+ */
+
+// This file holds platform-dependent routines used to write primitive jni
+// types to the array of arguments passed into JavaCalls::call
+
+class JNITypes : AllStatic {
+ // These functions write a java primitive type (in native format)
+ // to a java stack slot array to be passed as an argument to JavaCalls:calls.
+ // I.e., they are functionally 'push' operations if they have a 'pos'
+ // formal parameter. Note that jlong's and jdouble's are written
+ // _in reverse_ of the order in which they appear in the interpreter
+ // stack. This is because call stubs (see stubGenerator_zero.cpp)
+ // reverse the argument list constructed by JavaCallArguments (see
+ // javaCalls.hpp).
+
+private:
+ // Helper routines.
+ static inline void put_int2 (jint *from, jint *to) { to[0] = from[0]; to[1] = from[1]; }
+ static inline void put_int2 (jint *from, jint *to, int& pos) { put_int2 (from, (jint *)((intptr_t *)to + pos)); pos += 2; }
+ static inline void put_int2r(jint *from, jint *to) { to[0] = from[1]; to[1] = from[0]; }
+ static inline void put_int2r(jint *from, jint *to, int& pos) { put_int2r(from, (jint *)((intptr_t *)to + pos)); pos += 2; }
+
+public:
+ // Ints are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_int(jint from, intptr_t *to) { *(jint *)(to + 0 ) = from; }
+ static inline void put_int(jint from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = from; }
+ static inline void put_int(jint *from, intptr_t *to, int& pos) { *(jint *)(to + pos++) = *from; }
+
+#ifdef _LP64
+ // Longs are stored in native format in one JavaCallArgument slot at *(to+1).
+ static inline void put_long(jlong from, intptr_t *to) { *(jlong *)(to + 1 + 0) = from; }
+ static inline void put_long(jlong from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = from; pos += 2; }
+ static inline void put_long(jlong *from, intptr_t *to, int& pos) { *(jlong *)(to + 1 + pos) = *from; pos += 2; }
+#else
+ // Longs are stored in reversed native word format in two JavaCallArgument slots at *to.
+ // The high half is in *(to+1) and the low half in *to.
+ static inline void put_long(jlong from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); }
+ static inline void put_long(jlong from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); }
+ static inline void put_long(jlong *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); }
+#endif
+
+ // Oops are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_obj(oop from, intptr_t *to) { *(oop *)(to + 0 ) = from; }
+ static inline void put_obj(oop from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = from; }
+ static inline void put_obj(oop *from, intptr_t *to, int& pos) { *(oop *)(to + pos++) = *from; }
+
+ // Floats are stored in native format in one JavaCallArgument slot at *to.
+ static inline void put_float(jfloat from, intptr_t *to) { *(jfloat *)(to + 0 ) = from; }
+ static inline void put_float(jfloat from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = from; }
+ static inline void put_float(jfloat *from, intptr_t *to, int& pos) { *(jfloat *)(to + pos++) = *from; }
+
+#ifdef _LP64
+ // Doubles are stored in native word format in one JavaCallArgument slot at *(to+1).
+ static inline void put_double(jdouble from, intptr_t *to) { *(jdouble *)(to + 1 + 0) = from; }
+ static inline void put_double(jdouble from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = from; pos += 2; }
+ static inline void put_double(jdouble *from, intptr_t *to, int& pos) { *(jdouble *)(to + 1 + pos) = *from; pos += 2; }
+#else
+ // Doubles are stored in reversed native word format in two JavaCallArgument slots at *to.
+ static inline void put_double(jdouble from, intptr_t *to) { put_int2r((jint *)&from, (jint *)to); }
+ static inline void put_double(jdouble from, intptr_t *to, int& pos) { put_int2r((jint *)&from, (jint *)to, pos); }
+ static inline void put_double(jdouble *from, intptr_t *to, int& pos) { put_int2r((jint *) from, (jint *)to, pos); }
+#endif
+
+ // The get_xxx routines, on the other hand, actually _do_ fetch
+ // java primitive types from the interpreter stack.
+ static inline jint get_int(intptr_t *from) { return *(jint *)from; }
+
+#ifdef _LP64
+ static inline jlong get_long(intptr_t *from) { return *(jlong *)from; }
+#else
+ static inline jlong get_long(intptr_t *from) { return ((jlong)(*( signed int *)((jint *)from )) << 32) |
+ ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0); }
+#endif
+
+ static inline oop get_obj(intptr_t *from) { return *(oop *)from; }
+ static inline jfloat get_float(intptr_t *from) { return *(jfloat *)from; }
+
+#ifdef _LP64
+ static inline jdouble get_double(intptr_t *from) { return *(jdouble *)from; }
+#else
+ static inline jdouble get_double(intptr_t *from) { jlong jl = ((jlong)(*( signed int *)((jint *)from )) << 32) |
+ ((jlong)(*(unsigned int *)((jint *)from + 1)) << 0);
+ return *(jdouble *)&jl; }
+#endif
+
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/jni_zero.h Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#define JNIEXPORT
+#define JNIIMPORT
+#define JNICALL
+
+typedef int jint;
+typedef signed char jbyte;
+
+#ifdef _LP64
+typedef long jlong;
+#else
+typedef long long jlong;
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/methodHandles_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_nativeInst_zero.cpp.incl"
+
+// This method is called by nmethod::make_not_entrant_or_zombie to
+// insert a jump to SharedRuntime::get_handle_wrong_method_stub()
+// (dest) at the start of a compiled method (verified_entry) to avoid
+// a race where a method is invoked while being made non-entrant.
+//
+// In Shark, verified_entry is a pointer to a SharkEntry. We can
+// handle this simply by changing it's entry point to point at the
+// interpreter. This only works because the interpreter and Shark
+// calling conventions are the same.
+
+void NativeJump::patch_verified_entry(address entry,
+ address verified_entry,
+ address dest) {
+ assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
+
+#ifdef CC_INTERP
+ ((ZeroEntry*) verified_entry)->set_entry_point(
+ (address) CppInterpreter::normal_entry);
+#else
+ Unimplemented();
+#endif // CC_INTERP
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// We have interfaces for the following instructions:
+// - NativeInstruction
+// - - NativeCall
+// - - NativeMovConstReg
+// - - NativeMovConstRegPatching
+// - - NativeJump
+// - - NativeIllegalOpCode
+// - - NativeReturn
+// - - NativeReturnX (return with argument)
+// - - NativePushConst
+// - - NativeTstRegMem
+
+// The base class for different kinds of native instruction abstractions.
+// Provides the primitive operations to manipulate code relative to this.
+
+class NativeInstruction VALUE_OBJ_CLASS_SPEC {
+ public:
+ bool is_jump() {
+ ShouldNotCallThis();
+ }
+
+ bool is_safepoint_poll() {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeInstruction* nativeInstruction_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeCall : public NativeInstruction {
+ public:
+ enum zero_specific_constants {
+ instruction_size = 0 // not used within the interpreter
+ };
+
+ address instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ address next_instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ address return_address() const {
+ ShouldNotCallThis();
+ }
+
+ address destination() const {
+ ShouldNotCallThis();
+ }
+
+ void set_destination_mt_safe(address dest) {
+ ShouldNotCallThis();
+ }
+
+ void verify_alignment() {
+ ShouldNotCallThis();
+ }
+
+ void verify() {
+ ShouldNotCallThis();
+ }
+
+ static bool is_call_before(address return_address) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeCall* nativeCall_before(address return_address) {
+ ShouldNotCallThis();
+}
+
+inline NativeCall* nativeCall_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeMovConstReg : public NativeInstruction {
+ public:
+ address next_instruction_address() const {
+ ShouldNotCallThis();
+ }
+
+ intptr_t data() const {
+ ShouldNotCallThis();
+ }
+
+ void set_data(intptr_t x) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeMovConstReg* nativeMovConstReg_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeMovRegMem : public NativeInstruction {
+ public:
+ int offset() const {
+ ShouldNotCallThis();
+ }
+
+ void set_offset(intptr_t x) {
+ ShouldNotCallThis();
+ }
+
+ void add_offset_in_bytes(int add_offset) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeMovRegMem* nativeMovRegMem_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeJump : public NativeInstruction {
+ public:
+ enum zero_specific_constants {
+ instruction_size = 0 // not used within the interpreter
+ };
+
+ address jump_destination() const {
+ ShouldNotCallThis();
+ }
+
+ void set_jump_destination(address dest) {
+ ShouldNotCallThis();
+ }
+
+ static void check_verified_entry_alignment(address entry,
+ address verified_entry) {
+ }
+
+ static void patch_verified_entry(address entry,
+ address verified_entry,
+ address dest);
+};
+
+inline NativeJump* nativeJump_at(address address) {
+ ShouldNotCallThis();
+}
+
+class NativeGeneralJump : public NativeInstruction {
+ public:
+ address jump_destination() const {
+ ShouldNotCallThis();
+ }
+
+ static void insert_unconditional(address code_pos, address entry) {
+ ShouldNotCallThis();
+ }
+
+ static void replace_mt_safe(address instr_addr, address code_buffer) {
+ ShouldNotCallThis();
+ }
+};
+
+inline NativeGeneralJump* nativeGeneralJump_at(address address) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/registerMap_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1998-2007 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.
+ *
+ */
+
+ // machine-dependent implemention for register maps
+ friend class frame;
+
+ private:
+ // This is the hook for finding a register in an "well-known" location,
+ // such as a register block of a predetermined format.
+ // Since there is none, we just return NULL.
+ // See registerMap_sparc.hpp for an example of grabbing registers
+ // from register save areas of a standard layout.
+ address pd_location(VMReg reg) const { return NULL; }
+
+ // no PD state to clear or copy:
+ void pd_clear() {}
+ void pd_initialize() {}
+ void pd_initialize_from(const RegisterMap* map) {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/register_definitions_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/register_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_register_zero.cpp.incl"
+
+const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers;
+const int ConcreteRegisterImpl::max_fpr =
+ ConcreteRegisterImpl::max_gpr + FloatRegisterImpl::number_of_registers;
+
+const char* RegisterImpl::name() const {
+ ShouldNotCallThis();
+}
+
+const char* FloatRegisterImpl::name() const {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/register_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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 VMRegImpl;
+typedef VMRegImpl* VMReg;
+
+// Use Register as shortcut
+class RegisterImpl;
+typedef RegisterImpl* Register;
+
+inline Register as_Register(int encoding) {
+ return (Register)(intptr_t) encoding;
+}
+
+// The implementation of integer registers for the zero architecture
+class RegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = 0
+ };
+
+ // construction
+ inline friend Register as_Register(int encoding);
+ VMReg as_VMReg();
+
+ // derived registers, offsets, and addresses
+ Register successor() const {
+ return as_Register(encoding() + 1);
+ }
+
+ // accessors
+ int encoding() const {
+ assert(is_valid(), "invalid register");
+ return (intptr_t)this;
+ }
+ bool is_valid() const {
+ return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers;
+ }
+ const char* name() const;
+};
+
+// Use FloatRegister as shortcut
+class FloatRegisterImpl;
+typedef FloatRegisterImpl* FloatRegister;
+
+inline FloatRegister as_FloatRegister(int encoding) {
+ return (FloatRegister)(intptr_t) encoding;
+}
+
+// The implementation of floating point registers for the zero architecture
+class FloatRegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = 0
+ };
+
+ // construction
+ inline friend FloatRegister as_FloatRegister(int encoding);
+ VMReg as_VMReg();
+
+ // derived registers, offsets, and addresses
+ FloatRegister successor() const {
+ return as_FloatRegister(encoding() + 1);
+ }
+
+ // accessors
+ int encoding() const {
+ assert(is_valid(), "invalid register");
+ return (intptr_t)this;
+ }
+ bool is_valid() const {
+ return 0 <= (intptr_t) this && (intptr_t)this < number_of_registers;
+ }
+ const char* name() const;
+};
+
+class ConcreteRegisterImpl : public AbstractRegisterImpl {
+ public:
+ enum {
+ number_of_registers = RegisterImpl::number_of_registers +
+ FloatRegisterImpl::number_of_registers
+ };
+
+ static const int max_gpr;
+ static const int max_fpr;
+};
+
+CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_relocInfo_zero.cpp.incl"
+
+void Relocation::pd_set_data_value(address x, intptr_t o) {
+ ShouldNotCallThis();
+}
+
+address Relocation::pd_call_destination(address orig_addr) {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_set_call_destination(address x) {
+ ShouldNotCallThis();
+}
+
+address Relocation::pd_get_address_from_code() {
+ ShouldNotCallThis();
+}
+
+address* Relocation::pd_address_in_code() {
+ // Relocations in Shark are just stored directly
+ return (address *) addr();
+}
+
+int Relocation::pd_breakpoint_size() {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_swap_in_breakpoint(address x,
+ short* instrs,
+ int instrlen) {
+ ShouldNotCallThis();
+}
+
+void Relocation::pd_swap_out_breakpoint(address x,
+ short* instrs,
+ int instrlen) {
+ ShouldNotCallThis();
+}
+
+void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src,
+ CodeBuffer* dst) {
+ ShouldNotCallThis();
+}
+
+void poll_return_Relocation::fix_relocation_after_move(const CodeBuffer* src,
+ CodeBuffer* dst) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/relocInfo_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // machine-dependent parts of class relocInfo
+ private:
+ enum {
+ // these constants mean nothing without an assembler
+ offset_unit = 1,
+ format_width = 1
+ };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharedRuntime_zero.cpp.incl"
+
+DeoptimizationBlob *SharedRuntime::_deopt_blob;
+SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob;
+SafepointBlob *SharedRuntime::_polling_page_return_handler_blob;
+RuntimeStub *SharedRuntime::_wrong_method_blob;
+RuntimeStub *SharedRuntime::_ic_miss_blob;
+RuntimeStub *SharedRuntime::_resolve_opt_virtual_call_blob;
+RuntimeStub *SharedRuntime::_resolve_virtual_call_blob;
+RuntimeStub *SharedRuntime::_resolve_static_call_blob;
+
+int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
+ VMRegPair *regs,
+ int total_args_passed,
+ int is_outgoing) {
+ return 0;
+}
+
+AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(
+ MacroAssembler *masm,
+ int total_args_passed,
+ int comp_args_on_stack,
+ const BasicType *sig_bt,
+ const VMRegPair *regs) {
+ return new AdapterHandlerEntry(
+ ShouldNotCallThisStub(),
+ ShouldNotCallThisStub(),
+ ShouldNotCallThisStub());
+}
+
+nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
+ methodHandle method,
+ int total_in_args,
+ int comp_args_on_stack,
+ BasicType *in_sig_bt,
+ VMRegPair *in_regs,
+ BasicType ret_type) {
+ ShouldNotCallThis();
+}
+
+int Deoptimization::last_frame_adjust(int callee_parameters,
+ int callee_locals) {
+ return 0;
+}
+
+uint SharedRuntime::out_preserve_stack_slots() {
+ ShouldNotCallThis();
+}
+
+static RuntimeStub* generate_empty_runtime_stub(const char* name) {
+ CodeBuffer buffer(name, 0, 0);
+ return RuntimeStub::new_runtime_stub(name, &buffer, 0, 0, NULL, false);
+}
+
+static SafepointBlob* generate_empty_safepoint_blob() {
+ CodeBuffer buffer("handler_blob", 0, 0);
+ return SafepointBlob::create(&buffer, NULL, 0);
+}
+
+void SharedRuntime::generate_stubs() {
+ _wrong_method_blob =
+ generate_empty_runtime_stub("wrong_method_stub");
+ _ic_miss_blob =
+ generate_empty_runtime_stub("ic_miss_stub");
+ _resolve_opt_virtual_call_blob =
+ generate_empty_runtime_stub("resolve_opt_virtual_call");
+ _resolve_virtual_call_blob =
+ generate_empty_runtime_stub("resolve_virtual_call");
+ _resolve_static_call_blob =
+ generate_empty_runtime_stub("resolve_static_call");
+
+ _polling_page_safepoint_handler_blob =
+ generate_empty_safepoint_blob();
+ _polling_page_return_handler_blob =
+ generate_empty_safepoint_blob();
+}
+
+int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
+ VMRegPair *regs,
+ int total_args_passed) {
+ ShouldNotCallThis();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// | ... |
+// +--------------------+ ------------------
+// | stack slot n-1 | low addresses
+// | ... |
+// | stack slot 0 |
+// | monitor m-1 |
+// | ... |
+// | monitor 0 |
+// | oop_tmp |
+// | method |
+// | unextended_sp |
+// | pc |
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class SharkFrame : public ZeroFrame {
+ friend class SharkFunction;
+
+ private:
+ SharkFrame() : ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ protected:
+ enum Layout {
+ pc_off = jf_header_words,
+ unextended_sp_off,
+ method_off,
+ oop_tmp_off,
+ header_words
+ };
+
+ public:
+ address pc() const {
+ return (address) value_of_word(pc_off);
+ }
+
+ intptr_t* unextended_sp() const {
+ return (intptr_t *) value_of_word(unextended_sp_off);
+ }
+
+ methodOop method() const {
+ return (methodOop) value_of_word(method_off);
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/stack_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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 ZeroStack {
+ private:
+ intptr_t *_base; // the last available word
+ intptr_t *_top; // the word past the end of the stack
+ intptr_t *_sp; // the top word on the stack
+
+ public:
+ ZeroStack()
+ : _base(NULL), _top(NULL), _sp(NULL) {}
+
+ bool needs_setup() const {
+ return _base == NULL;
+ }
+
+ void setup(void *mem, size_t size) {
+ assert(needs_setup(), "already set up");
+ assert(!(size & WordAlignmentMask), "unaligned");
+
+ _base = (intptr_t *) mem;
+ _top = _base + (size >> LogBytesPerWord);
+ _sp = _top;
+ }
+ void teardown() {
+ assert(!needs_setup(), "not set up");
+ assert(_sp == _top, "stuff on stack at teardown");
+
+ _base = NULL;
+ _top = NULL;
+ _sp = NULL;
+ }
+
+ intptr_t *sp() const {
+ return _sp;
+ }
+ void set_sp(intptr_t *new_sp) {
+ assert(_top >= new_sp && new_sp >= _base, "bad stack pointer");
+ _sp = new_sp;
+ }
+
+ int available_words() const {
+ return _sp - _base;
+ }
+
+ void push(intptr_t value) {
+ assert(_sp > _base, "stack overflow");
+ *(--_sp) = value;
+ }
+ intptr_t pop() {
+ assert(_sp < _top, "stack underflow");
+ return *(_sp++);
+ }
+
+ void *alloc(size_t size) {
+ int count = align_size_up(size, wordSize) >> LogBytesPerWord;
+ assert(count <= available_words(), "stack overflow");
+ return _sp -= count;
+ }
+
+ public:
+ static ByteSize base_offset() {
+ return byte_offset_of(ZeroStack, _base);
+ }
+ static ByteSize top_offset() {
+ return byte_offset_of(ZeroStack, _top);
+ }
+ static ByteSize sp_offset() {
+ return byte_offset_of(ZeroStack, _sp);
+ }
+};
+
+
+class EntryFrame;
+class InterpreterFrame;
+class SharkFrame;
+class FakeStubFrame;
+
+//
+// | ... |
+// +--------------------+ ------------------
+// | ... | low addresses
+// | frame_type |
+// | next_frame | high addresses
+// +--------------------+ ------------------
+// | ... |
+
+class ZeroFrame {
+ friend class frame;
+ friend class ZeroStackPrinter;
+
+ protected:
+ ZeroFrame() {
+ ShouldNotCallThis();
+ }
+
+ enum Layout {
+ next_frame_off,
+ frame_type_off,
+ jf_header_words
+ };
+
+ enum FrameType {
+ ENTRY_FRAME = 1,
+ INTERPRETER_FRAME,
+ SHARK_FRAME,
+ FAKE_STUB_FRAME
+ };
+
+ protected:
+ intptr_t *addr_of_word(int offset) const {
+ return (intptr_t *) this - offset;
+ }
+ intptr_t value_of_word(int offset) const {
+ return *addr_of_word(offset);
+ }
+
+ public:
+ ZeroFrame *next() const {
+ return (ZeroFrame *) value_of_word(next_frame_off);
+ }
+
+ protected:
+ FrameType type() const {
+ return (FrameType) value_of_word(frame_type_off);
+ }
+
+ public:
+ bool is_entry_frame() const {
+ return type() == ENTRY_FRAME;
+ }
+ bool is_interpreter_frame() const {
+ return type() == INTERPRETER_FRAME;
+ }
+ bool is_shark_frame() const {
+ return type() == SHARK_FRAME;
+ }
+ bool is_fake_stub_frame() const {
+ return type() == FAKE_STUB_FRAME;
+ }
+
+ public:
+ EntryFrame *as_entry_frame() const {
+ assert(is_entry_frame(), "should be");
+ return (EntryFrame *) this;
+ }
+ InterpreterFrame *as_interpreter_frame() const {
+ assert(is_interpreter_frame(), "should be");
+ return (InterpreterFrame *) this;
+ }
+ SharkFrame *as_shark_frame() const {
+ assert(is_shark_frame(), "should be");
+ return (SharkFrame *) this;
+ }
+ FakeStubFrame *as_fake_stub_frame() const {
+ assert(is_fake_stub_frame(), "should be");
+ return (FakeStubFrame *) this;
+ }
+
+ public:
+ void identify_word(int frame_index,
+ int offset,
+ char* fieldbuf,
+ char* valuebuf,
+ int buflen) const;
+
+ protected:
+ void identify_vp_word(int frame_index,
+ intptr_t* addr,
+ intptr_t* monitor_base,
+ intptr_t* stack_base,
+ char* fieldbuf,
+ int buflen) const;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_stubGenerator_zero.cpp.incl"
+
+// Declaration and definition of StubGenerator (no .hpp file).
+// For a more detailed description of the stub routine structure
+// see the comment in stubRoutines.hpp
+
+class StubGenerator: public StubCodeGenerator {
+ private:
+ // The call stub is used to call Java from C
+ static void call_stub(
+ JavaCallWrapper *call_wrapper,
+ intptr_t* result,
+ BasicType result_type,
+ methodOop method,
+ address entry_point,
+ intptr_t* parameters,
+ int parameter_words,
+ TRAPS) {
+ JavaThread *thread = (JavaThread *) THREAD;
+ ZeroStack *stack = thread->zero_stack();
+
+ // Make sure we have no pending exceptions
+ assert(!HAS_PENDING_EXCEPTION, "call_stub called with pending exception");
+
+ // Set up the stack if necessary
+ bool stack_needs_teardown = false;
+ if (stack->needs_setup()) {
+ size_t stack_used = thread->stack_base() - (address) &stack_used;
+ size_t stack_free = thread->stack_size() - stack_used;
+ size_t zero_stack_size = align_size_down(stack_free / 2, wordSize);
+
+ stack->setup(alloca(zero_stack_size), zero_stack_size);
+ stack_needs_teardown = true;
+ }
+
+ // Allocate and initialize our frame
+ thread->push_zero_frame(
+ EntryFrame::build(stack, parameters, parameter_words, call_wrapper));
+
+ // Make the call
+ Interpreter::invoke_method(method, entry_point, THREAD);
+
+ // Store result depending on type
+ if (!HAS_PENDING_EXCEPTION) {
+ switch (result_type) {
+ case T_INT:
+ *(jint *) result = *(jint *) stack->sp();
+ break;
+ case T_LONG:
+ *(jlong *) result = *(jlong *) stack->sp();
+ break;
+ case T_FLOAT:
+ *(jfloat *) result = *(jfloat *) stack->sp();
+ break;
+ case T_DOUBLE:
+ *(jdouble *) result = *(jdouble *) stack->sp();
+ break;
+ case T_OBJECT:
+ *(oop *) result = *(oop *) stack->sp();
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+ }
+
+ // Unwind our frame
+ thread->pop_zero_frame();
+
+ // Tear down the stack if necessary
+ if (stack_needs_teardown)
+ stack->teardown();
+ }
+
+ // These stubs get called from some dumb test routine.
+ // I'll write them properly when they're called from
+ // something that's actually doing something.
+ static void fake_arraycopy_stub(address src, address dst, int count) {
+ assert(count == 0, "huh?");
+ }
+
+ void generate_arraycopy_stubs() {
+ // Call the conjoint generation methods immediately after
+ // the disjoint ones so that short branches from the former
+ // to the latter can be generated.
+ StubRoutines::_jbyte_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jbyte_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jshort_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jshort_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jint_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jint_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_jlong_disjoint_arraycopy = (address) fake_arraycopy_stub;
+ StubRoutines::_jlong_arraycopy = (address) fake_arraycopy_stub;
+
+ StubRoutines::_oop_disjoint_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_oop_arraycopy = ShouldNotCallThisStub();
+
+ StubRoutines::_checkcast_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_unsafe_arraycopy = ShouldNotCallThisStub();
+ StubRoutines::_generic_arraycopy = ShouldNotCallThisStub();
+
+ // We don't generate specialized code for HeapWord-aligned source
+ // arrays, so just use the code we've already generated
+ StubRoutines::_arrayof_jbyte_disjoint_arraycopy =
+ StubRoutines::_jbyte_disjoint_arraycopy;
+ StubRoutines::_arrayof_jbyte_arraycopy =
+ StubRoutines::_jbyte_arraycopy;
+
+ StubRoutines::_arrayof_jshort_disjoint_arraycopy =
+ StubRoutines::_jshort_disjoint_arraycopy;
+ StubRoutines::_arrayof_jshort_arraycopy =
+ StubRoutines::_jshort_arraycopy;
+
+ StubRoutines::_arrayof_jint_disjoint_arraycopy =
+ StubRoutines::_jint_disjoint_arraycopy;
+ StubRoutines::_arrayof_jint_arraycopy =
+ StubRoutines::_jint_arraycopy;
+
+ StubRoutines::_arrayof_jlong_disjoint_arraycopy =
+ StubRoutines::_jlong_disjoint_arraycopy;
+ StubRoutines::_arrayof_jlong_arraycopy =
+ StubRoutines::_jlong_arraycopy;
+
+ StubRoutines::_arrayof_oop_disjoint_arraycopy =
+ StubRoutines::_oop_disjoint_arraycopy;
+ StubRoutines::_arrayof_oop_arraycopy =
+ StubRoutines::_oop_arraycopy;
+ }
+
+ void generate_initial() {
+ // Generates all stubs and initializes the entry points
+
+ // entry points that exist in all platforms Note: This is code
+ // that could be shared among different platforms - however the
+ // benefit seems to be smaller than the disadvantage of having a
+ // much more complicated generator structure. See also comment in
+ // stubRoutines.hpp.
+
+ StubRoutines::_forward_exception_entry = ShouldNotCallThisStub();
+ StubRoutines::_call_stub_entry = (address) call_stub;
+ StubRoutines::_catch_exception_entry = ShouldNotCallThisStub();
+
+ // atomic calls
+ StubRoutines::_atomic_xchg_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_xchg_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_cmpxchg_long_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_add_entry = ShouldNotCallThisStub();
+ StubRoutines::_atomic_add_ptr_entry = ShouldNotCallThisStub();
+ StubRoutines::_fence_entry = ShouldNotCallThisStub();
+
+ // amd64 does this here, sparc does it in generate_all()
+ StubRoutines::_handler_for_unsafe_access_entry =
+ ShouldNotCallThisStub();
+ }
+
+ void generate_all() {
+ // Generates all stubs and initializes the entry points
+
+ // These entry points require SharedInfo::stack0 to be set up in
+ // non-core builds and need to be relocatable, so they each
+ // fabricate a RuntimeStub internally.
+ StubRoutines::_throw_AbstractMethodError_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_ArithmeticException_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_NullPointerException_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_NullPointerException_at_call_entry =
+ ShouldNotCallThisStub();
+
+ StubRoutines::_throw_StackOverflowError_entry =
+ ShouldNotCallThisStub();
+
+ // support for verify_oop (must happen after universe_init)
+ StubRoutines::_verify_oop_subroutine_entry =
+ ShouldNotCallThisStub();
+
+ // arraycopy stubs used by compilers
+ generate_arraycopy_stubs();
+ }
+
+ public:
+ StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) {
+ if (all) {
+ generate_all();
+ } else {
+ generate_initial();
+ }
+ }
+};
+
+void StubGenerator_generate(CodeBuffer* code, bool all) {
+ StubGenerator g(code, all);
+}
+
+EntryFrame *EntryFrame::build(ZeroStack* stack,
+ const intptr_t* parameters,
+ int parameter_words,
+ JavaCallWrapper* call_wrapper) {
+ if (header_words + parameter_words > stack->available_words()) {
+ Unimplemented();
+ }
+
+ stack->push(0); // next_frame, filled in later
+ intptr_t *fp = stack->sp();
+ assert(fp - stack->sp() == next_frame_off, "should be");
+
+ stack->push(ENTRY_FRAME);
+ assert(fp - stack->sp() == frame_type_off, "should be");
+
+ stack->push((intptr_t) call_wrapper);
+ assert(fp - stack->sp() == call_wrapper_off, "should be");
+
+ for (int i = 0; i < parameter_words; i++)
+ stack->push(parameters[i]);
+
+ return (EntryFrame *) fp;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/stubRoutines_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_stubRoutines_zero.cpp.incl"
+
+#ifdef IA32
+address StubRoutines::x86::_call_stub_compiled_return = NULL;
+#endif // IA32
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/stubRoutines_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ // This file holds the platform specific parts of the StubRoutines
+ // definition. See stubRoutines.hpp for a description on how to
+ // extend it.
+
+ public:
+ static address call_stub_return_pc() {
+ return (address) -1;
+ }
+
+ static bool returns_to_call_stub(address return_pc) {
+ return return_pc == call_stub_return_pc();
+ }
+
+ enum platform_dependent_constants {
+ code_size1 = 0, // The assembler will fail with a guarantee
+ code_size2 = 0 // if these are too small. Simply increase
+ }; // them if that happens.
+
+#ifdef IA32
+ class x86 {
+ friend class VMStructs;
+
+ private:
+ static address _call_stub_compiled_return;
+ };
+#endif // IA32
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/templateInterpreterGenerator_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/templateInterpreter_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/templateTable_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/templateTable_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// These are the CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
+ /* be present there) */
+
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+
+ /* NOTE that we do not use the last_entry() macro here; it is used */
+ /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
+ /* be present there) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vm_version_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vm_version_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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 VM_Version : public Abstract_VM_Version {
+ public:
+ static const char* cpu_features() {
+ return "";
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vmreg_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_vmreg_zero.cpp.incl"
+
+void VMRegImpl::set_regName() {
+ int i = 0;
+ Register reg = ::as_Register(0);
+ for ( ; i < ConcreteRegisterImpl::max_gpr ; ) {
+ regName[i++] = reg->name();
+ reg = reg->successor();
+ }
+ FloatRegister freg = ::as_FloatRegister(0);
+ for ( ; i < ConcreteRegisterImpl::max_fpr ; ) {
+ regName[i++] = freg->name();
+ freg = freg->successor();
+ }
+ assert(i == ConcreteRegisterImpl::number_of_registers, "fix this");
+}
+
+bool VMRegImpl::is_Register() {
+ return value() >= 0 &&
+ value() < ConcreteRegisterImpl::max_gpr;
+}
+
+bool VMRegImpl::is_FloatRegister() {
+ return value() >= ConcreteRegisterImpl::max_gpr &&
+ value() < ConcreteRegisterImpl::max_fpr;
+}
+
+Register VMRegImpl::as_Register() {
+ assert(is_Register(), "must be");
+ return ::as_Register(value());
+}
+
+FloatRegister VMRegImpl::as_FloatRegister() {
+ assert(is_FloatRegister(), "must be" );
+ return ::as_FloatRegister(value() - ConcreteRegisterImpl::max_gpr);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vmreg_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2006 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.
+ *
+ */
+
+ bool is_Register();
+ Register as_Register();
+
+ bool is_FloatRegister();
+ FloatRegister as_FloatRegister();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vmreg_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+inline VMReg RegisterImpl::as_VMReg() {
+ return VMRegImpl::as_VMReg(encoding());
+}
+
+inline VMReg FloatRegisterImpl::as_VMReg() {
+ return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_gpr);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/vtableStubs_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_vtableStubs_zero.cpp.incl"
+
+VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
+ ShouldNotCallThis();
+}
+
+VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
+ ShouldNotCallThis();
+}
+
+int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
+ ShouldNotCallThis();
+}
+
+int VtableStub::pd_code_alignment() {
+ ShouldNotCallThis();
+}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -176,7 +176,9 @@
#endif
// Cpu architecture string
-#if defined(IA64)
+#if defined(ZERO)
+static char cpu_arch[] = ZERO_LIBARCH;
+#elif defined(IA64)
static char cpu_arch[] = "ia64";
#elif defined(IA32)
static char cpu_arch[] = "i386";
@@ -1743,7 +1745,14 @@
{EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
{EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
- {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}
+ {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
+ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
+ {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
+ {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
+ {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
+ {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
+ {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
+ {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
};
#if (defined IA32)
@@ -1760,9 +1769,23 @@
static Elf32_Half running_arch_code=EM_PPC64;
#elif (defined __powerpc__)
static Elf32_Half running_arch_code=EM_PPC;
+ #elif (defined ARM)
+ static Elf32_Half running_arch_code=EM_ARM;
+ #elif (defined S390)
+ static Elf32_Half running_arch_code=EM_S390;
+ #elif (defined ALPHA)
+ static Elf32_Half running_arch_code=EM_ALPHA;
+ #elif (defined MIPSEL)
+ static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
+ #elif (defined PARISC)
+ static Elf32_Half running_arch_code=EM_PARISC;
+ #elif (defined MIPS)
+ static Elf32_Half running_arch_code=EM_MIPS;
+ #elif (defined M68K)
+ static Elf32_Half running_arch_code=EM_68K;
#else
#error Method os::dll_load requires that one of following is defined:\
- IA32, AMD64, IA64, __sparc, __powerpc__
+ IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
#endif
// Identify compatability class for VM's architecture and library's architecture
@@ -1794,10 +1817,12 @@
return NULL;
}
+#ifndef S390
if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
return NULL;
}
+#endif // !S390
if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
if ( lib_arch.name!=NULL ) {
@@ -2586,7 +2611,9 @@
// format has been changed), we'll use the largest page size supported by
// the processor.
+#ifndef ZERO
_large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M);
+#endif // ZERO
FILE *fp = fopen("/proc/meminfo", "r");
if (fp) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// Implementation of class atomic
+
+#ifdef M68K
+
+/*
+ * __m68k_cmpxchg
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Returns newval on success and oldval if no exchange happened.
+ * This implementation is processor specific and works on
+ * 68020 68030 68040 and 68060.
+ *
+ * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
+ * instruction.
+ * Using a kernelhelper would be better for arch complete implementation.
+ *
+ */
+
+static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
+ int ret;
+ __asm __volatile ("cas%.l %0,%2,%1"
+ : "=d" (ret), "+m" (*(ptr))
+ : "d" (newval), "0" (oldval));
+ return ret;
+}
+
+/* Perform an atomic compare and swap: if the current value of `*PTR'
+ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
+ `*PTR' before the operation.*/
+static inline int m68k_compare_and_swap(volatile int *ptr,
+ int oldval,
+ int newval) {
+ for (;;) {
+ int prev = *ptr;
+ if (prev != oldval)
+ return prev;
+
+ if (__m68k_cmpxchg (prev, newval, ptr) == newval)
+ // Success.
+ return prev;
+
+ // We failed even though prev == oldval. Try again.
+ }
+}
+
+/* Atomically add an int to memory. */
+static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
+ for (;;) {
+ // Loop until success.
+
+ int prev = *ptr;
+
+ if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
+ return prev + add_value;
+ }
+}
+
+/* Atomically write VALUE into `*PTR' and returns the previous
+ contents of `*PTR'. */
+static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) {
+ for (;;) {
+ // Loop until success.
+ int prev = *ptr;
+
+ if (__m68k_cmpxchg (prev, newval, ptr) == prev)
+ return prev;
+ }
+}
+#endif // M68K
+
+#ifdef ARM
+
+/*
+ * __kernel_cmpxchg
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ * The C flag is also set if *ptr was changed to allow for assembly
+ * optimization in the calling code.
+ *
+ */
+
+typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
+
+
+
+/* Perform an atomic compare and swap: if the current value of `*PTR'
+ is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
+ `*PTR' before the operation.*/
+static inline int arm_compare_and_swap(volatile int *ptr,
+ int oldval,
+ int newval) {
+ for (;;) {
+ int prev = *ptr;
+ if (prev != oldval)
+ return prev;
+
+ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
+ // Success.
+ return prev;
+
+ // We failed even though prev == oldval. Try again.
+ }
+}
+
+/* Atomically add an int to memory. */
+static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
+ for (;;) {
+ // Loop until a __kernel_cmpxchg succeeds.
+
+ int prev = *ptr;
+
+ if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0)
+ return prev + add_value;
+ }
+}
+
+/* Atomically write VALUE into `*PTR' and returns the previous
+ contents of `*PTR'. */
+static inline int arm_lock_test_and_set(volatile int *ptr, int newval) {
+ for (;;) {
+ // Loop until a __kernel_cmpxchg succeeds.
+ int prev = *ptr;
+
+ if (__kernel_cmpxchg (prev, newval, ptr) == 0)
+ return prev;
+ }
+}
+#endif // ARM
+
+inline void Atomic::store(jint store_value, volatile jint* dest) {
+ *dest = store_value;
+}
+
+inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) {
+ *dest = store_value;
+}
+
+inline jint Atomic::add(jint add_value, volatile jint* dest) {
+#ifdef ARM
+ return arm_add_and_fetch(dest, add_value);
+#else
+#ifdef M68K
+ return m68k_add_and_fetch(dest, add_value);
+#else
+ return __sync_add_and_fetch(dest, add_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+#ifdef ARM
+ return arm_add_and_fetch(dest, add_value);
+#else
+#ifdef M68K
+ return m68k_add_and_fetch(dest, add_value);
+#else
+ return __sync_add_and_fetch(dest, add_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
+ return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
+}
+
+inline void Atomic::inc(volatile jint* dest) {
+ add(1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile intptr_t* dest) {
+ add_ptr(1, dest);
+}
+
+inline void Atomic::inc_ptr(volatile void* dest) {
+ add_ptr(1, dest);
+}
+
+inline void Atomic::dec(volatile jint* dest) {
+ add(-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile intptr_t* dest) {
+ add_ptr(-1, dest);
+}
+
+inline void Atomic::dec_ptr(volatile void* dest) {
+ add_ptr(-1, dest);
+}
+
+inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) {
+#ifdef ARM
+ return arm_lock_test_and_set(dest, exchange_value);
+#else
+#ifdef M68K
+ return m68k_lock_test_and_set(dest, exchange_value);
+#else
+ // __sync_lock_test_and_set is a bizarrely named atomic exchange
+ // operation. Note that some platforms only support this with the
+ // limitation that the only valid value to store is the immediate
+ // constant 1. There is a test for this in JNI_CreateJavaVM().
+ return __sync_lock_test_and_set (dest, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value,
+ volatile intptr_t* dest) {
+#ifdef ARM
+ return arm_lock_test_and_set(dest, exchange_value);
+#else
+#ifdef M68K
+ return m68k_lock_test_and_set(dest, exchange_value);
+#else
+ return __sync_lock_test_and_set (dest, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
+ return (void *) xchg_ptr((intptr_t) exchange_value,
+ (volatile intptr_t*) dest);
+}
+
+inline jint Atomic::cmpxchg(jint exchange_value,
+ volatile jint* dest,
+ jint compare_value) {
+#ifdef ARM
+ return arm_compare_and_swap(dest, compare_value, exchange_value);
+#else
+#ifdef M68K
+ return m68k_compare_and_swap(dest, compare_value, exchange_value);
+#else
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline jlong Atomic::cmpxchg(jlong exchange_value,
+ volatile jlong* dest,
+ jlong compare_value) {
+
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+}
+
+inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value,
+ volatile intptr_t* dest,
+ intptr_t compare_value) {
+#ifdef ARM
+ return arm_compare_and_swap(dest, compare_value, exchange_value);
+#else
+#ifdef M68K
+ return m68k_compare_and_swap(dest, compare_value, exchange_value);
+#else
+ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+#endif // M68K
+#endif // ARM
+}
+
+inline void* Atomic::cmpxchg_ptr(void* exchange_value,
+ volatile void* dest,
+ void* compare_value) {
+
+ return (void *) cmpxchg_ptr((intptr_t) exchange_value,
+ (volatile intptr_t*) dest,
+ (intptr_t) compare_value);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2003 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.
+ *
+ */
+
+// Efficient swapping of data bytes from Java byte
+// ordering to native byte ordering and vice versa.
+
+#include <byteswap.h>
+
+inline u2 Bytes::swap_u2(u2 x) {
+ return bswap_16(x);
+}
+
+inline u4 Bytes::swap_u4(u4 x) {
+ return bswap_32(x);
+}
+
+inline u8 Bytes::swap_u8(u8 x) {
+ return bswap_64(x);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/globals_linux_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+//
+// Set the default values for platform dependent flags used by the
+// runtime system. See globals.hpp for details of what they do.
+//
+
+define_pd_global(bool, DontYieldALot, false);
+#ifdef _LP64
+define_pd_global(intx, ThreadStackSize, 1536);
+define_pd_global(intx, VMThreadStackSize, 1024);
+#else
+define_pd_global(intx, ThreadStackSize, 1024);
+define_pd_global(intx, VMThreadStackSize, 512);
+#endif // _LP64
+define_pd_global(intx, SurvivorRatio, 8);
+define_pd_global(intx, CompilerThreadStackSize, 0);
+define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
+
+define_pd_global(bool, UseVectoredExceptions, false);
+// Only used on 64 bit platforms
+define_pd_global(uintx, HeapBaseMinAddress, 2*G);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#ifdef ARM
+
+/*
+ * ARM Kernel helper for memory barrier.
+ * Using __asm __volatile ("":::"memory") does not work reliable on ARM
+ * and gcc __sync_synchronize(); implementation does not use the kernel
+ * helper for all gcc versions so it is unreliable to use as well.
+ */
+typedef void (__kernel_dmb_t) (void);
+#define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
+
+#define FULL_MEM_BARRIER __kernel_dmb()
+#define READ_MEM_BARRIER __kernel_dmb()
+#define WRITE_MEM_BARRIER __kernel_dmb()
+
+#else // ARM
+
+#define FULL_MEM_BARRIER __sync_synchronize()
+
+#ifdef PPC
+
+#define READ_MEM_BARRIER __asm __volatile ("isync":::"memory")
+#ifdef __NO_LWSYNC__
+#define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
+#else
+#define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
+#endif
+
+#else // PPC
+
+#define READ_MEM_BARRIER __asm __volatile ("":::"memory")
+#define WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+
+#endif // PPC
+
+#endif // ARM
+
+
+inline void OrderAccess::loadload() { acquire(); }
+inline void OrderAccess::storestore() { release(); }
+inline void OrderAccess::loadstore() { acquire(); }
+inline void OrderAccess::storeload() { fence(); }
+
+inline void OrderAccess::acquire() {
+ READ_MEM_BARRIER;
+}
+
+inline void OrderAccess::release() {
+ WRITE_MEM_BARRIER;
+}
+
+inline void OrderAccess::fence() {
+ FULL_MEM_BARRIER;
+}
+
+inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { jbyte data = *p; acquire(); return data; }
+inline jshort OrderAccess::load_acquire(volatile jshort* p) { jshort data = *p; acquire(); return data; }
+inline jint OrderAccess::load_acquire(volatile jint* p) { jint data = *p; acquire(); return data; }
+inline jlong OrderAccess::load_acquire(volatile jlong* p) {
+ jlong tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+inline jubyte OrderAccess::load_acquire(volatile jubyte* p) { jubyte data = *p; acquire(); return data; }
+inline jushort OrderAccess::load_acquire(volatile jushort* p) { jushort data = *p; acquire(); return data; }
+inline juint OrderAccess::load_acquire(volatile juint* p) { juint data = *p; acquire(); return data; }
+inline julong OrderAccess::load_acquire(volatile julong* p) {
+ julong tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+inline jfloat OrderAccess::load_acquire(volatile jfloat* p) { jfloat data = *p; acquire(); return data; }
+inline jdouble OrderAccess::load_acquire(volatile jdouble* p) {
+ jdouble tmp;
+ os::atomic_copy64(p, &tmp);
+ acquire();
+ return tmp;
+}
+
+inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t* p) {
+ intptr_t data = *p;
+ acquire();
+ return data;
+}
+inline void* OrderAccess::load_ptr_acquire(volatile void* p) {
+ void *data = *(void* volatile *)p;
+ acquire();
+ return data;
+}
+inline void* OrderAccess::load_ptr_acquire(const volatile void* p) {
+ void *data = *(void* const volatile *)p;
+ acquire();
+ return data;
+}
+
+inline void OrderAccess::release_store(volatile jbyte* p, jbyte v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jshort* p, jshort v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jint* p, jint v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jlong* p, jlong v)
+{ release(); os::atomic_copy64(&v, p); }
+inline void OrderAccess::release_store(volatile jubyte* p, jubyte v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jushort* p, jushort v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile juint* p, juint v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile julong* p, julong v)
+{ release(); os::atomic_copy64(&v, p); }
+inline void OrderAccess::release_store(volatile jfloat* p, jfloat v) { release(); *p = v; }
+inline void OrderAccess::release_store(volatile jdouble* p, jdouble v)
+{ release(); os::atomic_copy64(&v, p); }
+
+inline void OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v) { release(); *p = v; }
+inline void OrderAccess::release_store_ptr(volatile void* p, void* v)
+{ release(); *(void* volatile *)p = v; }
+
+inline void OrderAccess::store_fence(jbyte* p, jbyte v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jshort* p, jshort v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jint* p, jint v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jlong* p, jlong v) { os::atomic_copy64(&v, p); fence(); }
+inline void OrderAccess::store_fence(jubyte* p, jubyte v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jushort* p, jushort v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(juint* p, juint v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(julong* p, julong v) { os::atomic_copy64(&v, p); fence(); }
+inline void OrderAccess::store_fence(jfloat* p, jfloat v) { *p = v; fence(); }
+inline void OrderAccess::store_fence(jdouble* p, jdouble v) { os::atomic_copy64(&v, p); fence(); }
+
+inline void OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v) { *p = v; fence(); }
+inline void OrderAccess::store_ptr_fence(void** p, void* v) { *p = v; fence(); }
+
+inline void OrderAccess::release_store_fence(volatile jbyte* p, jbyte v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jshort* p, jshort v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jint* p, jint v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jlong* p, jlong v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jubyte* p, jubyte v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile juint* p, juint v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile julong* p, julong v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jfloat* p, jfloat v) { release_store(p, v); fence(); }
+inline void OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); }
+
+inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
+inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// do not include precompiled header file
+#include "incls/_os_linux_zero.cpp.incl"
+
+address os::current_stack_pointer() {
+ address dummy = (address) &dummy;
+ return dummy;
+}
+
+frame os::get_sender_for_C_frame(frame* fr) {
+ ShouldNotCallThis();
+}
+
+frame os::current_frame() {
+ // The only thing that calls this is the stack printing code in
+ // VMError::report:
+ // - Step 110 (printing stack bounds) uses the sp in the frame
+ // to determine the amount of free space on the stack. We
+ // set the sp to a close approximation of the real value in
+ // order to allow this step to complete.
+ // - Step 120 (printing native stack) tries to walk the stack.
+ // The frame we create has a NULL pc, which is ignored as an
+ // invalid frame.
+ frame dummy = frame();
+ dummy.set_sp((intptr_t *) current_stack_pointer());
+ return dummy;
+}
+
+char* os::non_memory_address_word() {
+ // Must never look like an address returned by reserve_memory,
+ // even in its subfields (as defined by the CPU immediate fields,
+ // if the CPU splits constants across multiple instructions).
+#ifdef SPARC
+ // On SPARC, 0 != %hi(any real address), because there is no
+ // allocation in the first 1Kb of the virtual address space.
+ return (char *) 0;
+#else
+ // This is the value for x86; works pretty well for PPC too.
+ return (char *) -1;
+#endif // SPARC
+}
+
+void os::initialize_thread() {
+ // Nothing to do.
+}
+
+address os::Linux::ucontext_get_pc(ucontext_t* uc) {
+ ShouldNotCallThis();
+}
+
+ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+ intptr_t** ret_sp,
+ intptr_t** ret_fp) {
+ ShouldNotCallThis();
+}
+
+frame os::fetch_frame_from_context(void* ucVoid) {
+ ShouldNotCallThis();
+}
+
+extern "C" int
+JVM_handle_linux_signal(int sig,
+ siginfo_t* info,
+ void* ucVoid,
+ int abort_if_unrecognized) {
+ ucontext_t* uc = (ucontext_t*) ucVoid;
+
+ Thread* t = ThreadLocalStorage::get_thread_slow();
+
+ SignalHandlerMark shm(t);
+
+ // Note: it's not uncommon that JNI code uses signal/sigset to
+ // install then restore certain signal handler (e.g. to temporarily
+ // block SIGPIPE, or have a SIGILL handler when detecting CPU
+ // type). When that happens, JVM_handle_linux_signal() might be
+ // invoked with junk info/ucVoid. To avoid unnecessary crash when
+ // libjsig is not preloaded, try handle signals that do not require
+ // siginfo/ucontext first.
+
+ if (sig == SIGPIPE || sig == SIGXFSZ) {
+ // allow chained handler to go first
+ if (os::Linux::chained_handler(sig, info, ucVoid)) {
+ return true;
+ } else {
+ if (PrintMiscellaneous && (WizardMode || Verbose)) {
+ char buf[64];
+ warning("Ignoring %s - see bugs 4229104 or 646499219",
+ os::exception_name(sig, buf, sizeof(buf)));
+ }
+ return true;
+ }
+ }
+
+ JavaThread* thread = NULL;
+ VMThread* vmthread = NULL;
+ if (os::Linux::signal_handlers_are_installed) {
+ if (t != NULL ){
+ if(t->is_Java_thread()) {
+ thread = (JavaThread*)t;
+ }
+ else if(t->is_VM_thread()){
+ vmthread = (VMThread *)t;
+ }
+ }
+ }
+
+ if (info != NULL && thread != NULL) {
+ // Handle ALL stack overflow variations here
+ if (sig == SIGSEGV) {
+ address addr = (address) info->si_addr;
+
+ // check if fault address is within thread stack
+ if (addr < thread->stack_base() &&
+ addr >= thread->stack_base() - thread->stack_size()) {
+ // stack overflow
+ if (thread->in_stack_yellow_zone(addr)) {
+ thread->disable_stack_yellow_zone();
+ ShouldNotCallThis();
+ }
+ else if (thread->in_stack_red_zone(addr)) {
+ thread->disable_stack_red_zone();
+ ShouldNotCallThis();
+ }
+ else {
+ // Accessing stack address below sp may cause SEGV if
+ // current thread has MAP_GROWSDOWN stack. This should
+ // only happen when current thread was created by user
+ // code with MAP_GROWSDOWN flag and then attached to VM.
+ // See notes in os_linux.cpp.
+ if (thread->osthread()->expanding_stack() == 0) {
+ thread->osthread()->set_expanding_stack();
+ if (os::Linux::manually_expand_stack(thread, addr)) {
+ thread->osthread()->clear_expanding_stack();
+ return true;
+ }
+ thread->osthread()->clear_expanding_stack();
+ }
+ else {
+ fatal("recursive segv. expanding stack.");
+ }
+ }
+ }
+ }
+
+ /*if (thread->thread_state() == _thread_in_Java) {
+ ShouldNotCallThis();
+ }
+ else*/ if (thread->thread_state() == _thread_in_vm &&
+ sig == SIGBUS && thread->doing_unsafe_access()) {
+ ShouldNotCallThis();
+ }
+
+ // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC
+ // kicks in and the heap gets shrunk before the field access.
+ /*if (sig == SIGSEGV || sig == SIGBUS) {
+ address addr = JNI_FastGetField::find_slowcase_pc(pc);
+ if (addr != (address)-1) {
+ stub = addr;
+ }
+ }*/
+
+ // Check to see if we caught the safepoint code in the process
+ // of write protecting the memory serialization page. It write
+ // enables the page immediately after protecting it so we can
+ // just return to retry the write.
+ if (sig == SIGSEGV &&
+ os::is_memory_serialize_page(thread, (address) info->si_addr)) {
+ // Block current thread until permission is restored.
+ os::block_on_serialize_page_trap();
+ return true;
+ }
+ }
+
+ // signal-chaining
+ if (os::Linux::chained_handler(sig, info, ucVoid)) {
+ return true;
+ }
+
+ if (!abort_if_unrecognized) {
+ // caller wants another chance, so give it to him
+ return false;
+ }
+
+#ifndef PRODUCT
+ if (sig == SIGSEGV) {
+ fatal("\n#"
+ "\n# /--------------------\\"
+ "\n# | segmentation fault |"
+ "\n# \\---\\ /--------------/"
+ "\n# /"
+ "\n# [-] |\\_/| "
+ "\n# (+)=C |o o|__ "
+ "\n# | | =-*-=__\\ "
+ "\n# OOO c_c_(___)");
+ }
+#endif // !PRODUCT
+
+ const char *fmt = "caught unhandled signal %d";
+ char buf[64];
+
+ sprintf(buf, fmt, sig);
+ fatal(buf);
+}
+
+void os::Linux::init_thread_fpu_state(void) {
+ // Nothing to do
+}
+
+int os::Linux::get_fpu_control_word() {
+ ShouldNotCallThis();
+}
+
+void os::Linux::set_fpu_control_word(int fpu) {
+ ShouldNotCallThis();
+}
+
+bool os::is_allocatable(size_t bytes) {
+ ShouldNotCallThis();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// thread stack
+
+size_t os::Linux::min_stack_allowed = 64 * K;
+
+bool os::Linux::supports_variable_stack_size() {
+ return true;
+}
+
+size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+#ifdef _LP64
+ size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
+#else
+ size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
+#endif // _LP64
+ return s;
+}
+
+size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
+ // Only enable glibc guard pages for non-Java threads
+ // (Java threads have HotSpot guard pages)
+ return (thr_type == java_thread ? 0 : page_size());
+}
+
+static void current_stack_region(address *bottom, size_t *size) {
+ pthread_attr_t attr;
+ int res = pthread_getattr_np(pthread_self(), &attr);
+ if (res != 0) {
+ if (res == ENOMEM) {
+ vm_exit_out_of_memory(0, "pthread_getattr_np");
+ }
+ else {
+ fatal1("pthread_getattr_np failed with errno = %d", res);
+ }
+ }
+
+ address stack_bottom;
+ size_t stack_bytes;
+ res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
+ if (res != 0) {
+ fatal1("pthread_attr_getstack failed with errno = %d", res);
+ }
+ address stack_top = stack_bottom + stack_bytes;
+
+ // The block of memory returned by pthread_attr_getstack() includes
+ // guard pages where present. We need to trim these off.
+ size_t page_bytes = os::Linux::page_size();
+ assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
+
+ size_t guard_bytes;
+ res = pthread_attr_getguardsize(&attr, &guard_bytes);
+ if (res != 0) {
+ fatal1("pthread_attr_getguardsize failed with errno = %d", res);
+ }
+ int guard_pages = align_size_up(guard_bytes, page_bytes) / page_bytes;
+ assert(guard_bytes == guard_pages * page_bytes, "unaligned guard");
+
+#ifdef IA64
+ // IA64 has two stacks sharing the same area of memory, a normal
+ // stack growing downwards and a register stack growing upwards.
+ // Guard pages, if present, are in the centre. This code splits
+ // the stack in two even without guard pages, though in theory
+ // there's nothing to stop us allocating more to the normal stack
+ // or more to the register stack if one or the other were found
+ // to grow faster.
+ int total_pages = align_size_down(stack_bytes, page_bytes) / page_bytes;
+ stack_bottom += (total_pages - guard_pages) / 2 * page_bytes;
+#endif // IA64
+
+ stack_bottom += guard_bytes;
+
+ pthread_attr_destroy(&attr);
+
+ // The initial thread has a growable stack, and the size reported
+ // by pthread_attr_getstack is the maximum size it could possibly
+ // be given what currently mapped. This can be huge, so we cap it.
+ if (os::Linux::is_initial_thread()) {
+ stack_bytes = stack_top - stack_bottom;
+
+ if (stack_bytes > JavaThread::stack_size_at_create())
+ stack_bytes = JavaThread::stack_size_at_create();
+
+ stack_bottom = stack_top - stack_bytes;
+ }
+
+ assert(os::current_stack_pointer() >= stack_bottom, "should do");
+ assert(os::current_stack_pointer() < stack_top, "should do");
+
+ *bottom = stack_bottom;
+ *size = stack_top - stack_bottom;
+}
+
+address os::current_stack_base() {
+ address bottom;
+ size_t size;
+ current_stack_region(&bottom, &size);
+ return bottom + size;
+}
+
+size_t os::current_stack_size() {
+ // stack size includes normal stack and HotSpot guard pages
+ address bottom;
+ size_t size;
+ current_stack_region(&bottom, &size);
+ return size;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// helper functions for fatal error handler
+
+void os::print_context(outputStream* st, void* context) {
+ ShouldNotCallThis();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Stubs for things that would be in linux_zero.s if it existed.
+// You probably want to disassemble these monkeys to check they're ok.
+
+extern "C" {
+ int SpinPause() {
+ }
+
+ int SafeFetch32(int *adr, int errValue) {
+ int value = errValue;
+ value = *adr;
+ return value;
+ }
+ intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
+ intptr_t value = errValue;
+ value = *adr;
+ return value;
+ }
+
+ void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
+ if (from > to) {
+ jshort *end = from + count;
+ while (from < end)
+ *(to++) = *(from++);
+ }
+ else if (from < to) {
+ jshort *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ *(to--) = *(from--);
+ }
+ }
+ void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
+ if (from > to) {
+ jint *end = from + count;
+ while (from < end)
+ *(to++) = *(from++);
+ }
+ else if (from < to) {
+ jint *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ *(to--) = *(from--);
+ }
+ }
+ void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
+ if (from > to) {
+ jlong *end = from + count;
+ while (from < end)
+ os::atomic_copy64(from++, to++);
+ }
+ else if (from < to) {
+ jlong *end = from;
+ from += count - 1;
+ to += count - 1;
+ while (from >= end)
+ os::atomic_copy64(from--, to--);
+ }
+ }
+
+ void _Copy_arrayof_conjoint_bytes(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jshorts(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jints(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+ void _Copy_arrayof_conjoint_jlongs(HeapWord* from,
+ HeapWord* to,
+ size_t count) {
+ ShouldNotCallThis();
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementations of atomic operations not supported by processors.
+// -- http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Atomic-Builtins.html
+
+#ifndef _LP64
+extern "C" {
+ long long unsigned int __sync_val_compare_and_swap_8(
+ volatile void *ptr,
+ long long unsigned int oldval,
+ long long unsigned int newval) {
+ ShouldNotCallThis();
+ }
+};
+#endif // !_LP64
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ static void setup_fpu() {}
+
+ static bool is_allocatable(size_t bytes);
+
+ // Used to register dynamic code cache area with the OS
+ // Note: Currently only used in 64 bit Windows implementations
+ static bool register_code_area(char *low, char *high) { return true; }
+
+ // Atomically copy 64 bits of data
+ static void atomic_copy64(volatile void *src, volatile void *dst) {
+#if defined(PPC) && !defined(_LP64)
+ double tmp;
+ asm volatile ("lfd %0, 0(%1)\n"
+ "stfd %0, 0(%2)\n"
+ : "=f"(tmp)
+ : "b"(src), "b"(dst));
+#else
+ *(jlong *) dst = *(jlong *) src;
+#endif // PPC && !_LP64
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+inline void Prefetch::read(void* loc, intx interval) {
+}
+
+inline void Prefetch::write(void* loc, intx interval) {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_threadLS_linux_zero.cpp.incl"
+
+void ThreadLocalStorage::generate_code_for_get_thread() {
+ // nothing to do
+}
+
+void ThreadLocalStorage::pd_init() {
+ // nothing to do
+}
+
+void ThreadLocalStorage::pd_set_thread(Thread* thread) {
+ os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2003 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.
+ *
+ */
+
+// Processor dependent parts of ThreadLocalStorage
+
+ public:
+ static Thread* thread() {
+ return (Thread*) os::thread_local_storage_at(thread_index());
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/thread_linux_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+ private:
+ ZeroStack _zero_stack;
+ ZeroFrame* _top_zero_frame;
+
+ void pd_initialize() {
+ _top_zero_frame = NULL;
+ }
+
+ public:
+ ZeroStack *zero_stack() {
+ return &_zero_stack;
+ }
+
+ public:
+ ZeroFrame *top_zero_frame() {
+ return _top_zero_frame;
+ }
+ void push_zero_frame(ZeroFrame *frame) {
+ *(ZeroFrame **) frame = _top_zero_frame;
+ _top_zero_frame = frame;
+ }
+ void pop_zero_frame() {
+ zero_stack()->set_sp((intptr_t *) _top_zero_frame + 1);
+ _top_zero_frame = *(ZeroFrame **) _top_zero_frame;
+ }
+
+ public:
+ static ByteSize zero_stack_offset() {
+ return byte_offset_of(JavaThread, _zero_stack);
+ }
+ static ByteSize top_zero_frame_offset() {
+ return byte_offset_of(JavaThread, _top_zero_frame);
+ }
+
+ public:
+ void record_base_of_stack_pointer() {
+ assert(top_zero_frame() == NULL, "junk on stack prior to Java call");
+ }
+ void set_base_of_stack_pointer(intptr_t* base_sp) {
+ assert(base_sp == NULL, "should be");
+ assert(top_zero_frame() == NULL, "junk on stack after Java call");
+ }
+
+ public:
+ void set_last_Java_frame() {
+ JavaFrameAnchor *jfa = frame_anchor();
+ jfa->set_last_Java_sp((intptr_t *) top_zero_frame());
+ }
+ void reset_last_Java_frame() {
+ JavaFrameAnchor *jfa = frame_anchor();
+ jfa->set_last_Java_sp(NULL);
+ }
+
+ private:
+ frame pd_last_frame() {
+ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
+ return frame(last_Java_sp(), zero_stack()->sp());
+ }
+
+ public:
+ // Check for pending suspend requests and pending asynchronous
+ // exceptions. There are separate accessors for these, but
+ // _suspend_flags is volatile so using them would be unsafe.
+ bool has_special_condition_for_native_trans() {
+ return _suspend_flags != 0;
+ }
+
+ public:
+ bool pd_get_top_frame_for_signal_handler(frame* fr_addr,
+ void* ucontext,
+ bool isInJava) {
+ ShouldNotCallThis();
+ }
+
+ // These routines are only used on cpu architectures that
+ // have separate register stacks (Itanium).
+ static bool register_stack_overflow() { return false; }
+ static void enable_register_stack_guard() {}
+ static void disable_register_stack_guard() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2007 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// These are the OS and CPU-specific fields, types and integer
+// constants required by the Serviceability Agent. This file is
+// referenced by vmStructs.cpp.
+
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
+
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+ /* This must be the last entry, and must be present */ \
+ last_entry()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009 Red Hat, Inc.
+ * 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.
+ *
+ */
+
+// This file is intentionally empty
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -356,8 +356,7 @@
// search forward until it finds last.
// In addition, it does not matter if the last PcDesc
// is for a safepoint or not.
- if (_prev_safepoint_pc < prev->pc_offset() &&
- prev->scope_decode_offset() == last->scope_decode_offset()) {
+ if (_prev_safepoint_pc < prev->pc_offset() && prev->is_same_info(last)) {
assert(prev == last-1, "sane");
prev->set_pc_offset(pc_offset);
_pcs_length -= 1;
--- a/hotspot/src/share/vm/code/pcDesc.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/code/pcDesc.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -39,6 +39,7 @@
struct {
unsigned int reexecute: 1;
} bits;
+ bool operator ==(const PcDescFlags& other) { return word == other.word; }
} _flags;
public:
@@ -64,6 +65,13 @@
bool should_reexecute() const { return _flags.bits.reexecute; }
void set_should_reexecute(bool z) { _flags.bits.reexecute = z; }
+ // Does pd refer to the same information as pd?
+ bool is_same_info(const PcDesc* pd) {
+ return _scope_decode_offset == pd->_scope_decode_offset &&
+ _obj_decode_offset == pd->_obj_decode_offset &&
+ _flags == pd->_flags;
+ }
+
// Returns the real pc
address real_pc(const nmethod* code) const;
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -377,3 +377,11 @@
_g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0);
#endif
}
+
+void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
+ for (int i = 0; i < _n_threads; ++i) {
+ _threads[i]->print_on(st);
+ st->cr();
+ }
+}
+
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -179,4 +179,6 @@
void clear_and_record_card_counts();
static size_t thread_num();
+
+ void print_worker_threads_on(outputStream* st) const;
};
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -204,8 +204,12 @@
if (G1TraceConcurrentRefinement) gclog_or_tty->print_cr("G1-Refine-stop");
}
-void ConcurrentG1RefineThread::print() {
- gclog_or_tty->print("\"Concurrent G1 Refinement Thread\" ");
- Thread::print();
- gclog_or_tty->cr();
+void ConcurrentG1RefineThread::print() const {
+ print_on(tty);
}
+
+void ConcurrentG1RefineThread::print_on(outputStream* st) const {
+ st->print("\"G1 Concurrent Refinement Thread#%d\" ", _worker_id);
+ Thread::print_on(st);
+ st->cr();
+}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -77,7 +77,8 @@
int worker_id_offset, int worker_id);
// Printing
- void print();
+ void print() const;
+ void print_on(outputStream* st) const;
// Total virtual time so far.
double vtime_accum() { return _vtime_accum; }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -237,7 +237,7 @@
_index = next_index;
for (int i = 0; i < n; i++) {
int ind = start + i;
- guarantee(ind < _capacity, "By overflow test above.");
+ assert(ind < _capacity, "By overflow test above.");
_base[ind] = ptr_arr[i];
}
}
@@ -310,12 +310,12 @@
if (res == index) {
MemRegion mr = _base[next_index];
if (mr.start() != NULL) {
- tmp_guarantee_CM( mr.end() != NULL, "invariant" );
- tmp_guarantee_CM( mr.word_size() > 0, "invariant" );
+ assert(mr.end() != NULL, "invariant");
+ assert(mr.word_size() > 0, "invariant");
return mr;
} else {
// that entry was invalidated... let's skip it
- tmp_guarantee_CM( mr.end() == NULL, "invariant" );
+ assert(mr.end() == NULL, "invariant");
}
}
// Otherwise, we need to try again.
@@ -328,10 +328,10 @@
for (int i = 0; i < _oops_do_bound; ++i) {
MemRegion mr = _base[i];
if (mr.start() != NULL) {
- tmp_guarantee_CM( mr.end() != NULL, "invariant");
- tmp_guarantee_CM( mr.word_size() > 0, "invariant" );
+ assert(mr.end() != NULL, "invariant");
+ assert(mr.word_size() > 0, "invariant");
HeapRegion* hr = g1h->heap_region_containing(mr.start());
- tmp_guarantee_CM( hr != NULL, "invariant" );
+ assert(hr != NULL, "invariant");
if (hr->in_collection_set()) {
// The region points into the collection set
_base[i] = MemRegion();
@@ -339,7 +339,7 @@
}
} else {
// that entry was invalidated... let's skip it
- tmp_guarantee_CM( mr.end() == NULL, "invariant" );
+ assert(mr.end() == NULL, "invariant");
}
}
return result;
@@ -542,8 +542,8 @@
gclog_or_tty->print_cr("CL Sleep Factor %1.4lf", cleanup_sleep_factor());
#endif
- guarantee( parallel_marking_threads() > 0, "peace of mind" );
- _parallel_workers = new WorkGang("Parallel Marking Threads",
+ guarantee(parallel_marking_threads() > 0, "peace of mind");
+ _parallel_workers = new WorkGang("G1 Parallel Marking Threads",
(int) parallel_marking_threads(), false, true);
if (_parallel_workers == NULL)
vm_exit_during_initialization("Failed necessary allocation.");
@@ -569,8 +569,7 @@
return;
MemRegion committed = _g1h->g1_committed();
- tmp_guarantee_CM( committed.start() == _heap_start,
- "start shouldn't change" );
+ assert(committed.start() == _heap_start, "start shouldn't change");
HeapWord* new_end = committed.end();
if (new_end > _heap_end) {
// The heap has been expanded.
@@ -592,9 +591,10 @@
_heap_start = committed.start();
_heap_end = committed.end();
- guarantee( _heap_start != NULL &&
- _heap_end != NULL &&
- _heap_start < _heap_end, "heap bounds should look ok" );
+ // Separated the asserts so that we know which one fires.
+ assert(_heap_start != NULL, "heap bounds should look ok");
+ assert(_heap_end != NULL, "heap bounds should look ok");
+ assert(_heap_start < _heap_end, "heap bounds should look ok");
// reset all the marking data structures and any necessary flags
clear_marking_state();
@@ -614,7 +614,7 @@
}
void ConcurrentMark::set_phase(size_t active_tasks, bool concurrent) {
- guarantee( active_tasks <= _max_task_num, "we should not have more" );
+ assert(active_tasks <= _max_task_num, "we should not have more");
_active_tasks = active_tasks;
// Need to update the three data structures below according to the
@@ -634,8 +634,8 @@
// We currently assume that the concurrent flag has been set to
// false before we start remark. At this point we should also be
// in a STW phase.
- guarantee( !concurrent_marking_in_progress(), "invariant" );
- guarantee( _finger == _heap_end, "only way to get here" );
+ assert(!concurrent_marking_in_progress(), "invariant");
+ assert(_finger == _heap_end, "only way to get here");
update_g1_committed(true);
}
}
@@ -933,8 +933,8 @@
// initial-mark that the committed space is expanded during the
// pause without CM observing this change. So the assertions below
// is a bit conservative; but better than nothing.
- tmp_guarantee_CM( _g1h->g1_committed().contains(addr),
- "address should be within the heap bounds" );
+ assert(_g1h->g1_committed().contains(addr),
+ "address should be within the heap bounds");
if (!_nextMarkBitMap->isMarked(addr))
_nextMarkBitMap->parMark(addr);
@@ -960,12 +960,15 @@
if (mr.start() < finger) {
// The finger is always heap region aligned and it is not possible
// for mr to span heap regions.
- tmp_guarantee_CM( mr.end() <= finger, "invariant" );
-
- tmp_guarantee_CM( mr.start() <= mr.end() &&
- _heap_start <= mr.start() &&
- mr.end() <= _heap_end,
- "region boundaries should fall within the committed space" );
+ assert(mr.end() <= finger, "invariant");
+
+ // Separated the asserts so that we know which one fires.
+ assert(mr.start() <= mr.end(),
+ "region boundaries should fall within the committed space");
+ assert(_heap_start <= mr.start(),
+ "region boundaries should fall within the committed space");
+ assert(mr.end() <= _heap_end,
+ "region boundaries should fall within the committed space");
if (verbose_low())
gclog_or_tty->print_cr("[global] region ["PTR_FORMAT", "PTR_FORMAT") "
"below the finger, pushing it",
@@ -1014,14 +1017,14 @@
public:
void work(int worker_i) {
- guarantee( Thread::current()->is_ConcurrentGC_thread(),
- "this should only be done by a conc GC thread" );
+ assert(Thread::current()->is_ConcurrentGC_thread(),
+ "this should only be done by a conc GC thread");
double start_vtime = os::elapsedVTime();
ConcurrentGCThread::stsJoin();
- guarantee( (size_t)worker_i < _cm->active_tasks(), "invariant" );
+ assert((size_t) worker_i < _cm->active_tasks(), "invariant");
CMTask* the_task = _cm->task(worker_i);
the_task->record_start_time();
if (!_cm->has_aborted()) {
@@ -1059,7 +1062,7 @@
} while (!_cm->has_aborted() && the_task->has_aborted());
}
the_task->record_end_time();
- guarantee( !the_task->has_aborted() || _cm->has_aborted(), "invariant" );
+ guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
ConcurrentGCThread::stsLeave();
@@ -1182,8 +1185,7 @@
void mark_card_num_range(intptr_t start_card_num, intptr_t last_card_num) {
for (intptr_t i = start_card_num; i <= last_card_num; i++) {
#if CARD_BM_TEST_MODE
- guarantee(_card_bm->at(i - _bottom_card_num),
- "Should already be set.");
+ guarantee(_card_bm->at(i - _bottom_card_num), "Should already be set.");
#else
_card_bm->par_at_put(i - _bottom_card_num, 1);
#endif
@@ -1328,7 +1330,7 @@
// In any case, we set the last card num.
last_card_num = obj_last_card_num;
- marked_bytes += obj_sz * HeapWordSize;
+ marked_bytes += (size_t)obj_sz * HeapWordSize;
// Find the next marked object after this one.
start = _bm->getNextMarkedWordAddress(start + 1, nextTop);
_changed = true;
@@ -1442,7 +1444,7 @@
}
assert(calccl.complete(), "Shouldn't have yielded!");
- guarantee( (size_t)i < _n_workers, "invariant" );
+ assert((size_t) i < _n_workers, "invariant");
_live_bytes[i] = calccl.tot_live();
_used_bytes[i] = calccl.tot_used();
}
@@ -1774,14 +1776,14 @@
hd->rem_set()->clear();
HeapRegion* next_hd = hd->next_from_unclean_list();
(void)list->pop();
- guarantee(list->hd() == next_hd, "how not?");
+ assert(list->hd() == next_hd, "how not?");
_g1h->put_region_on_unclean_list(hd);
if (!hd->isHumongous()) {
// Add this to the _free_regions count by 1.
_g1h->finish_free_region_work(0, 0, 1, NULL);
}
hd = list->hd();
- guarantee(hd == next_hd, "how not?");
+ assert(hd == next_hd, "how not?");
}
}
}
@@ -1931,9 +1933,6 @@
g1h->set_par_threads(n_workers);
g1h->workers()->run_task(&remarkTask);
g1h->set_par_threads(0);
-
- SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" );
} else {
G1CollectedHeap::StrongRootsScope srs(g1h);
// this is remark, so we'll use up all available threads
@@ -1945,10 +1944,9 @@
// active_workers will be fewer. The extra ones will just bail out
// immediately.
remarkTask.work(0);
-
- SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
- guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" );
}
+ SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
+ guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant");
print_stats();
@@ -1989,7 +1987,7 @@
str = "outside G1 reserved";
else {
HeapRegion* hr = _g1h->heap_region_containing(obj);
- guarantee( hr != NULL, "invariant" );
+ guarantee(hr != NULL, "invariant");
if (hr->obj_allocated_since_prev_marking(obj)) {
str = "over TAMS";
if (_bitmap->isMarked((HeapWord*) obj))
@@ -2125,7 +2123,7 @@
HeapWord* objAddr = (HeapWord*) obj;
assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
if (_g1h->is_in_g1_reserved(objAddr)) {
- tmp_guarantee_CM( obj != NULL, "is_in_g1_reserved should ensure this" );
+ assert(obj != NULL, "is_in_g1_reserved should ensure this");
HeapRegion* hr = _g1h->heap_region_containing(obj);
if (_g1h->is_obj_ill(obj, hr)) {
if (verbose_high())
@@ -2167,7 +2165,7 @@
satb_mq_set.iterate_closure_all_threads();
satb_mq_set.set_closure(NULL);
- guarantee( satb_mq_set.completed_buffers_num() == 0, "invariant" );
+ assert(satb_mq_set.completed_buffers_num() == 0, "invariant");
}
void ConcurrentMark::markPrev(oop p) {
@@ -2200,7 +2198,7 @@
// _heap_end will not change underneath our feet; it only changes at
// yield points.
while (finger < _heap_end) {
- tmp_guarantee_CM( _g1h->is_in_g1_reserved(finger), "invariant" );
+ assert(_g1h->is_in_g1_reserved(finger), "invariant");
// is the gap between reading the finger and doing the CAS too long?
@@ -2222,7 +2220,7 @@
// notice that _finger == end cannot be guaranteed here since,
// someone else might have moved the finger even further
- guarantee( _finger >= end, "the finger should have moved forward" );
+ assert(_finger >= end, "the finger should have moved forward");
if (verbose_low())
gclog_or_tty->print_cr("[%d] we were successful with region = "
@@ -2234,8 +2232,8 @@
"returning it ", task_num, curr_region);
return curr_region;
} else {
- tmp_guarantee_CM( limit == bottom,
- "the region limit should be at bottom" );
+ assert(limit == bottom,
+ "the region limit should be at bottom");
if (verbose_low())
gclog_or_tty->print_cr("[%d] region "PTR_FORMAT" is empty, "
"returning NULL", task_num, curr_region);
@@ -2244,7 +2242,7 @@
return NULL;
}
} else {
- guarantee( _finger > finger, "the finger should have moved forward" );
+ assert(_finger > finger, "the finger should have moved forward");
if (verbose_low())
gclog_or_tty->print_cr("[%d] somebody else moved the finger, "
"global finger = "PTR_FORMAT", "
@@ -2282,7 +2280,7 @@
if (_regionStack.invalidate_entries_into_cset()) {
// otherwise, any gray objects copied during the evacuation pause
// might not be visited.
- guarantee( _should_gray_objects, "invariant" );
+ assert(_should_gray_objects, "invariant");
}
}
@@ -2637,6 +2635,10 @@
cmThread()->vtime_count_accum());
}
+void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
+ _parallel_workers->print_worker_threads_on(st);
+}
+
// Closures
// XXX: there seems to be a lot of code duplication here;
// should refactor and consolidate the shared code.
@@ -2711,12 +2713,12 @@
bool do_bit(size_t offset) {
HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset);
- tmp_guarantee_CM( _nextMarkBitMap->isMarked(addr), "invariant" );
- tmp_guarantee_CM( addr < _cm->finger(), "invariant" );
+ assert(_nextMarkBitMap->isMarked(addr), "invariant");
+ assert( addr < _cm->finger(), "invariant");
if (_scanning_heap_region) {
statsOnly( _task->increase_objs_found_on_bitmap() );
- tmp_guarantee_CM( addr >= _task->finger(), "invariant" );
+ assert(addr >= _task->finger(), "invariant");
// We move that task's local finger along.
_task->move_finger_to(addr);
} else {
@@ -2761,8 +2763,9 @@
virtual void do_oop( oop* p) { do_oop_work(p); }
template <class T> void do_oop_work(T* p) {
- tmp_guarantee_CM( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant" );
- tmp_guarantee_CM( !_g1h->heap_region_containing((HeapWord*) p)->is_on_free_list(), "invariant" );
+ assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
+ assert(!_g1h->heap_region_containing((HeapWord*) p)->is_on_free_list(),
+ "invariant");
oop obj = oopDesc::load_decode_heap_oop(p);
if (_cm->verbose_high())
@@ -2779,8 +2782,11 @@
};
void CMTask::setup_for_region(HeapRegion* hr) {
- tmp_guarantee_CM( hr != NULL && !hr->continuesHumongous(),
- "claim_region() should have filtered out continues humongous regions" );
+ // Separated the asserts so that we know which one fires.
+ assert(hr != NULL,
+ "claim_region() should have filtered out continues humongous regions");
+ assert(!hr->continuesHumongous(),
+ "claim_region() should have filtered out continues humongous regions");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] setting up for region "PTR_FORMAT,
@@ -2808,9 +2814,9 @@
// as the region is not supposed to be empty in the first place)
_finger = bottom;
} else if (limit >= _region_limit) {
- tmp_guarantee_CM( limit >= _finger, "peace of mind" );
+ assert(limit >= _finger, "peace of mind");
} else {
- tmp_guarantee_CM( limit < _region_limit, "only way to get here" );
+ assert(limit < _region_limit, "only way to get here");
// This can happen under some pretty unusual circumstances. An
// evacuation pause empties the region underneath our feet (NTAMS
// at bottom). We then do some allocation in the region (NTAMS
@@ -2828,7 +2834,7 @@
}
void CMTask::giveup_current_region() {
- tmp_guarantee_CM( _curr_region != NULL, "invariant" );
+ assert(_curr_region != NULL, "invariant");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] giving up region "PTR_FORMAT,
_task_id, _curr_region);
@@ -2846,7 +2852,7 @@
}
void CMTask::reset(CMBitMap* nextMarkBitMap) {
- guarantee( nextMarkBitMap != NULL, "invariant" );
+ guarantee(nextMarkBitMap != NULL, "invariant");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] resetting", _task_id);
@@ -2912,7 +2918,7 @@
HeapWord* objAddr = (HeapWord*) obj;
assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
if (_g1h->is_in_g1_reserved(objAddr)) {
- tmp_guarantee_CM( obj != NULL, "is_in_g1_reserved should ensure this" );
+ assert(obj != NULL, "is_in_g1_reserved should ensure this");
HeapRegion* hr = _g1h->heap_region_containing(obj);
if (_g1h->is_obj_ill(obj, hr)) {
if (_cm->verbose_high())
@@ -2973,10 +2979,11 @@
void CMTask::push(oop obj) {
HeapWord* objAddr = (HeapWord*) obj;
- tmp_guarantee_CM( _g1h->is_in_g1_reserved(objAddr), "invariant" );
- tmp_guarantee_CM( !_g1h->heap_region_containing(objAddr)->is_on_free_list(), "invariant" );
- tmp_guarantee_CM( !_g1h->is_obj_ill(obj), "invariant" );
- tmp_guarantee_CM( _nextMarkBitMap->isMarked(objAddr), "invariant" );
+ assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
+ assert(!_g1h->heap_region_containing(objAddr)->is_on_free_list(),
+ "invariant");
+ assert(!_g1h->is_obj_ill(obj), "invariant");
+ assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
if (_cm->verbose_high())
gclog_or_tty->print_cr("[%d] pushing "PTR_FORMAT, _task_id, (void*) obj);
@@ -2995,7 +3002,7 @@
// stack, we should have definitely removed some entries from the
// local queue. So, there must be space on it.
bool success = _task_queue->push(obj);
- tmp_guarantee_CM( success, "invariant" );
+ assert(success, "invariant");
}
statsOnly( int tmp_size = _task_queue->size();
@@ -3005,9 +3012,9 @@
}
void CMTask::reached_limit() {
- tmp_guarantee_CM( _words_scanned >= _words_scanned_limit ||
- _refs_reached >= _refs_reached_limit ,
- "shouldn't have been called otherwise" );
+ assert(_words_scanned >= _words_scanned_limit ||
+ _refs_reached >= _refs_reached_limit ,
+ "shouldn't have been called otherwise");
regular_clock_call();
}
@@ -3165,8 +3172,8 @@
oop buffer[global_stack_transfer_size];
int n;
_cm->mark_stack_pop(buffer, global_stack_transfer_size, &n);
- tmp_guarantee_CM( n <= global_stack_transfer_size,
- "we should not pop more than the given limit" );
+ assert(n <= global_stack_transfer_size,
+ "we should not pop more than the given limit");
if (n > 0) {
// yes, we did actually pop at least one entry
@@ -3178,7 +3185,7 @@
bool success = _task_queue->push(buffer[i]);
// We only call this when the local queue is empty or under a
// given target limit. So, we do not expect this push to fail.
- tmp_guarantee_CM( success, "invariant" );
+ assert(success, "invariant");
}
statsOnly( int tmp_size = _task_queue->size();
@@ -3218,10 +3225,9 @@
gclog_or_tty->print_cr("[%d] popped "PTR_FORMAT, _task_id,
(void*) obj);
- tmp_guarantee_CM( _g1h->is_in_g1_reserved((HeapWord*) obj),
- "invariant" );
- tmp_guarantee_CM( !_g1h->heap_region_containing(obj)->is_on_free_list(),
- "invariant" );
+ assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
+ assert(!_g1h->heap_region_containing(obj)->is_on_free_list(),
+ "invariant");
scan_object(obj);
@@ -3243,7 +3249,7 @@
// We have a policy to drain the local queue before we attempt to
// drain the global stack.
- tmp_guarantee_CM( partially || _task_queue->size() == 0, "invariant" );
+ assert(partially || _task_queue->size() == 0, "invariant");
// Decide what the target size is, depending whether we're going to
// drain it partially (so that other tasks can steal if they run out
@@ -3324,9 +3330,9 @@
_draining_satb_buffers = false;
- tmp_guarantee_CM( has_aborted() ||
- concurrent() ||
- satb_mq_set.completed_buffers_num() == 0, "invariant" );
+ assert(has_aborted() ||
+ concurrent() ||
+ satb_mq_set.completed_buffers_num() == 0, "invariant");
if (ParallelGCThreads > 0)
satb_mq_set.set_par_closure(_task_id, NULL);
@@ -3342,8 +3348,8 @@
if (has_aborted())
return;
- tmp_guarantee_CM( _region_finger == NULL,
- "it should be NULL when we're not scanning a region" );
+ assert(_region_finger == NULL,
+ "it should be NULL when we're not scanning a region");
if (!_cm->region_stack_empty()) {
if (_cm->verbose_low())
@@ -3359,12 +3365,12 @@
gclog_or_tty->print_cr("[%d] we are scanning region "
"["PTR_FORMAT", "PTR_FORMAT")",
_task_id, mr.start(), mr.end());
- tmp_guarantee_CM( mr.end() <= _cm->finger(),
- "otherwise the region shouldn't be on the stack" );
+ assert(mr.end() <= _cm->finger(),
+ "otherwise the region shouldn't be on the stack");
assert(!mr.is_empty(), "Only non-empty regions live on the region stack");
if (_nextMarkBitMap->iterate(bc, mr)) {
- tmp_guarantee_CM( !has_aborted(),
- "cannot abort the task without aborting the bitmap iteration" );
+ assert(!has_aborted(),
+ "cannot abort the task without aborting the bitmap iteration");
// We finished iterating over the region without aborting.
regular_clock_call();
@@ -3376,14 +3382,14 @@
statsOnly(if (mr.start() != NULL) ++_region_stack_pops );
}
} else {
- guarantee( has_aborted(), "currently the only way to do so" );
+ assert(has_aborted(), "currently the only way to do so");
// The only way to abort the bitmap iteration is to return
// false from the do_bit() method. However, inside the
// do_bit() method we move the _region_finger to point to the
// object currently being looked at. So, if we bail out, we
// have definitely set _region_finger to something non-null.
- guarantee( _region_finger != NULL, "invariant" );
+ assert(_region_finger != NULL, "invariant");
// The iteration was actually aborted. So now _region_finger
// points to the address of the object we last scanned. If we
@@ -3412,13 +3418,6 @@
_region_finger = NULL;
}
- // We only push regions on the region stack during evacuation
- // pauses. So if we come out the above iteration because we region
- // stack is empty, it will remain empty until the next yield
- // point. So, the guarantee below is safe.
- guarantee( has_aborted() || _cm->region_stack_empty(),
- "only way to exit the loop" );
-
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] drained region stack, size = %d",
_task_id, _cm->region_stack_size());
@@ -3576,21 +3575,21 @@
*****************************************************************************/
void CMTask::do_marking_step(double time_target_ms) {
- guarantee( time_target_ms >= 1.0, "minimum granularity is 1ms" );
- guarantee( concurrent() == _cm->concurrent(), "they should be the same" );
-
- guarantee( concurrent() || _cm->region_stack_empty(),
- "the region stack should have been cleared before remark" );
- guarantee( _region_finger == NULL,
- "this should be non-null only when a region is being scanned" );
+ assert(time_target_ms >= 1.0, "minimum granularity is 1ms");
+ assert(concurrent() == _cm->concurrent(), "they should be the same");
+
+ assert(concurrent() || _cm->region_stack_empty(),
+ "the region stack should have been cleared before remark");
+ assert(_region_finger == NULL,
+ "this should be non-null only when a region is being scanned");
G1CollectorPolicy* g1_policy = _g1h->g1_policy();
- guarantee( _task_queues != NULL, "invariant" );
- guarantee( _task_queue != NULL, "invariant" );
- guarantee( _task_queues->queue(_task_id) == _task_queue, "invariant" );
-
- guarantee( !_claimed,
- "only one thread should claim this task at any one time" );
+ assert(_task_queues != NULL, "invariant");
+ assert(_task_queue != NULL, "invariant");
+ assert(_task_queues->queue(_task_id) == _task_queue, "invariant");
+
+ assert(!_claimed,
+ "only one thread should claim this task at any one time");
// OK, this doesn't safeguard again all possible scenarios, as it is
// possible for two threads to set the _claimed flag at the same
@@ -3661,9 +3660,8 @@
do {
if (!has_aborted() && _curr_region != NULL) {
// This means that we're already holding on to a region.
- tmp_guarantee_CM( _finger != NULL,
- "if region is not NULL, then the finger "
- "should not be NULL either" );
+ assert(_finger != NULL, "if region is not NULL, then the finger "
+ "should not be NULL either");
// We might have restarted this task after an evacuation pause
// which might have evacuated the region we're holding on to
@@ -3695,13 +3693,13 @@
giveup_current_region();
regular_clock_call();
} else {
- guarantee( has_aborted(), "currently the only way to do so" );
+ assert(has_aborted(), "currently the only way to do so");
// The only way to abort the bitmap iteration is to return
// false from the do_bit() method. However, inside the
// do_bit() method we move the _finger to point to the
// object currently being looked at. So, if we bail out, we
// have definitely set _finger to something non-null.
- guarantee( _finger != NULL, "invariant" );
+ assert(_finger != NULL, "invariant");
// Region iteration was actually aborted. So now _finger
// points to the address of the object we last scanned. If we
@@ -3728,9 +3726,10 @@
while (!has_aborted() && _curr_region == NULL && !_cm->out_of_regions()) {
// We are going to try to claim a new region. We should have
// given up on the previous one.
- tmp_guarantee_CM( _curr_region == NULL &&
- _finger == NULL &&
- _region_limit == NULL, "invariant" );
+ // Separated the asserts so that we know which one fires.
+ assert(_curr_region == NULL, "invariant");
+ assert(_finger == NULL, "invariant");
+ assert(_region_limit == NULL, "invariant");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] trying to claim a new region", _task_id);
HeapRegion* claimed_region = _cm->claim_region(_task_id);
@@ -3744,7 +3743,7 @@
_task_id, claimed_region);
setup_for_region(claimed_region);
- tmp_guarantee_CM( _curr_region == claimed_region, "invariant" );
+ assert(_curr_region == claimed_region, "invariant");
}
// It is important to call the regular clock here. It might take
// a while to claim a region if, for example, we hit a large
@@ -3755,8 +3754,8 @@
}
if (!has_aborted() && _curr_region == NULL) {
- tmp_guarantee_CM( _cm->out_of_regions(),
- "at this point we should be out of regions" );
+ assert(_cm->out_of_regions(),
+ "at this point we should be out of regions");
}
} while ( _curr_region != NULL && !has_aborted());
@@ -3765,8 +3764,8 @@
// tasks might be pushing objects to it concurrently. We also cannot
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
- tmp_guarantee_CM( _cm->out_of_regions(),
- "at this point we should be out of regions" );
+ assert(_cm->out_of_regions(),
+ "at this point we should be out of regions");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] all regions claimed", _task_id);
@@ -3790,8 +3789,8 @@
// tasks might be pushing objects to it concurrently. We also cannot
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
- guarantee( _cm->out_of_regions() &&
- _task_queue->size() == 0, "only way to reach here" );
+ assert(_cm->out_of_regions() && _task_queue->size() == 0,
+ "only way to reach here");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] starting to steal", _task_id);
@@ -3807,8 +3806,8 @@
statsOnly( ++_steals );
- tmp_guarantee_CM( _nextMarkBitMap->isMarked((HeapWord*) obj),
- "any stolen object should be marked" );
+ assert(_nextMarkBitMap->isMarked((HeapWord*) obj),
+ "any stolen object should be marked");
scan_object(obj);
// And since we're towards the end, let's totally drain the
@@ -3828,8 +3827,9 @@
// tasks might be concurrently pushing objects on it. We also cannot
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
- guarantee( _cm->out_of_regions() &&
- _task_queue->size() == 0, "only way to reach here" );
+ // Separated the asserts so that we know which one fires.
+ assert(_cm->out_of_regions(), "only way to reach here");
+ assert(_task_queue->size() == 0, "only way to reach here");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] starting termination protocol", _task_id);
@@ -3849,7 +3849,7 @@
if (_task_id == 0) {
// let's allow task 0 to do this
if (concurrent()) {
- guarantee( _cm->concurrent_marking_in_progress(), "invariant" );
+ assert(_cm->concurrent_marking_in_progress(), "invariant");
// we need to set this to false before the next
// safepoint. This way we ensure that the marking phase
// doesn't observe any more heap expansions.
@@ -3858,15 +3858,16 @@
}
// We can now guarantee that the global stack is empty, since
- // all other tasks have finished.
- guarantee( _cm->out_of_regions() &&
- _cm->region_stack_empty() &&
- _cm->mark_stack_empty() &&
- _task_queue->size() == 0 &&
- !_cm->has_overflown() &&
- !_cm->mark_stack_overflow() &&
- !_cm->region_stack_overflow(),
- "only way to reach here" );
+ // all other tasks have finished. We separated the guarantees so
+ // that, if a condition is false, we can immediately find out
+ // which one.
+ guarantee(_cm->out_of_regions(), "only way to reach here");
+ guarantee(_cm->region_stack_empty(), "only way to reach here");
+ guarantee(_cm->mark_stack_empty(), "only way to reach here");
+ guarantee(_task_queue->size() == 0, "only way to reach here");
+ guarantee(!_cm->has_overflown(), "only way to reach here");
+ guarantee(!_cm->mark_stack_overflow(), "only way to reach here");
+ guarantee(!_cm->region_stack_overflow(), "only way to reach here");
if (_cm->verbose_low())
gclog_or_tty->print_cr("[%d] all tasks terminated", _task_id);
@@ -3961,8 +3962,8 @@
_task_queue(task_queue),
_task_queues(task_queues),
_oop_closure(NULL) {
- guarantee( task_queue != NULL, "invariant" );
- guarantee( task_queues != NULL, "invariant" );
+ guarantee(task_queue != NULL, "invariant");
+ guarantee(task_queues != NULL, "invariant");
statsOnly( _clock_due_to_scanning = 0;
_clock_due_to_marking = 0 );
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -295,12 +295,6 @@
} while (0)
#endif // _MARKING_STATS_
-// Some extra guarantees that I like to also enable in optimised mode
-// when debugging. If you want to enable them, comment out the assert
-// macro and uncomment out the guaratee macro
-// #define tmp_guarantee_CM(expr, str) guarantee(expr, str)
-#define tmp_guarantee_CM(expr, str) assert(expr, str)
-
typedef enum {
no_verbose = 0, // verbose turned off
stats_verbose, // only prints stats at the end of marking
@@ -485,15 +479,15 @@
// Returns the task with the given id
CMTask* task(int id) {
- guarantee( 0 <= id && id < (int) _active_tasks, "task id not within "
- "active bounds" );
+ assert(0 <= id && id < (int) _active_tasks,
+ "task id not within active bounds");
return _tasks[id];
}
// Returns the task queue with the given id
CMTaskQueue* task_queue(int id) {
- guarantee( 0 <= id && id < (int) _active_tasks, "task queue id not within "
- "active bounds" );
+ assert(0 <= id && id < (int) _active_tasks,
+ "task queue id not within active bounds");
return (CMTaskQueue*) _task_queues->queue(id);
}
@@ -723,6 +717,8 @@
void print_summary_info();
+ void print_worker_threads_on(outputStream* st) const;
+
// The following indicate whether a given verbose level has been
// set. Notice that anything above stats is conditional to
// _MARKING_VERBOSE_ having been set to 1
@@ -959,8 +955,7 @@
// It scans an object and visits its children.
void scan_object(oop obj) {
- tmp_guarantee_CM( _nextMarkBitMap->isMarked((HeapWord*) obj),
- "invariant" );
+ assert(_nextMarkBitMap->isMarked((HeapWord*) obj), "invariant");
if (_cm->verbose_high())
gclog_or_tty->print_cr("[%d] we're scanning object "PTR_FORMAT,
@@ -999,14 +994,13 @@
// moves the local finger to a new location
inline void move_finger_to(HeapWord* new_finger) {
- tmp_guarantee_CM( new_finger >= _finger && new_finger < _region_limit,
- "invariant" );
+ assert(new_finger >= _finger && new_finger < _region_limit, "invariant");
_finger = new_finger;
}
// moves the region finger to a new location
inline void move_region_finger_to(HeapWord* new_finger) {
- tmp_guarantee_CM( new_finger < _cm->finger(), "invariant" );
+ assert(new_finger < _cm->finger(), "invariant");
_region_finger = new_finger;
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -286,10 +286,14 @@
}
}
-void ConcurrentMarkThread::print() {
- gclog_or_tty->print("\"Concurrent Mark GC Thread\" ");
- Thread::print();
- gclog_or_tty->cr();
+void ConcurrentMarkThread::print() const {
+ print_on(tty);
+}
+
+void ConcurrentMarkThread::print_on(outputStream* st) const {
+ st->print("\"G1 Main Concurrent Mark GC Thread\" ");
+ Thread::print_on(st);
+ st->cr();
}
void ConcurrentMarkThread::sleepBeforeNextCycle() {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -57,7 +57,8 @@
static SurrogateLockerThread* slt() { return _slt; }
// Printing
- void print();
+ void print_on(outputStream* st) const;
+ void print() const;
// Total virtual time so far.
double vtime_accum();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -157,10 +157,14 @@
}
}
-void ConcurrentZFThread::print() {
- gclog_or_tty->print("\"Concurrent ZF Thread\" ");
- Thread::print();
- gclog_or_tty->cr();
+void ConcurrentZFThread::print() const {
+ print_on(tty);
+}
+
+void ConcurrentZFThread::print_on(outputStream* st) const {
+ st->print("\"G1 Concurrent Zero-Fill Thread\" ");
+ Thread::print_on(st);
+ st->cr();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentZFThread.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -61,7 +61,8 @@
virtual void run();
// Printing
- void print();
+ void print_on(outputStream* st) const;
+ void print() const;
// Waits until "r" has been zero-filled. Requires caller to hold the
// ZF_mon.
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -2210,40 +2210,58 @@
bool _allow_dirty;
bool _par;
bool _use_prev_marking;
+ bool _failures;
public:
// use_prev_marking == true -> use "prev" marking information,
// use_prev_marking == false -> use "next" marking information
VerifyRegionClosure(bool allow_dirty, bool par, bool use_prev_marking)
: _allow_dirty(allow_dirty),
_par(par),
- _use_prev_marking(use_prev_marking) {}
+ _use_prev_marking(use_prev_marking),
+ _failures(false) {}
+
+ bool failures() {
+ return _failures;
+ }
bool doHeapRegion(HeapRegion* r) {
guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue,
"Should be unclaimed at verify points.");
if (!r->continuesHumongous()) {
- VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking);
- r->verify(_allow_dirty, _use_prev_marking);
- r->object_iterate(¬_dead_yet_cl);
- guarantee(r->max_live_bytes() >= not_dead_yet_cl.live_bytes(),
- "More live objects than counted in last complete marking.");
+ bool failures = false;
+ r->verify(_allow_dirty, _use_prev_marking, &failures);
+ if (failures) {
+ _failures = true;
+ } else {
+ VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking);
+ r->object_iterate(¬_dead_yet_cl);
+ if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
+ gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
+ "max_live_bytes "SIZE_FORMAT" "
+ "< calculated "SIZE_FORMAT,
+ r->bottom(), r->end(),
+ r->max_live_bytes(),
+ not_dead_yet_cl.live_bytes());
+ _failures = true;
+ }
+ }
}
- return false;
+ return false; // stop the region iteration if we hit a failure
}
};
class VerifyRootsClosure: public OopsInGenClosure {
private:
G1CollectedHeap* _g1h;
+ bool _use_prev_marking;
bool _failures;
- bool _use_prev_marking;
public:
// use_prev_marking == true -> use "prev" marking information,
// use_prev_marking == false -> use "next" marking information
VerifyRootsClosure(bool use_prev_marking) :
_g1h(G1CollectedHeap::heap()),
- _failures(false),
- _use_prev_marking(use_prev_marking) { }
+ _use_prev_marking(use_prev_marking),
+ _failures(false) { }
bool failures() { return _failures; }
@@ -2253,7 +2271,7 @@
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (_g1h->is_obj_dead_cond(obj, _use_prev_marking)) {
gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
- "points to dead obj "PTR_FORMAT, p, (void*) obj);
+ "points to dead obj "PTR_FORMAT, p, (void*) obj);
obj->print_on(gclog_or_tty);
_failures = true;
}
@@ -2271,6 +2289,7 @@
G1CollectedHeap* _g1h;
bool _allow_dirty;
bool _use_prev_marking;
+ bool _failures;
public:
// use_prev_marking == true -> use "prev" marking information,
@@ -2280,13 +2299,21 @@
AbstractGangTask("Parallel verify task"),
_g1h(g1h),
_allow_dirty(allow_dirty),
- _use_prev_marking(use_prev_marking) { }
+ _use_prev_marking(use_prev_marking),
+ _failures(false) { }
+
+ bool failures() {
+ return _failures;
+ }
void work(int worker_i) {
HandleMark hm;
VerifyRegionClosure blk(_allow_dirty, true, _use_prev_marking);
_g1h->heap_region_par_iterate_chunked(&blk, worker_i,
HeapRegion::ParVerifyClaimValue);
+ if (blk.failures()) {
+ _failures = true;
+ }
}
};
@@ -2307,6 +2334,7 @@
&rootsCl,
&blobsCl,
&rootsCl);
+ bool failures = rootsCl.failures();
rem_set()->invalidate(perm_gen()->used_region(), false);
if (!silent) { gclog_or_tty->print("heapRegions "); }
if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
@@ -2318,6 +2346,9 @@
set_par_threads(n_workers);
workers()->run_task(&task);
set_par_threads(0);
+ if (task.failures()) {
+ failures = true;
+ }
assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue),
"sanity check");
@@ -2329,10 +2360,23 @@
} else {
VerifyRegionClosure blk(allow_dirty, false, use_prev_marking);
_hrs->iterate(&blk);
+ if (blk.failures()) {
+ failures = true;
+ }
}
if (!silent) gclog_or_tty->print("remset ");
rem_set()->verify();
- guarantee(!rootsCl.failures(), "should not have had failures");
+
+ if (failures) {
+ gclog_or_tty->print_cr("Heap:");
+ print_on(gclog_or_tty, true /* extended */);
+ gclog_or_tty->print_cr("");
+ if (VerifyDuringGC && G1VerifyConcMarkPrintReachable) {
+ concurrent_mark()->print_prev_bitmap_reachable();
+ }
+ gclog_or_tty->flush();
+ }
+ guarantee(!failures, "there should not have been any failures");
} else {
if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) ");
}
@@ -2374,6 +2418,7 @@
st->cr();
perm()->as_gen()->print_on(st);
if (extended) {
+ st->cr();
print_on_extended(st);
}
}
@@ -2383,27 +2428,18 @@
_hrs->iterate(&blk);
}
-class PrintOnThreadsClosure : public ThreadClosure {
- outputStream* _st;
-public:
- PrintOnThreadsClosure(outputStream* st) : _st(st) { }
- virtual void do_thread(Thread *t) {
- t->print_on(_st);
- }
-};
-
void G1CollectedHeap::print_gc_threads_on(outputStream* st) const {
if (ParallelGCThreads > 0) {
- workers()->print_worker_threads();
- }
- st->print("\"G1 concurrent mark GC Thread\" ");
- _cmThread->print();
+ workers()->print_worker_threads_on(st);
+ }
+
+ _cmThread->print_on(st);
st->cr();
- st->print("\"G1 concurrent refinement GC Threads\" ");
- PrintOnThreadsClosure p(st);
- _cg1r->threads_do(&p);
- st->cr();
- st->print("\"G1 zero-fill GC Thread\" ");
+
+ _cm->print_worker_threads_on(st);
+
+ _cg1r->print_worker_threads_on(st);
+
_czft->print_on(st);
st->cr();
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -992,11 +992,39 @@
// Can a compiler initialize a new object without store barriers?
// This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint.
+ // via a TLAB up to the first subsequent safepoint. If such permission
+ // is granted for this heap type, the compiler promises to call
+ // defer_store_barrier() below on any slow path allocation of
+ // a new object for which such initializing store barriers will
+ // have been elided. G1, like CMS, allows this, but should be
+ // ready to provide a compensating write barrier as necessary
+ // if that storage came out of a non-young region. The efficiency
+ // of this implementation depends crucially on being able to
+ // answer very efficiently in constant time whether a piece of
+ // storage in the heap comes from a young region or not.
+ // See ReduceInitialCardMarks.
virtual bool can_elide_tlab_store_barriers() const {
- // Since G1's TLAB's may, on occasion, come from non-young regions
- // as well. (Is there a flag controlling that? XXX)
- return false;
+ return true;
+ }
+
+ bool is_in_young(oop obj) {
+ HeapRegion* hr = heap_region_containing(obj);
+ return hr != NULL && hr->is_young();
+ }
+
+ // We don't need barriers for initializing stores to objects
+ // in the young gen: for the SATB pre-barrier, there is no
+ // pre-value that needs to be remembered; for the remembered-set
+ // update logging post-barrier, we don't maintain remembered set
+ // information for young gen objects. Note that non-generational
+ // G1 does not have any "young" objects, should not elide
+ // the rs logging barrier and so should always answer false below.
+ // However, non-generational G1 (-XX:-G1Gen) appears to have
+ // bit-rotted so was not tested below.
+ virtual bool can_elide_initializing_store_barrier(oop new_obj) {
+ assert(G1Gen || !is_in_young(new_obj),
+ "Non-generational G1 should never return true below");
+ return is_in_young(new_obj);
}
// Can a compiler elide a store barrier when it writes
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -722,12 +722,13 @@
st->print(" F");
else
st->print(" ");
- st->print(" %d", _gc_time_stamp);
+ st->print(" %5d", _gc_time_stamp);
G1OffsetTableContigSpace::print_on(st);
}
void HeapRegion::verify(bool allow_dirty) const {
- verify(allow_dirty, /* use_prev_marking */ true);
+ bool dummy = false;
+ verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy);
}
#define OBJ_SAMPLE_INTERVAL 0
@@ -736,8 +737,11 @@
// This really ought to be commoned up into OffsetTableContigSpace somehow.
// We would need a mechanism to make that code skip dead objects.
-void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const {
+void HeapRegion::verify(bool allow_dirty,
+ bool use_prev_marking,
+ bool* failures) const {
G1CollectedHeap* g1 = G1CollectedHeap::heap();
+ *failures = false;
HeapWord* p = bottom();
HeapWord* prev_p = NULL;
int objs = 0;
@@ -746,8 +750,14 @@
while (p < top()) {
size_t size = oop(p)->size();
if (blocks == BLOCK_SAMPLE_INTERVAL) {
- guarantee(p == block_start_const(p + (size/2)),
- "check offset computation");
+ HeapWord* res = block_start_const(p + (size/2));
+ if (p != res) {
+ gclog_or_tty->print_cr("offset computation 1 for "PTR_FORMAT" and "
+ SIZE_FORMAT" returned "PTR_FORMAT,
+ p, size, res);
+ *failures = true;
+ return;
+ }
blocks = 0;
} else {
blocks++;
@@ -755,11 +765,34 @@
if (objs == OBJ_SAMPLE_INTERVAL) {
oop obj = oop(p);
if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) {
- obj->verify();
- vl_cl.set_containing_obj(obj);
- obj->oop_iterate(&vl_cl);
- if (G1MaxVerifyFailures >= 0
- && vl_cl.n_failures() >= G1MaxVerifyFailures) break;
+ if (obj->is_oop()) {
+ klassOop klass = obj->klass();
+ if (!klass->is_perm()) {
+ gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
+ "not in perm", klass, obj);
+ *failures = true;
+ return;
+ } else if (!klass->is_klass()) {
+ gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
+ "not a klass", klass, obj);
+ *failures = true;
+ return;
+ } else {
+ vl_cl.set_containing_obj(obj);
+ obj->oop_iterate(&vl_cl);
+ if (vl_cl.failures()) {
+ *failures = true;
+ }
+ if (G1MaxVerifyFailures >= 0 &&
+ vl_cl.n_failures() >= G1MaxVerifyFailures) {
+ return;
+ }
+ }
+ } else {
+ gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj);
+ *failures = true;
+ return;
+ }
}
objs = 0;
} else {
@@ -771,21 +804,22 @@
HeapWord* rend = end();
HeapWord* rtop = top();
if (rtop < rend) {
- guarantee(block_start_const(rtop + (rend - rtop) / 2) == rtop,
- "check offset computation");
- }
- if (vl_cl.failures()) {
- gclog_or_tty->print_cr("Heap:");
- G1CollectedHeap::heap()->print_on(gclog_or_tty, true /* extended */);
- gclog_or_tty->print_cr("");
+ HeapWord* res = block_start_const(rtop + (rend - rtop) / 2);
+ if (res != rtop) {
+ gclog_or_tty->print_cr("offset computation 2 for "PTR_FORMAT" and "
+ PTR_FORMAT" returned "PTR_FORMAT,
+ rtop, rend, res);
+ *failures = true;
+ return;
+ }
}
- if (VerifyDuringGC &&
- G1VerifyConcMarkPrintReachable &&
- vl_cl.failures()) {
- g1->concurrent_mark()->print_prev_bitmap_reachable();
+
+ if (p != top()) {
+ gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
+ "does not match top "PTR_FORMAT, p, top());
+ *failures = true;
+ return;
}
- guarantee(!vl_cl.failures(), "region verification failed");
- guarantee(p == top(), "end of last object must match end of space");
}
// G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -569,13 +569,8 @@
// ever evacuated into this region. If we evacuate, allocate, and
// then evacuate we are in deep doodoo.
void note_end_of_copying() {
- assert(top() >= _next_top_at_mark_start,
- "Increase only");
- // Survivor regions will be scanned on the start of concurrent
- // marking.
- if (!is_survivor()) {
- _next_top_at_mark_start = top();
- }
+ assert(top() >= _next_top_at_mark_start, "Increase only");
+ _next_top_at_mark_start = top();
}
// Returns "false" iff no object in the region was allocated when the
@@ -798,7 +793,7 @@
// use_prev_marking == true. Currently, there is only one case where
// this is called with use_prev_marking == false, which is to verify
// the "next" marking information at the end of remark.
- void verify(bool allow_dirty, bool use_prev_marking) const;
+ void verify(bool allow_dirty, bool use_prev_marking, bool *failures) const;
// Override; it uses the "prev" marking information
virtual void verify(bool allow_dirty) const;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -314,41 +314,6 @@
return false;
}
-// Static method
-bool ParallelScavengeHeap::is_in_young(oop* p) {
- ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
- assert(heap->kind() == CollectedHeap::ParallelScavengeHeap,
- "Must be ParallelScavengeHeap");
-
- PSYoungGen* young_gen = heap->young_gen();
-
- if (young_gen->is_in_reserved(p)) {
- return true;
- }
-
- return false;
-}
-
-// Static method
-bool ParallelScavengeHeap::is_in_old_or_perm(oop* p) {
- ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
- assert(heap->kind() == CollectedHeap::ParallelScavengeHeap,
- "Must be ParallelScavengeHeap");
-
- PSOldGen* old_gen = heap->old_gen();
- PSPermGen* perm_gen = heap->perm_gen();
-
- if (old_gen->is_in_reserved(p)) {
- return true;
- }
-
- if (perm_gen->is_in_reserved(p)) {
- return true;
- }
-
- return false;
-}
-
// There are two levels of allocation policy here.
//
// When an allocation request fails, the requesting thread must invoke a VM
@@ -764,6 +729,13 @@
CollectedHeap::resize_all_tlabs();
}
+bool ParallelScavengeHeap::can_elide_initializing_store_barrier(oop new_obj) {
+ // We don't need barriers for stores to objects in the
+ // young gen and, a fortiori, for initializing stores to
+ // objects therein.
+ return is_in_young(new_obj);
+}
+
// This method is used by System.gc() and JVMTI.
void ParallelScavengeHeap::collect(GCCause::Cause cause) {
assert(!Heap_lock->owned_by_self(),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -129,8 +129,8 @@
return perm_gen()->is_in(p);
}
- static bool is_in_young(oop *p); // reserved part
- static bool is_in_old_or_perm(oop *p); // reserved part
+ inline bool is_in_young(oop p); // reserved part
+ inline bool is_in_old_or_perm(oop p); // reserved part
// Memory allocation. "gc_time_limit_was_exceeded" will
// be set to true if the adaptive size policy determine that
@@ -191,6 +191,10 @@
return true;
}
+ // Return true if we don't we need a store barrier for
+ // initializing stores to an object at this address.
+ virtual bool can_elide_initializing_store_barrier(oop new_obj);
+
// Can a compiler elide a store barrier when it writes
// a permanent oop into the heap? Applies when the compiler
// is storing x to the heap, where x->is_perm() is true.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -41,3 +41,11 @@
PSMarkSweep::invoke(maximum_compaction);
}
}
+
+inline bool ParallelScavengeHeap::is_in_young(oop p) {
+ return young_gen()->is_in_reserved(p);
+}
+
+inline bool ParallelScavengeHeap::is_in_old_or_perm(oop p) {
+ return old_gen()->is_in_reserved(p) || perm_gen()->is_in_reserved(p);
+}
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -137,6 +137,89 @@
return obj;
}
+void CollectedHeap::flush_deferred_store_barrier(JavaThread* thread) {
+ MemRegion deferred = thread->deferred_card_mark();
+ if (!deferred.is_empty()) {
+ {
+ // Verify that the storage points to a parsable object in heap
+ DEBUG_ONLY(oop old_obj = oop(deferred.start());)
+ assert(is_in(old_obj), "Not in allocated heap");
+ assert(!can_elide_initializing_store_barrier(old_obj),
+ "Else should have been filtered in defer_store_barrier()");
+ assert(!is_in_permanent(old_obj), "Sanity: not expected");
+ assert(old_obj->is_oop(true), "Not an oop");
+ assert(old_obj->is_parsable(), "Will not be concurrently parsable");
+ assert(deferred.word_size() == (size_t)(old_obj->size()),
+ "Mismatch: multiple objects?");
+ }
+ BarrierSet* bs = barrier_set();
+ assert(bs->has_write_region_opt(), "No write_region() on BarrierSet");
+ bs->write_region(deferred);
+ // "Clear" the deferred_card_mark field
+ thread->set_deferred_card_mark(MemRegion());
+ }
+ assert(thread->deferred_card_mark().is_empty(), "invariant");
+}
+
+// Helper for ReduceInitialCardMarks. For performance,
+// compiled code may elide card-marks for initializing stores
+// to a newly allocated object along the fast-path. We
+// compensate for such elided card-marks as follows:
+// (a) Generational, non-concurrent collectors, such as
+// GenCollectedHeap(ParNew,DefNew,Tenured) and
+// ParallelScavengeHeap(ParallelGC, ParallelOldGC)
+// need the card-mark if and only if the region is
+// in the old gen, and do not care if the card-mark
+// succeeds or precedes the initializing stores themselves,
+// so long as the card-mark is completed before the next
+// scavenge. For all these cases, we can do a card mark
+// at the point at which we do a slow path allocation
+// in the old gen. For uniformity, however, we end
+// up using the same scheme (see below) for all three
+// cases (deferring the card-mark appropriately).
+// (b) GenCollectedHeap(ConcurrentMarkSweepGeneration) requires
+// in addition that the card-mark for an old gen allocated
+// object strictly follow any associated initializing stores.
+// In these cases, the memRegion remembered below is
+// used to card-mark the entire region either just before the next
+// slow-path allocation by this thread or just before the next scavenge or
+// CMS-associated safepoint, whichever of these events happens first.
+// (The implicit assumption is that the object has been fully
+// initialized by this point, a fact that we assert when doing the
+// card-mark.)
+// (c) G1CollectedHeap(G1) uses two kinds of write barriers. When a
+// G1 concurrent marking is in progress an SATB (pre-write-)barrier is
+// is used to remember the pre-value of any store. Initializing
+// stores will not need this barrier, so we need not worry about
+// compensating for the missing pre-barrier here. Turning now
+// to the post-barrier, we note that G1 needs a RS update barrier
+// which simply enqueues a (sequence of) dirty cards which may
+// optionally be refined by the concurrent update threads. Note
+// that this barrier need only be applied to a non-young write,
+// but, like in CMS, because of the presence of concurrent refinement
+// (much like CMS' precleaning), must strictly follow the oop-store.
+// Thus, using the same protocol for maintaining the intended
+// invariants turns out, serendepitously, to be the same for all
+// three collectors/heap types above.
+//
+// For each future collector, this should be reexamined with
+// that specific collector in mind.
+oop CollectedHeap::defer_store_barrier(JavaThread* thread, oop new_obj) {
+ // If a previous card-mark was deferred, flush it now.
+ flush_deferred_store_barrier(thread);
+ if (can_elide_initializing_store_barrier(new_obj)) {
+ // The deferred_card_mark region should be empty
+ // following the flush above.
+ assert(thread->deferred_card_mark().is_empty(), "Error");
+ } else {
+ // Remember info for the newly deferred store barrier
+ MemRegion deferred = MemRegion((HeapWord*)new_obj, new_obj->size());
+ assert(!deferred.is_empty(), "Error");
+ thread->set_deferred_card_mark(deferred);
+ }
+ return new_obj;
+}
+
size_t CollectedHeap::filler_array_hdr_size() {
return size_t(arrayOopDesc::header_size(T_INT));
}
@@ -225,16 +308,6 @@
fill_with_object_impl(start, words);
}
-oop CollectedHeap::new_store_barrier(oop new_obj) {
- // %%% This needs refactoring. (It was imported from the server compiler.)
- guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported");
- BarrierSet* bs = this->barrier_set();
- assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
- int new_size = new_obj->size();
- bs->write_region(MemRegion((HeapWord*)new_obj, new_size));
- return new_obj;
-}
-
HeapWord* CollectedHeap::allocate_new_tlab(size_t size) {
guarantee(false, "thread-local allocation buffers not supported");
return NULL;
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -415,9 +415,14 @@
guarantee(false, "thread-local allocation buffers not supported");
return 0;
}
+
// Can a compiler initialize a new object without store barriers?
// This permission only extends from the creation of a new object
- // via a TLAB up to the first subsequent safepoint.
+ // via a TLAB up to the first subsequent safepoint. If such permission
+ // is granted for this heap type, the compiler promises to call
+ // defer_store_barrier() below on any slow path allocation of
+ // a new object for which such initializing store barriers will
+ // have been elided.
virtual bool can_elide_tlab_store_barriers() const = 0;
// If a compiler is eliding store barriers for TLAB-allocated objects,
@@ -425,8 +430,19 @@
// an object allocated anywhere. The compiler's runtime support
// promises to call this function on such a slow-path-allocated
// object before performing initializations that have elided
- // store barriers. Returns new_obj, or maybe a safer copy thereof.
- virtual oop new_store_barrier(oop new_obj);
+ // store barriers. Returns new_obj, or maybe a safer copy thereof.
+ virtual oop defer_store_barrier(JavaThread* thread, oop new_obj);
+
+ // Answers whether an initializing store to a new object currently
+ // allocated at the given address doesn't need a (deferred) store
+ // barrier. Returns "true" if it doesn't need an initializing
+ // store barrier; answers "false" if it does.
+ virtual bool can_elide_initializing_store_barrier(oop new_obj) = 0;
+
+ // If the CollectedHeap was asked to defer a store barrier above,
+ // this informs it to flush such a deferred store barrier to the
+ // remembered set.
+ virtual void flush_deferred_store_barrier(JavaThread* thread);
// Can a compiler elide a store barrier when it writes
// a permanent oop into the heap? Applies when the compiler
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/includeDB_zero Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,55 @@
+//
+// Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
+// Copyright 2009 Red Hat, Inc.
+// 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.
+//
+//
+
+// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
+
+entryFrame_<arch>.hpp javaCalls.hpp
+entryFrame_<arch>.hpp stack_<arch>.hpp
+
+fakeStubFrame_<arch>.hpp stack_<arch>.hpp
+
+frame.hpp stack_<arch>.hpp
+
+frame.inline.hpp fakeStubFrame_<arch>.hpp
+frame.inline.hpp entryFrame_<arch>.hpp
+frame.inline.hpp interpreterFrame_<arch>.hpp
+frame.inline.hpp sharkFrame_<arch>.hpp
+
+frame_<arch>.cpp interpreterRuntime.hpp
+frame_<arch>.cpp scopeDesc.hpp
+
+interpreter.hpp entry_<arch>.hpp
+
+interpreterFrame_<arch>.hpp bytecodeInterpreter.hpp
+interpreterFrame_<arch>.hpp methodOop.hpp
+interpreterFrame_<arch>.hpp stack_<arch>.hpp
+interpreterFrame_<arch>.hpp thread.hpp
+
+sharkFrame_<arch>.hpp methodOop.hpp
+sharkFrame_<arch>.hpp stack_<arch>.hpp
+
+stack_<arch>.hpp sizes.hpp
+
+thread.hpp stack_<arch>.hpp
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -3031,9 +3031,9 @@
tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult);
tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult);
#endif
-#ifdef IA64
+#if defined(IA64) && !defined(ZERO)
tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp);
-#endif // IA64
+#endif // IA64 && !ZERO
tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link);
}
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -281,7 +281,7 @@
public:
void pass_int() { /* ignore */ }
void pass_long() { /* ignore */ }
-#ifdef _LP64
+#if defined(_LP64) || defined(ZERO)
void pass_float() { /* ignore */ }
#endif
void pass_double() { /* ignore */ }
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -260,6 +260,20 @@
return true;
}
+ // We don't need barriers for stores to objects in the
+ // young gen and, a fortiori, for initializing stores to
+ // objects therein. This applies to {DefNew,ParNew}+{Tenured,CMS}
+ // only and may need to be re-examined in case other
+ // kinds of collectors are implemented in the future.
+ virtual bool can_elide_initializing_store_barrier(oop new_obj) {
+ // We wanted to assert that:-
+ // assert(UseParNewGC || UseSerialGC || UseConcMarkSweepGC,
+ // "Check can_elide_initializing_store_barrier() for this collector");
+ // but unfortunately the flag UseSerialGC need not necessarily always
+ // be set when DefNew+Tenured are being used.
+ return is_in_youngest((void*)new_obj);
+ }
+
// Can a compiler elide a store barrier when it writes
// a permanent oop into the heap? Applies when the compiler
// is storing x to the heap, where x->is_perm() is true.
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -1531,6 +1531,8 @@
return NULL; // No change
Node *top = phase->C->top();
+ bool new_phi = (outcnt() == 0); // transforming new Phi
+ assert(!can_reshape || !new_phi, "for igvn new phi should be hooked");
// The are 2 situations when only one valid phi's input is left
// (in addition to Region input).
@@ -1550,6 +1552,12 @@
}
}
+ if (can_reshape && outcnt() == 0) {
+ // set_req() above may kill outputs if Phi is referenced
+ // only by itself on the dead (top) control path.
+ return top;
+ }
+
Node* uin = unique_input(phase);
if (uin == top) { // Simplest case: no alive inputs.
if (can_reshape) // IGVN transformation
@@ -1684,8 +1692,7 @@
// Equivalent code is in MemNode::Ideal_common
Node *m = phase->transform(n);
if (outcnt() == 0) { // Above transform() may kill us!
- progress = phase->C->top();
- break;
+ return top;
}
// If transformed to a MergeMem, get the desired slice
// Otherwise the returned node represents memory for every slice
--- a/hotspot/src/share/vm/opto/chaitin.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -985,6 +985,8 @@
uint lo_score = _hi_degree;
double score = lrgs(lo_score).score();
double area = lrgs(lo_score)._area;
+ double cost = lrgs(lo_score)._cost;
+ bool bound = lrgs(lo_score)._is_bound;
// Find cheapest guy
debug_only( int lo_no_simplify=0; );
@@ -1002,17 +1004,27 @@
debug_only( if( lrgs(i)._was_lo ) lo_no_simplify=i; );
double iscore = lrgs(i).score();
double iarea = lrgs(i)._area;
+ double icost = lrgs(i)._cost;
+ bool ibound = lrgs(i)._is_bound;
// Compare cost/area of i vs cost/area of lo_score. Smaller cost/area
// wins. Ties happen because all live ranges in question have spilled
// a few times before and the spill-score adds a huge number which
// washes out the low order bits. We are choosing the lesser of 2
// evils; in this case pick largest area to spill.
+ // Ties also happen when live ranges are defined and used only inside
+ // one block. In which case their area is 0 and score set to max.
+ // In such case choose bound live range over unbound to free registers
+ // or with smaller cost to spill.
if( iscore < score ||
- (iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) ) {
+ (iscore == score && iarea > area && lrgs(lo_score)._was_spilled2) ||
+ (iscore == score && iarea == area &&
+ ( (ibound && !bound) || ibound == bound && (icost < cost) )) ) {
lo_score = i;
score = iscore;
area = iarea;
+ cost = icost;
+ bound = ibound;
}
}
LRG *lo_lrg = &lrgs(lo_score);
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -3186,6 +3186,15 @@
return;
}
+ if (use_ReduceInitialCardMarks()
+ && obj == just_allocated_object(control())) {
+ // We can skip marks on a freshly-allocated object in Eden.
+ // Keep this code in sync with maybe_defer_card_mark() in runtime.cpp.
+ // That routine informs GC to take appropriate compensating steps
+ // so as to make this card-mark elision safe.
+ return;
+ }
+
if (!use_precise) {
// All card marks for a (non-array) instance are in one place:
adr = obj;
--- a/hotspot/src/share/vm/opto/ifnode.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/ifnode.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -240,13 +240,13 @@
// as a single huge transform.
igvn->register_new_node_with_optimizer( region_c );
igvn->register_new_node_with_optimizer( region_x );
- phi_x = phase->transform( phi_x );
// Prevent the untimely death of phi_x. Currently he has no uses. He is
// about to get one. If this only use goes away, then phi_x will look dead.
// However, he will be picking up some more uses down below.
Node *hook = new (igvn->C, 4) Node(4);
hook->init_req(0, phi_x);
hook->init_req(1, phi_c);
+ phi_x = phase->transform( phi_x );
// Make the compare
Node *cmp_c = phase->makecon(t);
@@ -322,6 +322,7 @@
phi_s = PhiNode::make_blank(region_s,phi);
phi_s->init_req( 1, phi_c );
phi_s->init_req( 2, phi_x );
+ hook->add_req(phi_s);
phi_s = phase->transform(phi_s);
}
proj_path_data = phi_s;
@@ -333,6 +334,7 @@
phi_f = PhiNode::make_blank(region_f,phi);
phi_f->init_req( 1, phi_c );
phi_f->init_req( 2, phi_x );
+ hook->add_req(phi_f);
phi_f = phase->transform(phi_f);
}
proj_path_data = phi_f;
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -4160,13 +4160,13 @@
result_mem ->set_req(_objArray_path, reset_memory());
}
}
- // We can dispense with card marks if we know the allocation
- // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks
- // causes the non-eden paths to simulate a fresh allocation,
- // insofar that no further card marks are required to initialize
- // the object.
-
// Otherwise, there are no card marks to worry about.
+ // (We can dispense with card marks if we know the allocation
+ // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks
+ // causes the non-eden paths to take compensating steps to
+ // simulate a fresh allocation, so that no further
+ // card marks are required in compiled code to initialize
+ // the object.)
if (!stopped()) {
copy_to_clone(obj, alloc_obj, obj_size, true, false);
--- a/hotspot/src/share/vm/opto/phaseX.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -1502,7 +1502,7 @@
//---------------------------------saturate------------------------------------
const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type,
const Type* limit_type) const {
- const Type* wide_type = new_type->widen(old_type);
+ const Type* wide_type = new_type->widen(old_type, limit_type);
if (wide_type != new_type) { // did we widen?
// If so, we may have widened beyond the limit type. Clip it back down.
new_type = wide_type->filter(limit_type);
--- a/hotspot/src/share/vm/opto/runtime.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -143,18 +143,20 @@
// We failed the fast-path allocation. Now we need to do a scavenge or GC
// and try allocation again.
-void OptoRuntime::do_eager_card_mark(JavaThread* thread) {
+void OptoRuntime::maybe_defer_card_mark(JavaThread* thread) {
// After any safepoint, just before going back to compiled code,
- // we perform a card mark. This lets the compiled code omit
- // card marks for initialization of new objects.
- // Keep this code consistent with GraphKit::store_barrier.
+ // we inform the GC that we will be doing initializing writes to
+ // this object in the future without emitting card-marks, so
+ // GC may take any compensating steps.
+ // NOTE: Keep this code consistent with GraphKit::store_barrier.
oop new_obj = thread->vm_result();
if (new_obj == NULL) return;
assert(Universe::heap()->can_elide_tlab_store_barriers(),
"compiler must check this first");
- new_obj = Universe::heap()->new_store_barrier(new_obj);
+ // GC may decide to give back a safer copy of new_obj.
+ new_obj = Universe::heap()->defer_store_barrier(thread, new_obj);
thread->set_vm_result(new_obj);
}
@@ -197,8 +199,8 @@
JRT_BLOCK_END;
if (GraphKit::use_ReduceInitialCardMarks()) {
- // do them now so we don't have to do them on the fast path
- do_eager_card_mark(thread);
+ // inform GC that we won't do card marks for initializing writes.
+ maybe_defer_card_mark(thread);
}
JRT_END
@@ -236,8 +238,8 @@
JRT_BLOCK_END;
if (GraphKit::use_ReduceInitialCardMarks()) {
- // do them now so we don't have to do them on the fast path
- do_eager_card_mark(thread);
+ // inform GC that we won't do card marks for initializing writes.
+ maybe_defer_card_mark(thread);
}
JRT_END
--- a/hotspot/src/share/vm/opto/runtime.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/runtime.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -133,8 +133,8 @@
// Allocate storage for a objArray or typeArray
static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread);
- // Post-allocation step for implementing ReduceInitialCardMarks:
- static void do_eager_card_mark(JavaThread* thread);
+ // Post-slow-path-allocation step for implementing ReduceInitialCardMarks:
+ static void maybe_defer_card_mark(JavaThread* thread);
// Allocate storage for a multi-dimensional arrays
// Note: needs to be fixed for arbitrary number of dimensions
--- a/hotspot/src/share/vm/opto/type.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -1115,7 +1115,7 @@
//------------------------------widen------------------------------------------
// Only happens for optimistic top-down optimizations.
-const Type *TypeInt::widen( const Type *old ) const {
+const Type *TypeInt::widen( const Type *old, const Type* limit ) const {
// Coming from TOP or such; no widening
if( old->base() != Int ) return this;
const TypeInt *ot = old->is_int();
@@ -1134,15 +1134,21 @@
// Now widen new guy.
// Check for widening too far
if (_widen == WidenMax) {
- if (min_jint < _lo && _hi < max_jint) {
+ int max = max_jint;
+ int min = min_jint;
+ if (limit->isa_int()) {
+ max = limit->is_int()->_hi;
+ min = limit->is_int()->_lo;
+ }
+ if (min < _lo && _hi < max) {
// If neither endpoint is extremal yet, push out the endpoint
// which is closer to its respective limit.
if (_lo >= 0 || // easy common case
- (juint)(_lo - min_jint) >= (juint)(max_jint - _hi)) {
+ (juint)(_lo - min) >= (juint)(max - _hi)) {
// Try to widen to an unsigned range type of 31 bits:
- return make(_lo, max_jint, WidenMax);
+ return make(_lo, max, WidenMax);
} else {
- return make(min_jint, _hi, WidenMax);
+ return make(min, _hi, WidenMax);
}
}
return TypeInt::INT;
@@ -1357,7 +1363,7 @@
//------------------------------widen------------------------------------------
// Only happens for optimistic top-down optimizations.
-const Type *TypeLong::widen( const Type *old ) const {
+const Type *TypeLong::widen( const Type *old, const Type* limit ) const {
// Coming from TOP or such; no widening
if( old->base() != Long ) return this;
const TypeLong *ot = old->is_long();
@@ -1376,18 +1382,24 @@
// Now widen new guy.
// Check for widening too far
if (_widen == WidenMax) {
- if (min_jlong < _lo && _hi < max_jlong) {
+ jlong max = max_jlong;
+ jlong min = min_jlong;
+ if (limit->isa_long()) {
+ max = limit->is_long()->_hi;
+ min = limit->is_long()->_lo;
+ }
+ if (min < _lo && _hi < max) {
// If neither endpoint is extremal yet, push out the endpoint
// which is closer to its respective limit.
if (_lo >= 0 || // easy common case
- (julong)(_lo - min_jlong) >= (julong)(max_jlong - _hi)) {
+ (julong)(_lo - min) >= (julong)(max - _hi)) {
// Try to widen to an unsigned range type of 32/63 bits:
- if (_hi < max_juint)
+ if (max >= max_juint && _hi < max_juint)
return make(_lo, max_juint, WidenMax);
else
- return make(_lo, max_jlong, WidenMax);
+ return make(_lo, max, WidenMax);
} else {
- return make(min_jlong, _hi, WidenMax);
+ return make(min, _hi, WidenMax);
}
}
return TypeLong::LONG;
--- a/hotspot/src/share/vm/opto/type.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -168,7 +168,7 @@
// MEET operation; lower in lattice.
const Type *meet( const Type *t ) const;
// WIDEN: 'widens' for Ints and other range types
- virtual const Type *widen( const Type *old ) const { return this; }
+ virtual const Type *widen( const Type *old, const Type* limit ) const { return this; }
// NARROW: complement for widen, used by pessimistic phases
virtual const Type *narrow( const Type *old ) const { return this; }
@@ -409,7 +409,7 @@
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
- virtual const Type *widen( const Type *t ) const;
+ virtual const Type *widen( const Type *t, const Type* limit_type ) const;
virtual const Type *narrow( const Type *t ) const;
// Do not kill _widen bits.
virtual const Type *filter( const Type *kills ) const;
@@ -465,7 +465,7 @@
virtual const Type *xmeet( const Type *t ) const;
virtual const Type *xdual() const; // Compute dual right now.
- virtual const Type *widen( const Type *t ) const;
+ virtual const Type *widen( const Type *t, const Type* limit_type ) const;
virtual const Type *narrow( const Type *t ) const;
// Do not kill _widen bits.
virtual const Type *filter( const Type *kills ) const;
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -1229,6 +1229,7 @@
}
}
+#ifndef ZERO
#ifdef _LP64
// Check that UseCompressedOops can be set with the max heap size allocated
// by ergonomics.
@@ -1254,6 +1255,7 @@
// Also checks that certain machines are slower with compressed oops
// in vm_version initialization code.
#endif // _LP64
+#endif // !ZERO
}
void Arguments::set_parallel_gc_flags() {
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -47,7 +47,6 @@
define_pd_global(intx, OnStackReplacePercentage, 0);
define_pd_global(bool, ResizeTLAB, false);
define_pd_global(intx, FreqInlineSize, 0);
-define_pd_global(intx, InlineSmallCode, 0);
define_pd_global(intx, NewSizeThreadIncrease, 4*K);
define_pd_global(intx, NewRatio, 4);
define_pd_global(intx, InlineClassNatives, true);
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -99,6 +99,8 @@
class JNIHandleBlock : public CHeapObj {
friend class VMStructs;
+ friend class CppInterpreter;
+
private:
enum SomeConstants {
block_size_in_oops = 32 // Number of handles per handle block
@@ -126,9 +128,11 @@
// Fill block with bad_handle values
void zap();
+ protected:
// No more handles in the both the current and following blocks
void clear() { _top = 0; }
+ private:
// Free list computation
void rebuild_free_list();
--- a/hotspot/src/share/vm/runtime/mutex.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/mutex.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -61,18 +61,10 @@
} ;
// Endian-ness ... index of least-significant byte in SplitWord.Bytes[]
-#ifdef AMD64 // little
- #define _LSBINDEX 0
-#else
-#if IA32 // little
+#ifdef VM_LITTLE_ENDIAN
#define _LSBINDEX 0
#else
-#ifdef SPARC // big
#define _LSBINDEX (sizeof(intptr_t)-1)
-#else
- #error "unknown architecture"
-#endif
-#endif
#endif
class ParkEvent ;
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -81,6 +81,14 @@
jlong safepoint_limit_time;
timeout_error_printed = false;
+ // PrintSafepointStatisticsTimeout can be specified separately. When
+ // specified, PrintSafepointStatistics will be set to true in
+ // deferred_initialize_stat method. The initialization has to be done
+ // early enough to avoid any races. See bug 6880029 for details.
+ if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0) {
+ deferred_initialize_stat();
+ }
+
// Begin the process of bringing the system to a safepoint.
// Java threads can be in several different states and are
// stopped by different mechanisms:
@@ -169,8 +177,7 @@
}
}
- if ( (PrintSafepointStatistics || (PrintSafepointStatisticsTimeout > 0))
- && iterations == 0) {
+ if (PrintSafepointStatistics && iterations == 0) {
begin_statistics(nof_threads, still_running);
}
@@ -1026,8 +1033,7 @@
}
void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) {
- deferred_initialize_stat();
-
+ assert(init_done, "safepoint statistics array hasn't been initialized");
SafepointStats *spstat = &_safepoint_stats[_cur_stat_index];
VM_Operation *op = VMThread::vm_operation();
--- a/hotspot/src/share/vm/runtime/signature.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/signature.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -275,11 +275,14 @@
void do_bool () { pass_int(); _jni_offset++; _offset++; }
void do_char () { pass_int(); _jni_offset++; _offset++; }
+#if defined(_LP64) || defined(ZERO)
+ void do_float () { pass_float(); _jni_offset++; _offset++; }
+#else
+ void do_float () { pass_int(); _jni_offset++; _offset++; }
+#endif
#ifdef _LP64
- void do_float () { pass_float(); _jni_offset++; _offset++; }
void do_double() { pass_double(); _jni_offset++; _offset += 2; }
#else
- void do_float () { pass_int(); _jni_offset++; _offset++; }
void do_double() { pass_double(); _jni_offset += 2; _offset += 2; }
#endif
void do_byte () { pass_int(); _jni_offset++; _offset++; }
@@ -303,8 +306,10 @@
virtual void pass_int() = 0;
virtual void pass_long() = 0;
virtual void pass_object() = 0;
+#if defined(_LP64) || defined(ZERO)
+ virtual void pass_float() = 0;
+#endif
#ifdef _LP64
- virtual void pass_float() = 0;
virtual void pass_double() = 0;
#else
virtual void pass_double() { pass_long(); } // may be same as long
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -1213,6 +1213,7 @@
{
initialize();
_is_attaching = is_attaching;
+ assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
}
bool JavaThread::reguard_stack(address cur_sp) {
@@ -2318,6 +2319,10 @@
void JavaThread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
+ // Flush deferred store-barriers, if any, associated with
+ // initializing stores done by this JavaThread in the current epoch.
+ Universe::heap()->flush_deferred_store_barrier(this);
+
// The ThreadProfiler oops_do is done from FlatProfiler::oops_do
// since there may be more than one thread using each ThreadProfiler.
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -684,8 +684,13 @@
methodOop _callee_target;
// Oop results of VM runtime calls
- oop _vm_result; // Used to pass back an oop result into Java code, GC-preserved
- oop _vm_result_2; // Used to pass back an oop result into Java code, GC-preserved
+ oop _vm_result; // Used to pass back an oop result into Java code, GC-preserved
+ oop _vm_result_2; // Used to pass back an oop result into Java code, GC-preserved
+
+ // See ReduceInitialCardMarks: this holds the precise space interval of
+ // the most recent slow path allocation for which compiled code has
+ // elided card-marks for performance along the fast-path.
+ MemRegion _deferred_card_mark;
MonitorChunk* _monitor_chunks; // Contains the off stack monitors
// allocated during deoptimization
@@ -1082,6 +1087,9 @@
oop vm_result_2() const { return _vm_result_2; }
void set_vm_result_2 (oop x) { _vm_result_2 = x; }
+ MemRegion deferred_card_mark() const { return _deferred_card_mark; }
+ void set_deferred_card_mark(MemRegion mr) { _deferred_card_mark = mr; }
+
// Exception handling for compiled methods
oop exception_oop() const { return _exception_oop; }
int exception_stack_size() const { return _exception_stack_size; }
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -93,9 +93,13 @@
#else // KERNEL
#ifdef TIERED
#define VMTYPE "Server"
-#else
- #define VMTYPE COMPILER1_PRESENT("Client") \
- COMPILER2_PRESENT("Server")
+#else // TIERED
+#ifdef ZERO
+ #define VMTYPE "Zero"
+#else // ZERO
+ #define VMTYPE COMPILER1_PRESENT("Client") \
+ COMPILER2_PRESENT("Server")
+#endif // ZERO
#endif // TIERED
#endif // KERNEL
@@ -142,10 +146,14 @@
WINDOWS_ONLY("windows") \
SOLARIS_ONLY("solaris")
+#ifdef ZERO
+#define CPU ZERO_LIBARCH
+#else
#define CPU IA32_ONLY("x86") \
IA64_ONLY("ia64") \
AMD64_ONLY("amd64") \
SPARC_ONLY("sparc")
+#endif // ZERO
const char *Abstract_VM_Version::vm_platform_string() {
return OS "-" CPU;
--- a/hotspot/src/share/vm/utilities/exceptions.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -103,15 +103,18 @@
_throw(thread, file, line, h_exception);
}
-void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception) {
+void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
assert(h_exception() != NULL, "exception should not be NULL");
// tracing (do this up front - so it works during boot strapping)
if (TraceExceptions) {
ttyLocker ttyl;
ResourceMark rm;
- tty->print_cr("Exception <%s> (" INTPTR_FORMAT " ) \nthrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
- h_exception->print_value_string(), (address)h_exception(), file, line, thread);
+ tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n"
+ "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
+ h_exception->print_value_string(),
+ message ? ": " : "", message ? message : "",
+ (address)h_exception(), file, line, thread);
}
// for AbortVMOnException flag
NOT_PRODUCT(Exceptions::debug_check_abort(h_exception));
@@ -135,7 +138,7 @@
// Create and throw exception
Handle h_cause(thread, NULL);
Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
- _throw(thread, file, line, h_exception);
+ _throw(thread, file, line, h_exception, message);
}
// Throw an exception with a message and a cause
@@ -144,7 +147,7 @@
if (special_exception(thread, file, line, h_name, message)) return;
// Create and throw exception and init cause
Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
- _throw(thread, file, line, h_exception);
+ _throw(thread, file, line, h_exception, message);
}
// This version creates handles and calls the other version
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -103,7 +103,7 @@
} ExceptionMsgToUtf8Mode;
// Throw exceptions: w/o message, w/ message & with formatted message.
static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
- static void _throw(Thread* thread, const char* file, int line, Handle exception);
+ static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL);
static void _throw_msg(Thread* thread, const char* file, int line,
symbolHandle name, const char* message, Handle loader,
Handle protection_domain);
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp Wed Jul 05 17:02:18 2017 +0200
@@ -207,7 +207,7 @@
// Actually means 0, so do the push.
uint localBot = _bottom;
_elems[localBot] = t;
- _bottom = increment_index(localBot);
+ OrderAccess::release_store(&_bottom, increment_index(localBot));
return true;
}
return false;
@@ -465,19 +465,7 @@
#endif
};
-#define SIMPLE_STACK 0
-
template<class E> inline bool GenericTaskQueue<E>::push(E t) {
-#if SIMPLE_STACK
- uint localBot = _bottom;
- if (_bottom < max_elems()) {
- _elems[localBot] = t;
- _bottom = localBot + 1;
- return true;
- } else {
- return false;
- }
-#else
uint localBot = _bottom;
assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
idx_t top = _age.top();
@@ -485,23 +473,14 @@
assert((dirty_n_elems >= 0) && (dirty_n_elems < N), "n_elems out of range.");
if (dirty_n_elems < max_elems()) {
_elems[localBot] = t;
- _bottom = increment_index(localBot);
+ OrderAccess::release_store(&_bottom, increment_index(localBot));
return true;
} else {
return push_slow(t, dirty_n_elems);
}
-#endif
}
template<class E> inline bool GenericTaskQueue<E>::pop_local(E& t) {
-#if SIMPLE_STACK
- uint localBot = _bottom;
- assert(localBot > 0, "precondition.");
- localBot--;
- t = _elems[localBot];
- _bottom = localBot;
- return true;
-#else
uint localBot = _bottom;
// This value cannot be N-1. That can only occur as a result of
// the assignment to bottom in this method. If it does, this method
@@ -529,7 +508,6 @@
// path.
return pop_local_slow(localBot, _age.get());
}
-#endif
}
typedef oop Task;
--- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 17:02:18 2017 +0200
@@ -458,6 +458,40 @@
if (_verbose && _thread && _thread->is_Java_thread()) {
JavaThread* jt = (JavaThread*)_thread;
+#ifdef ZERO
+ if (jt->zero_stack()->sp() && jt->top_zero_frame()) {
+ // StackFrameStream uses the frame anchor, which may not have
+ // been set up. This can be done at any time in Zero, however,
+ // so if it hasn't been set up then we just set it up now and
+ // clear it again when we're done.
+ bool has_last_Java_frame = jt->has_last_Java_frame();
+ if (!has_last_Java_frame)
+ jt->set_last_Java_frame();
+ st->print("Java frames:");
+
+ // If the top frame is a Shark frame and the frame anchor isn't
+ // set up then it's possible that the information in the frame
+ // is garbage: it could be from a previous decache, or it could
+ // simply have never been written. So we print a warning...
+ StackFrameStream sfs(jt);
+ if (!has_last_Java_frame && !sfs.is_done()) {
+ if (sfs.current()->zeroframe()->is_shark_frame()) {
+ st->print(" (TOP FRAME MAY BE JUNK)");
+ }
+ }
+ st->cr();
+
+ // Print the frames
+ for(int i = 0; !sfs.is_done(); sfs.next(), i++) {
+ sfs.current()->zero_print_on_error(i, st, buf, sizeof(buf));
+ st->cr();
+ }
+
+ // Reset the frame anchor if necessary
+ if (!has_last_Java_frame)
+ jt->reset_last_Java_frame();
+ }
+#else
if (jt->has_last_Java_frame()) {
st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)");
for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) {
@@ -465,6 +499,7 @@
st->cr();
}
}
+#endif // ZERO
}
STEP(140, "(printing VM operation)" )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6879902/Test6879902.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/**
+ * @test
+ * @bug 6879902
+ * @summary CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845
+ *
+ * @run main Test6879902
+ */
+
+import java.util.Arrays;
+
+public class Test6879902 {
+ public static void main(String[] args) {
+ Object[] oa = new Object[250];
+ for (int i = 0; i < 250; i++) {
+ oa[i] = Integer.valueOf(i);
+ }
+ Object[] oa2 = createArray(oa[0], oa[1], oa[2], oa[3], oa[4], oa[5], oa[6], oa[7], oa[8], oa[9], oa[10], oa[11], oa[12], oa[13], oa[14], oa[15], oa[16], oa[17], oa[18], oa[19], oa[20], oa[21], oa[22], oa[23], oa[24], oa[25], oa[26], oa[27], oa[28], oa[29], oa[30], oa[31], oa[32], oa[33], oa[34], oa[35], oa[36], oa[37], oa[38], oa[39], oa[40], oa[41], oa[42], oa[43], oa[44], oa[45], oa[46], oa[47], oa[48], oa[49], oa[50], oa[51], oa[52], oa[53], oa[54], oa[55], oa[56], oa[57], oa[58], oa[59], oa[60], oa[61], oa[62], oa[63], oa[64], oa[65], oa[66], oa[67], oa[68], oa[69], oa[70], oa[71], oa[72], oa[73], oa[74], oa[75], oa[76], oa[77], oa[78], oa[79], oa[80], oa[81], oa[82], oa[83], oa[84], oa[85], oa[86], oa[87], oa[88], oa[89], oa[90], oa[91], oa[92], oa[93], oa[94], oa[95], oa[96], oa[97], oa[98], oa[99], oa[100], oa[101], oa[102], oa[103], oa[104], oa[105], oa[106], oa[107], oa[108], oa[109], oa[110], oa[111], oa[112], oa[113], oa[114], oa[115], oa[116], oa[117], oa[118], oa[119], oa[120], oa[121], oa[122], oa[123], oa[124], oa[125], oa[126], oa[127], oa[128], oa[129], oa[130], oa[131], oa[132], oa[133], oa[134], oa[135], oa[136], oa[137], oa[138], oa[139], oa[140], oa[141], oa[142], oa[143], oa[144], oa[145], oa[146], oa[147], oa[148], oa[149], oa[150], oa[151], oa[152], oa[153], oa[154], oa[155], oa[156], oa[157], oa[158], oa[159], oa[160], oa[161], oa[162], oa[163], oa[164], oa[165], oa[166], oa[167], oa[168], oa[169], oa[170], oa[171], oa[172], oa[173], oa[174], oa[175], oa[176], oa[177], oa[178], oa[179], oa[180], oa[181], oa[182], oa[183], oa[184], oa[185], oa[186], oa[187], oa[188], oa[189], oa[190], oa[191], oa[192], oa[193], oa[194], oa[195], oa[196], oa[197], oa[198], oa[199], oa[200], oa[201], oa[202], oa[203], oa[204], oa[205], oa[206], oa[207], oa[208], oa[209], oa[210], oa[211], oa[212], oa[213], oa[214], oa[215], oa[216], oa[217], oa[218], oa[219], oa[220], oa[221], oa[222], oa[223], oa[224], oa[225], oa[226], oa[227], oa[228], oa[229], oa[230], oa[231], oa[232], oa[233], oa[234], oa[235], oa[236], oa[237], oa[238], oa[239], oa[240], oa[241], oa[242], oa[243], oa[244], oa[245], oa[246], oa[247], oa[248], oa[249]);
+ if (!Arrays.equals(oa, oa2))
+ throw new InternalError("arrays not equal");
+ }
+
+ public static Object[] createArray(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20, Object arg21, Object arg22, Object arg23, Object arg24, Object arg25, Object arg26, Object arg27, Object arg28, Object arg29, Object arg30, Object arg31, Object arg32, Object arg33, Object arg34, Object arg35, Object arg36, Object arg37, Object arg38, Object arg39, Object arg40, Object arg41, Object arg42, Object arg43, Object arg44, Object arg45, Object arg46, Object arg47, Object arg48, Object arg49, Object arg50, Object arg51, Object arg52, Object arg53, Object arg54, Object arg55, Object arg56, Object arg57, Object arg58, Object arg59, Object arg60, Object arg61, Object arg62, Object arg63, Object arg64, Object arg65, Object arg66, Object arg67, Object arg68, Object arg69, Object arg70, Object arg71, Object arg72, Object arg73, Object arg74, Object arg75, Object arg76, Object arg77, Object arg78, Object arg79, Object arg80, Object arg81, Object arg82, Object arg83, Object arg84, Object arg85, Object arg86, Object arg87, Object arg88, Object arg89, Object arg90, Object arg91, Object arg92, Object arg93, Object arg94, Object arg95, Object arg96, Object arg97, Object arg98, Object arg99, Object arg100, Object arg101, Object arg102, Object arg103, Object arg104, Object arg105, Object arg106, Object arg107, Object arg108, Object arg109, Object arg110, Object arg111, Object arg112, Object arg113, Object arg114, Object arg115, Object arg116, Object arg117, Object arg118, Object arg119, Object arg120, Object arg121, Object arg122, Object arg123, Object arg124, Object arg125, Object arg126, Object arg127, Object arg128, Object arg129, Object arg130, Object arg131, Object arg132, Object arg133, Object arg134, Object arg135, Object arg136, Object arg137, Object arg138, Object arg139, Object arg140, Object arg141, Object arg142, Object arg143, Object arg144, Object arg145, Object arg146, Object arg147, Object arg148, Object arg149, Object arg150, Object arg151, Object arg152, Object arg153, Object arg154, Object arg155, Object arg156, Object arg157, Object arg158, Object arg159, Object arg160, Object arg161, Object arg162, Object arg163, Object arg164, Object arg165, Object arg166, Object arg167, Object arg168, Object arg169, Object arg170, Object arg171, Object arg172, Object arg173, Object arg174, Object arg175, Object arg176, Object arg177, Object arg178, Object arg179, Object arg180, Object arg181, Object arg182, Object arg183, Object arg184, Object arg185, Object arg186, Object arg187, Object arg188, Object arg189, Object arg190, Object arg191, Object arg192, Object arg193, Object arg194, Object arg195, Object arg196, Object arg197, Object arg198, Object arg199, Object arg200, Object arg201, Object arg202, Object arg203, Object arg204, Object arg205, Object arg206, Object arg207, Object arg208, Object arg209, Object arg210, Object arg211, Object arg212, Object arg213, Object arg214, Object arg215, Object arg216, Object arg217, Object arg218, Object arg219, Object arg220, Object arg221, Object arg222, Object arg223, Object arg224, Object arg225, Object arg226, Object arg227, Object arg228, Object arg229, Object arg230, Object arg231, Object arg232, Object arg233, Object arg234, Object arg235, Object arg236, Object arg237, Object arg238, Object arg239, Object arg240, Object arg241, Object arg242, Object arg243, Object arg244, Object arg245, Object arg246, Object arg247, Object arg248, Object arg249) {
+ return new Object[]{
+ arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30, arg31, arg32, arg33, arg34, arg35, arg36, arg37, arg38, arg39, arg40, arg41, arg42, arg43, arg44, arg45, arg46, arg47, arg48, arg49, arg50, arg51, arg52, arg53, arg54, arg55, arg56, arg57, arg58, arg59, arg60, arg61, arg62, arg63, arg64, arg65, arg66, arg67, arg68, arg69, arg70, arg71, arg72, arg73, arg74, arg75, arg76, arg77, arg78, arg79, arg80, arg81, arg82, arg83, arg84, arg85, arg86, arg87, arg88, arg89, arg90, arg91, arg92, arg93, arg94, arg95, arg96, arg97, arg98, arg99, arg100, arg101, arg102, arg103, arg104, arg105, arg106, arg107, arg108, arg109, arg110, arg111, arg112, arg113, arg114, arg115, arg116, arg117, arg118, arg119, arg120, arg121, arg122, arg123, arg124, arg125, arg126, arg127, arg128, arg129, arg130, arg131, arg132, arg133, arg134, arg135, arg136, arg137, arg138, arg139, arg140, arg141, arg142, arg143, arg144, arg145, arg146, arg147, arg148, arg149, arg150, arg151, arg152, arg153, arg154, arg155, arg156, arg157, arg158, arg159, arg160, arg161, arg162, arg163, arg164, arg165, arg166, arg167, arg168, arg169, arg170, arg171, arg172, arg173, arg174, arg175, arg176, arg177, arg178, arg179, arg180, arg181, arg182, arg183, arg184, arg185, arg186, arg187, arg188, arg189, arg190, arg191, arg192, arg193, arg194, arg195, arg196, arg197, arg198, arg199, arg200, arg201, arg202, arg203, arg204, arg205, arg206, arg207, arg208, arg209, arg210, arg211, arg212, arg213, arg214, arg215, arg216, arg217, arg218, arg219, arg220, arg221, arg222, arg223, arg224, arg225, arg226, arg227, arg228, arg229, arg230, arg231, arg232, arg233, arg234, arg235, arg236, arg237, arg238, arg239, arg240, arg241, arg242, arg243, arg244, arg245, arg246, arg247, arg248, arg249};
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6880034/Test6880034.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2009 SAP AG. 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.
+ */
+
+/**
+ * @test
+ * @bug 6880034
+ * @summary SIGBUS during deoptimisation at a safepoint on 64bit-SPARC
+ *
+ * @run main/othervm -Xcomp -Xbatch -XX:CompileCommand=compileonly,Test6880034,deopt_compiledframe_at_safepoint -XX:+PrintCompilation Test6880034
+ */
+
+
+
+// This test provokes a deoptimisation at a safepoint.
+//
+// It achieves this by compiling the method 'deopt_compiledframe_at_safepoint'
+// before its first usage at a point in time when a call to the virtual method
+// A::doSomething() from within 'deopt_compiledframe_at_safepoint' can be
+// optimised to a static call because class A has no descendants.
+//
+// Later, when deopt_compiledframe_at_safepoint() is running, class B which
+// extends A and overrides the virtual method "doSomething()", is loaded
+// asynchronously in another thread. This makes the compiled code of
+// 'deopt_compiledframe_at_safepoint' invalid and triggers a deoptimisation of
+// the frame where 'deopt_compiledframe_at_safepoint' is running in a
+// loop.
+//
+// The deoptimisation leads to a SIGBUS on 64-bit server VMs on SPARC and to
+// an incorrect result on 32-bit server VMs on SPARC due to a regression
+// introduced by the change: "6420645: Create a vm that uses compressed oops
+// for up to 32gb heapsizes"
+// (http://hg.openjdk.java.net/jdk7/jdk7/hotspot/rev/ba764ed4b6f2). Further
+// investigation showed that change 6420645 is not really the root cause of
+// this error but only reveals a problem with the float register encodings in
+// sparc.ad which was hidden until now.
+//
+// Notice that for this test to fail in jtreg it is crucial that
+// deopt_compiledframe_at_safepoint() runs in the main thread. Otherwise a
+// crash in deopt_compiledframe_at_safepoint() will not be detected as a test
+// failure by jtreg.
+//
+// Author: Volker H. Simonis
+
+class A {
+ public int doSomething() {
+ return 0;
+ }
+}
+
+class B extends A {
+ public B() {}
+ // override 'A::doSomething()'
+ public int doSomething() {
+ return 1;
+ }
+}
+
+class G {
+ public static volatile A a = new A();
+
+ // Change 'a' to point to a 'B' object
+ public static void setAtoB() {
+ try {
+ a = (A) ClassLoader.
+ getSystemClassLoader().
+ loadClass("B").
+ getConstructor(new Class[] {}).
+ newInstance(new Object[] {});
+ }
+ catch (Exception e) {
+ System.out.println(e);
+ }
+ }
+}
+
+public class Test6880034 {
+
+ public static volatile boolean is_in_loop = false;
+ public static volatile boolean stop_while_loop = false;
+
+ public static double deopt_compiledframe_at_safepoint() {
+ // This will be an optimised static call to A::doSomething() until we load "B"
+ int i = G.a.doSomething();
+
+ // Need more than 16 'double' locals in this frame
+ double local1 = 1;
+ double local2 = 2;
+ double local3 = 3;
+ double local4 = 4;
+ double local5 = 5;
+ double local6 = 6;
+ double local7 = 7;
+ double local8 = 8;
+
+ long k = 0;
+ // Once we load "B", this method will be made 'not entrant' and deoptimised
+ // at the safepoint which is at the end of this loop.
+ while (!stop_while_loop) {
+ if (k == 1) local1 += i;
+ if (k == 2) local2 += i;
+ if (k == 3) local3 += i;
+ if (k == 4) local4 += i;
+ if (k == 5) local5 += i;
+ if (k == 6) local6 += i;
+ if (k == 7) local7 += i;
+ if (k == 8) local8 += i;
+
+ // Tell the world that we're now running wild in the loop
+ if (k++ == 20000) is_in_loop = true;
+ }
+
+ return
+ local1 + local2 + local3 + local4 +
+ local5 + local6 + local7 + local8 + i;
+ }
+
+ public static void main(String[] args) {
+
+ // Just to resolve G before we compile deopt_compiledframe_at_safepoint()
+ G g = new G();
+
+ // Asynchronous thread which will eventually invalidate the code for
+ // deopt_compiledframe_at_safepoint() and therefore triggering a
+ // deoptimisation of that method.
+ new Thread() {
+ public void run() {
+ while (!is_in_loop) {
+ // Wait until the loop is running
+ }
+ // Load class 'B' asynchronously..
+ G.setAtoB();
+ // ..and stop the loop
+ stop_while_loop = true;
+ }
+ }.start();
+
+ // Run the loop in deopt_compiledframe_at_safepoint()
+ double retVal = deopt_compiledframe_at_safepoint();
+
+ System.out.println(retVal == 36 ? "OK" : "ERROR : " + retVal);
+ if (retVal != 36) throw new RuntimeException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6885584/Test6885584.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2009 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.
+ *
+ */
+
+/**
+ * @test
+ * @bug 6885584
+ * @summary A particular class structure causes large allocation spike for jit
+ *
+ * @run main/othervm -Xbatch Test6885584
+ */
+
+
+
+public class Test6885584 {
+ static private int i1;
+ static private int i2;
+ static private int i3;
+
+ static int limit = Integer.MAX_VALUE - 8;
+
+ public static void main(String args[]) {
+ // Run long enough to trigger an OSR
+ for(int j = 200000; j != 0; j--) {
+ }
+
+ // This must reference a field
+ i1 = i2;
+
+ // The resource leak is roughly proportional to this initial value
+ for(int k = Integer.MAX_VALUE - 1; k != 0; k--) {
+ // Make sure the body does some work
+ if(i2 > i3)i1 = k;
+ if (k <= limit) break;
+ }
+ }
+
+}
--- a/hotspot/test/gc/6845368/bigobj.java Thu Oct 15 16:40:16 2009 -0700
+++ b/hotspot/test/gc/6845368/bigobj.java Wed Jul 05 17:02:18 2017 +0200
@@ -3,7 +3,7 @@
@bug 6845368
@summary ensure gc updates references > 64K bytes from the start of the obj
@author John Coomes
- @run main/othervm -Xmx64m bigobj
+ @run main/othervm/timeout=720 -Xmx64m bigobj
*/
// Allocate an object with a block of reference fields that starts more
--- a/jdk/.hgtags Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/.hgtags Wed Jul 05 17:02:18 2017 +0200
@@ -48,3 +48,4 @@
b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71
460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
f708138c9aca4b389872838fe6773872fce3609e jdk7-b73
+eacb36e30327e7ae33baa068e82ddccbd91eaae2 jdk7-b74
--- a/jdk/make/common/shared/Defs-java.gmk Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/make/common/shared/Defs-java.gmk Wed Jul 05 17:02:18 2017 +0200
@@ -165,11 +165,6 @@
JAVADOC_CMD = $(JAVA_TOOLS_DIR)/javadoc $(JAVA_TOOLS_FLAGS:%=-J%)
endif
-#always use the bootstrap javah until bug-ID 6889255 is fixed. These
-#five lines should be removed as part of that fix:
-JAVAH_CMD = $(JAVA_TOOLS_DIR)/javah \
- $(JAVAHFLAGS)
-
# Override of what javac to use (see deploy workspace)
ifdef JAVAC
JAVAC_CMD = $(JAVAC)
--- a/jdk/make/java/java/FILES_java.gmk Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/make/java/java/FILES_java.gmk Wed Jul 05 17:02:18 2017 +0200
@@ -258,6 +258,7 @@
java/util/ServiceConfigurationError.java \
java/util/Timer.java \
java/util/TimerTask.java \
+ java/util/Objects.java \
java/util/UUID.java \
java/util/concurrent/AbstractExecutorService.java \
java/util/concurrent/ArrayBlockingQueue.java \
--- a/jdk/make/java/redist/Makefile Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/make/java/redist/Makefile Wed Jul 05 17:02:18 2017 +0200
@@ -211,7 +211,7 @@
$(LIB_LOCATION)/$(KERNEL_LOCATION)/$(JVM_NAME): $(HOTSPOT_KERNEL_PATH)/$(JVM_NAME)
$(install-file)
-$(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_SERVER_PATH)/$(LIBJSIG_NAME)
+$(LIB_LOCATION)/$(LIBJSIG_NAME): $(HOTSPOT_IMPORT_PATH)/$(ARCH_VM_SUBDIR)/$(LIBJSIG_NAME)
$(install-import-file)
$(LIB_LOCATION)/$(CLIENT_LOCATION)/$(LIBJSIG_NAME) \
--- a/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/com/sun/naming/internal/ResourceManager.java Wed Jul 05 17:02:18 2017 +0200
@@ -25,11 +25,12 @@
package com.sun.naming.internal;
-import java.applet.Applet;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
@@ -112,6 +113,52 @@
private static final WeakHashMap urlFactoryCache = new WeakHashMap(11);
private static final WeakReference NO_FACTORY = new WeakReference(null);
+ /**
+ * A class to allow JNDI properties be specified as applet parameters
+ * without creating a static dependency on java.applet.
+ */
+ private static class AppletParameter {
+ private static final Class<?> clazz = getClass("java.applet.Applet");
+ private static final Method getMethod =
+ getMethod(clazz, "getParameter", String.class);
+ private static Class<?> getClass(String name) {
+ try {
+ return Class.forName(name, true, null);
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
+ private static Method getMethod(Class<?> clazz,
+ String name,
+ Class<?>... paramTypes)
+ {
+ if (clazz != null) {
+ try {
+ return clazz.getMethod(name, paramTypes);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value of the applet's named parameter.
+ */
+ static Object get(Object applet, String name) {
+ // if clazz is null then applet cannot be an Applet.
+ if (clazz == null || !clazz.isInstance(applet))
+ throw new ClassCastException(applet.getClass().getName());
+ try {
+ return getMethod.invoke(applet, name);
+ } catch (InvocationTargetException e) {
+ throw new AssertionError(e);
+ } catch (IllegalAccessException iae) {
+ throw new AssertionError(iae);
+ }
+ }
+ }
// There should be no instances of this class.
private ResourceManager() {
@@ -143,7 +190,7 @@
if (env == null) {
env = new Hashtable(11);
}
- Applet applet = (Applet)env.get(Context.APPLET);
+ Object applet = env.get(Context.APPLET);
// Merge property values from env param, applet params, and system
// properties. The first value wins: there's no concatenation of
@@ -157,7 +204,7 @@
Object val = env.get(props[i]);
if (val == null) {
if (applet != null) {
- val = applet.getParameter(props[i]);
+ val = AppletParameter.get(applet, props[i]);
}
if (val == null) {
// Read system property.
--- a/jdk/src/share/classes/java/io/FilePermission.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/java/io/FilePermission.java Wed Jul 05 17:02:18 2017 +0200
@@ -209,7 +209,17 @@
cpath = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
try {
- return sun.security.provider.PolicyFile.canonPath(cpath);
+ String path = cpath;
+ if (cpath.endsWith("*")) {
+ // call getCanonicalPath with a path with wildcard character
+ // replaced to avoid calling it with paths that are
+ // intended to match all entries in a directory
+ path = path.substring(0, path.length()-1) + "-";
+ path = new File(path).getCanonicalPath();
+ return path.substring(0, path.length()-1) + "*";
+ } else {
+ return new File(path).getCanonicalPath();
+ }
} catch (IOException ioe) {
return cpath;
}
--- a/jdk/src/share/classes/java/lang/Enum.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/java/lang/Enum.java Wed Jul 05 17:02:18 2017 +0200
@@ -40,10 +40,17 @@
* Edition</i>, <a
* href="http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.9">§8.9</a>.
*
+ * <p> Note that when using an enumeration type as the type of a set
+ * or as the type of the keys in a map, specialized and efficient
+ * {@linkplain java.util.EnumSet set} and {@linkplain
+ * java.util.EnumMap map} implementations are available.
+ *
* @param <E> The enum type subclass
* @author Josh Bloch
* @author Neal Gafter
* @see Class#getEnumConstants()
+ * @see java.util.EnumSet
+ * @see java.util.EnumMap
* @since 1.5
*/
public abstract class Enum<E extends Enum<E>>
--- a/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/java/lang/reflect/AccessibleObject.java Wed Jul 05 17:02:18 2017 +0200
@@ -44,6 +44,8 @@
* as Java Object Serialization or other persistence mechanisms, to
* manipulate objects in a manner that would normally be prohibited.
*
+ * <p>By default, a reflected object is <em>not</em> accessible.
+ *
* @see Field
* @see Method
* @see Constructor
--- a/jdk/src/share/classes/java/nio/file/Path.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/java/nio/file/Path.java Wed Jul 05 17:02:18 2017 +0200
@@ -412,7 +412,7 @@
* dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}.
*
* @param other
- * the resulting path
+ * the path to relativize against this path
*
* @return the resulting relative path, or {@code null} if both paths are
* equal
@@ -1615,23 +1615,23 @@
* Tests if the file referenced by this object is the same file referenced
* by another object.
*
- * <p> If this {@code FileRef} and the given {@code FileRef} are {@link
+ * <p> If this {@code Path} and the given {@code Path} are {@link
* #equals(Object) equal} then this method returns {@code true} without checking
- * if the file exists. If the {@code FileRef} and the given {@code FileRef}
- * are associated with different providers, or the given {@code FileRef} is
+ * if the file exists. If the {@code Path} and the given {@code Path}
+ * are associated with different providers, or the given {@code Path} is
* {@code null} then this method returns {@code false}. Otherwise, this method
- * checks if both {@code FileRefs} locate the same file, and depending on the
+ * checks if both {@code Paths} locate the same file, and depending on the
* implementation, may require to open or access both files.
*
* <p> If the file system and files remain static, then this method implements
- * an equivalence relation for non-null {@code FileRefs}.
+ * an equivalence relation for non-null {@code Paths}.
* <ul>
- * <li>It is <i>reflexive</i>: for a non-null {@code FileRef} {@code f},
+ * <li>It is <i>reflexive</i>: for a non-null {@code Path} {@code f},
* {@code f.isSameFile(f)} should return {@code true}.
- * <li>It is <i>symmetric</i>: for two non-null {@code FileRefs}
+ * <li>It is <i>symmetric</i>: for two non-null {@code Path}
* {@code f} and {@code g}, {@code f.isSameFile(g)} will equal
* {@code g.isSameFile(f)}.
- * <li>It is <i>transitive</i>: for three {@code FileRefs}
+ * <li>It is <i>transitive</i>: for three {@code Paths}
* {@code f}, {@code g}, and {@code h}, if {@code f.isSameFile(g)} returns
* {@code true} and {@code g.isSameFile(h)} returns {@code true}, then
* {@code f.isSameFile(h)} will return return {@code true}.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/util/Objects.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2009 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package java.util;
+
+/**
+ * This class consists of {@code static} utility methods for operating
+ * on objects. These utilities include {@code null}-safe or {@code
+ * null}-tolerant methods for computing the hash code of an object,
+ * returning a string for an object, and comparing two objects.
+ *
+ * @since 1.7
+ */
+public class Objects {
+ private Objects() {
+ throw new AssertionError("No java.util.Objects instances for you!");
+ }
+
+ /**
+ * Returns {@code true} if the arguments are equal to each other
+ * and {@code false} otherwise.
+ * Consequently, if both arguments are {@code null}, {@code true}
+ * is returned and if exactly one argument is {@code null}, {@code
+ * false} is returned. Otherwise, equality is determined by using
+ * the {@link Object#equals equals} method of the first
+ * argument.
+ *
+ * @param a an object
+ * @param b an object to be compared with {@code a} for equality
+ * @return {@code true} if the arguments are equal to each other
+ * and {@code false} otherwise
+ * @see Object#equals(Object)
+ */
+ public static boolean equals(Object a, Object b) {
+ return (a == b) || (a != null && a.equals(b));
+ }
+
+ /**
+ * Returns the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument.
+ *
+ * @param o an object
+ * @return the hash code of a non-{@code null} argument and 0 for
+ * a {@code null} argument
+ * @see Object#hashCode
+ */
+ public static int hashCode(Object o) {
+ return o != null ? o.hashCode() : 0;
+ }
+
+ /**
+ * Returns the result of calling {@code toString} for a non-{@code
+ * null} argument and {@code "null"} for a {@code null} argument.
+ *
+ * @param o an object
+ * @return the result of calling {@code toString} for a non-{@code
+ * null} argument and {@code "null"} for a {@code null} argument
+ * @see Object#toString
+ * @see String#valueOf(Object)
+ */
+ public static String toString(Object o) {
+ return String.valueOf(o);
+ }
+
+ /**
+ * Returns 0 if the arguments are identical and {@code
+ * c.compare(a, b)} otherwise.
+ * Consequently, if both arguments are {@code null} 0
+ * is returned.
+ *
+ * <p>Note that if one of the arguments is {@code null}, a {@code
+ * NullPointerException} may or may not be thrown depending on
+ * what ordering policy, if any, the {@link Comparator Comparator}
+ * chooses to have for {@code null} values.
+ *
+ * @param <T> the type of the objects being compared
+ * @param a an object
+ * @param b an object to be compared with {@code a}
+ * @param c the {@code Comparator} to compare the first two arguments
+ * @return 0 if the arguments are identical and {@code
+ * c.compare(a, b)} otherwise.
+ * @see Comparable
+ * @see Comparator
+ */
+ public static <T> int compare(T a, T b, Comparator<? super T> c) {
+ return (a == b) ? 0 : c.compare(a, b);
+ }
+
+ /**
+ * Checks that the specified object reference is not {@code null}. This
+ * method is designed primarily for doing parameter validation in methods
+ * and constructors, as demonstrated below:
+ * <blockquote><pre>
+ * public Foo(Bar bar) {
+ * this.bar = Objects.nonNull(bar);
+ * }
+ * </pre></blockquote>
+ *
+ * @param obj the object reference to check for nullity
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static <T> T nonNull(T obj) {
+ if (obj == null)
+ throw new NullPointerException();
+ return obj;
+ }
+
+ /**
+ * Checks that the specified object reference is not {@code null} and
+ * throws a customized {@link NullPointerException} if it is. This method
+ * is designed primarily for doing parameter validation in methods and
+ * constructors with multiple parameters, as demonstrated below:
+ * <blockquote><pre>
+ * public Foo(Bar bar, Baz baz) {
+ * this.bar = Objects.nonNull(bar, "bar must not be null");
+ * this.baz = Objects.nonNull(baz, "baz must not be null");
+ * }
+ * </pre></blockquote>
+ *
+ * @param obj the object reference to check for nullity
+ * @param message detail message to be used in the event that a {@code
+ * NullPointerException} is thrown
+ * @param <T> the type of the reference
+ * @return {@code obj} if not {@code null}
+ * @throws NullPointerException if {@code obj} is {@code null}
+ */
+ public static <T> T nonNull(T obj, String message) {
+ if (obj == null)
+ throw new NullPointerException(message);
+ return obj;
+ }
+}
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Wed Jul 05 17:02:18 2017 +0200
@@ -293,10 +293,8 @@
}
sfv.process(sigFileSigners);
- } catch (sun.security.pkcs.ParsingException pe) {
- if (debug != null) debug.println("processEntry caught: "+pe);
- // ignore and treat as unsigned
} catch (IOException ioe) {
+ // e.g. sun.security.pkcs.ParsingException
if (debug != null) debug.println("processEntry caught: "+ioe);
// ignore and treat as unsigned
} catch (SignatureException se) {
--- a/jdk/src/share/classes/sun/misc/FloatingDecimal.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/misc/FloatingDecimal.java Wed Jul 05 17:02:18 2017 +0200
@@ -730,7 +730,7 @@
* Thus we will need more than one digit if we're using
* E-form
*/
- if ( decExp <= -3 || decExp >= 8 ){
+ if ( decExp < -3 || decExp >= 8 ){
high = low = false;
}
while( ! low && ! high ){
@@ -783,7 +783,7 @@
* Thus we will need more than one digit if we're using
* E-form
*/
- if ( decExp <= -3 || decExp >= 8 ){
+ if ( decExp < -3 || decExp >= 8 ){
high = low = false;
}
while( ! low && ! high ){
@@ -847,7 +847,7 @@
* Thus we will need more than one digit if we're using
* E-form
*/
- if ( decExp <= -3 || decExp >= 8 ){
+ if ( decExp < -3 || decExp >= 8 ){
high = low = false;
}
while( ! low && ! high ){
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Jul 05 17:02:18 2017 +0200
@@ -31,6 +31,7 @@
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
+import java.util.logging.Logger;
import java.text.*;
import sun.net.www.MessageHeader;
import com.sun.net.httpserver.*;
@@ -204,6 +205,21 @@
tmpout.write (bytes(statusLine, 0), 0, statusLine.length());
boolean noContentToSend = false; // assume there is content
rspHdrs.set ("Date", df.format (new Date()));
+
+ /* check for response type that is not allowed to send a body */
+
+ if ((rCode>=100 && rCode <200) /* informational */
+ ||(rCode == 204) /* no content */
+ ||(rCode == 304)) /* not modified */
+ {
+ if (contentLen != -1) {
+ Logger logger = server.getLogger();
+ String msg = "sendResponseHeaders: rCode = "+ rCode
+ + ": forcing contentLen = -1";
+ logger.warning (msg);
+ }
+ contentLen = -1;
+ }
if (contentLen == 0) {
if (http10) {
o.setWrappedStream (new UndefLengthOutputStream (this, ros));
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 05 17:02:18 2017 +0200
@@ -1180,6 +1180,10 @@
inputStream = http.getInputStream();
respCode = getResponseCode();
+ if (respCode == -1) {
+ disconnectInternal();
+ throw new IOException ("Invalid Http response");
+ }
if (respCode == HTTP_PROXY_AUTH) {
if (streaming()) {
disconnectInternal();
--- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java Wed Jul 05 17:02:18 2017 +0200
@@ -1832,8 +1832,9 @@
return canonCs;
}
- // public for java.io.FilePermission
- public static String canonPath(String path) throws IOException {
+ // Wrapper to return a canonical path that avoids calling getCanonicalPath()
+ // with paths that are intended to match all entries in the directory
+ private static String canonPath(String path) throws IOException {
if (path.endsWith("*")) {
path = path.substring(0, path.length()-1) + "-";
path = new File(path).getCanonicalPath();
--- a/jdk/src/share/classes/sun/security/provider/SunEntries.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/SunEntries.java Wed Jul 05 17:02:18 2017 +0200
@@ -210,7 +210,7 @@
* CertStores
*/
map.put("CertStore.LDAP",
- "sun.security.provider.certpath.LDAPCertStore");
+ "sun.security.provider.certpath.ldap.LDAPCertStore");
map.put("CertStore.LDAP LDAPSchema", "RFC2587");
map.put("CertStore.Collection",
"sun.security.provider.certpath.CollectionCertStore");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertStoreHelper.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2009 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.provider.certpath;
+
+import java.net.URI;
+import java.util.Collection;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.CertStore;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509CRLSelector;
+import javax.security.auth.x500.X500Principal;
+import java.io.IOException;
+
+/**
+ * Helper used by URICertStore when delegating to another CertStore to
+ * fetch certs and CRLs.
+ */
+
+public interface CertStoreHelper {
+
+ /**
+ * Returns a CertStore using the given URI as parameters.
+ */
+ CertStore getCertStore(URI uri)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException;
+
+ /**
+ * Wraps an existing X509CertSelector when needing to avoid DN matching
+ * issues.
+ */
+ X509CertSelector wrap(X509CertSelector selector,
+ X500Principal certSubject,
+ String dn)
+ throws IOException;
+
+ /**
+ * Wraps an existing X509CRLSelector when needing to avoid DN matching
+ * issues.
+ */
+ X509CRLSelector wrap(X509CRLSelector selector,
+ Collection<X500Principal> certIssuers,
+ String dn)
+ throws IOException;
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/LDAPCertStore.java Thu Oct 15 16:40:16 2009 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1065 +0,0 @@
-/*
- * Copyright 2000-2006 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. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.provider.certpath;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.net.URI;
-import java.util.*;
-import javax.naming.Context;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.naming.NameNotFoundException;
-import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.DirContext;
-import javax.naming.directory.InitialDirContext;
-
-import java.security.*;
-import java.security.cert.Certificate;
-import java.security.cert.*;
-import javax.security.auth.x500.X500Principal;
-
-import sun.misc.HexDumpEncoder;
-import sun.security.util.Cache;
-import sun.security.util.Debug;
-import sun.security.x509.X500Name;
-import sun.security.action.GetPropertyAction;
-
-/**
- * A <code>CertStore</code> that retrieves <code>Certificates</code> and
- * <code>CRL</code>s from an LDAP directory, using the PKIX LDAP V2 Schema
- * (RFC 2587):
- * <a href="http://www.ietf.org/rfc/rfc2587.txt">
- * http://www.ietf.org/rfc/rfc2587.txt</a>.
- * <p>
- * Before calling the {@link #engineGetCertificates engineGetCertificates} or
- * {@link #engineGetCRLs engineGetCRLs} methods, the
- * {@link #LDAPCertStore(CertStoreParameters)
- * LDAPCertStore(CertStoreParameters)} constructor is called to create the
- * <code>CertStore</code> and establish the DNS name and port of the LDAP
- * server from which <code>Certificate</code>s and <code>CRL</code>s will be
- * retrieved.
- * <p>
- * <b>Concurrent Access</b>
- * <p>
- * As described in the javadoc for <code>CertStoreSpi</code>, the
- * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods
- * must be thread-safe. That is, multiple threads may concurrently
- * invoke these methods on a single <code>LDAPCertStore</code> object
- * (or more than one) with no ill effects. This allows a
- * <code>CertPathBuilder</code> to search for a CRL while simultaneously
- * searching for further certificates, for instance.
- * <p>
- * This is achieved by adding the <code>synchronized</code> keyword to the
- * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods.
- * <p>
- * This classes uses caching and requests multiple attributes at once to
- * minimize LDAP round trips. The cache is associated with the CertStore
- * instance. It uses soft references to hold the values to minimize impact
- * on footprint and currently has a maximum size of 750 attributes and a
- * 30 second default lifetime.
- * <p>
- * We always request CA certificates, cross certificate pairs, and ARLs in
- * a single LDAP request when any one of them is needed. The reason is that
- * we typically need all of them anyway and requesting them in one go can
- * reduce the number of requests to a third. Even if we don't need them,
- * these attributes are typically small enough not to cause a noticeable
- * overhead. In addition, when the prefetchCRLs flag is true, we also request
- * the full CRLs. It is currently false initially but set to true once any
- * request for an ARL to the server returns an null value. The reason is
- * that CRLs could be rather large but are rarely used. This implementation
- * should improve performance in most cases.
- *
- * @see java.security.cert.CertStore
- *
- * @since 1.4
- * @author Steve Hanna
- * @author Andreas Sterbenz
- */
-public class LDAPCertStore extends CertStoreSpi {
-
- private static final Debug debug = Debug.getInstance("certpath");
-
- private final static boolean DEBUG = false;
-
- /**
- * LDAP attribute identifiers.
- */
- private static final String USER_CERT = "userCertificate;binary";
- private static final String CA_CERT = "cACertificate;binary";
- private static final String CROSS_CERT = "crossCertificatePair;binary";
- private static final String CRL = "certificateRevocationList;binary";
- private static final String ARL = "authorityRevocationList;binary";
- private static final String DELTA_CRL = "deltaRevocationList;binary";
-
- // Constants for various empty values
- private final static String[] STRING0 = new String[0];
-
- private final static byte[][] BB0 = new byte[0][];
-
- private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes();
-
- // cache related constants
- private final static int DEFAULT_CACHE_SIZE = 750;
- private final static int DEFAULT_CACHE_LIFETIME = 30;
-
- private final static int LIFETIME;
-
- private final static String PROP_LIFETIME =
- "sun.security.certpath.ldap.cache.lifetime";
-
- static {
- String s = AccessController.doPrivileged(
- new GetPropertyAction(PROP_LIFETIME));
- if (s != null) {
- LIFETIME = Integer.parseInt(s); // throws NumberFormatException
- } else {
- LIFETIME = DEFAULT_CACHE_LIFETIME;
- }
- }
-
- /**
- * The CertificateFactory used to decode certificates from
- * their binary stored form.
- */
- private CertificateFactory cf;
- /**
- * The JNDI directory context.
- */
- private DirContext ctx;
-
- /**
- * Flag indicating whether we should prefetch CRLs.
- */
- private boolean prefetchCRLs = false;
-
- private final Cache valueCache;
-
- private int cacheHits = 0;
- private int cacheMisses = 0;
- private int requests = 0;
-
- /**
- * Creates a <code>CertStore</code> with the specified parameters.
- * For this class, the parameters object must be an instance of
- * <code>LDAPCertStoreParameters</code>.
- *
- * @param params the algorithm parameters
- * @exception InvalidAlgorithmParameterException if params is not an
- * instance of <code>LDAPCertStoreParameters</code>
- */
- public LDAPCertStore(CertStoreParameters params)
- throws InvalidAlgorithmParameterException {
- super(params);
- if (!(params instanceof LDAPCertStoreParameters))
- throw new InvalidAlgorithmParameterException(
- "parameters must be LDAPCertStoreParameters");
-
- LDAPCertStoreParameters lparams = (LDAPCertStoreParameters) params;
-
- // Create InitialDirContext needed to communicate with the server
- createInitialDirContext(lparams.getServerName(), lparams.getPort());
-
- // Create CertificateFactory for use later on
- try {
- cf = CertificateFactory.getInstance("X.509");
- } catch (CertificateException e) {
- throw new InvalidAlgorithmParameterException(
- "unable to create CertificateFactory for X.509");
- }
- if (LIFETIME == 0) {
- valueCache = Cache.newNullCache();
- } else if (LIFETIME < 0) {
- valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE);
- } else {
- valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE, LIFETIME);
- }
- }
-
- /**
- * Returns an LDAP CertStore. This method consults a cache of
- * CertStores (shared per JVM) using the LDAP server/port as a key.
- */
- private static final Cache certStoreCache = Cache.newSoftMemoryCache(185);
- static synchronized CertStore getInstance(LDAPCertStoreParameters params)
- throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
- CertStore lcs = (CertStore) certStoreCache.get(params);
- if (lcs == null) {
- lcs = CertStore.getInstance("LDAP", params);
- certStoreCache.put(params, lcs);
- } else {
- if (debug != null) {
- debug.println("LDAPCertStore.getInstance: cache hit");
- }
- }
- return lcs;
- }
-
- /**
- * Create InitialDirContext.
- *
- * @param server Server DNS name hosting LDAP service
- * @param port Port at which server listens for requests
- * @throws InvalidAlgorithmParameterException if creation fails
- */
- private void createInitialDirContext(String server, int port)
- throws InvalidAlgorithmParameterException {
- String url = "ldap://" + server + ":" + port;
- Hashtable<String,Object> env = new Hashtable<String,Object>();
- env.put(Context.INITIAL_CONTEXT_FACTORY,
- "com.sun.jndi.ldap.LdapCtxFactory");
- env.put(Context.PROVIDER_URL, url);
- try {
- ctx = new InitialDirContext(env);
- /*
- * By default, follow referrals unless application has
- * overridden property in an application resource file.
- */
- Hashtable<?,?> currentEnv = ctx.getEnvironment();
- if (currentEnv.get(Context.REFERRAL) == null) {
- ctx.addToEnvironment(Context.REFERRAL, "follow");
- }
- } catch (NamingException e) {
- if (debug != null) {
- debug.println("LDAPCertStore.engineInit about to throw "
- + "InvalidAlgorithmParameterException");
- e.printStackTrace();
- }
- Exception ee = new InvalidAlgorithmParameterException
- ("unable to create InitialDirContext using supplied parameters");
- ee.initCause(e);
- throw (InvalidAlgorithmParameterException)ee;
- }
- }
-
- /**
- * Private class encapsulating the actual LDAP operations and cache
- * handling. Use:
- *
- * LDAPRequest request = new LDAPRequest(dn);
- * request.addRequestedAttribute(CROSS_CERT);
- * request.addRequestedAttribute(CA_CERT);
- * byte[][] crossValues = request.getValues(CROSS_CERT);
- * byte[][] caValues = request.getValues(CA_CERT);
- *
- * At most one LDAP request is sent for each instance created. If all
- * getValues() calls can be satisfied from the cache, no request
- * is sent at all. If a request is sent, all requested attributes
- * are always added to the cache irrespective of whether the getValues()
- * method is called.
- */
- private class LDAPRequest {
-
- private final String name;
- private Map<String, byte[][]> valueMap;
- private final List<String> requestedAttributes;
-
- LDAPRequest(String name) {
- this.name = name;
- requestedAttributes = new ArrayList<String>(5);
- }
-
- String getName() {
- return name;
- }
-
- void addRequestedAttribute(String attrId) {
- if (valueMap != null) {
- throw new IllegalStateException("Request already sent");
- }
- requestedAttributes.add(attrId);
- }
-
- /**
- * Gets one or more binary values from an attribute.
- *
- * @param name the location holding the attribute
- * @param attrId the attribute identifier
- * @return an array of binary values (byte arrays)
- * @throws NamingException if a naming exception occurs
- */
- byte[][] getValues(String attrId) throws NamingException {
- if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) {
- System.out.println("Cache hits: " + cacheHits + "; misses: "
- + cacheMisses);
- }
- String cacheKey = name + "|" + attrId;
- byte[][] values = (byte[][])valueCache.get(cacheKey);
- if (values != null) {
- cacheHits++;
- return values;
- }
- cacheMisses++;
- Map<String, byte[][]> attrs = getValueMap();
- values = attrs.get(attrId);
- return values;
- }
-
- /**
- * Get a map containing the values for this request. The first time
- * this method is called on an object, the LDAP request is sent,
- * the results parsed and added to a private map and also to the
- * cache of this LDAPCertStore. Subsequent calls return the private
- * map immediately.
- *
- * The map contains an entry for each requested attribute. The
- * attribute name is the key, values are byte[][]. If there are no
- * values for that attribute, values are byte[0][].
- *
- * @return the value Map
- * @throws NamingException if a naming exception occurs
- */
- private Map<String, byte[][]> getValueMap() throws NamingException {
- if (valueMap != null) {
- return valueMap;
- }
- if (DEBUG) {
- System.out.println("Request: " + name + ":" + requestedAttributes);
- requests++;
- if (requests % 5 == 0) {
- System.out.println("LDAP requests: " + requests);
- }
- }
- valueMap = new HashMap<String, byte[][]>(8);
- String[] attrIds = requestedAttributes.toArray(STRING0);
- Attributes attrs;
- try {
- attrs = ctx.getAttributes(name, attrIds);
- } catch (NameNotFoundException e) {
- // name does not exist on this LDAP server
- // treat same as not attributes found
- attrs = EMPTY_ATTRIBUTES;
- }
- for (String attrId : requestedAttributes) {
- Attribute attr = attrs.get(attrId);
- byte[][] values = getAttributeValues(attr);
- cacheAttribute(attrId, values);
- valueMap.put(attrId, values);
- }
- return valueMap;
- }
-
- /**
- * Add the values to the cache.
- */
- private void cacheAttribute(String attrId, byte[][] values) {
- String cacheKey = name + "|" + attrId;
- valueCache.put(cacheKey, values);
- }
-
- /**
- * Get the values for the given attribute. If the attribute is null
- * or does not contain any values, a zero length byte array is
- * returned. NOTE that it is assumed that all values are byte arrays.
- */
- private byte[][] getAttributeValues(Attribute attr)
- throws NamingException {
- byte[][] values;
- if (attr == null) {
- values = BB0;
- } else {
- values = new byte[attr.size()][];
- int i = 0;
- NamingEnumeration<?> enum_ = attr.getAll();
- while (enum_.hasMore()) {
- Object obj = enum_.next();
- if (debug != null) {
- if (obj instanceof String) {
- debug.println("LDAPCertStore.getAttrValues() "
- + "enum.next is a string!: " + obj);
- }
- }
- byte[] value = (byte[])obj;
- values[i++] = value;
- }
- }
- return values;
- }
-
- }
-
- /*
- * Gets certificates from an attribute id and location in the LDAP
- * directory. Returns a Collection containing only the Certificates that
- * match the specified CertSelector.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @param sel a CertSelector that the Certificates must match
- * @return a Collection of Certificates found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509Certificate> getCertificates(LDAPRequest request,
- String id, X509CertSelector sel) throws CertStoreException {
-
- /* fetch encoded certs from storage */
- byte[][] encodedCert;
- try {
- encodedCert = request.getValues(id);
- } catch (NamingException namingEx) {
- throw new CertStoreException(namingEx);
- }
-
- int n = encodedCert.length;
- if (n == 0) {
- return Collections.<X509Certificate>emptySet();
- }
-
- List<X509Certificate> certs = new ArrayList<X509Certificate>(n);
- /* decode certs and check if they satisfy selector */
- for (int i = 0; i < n; i++) {
- ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]);
- try {
- Certificate cert = cf.generateCertificate(bais);
- if (sel.match(cert)) {
- certs.add((X509Certificate)cert);
- }
- } catch (CertificateException e) {
- if (debug != null) {
- debug.println("LDAPCertStore.getCertificates() encountered "
- + "exception while parsing cert, skipping the bad data: ");
- HexDumpEncoder encoder = new HexDumpEncoder();
- debug.println(
- "[ " + encoder.encodeBuffer(encodedCert[i]) + " ]");
- }
- }
- }
-
- return certs;
- }
-
- /*
- * Gets certificate pairs from an attribute id and location in the LDAP
- * directory.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @return a Collection of X509CertificatePairs found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509CertificatePair> getCertPairs(
- LDAPRequest request, String id) throws CertStoreException {
-
- /* fetch the encoded cert pairs from storage */
- byte[][] encodedCertPair;
- try {
- encodedCertPair = request.getValues(id);
- } catch (NamingException namingEx) {
- throw new CertStoreException(namingEx);
- }
-
- int n = encodedCertPair.length;
- if (n == 0) {
- return Collections.<X509CertificatePair>emptySet();
- }
-
- List<X509CertificatePair> certPairs =
- new ArrayList<X509CertificatePair>(n);
- /* decode each cert pair and add it to the Collection */
- for (int i = 0; i < n; i++) {
- try {
- X509CertificatePair certPair =
- X509CertificatePair.generateCertificatePair(encodedCertPair[i]);
- certPairs.add(certPair);
- } catch (CertificateException e) {
- if (debug != null) {
- debug.println(
- "LDAPCertStore.getCertPairs() encountered exception "
- + "while parsing cert, skipping the bad data: ");
- HexDumpEncoder encoder = new HexDumpEncoder();
- debug.println(
- "[ " + encoder.encodeBuffer(encodedCertPair[i]) + " ]");
- }
- }
- }
-
- return certPairs;
- }
-
- /*
- * Looks at certificate pairs stored in the crossCertificatePair attribute
- * at the specified location in the LDAP directory. Returns a Collection
- * containing all Certificates stored in the forward component that match
- * the forward CertSelector and all Certificates stored in the reverse
- * component that match the reverse CertSelector.
- * <p>
- * If either forward or reverse is null, all certificates from the
- * corresponding component will be rejected.
- *
- * @param name the location to look in
- * @param forward the forward CertSelector (or null)
- * @param reverse the reverse CertSelector (or null)
- * @return a Collection of Certificates found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509Certificate> getMatchingCrossCerts(
- LDAPRequest request, X509CertSelector forward,
- X509CertSelector reverse)
- throws CertStoreException {
- // Get the cert pairs
- Collection<X509CertificatePair> certPairs =
- getCertPairs(request, CROSS_CERT);
-
- // Find Certificates that match and put them in a list
- ArrayList<X509Certificate> matchingCerts =
- new ArrayList<X509Certificate>();
- for (X509CertificatePair certPair : certPairs) {
- X509Certificate cert;
- if (forward != null) {
- cert = certPair.getForward();
- if ((cert != null) && forward.match(cert)) {
- matchingCerts.add(cert);
- }
- }
- if (reverse != null) {
- cert = certPair.getReverse();
- if ((cert != null) && reverse.match(cert)) {
- matchingCerts.add(cert);
- }
- }
- }
- return matchingCerts;
- }
-
- /**
- * Returns a <code>Collection</code> of <code>Certificate</code>s that
- * match the specified selector. If no <code>Certificate</code>s
- * match the selector, an empty <code>Collection</code> will be returned.
- * <p>
- * It is not practical to search every entry in the LDAP database for
- * matching <code>Certificate</code>s. Instead, the <code>CertSelector</code>
- * is examined in order to determine where matching <code>Certificate</code>s
- * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
- * If the subject is specified, its directory entry is searched. If the
- * issuer is specified, its directory entry is searched. If neither the
- * subject nor the issuer are specified (or the selector is not an
- * <code>X509CertSelector</code>), a <code>CertStoreException</code> is
- * thrown.
- *
- * @param selector a <code>CertSelector</code> used to select which
- * <code>Certificate</code>s should be returned.
- * @return a <code>Collection</code> of <code>Certificate</code>s that
- * match the specified selector
- * @throws CertStoreException if an exception occurs
- */
- public synchronized Collection<X509Certificate> engineGetCertificates
- (CertSelector selector) throws CertStoreException {
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() selector: "
- + String.valueOf(selector));
- }
-
- if (selector == null) {
- selector = new X509CertSelector();
- }
- if (!(selector instanceof X509CertSelector)) {
- throw new CertStoreException("LDAPCertStore needs an X509CertSelector " +
- "to find certs");
- }
- X509CertSelector xsel = (X509CertSelector) selector;
- int basicConstraints = xsel.getBasicConstraints();
- String subject = xsel.getSubjectAsString();
- String issuer = xsel.getIssuerAsString();
- HashSet<X509Certificate> certs = new HashSet<X509Certificate>();
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: "
- + basicConstraints);
- }
-
- // basicConstraints:
- // -2: only EE certs accepted
- // -1: no check is done
- // 0: any CA certificate accepted
- // >1: certificate's basicConstraints extension pathlen must match
- if (subject != null) {
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() "
- + "subject is not null");
- }
- LDAPRequest request = new LDAPRequest(subject);
- if (basicConstraints > -2) {
- request.addRequestedAttribute(CROSS_CERT);
- request.addRequestedAttribute(CA_CERT);
- request.addRequestedAttribute(ARL);
- if (prefetchCRLs) {
- request.addRequestedAttribute(CRL);
- }
- }
- if (basicConstraints < 0) {
- request.addRequestedAttribute(USER_CERT);
- }
-
- if (basicConstraints > -2) {
- certs.addAll(getMatchingCrossCerts(request, xsel, null));
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() after "
- + "getMatchingCrossCerts(subject,xsel,null),certs.size(): "
- + certs.size());
- }
- certs.addAll(getCertificates(request, CA_CERT, xsel));
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() after "
- + "getCertificates(subject,CA_CERT,xsel),certs.size(): "
- + certs.size());
- }
- }
- if (basicConstraints < 0) {
- certs.addAll(getCertificates(request, USER_CERT, xsel));
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() after "
- + "getCertificates(subject,USER_CERT, xsel),certs.size(): "
- + certs.size());
- }
- }
- } else {
- if (debug != null) {
- debug.println
- ("LDAPCertStore.engineGetCertificates() subject is null");
- }
- if (basicConstraints == -2) {
- throw new CertStoreException("need subject to find EE certs");
- }
- if (issuer == null) {
- throw new CertStoreException("need subject or issuer to find certs");
- }
- }
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() about to "
- + "getMatchingCrossCerts...");
- }
- if ((issuer != null) && (basicConstraints > -2)) {
- LDAPRequest request = new LDAPRequest(issuer);
- request.addRequestedAttribute(CROSS_CERT);
- request.addRequestedAttribute(CA_CERT);
- request.addRequestedAttribute(ARL);
- if (prefetchCRLs) {
- request.addRequestedAttribute(CRL);
- }
-
- certs.addAll(getMatchingCrossCerts(request, null, xsel));
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() after "
- + "getMatchingCrossCerts(issuer,null,xsel),certs.size(): "
- + certs.size());
- }
- certs.addAll(getCertificates(request, CA_CERT, xsel));
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() after "
- + "getCertificates(issuer,CA_CERT,xsel),certs.size(): "
- + certs.size());
- }
- }
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCertificates() returning certs");
- }
- return certs;
- }
-
- /*
- * Gets CRLs from an attribute id and location in the LDAP directory.
- * Returns a Collection containing only the CRLs that match the
- * specified CRLSelector.
- *
- * @param name the location holding the attribute
- * @param id the attribute identifier
- * @param sel a CRLSelector that the CRLs must match
- * @return a Collection of CRLs found
- * @throws CertStoreException if an exception occurs
- */
- private Collection<X509CRL> getCRLs(LDAPRequest request, String id,
- X509CRLSelector sel) throws CertStoreException {
-
- /* fetch the encoded crls from storage */
- byte[][] encodedCRL;
- try {
- encodedCRL = request.getValues(id);
- } catch (NamingException namingEx) {
- throw new CertStoreException(namingEx);
- }
-
- int n = encodedCRL.length;
- if (n == 0) {
- return Collections.<X509CRL>emptySet();
- }
-
- List<X509CRL> crls = new ArrayList<X509CRL>(n);
- /* decode each crl and check if it matches selector */
- for (int i = 0; i < n; i++) {
- try {
- CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i]));
- if (sel.match(crl)) {
- crls.add((X509CRL)crl);
- }
- } catch (CRLException e) {
- if (debug != null) {
- debug.println("LDAPCertStore.getCRLs() encountered exception"
- + " while parsing CRL, skipping the bad data: ");
- HexDumpEncoder encoder = new HexDumpEncoder();
- debug.println("[ " + encoder.encodeBuffer(encodedCRL[i]) + " ]");
- }
- }
- }
-
- return crls;
- }
-
- /**
- * Returns a <code>Collection</code> of <code>CRL</code>s that
- * match the specified selector. If no <code>CRL</code>s
- * match the selector, an empty <code>Collection</code> will be returned.
- * <p>
- * It is not practical to search every entry in the LDAP database for
- * matching <code>CRL</code>s. Instead, the <code>CRLSelector</code>
- * is examined in order to determine where matching <code>CRL</code>s
- * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
- * If issuerNames or certChecking are specified, the issuer's directory
- * entry is searched. If neither issuerNames or certChecking are specified
- * (or the selector is not an <code>X509CRLSelector</code>), a
- * <code>CertStoreException</code> is thrown.
- *
- * @param selector A <code>CRLSelector</code> used to select which
- * <code>CRL</code>s should be returned. Specify <code>null</code>
- * to return all <code>CRL</code>s.
- * @return A <code>Collection</code> of <code>CRL</code>s that
- * match the specified selector
- * @throws CertStoreException if an exception occurs
- */
- public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
- throws CertStoreException {
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCRLs() selector: "
- + selector);
- }
- // Set up selector and collection to hold CRLs
- if (selector == null) {
- selector = new X509CRLSelector();
- }
- if (!(selector instanceof X509CRLSelector)) {
- throw new CertStoreException("need X509CRLSelector to find CRLs");
- }
- X509CRLSelector xsel = (X509CRLSelector) selector;
- HashSet<X509CRL> crls = new HashSet<X509CRL>();
-
- // Look in directory entry for issuer of cert we're checking.
- Collection<Object> issuerNames;
- X509Certificate certChecking = xsel.getCertificateChecking();
- if (certChecking != null) {
- issuerNames = new HashSet<Object>();
- X500Principal issuer = certChecking.getIssuerX500Principal();
- issuerNames.add(issuer.getName(X500Principal.RFC2253));
- } else {
- // But if we don't know which cert we're checking, try the directory
- // entries of all acceptable CRL issuers
- issuerNames = xsel.getIssuerNames();
- if (issuerNames == null) {
- throw new CertStoreException("need issuerNames or certChecking to "
- + "find CRLs");
- }
- }
- for (Object nameObject : issuerNames) {
- String issuerName;
- if (nameObject instanceof byte[]) {
- try {
- X500Principal issuer = new X500Principal((byte[])nameObject);
- issuerName = issuer.getName(X500Principal.RFC2253);
- } catch (IllegalArgumentException e) {
- continue;
- }
- } else {
- issuerName = (String)nameObject;
- }
- // If all we want is CA certs, try to get the (probably shorter) ARL
- Collection<X509CRL> entryCRLs = Collections.<X509CRL>emptySet();
- if (certChecking == null || certChecking.getBasicConstraints() != -1) {
- LDAPRequest request = new LDAPRequest(issuerName);
- request.addRequestedAttribute(CROSS_CERT);
- request.addRequestedAttribute(CA_CERT);
- request.addRequestedAttribute(ARL);
- if (prefetchCRLs) {
- request.addRequestedAttribute(CRL);
- }
- try {
- entryCRLs = getCRLs(request, ARL, xsel);
- if (entryCRLs.isEmpty()) {
- // no ARLs found. We assume that means that there are
- // no ARLs on this server at all and prefetch the CRLs.
- prefetchCRLs = true;
- } else {
- crls.addAll(entryCRLs);
- }
- } catch (CertStoreException e) {
- if (debug != null) {
- debug.println("LDAPCertStore.engineGetCRLs non-fatal error "
- + "retrieving ARLs:" + e);
- e.printStackTrace();
- }
- }
- }
- // Otherwise, get the CRL
- // if certChecking is null, we don't know if we should look in ARL or CRL
- // attribute, so check both for matching CRLs.
- if (entryCRLs.isEmpty() || certChecking == null) {
- LDAPRequest request = new LDAPRequest(issuerName);
- request.addRequestedAttribute(CRL);
- entryCRLs = getCRLs(request, CRL, xsel);
- crls.addAll(entryCRLs);
- }
- }
- return crls;
- }
-
- // converts an LDAP URI into LDAPCertStoreParameters
- static LDAPCertStoreParameters getParameters(URI uri) {
- String host = uri.getHost();
- if (host == null) {
- return new SunLDAPCertStoreParameters();
- } else {
- int port = uri.getPort();
- return (port == -1
- ? new SunLDAPCertStoreParameters(host)
- : new SunLDAPCertStoreParameters(host, port));
- }
- }
-
- /*
- * Subclass of LDAPCertStoreParameters with overridden equals/hashCode
- * methods. This is necessary because the parameters are used as
- * keys in the LDAPCertStore cache.
- */
- private static class SunLDAPCertStoreParameters
- extends LDAPCertStoreParameters {
-
- private volatile int hashCode = 0;
-
- SunLDAPCertStoreParameters(String serverName, int port) {
- super(serverName, port);
- }
- SunLDAPCertStoreParameters(String serverName) {
- super(serverName);
- }
- SunLDAPCertStoreParameters() {
- super();
- }
- public boolean equals(Object obj) {
- if (!(obj instanceof LDAPCertStoreParameters)) {
- return false;
- }
- LDAPCertStoreParameters params = (LDAPCertStoreParameters) obj;
- return (getPort() == params.getPort() &&
- getServerName().equalsIgnoreCase(params.getServerName()));
- }
- public int hashCode() {
- if (hashCode == 0) {
- int result = 17;
- result = 37*result + getPort();
- result = 37*result + getServerName().toLowerCase().hashCode();
- hashCode = result;
- }
- return hashCode;
- }
- }
-
- /*
- * This inner class wraps an existing X509CertSelector and adds
- * additional criteria to match on when the certificate's subject is
- * different than the LDAP Distinguished Name entry. The LDAPCertStore
- * implementation uses the subject DN as the directory entry for
- * looking up certificates. This can be problematic if the certificates
- * that you want to fetch have a different subject DN than the entry
- * where they are stored. You could set the selector's subject to the
- * LDAP DN entry, but then the resulting match would fail to find the
- * desired certificates because the subject DNs would not match. This
- * class avoids that problem by introducing a certSubject which should
- * be set to the certificate's subject DN when it is different than
- * the LDAP DN.
- */
- static class LDAPCertSelector extends X509CertSelector {
-
- private X500Principal certSubject;
- private X509CertSelector selector;
- private X500Principal subject;
-
- /**
- * Creates an LDAPCertSelector.
- *
- * @param selector the X509CertSelector to wrap
- * @param certSubject the subject DN of the certificate that you want
- * to retrieve via LDAP
- * @param ldapDN the LDAP DN where the certificate is stored
- */
- LDAPCertSelector(X509CertSelector selector, X500Principal certSubject,
- String ldapDN) throws IOException {
- this.selector = selector == null ? new X509CertSelector() : selector;
- this.certSubject = certSubject;
- this.subject = new X500Name(ldapDN).asX500Principal();
- }
-
- // we only override the get (accessor methods) since the set methods
- // will not be invoked by the code that uses this LDAPCertSelector.
- public X509Certificate getCertificate() {
- return selector.getCertificate();
- }
- public BigInteger getSerialNumber() {
- return selector.getSerialNumber();
- }
- public X500Principal getIssuer() {
- return selector.getIssuer();
- }
- public String getIssuerAsString() {
- return selector.getIssuerAsString();
- }
- public byte[] getIssuerAsBytes() throws IOException {
- return selector.getIssuerAsBytes();
- }
- public X500Principal getSubject() {
- // return the ldap DN
- return subject;
- }
- public String getSubjectAsString() {
- // return the ldap DN
- return subject.getName();
- }
- public byte[] getSubjectAsBytes() throws IOException {
- // return the encoded ldap DN
- return subject.getEncoded();
- }
- public byte[] getSubjectKeyIdentifier() {
- return selector.getSubjectKeyIdentifier();
- }
- public byte[] getAuthorityKeyIdentifier() {
- return selector.getAuthorityKeyIdentifier();
- }
- public Date getCertificateValid() {
- return selector.getCertificateValid();
- }
- public Date getPrivateKeyValid() {
- return selector.getPrivateKeyValid();
- }
- public String getSubjectPublicKeyAlgID() {
- return selector.getSubjectPublicKeyAlgID();
- }
- public PublicKey getSubjectPublicKey() {
- return selector.getSubjectPublicKey();
- }
- public boolean[] getKeyUsage() {
- return selector.getKeyUsage();
- }
- public Set<String> getExtendedKeyUsage() {
- return selector.getExtendedKeyUsage();
- }
- public boolean getMatchAllSubjectAltNames() {
- return selector.getMatchAllSubjectAltNames();
- }
- public Collection<List<?>> getSubjectAlternativeNames() {
- return selector.getSubjectAlternativeNames();
- }
- public byte[] getNameConstraints() {
- return selector.getNameConstraints();
- }
- public int getBasicConstraints() {
- return selector.getBasicConstraints();
- }
- public Set<String> getPolicy() {
- return selector.getPolicy();
- }
- public Collection<List<?>> getPathToNames() {
- return selector.getPathToNames();
- }
-
- public boolean match(Certificate cert) {
- // temporarily set the subject criterion to the certSubject
- // so that match will not reject the desired certificates
- selector.setSubject(certSubject);
- boolean match = selector.match(cert);
- selector.setSubject(subject);
- return match;
- }
- }
-
- /**
- * This class has the same purpose as LDAPCertSelector except it is for
- * X.509 CRLs.
- */
- static class LDAPCRLSelector extends X509CRLSelector {
-
- private X509CRLSelector selector;
- private Collection<X500Principal> certIssuers;
- private Collection<X500Principal> issuers;
- private HashSet<Object> issuerNames;
-
- /**
- * Creates an LDAPCRLSelector.
- *
- * @param selector the X509CRLSelector to wrap
- * @param certIssuers the issuer DNs of the CRLs that you want
- * to retrieve via LDAP
- * @param ldapDN the LDAP DN where the CRL is stored
- */
- LDAPCRLSelector(X509CRLSelector selector,
- Collection<X500Principal> certIssuers, String ldapDN)
- throws IOException {
- this.selector = selector == null ? new X509CRLSelector() : selector;
- this.certIssuers = certIssuers;
- issuerNames = new HashSet<Object>();
- issuerNames.add(ldapDN);
- issuers = new HashSet<X500Principal>();
- issuers.add(new X500Name(ldapDN).asX500Principal());
- }
- // we only override the get (accessor methods) since the set methods
- // will not be invoked by the code that uses this LDAPCRLSelector.
- public Collection<X500Principal> getIssuers() {
- // return the ldap DN
- return Collections.unmodifiableCollection(issuers);
- }
- public Collection<Object> getIssuerNames() {
- // return the ldap DN
- return Collections.unmodifiableCollection(issuerNames);
- }
- public BigInteger getMinCRL() {
- return selector.getMinCRL();
- }
- public BigInteger getMaxCRL() {
- return selector.getMaxCRL();
- }
- public Date getDateAndTime() {
- return selector.getDateAndTime();
- }
- public X509Certificate getCertificateChecking() {
- return selector.getCertificateChecking();
- }
- public boolean match(CRL crl) {
- // temporarily set the issuer criterion to the certIssuers
- // so that match will not reject the desired CRL
- selector.setIssuers(certIssuers);
- boolean match = selector.match(crl);
- selector.setIssuers(issuers);
- return match;
- }
- }
-}
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java Wed Jul 05 17:02:18 2017 +0200
@@ -64,6 +64,8 @@
private static final Debug debug = Debug.getInstance("certpath");
+ private static final int CONNECT_TIMEOUT = 15000; // 15 seconds
+
private OCSP() {}
/**
@@ -176,6 +178,8 @@
debug.println("connecting to OCSP service at: " + url);
}
HttpURLConnection con = (HttpURLConnection)url.openConnection();
+ con.setConnectTimeout(CONNECT_TIMEOUT);
+ con.setReadTimeout(CONNECT_TIMEOUT);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Wed Jul 05 17:02:18 2017 +0200
@@ -25,7 +25,6 @@
package sun.security.provider.certpath;
-import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import java.security.AccessController;
@@ -335,10 +334,11 @@
(issuerCert, currCertImpl.getSerialNumberObject());
response = OCSP.check(Collections.singletonList(certId), uri,
responderCert, pkixParams.getDate());
- } catch (IOException ioe) {
- // should allow this to pass if network failures are acceptable
+ } catch (Exception e) {
+ // Wrap all exceptions in CertPathValidatorException so that
+ // we can fallback to CRLs, if enabled.
throw new CertPathValidatorException
- ("Unable to send OCSP request", ioe);
+ ("Unable to send OCSP request", e);
}
RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
--- a/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/URICertStore.java Wed Jul 05 17:02:18 2017 +0200
@@ -30,6 +30,8 @@
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URLConnection;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
@@ -121,6 +123,32 @@
private String ldapPath;
/**
+ * Holder class to lazily load LDAPCertStoreHelper if present.
+ */
+ private static class LDAP {
+ private static final String CERT_STORE_HELPER =
+ "sun.security.provider.certpath.ldap.LDAPCertStoreHelper";
+ private static final CertStoreHelper helper =
+ AccessController.doPrivileged(
+ new PrivilegedAction<CertStoreHelper>() {
+ public CertStoreHelper run() {
+ try {
+ Class<?> c = Class.forName(CERT_STORE_HELPER, true, null);
+ return (CertStoreHelper)c.newInstance();
+ } catch (ClassNotFoundException cnf) {
+ return null;
+ } catch (InstantiationException e) {
+ throw new AssertionError(e);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }});
+ static CertStoreHelper helper() {
+ return helper;
+ }
+ }
+
+ /**
* Creates a URICertStore.
*
* @param parameters specifying the URI
@@ -135,9 +163,10 @@
this.uri = ((URICertStoreParameters) params).uri;
// if ldap URI, use an LDAPCertStore to fetch certs and CRLs
if (uri.getScheme().toLowerCase().equals("ldap")) {
+ if (LDAP.helper() == null)
+ throw new NoSuchAlgorithmException("LDAP not present");
ldap = true;
- ldapCertStore =
- LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri));
+ ldapCertStore = LDAP.helper().getCertStore(uri);
ldapPath = uri.getPath();
// strip off leading '/'
if (ldapPath.charAt(0) == '/') {
@@ -219,8 +248,7 @@
if (ldap) {
X509CertSelector xsel = (X509CertSelector) selector;
try {
- xsel = new LDAPCertStore.LDAPCertSelector
- (xsel, xsel.getSubject(), ldapPath);
+ xsel = LDAP.helper().wrap(xsel, xsel.getSubject(), ldapPath);
} catch (IOException ioe) {
throw new CertStoreException(ioe);
}
@@ -340,7 +368,7 @@
if (ldap) {
X509CRLSelector xsel = (X509CRLSelector) selector;
try {
- xsel = new LDAPCertStore.LDAPCRLSelector(xsel, null, ldapPath);
+ xsel = LDAP.helper().wrap(xsel, null, ldapPath);
} catch (IOException ioe) {
throw new CertStoreException(ioe);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,1066 @@
+/*
+ * Copyright 2000-2006 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.provider.certpath.ldap;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.*;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NameNotFoundException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+
+import java.security.*;
+import java.security.cert.Certificate;
+import java.security.cert.*;
+import javax.security.auth.x500.X500Principal;
+
+import sun.misc.HexDumpEncoder;
+import sun.security.provider.certpath.X509CertificatePair;
+import sun.security.util.Cache;
+import sun.security.util.Debug;
+import sun.security.x509.X500Name;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * A <code>CertStore</code> that retrieves <code>Certificates</code> and
+ * <code>CRL</code>s from an LDAP directory, using the PKIX LDAP V2 Schema
+ * (RFC 2587):
+ * <a href="http://www.ietf.org/rfc/rfc2587.txt">
+ * http://www.ietf.org/rfc/rfc2587.txt</a>.
+ * <p>
+ * Before calling the {@link #engineGetCertificates engineGetCertificates} or
+ * {@link #engineGetCRLs engineGetCRLs} methods, the
+ * {@link #LDAPCertStore(CertStoreParameters)
+ * LDAPCertStore(CertStoreParameters)} constructor is called to create the
+ * <code>CertStore</code> and establish the DNS name and port of the LDAP
+ * server from which <code>Certificate</code>s and <code>CRL</code>s will be
+ * retrieved.
+ * <p>
+ * <b>Concurrent Access</b>
+ * <p>
+ * As described in the javadoc for <code>CertStoreSpi</code>, the
+ * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods
+ * must be thread-safe. That is, multiple threads may concurrently
+ * invoke these methods on a single <code>LDAPCertStore</code> object
+ * (or more than one) with no ill effects. This allows a
+ * <code>CertPathBuilder</code> to search for a CRL while simultaneously
+ * searching for further certificates, for instance.
+ * <p>
+ * This is achieved by adding the <code>synchronized</code> keyword to the
+ * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods.
+ * <p>
+ * This classes uses caching and requests multiple attributes at once to
+ * minimize LDAP round trips. The cache is associated with the CertStore
+ * instance. It uses soft references to hold the values to minimize impact
+ * on footprint and currently has a maximum size of 750 attributes and a
+ * 30 second default lifetime.
+ * <p>
+ * We always request CA certificates, cross certificate pairs, and ARLs in
+ * a single LDAP request when any one of them is needed. The reason is that
+ * we typically need all of them anyway and requesting them in one go can
+ * reduce the number of requests to a third. Even if we don't need them,
+ * these attributes are typically small enough not to cause a noticeable
+ * overhead. In addition, when the prefetchCRLs flag is true, we also request
+ * the full CRLs. It is currently false initially but set to true once any
+ * request for an ARL to the server returns an null value. The reason is
+ * that CRLs could be rather large but are rarely used. This implementation
+ * should improve performance in most cases.
+ *
+ * @see java.security.cert.CertStore
+ *
+ * @since 1.4
+ * @author Steve Hanna
+ * @author Andreas Sterbenz
+ */
+public class LDAPCertStore extends CertStoreSpi {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+
+ private final static boolean DEBUG = false;
+
+ /**
+ * LDAP attribute identifiers.
+ */
+ private static final String USER_CERT = "userCertificate;binary";
+ private static final String CA_CERT = "cACertificate;binary";
+ private static final String CROSS_CERT = "crossCertificatePair;binary";
+ private static final String CRL = "certificateRevocationList;binary";
+ private static final String ARL = "authorityRevocationList;binary";
+ private static final String DELTA_CRL = "deltaRevocationList;binary";
+
+ // Constants for various empty values
+ private final static String[] STRING0 = new String[0];
+
+ private final static byte[][] BB0 = new byte[0][];
+
+ private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes();
+
+ // cache related constants
+ private final static int DEFAULT_CACHE_SIZE = 750;
+ private final static int DEFAULT_CACHE_LIFETIME = 30;
+
+ private final static int LIFETIME;
+
+ private final static String PROP_LIFETIME =
+ "sun.security.certpath.ldap.cache.lifetime";
+
+ static {
+ String s = AccessController.doPrivileged(
+ new GetPropertyAction(PROP_LIFETIME));
+ if (s != null) {
+ LIFETIME = Integer.parseInt(s); // throws NumberFormatException
+ } else {
+ LIFETIME = DEFAULT_CACHE_LIFETIME;
+ }
+ }
+
+ /**
+ * The CertificateFactory used to decode certificates from
+ * their binary stored form.
+ */
+ private CertificateFactory cf;
+ /**
+ * The JNDI directory context.
+ */
+ private DirContext ctx;
+
+ /**
+ * Flag indicating whether we should prefetch CRLs.
+ */
+ private boolean prefetchCRLs = false;
+
+ private final Cache valueCache;
+
+ private int cacheHits = 0;
+ private int cacheMisses = 0;
+ private int requests = 0;
+
+ /**
+ * Creates a <code>CertStore</code> with the specified parameters.
+ * For this class, the parameters object must be an instance of
+ * <code>LDAPCertStoreParameters</code>.
+ *
+ * @param params the algorithm parameters
+ * @exception InvalidAlgorithmParameterException if params is not an
+ * instance of <code>LDAPCertStoreParameters</code>
+ */
+ public LDAPCertStore(CertStoreParameters params)
+ throws InvalidAlgorithmParameterException {
+ super(params);
+ if (!(params instanceof LDAPCertStoreParameters))
+ throw new InvalidAlgorithmParameterException(
+ "parameters must be LDAPCertStoreParameters");
+
+ LDAPCertStoreParameters lparams = (LDAPCertStoreParameters) params;
+
+ // Create InitialDirContext needed to communicate with the server
+ createInitialDirContext(lparams.getServerName(), lparams.getPort());
+
+ // Create CertificateFactory for use later on
+ try {
+ cf = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new InvalidAlgorithmParameterException(
+ "unable to create CertificateFactory for X.509");
+ }
+ if (LIFETIME == 0) {
+ valueCache = Cache.newNullCache();
+ } else if (LIFETIME < 0) {
+ valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE);
+ } else {
+ valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE, LIFETIME);
+ }
+ }
+
+ /**
+ * Returns an LDAP CertStore. This method consults a cache of
+ * CertStores (shared per JVM) using the LDAP server/port as a key.
+ */
+ private static final Cache certStoreCache = Cache.newSoftMemoryCache(185);
+ static synchronized CertStore getInstance(LDAPCertStoreParameters params)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ CertStore lcs = (CertStore) certStoreCache.get(params);
+ if (lcs == null) {
+ lcs = CertStore.getInstance("LDAP", params);
+ certStoreCache.put(params, lcs);
+ } else {
+ if (debug != null) {
+ debug.println("LDAPCertStore.getInstance: cache hit");
+ }
+ }
+ return lcs;
+ }
+
+ /**
+ * Create InitialDirContext.
+ *
+ * @param server Server DNS name hosting LDAP service
+ * @param port Port at which server listens for requests
+ * @throws InvalidAlgorithmParameterException if creation fails
+ */
+ private void createInitialDirContext(String server, int port)
+ throws InvalidAlgorithmParameterException {
+ String url = "ldap://" + server + ":" + port;
+ Hashtable<String,Object> env = new Hashtable<String,Object>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,
+ "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, url);
+ try {
+ ctx = new InitialDirContext(env);
+ /*
+ * By default, follow referrals unless application has
+ * overridden property in an application resource file.
+ */
+ Hashtable<?,?> currentEnv = ctx.getEnvironment();
+ if (currentEnv.get(Context.REFERRAL) == null) {
+ ctx.addToEnvironment(Context.REFERRAL, "follow");
+ }
+ } catch (NamingException e) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineInit about to throw "
+ + "InvalidAlgorithmParameterException");
+ e.printStackTrace();
+ }
+ Exception ee = new InvalidAlgorithmParameterException
+ ("unable to create InitialDirContext using supplied parameters");
+ ee.initCause(e);
+ throw (InvalidAlgorithmParameterException)ee;
+ }
+ }
+
+ /**
+ * Private class encapsulating the actual LDAP operations and cache
+ * handling. Use:
+ *
+ * LDAPRequest request = new LDAPRequest(dn);
+ * request.addRequestedAttribute(CROSS_CERT);
+ * request.addRequestedAttribute(CA_CERT);
+ * byte[][] crossValues = request.getValues(CROSS_CERT);
+ * byte[][] caValues = request.getValues(CA_CERT);
+ *
+ * At most one LDAP request is sent for each instance created. If all
+ * getValues() calls can be satisfied from the cache, no request
+ * is sent at all. If a request is sent, all requested attributes
+ * are always added to the cache irrespective of whether the getValues()
+ * method is called.
+ */
+ private class LDAPRequest {
+
+ private final String name;
+ private Map<String, byte[][]> valueMap;
+ private final List<String> requestedAttributes;
+
+ LDAPRequest(String name) {
+ this.name = name;
+ requestedAttributes = new ArrayList<String>(5);
+ }
+
+ String getName() {
+ return name;
+ }
+
+ void addRequestedAttribute(String attrId) {
+ if (valueMap != null) {
+ throw new IllegalStateException("Request already sent");
+ }
+ requestedAttributes.add(attrId);
+ }
+
+ /**
+ * Gets one or more binary values from an attribute.
+ *
+ * @param name the location holding the attribute
+ * @param attrId the attribute identifier
+ * @return an array of binary values (byte arrays)
+ * @throws NamingException if a naming exception occurs
+ */
+ byte[][] getValues(String attrId) throws NamingException {
+ if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) {
+ System.out.println("Cache hits: " + cacheHits + "; misses: "
+ + cacheMisses);
+ }
+ String cacheKey = name + "|" + attrId;
+ byte[][] values = (byte[][])valueCache.get(cacheKey);
+ if (values != null) {
+ cacheHits++;
+ return values;
+ }
+ cacheMisses++;
+ Map<String, byte[][]> attrs = getValueMap();
+ values = attrs.get(attrId);
+ return values;
+ }
+
+ /**
+ * Get a map containing the values for this request. The first time
+ * this method is called on an object, the LDAP request is sent,
+ * the results parsed and added to a private map and also to the
+ * cache of this LDAPCertStore. Subsequent calls return the private
+ * map immediately.
+ *
+ * The map contains an entry for each requested attribute. The
+ * attribute name is the key, values are byte[][]. If there are no
+ * values for that attribute, values are byte[0][].
+ *
+ * @return the value Map
+ * @throws NamingException if a naming exception occurs
+ */
+ private Map<String, byte[][]> getValueMap() throws NamingException {
+ if (valueMap != null) {
+ return valueMap;
+ }
+ if (DEBUG) {
+ System.out.println("Request: " + name + ":" + requestedAttributes);
+ requests++;
+ if (requests % 5 == 0) {
+ System.out.println("LDAP requests: " + requests);
+ }
+ }
+ valueMap = new HashMap<String, byte[][]>(8);
+ String[] attrIds = requestedAttributes.toArray(STRING0);
+ Attributes attrs;
+ try {
+ attrs = ctx.getAttributes(name, attrIds);
+ } catch (NameNotFoundException e) {
+ // name does not exist on this LDAP server
+ // treat same as not attributes found
+ attrs = EMPTY_ATTRIBUTES;
+ }
+ for (String attrId : requestedAttributes) {
+ Attribute attr = attrs.get(attrId);
+ byte[][] values = getAttributeValues(attr);
+ cacheAttribute(attrId, values);
+ valueMap.put(attrId, values);
+ }
+ return valueMap;
+ }
+
+ /**
+ * Add the values to the cache.
+ */
+ private void cacheAttribute(String attrId, byte[][] values) {
+ String cacheKey = name + "|" + attrId;
+ valueCache.put(cacheKey, values);
+ }
+
+ /**
+ * Get the values for the given attribute. If the attribute is null
+ * or does not contain any values, a zero length byte array is
+ * returned. NOTE that it is assumed that all values are byte arrays.
+ */
+ private byte[][] getAttributeValues(Attribute attr)
+ throws NamingException {
+ byte[][] values;
+ if (attr == null) {
+ values = BB0;
+ } else {
+ values = new byte[attr.size()][];
+ int i = 0;
+ NamingEnumeration<?> enum_ = attr.getAll();
+ while (enum_.hasMore()) {
+ Object obj = enum_.next();
+ if (debug != null) {
+ if (obj instanceof String) {
+ debug.println("LDAPCertStore.getAttrValues() "
+ + "enum.next is a string!: " + obj);
+ }
+ }
+ byte[] value = (byte[])obj;
+ values[i++] = value;
+ }
+ }
+ return values;
+ }
+
+ }
+
+ /*
+ * Gets certificates from an attribute id and location in the LDAP
+ * directory. Returns a Collection containing only the Certificates that
+ * match the specified CertSelector.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @param sel a CertSelector that the Certificates must match
+ * @return a Collection of Certificates found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509Certificate> getCertificates(LDAPRequest request,
+ String id, X509CertSelector sel) throws CertStoreException {
+
+ /* fetch encoded certs from storage */
+ byte[][] encodedCert;
+ try {
+ encodedCert = request.getValues(id);
+ } catch (NamingException namingEx) {
+ throw new CertStoreException(namingEx);
+ }
+
+ int n = encodedCert.length;
+ if (n == 0) {
+ return Collections.<X509Certificate>emptySet();
+ }
+
+ List<X509Certificate> certs = new ArrayList<X509Certificate>(n);
+ /* decode certs and check if they satisfy selector */
+ for (int i = 0; i < n; i++) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]);
+ try {
+ Certificate cert = cf.generateCertificate(bais);
+ if (sel.match(cert)) {
+ certs.add((X509Certificate)cert);
+ }
+ } catch (CertificateException e) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.getCertificates() encountered "
+ + "exception while parsing cert, skipping the bad data: ");
+ HexDumpEncoder encoder = new HexDumpEncoder();
+ debug.println(
+ "[ " + encoder.encodeBuffer(encodedCert[i]) + " ]");
+ }
+ }
+ }
+
+ return certs;
+ }
+
+ /*
+ * Gets certificate pairs from an attribute id and location in the LDAP
+ * directory.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @return a Collection of X509CertificatePairs found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509CertificatePair> getCertPairs(
+ LDAPRequest request, String id) throws CertStoreException {
+
+ /* fetch the encoded cert pairs from storage */
+ byte[][] encodedCertPair;
+ try {
+ encodedCertPair = request.getValues(id);
+ } catch (NamingException namingEx) {
+ throw new CertStoreException(namingEx);
+ }
+
+ int n = encodedCertPair.length;
+ if (n == 0) {
+ return Collections.<X509CertificatePair>emptySet();
+ }
+
+ List<X509CertificatePair> certPairs =
+ new ArrayList<X509CertificatePair>(n);
+ /* decode each cert pair and add it to the Collection */
+ for (int i = 0; i < n; i++) {
+ try {
+ X509CertificatePair certPair =
+ X509CertificatePair.generateCertificatePair(encodedCertPair[i]);
+ certPairs.add(certPair);
+ } catch (CertificateException e) {
+ if (debug != null) {
+ debug.println(
+ "LDAPCertStore.getCertPairs() encountered exception "
+ + "while parsing cert, skipping the bad data: ");
+ HexDumpEncoder encoder = new HexDumpEncoder();
+ debug.println(
+ "[ " + encoder.encodeBuffer(encodedCertPair[i]) + " ]");
+ }
+ }
+ }
+
+ return certPairs;
+ }
+
+ /*
+ * Looks at certificate pairs stored in the crossCertificatePair attribute
+ * at the specified location in the LDAP directory. Returns a Collection
+ * containing all Certificates stored in the forward component that match
+ * the forward CertSelector and all Certificates stored in the reverse
+ * component that match the reverse CertSelector.
+ * <p>
+ * If either forward or reverse is null, all certificates from the
+ * corresponding component will be rejected.
+ *
+ * @param name the location to look in
+ * @param forward the forward CertSelector (or null)
+ * @param reverse the reverse CertSelector (or null)
+ * @return a Collection of Certificates found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509Certificate> getMatchingCrossCerts(
+ LDAPRequest request, X509CertSelector forward,
+ X509CertSelector reverse)
+ throws CertStoreException {
+ // Get the cert pairs
+ Collection<X509CertificatePair> certPairs =
+ getCertPairs(request, CROSS_CERT);
+
+ // Find Certificates that match and put them in a list
+ ArrayList<X509Certificate> matchingCerts =
+ new ArrayList<X509Certificate>();
+ for (X509CertificatePair certPair : certPairs) {
+ X509Certificate cert;
+ if (forward != null) {
+ cert = certPair.getForward();
+ if ((cert != null) && forward.match(cert)) {
+ matchingCerts.add(cert);
+ }
+ }
+ if (reverse != null) {
+ cert = certPair.getReverse();
+ if ((cert != null) && reverse.match(cert)) {
+ matchingCerts.add(cert);
+ }
+ }
+ }
+ return matchingCerts;
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector. If no <code>Certificate</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.
+ * <p>
+ * It is not practical to search every entry in the LDAP database for
+ * matching <code>Certificate</code>s. Instead, the <code>CertSelector</code>
+ * is examined in order to determine where matching <code>Certificate</code>s
+ * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
+ * If the subject is specified, its directory entry is searched. If the
+ * issuer is specified, its directory entry is searched. If neither the
+ * subject nor the issuer are specified (or the selector is not an
+ * <code>X509CertSelector</code>), a <code>CertStoreException</code> is
+ * thrown.
+ *
+ * @param selector a <code>CertSelector</code> used to select which
+ * <code>Certificate</code>s should be returned.
+ * @return a <code>Collection</code> of <code>Certificate</code>s that
+ * match the specified selector
+ * @throws CertStoreException if an exception occurs
+ */
+ public synchronized Collection<X509Certificate> engineGetCertificates
+ (CertSelector selector) throws CertStoreException {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() selector: "
+ + String.valueOf(selector));
+ }
+
+ if (selector == null) {
+ selector = new X509CertSelector();
+ }
+ if (!(selector instanceof X509CertSelector)) {
+ throw new CertStoreException("LDAPCertStore needs an X509CertSelector " +
+ "to find certs");
+ }
+ X509CertSelector xsel = (X509CertSelector) selector;
+ int basicConstraints = xsel.getBasicConstraints();
+ String subject = xsel.getSubjectAsString();
+ String issuer = xsel.getIssuerAsString();
+ HashSet<X509Certificate> certs = new HashSet<X509Certificate>();
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: "
+ + basicConstraints);
+ }
+
+ // basicConstraints:
+ // -2: only EE certs accepted
+ // -1: no check is done
+ // 0: any CA certificate accepted
+ // >1: certificate's basicConstraints extension pathlen must match
+ if (subject != null) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() "
+ + "subject is not null");
+ }
+ LDAPRequest request = new LDAPRequest(subject);
+ if (basicConstraints > -2) {
+ request.addRequestedAttribute(CROSS_CERT);
+ request.addRequestedAttribute(CA_CERT);
+ request.addRequestedAttribute(ARL);
+ if (prefetchCRLs) {
+ request.addRequestedAttribute(CRL);
+ }
+ }
+ if (basicConstraints < 0) {
+ request.addRequestedAttribute(USER_CERT);
+ }
+
+ if (basicConstraints > -2) {
+ certs.addAll(getMatchingCrossCerts(request, xsel, null));
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() after "
+ + "getMatchingCrossCerts(subject,xsel,null),certs.size(): "
+ + certs.size());
+ }
+ certs.addAll(getCertificates(request, CA_CERT, xsel));
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() after "
+ + "getCertificates(subject,CA_CERT,xsel),certs.size(): "
+ + certs.size());
+ }
+ }
+ if (basicConstraints < 0) {
+ certs.addAll(getCertificates(request, USER_CERT, xsel));
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() after "
+ + "getCertificates(subject,USER_CERT, xsel),certs.size(): "
+ + certs.size());
+ }
+ }
+ } else {
+ if (debug != null) {
+ debug.println
+ ("LDAPCertStore.engineGetCertificates() subject is null");
+ }
+ if (basicConstraints == -2) {
+ throw new CertStoreException("need subject to find EE certs");
+ }
+ if (issuer == null) {
+ throw new CertStoreException("need subject or issuer to find certs");
+ }
+ }
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() about to "
+ + "getMatchingCrossCerts...");
+ }
+ if ((issuer != null) && (basicConstraints > -2)) {
+ LDAPRequest request = new LDAPRequest(issuer);
+ request.addRequestedAttribute(CROSS_CERT);
+ request.addRequestedAttribute(CA_CERT);
+ request.addRequestedAttribute(ARL);
+ if (prefetchCRLs) {
+ request.addRequestedAttribute(CRL);
+ }
+
+ certs.addAll(getMatchingCrossCerts(request, null, xsel));
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() after "
+ + "getMatchingCrossCerts(issuer,null,xsel),certs.size(): "
+ + certs.size());
+ }
+ certs.addAll(getCertificates(request, CA_CERT, xsel));
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() after "
+ + "getCertificates(issuer,CA_CERT,xsel),certs.size(): "
+ + certs.size());
+ }
+ }
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCertificates() returning certs");
+ }
+ return certs;
+ }
+
+ /*
+ * Gets CRLs from an attribute id and location in the LDAP directory.
+ * Returns a Collection containing only the CRLs that match the
+ * specified CRLSelector.
+ *
+ * @param name the location holding the attribute
+ * @param id the attribute identifier
+ * @param sel a CRLSelector that the CRLs must match
+ * @return a Collection of CRLs found
+ * @throws CertStoreException if an exception occurs
+ */
+ private Collection<X509CRL> getCRLs(LDAPRequest request, String id,
+ X509CRLSelector sel) throws CertStoreException {
+
+ /* fetch the encoded crls from storage */
+ byte[][] encodedCRL;
+ try {
+ encodedCRL = request.getValues(id);
+ } catch (NamingException namingEx) {
+ throw new CertStoreException(namingEx);
+ }
+
+ int n = encodedCRL.length;
+ if (n == 0) {
+ return Collections.<X509CRL>emptySet();
+ }
+
+ List<X509CRL> crls = new ArrayList<X509CRL>(n);
+ /* decode each crl and check if it matches selector */
+ for (int i = 0; i < n; i++) {
+ try {
+ CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i]));
+ if (sel.match(crl)) {
+ crls.add((X509CRL)crl);
+ }
+ } catch (CRLException e) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.getCRLs() encountered exception"
+ + " while parsing CRL, skipping the bad data: ");
+ HexDumpEncoder encoder = new HexDumpEncoder();
+ debug.println("[ " + encoder.encodeBuffer(encodedCRL[i]) + " ]");
+ }
+ }
+ }
+
+ return crls;
+ }
+
+ /**
+ * Returns a <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector. If no <code>CRL</code>s
+ * match the selector, an empty <code>Collection</code> will be returned.
+ * <p>
+ * It is not practical to search every entry in the LDAP database for
+ * matching <code>CRL</code>s. Instead, the <code>CRLSelector</code>
+ * is examined in order to determine where matching <code>CRL</code>s
+ * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
+ * If issuerNames or certChecking are specified, the issuer's directory
+ * entry is searched. If neither issuerNames or certChecking are specified
+ * (or the selector is not an <code>X509CRLSelector</code>), a
+ * <code>CertStoreException</code> is thrown.
+ *
+ * @param selector A <code>CRLSelector</code> used to select which
+ * <code>CRL</code>s should be returned. Specify <code>null</code>
+ * to return all <code>CRL</code>s.
+ * @return A <code>Collection</code> of <code>CRL</code>s that
+ * match the specified selector
+ * @throws CertStoreException if an exception occurs
+ */
+ public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
+ throws CertStoreException {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCRLs() selector: "
+ + selector);
+ }
+ // Set up selector and collection to hold CRLs
+ if (selector == null) {
+ selector = new X509CRLSelector();
+ }
+ if (!(selector instanceof X509CRLSelector)) {
+ throw new CertStoreException("need X509CRLSelector to find CRLs");
+ }
+ X509CRLSelector xsel = (X509CRLSelector) selector;
+ HashSet<X509CRL> crls = new HashSet<X509CRL>();
+
+ // Look in directory entry for issuer of cert we're checking.
+ Collection<Object> issuerNames;
+ X509Certificate certChecking = xsel.getCertificateChecking();
+ if (certChecking != null) {
+ issuerNames = new HashSet<Object>();
+ X500Principal issuer = certChecking.getIssuerX500Principal();
+ issuerNames.add(issuer.getName(X500Principal.RFC2253));
+ } else {
+ // But if we don't know which cert we're checking, try the directory
+ // entries of all acceptable CRL issuers
+ issuerNames = xsel.getIssuerNames();
+ if (issuerNames == null) {
+ throw new CertStoreException("need issuerNames or certChecking to "
+ + "find CRLs");
+ }
+ }
+ for (Object nameObject : issuerNames) {
+ String issuerName;
+ if (nameObject instanceof byte[]) {
+ try {
+ X500Principal issuer = new X500Principal((byte[])nameObject);
+ issuerName = issuer.getName(X500Principal.RFC2253);
+ } catch (IllegalArgumentException e) {
+ continue;
+ }
+ } else {
+ issuerName = (String)nameObject;
+ }
+ // If all we want is CA certs, try to get the (probably shorter) ARL
+ Collection<X509CRL> entryCRLs = Collections.<X509CRL>emptySet();
+ if (certChecking == null || certChecking.getBasicConstraints() != -1) {
+ LDAPRequest request = new LDAPRequest(issuerName);
+ request.addRequestedAttribute(CROSS_CERT);
+ request.addRequestedAttribute(CA_CERT);
+ request.addRequestedAttribute(ARL);
+ if (prefetchCRLs) {
+ request.addRequestedAttribute(CRL);
+ }
+ try {
+ entryCRLs = getCRLs(request, ARL, xsel);
+ if (entryCRLs.isEmpty()) {
+ // no ARLs found. We assume that means that there are
+ // no ARLs on this server at all and prefetch the CRLs.
+ prefetchCRLs = true;
+ } else {
+ crls.addAll(entryCRLs);
+ }
+ } catch (CertStoreException e) {
+ if (debug != null) {
+ debug.println("LDAPCertStore.engineGetCRLs non-fatal error "
+ + "retrieving ARLs:" + e);
+ e.printStackTrace();
+ }
+ }
+ }
+ // Otherwise, get the CRL
+ // if certChecking is null, we don't know if we should look in ARL or CRL
+ // attribute, so check both for matching CRLs.
+ if (entryCRLs.isEmpty() || certChecking == null) {
+ LDAPRequest request = new LDAPRequest(issuerName);
+ request.addRequestedAttribute(CRL);
+ entryCRLs = getCRLs(request, CRL, xsel);
+ crls.addAll(entryCRLs);
+ }
+ }
+ return crls;
+ }
+
+ // converts an LDAP URI into LDAPCertStoreParameters
+ static LDAPCertStoreParameters getParameters(URI uri) {
+ String host = uri.getHost();
+ if (host == null) {
+ return new SunLDAPCertStoreParameters();
+ } else {
+ int port = uri.getPort();
+ return (port == -1
+ ? new SunLDAPCertStoreParameters(host)
+ : new SunLDAPCertStoreParameters(host, port));
+ }
+ }
+
+ /*
+ * Subclass of LDAPCertStoreParameters with overridden equals/hashCode
+ * methods. This is necessary because the parameters are used as
+ * keys in the LDAPCertStore cache.
+ */
+ private static class SunLDAPCertStoreParameters
+ extends LDAPCertStoreParameters {
+
+ private volatile int hashCode = 0;
+
+ SunLDAPCertStoreParameters(String serverName, int port) {
+ super(serverName, port);
+ }
+ SunLDAPCertStoreParameters(String serverName) {
+ super(serverName);
+ }
+ SunLDAPCertStoreParameters() {
+ super();
+ }
+ public boolean equals(Object obj) {
+ if (!(obj instanceof LDAPCertStoreParameters)) {
+ return false;
+ }
+ LDAPCertStoreParameters params = (LDAPCertStoreParameters) obj;
+ return (getPort() == params.getPort() &&
+ getServerName().equalsIgnoreCase(params.getServerName()));
+ }
+ public int hashCode() {
+ if (hashCode == 0) {
+ int result = 17;
+ result = 37*result + getPort();
+ result = 37*result + getServerName().toLowerCase().hashCode();
+ hashCode = result;
+ }
+ return hashCode;
+ }
+ }
+
+ /*
+ * This inner class wraps an existing X509CertSelector and adds
+ * additional criteria to match on when the certificate's subject is
+ * different than the LDAP Distinguished Name entry. The LDAPCertStore
+ * implementation uses the subject DN as the directory entry for
+ * looking up certificates. This can be problematic if the certificates
+ * that you want to fetch have a different subject DN than the entry
+ * where they are stored. You could set the selector's subject to the
+ * LDAP DN entry, but then the resulting match would fail to find the
+ * desired certificates because the subject DNs would not match. This
+ * class avoids that problem by introducing a certSubject which should
+ * be set to the certificate's subject DN when it is different than
+ * the LDAP DN.
+ */
+ static class LDAPCertSelector extends X509CertSelector {
+
+ private X500Principal certSubject;
+ private X509CertSelector selector;
+ private X500Principal subject;
+
+ /**
+ * Creates an LDAPCertSelector.
+ *
+ * @param selector the X509CertSelector to wrap
+ * @param certSubject the subject DN of the certificate that you want
+ * to retrieve via LDAP
+ * @param ldapDN the LDAP DN where the certificate is stored
+ */
+ LDAPCertSelector(X509CertSelector selector, X500Principal certSubject,
+ String ldapDN) throws IOException {
+ this.selector = selector == null ? new X509CertSelector() : selector;
+ this.certSubject = certSubject;
+ this.subject = new X500Name(ldapDN).asX500Principal();
+ }
+
+ // we only override the get (accessor methods) since the set methods
+ // will not be invoked by the code that uses this LDAPCertSelector.
+ public X509Certificate getCertificate() {
+ return selector.getCertificate();
+ }
+ public BigInteger getSerialNumber() {
+ return selector.getSerialNumber();
+ }
+ public X500Principal getIssuer() {
+ return selector.getIssuer();
+ }
+ public String getIssuerAsString() {
+ return selector.getIssuerAsString();
+ }
+ public byte[] getIssuerAsBytes() throws IOException {
+ return selector.getIssuerAsBytes();
+ }
+ public X500Principal getSubject() {
+ // return the ldap DN
+ return subject;
+ }
+ public String getSubjectAsString() {
+ // return the ldap DN
+ return subject.getName();
+ }
+ public byte[] getSubjectAsBytes() throws IOException {
+ // return the encoded ldap DN
+ return subject.getEncoded();
+ }
+ public byte[] getSubjectKeyIdentifier() {
+ return selector.getSubjectKeyIdentifier();
+ }
+ public byte[] getAuthorityKeyIdentifier() {
+ return selector.getAuthorityKeyIdentifier();
+ }
+ public Date getCertificateValid() {
+ return selector.getCertificateValid();
+ }
+ public Date getPrivateKeyValid() {
+ return selector.getPrivateKeyValid();
+ }
+ public String getSubjectPublicKeyAlgID() {
+ return selector.getSubjectPublicKeyAlgID();
+ }
+ public PublicKey getSubjectPublicKey() {
+ return selector.getSubjectPublicKey();
+ }
+ public boolean[] getKeyUsage() {
+ return selector.getKeyUsage();
+ }
+ public Set<String> getExtendedKeyUsage() {
+ return selector.getExtendedKeyUsage();
+ }
+ public boolean getMatchAllSubjectAltNames() {
+ return selector.getMatchAllSubjectAltNames();
+ }
+ public Collection<List<?>> getSubjectAlternativeNames() {
+ return selector.getSubjectAlternativeNames();
+ }
+ public byte[] getNameConstraints() {
+ return selector.getNameConstraints();
+ }
+ public int getBasicConstraints() {
+ return selector.getBasicConstraints();
+ }
+ public Set<String> getPolicy() {
+ return selector.getPolicy();
+ }
+ public Collection<List<?>> getPathToNames() {
+ return selector.getPathToNames();
+ }
+
+ public boolean match(Certificate cert) {
+ // temporarily set the subject criterion to the certSubject
+ // so that match will not reject the desired certificates
+ selector.setSubject(certSubject);
+ boolean match = selector.match(cert);
+ selector.setSubject(subject);
+ return match;
+ }
+ }
+
+ /**
+ * This class has the same purpose as LDAPCertSelector except it is for
+ * X.509 CRLs.
+ */
+ static class LDAPCRLSelector extends X509CRLSelector {
+
+ private X509CRLSelector selector;
+ private Collection<X500Principal> certIssuers;
+ private Collection<X500Principal> issuers;
+ private HashSet<Object> issuerNames;
+
+ /**
+ * Creates an LDAPCRLSelector.
+ *
+ * @param selector the X509CRLSelector to wrap
+ * @param certIssuers the issuer DNs of the CRLs that you want
+ * to retrieve via LDAP
+ * @param ldapDN the LDAP DN where the CRL is stored
+ */
+ LDAPCRLSelector(X509CRLSelector selector,
+ Collection<X500Principal> certIssuers, String ldapDN)
+ throws IOException {
+ this.selector = selector == null ? new X509CRLSelector() : selector;
+ this.certIssuers = certIssuers;
+ issuerNames = new HashSet<Object>();
+ issuerNames.add(ldapDN);
+ issuers = new HashSet<X500Principal>();
+ issuers.add(new X500Name(ldapDN).asX500Principal());
+ }
+ // we only override the get (accessor methods) since the set methods
+ // will not be invoked by the code that uses this LDAPCRLSelector.
+ public Collection<X500Principal> getIssuers() {
+ // return the ldap DN
+ return Collections.unmodifiableCollection(issuers);
+ }
+ public Collection<Object> getIssuerNames() {
+ // return the ldap DN
+ return Collections.unmodifiableCollection(issuerNames);
+ }
+ public BigInteger getMinCRL() {
+ return selector.getMinCRL();
+ }
+ public BigInteger getMaxCRL() {
+ return selector.getMaxCRL();
+ }
+ public Date getDateAndTime() {
+ return selector.getDateAndTime();
+ }
+ public X509Certificate getCertificateChecking() {
+ return selector.getCertificateChecking();
+ }
+ public boolean match(CRL crl) {
+ // temporarily set the issuer criterion to the certIssuers
+ // so that match will not reject the desired CRL
+ selector.setIssuers(certIssuers);
+ boolean match = selector.match(crl);
+ selector.setIssuers(issuers);
+ return match;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreHelper.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.provider.certpath.ldap;
+
+import java.net.URI;
+import java.util.Collection;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.cert.CertStore;
+import java.security.cert.X509CertSelector;
+import java.security.cert.X509CRLSelector;
+import javax.security.auth.x500.X500Principal;
+import java.io.IOException;
+
+import sun.security.provider.certpath.CertStoreHelper;
+
+/**
+ * LDAP implementation of CertStoreHelper.
+ */
+
+public class LDAPCertStoreHelper
+ implements CertStoreHelper
+{
+ public LDAPCertStoreHelper() { }
+
+ @Override
+ public CertStore getCertStore(URI uri)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException
+ {
+ return LDAPCertStore.getInstance(LDAPCertStore.getParameters(uri));
+ }
+
+ @Override
+ public X509CertSelector wrap(X509CertSelector selector,
+ X500Principal certSubject,
+ String ldapDN)
+ throws IOException
+ {
+ return new LDAPCertStore.LDAPCertSelector(selector, certSubject, ldapDN);
+ }
+
+ @Override
+ public X509CRLSelector wrap(X509CRLSelector selector,
+ Collection<X500Principal> certIssuers,
+ String ldapDN)
+ throws IOException
+ {
+ return new LDAPCertStore.LDAPCRLSelector(selector, certIssuers, ldapDN);
+ }
+}
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Wed Jul 05 17:02:18 2017 +0200
@@ -104,11 +104,11 @@
int uid;
if (user.isSpecial()) {
uid = -1;
- if (who.getName().equals(UnixUserPrincipals.SPECIAL_OWNER.getName()))
+ if (who == UnixUserPrincipals.SPECIAL_OWNER)
flags |= ACE_OWNER;
- else if (who.getName().equals(UnixUserPrincipals.SPECIAL_GROUP.getName()))
- flags |= ACE_GROUP;
- else if (who.getName().equals(UnixUserPrincipals.SPECIAL_EVERYONE.getName()))
+ else if (who == UnixUserPrincipals.SPECIAL_GROUP)
+ flags |= (ACE_GROUP | ACE_IDENTIFIER_GROUP);
+ else if (who == UnixUserPrincipals.SPECIAL_EVERYONE)
flags |= ACE_EVERYONE;
else
throw new AssertionError("Unable to map special identifier");
@@ -281,7 +281,7 @@
aceFlags.add(AclEntryFlag.DIRECTORY_INHERIT);
if ((flags & ACE_NO_PROPAGATE_INHERIT_ACE) > 0)
aceFlags.add(AclEntryFlag.NO_PROPAGATE_INHERIT);
- if ((flags & ACE_INHERIT_ONLY_ACE ) > 0)
+ if ((flags & ACE_INHERIT_ONLY_ACE) > 0)
aceFlags.add(AclEntryFlag.INHERIT_ONLY);
// build the ACL entry and add it to the list
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixDirectoryStream.java Wed Jul 05 17:02:18 2017 +0200
@@ -235,7 +235,8 @@
@Override
public void remove() {
if (isClosed) {
- throw new ClosedDirectoryStreamException();
+ throwAsConcurrentModificationException(new
+ ClosedDirectoryStreamException());
}
Path entry;
synchronized (this) {
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsDirectoryStream.java Wed Jul 05 17:02:18 2017 +0200
@@ -179,7 +179,7 @@
synchronized (closeLock) {
if (!isOpen)
throwAsConcurrentModificationException(new
- IllegalStateException("Directory stream is closed"));
+ ClosedDirectoryStreamException());
try {
name = FindNextFile(handle, findDataBuffer.address());
if (name == null) {
@@ -236,7 +236,8 @@
@Override
public void remove() {
if (!isOpen) {
- throw new IllegalStateException("Directory stream is closed");
+ throwAsConcurrentModificationException(new
+ ClosedDirectoryStreamException());
}
Path entry;
synchronized (this) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/B6886436.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/**
+ * @test
+ * @bug 6886436
+ * @summary
+ */
+
+import com.sun.net.httpserver.*;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.logging.*;
+import java.io.*;
+import java.net.*;
+
+public class B6886436 {
+
+ public static void main (String[] args) throws Exception {
+ Logger logger = Logger.getLogger ("com.sun.net.httpserver");
+ ConsoleHandler c = new ConsoleHandler();
+ c.setLevel (Level.WARNING);
+ logger.addHandler (c);
+ logger.setLevel (Level.WARNING);
+ Handler handler = new Handler();
+ InetSocketAddress addr = new InetSocketAddress (0);
+ HttpServer server = HttpServer.create (addr, 0);
+ HttpContext ctx = server.createContext ("/test", handler);
+ ExecutorService executor = Executors.newCachedThreadPool();
+ server.setExecutor (executor);
+ server.start ();
+
+ URL url = new URL ("http://localhost:"+server.getAddress().getPort()+"/test/foo.html");
+ HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
+ try {
+ InputStream is = urlc.getInputStream();
+ while (is.read()!= -1) ;
+ is.close ();
+ urlc = (HttpURLConnection)url.openConnection ();
+ urlc.setReadTimeout (3000);
+ is = urlc.getInputStream();
+ while (is.read()!= -1);
+ is.close ();
+
+ } catch (IOException e) {
+ server.stop(2);
+ executor.shutdown();
+ throw new RuntimeException ("Test failed");
+ }
+ server.stop(2);
+ executor.shutdown();
+ System.out.println ("OK");
+ }
+
+ public static boolean error = false;
+
+ static class Handler implements HttpHandler {
+ int invocation = 1;
+ public void handle (HttpExchange t)
+ throws IOException
+ {
+ InputStream is = t.getRequestBody();
+ Headers map = t.getRequestHeaders();
+ Headers rmap = t.getResponseHeaders();
+ while (is.read () != -1) ;
+ is.close();
+ // send a 204 response with an empty chunked body
+ t.sendResponseHeaders (204, 0);
+ t.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Double/ToString.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/*
+ * @test
+ * @bug 4428022
+ * @summary Tests for Double.toString
+ * @author Andrew Haley <aph@redhat.com>
+ */
+
+public class ToString {
+
+ public static void main(String args[]) {
+ if (!Double.toString(0.001).equals("0.001"))
+ throw new RuntimeException("Double.toString(0.001) is not \"0.001\"");
+ if (!Double.toString(0.002).equals("0.002"))
+ throw new RuntimeException("Double.toString(0.001) is not \"0.002\"");
+ }
+}
--- a/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/lang/management/RuntimeMXBean/GetSystemProperties.java Wed Jul 05 17:02:18 2017 +0200
@@ -49,6 +49,21 @@
private static final String VALUE4 = "test.property.value4";
public static void main(String[] argv) throws Exception {
+ // Save a copy of the original system properties
+ Properties props = System.getProperties();
+
+ try {
+ // replace the system Properties object for any modification
+ // in case jtreg caches a copy
+ System.setProperties(new Properties(props));
+ runTest();
+ } finally {
+ // restore original system properties
+ System.setProperties(props);
+ }
+ }
+
+ private static void runTest() throws Exception {
RuntimeMXBean mbean = ManagementFactory.getRuntimeMXBean();
// Print all system properties
@@ -88,7 +103,10 @@
Map<String,String> props2 = mbean.getSystemProperties();
// expect the system properties returned should be
// same as the one before adding KEY3 and KEY4
- props1.equals(props2);
+ if (!props1.equals(props2)) {
+ throw new RuntimeException("Two copies of system properties " +
+ "are expected to be equal");
+ }
System.out.println("Test passed.");
}
--- a/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/lang/management/RuntimeMXBean/PropertiesTest.java Wed Jul 05 17:02:18 2017 +0200
@@ -40,8 +40,21 @@
public class PropertiesTest {
private static int NUM_MYPROPS = 3;
public static void main(String[] argv) throws Exception {
- Properties sysProps = System.getProperties();
+ // Save a copy of the original system properties
+ Properties props = System.getProperties();
+ try {
+ // replace the system Properties object for any modification
+ // in case jtreg caches a copy
+ System.setProperties(new Properties(props));
+ runTest(props.size());
+ } finally {
+ // restore original system properties
+ System.setProperties(props);
+ }
+ }
+
+ private static void runTest(int sysPropsCount) throws Exception {
// Create a new system properties using the old one
// as the defaults
Properties myProps = new Properties( System.getProperties() );
@@ -65,10 +78,10 @@
System.out.println(i++ + ": " + key + " : " + value);
}
- if (props.size() != NUM_MYPROPS + sysProps.size()) {
+ if (props.size() != NUM_MYPROPS + sysPropsCount) {
throw new RuntimeException("Test Failed: " +
"Expected number of properties = " +
- NUM_MYPROPS + sysProps.size() +
+ NUM_MYPROPS + sysPropsCount +
" but found = " + props.size());
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/DefaultAccessibility.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/*
+ * @test
+ * @bug 6648344
+ * @summary Test that default accessibility is false
+ * @author Joseph D. Darcy
+ */
+
+import java.lang.reflect.*;
+
+public class DefaultAccessibility {
+ private DefaultAccessibility() {
+ super();
+ }
+
+ private static int f = 42;
+
+ public static void main(String... args) throws Exception {
+ Class<?> daClass = (new DefaultAccessibility()).getClass();
+
+ int elementCount = 0;
+ for(Constructor<?> ctor : daClass.getDeclaredConstructors()) {
+ elementCount++;
+ if (ctor.isAccessible())
+ throw new RuntimeException("Unexpected accessibility for constructor " +
+ ctor);
+ }
+
+ for(Method method : daClass.getDeclaredMethods()) {
+ elementCount++;
+ if (method.isAccessible())
+ throw new RuntimeException("Unexpected accessibility for method " +
+ method);
+ }
+
+ for(Field field : daClass.getDeclaredFields()) {
+ elementCount++;
+ if (field.isAccessible())
+ throw new RuntimeException("Unexpected accessibility for field " +
+ field);
+ }
+
+ if (elementCount < 3)
+ throw new RuntimeException("Expected at least three members; only found " +
+ elementCount);
+ }
+}
--- a/jdk/test/java/nio/file/DirectoryStream/Basic.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/nio/file/DirectoryStream/Basic.java Wed Jul 05 17:02:18 2017 +0200
@@ -154,8 +154,10 @@
stream.close();
// test IllegalStateException
+ dir.resolve(foo).createFile();
stream = dir.newDirectoryStream();
i = stream.iterator();
+ i.next();
try {
stream.iterator();
throw new RuntimeException("IllegalStateException not thrown as expected");
@@ -172,17 +174,26 @@
throw new RuntimeException("ConcurrentModificationException not thrown as expected");
} catch (ConcurrentModificationException x) {
Throwable t = x.getCause();
- if (!(t instanceof IllegalStateException))
- throw new RuntimeException("Cause is not IllegalStateException as expected");
+ if (!(t instanceof ClosedDirectoryStreamException))
+ throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
}
try {
i.next();
- throw new RuntimeException("IllegalStateException not thrown as expected");
+ throw new RuntimeException("ConcurrentModificationException not thrown as expected");
} catch (ConcurrentModificationException x) {
Throwable t = x.getCause();
- if (!(t instanceof IllegalStateException))
- throw new RuntimeException("Cause is not IllegalStateException as expected");
+ if (!(t instanceof ClosedDirectoryStreamException))
+ throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
}
+ try {
+ i.remove();
+ throw new RuntimeException("ConcurrentModificationException not thrown as expected");
+ } catch (ConcurrentModificationException x) {
+ Throwable t = x.getCause();
+ if (!(t instanceof ClosedDirectoryStreamException))
+ throw new RuntimeException("Cause is not ClosedDirectoryStreamException as expected");
+ }
+
}
public static void main(String[] args) throws IOException {
--- a/jdk/test/java/nio/file/Files/ContentType.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/nio/file/Files/ContentType.java Wed Jul 05 17:02:18 2017 +0200
@@ -26,7 +26,7 @@
* @summary Unit test for probeContentType method
* @library ..
* @build ContentType SimpleFileTypeDetector
- * @run main ContentType
+ * @run main/othervm ContentType
*/
import java.nio.file.*;
--- a/jdk/test/java/nio/file/Path/CheckPermissions.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/nio/file/Path/CheckPermissions.java Wed Jul 05 17:02:18 2017 +0200
@@ -25,6 +25,8 @@
* @bug 6866804
* @summary Unit test for java.nio.file.Path
* @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
*/
import java.nio.ByteBuffer;
--- a/jdk/test/java/nio/file/Path/CopyAndMove.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/nio/file/Path/CopyAndMove.java Wed Jul 05 17:02:18 2017 +0200
@@ -92,7 +92,6 @@
{
assertTrue(attrs1.isReadOnly() == attrs2.isReadOnly());
assertTrue(attrs1.isHidden() == attrs2.isHidden());
- assertTrue(attrs1.isArchive() == attrs2.isArchive());
assertTrue(attrs1.isSystem() == attrs2.isSystem());
}
--- a/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Thu Oct 15 16:40:16 2009 -0700
+++ b/jdk/test/java/nio/file/attribute/AclFileAttributeView/Basic.java Wed Jul 05 17:02:18 2017 +0200
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333
+ * @bug 4313887 6838333 6891404
* @summary Unit test for java.nio.file.attribute.AclFileAttribueView
* @library ../..
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java Wed Jul 05 17:02:18 2017 +0200
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2009 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.
+ */
+
+/*
+ * @test
+ * @bug 6797535
+ * @summary Basic tests for methods in java.util.Objects
+ * @author Joseph D. Darcy
+ */
+
+import java.util.*;
+
+public class BasicObjectsTest {
+ public static void main(String... args) {
+ int errors = 0;
+ errors += testEquals();
+ errors += testHashCode();
+ errors += testToString();
+ errors += testCompare();
+ errors += testNonNull();
+ if (errors > 0 )
+ throw new RuntimeException();
+ }
+
+ private static int testEquals() {
+ int errors = 0;
+ Object[] values = {null, "42", 42};
+ for(int i = 0; i < values.length; i++)
+ for(int j = 0; j < values.length; j++) {
+ boolean expected = (i == j);
+ Object a = values[i];
+ Object b = values[j];
+ boolean result = Objects.equals(a, b);
+ if (result != expected) {
+ errors++;
+ System.err.printf("When equating %s to %s, got %b instead of %b%n.",
+ a, b, result, expected);
+ }
+ }
+ return errors;
+ }
+
+ private static int testHashCode() {
+ int errors = 0;
+ errors += (Objects.hashCode(null) == 0 ) ? 0 : 1;
+ String s = "42";
+ errors += (Objects.hashCode(s) == s.hashCode() ) ? 0 : 1;
+ return errors;
+ }
+
+ private static int testToString() {
+ int errors = 0;
+ errors += ("null".equals(Objects.toString(null)) ) ? 0 : 1;
+ String s = "Some string";
+ errors += (s.equals(Objects.toString(s)) ) ? 0 : 1;
+ return errors;
+ }
+
+ private static int testCompare() {
+ int errors = 0;
+ String[] values = {"e. e. cummings", "zzz"};
+ String[] VALUES = {"E. E. Cummings", "ZZZ"};
+ errors += compareTest(null, null, 0);
+ for(int i = 0; i < values.length; i++) {
+ String a = values[i];
+ errors += compareTest(a, a, 0);
+ for(int j = 0; j < VALUES.length; j++) {
+ int expected = Integer.compare(i, j);
+ String b = VALUES[j];
+ errors += compareTest(a, b, expected);
+ }
+ }
+ return errors;
+ }
+
+ private static int compareTest(String a, String b, int expected) {
+ int errors = 0;
+ int result = Objects.compare(a, b, String.CASE_INSENSITIVE_ORDER);
+ if (Integer.signum(result) != Integer.signum(expected)) {
+ errors++;
+ System.err.printf("When comparing %s to %s, got %d instead of %d%n.",
+ a, b, result, expected);
+ }
+ return errors;
+ }
+
+ private static int testNonNull() {
+ int errors = 0;
+ String s;
+
+ // Test 1-arg variant
+ try {
+ s = Objects.nonNull("pants");
+ if (s != "pants") {
+ System.err.printf("1-arg non-null failed to return its arg");
+ errors++;
+ }
+ } catch (NullPointerException e) {
+ System.err.printf("1-arg nonNull threw unexpected NPE");
+ errors++;
+ }
+
+ try {
+ s = Objects.nonNull(null);
+ System.err.printf("1-arg nonNull failed to throw NPE");
+ errors++;
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // Test 2-arg variant
+ try {
+ s = Objects.nonNull("pants", "trousers");
+ if (s != "pants") {
+ System.err.printf("2-arg nonNull failed to return its arg");
+ errors++;
+ }
+ } catch (NullPointerException e) {
+ System.err.printf("2-arg nonNull threw unexpected NPE");
+ errors++;
+ }
+
+ try {
+ s = Objects.nonNull(null, "pantaloons");
+ System.err.printf("2-arg nonNull failed to throw NPE");
+ errors++;
+ } catch (NullPointerException e) {
+ if (e.getMessage() != "pantaloons") {
+ System.err.printf("2-arg nonNull threw NPE w/ bad detail msg");
+ errors++;
+ }
+ }
+ return errors;
+ }
+}