diff --git a/.hgtags b/.hgtags index 3962b8e67fc..ce61a561609 100644 --- a/.hgtags +++ b/.hgtags @@ -629,3 +629,5 @@ bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14-ga 5c7ec21f5d13f6eb5cd32288c69b8be2f9cac256 jdk-15+16 dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17 44aef192b488a48cce12422394691a6b1d16b98e jdk-15+18 +7cc27caabe6e342151e8baf549beb07a9c755ec2 jdk-15+19 +46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20 diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index 9332649cca4..cf441dc5be2 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -303,8 +303,8 @@ jdk.compiler_CLEAN_FILES += $(wildcard \ ################################################################################ -jdk.hotspot.agent_DISABLED_WARNINGS += deprecation rawtypes serial unchecked \ - cast static overrides fallthrough +jdk.hotspot.agent_DISABLED_WARNINGS += rawtypes serial cast static overrides \ + fallthrough jdk.hotspot.agent_COPY += .gif .png sa.js .properties ################################################################################ @@ -668,12 +668,6 @@ endif ################################################################################ -ifeq ($(MODULE), jdk.scripting.nashorn) - include CompileJavaModulesNashorn.gmk -endif - -################################################################################ - $(eval $(call IncludeCustomExtension, CompileJavaModules-post.gmk)) ################################################################################ diff --git a/make/CompileJavaModulesNashorn.gmk b/make/CompileJavaModulesNashorn.gmk deleted file mode 100644 index cc09a88b3bf..00000000000 --- a/make/CompileJavaModulesNashorn.gmk +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -NASGEN_SRC := $(TOPDIR)/make/nashorn/buildtools/nasgen/src -ASM_SRC := $(TOPDIR)/src/java.base/share/classes/jdk/internal/org/objectweb/asm - -# Build nasgen -$(eval $(call SetupJavaCompilation, BUILD_NASGEN, \ - SETUP := GENERATE_OLDBYTECODE, \ - SRC := $(NASGEN_SRC) $(ASM_SRC), \ - BIN := $(BUILDTOOLS_OUTPUTDIR)/nasgen_classes, \ -)) - -NASHORN_CLASSES_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE) -NASGEN_RUN_FILE := $(NASHORN_CLASSES_DIR)/_the.nasgen.run - -NASGEN_OPTIONS := \ - -cp $(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \ - --patch-module java.base=$(BUILDTOOLS_OUTPUTDIR)/nasgen_classes \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED \ - # - -# Run nasgen to modify classes in jdk.nashorn.internal.objects package -$(NASGEN_RUN_FILE): $(BUILD_NASGEN) $($(MODULE)) - $(ECHO) Running nasgen - $(JAVA_SMALL) $(NASGEN_OPTIONS) \ - jdk.nashorn.internal.tools.nasgen.Main $(@D) \ - jdk.nashorn.internal.objects $(@D) - $(TOUCH) $@ - -TARGETS += $(NASGEN_RUN_FILE) diff --git a/make/CompileToolsJdk.gmk b/make/CompileToolsJdk.gmk index 41222ba05f4..1cef5108f1a 100644 --- a/make/CompileToolsJdk.gmk +++ b/make/CompileToolsJdk.gmk @@ -103,9 +103,8 @@ ifeq ($(ENABLE_PANDOC), true) SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-troff-manpage-filter.sh.template, \ OUTPUT_FILE := $(PANDOC_TROFF_MANPAGE_FILTER), \ REPLACEMENTS := \ - @@BOOT_JDK@@ => $(BOOT_JDK) ; \ + @@JJS@@ => $(JJS) ; \ @@TOPDIR@@ => $(TOPDIR) ; \ - @@JJS_FLAGS@@ => $(addprefix -J, $(JAVA_FLAGS_SMALL)), \ )) # Created script must be made executable @@ -127,9 +126,8 @@ ifeq ($(ENABLE_PANDOC), true) SOURCE_FILES := $(TOPDIR)/make/scripts/pandoc-html-manpage-filter.sh.template, \ OUTPUT_FILE := $(PANDOC_HTML_MANPAGE_FILTER), \ REPLACEMENTS := \ - @@BOOT_JDK@@ => $(BOOT_JDK) ; \ + @@JJS@@ => $(JJS) ; \ @@TOPDIR@@ => $(TOPDIR) ; \ - @@JJS_FLAGS@@ => $(addprefix -J, $(JAVA_FLAGS_SMALL)), \ )) # Created script must be made executable diff --git a/make/CreateJmods.gmk b/make/CreateJmods.gmk index 59eb16ad471..01ce2cf48ea 100644 --- a/make/CreateJmods.gmk +++ b/make/CreateJmods.gmk @@ -177,6 +177,11 @@ else # not java.base JMOD_FLAGS += --exclude '$(notdir $(MSVCR_DLL))' endif endif + ifneq ($(VCRUNTIME_1_DLL), ) + ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(VCRUNTIME_1_DLL))), ) + JMOD_FLAGS += --exclude '$(notdir $(VCRUNTIME_1_DLL))' + endif + endif ifneq ($(MSVCP_DLL), ) ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCP_DLL))), ) JMOD_FLAGS += --exclude '$(notdir $(MSVCP_DLL))' diff --git a/make/RunTests.gmk b/make/RunTests.gmk index b3ce833bb41..ecabdbcb696 100644 --- a/make/RunTests.gmk +++ b/make/RunTests.gmk @@ -356,7 +356,6 @@ jdk_JTREG_NATIVEPATH := $(TEST_IMAGE_DIR)/jdk/jtreg/native jdk_JTREG_PROBLEM_LIST += $(TOPDIR)/test/jdk/ProblemList.txt jaxp_JTREG_PROBLEM_LIST += $(TOPDIR)/test/jaxp/ProblemList.txt langtools_JTREG_PROBLEM_LIST += $(TOPDIR)/test/langtools/ProblemList.txt -nashorn_JTREG_PROBLEM_LIST += $(TOPDIR)/test/nashorn/ProblemList.txt hotspot_JTREG_PROBLEM_LIST += $(TOPDIR)/test/hotspot/jtreg/ProblemList.txt langtools_JTREG_MAX_MEM := 768m diff --git a/make/TestImage.gmk b/make/TestImage.gmk index a1ba75b01b9..8fd3a0c0eff 100644 --- a/make/TestImage.gmk +++ b/make/TestImage.gmk @@ -37,10 +37,22 @@ ifeq ($(call isTargetOs, windows), true) $(call install-file) endif -prepare-test-image: $(FIXPATH_COPY) +BUILD_INFO_PROPERTIES := $(TEST_IMAGE_DIR)/build-info.properties + +FIXPATH_ECHO := $(FIXPATH) $(call FixPath, $(ECHO)) + +$(BUILD_INFO_PROPERTIES): + $(call MakeTargetDir) + $(ECHO) "# Build info properties for JDK tests" > $@ + $(FIXPATH_ECHO) "build.workspace.root=$(WORKSPACE_ROOT)" >> $@ + $(FIXPATH_ECHO) "build.output.root=$(OUTPUTDIR)" >> $@ + +prepare-test-image: $(FIXPATH_COPY) $(BUILD_INFO_PROPERTIES) $(call MakeDir, $(TEST_IMAGE_DIR)) $(ECHO) > $(TEST_IMAGE_DIR)/Readme.txt 'JDK test image' +################################################################################ + all: prepare-test-image .PHONY: default all prepare-test-image diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index 9536d99551f..3d3e6aeea86 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -86,6 +86,13 @@ AC_DEFUN_ONCE([BASIC_SETUP_PATHS], AC_SUBST(TOPDIR) AC_SUBST(CONFIGURE_START_DIR) + if test "x$CUSTOM_ROOT" != x; then + WORKSPACE_ROOT="${CUSTOM_ROOT}" + else + WORKSPACE_ROOT="${TOPDIR}" + fi + AC_SUBST(WORKSPACE_ROOT) + # We can only call UTIL_FIXUP_PATH after BASIC_CHECK_PATHS_WINDOWS. UTIL_FIXUP_PATH(CONFIGURE_START_DIR) UTIL_FIXUP_PATH(TOPDIR) @@ -141,6 +148,8 @@ AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT], BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_VS_LIB]) # Corresponds to --with-msvcr-dll BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_MSVCR_DLL]) + # Corresponds to --with-vcruntime-1-dll + BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_VCRUNTIME_1_DLL]) # Corresponds to --with-msvcp-dll BASIC_EVAL_DEVKIT_VARIABLE([DEVKIT_MSVCP_DLL]) # Corresponds to --with-ucrt-dll-dir @@ -313,11 +322,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR], AC_MSG_RESULT([in build directory with custom name]) fi - if test "x$CUSTOM_ROOT" != x; then - WORKSPACE_ROOT="${CUSTOM_ROOT}" - else - WORKSPACE_ROOT="${TOPDIR}" - fi OUTPUTDIR="${WORKSPACE_ROOT}/build/${CONF_NAME}" $MKDIR -p "$OUTPUTDIR" if test ! -d "$OUTPUTDIR"; then @@ -374,7 +378,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR], AC_SUBST(SPEC) AC_SUBST(CONF_NAME) AC_SUBST(OUTPUTDIR) - AC_SUBST(WORKSPACE_ROOT) AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR) # The spec.gmk file contains all variables for the make system. diff --git a/make/autoconf/boot-jdk.m4 b/make/autoconf/boot-jdk.m4 index 841f0e9bbe7..874adab97b8 100644 --- a/make/autoconf/boot-jdk.m4 +++ b/make/autoconf/boot-jdk.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -345,7 +345,9 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK], # When compiling code to be executed by the Boot JDK, force compatibility with the # oldest supported bootjdk. - BOOT_JDK_SOURCETARGET="-source 13 -target 13" + OLDEST_BOOT_JDK=`$ECHO $DEFAULT_ACCEPTABLE_BOOT_VERSIONS \ + | $TR " " "\n" | $SORT -n | $HEAD -n1` + BOOT_JDK_SOURCETARGET="-source $OLDEST_BOOT_JDK -target $OLDEST_BOOT_JDK" AC_SUBST(BOOT_JDK_SOURCETARGET) AC_SUBST(JAVAC_FLAGS) @@ -379,6 +381,21 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK], BOOTJDK_USE_LOCAL_CDS=false AC_MSG_RESULT([no, -XX:SharedArchiveFile not supported]) fi + + # Check for jjs in bootjdk + UTIL_SETUP_TOOL(JJS, + [ + AC_MSG_CHECKING([for jjs in Boot JDK]) + JJS=$BOOT_JDK/bin/jjs + if test ! -x $JJS; then + AC_MSG_RESULT(not found) + JJS="" + AC_MSG_NOTICE([Cannot use pandoc without jjs]) + ENABLE_PANDOC=false + fi + AC_MSG_RESULT(ok) + AC_SUBST(JJS) + ]) ]) AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK_ARGUMENTS], diff --git a/make/autoconf/bootcycle-spec.gmk.in b/make/autoconf/bootcycle-spec.gmk.in index 339fa1bdf11..0a8496a3421 100644 --- a/make/autoconf/bootcycle-spec.gmk.in +++ b/make/autoconf/bootcycle-spec.gmk.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -66,3 +66,6 @@ JAVA_FLAGS_BIG := @BOOTCYCLE_JVM_ARGS_BIG@ # By filtering out those JVM args, the bootcycle JVM will use its default # settings for CDS. JAVA_FLAGS := $(filter-out -XX:SharedArchiveFile% -Xshare%, $(JAVA_FLAGS)) + +# Pandoc cannot be used without the jjs plugin, which was removed with Nashorn. +ENABLE_PANDOC := false diff --git a/make/autoconf/configure.ac b/make/autoconf/configure.ac index decf29accd3..dce5f26ac2c 100644 --- a/make/autoconf/configure.ac +++ b/make/autoconf/configure.ac @@ -97,6 +97,9 @@ HOTSPOT_SETUP_JVM_VARIANTS # With basic setup done, call the custom early hook. CUSTOM_EARLY_HOOK +# This only needs debug level to be setup +JDKOPT_ALLOW_ABSOLUTE_PATHS_IN_OUTPUT + # Check if we have devkits, extra paths or sysroot set. BASIC_SETUP_DEVKIT @@ -123,12 +126,11 @@ BASIC_SETUP_DEFAULT_LOG ############################################################################### # -# Determine OpenJDK variants, options and version numbers. +# Determine OpenJDK variants and version numbers. # ############################################################################### # We need build & target for this. -JDKOPT_SETUP_JDK_OPTIONS JDKOPT_SETUP_JLINK_OPTIONS JDKVER_SETUP_JDK_VERSION_NUMBERS @@ -141,6 +143,14 @@ JDKVER_SETUP_JDK_VERSION_NUMBERS BOOTJDK_SETUP_BOOT_JDK BOOTJDK_SETUP_BUILD_JDK +############################################################################### +# +# Determine JDK specific build time options. +# +############################################################################### + +JDKOPT_SETUP_JDK_OPTIONS + ############################################################################### # # Configure the sources to use. We can add or override individual directories. diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 098d1be7e87..afd2e22a7fb 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -641,6 +641,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER], # Where does this really belong?? if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then PICFLAG="-fPIC" + PIEFLAG="-fPIE" elif test "x$TOOLCHAIN_TYPE" = xsolstudio; then PICFLAG="-KPIC" elif test "x$TOOLCHAIN_TYPE" = xxlc; then @@ -854,18 +855,27 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], $1_WARNING_CFLAGS_JVM="-Wno-format-zero-length -Wtype-limits -Wuninitialized" fi - if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then - # Check if compiler supports -fmacro-prefix-map. If so, use that to make - # the __FILE__ macro resolve to paths relative to the workspace root. - workspace_root_trailing_slash="${WORKSPACE_ROOT%/}/" - FILE_MACRO_CFLAGS="-fmacro-prefix-map=${workspace_root_trailing_slash}=" - FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${FILE_MACRO_CFLAGS}], - PREFIX: $3, - IF_FALSE: [ - FILE_MACRO_CFLAGS= - ] - ) + # Prevent the __FILE__ macro from generating absolute paths into the built + # binaries. Depending on toolchain, different mitigations are possible. + # * GCC and Clang of new enough versions have -fmacro-prefix-map. + # * For most other toolchains, supplying all source files and -I flags as + # relative paths fixes the issue. + FILE_MACRO_CFLAGS= + if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then + if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then + # Check if compiler supports -fmacro-prefix-map. If so, use that to make + # the __FILE__ macro resolve to paths relative to the workspace root. + workspace_root_trailing_slash="${WORKSPACE_ROOT%/}/" + FILE_MACRO_CFLAGS="-fmacro-prefix-map=${workspace_root_trailing_slash}=" + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${FILE_MACRO_CFLAGS}], + PREFIX: $3, + IF_FALSE: [ + FILE_MACRO_CFLAGS= + ] + ) + fi fi + AC_SUBST(FILE_MACRO_CFLAGS) # EXPORT to API CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \ @@ -894,10 +904,12 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], $2JVM_CFLAGS="$CFLAGS_JVM_COMMON ${$1_CFLAGS_JVM} ${$2EXTRA_CXXFLAGS}" - $2CFLAGS_JDKEXE="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CONLY ${$1_CFLAGS_JDK}" - $2CXXFLAGS_JDKEXE="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CXXONLY ${$1_CFLAGS_JDK}" - $2CFLAGS_JDKLIB="${$2CFLAGS_JDKEXE} $JDK_PICFLAG ${$1_CFLAGS_CPU_JDK_LIBONLY}" - $2CXXFLAGS_JDKLIB="${$2CXXFLAGS_JDKEXE} $JDK_PICFLAG ${$1_CFLAGS_CPU_JDK_LIBONLY}" + $2CFLAGS_JDKEXE="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CONLY ${$1_CFLAGS_JDK} $PIEFLAG" + $2CXXFLAGS_JDKEXE="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CXXONLY ${$1_CFLAGS_JDK} $PIEFLAG" + $2CFLAGS_JDKLIB="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CONLY ${$1_CFLAGS_JDK} \ + $JDK_PICFLAG ${$1_CFLAGS_CPU_JDK_LIBONLY}" + $2CXXFLAGS_JDKLIB="$CFLAGS_JDK_COMMON $CFLAGS_JDK_COMMON_CXXONLY ${$1_CFLAGS_JDK} \ + $JDK_PICFLAG ${$1_CFLAGS_CPU_JDK_LIBONLY}" AC_SUBST($2JVM_CFLAGS) AC_SUBST($2CFLAGS_JDKLIB) diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index e9a849b2e29..fc2529d0c26 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -152,6 +152,17 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER], # Setup LDFLAGS for linking executables if test "x$TOOLCHAIN_TYPE" = xgcc; then EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -Wl,--allow-shlib-undefined" + # Enabling pie on 32 bit builds prevents the JVM from allocating a continuous + # java heap. + if test "x$OPENJDK_TARGET_CPU_BITS" != "x32"; then + EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -pie" + fi + fi + + if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + BASIC_LDFLAGS="$BASIC_LDFLAGS -pdbaltpath:%_PDB%" + fi fi # Export some intermediate variables for compatibility diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index 75991ef3452..2d92cb43a73 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -140,7 +140,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS], fi AC_MSG_CHECKING([for pandoc]) - if test "x$PANDOC" != "x"; then + if test "x$ENABLE_PANDOC" = "xtrue"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, cannot generate full docs]) @@ -598,3 +598,35 @@ AC_DEFUN([JDKOPT_ENABLE_DISABLE_CDS_ARCHIVE], ]) AC_SUBST(BUILD_CDS_ARCHIVE) ]) + +################################################################################ +# +# Disallow any output from containing absolute paths from the build system. +# This setting defaults to allowed on debug builds and not allowed on release +# builds. +# +AC_DEFUN([JDKOPT_ALLOW_ABSOLUTE_PATHS_IN_OUTPUT], +[ + AC_ARG_ENABLE([absolute-paths-in-output], + [AS_HELP_STRING([--disable-absolute-paths-in-output], + [Set to disable to prevent any absolute paths from the build to end up in + any of the build output. @<:@disabled in release builds, otherwise enabled@:>@]) + ]) + + AC_MSG_CHECKING([if absolute paths should be allowed in the build output]) + if test "x$enable_absolute_paths_in_output" = "xno"; then + AC_MSG_RESULT([no, forced]) + ALLOW_ABSOLUTE_PATHS_IN_OUTPUT="false" + elif test "x$enable_absolute_paths_in_output" = "xyes"; then + AC_MSG_RESULT([yes, forced]) + ALLOW_ABSOLUTE_PATHS_IN_OUTPUT="true" + elif test "x$DEBUG_LEVEL" = "xrelease"; then + AC_MSG_RESULT([no, release build]) + ALLOW_ABSOLUTE_PATHS_IN_OUTPUT="false" + else + AC_MSG_RESULT([yes, debug build]) + ALLOW_ABSOLUTE_PATHS_IN_OUTPUT="true" + fi + + AC_SUBST(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT) +]) diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index c17d727fe94..60d660b32ec 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -338,6 +338,8 @@ BUILD_MANPAGES := @BUILD_MANPAGES@ BUILD_CDS_ARCHIVE := @BUILD_CDS_ARCHIVE@ +ALLOW_ABSOLUTE_PATHS_IN_OUTPUT := @ALLOW_ABSOLUTE_PATHS_IN_OUTPUT@ + # The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep # it in sync. BOOT_JDK:=@BOOT_JDK@ @@ -381,6 +383,7 @@ LIBFFI_CFLAGS:=@LIBFFI_CFLAGS@ ENABLE_LIBFFI_BUNDLING:=@ENABLE_LIBFFI_BUNDLING@ LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@ GRAALUNIT_LIB := @GRAALUNIT_LIB@ +FILE_MACRO_CFLAGS := @FILE_MACRO_CFLAGS@ STATIC_LIBS_CFLAGS := @STATIC_LIBS_CFLAGS@ @@ -631,6 +634,7 @@ JAR_CMD:=@JAR@ JLINK_CMD := @JLINK@ JMOD_CMD := @JMOD@ JARSIGNER_CMD:=@JARSIGNER@ +JJS_CMD:=@JJS@ SJAVAC_SERVER_JAVA_CMD:=@SJAVAC_SERVER_JAVA@ # These variables are meant to be used. They are defined with = instead of := to make # it possible to override only the *_CMD variables. @@ -643,6 +647,7 @@ JAR=@FIXPATH@ $(JAR_CMD) JLINK = @FIXPATH@ $(JLINK_CMD) $(JAVA_TOOL_FLAGS_SMALL) JMOD = @FIXPATH@ $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL) JARSIGNER=@FIXPATH@ $(JARSIGNER_CMD) +JJS=@FIXPATH@ $(JJS_CMD) $(JAVA_TOOL_FLAGS_SMALL) # A specific java binary with specific options can be used to run # the long running background sjavac servers and other long running tasks. SJAVAC_SERVER_JAVA=@FIXPATH@ @FIXPATH_DETACH_FLAG@ $(SJAVAC_SERVER_JAVA_CMD) \ @@ -783,6 +788,7 @@ LIBZ_CFLAGS:=@LIBZ_CFLAGS@ LIBZ_LIBS:=@LIBZ_LIBS@ LIBZIP_CAN_USE_MMAP:=@LIBZIP_CAN_USE_MMAP@ MSVCR_DLL:=@MSVCR_DLL@ +VCRUNTIME_1_DLL:=@VCRUNTIME_1_DLL@ MSVCP_DLL:=@MSVCP_DLL@ UCRT_DLL_DIR:=@UCRT_DLL_DIR@ STLPORT_LIB:=@STLPORT_LIB@ diff --git a/make/autoconf/toolchain_windows.m4 b/make/autoconf/toolchain_windows.m4 index 462d14a0f69..6067f22fd74 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4 @@ -90,8 +90,9 @@ VS_SUPPORTED_2017=true VS_TOOLSET_SUPPORTED_2017=true VS_DESCRIPTION_2019="Microsoft Visual Studio 2019" -VS_VERSION_INTERNAL_2019=141 +VS_VERSION_INTERNAL_2019=142 VS_MSVCR_2019=vcruntime140.dll +VS_VCRUNTIME_1_2019=vcruntime140_1.dll VS_MSVCP_2019=msvcp140.dll VS_ENVVAR_2019="VS160COMNTOOLS" VS_USE_UCRT_2019="true" @@ -299,6 +300,7 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO], fi eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}" eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}" + eval VCRUNTIME_1_NAME="\${VS_VCRUNTIME_1_${VS_VERSION}}" eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}" eval USE_UCRT="\${VS_USE_UCRT_${VS_VERSION}}" eval VS_SUPPORTED="\${VS_SUPPORTED_${VS_VERSION}}" @@ -365,6 +367,7 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO], eval VS_DESCRIPTION="\${VS_DESCRIPTION_${VS_VERSION}}" eval VS_VERSION_INTERNAL="\${VS_VERSION_INTERNAL_${VS_VERSION}}" eval MSVCR_NAME="\${VS_MSVCR_${VS_VERSION}}" + eval VCRUNTIME_1_NAME="\${VS_VCRUNTIME_1_${VS_VERSION}}" eval MSVCP_NAME="\${VS_MSVCP_${VS_VERSION}}" eval USE_UCRT="\${VS_USE_UCRT_${VS_VERSION}}" eval VS_SUPPORTED="\${VS_SUPPORTED_${VS_VERSION}}" @@ -802,6 +805,31 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], AC_SUBST(MSVCP_DLL) fi + AC_ARG_WITH(vcruntime-1-dll, [AS_HELP_STRING([--with-vcruntime-1-dll], + [path to microsoft C++ runtime dll (vcruntime*_1.dll) (Windows only) @<:@probed@:>@])]) + + if test "x$VCRUNTIME_1_NAME" != "x"; then + if test "x$with_vcruntime_1_dll" != x; then + # If given explicitly by user, do not probe. If not present, fail directly. + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL($VCRUNTIME_1_NAME, [$with_vcruntime_1_dll], + [--with-vcruntime-1-dll]) + if test "x$MSVC_DLL" = x; then + AC_MSG_ERROR([Could not find a proper $VCRUNTIME_1_NAME as specified by --with-vcruntime-1-dll]) + fi + VCRUNTIME_1_DLL="$MSVC_DLL" + elif test "x$DEVKIT_VCRUNTIME_1_DLL" != x; then + TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL($VCRUNTIME_1_NAME, [$DEVKIT_VCRUNTIME_1_DLL], [devkit]) + if test "x$MSVC_DLL" = x; then + AC_MSG_ERROR([Could not find a proper $VCRUNTIME_1_NAME as specified by devkit]) + fi + VCRUNTIME_1_DLL="$MSVC_DLL" + else + TOOLCHAIN_SETUP_MSVC_DLL([${VCRUNTIME_1_NAME}]) + VCRUNTIME_1_DLL="$MSVC_DLL" + fi + AC_SUBST(VCRUNTIME_1_DLL) + fi + AC_ARG_WITH(ucrt-dll-dir, [AS_HELP_STRING([--with-ucrt-dll-dir], [path to Microsoft Windows Kit UCRT DLL dir (Windows only) @<:@probed@:>@])]) diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers index 2200399b9af..7f6fac8de2b 100644 --- a/make/autoconf/version-numbers +++ b/make/autoconf/version-numbers @@ -36,7 +36,7 @@ DEFAULT_VERSION_EXTRA3=0 DEFAULT_VERSION_DATE=2020-09-15 DEFAULT_VERSION_CLASSFILE_MAJOR=59 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="13 14 15" +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="14 15" DEFAULT_JDK_SOURCE_TARGET_VERSION=15 DEFAULT_PROMOTED_VERSION_PRE=ea diff --git a/make/common/FindTests.gmk b/make/common/FindTests.gmk index 42e7e2f188d..a823125de03 100644 --- a/make/common/FindTests.gmk +++ b/make/common/FindTests.gmk @@ -43,7 +43,7 @@ $(eval $(call IncludeCustomExtension, common/FindTests.gmk)) TEST_BASEDIRS += $(TOPDIR)/test $(TOPDIR) # JTREG_TESTROOTS might have been set by a custom extension -JTREG_TESTROOTS += $(addprefix $(TOPDIR)/test/, hotspot/jtreg jdk langtools nashorn jaxp) +JTREG_TESTROOTS += $(addprefix $(TOPDIR)/test/, hotspot/jtreg jdk langtools jaxp) # Extract the names of the Jtreg group files from the TEST.ROOT files. The # TEST.ROOT files being properties files can be interpreted as makefiles so diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk index 05e2238f1ab..838573cab5d 100644 --- a/make/common/Modules.gmk +++ b/make/common/Modules.gmk @@ -112,7 +112,6 @@ PLATFORM_MODULES += \ jdk.jsobject \ jdk.localedata \ jdk.naming.dns \ - jdk.scripting.nashorn \ jdk.security.auth \ jdk.security.jgss \ jdk.xml.dom \ @@ -130,7 +129,6 @@ endif JRE_TOOL_MODULES += \ jdk.jdwp.agent \ jdk.incubator.jpackage \ - jdk.scripting.nashorn.shell \ # ################################################################################ @@ -172,7 +170,6 @@ DOCS_MODULES += \ jdk.naming.rmi \ jdk.net \ jdk.nio.mapmode \ - jdk.scripting.nashorn \ jdk.sctp \ jdk.security.auth \ jdk.security.jgss \ diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index 9b08709e697..4bce970dd33 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -204,6 +204,68 @@ DEPENDENCY_TARGET_SED_PATTERN := \ -e 's/$$$$/ :/' \ # +################################################################################ +# When absolute paths are not allowed in the output, and the compiler does not +# support any options to avoid it, we need to rewrite compile commands to use +# relative paths. By doing this, the __FILE__ macro will resolve to relative +# paths. The relevant input paths on the command line are the -I flags and the +# path to the source file itself. +# +# The macro MakeCommandRelative is used to rewrite the command line like this: +# 'CD $(WORKSPACE_ROOT) && ' +# and changes all paths in cmd to be relative to the workspace root. This only +# works properly if the build dir is inside the workspace root. If it's not, +# relative paths are still calculated, but depending on the distance between the +# dirs, paths in the build dir may end up as essentially absolute anyway. +# +# The fix-deps-file macro is used to adjust the contents of the generated make +# dependency files to contain paths compatible with make. +# +ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT)-$(FILE_MACRO_CFLAGS), false-) + # Need to handle -I flags as both '-Ifoo' and '-I foo'. + MakeCommandRelative = \ + $(CD) $(WORKSPACE_ROOT) && \ + $(foreach o, $1, \ + $(if $(filter $(WORKSPACE_ROOT)/% $(OUTPUTDIR)/%, $o), \ + $(call RelativePath, $o, $(WORKSPACE_ROOT)) \ + , \ + $(if $(filter -I$(WORKSPACE_ROOT)/%, $o), \ + -I$(call RelativePath, $(patsubst -I%, %, $o), $(WORKSPACE_ROOT)) \ + , \ + $o \ + ) \ + ) \ + ) + + # When compiling with relative paths, the deps file comes out with relative + # paths. + ifeq ($(TOOLCHAIN_TYPE), solstudio) + define fix-deps-file + $(SED) -e 's|\./|$(WORKSPACE_ROOT)/|g' $1.tmp > $1 + endef + else + define fix-deps-file + $(SED) -e 's|^\([ ]*\)|\1$(WORKSPACE_ROOT)|' $1.tmp > $1 + endef + endif +else + # By default the MakeCommandRelative macro does nothing. + MakeCommandRelative = $1 + + # Even with absolute paths on the command line, the Solaris studio compiler + # doesn't output the full path to the object file in the generated deps files. + # For other toolchains, no adjustment is needed. + ifeq ($(TOOLCHAIN_TYPE), solstudio) + define fix-deps-file + $(SED) 's|^$$(@F):|$$@:|' $1.tmp > $1 + endef + else + define fix-deps-file + $(MV) $1.tmp $1 + endef + endif +endif + ################################################################################ # Create the recipe needed to compile a single native source file. # @@ -214,7 +276,6 @@ DEPENDENCY_TARGET_SED_PATTERN := \ # Remaining parameters are named arguments: # FILE - The full path of the source file to compiler # BASE - The name of the rule for the entire binary to build ($1) -# DISABLE_THIS_FILE_DEFINE - Set to true to disable the THIS_FILE define. # SetupCompileNativeFile = $(NamedParamsMacroTemplate) define SetupCompileNativeFileBody @@ -236,12 +297,6 @@ define SetupCompileNativeFileBody # This is the definite source file to use for $1_FILENAME. $1_SRC_FILE := $$($1_FILE) - ifneq ($$($1_DEFINE_THIS_FILE), false) - ifneq ($$($$($1_BASE)_DEFINE_THIS_FILE), false) - $1_THIS_FILE = -DTHIS_FILE='"$$($1_FILENAME)"' - endif - endif - ifeq ($$($1_OPTIMIZATION), ) $1_OPT_CFLAGS := $$($$($1_BASE)_OPT_CFLAGS) $1_OPT_CXXFLAGS := $$($$($1_BASE)_OPT_CXXFLAGS) @@ -284,13 +339,13 @@ define SetupCompileNativeFileBody ifneq ($$(filter %.c, $$($1_FILENAME)), ) # Compile as a C file $1_FLAGS := $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) $$($1_BASE_CFLAGS) \ - $$($1_OPT_CFLAGS) $$($1_CFLAGS) $$($1_THIS_FILE) -c + $$($1_OPT_CFLAGS) $$($1_CFLAGS) -c $1_COMPILER := $$($$($1_BASE)_CC) $1_DEP_FLAG := $(C_FLAG_DEPS) else ifneq ($$(filter %.m, $$($1_FILENAME)), ) # Compile as an Objective-C file $1_FLAGS := -x objective-c $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) \ - $$($1_BASE_CFLAGS) $$($1_OPT_CFLAGS) $$($1_CFLAGS) $$($1_THIS_FILE) -c + $$($1_BASE_CFLAGS) $$($1_OPT_CFLAGS) $$($1_CFLAGS) -c $1_COMPILER := $$($$($1_BASE)_CC) $1_DEP_FLAG := $(C_FLAG_DEPS) else ifneq ($$(filter %.s %.S, $$($1_FILENAME)), ) @@ -301,7 +356,7 @@ define SetupCompileNativeFileBody else ifneq ($$(filter %.cpp %.cc %.mm, $$($1_FILENAME)), ) # Compile as a C++ or Objective-C++ file $1_FLAGS := $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) $$($1_BASE_CXXFLAGS) \ - $$($1_OPT_CXXFLAGS) $$($1_CXXFLAGS) $$($1_THIS_FILE) -c + $$($1_OPT_CXXFLAGS) $$($1_CXXFLAGS) -c $1_COMPILER := $$($$($1_BASE)_CXX) $1_DEP_FLAG := $(CXX_FLAG_DEPS) else @@ -341,21 +396,17 @@ define SetupCompileNativeFileBody $$(call LogInfo, Compiling $$($1_FILENAME) (for $$($$($1_BASE)_BASENAME))) $$(call MakeDir, $$(@D)) ifneq ($(TOOLCHAIN_TYPE), microsoft) - ifeq ($(TOOLCHAIN_TYPE)$$(filter %.s, $$($1_FILENAME)), solstudio) - # The Solaris studio compiler doesn't output the full path to the - # object file in the generated deps files. Fixing it with sed. If - # compiling assembly, don't try this. - $$(call ExecuteWithLog, $$@, \ - $$($1_COMPILER) $$($1_DEP_FLAG) $$($1_DEPS_FILE).tmp $$($1_COMPILE_OPTIONS)) - $(SED) 's|^$$(@F):|$$@:|' $$($1_DEPS_FILE).tmp > $$($1_DEPS_FILE) - else - $$(call ExecuteWithLog, $$@, \ - $$($1_COMPILER) $$($1_DEP_FLAG) $$($1_DEPS_FILE) $$($1_COMPILE_OPTIONS)) - endif - # Create a dependency target file from the dependency file. - # Solution suggested by http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ + $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \ + $$($1_COMPILER) $$($1_DEP_FLAG) \ + $$(addsuffix .tmp, $$($1_DEPS_FILE)) \ + $$($1_COMPILE_OPTIONS))) ifneq ($$($1_DEPS_FILE), ) - $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_DEPS_FILE) > $$($1_DEPS_TARGETS_FILE) + $$(call fix-deps-file, $$($1_DEPS_FILE)) + # Create a dependency target file from the dependency file. + # Solution suggested by: + # http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ + $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_DEPS_FILE) \ + > $$($1_DEPS_TARGETS_FILE) endif else # The Visual Studio compiler lacks a feature for generating make @@ -365,8 +416,8 @@ define SetupCompileNativeFileBody # Keep as much as possible on one execution line for best performance # on Windows. No need to save exit code from compilation since # pipefail is always active on Windows. - $$(call ExecuteWithLog, $$@, \ - $$($1_COMPILER) -showIncludes $$($1_COMPILE_OPTIONS)) \ + $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \ + $$($1_COMPILER) -showIncludes $$($1_COMPILE_OPTIONS))) \ | $(TR) -d '\r' | $(GREP) -v -e "^Note: including file:" \ -e "^$$($1_FILENAME)$$$$" || test "$$$$?" = "1" ; \ $(ECHO) $$@: \\ > $$($1_DEPS_FILE) ; \ @@ -430,7 +481,6 @@ endef # STRIPFLAGS Optionally change the flags given to the strip command # PRECOMPILED_HEADER Header file to use as precompiled header # PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH -# DEFINE_THIS_FILE Set to false to not set the THIS_FILE preprocessor macro # # After being called, some variables are exported from this macro, all prefixed # with parameter 1 followed by a '_': @@ -734,7 +784,6 @@ define SetupNativeCompilationBody FILE := $$($1_GENERATED_PCH_SRC), \ BASE := $1, \ EXTRA_CXXFLAGS := -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \ - DEFINE_THIS_FILE := false, \ )) $1_USE_PCH_FLAGS := \ @@ -769,7 +818,8 @@ define SetupNativeCompilationBody $$($1_PCH_FILE): $$($1_PRECOMPILED_HEADER) $$($1_COMPILE_VARDEPS_FILE) $$(call LogInfo, Generating precompiled header) $$(call MakeDir, $$(@D)) - $$(call ExecuteWithLog, $$@, $$($1_PCH_COMMAND) $$< -o $$@) + $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \ + $$($1_PCH_COMMAND) $$< -o $$@)) $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_PCH_DEPS_FILE) \ > $$($1_PCH_DEPS_TARGETS_FILE) @@ -825,9 +875,9 @@ define SetupNativeCompilationBody $$($1_RES): $$($1_VERSIONINFO_RESOURCE) $$($1_RES_VARDEPS_FILE) $$(call LogInfo, Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$($1_BASENAME))) $$(call MakeDir, $$(@D) $$($1_OBJECT_DIR)) - $$(call ExecuteWithLog, $$@, \ + $$(call ExecuteWithLog, $$@, $$(call MakeCommandRelative, \ $$($1_RC) $$($1_RC_FLAGS) $$($1_SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \ - $$($1_VERSIONINFO_RESOURCE) 2>&1 ) + $$($1_VERSIONINFO_RESOURCE) 2>&1 )) # Windows RC compiler does not support -showIncludes, so we mis-use CL # for this. Filter out RC specific arguments that are unknown to CL. # For some unknown reason, in this case CL actually outputs the show diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index eb0b16760f6..f65cf9c6087 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -381,8 +381,8 @@ var getJibProfilesCommon = function (input, data) { }; }; - common.boot_jdk_version = "13"; - common.boot_jdk_build_number = "33"; + common.boot_jdk_version = "14"; + common.boot_jdk_build_number = "36"; common.boot_jdk_home = input.get("boot_jdk", "install_path") + "/jdk-" + common.boot_jdk_version + (input.build_os == "macosx" ? ".jdk/Contents/Home" : ""); @@ -615,7 +615,13 @@ var getJibProfilesProfiles = function (input, common, data) { // The prebuilt bootcycle variant modifies the boot jdk argument var bootcyclePrebuiltBase = { dependencies: [ name + ".jdk" ], - configure_args: "--with-boot-jdk=" + input.get(name + ".jdk", "home_path"), + configure_args: [ + "--with-boot-jdk=" + input.get(name + ".jdk", "home_path"), + // Full docs do not currently work with bootcycle build + // since Nashorn was removed. This negates the + // --enable-full-docs from the main profile. + "--enable-full-docs=auto", + ] } profiles[bootcyclePrebuiltName] = concatObjects(profiles[name], bootcyclePrebuiltBase); @@ -1009,16 +1015,16 @@ var getJibProfilesDependencies = function (input, common) { : input.get("gnumake", "install_path") + "/bin"); if (input.build_cpu == 'aarch64') { - boot_jdk = { + boot_jdk = { organization: common.organization, ext: "tar.gz", module: "jdk-linux_aarch64", revision: "13+1.0", configure_args: "--with-boot-jdk=" + common.boot_jdk_home, environment_path: common.boot_jdk_home + "/bin" - } + } } else { - boot_jdk = { + boot_jdk = { server: "jpg", product: "jdk", version: common.boot_jdk_version, @@ -1027,7 +1033,12 @@ var getJibProfilesDependencies = function (input, common) { + boot_jdk_platform + "_bin" + boot_jdk_ext, configure_args: "--with-boot-jdk=" + common.boot_jdk_home, environment_path: common.boot_jdk_home + "/bin" - } + } + } + if (input.build_cpu == 'sparcv9') { + boot_jdk.file = "bundles/openjdk/GPL/" + boot_jdk_platform + + "/openjdk-" + common.boot_jdk_version + "_" + + boot_jdk_platform + "_bin" + boot_jdk_ext; } var dependencies = { diff --git a/make/copy/Copy-java.base.gmk b/make/copy/Copy-java.base.gmk index ad27c929f13..7e262a39389 100644 --- a/make/copy/Copy-java.base.gmk +++ b/make/copy/Copy-java.base.gmk @@ -59,12 +59,17 @@ ifeq ($(call isTargetOs, windows), true) FILES := $(MSVCR_DLL), \ MACRO := copy-and-chmod)) + $(eval $(call SetupCopyFiles,COPY_VCRUNTIME_1, \ + DEST := $(LIB_DST_DIR), \ + FILES := $(VCRUNTIME_1_DLL), \ + MACRO := copy-and-chmod)) + $(eval $(call SetupCopyFiles,COPY_MSVCP, \ DEST := $(LIB_DST_DIR), \ FILES := $(MSVCP_DLL), \ MACRO := copy-and-chmod)) - TARGETS += $(COPY_MSVCR) $(COPY_MSVCP) + TARGETS += $(COPY_MSVCR) $(COPY_VCRUNTIME_1) $(COPY_MSVCP) ifneq ($(UCRT_DLL_DIR), ) $(eval $(call SetupCopyFiles, COPY_UCRT_DLLS, \ diff --git a/make/data/jdwp/jdwp.spec b/make/data/jdwp/jdwp.spec index 258493edf97..a3377b61a09 100644 --- a/make/data/jdwp/jdwp.spec +++ b/make/data/jdwp/jdwp.spec @@ -70,7 +70,8 @@ JDWP "Java(tm) Debug Wire Protocol" ) (Command AllClasses=3 "Returns reference types for all classes currently loaded by the " - "target VM." + "target VM. " + "See JVM TI GetLoadedClasses." (Out ) (Reply @@ -600,14 +601,9 @@ JDWP "Java(tm) Debug Wire Protocol" (CommandSet ReferenceType=2 (Command Signature=1 - "Returns the JNI signature of a reference type. " - "JNI signature formats are described in the " - "Java Native Interface Specification" - "

- "For primitive classes " - "the returned signature is the signature of the corresponding primitive " - "type; for example, \"I\" is returned as the signature of the class " - "represented by java.lang.Integer.TYPE." + "Returns the type signature of a reference type. " + "Type signature formats are the same as specified in " + "JVM TI GetClassSignature." (Out (referenceType refType "The reference type ID.") ) @@ -2266,11 +2262,12 @@ JDWP "Java(tm) Debug Wire Protocol" ) (CommandSet ClassLoaderReference=14 (Command VisibleClasses=1 - "Returns a list of all classes which this class loader has " - "been requested to load. This class loader is considered to be " - "an initiating class loader for each class in the returned " - "list. The list contains each " - "reference type defined by this loader and any types for which " + "Returns a list of all classes which this class loader can find " + "by name via ClassLoader::loadClass, " + "Class::forName and bytecode linkage. That is, " + "all classes for which this class loader has been recorded as an " + "initiating loader. The list contains each " + "reference type created by this loader and any types for which " "loading was delegated by this class loader to another class loader. " "

" "The visible class list has useful properties with respect to " @@ -2280,6 +2277,8 @@ JDWP "Java(tm) Debug Wire Protocol" "this class loader must be resolved to that single type. " "

" "No ordering of the returned list is guaranteed. " + "

" + "See JVM TI GetClassLoaderClasses. " (Out (classLoaderObject classLoaderObject "The class loader object ID. ") ) diff --git a/make/devkit/createWindowsDevkit2019.sh b/make/devkit/createWindowsDevkit2019.sh index ef3720648a0..8a97f0c2a3b 100644 --- a/make/devkit/createWindowsDevkit2019.sh +++ b/make/devkit/createWindowsDevkit2019.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ VS_VERSION_NUM_NODOT="160" VS_DLL_VERSION="140" SDK_VERSION="10" SDK_FULL_VERSION="10.0.17763.0" -MSVC_DIR="Microsoft.VC141.CRT" +MSVC_DIR="Microsoft.VC142.CRT" MSVC_FULL_VERSION="14.12.27508" REDIST_FULL_VERSION="14.20.27508" @@ -102,6 +102,7 @@ DEVKIT_BUNDLE="${DEVKIT_ROOT}.tar.gz" echo "Creating devkit in $DEVKIT_ROOT" MSVCR_DLL=${MSVC_DIR}/vcruntime${VS_DLL_VERSION}.dll +VCRUNTIME_1_DLL=${MSVC_DIR}/vcruntime${VS_DLL_VERSION}_1.dll MSVCP_DLL=${MSVC_DIR}/msvcp${VS_DLL_VERSION}.dll ################################################################################ @@ -188,6 +189,7 @@ echo-info "DEVKIT_TOOLCHAIN_PATH_x86_64=\"\$DEVKIT_ROOT/VC/bin/x64:\$DEVKIT_ROOT echo-info "DEVKIT_VS_INCLUDE_x86_64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\"" echo-info "DEVKIT_VS_LIB_x86_64=\"\$DEVKIT_ROOT/VC/lib/x64;\$DEVKIT_ROOT/VC/atlmfc/lib/x64;\$DEVKIT_ROOT/$SDK_VERSION/lib/x64\"" echo-info "DEVKIT_MSVCR_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL\"" +echo-info "DEVKIT_VCRUNTIME_1_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$VCRUNTIME_1_DLL\"" echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\"" echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\"" echo-info "" diff --git a/make/gensrc/Gensrc-jdk.scripting.nashorn.gmk b/make/gensrc/Gensrc-jdk.scripting.nashorn.gmk deleted file mode 100644 index 9dec093eede..00000000000 --- a/make/gensrc/Gensrc-jdk.scripting.nashorn.gmk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -default: all - -include $(SPEC) -include MakeBase.gmk -include TextFileProcessing.gmk - -################################################################################ - -# Version file needs to be processed with version numbers -VERSION_FILE := jdk/nashorn/internal/runtime/resources/version.properties - -$(eval $(call SetupTextFileProcessing, BUILD_VERSION_FILE, \ - SOURCE_FILES := $(TOPDIR)/src/$(MODULE)/share/classes/$(VERSION_FILE).template, \ - OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/$(VERSION_FILE), \ - REPLACEMENTS := \ - @@VERSION_STRING@@ => $(VERSION_STRING) ; \ - @@VERSION_SHORT@@ => $(VERSION_SHORT) , \ -)) - -TARGETS += $(NASGEN_RUN_FILE) $(BUILD_VERSION_FILE) - -################################################################################ - -all: $(TARGETS) - -.PHONY: all default diff --git a/make/gensrc/GensrcCharacterData.gmk b/make/gensrc/GensrcCharacterData.gmk index 32e04e3d042..9c2a4902da3 100644 --- a/make/gensrc/GensrcCharacterData.gmk +++ b/make/gensrc/GensrcCharacterData.gmk @@ -38,6 +38,7 @@ define SetupCharacterData $$(call LogInfo, Generating $1.java) $$(call MakeDir, $$(@D)) $(TOOL_GENERATECHARACTER) $2 \ + $(if $(call equals, $(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT), true), -d) \ -template $(CHARACTERDATA)/$1.java.template \ -spec $(UNICODEDATA)/UnicodeData.txt \ -specialcasing $(UNICODEDATA)/SpecialCasing.txt \ diff --git a/make/gensrc/GensrcModuleInfo.gmk b/make/gensrc/GensrcModuleInfo.gmk index 789fd2b7008..56b5fb54eb8 100644 --- a/make/gensrc/GensrcModuleInfo.gmk +++ b/make/gensrc/GensrcModuleInfo.gmk @@ -81,7 +81,9 @@ ifneq ($(MOD_FILES), ) $(call DependOnVariable, ALL_MODULES) $(call MakeTargetDir) $(RM) $@ $@.tmp - $(TOOL_GENMODULEINFOSOURCE) -o $@.tmp \ + $(TOOL_GENMODULEINFOSOURCE) \ + $(if $(call equals, $(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT), true), -d) \ + -o $@.tmp \ --source-file $< \ --modules $(call CommaList, $(ALL_MODULES)) \ $(MOD_FILES) diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index e1c6aded5a2..d302a3df655 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk @@ -75,7 +75,6 @@ ifeq ($(call check-jvm-feature, compiler2), true) OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \ DEBUG_SYMBOLS := false, \ DISABLED_WARNINGS_clang := tautological-compare, \ - DEFINE_THIS_FILE := false, \ )) ADLC_TOOL := $(BUILD_ADLC_TARGET) @@ -201,6 +200,9 @@ ifeq ($(call check-jvm-feature, compiler2), true) $(NAWK) \ 'BEGIN { print "#line 1 \"$*\""; } \ /^#line 999999$$/ {print "#line " (NR+1) " \"$*\""; next} \ + $(if $(call equals, $(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT), false), \ + /^#line .*$$/ {sub("$(WORKSPACE_ROOT)/","")} \ + ) \ {print}' \ < $(ADLC_SUPPORT_DIR)/$* > $@ diff --git a/make/hotspot/gensrc/GensrcDtrace.gmk b/make/hotspot/gensrc/GensrcDtrace.gmk index 608f1dff7b4..2a54a6391fa 100644 --- a/make/hotspot/gensrc/GensrcDtrace.gmk +++ b/make/hotspot/gensrc/GensrcDtrace.gmk @@ -80,7 +80,6 @@ ifeq ($(call check-jvm-feature, dtrace), true) EXTRA_DEPS := $(JVMTI_H) $(JFR_FILES), \ OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \ OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \ - DEFINE_THIS_FILE := false, \ )) DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET) diff --git a/make/hotspot/lib/CompileDtraceLibraries.gmk b/make/hotspot/lib/CompileDtraceLibraries.gmk index 1a459d6a877..7f49a8eb9fa 100644 --- a/make/hotspot/lib/CompileDtraceLibraries.gmk +++ b/make/hotspot/lib/CompileDtraceLibraries.gmk @@ -42,7 +42,6 @@ ifeq ($(call check-jvm-feature, dtrace), true) LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ LIBS := $(LIBDL) -lthread -ldoor, \ OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \ - DEFINE_THIS_FILE := false, \ )) # Note that libjvm_db.c has tests for COMPILER2, but this was never set by @@ -55,7 +54,6 @@ ifeq ($(call check-jvm-feature, dtrace), true) CFLAGS := -I$(DTRACE_GENSRC_DIR) $(JNI_INCLUDE_FLAGS) -m64 -G -mt -KPIC -xldscope=hidden, \ LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \ - DEFINE_THIS_FILE := false, \ )) TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB) diff --git a/make/hotspot/lib/CompileGtest.gmk b/make/hotspot/lib/CompileGtest.gmk index f7c0524bc59..7932c2d9097 100644 --- a/make/hotspot/lib/CompileGtest.gmk +++ b/make/hotspot/lib/CompileGtest.gmk @@ -96,7 +96,6 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \ STRIP_SYMBOLS := false, \ PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \ PRECOMPILED_HEADER_EXCLUDE := gtest-all.cc gmock-all.cc gtestMain.cpp, \ - DEFINE_THIS_FILE := false, \ )) TARGETS += $(BUILD_GTEST_LIBJVM) @@ -123,7 +122,6 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \ LIBS_windows := $(JVM_OUTPUTDIR)/gtest/objs/jvm.lib, \ COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \ ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \ - DEFINE_THIS_FILE := false, \ )) $(BUILD_GTEST_LAUNCHER): $(BUILD_GTEST_LIBJVM) diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk index d41cc3594bc..d6f5d3c46a8 100644 --- a/make/hotspot/lib/CompileJvm.gmk +++ b/make/hotspot/lib/CompileJvm.gmk @@ -208,7 +208,6 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \ VERSIONINFO_RESOURCE := $(TOPDIR)/src/hotspot/os/windows/version.rc, \ PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \ PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \ - DEFINE_THIS_FILE := false, \ )) # Always recompile abstract_vm_version.cpp if libjvm needs to be relinked. This ensures diff --git a/make/hotspot/symbols/symbols-unix b/make/hotspot/symbols/symbols-unix index 29efcc5b55f..50a16fafa68 100644 --- a/make/hotspot/symbols/symbols-unix +++ b/make/hotspot/symbols/symbols-unix @@ -142,6 +142,7 @@ JVM_Interrupt JVM_InvokeMethod JVM_IsArrayClass JVM_IsConstructorIx +JVM_IsHiddenClass JVM_IsInterface JVM_IsPrimitiveClass JVM_IsRecord @@ -151,6 +152,7 @@ JVM_IsThreadAlive JVM_IsVMGeneratedMethodIx JVM_LatestUserDefinedLoader JVM_LoadLibrary +JVM_LookupDefineClass JVM_MaxMemory JVM_MaxObjectInspectionAge JVM_MonitorNotify diff --git a/make/hotspot/test/GtestImage.gmk b/make/hotspot/test/GtestImage.gmk index 3f8381b3b50..744957dcf1a 100644 --- a/make/hotspot/test/GtestImage.gmk +++ b/make/hotspot/test/GtestImage.gmk @@ -41,7 +41,7 @@ ifeq ($(call isTargetOs, windows), true) $(foreach v, $(JVM_VARIANTS), \ $(eval $(call SetupCopyFiles, COPY_GTEST_MSVCR_$v, \ DEST := $(TEST_IMAGE_DIR)/hotspot/gtest/$v, \ - FILES := $(MSVCR_DLL) $(MSVCP_DLL), \ + FILES := $(MSVCR_DLL) $(VCRUNTIME_1_DLL) $(MSVCP_DLL), \ FLATTEN := true, \ )) \ $(eval TARGETS += $$(COPY_GTEST_MSVCR_$v)) \ diff --git a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java index 23a2f8b220c..46b9357b4eb 100644 --- a/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java +++ b/make/jdk/src/classes/build/tools/generatecharacter/GenerateCharacter.java @@ -942,14 +942,15 @@ OUTER: for (int i = 0; i < n; i += m) { int n = sizes.length; StringBuffer result = new StringBuffer(); // liu : Add a comment showing the source of this table - result.append(commentStart + " The following tables and code generated using:" + - commentEnd + "\n "); - result.append(commentStart + ' ' + commandLineDescription + commentEnd + "\n "); - - if (plane == 0 && bLatin1 == false) { + if (debug) { + result.append(commentStart + " The following tables and code generated using:" + + commentEnd + "\n "); + result.append(commentStart + ' ' + commandLineDescription + commentEnd + "\n "); + } + if (plane == 0 && bLatin1 == false) { genCaseMapTableDeclaration(result); genCaseMapTable(initializers, specialCaseMaps); - } + } int totalBytes = 0; for (int k = 0; k < n - 1; k++) { genTable(result, tableNames[k], tables[k], 0, bytes[k]<<3, sizes[k], preshifted[k], @@ -1612,6 +1613,7 @@ OUTER: for (int i = 0; i < n; i += m) { */ static boolean verbose = false; + static boolean debug = false; static boolean nobidi = false; static boolean nomirror = false; static boolean identifiers = false; @@ -1692,6 +1694,8 @@ OUTER: for (int i = 0; i < n; i += m) { for (int j = 0; j < args.length; j++) { if (args[j].equals("-verbose") || args[j].equals("-v")) verbose = true; + else if (args[j].equals("-d")) + debug = true; else if (args[j].equals("-nobidi")) nobidi = true; else if (args[j].equals("-nomirror")) diff --git a/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java b/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java index d2688af3ba3..ce9b94db7a6 100644 --- a/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java +++ b/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java @@ -59,11 +59,14 @@ import static java.util.stream.Collectors.*; */ public class GenModuleInfoSource { private final static String USAGE = - "Usage: GenModuleInfoSource -o \n" + - " --source-file \n" + - " --modules [,...]\n" + - " ...\n"; + "Usage: GenModuleInfoSource \n" + + " [-d]\n" + + " -o \n" + + " --source-file \n" + + " --modules [,...]\n" + + " ...\n"; + static boolean debug = false; static boolean verbose = false; public static void main(String... args) throws Exception { Path outfile = null; @@ -75,6 +78,9 @@ public class GenModuleInfoSource { String option = args[i]; String arg = i+1 < args.length ? args[i+1] : null; switch (option) { + case "-d": + debug = true; + break; case "-o": outfile = Paths.get(arg); i++; @@ -148,10 +154,12 @@ public class GenModuleInfoSource { for (String l : lines) { writer.println(l); if (l.trim().startsWith("module ")) { - // print URI rather than file path to avoid escape - writer.format(" // source file: %s%n", sourceFile.toUri()); - for (Path file: extraFiles) { - writer.format(" // %s%n", file.toUri()); + if (debug) { + // print URI rather than file path to avoid escape + writer.format(" // source file: %s%n", sourceFile.toUri()); + for (Path file : extraFiles) { + writer.format(" // %s%n", file.toUri()); + } } break; } diff --git a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk deleted file mode 100644 index 82311e69fd6..00000000000 --- a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -include LauncherCommon.gmk - -$(eval $(call SetupBuildLauncher, jjs, \ - MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \ - JAVA_ARGS := --add-modules ALL-DEFAULT, \ - CFLAGS := -DENABLE_ARG_FILES, \ -)) diff --git a/make/launcher/LauncherCommon.gmk b/make/launcher/LauncherCommon.gmk index 08a3bf9b3ee..6f7d3fb361a 100644 --- a/make/launcher/LauncherCommon.gmk +++ b/make/launcher/LauncherCommon.gmk @@ -138,12 +138,11 @@ define SetupBuildLauncherBody EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \ OPTIMIZATION := $$($1_OPTIMIZATION), \ CFLAGS := $$(CFLAGS_JDKEXE) \ - $(LAUNCHER_CFLAGS) \ - $(VERSION_CFLAGS) \ - -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \ + $$(LAUNCHER_CFLAGS) \ + $$(VERSION_CFLAGS) \ + -DLAUNCHER_NAME='"$$(LAUNCHER_NAME)"' \ -DPROGNAME='"$1"' \ $$($1_CFLAGS), \ - CFLAGS_linux := -fPIC, \ CFLAGS_solaris := -KPIC, \ CFLAGS_windows := $$($1_CFLAGS_windows), \ DISABLED_WARNINGS_gcc := unused-function, \ diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk index c7286572be6..2c789f65b8e 100644 --- a/make/lib/CoreLibraries.gmk +++ b/make/lib/CoreLibraries.gmk @@ -184,6 +184,9 @@ endif ifeq ($(call isTargetOs, windows), true) # Supply the name of the C runtime lib. LIBJLI_CFLAGS += -DMSVCR_DLL_NAME='"$(notdir $(MSVCR_DLL))"' + ifneq ($(VCRUNTIME_1_DLL), ) + LIBJLI_CFLAGS += -DVCRUNTIME_1_DLL_NAME='"$(notdir $(VCRUNTIME_1_DLL))"' + endif ifneq ($(MSVCP_DLL), ) LIBJLI_CFLAGS += -DMSVCP_DLL_NAME='"$(notdir $(MSVCP_DLL))"' endif diff --git a/make/lib/Lib-java.base.gmk b/make/lib/Lib-java.base.gmk index b8b01c086ca..f128e3bc80a 100644 --- a/make/lib/Lib-java.base.gmk +++ b/make/lib/Lib-java.base.gmk @@ -111,9 +111,9 @@ ifeq ($(call isTargetOs, macosx), true) missing-method-return-type, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \ - $(call SET_SHARED_LIBRARY_ORIGIN) \ - -fobjc-link-runtime, \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := \ + -lobjc \ -framework JavaNativeFoundation \ -framework CoreServices \ -framework Security \ diff --git a/make/nashorn/build-benchmark.xml b/make/nashorn/build-benchmark.xml deleted file mode 100644 index 84f48518e56..00000000000 --- a/make/nashorn/build-benchmark.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - b) { - return 1; - } else { - return 0; - } - }); - - var runtime = project.getProperty("runtime"); - - for (var i in props) { - var task = project.createTask("run-one"); - // workaround for https://issues.apache.org/bugzilla/show_bug.cgi?id=53831, still not fixed - if (task.getOwningTarget() == null) { - task.setOwningTarget(self.getOwningTarget()); - } - var prop = props[i]; - task.setDynamicAttribute("cond", prop); - task.setDynamicAttribute("runtime", runtime); - task.perform(); - } - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/build-nasgen.xml b/make/nashorn/build-nasgen.xml deleted file mode 100644 index 4bd18d42203..00000000000 --- a/make/nashorn/build-nasgen.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - Builds and runs nasgen. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/build.xml b/make/nashorn/build.xml deleted file mode 100644 index cdd1c0e26f5..00000000000 --- a/make/nashorn/build.xml +++ /dev/null @@ -1,883 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${line.separator} - - - - - - - - - - - - - - -

- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -package.access=sun.misc.,\ - sun.reflect.,\ - jdk.nashorn.internal. - - - - - - - -grant codeBase "file:/${basedir}/${dynalink.module.classes.dir}" { - permission java.security.AllPermission; -}; - -grant codeBase "file:/${basedir}/${nashorn.module.classes.dir}" { - permission java.security.AllPermission; -}; - -grant codeBase "file:/${basedir}/${nashorn.internal.tests.jar}" { - permission java.security.AllPermission; -}; - -grant codeBase "file:/${basedir}/${nashorn.api.tests.jar}" { - permission java.util.PropertyPermission "parserapitest.*", "read"; - permission java.util.PropertyPermission "test.*", "read"; - permission java.util.PropertyPermission "test262.*", "read"; - permission java.io.FilePermission "${basedir}/test/nashorn/-","read"; - permission java.io.FilePermission "$${user.dir}", "read"; - permission java.util.PropertyPermission "user.dir", "read"; -}; - -grant codeBase "file:/${basedir}/${file.reference.testng.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${basedir}/${file.reference.jcommander.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${basedir}/${file.reference.bsh.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${basedir}/${file.reference.snakeyaml.jar}" { - permission java.security.AllPermission; -}; -//// in case of absolute path: -grant codeBase "file:/${nashorn.internal.tests.jar}" { - permission java.security.AllPermission; -}; - -grant codeBase "file:/${file.reference.testng.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${file.reference.jcommander.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${file.reference.bsh.jar}" { - permission java.security.AllPermission; -}; -grant codeBase "file:/${file.reference.snakeyaml.jar}" { - permission java.security.AllPermission; -}; - - -grant codeBase "file:/${basedir}/${test.script.dir}/trusted/*" { - permission java.security.AllPermission; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/maptests/*" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/maptests/*","read"; - permission java.lang.RuntimePermission "nashorn.debugMode"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/*" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/-", "read"; - permission java.io.FilePermission "$${user.dir}", "read"; - permission java.util.PropertyPermission "user.dir", "read"; - permission java.util.PropertyPermission "nashorn.test.*", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/apply_to_call/*" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/-", "read"; - permission java.io.FilePermission "$${user.dir}", "read"; - permission java.util.PropertyPermission "user.dir", "read"; - permission java.util.PropertyPermission "nashorn.test.*", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/parser/*" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/-", "read"; - permission java.io.FilePermission "$${user.dir}", "read"; - permission java.util.PropertyPermission "user.dir", "read"; - permission java.util.PropertyPermission "nashorn.test.*", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/es6/*" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/-", "read"; - permission java.io.FilePermission "$${user.dir}", "read"; - permission java.util.PropertyPermission "user.dir", "read"; - permission java.util.PropertyPermission "nashorn.test.*", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/JDK-8010946-privileged.js" { - permission java.util.PropertyPermission "java.security.policy", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/classloader.js" { - permission java.lang.RuntimePermission "nashorn.JavaReflection"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/markdown.js" { - permission java.io.FilePermission "${basedir}/${test.script.dir}/external/showdown/-", "read"; -}; - -grant codeBase "file:/${basedir}/${test.script.dir}/basic/JDK-8158467.js" { - permission java.lang.RuntimePermission "nashorn.setConfig"; -}; - - - - \/ - /// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/buildtools/nasgen/README b/make/nashorn/buildtools/nasgen/README deleted file mode 100644 index d4509459691..00000000000 --- a/make/nashorn/buildtools/nasgen/README +++ /dev/null @@ -1,34 +0,0 @@ -Nasgen is a tool for processing Java classes that implement native -JavaScript objects. It does so by looking for the -com.oracle.nashorn.objects.annotations.ScriptClass annotation and other -annotations in that package. - -For each class "C", nasgen instruments the original class and generates -two additional classes: a "C$Prototype" class for the JavaScript -prototype object, and a "C$Constructor" class for the JavaScript -constructor function. - -Each class instrumented or generated by nasgen contains a private static -"$nasgenmap$" field of type com.oracle.nashorn.runtime.PropertyMap and -static initializer block to initialize the field to the object's -JavaScript properties. - -Members annotated with @Function, @Property, @Getter, and @Setter are -mapped to the $Constructor, $Prototype, or main class, depending on the -value of the annotation's 'where' field. By default, @Property, @Getter, -and @Setter belong to the main class while @Function methods without -explicit 'where' field belong to the $Prototype class. The @Constructor -annotation marks a method to be invoked as JavaScript constructor. - -Nasgen enforces all @Function/@Getter/@Setter/@Constructor annotated -methods to be declared as static. Static final @Property fields remain -in the main class while other @Property fields are moved to respective -classes depending on the annotation's 'where' value. For functions -mapped to the $Prototype or $Constructor class, nasgen also generates -getters and setters prefixed by G$ and S$, respectively. - -Nasgen-generated classes are hidden from normal ClassLoaders by giving -them a ".clazz" file name extension instead of the standard ".class" -extension. This allows script classes to be loaded independently by each -Nashorn context through the com.oracle.nashorn.runtime.StructureLoader -class loader. diff --git a/make/nashorn/buildtools/nasgen/build.xml b/make/nashorn/buildtools/nasgen/build.xml deleted file mode 100644 index db1dea1eabe..00000000000 --- a/make/nashorn/buildtools/nasgen/build.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/buildtools/nasgen/nasgen.iml b/make/nashorn/buildtools/nasgen/nasgen.iml deleted file mode 100644 index f6c890a2ddc..00000000000 --- a/make/nashorn/buildtools/nasgen/nasgen.iml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/buildtools/nasgen/project.properties b/make/nashorn/buildtools/nasgen/project.properties deleted file mode 100644 index fcec900fd2d..00000000000 --- a/make/nashorn/buildtools/nasgen/project.properties +++ /dev/null @@ -1,48 +0,0 @@ -# -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -application.title=nasgen - -# source and target levels -build.compiler=modern - -# This directory is removed when the project is cleaned: -nasgen.build.dir=../../../../build/nashorn/nasgen -nasgen.build.classes.dir=${nasgen.build.dir}/classes - -# This directory is removed when the project is cleaned: -nasgen.dist.dir=${nasgen.build.dir}/dist -nasgen.dist.jar=${nasgen.dist.dir}/nasgen.jar -nasgen.dist.javadoc.dir=${nasgen.dist.dir}/javadoc - -javac.debug=true - -nasgen.module.imports=\ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED - -meta.inf.dir=${src.dir}/META-INF -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -run.jvmargs= -src.dir=src diff --git a/make/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF b/make/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF deleted file mode 100644 index b70986369a1..00000000000 --- a/make/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF +++ /dev/null @@ -1,4 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: lib/ant-1.7.1.jar -Main-Class: jdk.nashorn.internal.tools.nasgen.Main - diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java deleted file mode 100644 index 98a11d984e5..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.NATIVESYMBOL_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SYMBOL_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SYMBOL_PREFIX; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT; - -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.List; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Type; -import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; - -/** - * Base class for class generator classes. - * - */ -public class ClassGenerator { - /** ASM class writer used to output bytecode for this class */ - protected final ClassWriter cw; - - /** - * Constructor - */ - protected ClassGenerator() { - this.cw = makeClassWriter(); - } - - MethodGenerator makeStaticInitializer() { - return makeStaticInitializer(cw); - } - - MethodGenerator makeConstructor() { - return makeConstructor(cw); - } - - MethodGenerator makeMethod(final int access, final String name, final String desc) { - return makeMethod(cw, access, name, desc); - } - - void addMapField() { - addMapField(cw); - } - - void addField(final String name, final String desc) { - addField(cw, name, desc); - } - - void addFunctionField(final String name) { - addFunctionField(cw, name); - } - - void addGetter(final String owner, final MemberInfo memInfo) { - addGetter(cw, owner, memInfo); - } - - void addSetter(final String owner, final MemberInfo memInfo) { - addSetter(cw, owner, memInfo); - } - - void emitGetClassName(final String name) { - final MethodGenerator mi = makeMethod(ACC_PUBLIC, GET_CLASS_NAME, GET_CLASS_NAME_DESC); - mi.loadLiteral(name); - mi.returnValue(); - mi.computeMaxs(); - mi.visitEnd(); - } - - static ClassWriter makeClassWriter() { - return new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { - @Override - protected String getCommonSuperClass(final String type1, final String type2) { - try { - return super.getCommonSuperClass(type1, type2); - } catch (final RuntimeException | LinkageError e) { - if (MemberInfo.isScriptObject(type1) && MemberInfo.isScriptObject(type2)) { - return StringConstants.SCRIPTOBJECT_TYPE; - } - return StringConstants.OBJECT_TYPE; - } - } - }; - } - - static MethodGenerator makeStaticInitializer(final ClassVisitor cv) { - return makeStaticInitializer(cv, CLINIT); - } - - static MethodGenerator makeStaticInitializer(final ClassVisitor cv, final String name) { - final int access = ACC_PUBLIC | ACC_STATIC; - final String desc = DEFAULT_INIT_DESC; - final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); - return new MethodGenerator(mv, access, name, desc); - } - - static MethodGenerator makeConstructor(final ClassVisitor cv) { - final int access = 0; - final String name = INIT; - final String desc = DEFAULT_INIT_DESC; - final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); - return new MethodGenerator(mv, access, name, desc); - } - - static MethodGenerator makeMethod(final ClassVisitor cv, final int access, final String name, final String desc) { - final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); - return new MethodGenerator(mv, access, name, desc); - } - - static void emitStaticInitPrefix(final MethodGenerator mi, final String className, final int memberCount) { - mi.visitCode(); - if (memberCount > 0) { - // new ArrayList(int) - mi.newObject(ARRAYLIST_TYPE); - mi.dup(); - mi.push(memberCount); - mi.invokeSpecial(ARRAYLIST_TYPE, INIT, ARRAYLIST_INIT_DESC); - // stack: ArrayList - } else { - // java.util.Collections.EMPTY_LIST - mi.getStatic(COLLECTIONS_TYPE, COLLECTIONS_EMPTY_LIST, LIST_DESC); - // stack List - } - } - - static void emitStaticInitSuffix(final MethodGenerator mi, final String className) { - // stack: Collection - // pmap = PropertyMap.newMap(Collection); - mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC); - // $nasgenmap$ = pmap; - mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); - mi.returnVoid(); - mi.computeMaxs(); - mi.visitEnd(); - } - - @SuppressWarnings("fallthrough") - private static Type memInfoType(final MemberInfo memInfo) { - switch (memInfo.getJavaDesc().charAt(0)) { - case 'I': return Type.INT_TYPE; - case 'J': return Type.LONG_TYPE; - case 'D': return Type.DOUBLE_TYPE; - default: assert false : memInfo.getJavaDesc(); - case 'L': return TYPE_OBJECT; - } - } - - private static String getterDesc(final MemberInfo memInfo) { - return Type.getMethodDescriptor(memInfoType(memInfo)); - } - - private static String setterDesc(final MemberInfo memInfo) { - return Type.getMethodDescriptor(Type.VOID_TYPE, memInfoType(memInfo)); - } - - static void addGetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) { - final int access = ACC_PUBLIC; - final String name = GETTER_PREFIX + memInfo.getJavaName(); - final String desc = getterDesc(memInfo); - final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); - final MethodGenerator mi = new MethodGenerator(mv, access, name, desc); - mi.visitCode(); - if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) { - mi.getStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); - } else { - mi.loadLocal(0); - mi.getField(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); - } - mi.returnValue(); - mi.computeMaxs(); - mi.visitEnd(); - } - - static void addSetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) { - final int access = ACC_PUBLIC; - final String name = SETTER_PREFIX + memInfo.getJavaName(); - final String desc = setterDesc(memInfo); - final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); - final MethodGenerator mi = new MethodGenerator(mv, access, name, desc); - mi.visitCode(); - if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) { - mi.loadLocal(1); - mi.putStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); - } else { - mi.loadLocal(0); - mi.loadLocal(1); - mi.putField(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); - } - mi.returnVoid(); - mi.computeMaxs(); - mi.visitEnd(); - } - - static void addMapField(final ClassVisitor cv) { - // add a PropertyMap static field - final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, - PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC, null, null); - if (fv != null) { - fv.visitEnd(); - } - } - - static void addField(final ClassVisitor cv, final String name, final String desc) { - final FieldVisitor fv = cv.visitField(ACC_PRIVATE, name, desc, null, null); - if (fv != null) { - fv.visitEnd(); - } - } - - static void addFunctionField(final ClassVisitor cv, final String name) { - addField(cv, name, OBJECT_DESC); - } - - static void newFunction(final MethodGenerator mi, final String objName, final String className, final MemberInfo memInfo, final List specs) { - final boolean arityFound = (memInfo.getArity() != MemberInfo.DEFAULT_ARITY); - - loadFunctionName(mi, memInfo.getName()); - mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, memInfo.getJavaName(), memInfo.getJavaDesc(), false)); - - assert specs != null; - if (!specs.isEmpty()) { - mi.memberInfoArray(className, specs); - mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC); - } else { - mi.invokeStatic(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_CREATEBUILTIN, SCRIPTFUNCTION_CREATEBUILTIN_DESC); - } - - if (arityFound) { - mi.dup(); - mi.push(memInfo.getArity()); - mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC); - } - - mi.dup(); - mi.loadLiteral(memInfo.getDocumentationKey(objName)); - mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATIONKEY, SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC); - } - - static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) { - final String propertyName = memInfo.getName(); - // stack: Collection - // dup of Collection instance - mi.dup(); - - // Load property name, converting to Symbol if it begins with "@@" - loadPropertyKey(mi, propertyName); - // setup flags - mi.push(memInfo.getAttributes()); - // setup getter method handle - String javaName = GETTER_PREFIX + memInfo.getJavaName(); - mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, getterDesc(memInfo), false)); - // setup setter method handle - if (memInfo.isFinal()) { - mi.pushNull(); - } else { - javaName = SETTER_PREFIX + memInfo.getJavaName(); - mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo), false)); - } - // property = AccessorProperty.create(key, flags, getter, setter); - mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC); - // boolean Collection.add(property) - mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC); - // pop return value of Collection.add - mi.pop(); - // stack: Collection - } - - static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) { - final String propertyName = getter.getName(); - // stack: Collection - // dup of Collection instance - mi.dup(); - - // Load property name, converting to Symbol if it begins with "@@" - loadPropertyKey(mi, propertyName); - // setup flags - mi.push(getter.getAttributes()); - // setup getter method handle - mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, - getter.getJavaName(), getter.getJavaDesc(), false)); - // setup setter method handle - if (setter == null) { - mi.pushNull(); - } else { - mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, - setter.getJavaName(), setter.getJavaDesc(), false)); - } - // property = AccessorProperty.create(key, flags, getter, setter); - mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC); - // boolean Collection.add(property) - mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC); - // pop return value of Collection.add - mi.pop(); - // stack: Collection - } - - static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException { - try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) { - return getScriptClassInfo(new ClassReader(bis)); - } - } - - static ScriptClassInfo getScriptClassInfo(final byte[] classBuf) { - return getScriptClassInfo(new ClassReader(classBuf)); - } - - private static void loadFunctionName(final MethodGenerator mi, final String propertyName) { - if (propertyName.startsWith(SYMBOL_PREFIX)) { - mi.loadLiteral("Symbol[" + propertyName.substring(2) + "]"); - } else { - mi.loadLiteral(propertyName); - } - } - - private static void loadPropertyKey(final MethodGenerator mi, final String propertyName) { - if (propertyName.startsWith(SYMBOL_PREFIX)) { - mi.getStatic(NATIVESYMBOL_TYPE, propertyName.substring(2), SYMBOL_DESC); - } else { - mi.loadLiteral(propertyName); - } - } - - private static ScriptClassInfo getScriptClassInfo(final ClassReader reader) { - final ScriptClassInfoCollector scic = new ScriptClassInfoCollector(); - reader.accept(scic, 0); - return scic.getScriptClassInfo(); - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java deleted file mode 100644 index 1fa76ce9829..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC3; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_INIT_DESC4; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETPROTOTYPE_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; -import jdk.internal.org.objectweb.asm.Handle; - -/** - * This class generates constructor class for a @ScriptClass annotated class. - * - */ -public class ConstructorGenerator extends ClassGenerator { - private final ScriptClassInfo scriptClassInfo; - private final String className; - private final MemberInfo constructor; - private final int memberCount; - private final List specs; - - ConstructorGenerator(final ScriptClassInfo sci) { - this.scriptClassInfo = sci; - - this.className = scriptClassInfo.getConstructorClassName(); - this.constructor = scriptClassInfo.getConstructor(); - this.memberCount = scriptClassInfo.getConstructorMemberCount(); - this.specs = scriptClassInfo.getSpecializedConstructors(); - } - - byte[] getClassBytes() { - // new class extending from ScriptObject - final String superClass = (constructor != null)? SCRIPTFUNCTION_TYPE : SCRIPTOBJECT_TYPE; - cw.visit(V1_7, ACC_FINAL, className, null, superClass, null); - if (memberCount > 0) { - // add fields - emitFields(); - // add - emitStaticInitializer(); - } - // add - emitConstructor(); - - if (constructor == null) { - emitGetClassName(scriptClassInfo.getName()); - } - - cw.visitEnd(); - return cw.toByteArray(); - } - - // --Internals only below this point - private void emitFields() { - // Introduce "Function" type instance fields for each - // constructor @Function in script class and introduce instance - // fields for each constructor @Property in the script class. - for (MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isConstructorFunction()) { - addFunctionField(memInfo.getJavaName()); - memInfo = (MemberInfo)memInfo.clone(); - memInfo.setJavaDesc(OBJECT_DESC); - memInfo.setJavaAccess(ACC_PUBLIC); - addGetter(className, memInfo); - addSetter(className, memInfo); - } else if (memInfo.isConstructorProperty()) { - if (memInfo.isStaticFinal()) { - addGetter(scriptClassInfo.getJavaName(), memInfo); - } else { - addField(memInfo.getJavaName(), memInfo.getJavaDesc()); - memInfo = (MemberInfo)memInfo.clone(); - memInfo.setJavaAccess(ACC_PUBLIC); - addGetter(className, memInfo); - addSetter(className, memInfo); - } - } - } - - addMapField(); - } - - private void emitStaticInitializer() { - final MethodGenerator mi = makeStaticInitializer(); - emitStaticInitPrefix(mi, className, memberCount); - - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) { - linkerAddGetterSetter(mi, className, memInfo); - } else if (memInfo.isConstructorGetter()) { - final MemberInfo setter = scriptClassInfo.findSetter(memInfo); - linkerAddGetterSetter(mi, scriptClassInfo.getJavaName(), memInfo, setter); - } - } - emitStaticInitSuffix(mi, className); - } - - private void emitConstructor() { - final MethodGenerator mi = makeConstructor(); - mi.visitCode(); - callSuper(mi); - - if (memberCount > 0) { - // initialize Function type fields - initFunctionFields(mi); - // initialize data fields - initDataFields(mi); - } - - if (constructor != null) { - initPrototype(mi); - final int arity = constructor.getArity(); - if (arity != MemberInfo.DEFAULT_ARITY) { - mi.loadThis(); - mi.push(arity); - mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, - SCRIPTFUNCTION_SETARITY_DESC); - } - - mi.loadThis(); - mi.loadLiteral(scriptClassInfo.getName()); - mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATIONKEY, - SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC); - } - mi.returnVoid(); - mi.computeMaxs(); - mi.visitEnd(); - } - - private void loadMap(final MethodGenerator mi) { - if (memberCount > 0) { - mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); - } - } - - private void callSuper(final MethodGenerator mi) { - String superClass, superDesc; - mi.loadThis(); - if (constructor == null) { - // call ScriptObject. - superClass = SCRIPTOBJECT_TYPE; - superDesc = (memberCount > 0) ? SCRIPTOBJECT_INIT_DESC : DEFAULT_INIT_DESC; - loadMap(mi); - } else { - // call Function. - superClass = SCRIPTFUNCTION_TYPE; - superDesc = (memberCount > 0) ? SCRIPTFUNCTION_INIT_DESC4 : SCRIPTFUNCTION_INIT_DESC3; - mi.loadLiteral(constructor.getName()); - mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc(), false)); - loadMap(mi); - mi.memberInfoArray(scriptClassInfo.getJavaName(), specs); //pushes null if specs empty - } - - mi.invokeSpecial(superClass, INIT, superDesc); - } - - private void initFunctionFields(final MethodGenerator mi) { - assert memberCount > 0; - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (!memInfo.isConstructorFunction()) { - continue; - } - mi.loadThis(); - newFunction(mi, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); - mi.putField(className, memInfo.getJavaName(), OBJECT_DESC); - } - } - - private void initDataFields(final MethodGenerator mi) { - assert memberCount > 0; - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (!memInfo.isConstructorProperty() || memInfo.isFinal()) { - continue; - } - final Object value = memInfo.getValue(); - if (value != null) { - mi.loadThis(); - mi.loadLiteral(value); - mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc()); - } else if (!memInfo.getInitClass().isEmpty()) { - final String clazz = memInfo.getInitClass(); - mi.loadThis(); - mi.newObject(clazz); - mi.dup(); - mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC); - mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc()); - } - } - } - - private void initPrototype(final MethodGenerator mi) { - assert constructor != null; - mi.loadThis(); - final String protoName = scriptClassInfo.getPrototypeClassName(); - mi.newObject(protoName); - mi.dup(); - mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC); - mi.dup(); - mi.loadThis(); - mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR, - PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC); - mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETPROTOTYPE, SCRIPTFUNCTION_SETPROTOTYPE_DESC); - } - - /** - * Entry point for ConstructorGenerator run separately as an application. Will display - * usage. Takes one argument, a class name. - * @param args args vector - * @throws IOException if class can't be read - */ - public static void main(final String[] args) throws IOException { - if (args.length != 1) { - System.err.println("Usage: " + ConstructorGenerator.class.getName() + " "); - System.exit(1); - } - - final String className = args[0].replace('.', '/'); - final ScriptClassInfo sci = getScriptClassInfo(className + ".class"); - if (sci == null) { - System.err.println("No @ScriptClass in " + className); - System.exit(2); - throw new IOException(); // get rid of warning for sci.verify() below - may be null - } - - try { - sci.verify(); - } catch (final Exception e) { - System.err.println(e.getMessage()); - System.exit(3); - } - final ConstructorGenerator gen = new ConstructorGenerator(sci); - try (FileOutputStream fos = new FileOutputStream(className + CONSTRUCTOR_SUFFIX + ".class")) { - fos.write(gen.getClassBytes()); - } - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java deleted file mode 100644 index 90dbcc4849a..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; - -/** - * Main class for the "nasgen" tool. - * - */ -public class Main { - /** - * ASM version to be used by nasgen tool. - */ - public static final int ASM_VERSION = Opcodes.ASM7; - - private static final boolean DEBUG = Boolean.getBoolean("nasgen.debug"); - - private interface ErrorReporter { - public void error(String msg); - } - - /** - * Public entry point for Nasgen if invoked from command line. Nasgen takes three arguments - * in order: input directory, package list, output directory - * - * @param args argument vector - */ - public static void main(final String[] args) { - final ErrorReporter reporter = new ErrorReporter() { - @Override - public void error(final String msg) { - Main.error(msg, 1); - } - }; - if (args.length == 3) { - processAll(args[0], args[1], args[2], reporter); - } else { - error("Usage: nasgen ", 1); - } - } - - private static void processAll(final String in, final String pkgList, final String out, final ErrorReporter reporter) { - final File inDir = new File(in); - if (!inDir.exists() || !inDir.isDirectory()) { - reporter.error(in + " does not exist or not a directory"); - return; - } - - final File outDir = new File(out); - if (!outDir.exists() || !outDir.isDirectory()) { - reporter.error(out + " does not exist or not a directory"); - return; - } - - final String[] packages = pkgList.split(":"); - for (String pkg : packages) { - pkg = pkg.replace('.', File.separatorChar); - final File dir = new File(inDir, pkg); - final File[] classes = dir.listFiles(); - for (final File clazz : classes) { - if (clazz.isFile() && clazz.getName().endsWith(".class")) { - if (! process(clazz, new File(outDir, pkg), reporter)) { - return; - } - } - } - } - } - - private static boolean process(final File inFile, final File outDir, final ErrorReporter reporter) { - try { - byte[] buf = new byte[(int)inFile.length()]; - - try (FileInputStream fin = new FileInputStream(inFile)) { - fin.read(buf); - } - - final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(buf); - - if (sci != null) { - try { - sci.verify(); - } catch (final Exception e) { - reporter.error(e.getMessage()); - return false; - } - - // create necessary output package dir - outDir.mkdirs(); - - // instrument @ScriptClass - final ClassWriter writer = ClassGenerator.makeClassWriter(); - final ClassReader reader = new ClassReader(buf); - final ScriptClassInstrumentor inst = new ScriptClassInstrumentor(writer, sci); - reader.accept(inst, 0); - //noinspection UnusedAssignment - - // write instrumented class - try (FileOutputStream fos = new FileOutputStream(new File(outDir, inFile.getName()))) { - buf = writer.toByteArray(); - if (DEBUG) { - verify(buf); - } - fos.write(buf); - } - - // simple class name without package prefix - String simpleName = inFile.getName(); - simpleName = simpleName.substring(0, simpleName.indexOf(".class")); - - if (sci.isPrototypeNeeded()) { - // generate prototype class - final PrototypeGenerator protGen = new PrototypeGenerator(sci); - buf = protGen.getClassBytes(); - if (DEBUG) { - verify(buf); - } - try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.PROTOTYPE_SUFFIX + ".class"))) { - fos.write(buf); - } - } - - if (sci.isConstructorNeeded()) { - // generate constructor class - final ConstructorGenerator consGen = new ConstructorGenerator(sci); - buf = consGen.getClassBytes(); - if (DEBUG) { - verify(buf); - } - try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.CONSTRUCTOR_SUFFIX + ".class"))) { - fos.write(buf); - } - } - } - return true; - } catch (final IOException | RuntimeException e) { - if (DEBUG) { - e.printStackTrace(System.err); - } - reporter.error(e.getMessage()); - - return false; - } - } - - private static void verify(final byte[] buf) { - final ClassReader cr = new ClassReader(buf); - CheckClassAdapter.verify(cr, false, new PrintWriter(System.err)); - } - - private static void error(final String msg, final int exitCode) { - System.err.println(msg); - System.exit(exitCode); - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java deleted file mode 100644 index c5cb0b5de1f..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJ_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.RUNTIME_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTS_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_SYMBOL; - -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.Type; - -/** - * Details about a Java method or field annotated with any of the field/method - * annotations from the jdk.nashorn.internal.objects.annotations package. - */ -public final class MemberInfo implements Cloneable { - // class loader of this class - private static final ClassLoader MY_LOADER = MemberInfo.class.getClassLoader(); - - /** - * The different kinds of available class annotations - */ - public static enum Kind { - - /** - * This is a script class - */ - SCRIPT_CLASS, - /** - * This is a constructor - */ - CONSTRUCTOR, - /** - * This is a function - */ - FUNCTION, - /** - * This is a getter - */ - GETTER, - /** - * This is a setter - */ - SETTER, - /** - * This is a property - */ - PROPERTY, - /** - * This is a specialized version of a function - */ - SPECIALIZED_FUNCTION, - } - - // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute - static final int DEFAULT_ATTRIBUTES = 0x0; - - static final int DEFAULT_ARITY = -2; - - // the kind of the script annotation - one of the above constants - private MemberInfo.Kind kind; - // script property name - private String name; - // script property attributes - private int attributes; - // name of the java member - private String javaName; - // type descriptor of the java member - private String javaDesc; - // access bits of the Java field or method - private int javaAccess; - // initial value for static @Property fields - private Object value; - // class whose object is created to fill property value - private String initClass; - // arity of the Function or Constructor - private int arity; - - private Where where; - - private Type linkLogicClass; - - private boolean isSpecializedConstructor; - - private boolean isOptimistic; - - private boolean convertsNumericArgs; - - /** - * @return the kind - */ - public Kind getKind() { - return kind; - } - - /** - * @param kind the kind to set - */ - public void setKind(final Kind kind) { - this.kind = kind; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(final String name) { - this.name = name; - } - - /** - * Tag something as specialized constructor or not - * @param isSpecializedConstructor boolean, true if specialized constructor - */ - public void setIsSpecializedConstructor(final boolean isSpecializedConstructor) { - this.isSpecializedConstructor = isSpecializedConstructor; - } - - /** - * Check if something is a specialized constructor - * @return true if specialized constructor - */ - public boolean isSpecializedConstructor() { - return isSpecializedConstructor; - } - - /** - * Check if this is an optimistic builtin function - * @return true if optimistic builtin - */ - public boolean isOptimistic() { - return isOptimistic; - } - - /** - * Tag something as optimistic builtin or not - * @param isOptimistic boolean, true if builtin constructor - */ - public void setIsOptimistic(final boolean isOptimistic) { - this.isOptimistic = isOptimistic; - } - - /** - * Check if this function converts arguments for numeric parameters to numbers - * so it's safe to pass booleans as 0 and 1 - * @return true if it is safe to convert arguments to numbers - */ - public boolean convertsNumericArgs() { - return convertsNumericArgs; - } - - /** - * Tag this as a function that converts arguments for numeric params to numbers - * @param convertsNumericArgs if true args can be safely converted to numbers - */ - public void setConvertsNumericArgs(final boolean convertsNumericArgs) { - this.convertsNumericArgs = convertsNumericArgs; - } - - /** - * Get the SpecializedFunction guard for specializations, i.e. optimistic - * builtins - * @return specialization, null if none - */ - public Type getLinkLogicClass() { - return linkLogicClass; - } - - /** - * Set the SpecializedFunction link logic class for specializations, i.e. optimistic - * builtins - * @param linkLogicClass link logic class - */ - - public void setLinkLogicClass(final Type linkLogicClass) { - this.linkLogicClass = linkLogicClass; - } - - /** - * @return the attributes - */ - public int getAttributes() { - return attributes; - } - - /** - * @param attributes the attributes to set - */ - public void setAttributes(final int attributes) { - this.attributes = attributes; - } - - /** - * @return the javaName - */ - public String getJavaName() { - return javaName; - } - - /** - * @param javaName the javaName to set - */ - public void setJavaName(final String javaName) { - this.javaName = javaName; - } - - /** - * @return the javaDesc - */ - public String getJavaDesc() { - return javaDesc; - } - - void setJavaDesc(final String javaDesc) { - this.javaDesc = javaDesc; - } - - int getJavaAccess() { - return javaAccess; - } - - void setJavaAccess(final int access) { - this.javaAccess = access; - } - - Object getValue() { - return value; - } - - void setValue(final Object value) { - this.value = value; - } - - Where getWhere() { - return where; - } - - void setWhere(final Where where) { - this.where = where; - } - - boolean isFinal() { - return (javaAccess & Opcodes.ACC_FINAL) != 0; - } - - boolean isStatic() { - return (javaAccess & Opcodes.ACC_STATIC) != 0; - } - - boolean isStaticFinal() { - return isStatic() && isFinal(); - } - - boolean isInstanceGetter() { - return kind == Kind.GETTER && where == Where.INSTANCE; - } - - /** - * Check whether this MemberInfo is a getter that resides in the instance - * - * @return true if instance setter - */ - boolean isInstanceSetter() { - return kind == Kind.SETTER && where == Where.INSTANCE; - } - - boolean isInstanceProperty() { - return kind == Kind.PROPERTY && where == Where.INSTANCE; - } - - boolean isInstanceFunction() { - return kind == Kind.FUNCTION && where == Where.INSTANCE; - } - - boolean isPrototypeGetter() { - return kind == Kind.GETTER && where == Where.PROTOTYPE; - } - - boolean isPrototypeSetter() { - return kind == Kind.SETTER && where == Where.PROTOTYPE; - } - - boolean isPrototypeProperty() { - return kind == Kind.PROPERTY && where == Where.PROTOTYPE; - } - - boolean isPrototypeFunction() { - return kind == Kind.FUNCTION && where == Where.PROTOTYPE; - } - - boolean isConstructorGetter() { - return kind == Kind.GETTER && where == Where.CONSTRUCTOR; - } - - boolean isConstructorSetter() { - return kind == Kind.SETTER && where == Where.CONSTRUCTOR; - } - - boolean isConstructorProperty() { - return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR; - } - - boolean isConstructorFunction() { - return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR; - } - - boolean isConstructor() { - return kind == Kind.CONSTRUCTOR; - } - - void verify() { - switch (kind) { - case CONSTRUCTOR: { - final Type returnType = Type.getReturnType(javaDesc); - if (!isJSObjectType(returnType)) { - error("return value of a @Constructor method should be of Object type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length < 2) { - error("@Constructor methods should have at least 2 args"); - } - if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) { - error("first argument of a @Constructor method should be of boolean type, found " + argTypes[0]); - } - if (!isJavaLangObject(argTypes[1])) { - error("second argument of a @Constructor method should be of Object type, found " + argTypes[0]); - } - - if (argTypes.length > 2) { - for (int i = 2; i < argTypes.length - 1; i++) { - if (!isJavaLangObject(argTypes[i])) { - error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]); - } - } - - final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor(); - final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC); - if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) { - error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc); - } - - if (isVarArg && argTypes.length > 3) { - error("vararg of a @Constructor method has more than 3 arguments"); - } - } - } - break; - case FUNCTION: { - final Type returnType = Type.getReturnType(javaDesc); - if (!(isValidJSType(returnType) || Type.VOID_TYPE == returnType)) { - error("return value of a @Function method should be a valid JS type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length < 1) { - error("@Function methods should have at least 1 arg"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Function method should be of Object type, found " + argTypes[0]); - } - - if (argTypes.length > 1) { - for (int i = 1; i < argTypes.length - 1; i++) { - if (!isJavaLangObject(argTypes[i])) { - error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]); - } - } - - final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor(); - final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC); - if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) { - error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc); - } - - if (isVarArg && argTypes.length > 2) { - error("vararg @Function method has more than 2 arguments"); - } - } - } - break; - case SPECIALIZED_FUNCTION: { - final Type returnType = Type.getReturnType(javaDesc); - if (!(isValidJSType(returnType) || (isSpecializedConstructor() && Type.VOID_TYPE == returnType))) { - error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType); - } - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - for (int i = 0; i < argTypes.length; i++) { - if (!isValidJSType(argTypes[i])) { - error(i + "'th argument of a @SpecializedFunction method is not valid JS type, found " + argTypes[i]); - } - } - } - break; - case GETTER: { - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length != 1) { - error("@Getter methods should have one argument"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]); - } - - if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { - error("return type of getter should not be void"); - } - } - break; - case SETTER: { - final Type[] argTypes = Type.getArgumentTypes(javaDesc); - if (argTypes.length != 2) { - error("@Setter methods should have two arguments"); - } - if (!isJavaLangObject(argTypes[0])) { - error("first argument of a @Setter method should be of Object type, found: " + argTypes[0]); - } - if (!Type.getReturnType(javaDesc).toString().equals("V")) { - error("return type of of a @Setter method should be void, found: " + Type.getReturnType(javaDesc)); - } - } - break; - case PROPERTY: { - if (where == Where.CONSTRUCTOR) { - if (isStatic()) { - if (!isFinal()) { - error("static Where.CONSTRUCTOR @Property should be final"); - } - - if (!isJSPrimitiveType(Type.getType(javaDesc))) { - error("static Where.CONSTRUCTOR @Property should be a JS primitive"); - } - } - } else if (where == Where.PROTOTYPE) { - if (isStatic()) { - if (!isFinal()) { - error("static Where.PROTOTYPE @Property should be final"); - } - - if (!isJSPrimitiveType(Type.getType(javaDesc))) { - error("static Where.PROTOTYPE @Property should be a JS primitive"); - } - } - } - } - break; - - default: - break; - } - } - - /** - * Returns if the given (internal) name of a class represents a ScriptObject subtype. - */ - public static boolean isScriptObject(final String name) { - // very crude check for ScriptObject subtype! - if (name.startsWith(OBJ_PKG + "Native") || - name.equals(OBJ_PKG + "Global") || - name.equals(OBJ_PKG + "ArrayBufferView")) { - return true; - } - - if (name.startsWith(RUNTIME_PKG)) { - final String simpleName = name.substring(name.lastIndexOf('/') + 1); - switch (simpleName) { - case "ScriptObject": - case "ScriptFunction": - case "NativeJavaPackage": - case "Scope": - return true; - } - } - - if (name.startsWith(SCRIPTS_PKG)) { - final String simpleName = name.substring(name.lastIndexOf('/') + 1); - switch (simpleName) { - case "JD": - case "JO": - return true; - } - } - - return false; - } - - private static boolean isValidJSType(final Type type) { - return isJSPrimitiveType(type) || isJSObjectType(type); - } - - private static boolean isJSPrimitiveType(final Type type) { - switch (type.getSort()) { - case Type.BOOLEAN: - case Type.INT: - case Type.DOUBLE: - return true; - default: - return type != TYPE_SYMBOL; - } - } - - private static boolean isJSObjectType(final Type type) { - return isJavaLangObject(type) || isJavaLangString(type) || isScriptObject(type); - } - - private static boolean isJavaLangObject(final Type type) { - return type.getDescriptor().equals(OBJECT_DESC); - } - - private static boolean isJavaLangString(final Type type) { - return type.getDescriptor().equals(STRING_DESC); - } - - private static boolean isScriptObject(final Type type) { - if (type.getSort() != Type.OBJECT) { - return false; - } - - return isScriptObject(type.getInternalName()); - } - - private void error(final String msg) { - throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg); - } - - /** - * @return the initClass - */ - String getInitClass() { - return initClass; - } - - /** - * @param initClass the initClass to set - */ - void setInitClass(final String initClass) { - this.initClass = initClass; - } - - @Override - protected Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - assert false : "clone not supported " + e; - return null; - } - } - - /** - * @return the arity - */ - int getArity() { - return arity; - } - - /** - * @param arity the arity to set - */ - void setArity(final int arity) { - this.arity = arity; - } - - String getDocumentationKey(final String objName) { - if (kind == Kind.FUNCTION) { - final StringBuilder buf = new StringBuilder(objName); - switch (where) { - case CONSTRUCTOR: - break; - case PROTOTYPE: - buf.append(".prototype"); - break; - case INSTANCE: - buf.append(".this"); - break; - } - buf.append('.'); - buf.append(name); - return buf.toString(); - } - - return null; - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java deleted file mode 100644 index e69f03644df..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.AASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL; -import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.ANEWARRAY; -import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.BALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.BASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH; -import static jdk.internal.org.objectweb.asm.Opcodes.CALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.CASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST; -import static jdk.internal.org.objectweb.asm.Opcodes.DALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.DASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.DCONST_0; -import static jdk.internal.org.objectweb.asm.Opcodes.DRETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.DUP; -import static jdk.internal.org.objectweb.asm.Opcodes.DUP2; -import static jdk.internal.org.objectweb.asm.Opcodes.FALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.FASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.FCONST_0; -import static jdk.internal.org.objectweb.asm.Opcodes.FRETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD; -import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0; -import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1; -import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL; -import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.LALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.LASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0; -import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.NEW; -import static jdk.internal.org.objectweb.asm.Opcodes.POP; -import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD; -import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; -import static jdk.internal.org.objectweb.asm.Opcodes.SALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.SASTORE; -import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH; -import static jdk.internal.org.objectweb.asm.Opcodes.SWAP; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJ_ANNO_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT2; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_INIT3; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SPECIALIZATION_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_SPECIALIZATION; -import java.util.List; -import jdk.internal.org.objectweb.asm.Handle; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Type; - -/** - * Base class for all method generating classes. - * - */ -public class MethodGenerator extends MethodVisitor { - private final int access; - private final String name; - private final String descriptor; - private final Type returnType; - private final Type[] argumentTypes; - - static final Type EMPTY_LINK_LOGIC_TYPE = Type.getType("L" + OBJ_ANNO_PKG + "SpecializedFunction$LinkLogic$Empty;"); - - MethodGenerator(final MethodVisitor mv, final int access, final String name, final String descriptor) { - super(Main.ASM_VERSION, mv); - this.access = access; - this.name = name; - this.descriptor = descriptor; - this.returnType = Type.getReturnType(descriptor); - this.argumentTypes = Type.getArgumentTypes(descriptor); - } - - int getAccess() { - return access; - } - - final String getName() { - return name; - } - - final String getDescriptor() { - return descriptor; - } - - final Type getReturnType() { - return returnType; - } - - final Type[] getArgumentTypes() { - return argumentTypes; - } - - /** - * Check whether access for this method is static - * @return true if static - */ - protected final boolean isStatic() { - return (getAccess() & ACC_STATIC) != 0; - } - - /** - * Check whether this method is a constructor - * @return true if constructor - */ - protected final boolean isConstructor() { - return "".equals(name); - } - - void newObject(final String type) { - super.visitTypeInsn(NEW, type); - } - - void newObjectArray(final String type) { - super.visitTypeInsn(ANEWARRAY, type); - } - - void loadThis() { - if ((access & ACC_STATIC) != 0) { - throw new IllegalStateException("no 'this' inside static method"); - } - super.visitVarInsn(ALOAD, 0); - } - - void returnValue() { - super.visitInsn(returnType.getOpcode(IRETURN)); - } - - void returnVoid() { - super.visitInsn(RETURN); - } - - // load, store - void arrayLoad(final Type type) { - super.visitInsn(type.getOpcode(IALOAD)); - } - - void arrayLoad() { - super.visitInsn(AALOAD); - } - - void arrayStore(final Type type) { - super.visitInsn(type.getOpcode(IASTORE)); - } - - void arrayStore() { - super.visitInsn(AASTORE); - } - - void loadLiteral(final Object value) { - super.visitLdcInsn(value); - } - - void classLiteral(final String className) { - super.visitLdcInsn(className); - } - - void loadLocal(final Type type, final int index) { - super.visitVarInsn(type.getOpcode(ILOAD), index); - } - - void loadLocal(final int index) { - super.visitVarInsn(ALOAD, index); - } - - void storeLocal(final Type type, final int index) { - super.visitVarInsn(type.getOpcode(ISTORE), index); - } - - void storeLocal(final int index) { - super.visitVarInsn(ASTORE, index); - } - - void checkcast(final String type) { - super.visitTypeInsn(CHECKCAST, type); - } - - // push constants/literals - void pushNull() { - super.visitInsn(ACONST_NULL); - } - - void push(final int value) { - if (value >= -1 && value <= 5) { - super.visitInsn(ICONST_0 + value); - } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { - super.visitIntInsn(BIPUSH, value); - } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { - super.visitIntInsn(SIPUSH, value); - } else { - super.visitLdcInsn(value); - } - } - - void loadClass(final String className) { - super.visitLdcInsn(Type.getObjectType(className)); - } - - void pop() { - super.visitInsn(POP); - } - - // various "dups" - void dup() { - super.visitInsn(DUP); - } - - void dup2() { - super.visitInsn(DUP2); - } - - void swap() { - super.visitInsn(SWAP); - } - - void dupArrayValue(final int arrayOpcode) { - switch (arrayOpcode) { - case IALOAD: case FALOAD: - case AALOAD: case BALOAD: - case CALOAD: case SALOAD: - case IASTORE: case FASTORE: - case AASTORE: case BASTORE: - case CASTORE: case SASTORE: - dup(); - break; - - case LALOAD: case DALOAD: - case LASTORE: case DASTORE: - dup2(); - break; - default: - throw new AssertionError("invalid dup"); - } - } - - void dupReturnValue(final int returnOpcode) { - switch (returnOpcode) { - case IRETURN: - case FRETURN: - case ARETURN: - super.visitInsn(DUP); - return; - case LRETURN: - case DRETURN: - super.visitInsn(DUP2); - return; - case RETURN: - return; - default: - throw new IllegalArgumentException("not return"); - } - } - - void dupValue(final Type type) { - switch (type.getSize()) { - case 1: - dup(); - break; - case 2: - dup2(); - break; - default: - throw new AssertionError("invalid dup"); - } - } - - void dupValue(final String desc) { - final int typeCode = desc.charAt(0); - switch (typeCode) { - case '[': - case 'L': - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - super.visitInsn(DUP); - break; - case 'J': - case 'D': - super.visitInsn(DUP2); - break; - default: - throw new RuntimeException("invalid signature"); - } - } - - // push default value of given type desc - void defaultValue(final String desc) { - final int typeCode = desc.charAt(0); - switch (typeCode) { - case '[': - case 'L': - super.visitInsn(ACONST_NULL); - break; - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - super.visitInsn(ICONST_0); - break; - case 'J': - super.visitInsn(LCONST_0); - break; - case 'F': - super.visitInsn(FCONST_0); - break; - case 'D': - super.visitInsn(DCONST_0); - break; - default: - throw new AssertionError("invalid desc " + desc); - } - } - - // invokes, field get/sets - void invokeInterface(final String owner, final String method, final String desc) { - super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc, true); - } - - void invokeVirtual(final String owner, final String method, final String desc) { - super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc, false); - } - - void invokeSpecial(final String owner, final String method, final String desc) { - super.visitMethodInsn(INVOKESPECIAL, owner, method, desc, false); - } - - void invokeStatic(final String owner, final String method, final String desc) { - super.visitMethodInsn(INVOKESTATIC, owner, method, desc, false); - } - - void putStatic(final String owner, final String field, final String desc) { - super.visitFieldInsn(PUTSTATIC, owner, field, desc); - } - - void getStatic(final String owner, final String field, final String desc) { - super.visitFieldInsn(GETSTATIC, owner, field, desc); - } - - void putField(final String owner, final String field, final String desc) { - super.visitFieldInsn(PUTFIELD, owner, field, desc); - } - - void getField(final String owner, final String field, final String desc) { - super.visitFieldInsn(GETFIELD, owner, field, desc); - } - - private static boolean linkLogicIsEmpty(final Type type) { - assert EMPTY_LINK_LOGIC_TYPE != null; //type is ok for null if we are a @SpecializedFunction without any attribs - return EMPTY_LINK_LOGIC_TYPE.equals(type); - } - - void memberInfoArray(final String className, final List mis) { - if (mis.isEmpty()) { - pushNull(); - return; - } - - int pos = 0; - push(mis.size()); - newObjectArray(SPECIALIZATION_TYPE); - for (final MemberInfo mi : mis) { - dup(); - push(pos++); - visitTypeInsn(NEW, SPECIALIZATION_TYPE); - dup(); - visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc(), false)); - final Type linkLogicClass = mi.getLinkLogicClass(); - final boolean linkLogic = !linkLogicIsEmpty(linkLogicClass); - final String ctor = linkLogic ? SPECIALIZATION_INIT3 : SPECIALIZATION_INIT2; - if (linkLogic) { - visitLdcInsn(linkLogicClass); - } - visitInsn(mi.isOptimistic() ? ICONST_1 : ICONST_0); - visitInsn(mi.convertsNumericArgs() ? ICONST_1 : ICONST_0); - visitMethodInsn(INVOKESPECIAL, SPECIALIZATION_TYPE, INIT, ctor, false); - arrayStore(TYPE_SPECIALIZATION); - } - } - - void computeMaxs() { - // These values are ignored as we create class writer - // with ClassWriter.COMPUTE_MAXS flag. - super.visitMaxs(Short.MAX_VALUE, Short.MAX_VALUE); - } - - // debugging support - print calls - void println(final String msg) { - super.visitFieldInsn(GETSTATIC, - "java/lang/System", - "out", - "Ljava/io/PrintStream;"); - super.visitLdcInsn(msg); - super.visitMethodInsn(INVOKEVIRTUAL, - "java/io/PrintStream", - "println", - "(Ljava/lang/String;)V", - false); - } - - // print the object on the top of the stack - void printObject() { - super.visitFieldInsn(GETSTATIC, - "java/lang/System", - "out", - "Ljava/io/PrintStream;"); - super.visitInsn(SWAP); - super.visitMethodInsn(INVOKEVIRTUAL, - "java/io/PrintStream", - "println", - "(Ljava/lang/Object;)V", - false); - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java deleted file mode 100644 index 10d7f3f037b..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; - -/** - * A visitor that does nothing on visitXXX calls. - * - */ -public class NullVisitor extends ClassVisitor { - NullVisitor() { - super(Main.ASM_VERSION); - } - - @Override - public MethodVisitor visitMethod( - final int access, - final String name, - final String desc, - final String signature, - final String[] exceptions) { - return new MethodVisitor(Main.ASM_VERSION) { - @Override - public AnnotationVisitor visitAnnotationDefault() { - return new NullAnnotationVisitor(); - } - - @Override - public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { - return new NullAnnotationVisitor(); - } - }; - } - - @Override - public FieldVisitor visitField( - final int access, - final String name, - final String desc, - final String signature, - final Object value) { - return new FieldVisitor(Main.ASM_VERSION) { - @Override - public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { - return new NullAnnotationVisitor(); - } - }; - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - return new NullAnnotationVisitor(); - } - - private static class NullAnnotationVisitor extends AnnotationVisitor { - NullAnnotationVisitor() { - super(Main.ASM_VERSION); - } - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java deleted file mode 100644 index bcd543e8ae2..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; -import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; - -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * This class generates prototype class for a @ScriptClass annotated class. - * - */ -public class PrototypeGenerator extends ClassGenerator { - private final ScriptClassInfo scriptClassInfo; - private final String className; - private final int memberCount; - - PrototypeGenerator(final ScriptClassInfo sci) { - this.scriptClassInfo = sci; - this.className = scriptClassInfo.getPrototypeClassName(); - this.memberCount = scriptClassInfo.getPrototypeMemberCount(); - } - - byte[] getClassBytes() { - // new class extending from ScriptObject - cw.visit(V1_7, ACC_FINAL | ACC_SUPER, className, null, PROTOTYPEOBJECT_TYPE, null); - if (memberCount > 0) { - // add fields - emitFields(); - // add - emitStaticInitializer(); - } - - // add - emitConstructor(); - - // add getClassName() - emitGetClassName(scriptClassInfo.getName()); - - cw.visitEnd(); - return cw.toByteArray(); - } - - // --Internals only below this point - private void emitFields() { - // introduce "Function" type instance fields for each - // prototype @Function in script class info - for (MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isPrototypeFunction()) { - addFunctionField(memInfo.getJavaName()); - memInfo = (MemberInfo)memInfo.clone(); - memInfo.setJavaDesc(OBJECT_DESC); - addGetter(className, memInfo); - addSetter(className, memInfo); - } else if (memInfo.isPrototypeProperty()) { - if (memInfo.isStaticFinal()) { - addGetter(scriptClassInfo.getJavaName(), memInfo); - } else { - addField(memInfo.getJavaName(), memInfo.getJavaDesc()); - memInfo = (MemberInfo)memInfo.clone(); - memInfo.setJavaAccess(ACC_PUBLIC); - addGetter(className, memInfo); - addSetter(className, memInfo); - } - } - } - - addMapField(); - } - - private void emitStaticInitializer() { - final MethodGenerator mi = makeStaticInitializer(); - emitStaticInitPrefix(mi, className, memberCount); - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) { - linkerAddGetterSetter(mi, className, memInfo); - } else if (memInfo.isPrototypeGetter()) { - final MemberInfo setter = scriptClassInfo.findSetter(memInfo); - linkerAddGetterSetter(mi, scriptClassInfo.getJavaName(), memInfo, setter); - } - } - emitStaticInitSuffix(mi, className); - } - - private void emitConstructor() { - final MethodGenerator mi = makeConstructor(); - mi.visitCode(); - mi.loadThis(); - if (memberCount > 0) { - // call "super(map$)" - mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); - mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); - // initialize Function type fields - initFunctionFields(mi); - } else { - // call "super()" - mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, DEFAULT_INIT_DESC); - } - mi.returnVoid(); - mi.computeMaxs(); - mi.visitEnd(); - } - - private void initFunctionFields(final MethodGenerator mi) { - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (! memInfo.isPrototypeFunction()) { - continue; - } - mi.loadThis(); - newFunction(mi, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); - mi.putField(className, memInfo.getJavaName(), OBJECT_DESC); - } - } - - /** - * External entry point for PrototypeGenerator if called from the command line - * - * @param args arguments, takes 1 argument which is the class to process - * @throws IOException if class cannot be read - */ - public static void main(final String[] args) throws IOException { - if (args.length != 1) { - System.err.println("Usage: " + PrototypeGenerator.class.getName() + " "); - System.exit(1); - } - - final String className = args[0].replace('.', '/'); - final ScriptClassInfo sci = getScriptClassInfo(className + ".class"); - if (sci == null) { - System.err.println("No @ScriptClass in " + className); - System.exit(2); - throw new AssertionError(); //guard against warning that sci is null below - } - try { - sci.verify(); - } catch (final Exception e) { - System.err.println(e.getMessage()); - System.exit(3); - } - final PrototypeGenerator gen = new PrototypeGenerator(sci); - try (FileOutputStream fos = new FileOutputStream(className + PROTOTYPE_SUFFIX + ".class")) { - fos.write(gen.getClassBytes()); - } - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java deleted file mode 100644 index 85582232ad5..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import jdk.internal.org.objectweb.asm.Type; -import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; - -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJ_ANNO_PKG; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.RUNTIME_PKG; - -/** - * All annotation information from a class that is annotated with - * the annotation com.sun.oracle.objects.annotations.ScriptClass. - * - */ -public final class ScriptClassInfo { - private static String getTypeDescriptor(final String pkg, final String name) { - return "L" + pkg + name + ";"; - } - - // descriptors for various annotations - static final String SCRIPT_CLASS_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "ScriptClass"); - static final String CONSTRUCTOR_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Constructor"); - static final String FUNCTION_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Function"); - static final String GETTER_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Getter"); - static final String SETTER_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Setter"); - static final String PROPERTY_ANNO_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Property"); - static final String WHERE_ENUM_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "Where"); - static final String LINK_LOGIC_DESC = getTypeDescriptor(OBJ_ANNO_PKG, "SpecializedFunction$LinkLogic"); - static final String SPECIALIZED_FUNCTION = getTypeDescriptor(OBJ_ANNO_PKG, "SpecializedFunction"); - - static final Map annotations = new HashMap<>(); - - static { - annotations.put(SCRIPT_CLASS_ANNO_DESC, Kind.SCRIPT_CLASS); - annotations.put(FUNCTION_ANNO_DESC, Kind.FUNCTION); - annotations.put(CONSTRUCTOR_ANNO_DESC, Kind.CONSTRUCTOR); - annotations.put(GETTER_ANNO_DESC, Kind.GETTER); - annotations.put(SETTER_ANNO_DESC, Kind.SETTER); - annotations.put(PROPERTY_ANNO_DESC, Kind.PROPERTY); - annotations.put(SPECIALIZED_FUNCTION, Kind.SPECIALIZED_FUNCTION); - } - - // name of the script class - private String name; - // member info for script properties - private List members = Collections.emptyList(); - // java class name that is annotated with @ScriptClass - private String javaName; - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(final String name) { - this.name = name; - } - - /** - * @return the members - */ - public List getMembers() { - return Collections.unmodifiableList(members); - } - - /** - * @param members the members to set - */ - public void setMembers(final List members) { - this.members = members; - } - - MemberInfo getConstructor() { - for (final MemberInfo memInfo : members) { - if (memInfo.getKind() == Kind.CONSTRUCTOR) { - return memInfo; - } - } - return null; - } - - List getSpecializedConstructors() { - final List res = new LinkedList<>(); - for (final MemberInfo memInfo : members) { - if (memInfo.isSpecializedConstructor()) { - assert memInfo.getKind() == Kind.SPECIALIZED_FUNCTION; - res.add(memInfo); - } - } - return Collections.unmodifiableList(res); - } - - boolean isConstructorNeeded() { - // Constructor class generation is needed if we one or - // more constructor properties are defined or @Constructor - // is defined in the class. - for (final MemberInfo memInfo : members) { - if (memInfo.getKind() == Kind.CONSTRUCTOR || - memInfo.getWhere() == Where.CONSTRUCTOR) { - return true; - } - } - return false; - } - - boolean isPrototypeNeeded() { - // Prototype class generation is needed if we have at least one - // prototype property or @Constructor defined in the class. - for (final MemberInfo memInfo : members) { - if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) { - return true; - } - } - return false; - } - - int getPrototypeMemberCount() { - int count = 0; - for (final MemberInfo memInfo : members) { - switch (memInfo.getKind()) { - case SETTER: - case SPECIALIZED_FUNCTION: - // SETTER was counted when GETTER was encountered. - // SPECIALIZED_FUNCTION was counted as FUNCTION already. - continue; - } - - if (memInfo.getWhere() == Where.PROTOTYPE) { - count++; - } - } - return count; - } - - int getConstructorMemberCount() { - int count = 0; - for (final MemberInfo memInfo : members) { - switch (memInfo.getKind()) { - case CONSTRUCTOR: - case SETTER: - case SPECIALIZED_FUNCTION: - // SETTER was counted when GETTER was encountered. - // Constructor and constructor SpecializedFunctions - // are not added as members and so not counted. - continue; - } - - if (memInfo.getWhere() == Where.CONSTRUCTOR) { - count++; - } - } - return count; - } - - int getInstancePropertyCount() { - int count = 0; - for (final MemberInfo memInfo : members) { - switch (memInfo.getKind()) { - case SETTER: - case SPECIALIZED_FUNCTION: - // SETTER was counted when GETTER was encountered. - // SPECIALIZED_FUNCTION was counted as FUNCTION already. - continue; - } - - if (memInfo.getWhere() == Where.INSTANCE) { - count++; - } - } - return count; - } - - MemberInfo find(final String findJavaName, final String findJavaDesc, final int findAccess) { - for (final MemberInfo memInfo : members) { - if (memInfo.getJavaName().equals(findJavaName) && - memInfo.getJavaDesc().equals(findJavaDesc) && - memInfo.getJavaAccess() == findAccess) { - return memInfo; - } - } - return null; - } - - List findSpecializations(final String methodName) { - final List res = new LinkedList<>(); - for (final MemberInfo memInfo : members) { - if (memInfo.getName().equals(methodName) && - memInfo.getKind() == Kind.SPECIALIZED_FUNCTION) { - res.add(memInfo); - } - } - return Collections.unmodifiableList(res); - } - - MemberInfo findSetter(final MemberInfo getter) { - assert getter.getKind() == Kind.GETTER : "getter expected"; - final String getterName = getter.getName(); - final Where getterWhere = getter.getWhere(); - for (final MemberInfo memInfo : members) { - if (memInfo.getKind() == Kind.SETTER && - getterName.equals(memInfo.getName()) && - getterWhere == memInfo.getWhere()) { - return memInfo; - } - } - return null; - } - - /** - * @return the javaName - */ - public String getJavaName() { - return javaName; - } - - /** - * @param javaName the javaName to set - */ - void setJavaName(final String javaName) { - this.javaName = javaName; - } - - String getConstructorClassName() { - return getJavaName() + StringConstants.CONSTRUCTOR_SUFFIX; - } - - String getPrototypeClassName() { - return getJavaName() + StringConstants.PROTOTYPE_SUFFIX; - } - - void verify() { - boolean constructorSeen = false; - for (final MemberInfo memInfo : getMembers()) { - if (memInfo.isConstructor()) { - if (constructorSeen) { - error("more than @Constructor method"); - } - constructorSeen = true; - } - try { - memInfo.verify(); - } catch (final Exception e) { - e.printStackTrace(); - error(e.getMessage()); - } - } - } - - private void error(final String msg) throws RuntimeException { - throw new RuntimeException(javaName + " : " + msg); - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java deleted file mode 100644 index a39204d3b3e..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.SCRIPT_CLASS_ANNO_DESC; -import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.WHERE_ENUM_DESC; -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.Opcodes; -import jdk.internal.org.objectweb.asm.Type; -import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; - -/** - * This class collects all @ScriptClass and other annotation information from a - * compiled .class file. Enforces that @Function/@Getter/@Setter/@Constructor - * methods are declared to be 'static'. - */ -public class ScriptClassInfoCollector extends ClassVisitor { - private String scriptClassName; - private List scriptMembers; - private String javaClassName; - - ScriptClassInfoCollector(final ClassVisitor visitor) { - super(Main.ASM_VERSION, visitor); - } - - ScriptClassInfoCollector() { - this(new NullVisitor()); - } - - private void addScriptMember(final MemberInfo memInfo) { - if (scriptMembers == null) { - scriptMembers = new ArrayList<>(); - } - scriptMembers.add(memInfo); - } - - @Override - public void visit(final int version, final int access, final String name, final String signature, - final String superName, final String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - javaClassName = name; - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - final AnnotationVisitor delegateAV = super.visitAnnotation(desc, visible); - if (SCRIPT_CLASS_ANNO_DESC.equals(desc)) { - return new AnnotationVisitor(Main.ASM_VERSION, delegateAV) { - @Override - public void visit(final String name, final Object value) { - if ("value".equals(name)) { - scriptClassName = (String) value; - } - super.visit(name, value); - } - }; - } - - return delegateAV; - } - - @Override - public FieldVisitor visitField(final int fieldAccess, final String fieldName, final String fieldDesc, final String signature, final Object value) { - final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc, signature, value); - - return new FieldVisitor(Main.ASM_VERSION, delegateFV) { - @Override - public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { - final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible); - - if (ScriptClassInfo.PROPERTY_ANNO_DESC.equals(descriptor)) { - final MemberInfo memInfo = new MemberInfo(); - - memInfo.setKind(Kind.PROPERTY); - memInfo.setJavaName(fieldName); - memInfo.setJavaDesc(fieldDesc); - memInfo.setJavaAccess(fieldAccess); - - if ((fieldAccess & Opcodes.ACC_STATIC) != 0) { - memInfo.setValue(value); - } - - addScriptMember(memInfo); - - return new AnnotationVisitor(Main.ASM_VERSION, delegateAV) { - // These could be "null" if values are not supplied, - // in which case we have to use the default values. - private String name; - private Integer attributes; - private String clazz = ""; - private Where where; - - @Override - public void visit(final String annotationName, final Object annotationValue) { - switch (annotationName) { - case "name": - this.name = (String) annotationValue; - break; - case "attributes": - this.attributes = (Integer) annotationValue; - break; - case "clazz": - this.clazz = (annotationValue == null) ? "" : annotationValue.toString(); - break; - default: - break; - } - super.visit(annotationName, annotationValue); - } - - @Override - public void visitEnum(final String enumName, final String desc, final String enumValue) { - if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) { - this.where = Where.valueOf(enumValue); - } - super.visitEnum(enumName, desc, enumValue); - } - - @Override - public void visitEnd() { - super.visitEnd(); - memInfo.setName(name == null ? fieldName : name); - memInfo.setAttributes(attributes == null - ? MemberInfo.DEFAULT_ATTRIBUTES : attributes); - clazz = clazz.replace('.', '/'); - memInfo.setInitClass(clazz); - memInfo.setWhere(where == null? Where.INSTANCE : where); - } - }; - } - - return delegateAV; - } - }; - } - - private void error(final String javaName, final String javaDesc, final String msg) { - throw new RuntimeException(scriptClassName + "." + javaName + javaDesc + " : " + msg); - } - - @Override - public MethodVisitor visitMethod(final int methodAccess, final String methodName, - final String methodDesc, final String signature, final String[] exceptions) { - - final MethodVisitor delegateMV = super.visitMethod(methodAccess, methodName, methodDesc, - signature, exceptions); - - return new MethodVisitor(Main.ASM_VERSION, delegateMV) { - - @Override - public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { - final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible); - final Kind annoKind = ScriptClassInfo.annotations.get(descriptor); - - if (annoKind != null) { - if ((methodAccess & Opcodes.ACC_STATIC) == 0) { - error(methodName, methodDesc, "nasgen method annotations cannot be on instance methods"); - } - - final MemberInfo memInfo = new MemberInfo(); - - // annoKind == GETTER or SPECIALIZED_FUNCTION - memInfo.setKind(annoKind); - memInfo.setJavaName(methodName); - memInfo.setJavaDesc(methodDesc); - memInfo.setJavaAccess(methodAccess); - - addScriptMember(memInfo); - - return new AnnotationVisitor(Main.ASM_VERSION, delegateAV) { - // These could be "null" if values are not supplied, - // in which case we have to use the default values. - private String name; - private Integer attributes; - private Integer arity; - private Where where; - private boolean isSpecializedConstructor; - private boolean isOptimistic; - private boolean convertsNumericArgs; - private Type linkLogicClass = MethodGenerator.EMPTY_LINK_LOGIC_TYPE; - - @Override - public void visit(final String annotationName, final Object annotationValue) { - switch (annotationName) { - case "name": - this.name = (String)annotationValue; - if (name.isEmpty()) { - name = null; - } - break; - case "attributes": - this.attributes = (Integer)annotationValue; - break; - case "arity": - this.arity = (Integer)annotationValue; - break; - case "isConstructor": - assert annoKind == Kind.SPECIALIZED_FUNCTION; - this.isSpecializedConstructor = (Boolean)annotationValue; - break; - case "isOptimistic": - assert annoKind == Kind.SPECIALIZED_FUNCTION; - this.isOptimistic = (Boolean)annotationValue; - break; - case "linkLogic": - this.linkLogicClass = (Type)annotationValue; - break; - case "convertsNumericArgs": - assert annoKind == Kind.SPECIALIZED_FUNCTION; - this.convertsNumericArgs = (Boolean)annotationValue; - break; - default: - break; - } - - super.visit(annotationName, annotationValue); - } - - @Override - public void visitEnum(final String enumName, final String desc, final String enumValue) { - switch (enumName) { - case "where": - if (WHERE_ENUM_DESC.equals(desc)) { - this.where = Where.valueOf(enumValue); - } - break; - default: - break; - } - super.visitEnum(enumName, desc, enumValue); - } - - @SuppressWarnings("fallthrough") - @Override - public void visitEnd() { - super.visitEnd(); - - if (memInfo.getKind() == Kind.CONSTRUCTOR) { - memInfo.setName(name == null ? scriptClassName : name); - } else { - memInfo.setName(name == null ? methodName : name); - } - - memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes); - - memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity); - if (where == null) { - // by default @Getter/@Setter belongs to INSTANCE - // @Function belong to PROTOTYPE. - switch (memInfo.getKind()) { - case GETTER: - case SETTER: - where = Where.INSTANCE; - break; - case CONSTRUCTOR: - where = Where.CONSTRUCTOR; - break; - case FUNCTION: - where = Where.PROTOTYPE; - break; - case SPECIALIZED_FUNCTION: - where = isSpecializedConstructor? Where.CONSTRUCTOR : Where.PROTOTYPE; - //fallthru - default: - break; - } - } - memInfo.setWhere(where); - memInfo.setLinkLogicClass(linkLogicClass); - memInfo.setIsSpecializedConstructor(isSpecializedConstructor); - memInfo.setIsOptimistic(isOptimistic); - memInfo.setConvertsNumericArgs(convertsNumericArgs); - } - }; - } - - return delegateAV; - } - }; - } - - ScriptClassInfo getScriptClassInfo() { - ScriptClassInfo sci = null; - if (scriptClassName != null) { - sci = new ScriptClassInfo(); - sci.setName(scriptClassName); - if (scriptMembers == null) { - scriptMembers = Collections.emptyList(); - } - sci.setMembers(scriptMembers); - sci.setJavaName(javaClassName); - } - return sci; - } - - /** - * External entry point for ScriptClassInfoCollector if invoked from the command line - * @param args argument vector, args contains a class for which to collect info - * @throws IOException if there were problems parsing args or class - */ - public static void main(final String[] args) throws IOException { - if (args.length != 1) { - System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " "); - System.exit(1); - } - - args[0] = args[0].replace('.', '/'); - final ScriptClassInfoCollector scic = new ScriptClassInfoCollector(); - try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0] + ".class"))) { - final ClassReader reader = new ClassReader(bis); - reader.accept(scic, 0); - } - final ScriptClassInfo sci = scic.getScriptClassInfo(); - final PrintStream out = System.out; - if (sci != null) { - out.println("script class: " + sci.getName()); - out.println("==================================="); - for (final MemberInfo memInfo : sci.getMembers()) { - out.println("kind : " + memInfo.getKind()); - out.println("name : " + memInfo.getName()); - out.println("attributes: " + memInfo.getAttributes()); - out.println("javaName: " + memInfo.getJavaName()); - out.println("javaDesc: " + memInfo.getJavaDesc()); - out.println("where: " + memInfo.getWhere()); - out.println("====================================="); - } - } else { - out.println(args[0] + " is not a @ScriptClass"); - } - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java deleted file mode 100644 index 4bdb35867a3..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD; -import static jdk.internal.org.objectweb.asm.Opcodes.DUP; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; -import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.NEW; -import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD; -import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.$CLINIT$; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE; -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import jdk.internal.org.objectweb.asm.AnnotationVisitor; -import jdk.internal.org.objectweb.asm.Attribute; -import jdk.internal.org.objectweb.asm.ClassReader; -import jdk.internal.org.objectweb.asm.ClassVisitor; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.FieldVisitor; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; -import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; - -/** - * This class instruments the java class annotated with @ScriptClass. - * - * Changes done are: - * - * 1) remove all jdk.nashorn.internal.objects.annotations.* annotations. - * 2) static final @Property fields stay here. Other @Property fields moved to - * respective classes depending on 'where' value of annotation. - * 2) add "Map" type static field named "$map". - * 3) add static initializer block to initialize map. - */ -public class ScriptClassInstrumentor extends ClassVisitor { - private final ScriptClassInfo scriptClassInfo; - private final int memberCount; - private boolean staticInitFound; - - ScriptClassInstrumentor(final ClassVisitor visitor, final ScriptClassInfo sci) { - super(Main.ASM_VERSION, visitor); - if (sci == null) { - throw new IllegalArgumentException("Null ScriptClassInfo, is the class annotated?"); - } - this.scriptClassInfo = sci; - this.memberCount = scriptClassInfo.getInstancePropertyCount(); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (ScriptClassInfo.annotations.containsKey(desc)) { - // ignore @ScriptClass - return null; - } - - return super.visitAnnotation(desc, visible); - } - - @Override - public FieldVisitor visitField(final int fieldAccess, final String fieldName, - final String fieldDesc, final String signature, final Object value) { - final MemberInfo memInfo = scriptClassInfo.find(fieldName, fieldDesc, fieldAccess); - if (memInfo != null && memInfo.getKind() == Kind.PROPERTY && - memInfo.getWhere() != Where.INSTANCE && !memInfo.isStaticFinal()) { - // non-instance @Property fields - these have to go elsewhere unless 'static final' - return null; - } - - final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc, - signature, value); - return new FieldVisitor(Main.ASM_VERSION, delegateFV) { - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (ScriptClassInfo.annotations.containsKey(desc)) { - // ignore script field annotations - return null; - } - - return fv.visitAnnotation(desc, visible); - } - - @Override - public void visitAttribute(final Attribute attr) { - fv.visitAttribute(attr); - } - - @Override - public void visitEnd() { - fv.visitEnd(); - } - }; - } - - @Override - public MethodVisitor visitMethod(final int methodAccess, final String methodName, - final String methodDesc, final String signature, final String[] exceptions) { - - final boolean isConstructor = INIT.equals(methodName); - final boolean isStaticInit = CLINIT.equals(methodName); - - if (isStaticInit) { - staticInitFound = true; - } - - final MethodGenerator delegateMV = new MethodGenerator(super.visitMethod(methodAccess, methodName, methodDesc, - signature, exceptions), methodAccess, methodName, methodDesc); - - return new MethodVisitor(Main.ASM_VERSION, delegateMV) { - @Override - public void visitInsn(final int opcode) { - // call $clinit$ just before return from - if (isStaticInit && opcode == RETURN) { - super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(), - $CLINIT$, DEFAULT_INIT_DESC, false); - } - super.visitInsn(opcode); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { - if (isConstructor && opcode == INVOKESPECIAL && - INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) { - super.visitMethodInsn(opcode, owner, name, desc, false); - - if (memberCount > 0) { - // initialize @Property fields if needed - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isInstanceProperty() && !memInfo.getInitClass().isEmpty()) { - final String clazz = memInfo.getInitClass(); - super.visitVarInsn(ALOAD, 0); - super.visitTypeInsn(NEW, clazz); - super.visitInsn(DUP); - super.visitMethodInsn(INVOKESPECIAL, clazz, - INIT, DEFAULT_INIT_DESC, false); - super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(), - memInfo.getJavaName(), memInfo.getJavaDesc()); - } - - if (memInfo.isInstanceFunction()) { - super.visitVarInsn(ALOAD, 0); - ClassGenerator.newFunction(delegateMV, scriptClassInfo.getName(), scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); - super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(), - memInfo.getJavaName(), OBJECT_DESC); - } - } - } - } else { - super.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { - if (ScriptClassInfo.annotations.containsKey(desc)) { - // ignore script method annotations - return null; - } - return super.visitAnnotation(desc, visible); - } - }; - } - - @Override - public void visitEnd() { - emitFields(); - emitStaticInitializer(); - emitGettersSetters(); - super.visitEnd(); - } - - private void emitFields() { - // introduce "Function" type instance fields for each - // instance @Function in script class info - final String className = scriptClassInfo.getJavaName(); - for (MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isInstanceFunction()) { - ClassGenerator.addFunctionField(cv, memInfo.getJavaName()); - memInfo = (MemberInfo)memInfo.clone(); - memInfo.setJavaDesc(OBJECT_DESC); - ClassGenerator.addGetter(cv, className, memInfo); - ClassGenerator.addSetter(cv, className, memInfo); - } - } - // omit addMapField() since instance classes already define a static PropertyMap field - } - - void emitGettersSetters() { - if (memberCount > 0) { - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - final String className = scriptClassInfo.getJavaName(); - if (memInfo.isInstanceProperty()) { - ClassGenerator.addGetter(cv, className, memInfo); - if (! memInfo.isFinal()) { - ClassGenerator.addSetter(cv, className, memInfo); - } - } - } - } - } - - private void emitStaticInitializer() { - final String className = scriptClassInfo.getJavaName(); - if (! staticInitFound) { - // no user written and so create one - final MethodVisitor mv = ClassGenerator.makeStaticInitializer(this); - mv.visitCode(); - mv.visitInsn(RETURN); - mv.visitMaxs(Short.MAX_VALUE, 0); - mv.visitEnd(); - } - // Now generate $clinit$ - final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$); - ClassGenerator.emitStaticInitPrefix(mi, className, memberCount); - if (memberCount > 0) { - for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { - if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) { - ClassGenerator.linkerAddGetterSetter(mi, className, memInfo); - } else if (memInfo.isInstanceGetter()) { - final MemberInfo setter = scriptClassInfo.findSetter(memInfo); - ClassGenerator.linkerAddGetterSetter(mi, className, memInfo, setter); - } - } - } - ClassGenerator.emitStaticInitSuffix(mi, className); - } - - /** - * External entry point for ScriptClassInfoCollector if run from the command line - * - * @param args arguments - one argument is needed, the name of the class to collect info from - * - * @throws IOException if there are problems reading class - */ - public static void main(final String[] args) throws IOException { - if (args.length != 1) { - System.err.println("Usage: " + ScriptClassInstrumentor.class.getName() + " "); - System.exit(1); - } - - final String fileName = args[0].replace('.', '/') + ".class"; - final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(fileName); - if (sci == null) { - System.err.println("No @ScriptClass in " + fileName); - System.exit(2); - throw new AssertionError(); //guard against warning that sci is null below - } - - try { - sci.verify(); - } catch (final Exception e) { - System.err.println(e.getMessage()); - System.exit(3); - } - - final ClassWriter writer = ClassGenerator.makeClassWriter(); - try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) { - final ClassReader reader = new ClassReader(bis); - final CheckClassAdapter checker = new CheckClassAdapter(writer); - final ScriptClassInstrumentor instr = new ScriptClassInstrumentor(checker, sci); - reader.accept(instr, 0); - } - - try (FileOutputStream fos = new FileOutputStream(fileName)) { - fos.write(writer.toByteArray()); - } - } -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java deleted file mode 100644 index 2dc560af98b..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -import java.lang.invoke.MethodHandle; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import jdk.internal.org.objectweb.asm.Type; - -/** - * String constants used for code generation/instrumentation. - */ -@SuppressWarnings("javadoc") -public interface StringConstants { - static final String NASHORN_INTERNAL = "jdk/nashorn/internal/"; - static final String OBJ_PKG = NASHORN_INTERNAL + "objects/"; - static final String OBJ_ANNO_PKG = OBJ_PKG + "annotations/"; - static final String RUNTIME_PKG = NASHORN_INTERNAL + "runtime/"; - static final String SCRIPTS_PKG = NASHORN_INTERNAL + "scripts/"; - - // standard jdk types, methods - static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class); - static final Type TYPE_SPECIALIZATION = Type.getType("L" + RUNTIME_PKG + "Specialization;"); - static final Type TYPE_SPECIALIZATION_ARRAY = Type.getType("[L" + RUNTIME_PKG + "Specialization;"); - static final Type TYPE_OBJECT = Type.getType(Object.class); - static final Type TYPE_STRING = Type.getType(String.class); - static final Type TYPE_CLASS = Type.getType(Class.class); - static final Type TYPE_COLLECTION = Type.getType(Collection.class); - static final Type TYPE_COLLECTIONS = Type.getType(Collections.class); - static final Type TYPE_ARRAYLIST = Type.getType(ArrayList.class); - static final Type TYPE_LIST = Type.getType(List.class); - - static final String CLINIT = ""; - static final String INIT = ""; - static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE); - - static final String SPECIALIZATION_TYPE = TYPE_SPECIALIZATION.getInternalName(); - static final String SPECIALIZATION_INIT2 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, Type.BOOLEAN_TYPE, Type.BOOLEAN_TYPE); - static final String SPECIALIZATION_INIT3 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_METHODHANDLE, TYPE_CLASS, Type.BOOLEAN_TYPE, Type.BOOLEAN_TYPE); - static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName(); - static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor(); - static final String STRING_DESC = TYPE_STRING.getDescriptor(); - static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class); - static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName(); - static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName(); - static final String COLLECTIONS_TYPE = TYPE_COLLECTIONS.getInternalName(); - - // java.util.Collection.add(Object) - static final String COLLECTION_ADD = "add"; - static final String COLLECTION_ADD_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, TYPE_OBJECT); - // java.util.ArrayList.(int) - static final String ARRAYLIST_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); - // java.util.Collections.EMPTY_LIST - static final String COLLECTIONS_EMPTY_LIST = "EMPTY_LIST"; - static final String LIST_DESC = TYPE_LIST.getDescriptor(); - - // Nashorn types, methods - static final Type TYPE_ACCESSORPROPERTY = Type.getType("L" + RUNTIME_PKG + "AccessorProperty;"); - static final Type TYPE_PROPERTYMAP = Type.getType("L" + RUNTIME_PKG + "PropertyMap;"); - static final Type TYPE_PROTOTYPEOBJECT = Type.getType("L" + RUNTIME_PKG + "PrototypeObject;"); - static final Type TYPE_SCRIPTFUNCTION = Type.getType("L" + RUNTIME_PKG + "ScriptFunction;"); - static final Type TYPE_SCRIPTOBJECT = Type.getType("L" + RUNTIME_PKG + "ScriptObject;"); - static final Type TYPE_NATIVESYMBOL = Type.getType("L" + OBJ_PKG + "NativeSymbol;"); - static final Type TYPE_SYMBOL = Type.getType("L" + RUNTIME_PKG + "Symbol;"); - - static final String PROTOTYPE_SUFFIX = "$Prototype"; - static final String CONSTRUCTOR_SUFFIX = "$Constructor"; - - // This field name is known to Nashorn runtime (Context). - // Synchronize the name change, if needed at all. - static final String PROPERTYMAP_FIELD_NAME = "$nasgenmap$"; - static final String $CLINIT$ = "$clinit$"; - - // AccessorProperty - static final String ACCESSORPROPERTY_TYPE = TYPE_ACCESSORPROPERTY.getInternalName(); - static final String ACCESSORPROPERTY_CREATE = "create"; - static final String ACCESSORPROPERTY_CREATE_DESC = - Type.getMethodDescriptor(TYPE_ACCESSORPROPERTY, TYPE_OBJECT, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE); - - // PropertyMap - static final String PROPERTYMAP_TYPE = TYPE_PROPERTYMAP.getInternalName(); - static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); - static final String PROPERTYMAP_NEWMAP = "newMap"; - static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION); - - // PrototypeObject - static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName(); - static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor"; - static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT); - - // ScriptFunction - static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName(); - static final String SCRIPTFUNCTION_SETARITY = "setArity"; - static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); - static final String SCRIPTFUNCTION_SETDOCUMENTATIONKEY = "setDocumentationKey"; - static final String SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING); - static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype"; - static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT); - static final String SCRIPTFUNCTION_CREATEBUILTIN = "createBuiltin"; - static final String SCRIPTFUNCTION_CREATEBUILTIN_DESC = - Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE); - static final String SCRIPTFUNCTION_CREATEBUILTIN_SPECS_DESC = - Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY); - static final String SCRIPTFUNCTION_INIT_DESC3 = - Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_SPECIALIZATION_ARRAY); - static final String SCRIPTFUNCTION_INIT_DESC4 = - Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_SPECIALIZATION_ARRAY); - - // ScriptObject - static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName(); - static final String SCRIPTOBJECT_DESC = TYPE_SCRIPTOBJECT.getDescriptor(); - static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP); - - static final String GETTER_PREFIX = "G$"; - static final String SETTER_PREFIX = "S$"; - - // ScriptObject.getClassName() method. - static final String GET_CLASS_NAME = "getClassName"; - static final String GET_CLASS_NAME_DESC = Type.getMethodDescriptor(TYPE_STRING); - - // NativeSymbol - static final String NATIVESYMBOL_TYPE = TYPE_NATIVESYMBOL.getInternalName(); - static final String SYMBOL_DESC = TYPE_SYMBOL.getDescriptor(); - static final String SYMBOL_PREFIX = "@@"; -} diff --git a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Where.java b/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Where.java deleted file mode 100644 index daaa2bc34a2..00000000000 --- a/make/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Where.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.tools.nasgen; - -/** - * Enum to tell where a Function or Property belongs. - * Note: keep this in sync. with jdk.nashorn.internal.objects.annotations.Where. - */ -public enum Where { - /** this means that the item belongs in the Constructor of an object */ - CONSTRUCTOR, - /** this means that the item belongs in the Prototype of an object */ - PROTOTYPE, - /** this means that the item belongs in the Instance of an object */ - INSTANCE -} diff --git a/make/nashorn/buildtools/nashorntask/README b/make/nashorn/buildtools/nashorntask/README deleted file mode 100644 index 569250190ef..00000000000 --- a/make/nashorn/buildtools/nashorntask/README +++ /dev/null @@ -1 +0,0 @@ -This project implements an ant task to run Nashorn scripts from ant projects. diff --git a/make/nashorn/buildtools/nashorntask/build.xml b/make/nashorn/buildtools/nashorntask/build.xml deleted file mode 100644 index cb2c8ce27d2..00000000000 --- a/make/nashorn/buildtools/nashorntask/build.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/buildtools/nashorntask/project.properties b/make/nashorn/buildtools/nashorntask/project.properties deleted file mode 100644 index 19e0b198aee..00000000000 --- a/make/nashorn/buildtools/nashorntask/project.properties +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -application.title=nashorntask - -# source and target levels -build.compiler=modern - -# This directory is removed when the project is cleaned: -nashorntask.build.dir=../../../../build/nashorn/nashorntask -nashorntask.build.classes.dir=${nashorntask.build.dir}/classes - -# This directory is removed when the project is cleaned: -nashorntask.dist.dir=${nashorntask.build.dir}/dist -nashorntask.dist.jar=${nashorntask.dist.dir}/nashorntask.jar -nashorntask.dist.javadoc.dir=${nashorntask.dist.dir}/javadoc - -javac.debug=true -src.dir=src diff --git a/make/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java b/make/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java deleted file mode 100644 index c417f731d1a..00000000000 --- a/make/nashorn/buildtools/nashorntask/src/jdk/nashorn/ant/NashornTask.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.ant; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.BuildException; - -/** - * This class implements an ant task to evaluate nashorn scripts - * from ant projects. - */ -public final class NashornTask extends Task { - // Underlying nashorn script engine - private final ScriptEngine engine; - // the current ant project - private Project project; - // the script evaluated by this task - private String script; - - public NashornTask() { - final ScriptEngineManager m = new ScriptEngineManager(); - this.engine = m.getEngineByName("nashorn"); - } - - @Override - public void setProject(Project proj) { - this.project = proj; - } - - // set the script to be evaluated - public void addText(String text) { - this.script = text; - } - - @Override - public void execute() { - // expose project as "project" variable - engine.put("project", project); - // expose this task as "self" variable - engine.put("self", this); - - // evaluate specified script - try { - engine.eval(script); - } catch (final ScriptException se) { - throw new BuildException(se); - } - } -} diff --git a/make/nashorn/code_coverage.xml b/make/nashorn/code_coverage.xml deleted file mode 100644 index 7fe1f3845a1..00000000000 --- a/make/nashorn/code_coverage.xml +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/element-list b/make/nashorn/element-list deleted file mode 100644 index db8915cd08e..00000000000 --- a/make/nashorn/element-list +++ /dev/null @@ -1,280 +0,0 @@ -module:java.base -java.io -java.lang -java.lang.annotation -java.lang.invoke -java.lang.module -java.lang.ref -java.lang.reflect -java.math -java.net -java.net.spi -java.nio -java.nio.channels -java.nio.channels.spi -java.nio.charset -java.nio.charset.spi -java.nio.file -java.nio.file.attribute -java.nio.file.spi -java.security -java.security.acl -java.security.cert -java.security.interfaces -java.security.spec -java.text -java.text.spi -java.time -java.time.chrono -java.time.format -java.time.temporal -java.time.zone -java.util -java.util.concurrent -java.util.concurrent.atomic -java.util.concurrent.locks -java.util.function -java.util.jar -java.util.regex -java.util.spi -java.util.stream -java.util.zip -javax.crypto -javax.crypto.interfaces -javax.crypto.spec -javax.net -javax.net.ssl -javax.security.auth -javax.security.auth.callback -javax.security.auth.login -javax.security.auth.spi -javax.security.auth.x500 -javax.security.cert -module:java.compiler -javax.annotation.processing -javax.lang.model -javax.lang.model.element -javax.lang.model.type -javax.lang.model.util -javax.tools -module:java.datatransfer -java.awt.datatransfer -module:java.desktop -java.applet -java.awt -java.awt.color -java.awt.desktop -java.awt.dnd -java.awt.event -java.awt.font -java.awt.geom -java.awt.im -java.awt.im.spi -java.awt.image -java.awt.image.renderable -java.awt.print -java.beans -java.beans.beancontext -javax.accessibility -javax.imageio -javax.imageio.event -javax.imageio.metadata -javax.imageio.plugins.bmp -javax.imageio.plugins.jpeg -javax.imageio.plugins.tiff -javax.imageio.spi -javax.imageio.stream -javax.print -javax.print.attribute -javax.print.attribute.standard -javax.print.event -javax.sound.midi -javax.sound.midi.spi -javax.sound.sampled -javax.sound.sampled.spi -javax.swing -javax.swing.border -javax.swing.colorchooser -javax.swing.event -javax.swing.filechooser -javax.swing.plaf -javax.swing.plaf.basic -javax.swing.plaf.metal -javax.swing.plaf.multi -javax.swing.plaf.nimbus -javax.swing.plaf.synth -javax.swing.table -javax.swing.text -javax.swing.text.html -javax.swing.text.html.parser -javax.swing.text.rtf -javax.swing.tree -javax.swing.undo -module:java.instrument -java.lang.instrument -module:java.logging -java.util.logging -module:java.management -java.lang.management -javax.management -javax.management.loading -javax.management.modelmbean -javax.management.monitor -javax.management.openmbean -javax.management.relation -javax.management.remote -javax.management.timer -module:java.management.rmi -javax.management.remote.rmi -module:java.naming -javax.naming -javax.naming.directory -javax.naming.event -javax.naming.ldap -javax.naming.spi -module:java.net.http -java.net.http -module:java.prefs -java.util.prefs -module:java.rmi -java.rmi -java.rmi.activation -java.rmi.dgc -java.rmi.registry -java.rmi.server -javax.rmi.ssl -module:java.scripting -javax.script -module:java.se -module:java.security.jgss -javax.security.auth.kerberos -org.ietf.jgss -module:java.security.sasl -javax.security.sasl -module:java.smartcardio -javax.smartcardio -module:java.sql -java.sql -javax.sql -module:java.sql.rowset -javax.sql.rowset -javax.sql.rowset.serial -javax.sql.rowset.spi -module:java.transaction.xa -javax.transaction.xa -module:java.xml -javax.xml -javax.xml.catalog -javax.xml.datatype -javax.xml.namespace -javax.xml.parsers -javax.xml.stream -javax.xml.stream.events -javax.xml.stream.util -javax.xml.transform -javax.xml.transform.dom -javax.xml.transform.sax -javax.xml.transform.stax -javax.xml.transform.stream -javax.xml.validation -javax.xml.xpath -org.w3c.dom -org.w3c.dom.bootstrap -org.w3c.dom.events -org.w3c.dom.ls -org.w3c.dom.ranges -org.w3c.dom.traversal -org.w3c.dom.views -org.xml.sax -org.xml.sax.ext -org.xml.sax.helpers -module:java.xml.crypto -javax.xml.crypto -javax.xml.crypto.dom -javax.xml.crypto.dsig -javax.xml.crypto.dsig.dom -javax.xml.crypto.dsig.keyinfo -javax.xml.crypto.dsig.spec -module:jdk.accessibility -com.sun.java.accessibility.util -module:jdk.attach -com.sun.tools.attach -com.sun.tools.attach.spi -module:jdk.charsets -module:jdk.compiler -com.sun.source.doctree -com.sun.source.tree -com.sun.source.util -com.sun.tools.javac -module:jdk.crypto.cryptoki -module:jdk.crypto.ec -module:jdk.dynalink -jdk.dynalink -jdk.dynalink.beans -jdk.dynalink.linker -jdk.dynalink.linker.support -jdk.dynalink.support -module:jdk.editpad -module:jdk.hotspot.agent -module:jdk.httpserver -com.sun.net.httpserver -com.sun.net.httpserver.spi -module:jdk.jartool -com.sun.jarsigner -jdk.security.jarsigner -module:jdk.javadoc -com.sun.javadoc -com.sun.tools.javadoc -jdk.javadoc.doclet -module:jdk.jcmd -module:jdk.jconsole -com.sun.tools.jconsole -module:jdk.jdeps -module:jdk.jdi -com.sun.jdi -com.sun.jdi.connect -com.sun.jdi.connect.spi -com.sun.jdi.event -com.sun.jdi.request -module:jdk.jdwp.agent -module:jdk.jfr -jdk.jfr -jdk.jfr.consumer -module:jdk.jlink -module:jdk.jshell -jdk.jshell -jdk.jshell.execution -jdk.jshell.spi -jdk.jshell.tool -module:jdk.jsobject -netscape.javascript -module:jdk.jstatd -module:jdk.localedata -module:jdk.management -com.sun.management -module:jdk.management.agent -module:jdk.management.jfr -jdk.management.jfr -module:jdk.naming.dns -module:jdk.naming.rmi -module:jdk.net -jdk.net -jdk.nio -module:jdk.scripting.nashorn -jdk.nashorn.api.scripting -jdk.nashorn.api.tree -module:jdk.sctp -com.sun.nio.sctp -module:jdk.security.auth -com.sun.security.auth -com.sun.security.auth.callback -com.sun.security.auth.login -com.sun.security.auth.module -module:jdk.security.jgss -com.sun.security.jgss -module:jdk.xml.dom -org.w3c.dom.css -org.w3c.dom.html -org.w3c.dom.stylesheets -org.w3c.dom.xpath -module:jdk.zipfs diff --git a/make/nashorn/exclude/exclude_list.txt b/make/nashorn/exclude/exclude_list.txt deleted file mode 100644 index 89618933148..00000000000 --- a/make/nashorn/exclude/exclude_list.txt +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/make/nashorn/exclude/exclude_list_cc.txt b/make/nashorn/exclude/exclude_list_cc.txt deleted file mode 100644 index 79b6303eb16..00000000000 --- a/make/nashorn/exclude/exclude_list_cc.txt +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/make/nashorn/nbproject/ide-file-targets.xml b/make/nashorn/nbproject/ide-file-targets.xml deleted file mode 100644 index 00a06351cd3..00000000000 --- a/make/nashorn/nbproject/ide-file-targets.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - Must set property 'debug.class' - - - - - - - - - diff --git a/make/nashorn/nbproject/ide-targets.xml b/make/nashorn/nbproject/ide-targets.xml deleted file mode 100644 index 503f89a1887..00000000000 --- a/make/nashorn/nbproject/ide-targets.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/nbproject/jdk.xml b/make/nashorn/nbproject/jdk.xml deleted file mode 100644 index 2fabe8c9e3d..00000000000 --- a/make/nashorn/nbproject/jdk.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - Permits selection of a JDK to use when building and running project. - See: http://www.netbeans.org/issues/show_bug.cgi?id=64160 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - nbjdk.active=${nbjdk.active} nbjdk.home=${nbjdk.home} nbjdk.java=${nbjdk.java} nbjdk.javac=${nbjdk.javac} nbjdk.javadoc=${nbjdk.javadoc} nbjdk.bootclasspath=${nbjdk.bootclasspath} nbjdk.valid=${nbjdk.valid} have-jdk-1.4=${have-jdk-1.4} have-jdk-1.5=${have-jdk-1.5} - - - - - Warning: nbjdk.active=${nbjdk.active} or nbjdk.home=${nbjdk.home} is an invalid Java platform; ignoring and using ${jdkhome.presumed} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/nbproject/nbjdk.properties b/make/nashorn/nbproject/nbjdk.properties deleted file mode 100644 index 9e40c8d300a..00000000000 --- a/make/nashorn/nbproject/nbjdk.properties +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# -nbjdk.active=JDK_9 - diff --git a/make/nashorn/nbproject/nbjdk.xml b/make/nashorn/nbproject/nbjdk.xml deleted file mode 100644 index 102045e3ef1..00000000000 --- a/make/nashorn/nbproject/nbjdk.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/make/nashorn/nbproject/project.xml b/make/nashorn/nbproject/project.xml deleted file mode 100644 index d97a5ecacb0..00000000000 --- a/make/nashorn/nbproject/project.xml +++ /dev/null @@ -1,212 +0,0 @@ - - - - org.netbeans.modules.ant.freeform - - - nashorn - - - - nashorn - - - - - . - UTF-8 - - - - ../test/src - - - - ../buildtools/nasgen/src - - - - ../src/jdk.scripting.nashorn/share/classes - - - - ../src/jdk.scripting.nashorn.shell/share/classes - - - - java - ../test/src - UTF-8 - - - - java - ../buildtools/nasgen/src - UTF-8 - - - - java - ../src/jdk.scripting.nashorn/share/classes - UTF-8 - - - - java - ../src/jdk.scripting.nashorn.shell/share/classes - UTF-8 - - - - java - ../src/jdk.dynalink/share/classes - UTF-8 - - - - ../src/jdk.dynalink/share/classes - - - - - - jar - - - - clean - - - - javadoc - - - - test - - - - clean - jar - - - - run - - - - debug-nb - - - - test - - test.class - ../test/src - \.java$ - relative-path-noext - - - - - - - - debug-selected-file-in-src - - test.class - ../test/src - \.java$ - relative-path-noext - - - - - - - - - - - ../test/src - - - - ../buildtools/nasgen/src - - - - ../src/jdk.scripting.nashorn/share/classes - - - - ../src/jdk.scripting.nashorn.shell/share/classes - - - - ../src/jdk.dynalink/share/classes - - - build.xml - - - - - - - - - - - - - - - - - ../test/src - - ../test/lib/testng.jar:../build/classes:../src/jdk.scripting.nashorn/share/classes - 1.8 - - - ../buildtools/nasgen/src - ../build/classes:../src - 1.8 - - - ../src/jdk.scripting.nashorn/share/classes - 1.8 - - - ../src/jdk.scripting.nashorn.shell/share/classes - 1.8 - - - ../src/jdk.dynalink/share/classes - 1.8 - - - - diff --git a/make/nashorn/project.properties b/make/nashorn/project.properties deleted file mode 100644 index 3078351b514..00000000000 --- a/make/nashorn/project.properties +++ /dev/null @@ -1,492 +0,0 @@ -# -# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -application.title=nashorn - -# location of JDK embedded ASM sources -jdk.java.base.dir=src/java.base/share/classes -jdk.asm.src.dir=${jdk.java.base.dir}/jdk/internal/org/objectweb/asm - -# location of JDK embedded jline sources -jdk.jline.src.dir=src/jdk.internal.le/share/classes - -# source and target levels -build.compiler=modern - -jdk.build.dir=build -nashorn.make.dir=make/nashorn - -javadoc.base.url=https://docs.oracle.com/en/java/javase/11/docs/api/ -javadoc.element.list=make/nashorn - -javadoc.option=\ - -tag "implSpec:a:Implementation Requirements:" \ - -tag "implNote:a:Implementation Note:" \ - -tag "moduleGraph:a:Module Graph" - -# nashorn version information -nashorn.version=0.1 -nashorn.fullversion=0.1 -nashorn.product.name=Oracle Nashorn - -# This directory is removed when the project is cleaned: -build.dir=${jdk.build.dir}/nashorn -build.classes.dir=${build.dir}/classes -build.zip=${build.dir}/nashorn.zip -build.gzip=${build.dir}/nashorn.tar.gz - -nashorn.override.option=\ - --patch-module jdk.scripting.nashorn=${build.classes.dir}/jdk.scripting.nashorn \ - --patch-module jdk.scripting.nashorn.shell=${build.classes.dir}/jdk.scripting.nashorn.shell \ - --patch-module jdk.dynalink=${build.classes.dir}/jdk.dynalink - -# project directory of ant task -nashorntask.dir=${nashorn.make.dir}/buildtools/nashorntask -nashorntask.dist.dir=${build.dir}/nashorntask/dist - -# nashorn Shell tool -nashorn.shell.tool=jdk.nashorn.tools.Shell - -# nasgen tool -nasgen.tool=jdk.nashorn.internal.tools.nasgen.Main - -nasgen.module.imports=\ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.util=ALL-UNNAMED - -# parallel test runner tool -parallel.test.runner=jdk.nashorn.internal.test.framework.ParallelTestRunner - -# test classes directory -build.test.classes.dir=${build.dir}/test/classes - -# nashorn test jar - internal tests jar and api tests jar -nashorn.internal.tests.jar=${build.dir}/nashorn-internal-tests.jar -nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar - -# test results directory -build.test.results.dir=${build.dir}/test/reports -build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports -build.nooptimistic.test.results.dir=${build.dir}/test/nooptimistic/reports - -# This directory is removed when the project is cleaned: -dist.dir=build/nashorn/dist -dynalink.jar=${dist.dir}/dynalink.jar -nashorn.jar=${dist.dir}/nashorn.jar -jjs.jar=${dist.dir}/jjs.jar -dist.javadoc.dir=${dist.dir}/javadoc -dist.nashornapi.javadoc.dir=${dist.javadoc.dir}/nashornapi -dist.dynalinkapi.javadoc.dir=${dist.javadoc.dir}/dynalinkapi - -# configuration for flight recorder -run.test.jvmargs.jfr=XX:StartFlightRecording=disk=true,dumponexit=true,dumponexitpath=${build.dir},stackdepth=128 - -# test library location -test.lib=test/nashorn/lib - -# jars refererred -file.reference.testng.jar=${test.lib}${file.separator}testng-6.8.jar -file.reference.jcommander.jar=${test.lib}${file.separator}jcommander-1.27.jar -file.reference.bsh.jar=${test.lib}${file.separator}bsh-2.0b4.jar -file.reference.snakeyaml.jar=${test.lib}${file.separator}snakeyaml-1.6.jar -file.reference.asmtools.jar=${test.lib}${file.separator}asmtools-60.jar - -# TestNG ant task classpath -testng.ant.classpath=\ - ${file.reference.testng.jar}${path.separator}\ - ${file.reference.jcommander.jar}${path.separator}\ - ${file.reference.bsh.jar}${path.separator}\ - ${file.reference.snakeyaml.jar}${path.separator} - -# Set testng verbose level -# From TestNG docs: "the verbosity level (0 to 10 where 10 is most detailed) -# Actually, this is a lie: you can specify -1 and this will put TestNG in -# debug mode (no longer slicing off stack traces and all)." - -testng.verbose=2 - -# TestNG listeners - we want to replace TestNG's own JUnit -# reporter, but want everything else provided by default -# Unfortunately, we've to clone the other default reporters here. - -testng.listeners=\ - org.testng.reporters.SuiteHTMLReporter, \ - org.testng.reporters.TestHTMLReporter, \ - org.testng.reporters.jq.Main, \ - org.testng.reporters.FailedReporter, \ - org.testng.reporters.XMLReporter \ - org.testng.reporters.EmailableReporter, \ - jdk.nashorn.internal.test.framework.JSJUnitReportReporter - -javac.debug=true -javac.encoding=ascii -javac.test.classpath=\ - ${build.test.classes.dir}${path.separator}\ - ${file.reference.testng.jar}${path.separator}\ - ${file.reference.jcommander.jar}${path.separator}\ - ${file.reference.bsh.jar}${path.separator}\ - ${file.reference.snakeyaml.jar} - -test.module.imports.compile.time=\ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.ir=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.codegen=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.parser=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.objects=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.linker=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.events=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.options=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.internal.runtime.regexp.joni=ALL-UNNAMED \ - --add-exports jdk.scripting.nashorn/jdk.nashorn.tools=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED - -test.module.imports.runtime=\ - ${test.module.imports.compile.time} \ - --add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime=ALL-UNNAMED \ - --add-opens jdk.scripting.nashorn/jdk.nashorn.internal.runtime.doubleconv=ALL-UNNAMED - -meta.inf.dir=${nashorn.module.src.dir}/META-INF - -run.classpath=\ - ${build.classes.dir} - -# test scripts to run -test.dir=test/nashorn -test.nosecurity.dir=${test.dir}/script/nosecurity -test.script.dir=${test.dir}/script -test.basic.dir=${test.script.dir}/basic -test.maptests.dir=${test.script.dir}/maptests -test.error.dir=${test.script.dir}/error -test.sandbox.dir=${test.script.dir}/sandbox -test.trusted.dir=${test.script.dir}/trusted -test.external.dir=${test.script.dir}/external -test262.dir=${test.external.dir}/test262 -test262.suite.dir=${test262.dir}/test/suite -testjfx.dir=${test.script.dir}/jfx -testmarkdown.dir=${test.script.dir}/markdown - -test-sys-prop.test.dir=${test.dir} -test-sys-prop.test.js.roots=${test.basic.dir} ${test.maptests.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir} -test-sys-prop.test262.suite.dir=${test262.suite.dir} -test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases -test-sys-prop.test.basic.dir=${test.basic.dir} -test-sys-prop.test.external.dir=${test.external.dir} -test-sys-prop.test.maptests.dir=${test.maptests.dir} -test-sys-prop.test.sandbox.dir=${test.sandbox.dir} -test-sys-prop.test.trusted.dir=${test.trusted.dir} - -test-sys-prop-no-security.test.dir=${test.dir} -test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir} - -# framework root for our script tests -test-sys-prop.test.js.framework=${test.script.dir}/assert.js -test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js - -# Control the verbosity of ParserTest -test-sys-prop.parsertest.verbose=false - -# turn on/off scripting mode for parser tests -test-sys-prop.parsertest.scripting=true -test-sys-prop.parserapitest.verbose=false - -# turn on/off test262 scripts for parser tests -test-sys-prop.parsertest.test262=false -test-sys-prop.parserapitest.test262=false - -# Control the verbosity of the CompilerTest -test-sys-prop.compilertest.verbose=false - -# turn on/off scripting mode for compiler tests -test-sys-prop.compilertest.scripting=true - -# turn on/off test262 scripts for compiler tests -test-sys-prop.compilertest.test262=false - -# test directory to be excluded. -test-sys-prop.test.js.exclude.dir=${test.script.dir}/currently-failing ${test.external.dir} - -# run everything that's js in here, without checking file headers for test annotations -test-sys-prop.test.js.unchecked.dir=${test262.dir} - -# test root for octane -octane-test-sys-prop.test.js.roots=${test.external.dir}/octane/ - -# run octane benchmars in separate processes? (recommended) -octane-test-sys-prop.separate.process=true - -# framework root for octane -octane-test-sys-prop.test.js.framework=${test.basic.dir}/run-octane.js - -# test root for sunspider -sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/tests/sunspider-1.0.2/ - -# framework root for sunspider -sunspider-test-sys-prop.test.js.framework=${test.basic.dir}/runsunspider.js - -# list of tests to be excluded -sunspider-test-sys-prop.test.js.exclude.list= - -# execute our script tests in shared nashorn context or not? -test-sys-prop.test.js.shared.context=false - -# execute test262 tests in shared nashorn context or not? -test262-test-sys-prop.test.js.shared.context=true - -# test262 test root -test262-test-sys-prop.test.js.roots=${test262.suite.dir} - -# test262 enable/disable strict mode tests -test262-test-sys-prop.test.js.enable.strict.mode=true - -# file containing test262 tests to be excluded -# test262-test-sys-prop.test.js.excludes.file=${test262.dir}/test/config/excludelist.xml - -# list of test262 files to be excluded -test262-test-sys-prop.test.js.exclude.list=\ - ${test262.suite.dir}/ch07/7.4/S7.4_A6.js \ - ${test262.suite.dir}/ch07/7.8/7.8.5/S7.8.5_A1.4_T2.js \ - ${test262.suite.dir}/ch15/15.2/15.2.3/15.2.3.6/15.2.3.6-4-170.js - -# list of test262 test dirs to be excluded -test262-test-sys-prop.test.js.exclude.dir=\ - ${test262.suite.dir}/intl402/ \ - ${test262.suite.dir}/bestPractice/ - -test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests - -# test262 test frameworks -test262-test-sys-prop.test.js.framework=\ - --class-cache-size=10 \ - --no-java \ - --no-typed-arrays \ - -timezone=PST \ - ${test.script.dir}/test262.js \ - ${test262.dir}/test/harness/framework.js \ - ${test262.dir}/test/harness/sta.js - -# testmarkdown test root -testmarkdown-test-sys-prop.test.js.roots=${testmarkdown.dir} - -# execute testmarkdown tests in shared nashorn context or not? -testmarkdown-test-sys-prop.test.js.shared.context=false - -# framework root for markdown script tests -testmarkdown-test-sys-prop.test.js.framework=\ - ${test.script.dir}${file.separator}markdown.js - -# testjfx test root -testjfx-test-sys-prop.test.js.roots=${testjfx.dir} - -# execute testjfx tests in shared nashorn context or not? -testjfx-test-sys-prop.test.js.shared.context=false - -# framework root for our script tests -testjfx-test-sys-prop.test.js.framework=\ - -fx \ - ${test.script.dir}${file.separator}jfx.js - -file.reference.jemmyfx.jar=${test.lib}${file.separator}JemmyFX.jar -file.reference.jemmycore.jar=${test.lib}${file.separator}JemmyCore.jar -file.reference.jemmyawtinput.jar=${test.lib}${file.separator}JemmyAWTInput.jar -file.reference.jfxrt.jar=${java.home}${file.separator}lib${file.separator}ext${file.separator}jfxrt.jar -testjfx.run.test.classpath=\ - ${file.reference.jemmyfx.jar}${path.separator}\ - ${file.reference.jemmycore.jar}${path.separator}\ - ${file.reference.jemmyawtinput.jar}${path.separator}\ - ${file.reference.testng.jar}${path.separator}\ - ${file.reference.jcommander.jar}${path.separator}\ - ${file.reference.bsh.jar}${path.separator}\ - ${file.reference.snakeyaml.jar}${path.separator}\ - ${nashorn.internal.tests.jar}${path.separator}\ - ${nashorn.api.tests.jar} - -# testjfx VM options for script tests with @fork option -testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath} - -run.test.classpath=\ - ${file.reference.testng.jar}${path.separator}\ - ${file.reference.jcommander.jar}${path.separator}\ - ${file.reference.bsh.jar}${path.separator}\ - ${file.reference.snakeyaml.jar}${path.separator}\ - ${nashorn.internal.tests.jar}${path.separator}\ - ${nashorn.api.tests.jar} - -dynalink.module.src.dir=src/jdk.dynalink/share/classes -dynalink.module.classes.dir=${build.classes.dir}/jdk.dynalink -nashorn.module.src.dir=src/jdk.scripting.nashorn/share/classes -nashorn.module.classes.dir=${build.classes.dir}/jdk.scripting.nashorn -nashorn.shell.module.src.dir=src/jdk.scripting.nashorn.shell/share/classes -nashorn.shell.module.classes.dir=${build.classes.dir}/jdk.scripting.nashorn.shell - -src.dir=${dynalink.module.src.dir}${path.separator}\ - ${nashorn.module.src.dir}${path.separator}\ - ${nashorn.shell.module.src.dir}${path.separator}\ - ${jdk.jline.src.dir} - -test.src.dir=test/nashorn/src - -# -Xmx is used for all tests, -Xms only for octane benchmark -run.test.xmx=2G -run.test.xms=2G - -# uncomment this jfr.args to enable flight recordings. the stack needs to be cranked up to 1024 frames, -# or everything will as of the now drown in lambda forms and be cut off. -# -#jfr.args=-XX:StartFlightRecording=disk=true,dumponexit=true,dumponexitpath="test_suite.jfr",stackdepth=1024 - -jfr.args= - -run.test.user.language=tr -run.test.user.country=TR - -run.test.jvmargs.common=\ - -server \ - ${test.module.imports.runtime} \ - ${run.test.jvmargs.external} \ - --add-modules jdk.scripting.nashorn.shell \ - ${nashorn.override.option} \ - -Dfile.encoding=UTF-8 \ - -Duser.language=${run.test.user.language} \ - -Duser.country=${run.test.user.country} \ - -Dnashorn.typeInfo.cacheDir=${build.dir}${file.separator}test${file.separator}type_info_cache \ - -Dnashorn.args.prepend=--no-deprecation-warning \ - ${jfr.args} \ - -XX:+HeapDumpOnOutOfMemoryError - -# turn on assertions for tests -run.test.jvmargs.main=${run.test.jvmargs.common} -esa -ea - -# Extra jvmargs that might be useful for debugging -# and performance improvements/monitoring -# -# -XX:+UnlockDiagnosticVMOptions -# -# turn off compressed class pointers in metaspace -# -XX:-UseCompressedKlassPointers -# -# dump the heap after every GC -# -XX:+PrintHeapAtGC -# -# manually set a metaspace size for class data -# -XX:ClassMetaspaceSize=300M -# -# print out methods compiled -# -XX:+PrintCompilation -# -# print all compiled nmethods with oopmaps and lots of other info -# -XX:+PrintNMethods -# -# activate the generic "UseNewCode" flag to test whatever functionality -# lies behind it. This is the preferred way to test a, yet flagless, -# feature in HotSpot - for example, the uncommon trap placement fix -# was hidden behind this flag before it became the default -# -# -XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode -# -# Crank up the type profile level to 222, which has some warmup -# penalties, but produces much better code for JavaScript, where better -# and more intrusive type profiling is required to get rid of -# a large amount of unnecessary guard code, that could not otherwise -# be eliminated -# -# -XX:TypeProfileLevel=222 -# - -# Use best known performance options for octane -run.test.jvmargs.octane.main=${run.test.jvmargs.common} -XX:TypeProfileLevel=222 - -# Security manager args - make sure that we run with the nashorn.policy that the build creates -run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${build.dir}/nashorn.policy -Djava.security.properties=${build.dir}/nashorn.security.properties - -# VM options for script tests with @fork option -test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath} -# VM options for no-security script tests with @fork option - same as above but without jvmsecurityargs -test-sys-prop-no-security.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${run.test.classpath} - -# path of rhino.jar for benchmarks -rhino.dir= -rhino.jar=${rhino.dir}/js.jar - -v8.shell=d8 - -# How many iterations should 'ant octane' run for each -# benchmark -octane.iterations=25 - -# List of octane tests to run, as properties prefixed with -# "octane.benchmark." mapping to the benchmark name in -# the test harness -# -# Octane tests that are disabled should have their entire line -# commented out Tests may be disabled for functionality reasons when -# they have bugs or when the runtime doesn't handle them (yet) -octane.benchmark.box2d=box2d -#octane.benchmark.code-load=code-load -octane.benchmark.crypto=crypto -octane.benchmark.deltablue=deltablue -octane.benchmark.earley-boyer=earley-boyer -octane.benchmark.gbemu=gbemu -octane.benchmark.navier-stokes=navier-stokes -octane.benchmark.mandreel=mandreel -octane.benchmark.pdfjs=pdfjs -octane.benchmark.raytrace=raytrace -octane.benchmark.regexp=regexp -octane.benchmark.richards=richards -octane.benchmark.splay=splay -#octane.benchmark.typescript=typescript -#octane.benchmark.zlib=zlib - -#path to rhino jar file -octaneperf-sys-prop.rhino.jar=${rhino.jar} - -#timeout for performance tests in minutes -octaneperf-sys-prop.timeout.value=10 - -#how many iterations to run sunspider after warmup -sunspider.iterations=3000 - -################# -# code coverage # -################# - -#enable/disable code coverage; please redifine in the ${user.home}/.nashorn.project.local.properties -make.code.coverage=false - -#type of codecoverage; one of static or dynamic. Now only dynamic is supported -jcov=dynamic - -#naming of CC results -#NB directory specified in the cc.dir will be cleaned up!!! -cc.dir=${build.dir}/Codecoverage_Nashorn -cc.result.file.name=CC_${jcov}_nashorn.xml - -#dynamic CC parameters; please redefine in the ${user.home}/.nashorn.project.local.properties -jcov2.lib.dir=${build.dir}/jcov2/lib -jcov.jar=${jcov2.lib.dir}/jcov.jar -cc.include=jdk\.nashorn\.* -cc.exclude=jdk\.nashorn\.internal\.scripts\.* -cc.dynamic.genereate.template=true -cc.template=${cc.dir}/CC_template.xml -cc.dynamic.args=-javaagent:${jcov.jar}=include=${cc.include},exclude=${cc.exclude},type=all,verbose=0,file=${cc.dir}/${cc.result.file.name} diff --git a/make/scripts/pandoc-html-manpage-filter.sh.template b/make/scripts/pandoc-html-manpage-filter.sh.template index 8e04ba79055..9f906eaa389 100644 --- a/make/scripts/pandoc-html-manpage-filter.sh.template +++ b/make/scripts/pandoc-html-manpage-filter.sh.template @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,5 +24,5 @@ # Simple wrapper script to call Nashorn with the javascript pandoc filter -@@BOOT_JDK@@/bin/jjs @@JJS_FLAGS@@ -scripting \ +@@JJS@@ -scripting \ "@@TOPDIR@@/make/scripts/pandoc-html-manpage-filter.js" 2> /dev/null diff --git a/make/scripts/pandoc-troff-manpage-filter.sh.template b/make/scripts/pandoc-troff-manpage-filter.sh.template index 5985bda2129..c4f9999ed6c 100644 --- a/make/scripts/pandoc-troff-manpage-filter.sh.template +++ b/make/scripts/pandoc-troff-manpage-filter.sh.template @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -24,5 +24,5 @@ # Simple wrapper script to call Nashorn with the javascript pandoc filter -@@BOOT_JDK@@/bin/jjs @@JJS_FLAGS@@ -scripting \ +@@JJS@@ -scripting \ "@@TOPDIR@@/make/scripts/pandoc-troff-manpage-filter.js" 2> /dev/null diff --git a/make/test/BuildFailureHandler.gmk b/make/test/BuildFailureHandler.gmk index 40dcd4116ca..3af3c5b5d17 100644 --- a/make/test/BuildFailureHandler.gmk +++ b/make/test/BuildFailureHandler.gmk @@ -52,7 +52,7 @@ $(eval $(call SetupJavaCompilation, BUILD_FAILURE_HANDLER, \ SETUP := GENERATE_OLDBYTECODE, \ SRC := $(FH_BASEDIR)/src/share/classes $(FH_BASEDIR)/src/share/conf, \ BIN := $(FH_SUPPORT)/classes, \ - DISABLED_WARNINGS := deprecation serial try, \ + DISABLED_WARNINGS := serial try, \ COPY := .properties, \ CLASSPATH := $(JTREG_JAR) $(TOOLS_JAR), \ JAR := $(FH_JAR), \ diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 641819a4b52..08339d00ef3 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -77,7 +77,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ SETUP := GENERATE_OLDBYTECODE, \ SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ INCLUDE_FILES := indify/Indify.java, \ - DISABLED_WARNINGS := rawtypes unchecked serial deprecation, \ + DISABLED_WARNINGS := rawtypes serial, \ BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ )) @@ -99,7 +99,7 @@ $(eval $(call SetupJavaCompiler, MICROBENCHMARK_JAVA_COMPILER, \ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ SETUP := MICROBENCHMARK_JAVA_COMPILER, \ ADD_JAVAC_FLAGS := -cp $(MICROBENCHMARK_CLASSPATH), \ - DISABLED_WARNINGS := processing rawtypes cast serial deprecation, \ + DISABLED_WARNINGS := processing rawtypes cast serial, \ SRC := $(MICROBENCHMARK_SRC), \ BIN := $(MICROBENCHMARK_CLASSES), \ )) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index cb5402a7c99..9fe6053f3a0 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -1097,9 +1097,9 @@ source %{ _NO_SPECIAL_PTR_REG_mask = _ALL_REG_mask; _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_NON_ALLOCATABLE_REG_mask); - // r27 is not allocatable when compressed oops is on, compressed klass - // pointers doesn't use r27 after JDK-8234794 - if (UseCompressedOops) { + // r27 is not allocatable when compressed oops is on and heapbase is not + // zero, compressed klass pointers doesn't use r27 after JDK-8234794 + if (UseCompressedOops && CompressedOops::ptrs_base() != NULL) { _NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg())); _NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); _NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask); @@ -2170,15 +2170,6 @@ const uint Matcher::vector_ideal_reg(int len) { return 0; } -const uint Matcher::vector_shift_count_ideal_reg(int size) { - switch(size) { - case 8: return Op_VecD; - case 16: return Op_VecX; - } - ShouldNotReachHere(); - return 0; -} - // AES support not yet implemented const bool Matcher::pass_original_key_for_aes() { return false; @@ -2213,7 +2204,7 @@ const bool Matcher::need_masked_shift_count = false; // No support for generic vector operands. const bool Matcher::supports_generic_vector_operands = false; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ShouldNotReachHere(); // generic vector operands not supported return NULL; } @@ -7486,19 +7477,17 @@ instruct storeN(iRegN src, memory4 mem) ins_pipe(istore_reg_mem); %} -instruct storeImmN0(iRegIHeapbase heapbase, immN0 zero, memory4 mem) +instruct storeImmN0(immN0 zero, memory4 mem) %{ match(Set mem (StoreN mem zero)); - predicate(CompressedOops::base() == NULL && - CompressedKlassPointers::base() == NULL && - (!needs_releasing_store(n))); + predicate(!needs_releasing_store(n)); ins_cost(INSN_COST); - format %{ "strw rheapbase, $mem\t# compressed ptr (rheapbase==0)" %} + format %{ "strw zr, $mem\t# compressed ptr" %} - ins_encode(aarch64_enc_strw(heapbase, mem)); + ins_encode(aarch64_enc_strw0(mem)); - ins_pipe(istore_reg_mem); + ins_pipe(istore_mem); %} // Store Float @@ -8450,17 +8439,6 @@ instruct castII(iRegI dst) ins_pipe(pipe_class_empty); %} -instruct castLL(iRegL dst) -%{ - match(Set dst (CastLL dst)); - - size(0); - format %{ "# castLL of $dst" %} - ins_encode(/* empty encoding */); - ins_cost(0); - ins_pipe(pipe_class_empty); -%} - // ============================================================================ // Atomic operation instructions // @@ -16033,318 +16011,318 @@ instruct replicate2D(vecX dst, vRegD src) // ====================REDUCTION ARITHMETIC==================================== -instruct reduce_add2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp, iRegINoSp tmp2) +instruct reduce_add2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp, iRegINoSp tmp2) %{ - match(Set dst (AddReductionVI src1 src2)); + match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP tmp2); - format %{ "umov $tmp, $src2, S, 0\n\t" - "umov $tmp2, $src2, S, 1\n\t" - "addw $tmp, $src1, $tmp\n\t" + format %{ "umov $tmp, $vsrc, S, 0\n\t" + "umov $tmp2, $vsrc, S, 1\n\t" + "addw $tmp, $isrc, $tmp\n\t" "addw $dst, $tmp, $tmp2\t# add reduction2I" %} ins_encode %{ - __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); - __ umov($tmp2$$Register, as_FloatRegister($src2$$reg), __ S, 1); - __ addw($tmp$$Register, $src1$$Register, $tmp$$Register); + __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); + __ umov($tmp2$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); + __ addw($tmp$$Register, $isrc$$Register, $tmp$$Register); __ addw($dst$$Register, $tmp$$Register, $tmp2$$Register); %} ins_pipe(pipe_class_default); %} -instruct reduce_add4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) +instruct reduce_add4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) %{ - match(Set dst (AddReductionVI src1 src2)); + match(Set dst (AddReductionVI isrc vsrc)); ins_cost(INSN_COST); - effect(TEMP tmp, TEMP tmp2); - format %{ "addv $tmp, T4S, $src2\n\t" - "umov $tmp2, $tmp, S, 0\n\t" - "addw $dst, $tmp2, $src1\t# add reduction4I" + effect(TEMP vtmp, TEMP itmp); + format %{ "addv $vtmp, T4S, $vsrc\n\t" + "umov $itmp, $vtmp, S, 0\n\t" + "addw $dst, $itmp, $isrc\t# add reduction4I" %} ins_encode %{ - __ addv(as_FloatRegister($tmp$$reg), __ T4S, - as_FloatRegister($src2$$reg)); - __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); - __ addw($dst$$Register, $tmp2$$Register, $src1$$Register); + __ addv(as_FloatRegister($vtmp$$reg), __ T4S, + as_FloatRegister($vsrc$$reg)); + __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); + __ addw($dst$$Register, $itmp$$Register, $isrc$$Register); %} ins_pipe(pipe_class_default); %} -instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I src1, vecD src2, iRegINoSp tmp) +instruct reduce_mul2I(iRegINoSp dst, iRegIorL2I isrc, vecD vsrc, iRegINoSp tmp) %{ - match(Set dst (MulReductionVI src1 src2)); + match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "umov $tmp, $src2, S, 0\n\t" - "mul $dst, $tmp, $src1\n\t" - "umov $tmp, $src2, S, 1\n\t" + format %{ "umov $tmp, $vsrc, S, 0\n\t" + "mul $dst, $tmp, $isrc\n\t" + "umov $tmp, $vsrc, S, 1\n\t" "mul $dst, $tmp, $dst\t# mul reduction2I" %} ins_encode %{ - __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 0); - __ mul($dst$$Register, $tmp$$Register, $src1$$Register); - __ umov($tmp$$Register, as_FloatRegister($src2$$reg), __ S, 1); + __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 0); + __ mul($dst$$Register, $tmp$$Register, $isrc$$Register); + __ umov($tmp$$Register, as_FloatRegister($vsrc$$reg), __ S, 1); __ mul($dst$$Register, $tmp$$Register, $dst$$Register); %} ins_pipe(pipe_class_default); %} -instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I src1, vecX src2, vecX tmp, iRegINoSp tmp2) +instruct reduce_mul4I(iRegINoSp dst, iRegIorL2I isrc, vecX vsrc, vecX vtmp, iRegINoSp itmp) %{ - match(Set dst (MulReductionVI src1 src2)); + match(Set dst (MulReductionVI isrc vsrc)); ins_cost(INSN_COST); - effect(TEMP tmp, TEMP tmp2, TEMP dst); - format %{ "ins $tmp, $src2, 0, 1\n\t" - "mul $tmp, $tmp, $src2\n\t" - "umov $tmp2, $tmp, S, 0\n\t" - "mul $dst, $tmp2, $src1\n\t" - "umov $tmp2, $tmp, S, 1\n\t" - "mul $dst, $tmp2, $dst\t# mul reduction4I" + effect(TEMP vtmp, TEMP itmp, TEMP dst); + format %{ "ins $vtmp, D, $vsrc, 0, 1\n\t" + "mulv $vtmp, T2S, $vtmp, $vsrc\n\t" + "umov $itmp, $vtmp, S, 0\n\t" + "mul $dst, $itmp, $isrc\n\t" + "umov $itmp, $vtmp, S, 1\n\t" + "mul $dst, $itmp, $dst\t# mul reduction4I" %} ins_encode %{ - __ ins(as_FloatRegister($tmp$$reg), __ D, - as_FloatRegister($src2$$reg), 0, 1); - __ mulv(as_FloatRegister($tmp$$reg), __ T2S, - as_FloatRegister($tmp$$reg), as_FloatRegister($src2$$reg)); - __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 0); - __ mul($dst$$Register, $tmp2$$Register, $src1$$Register); - __ umov($tmp2$$Register, as_FloatRegister($tmp$$reg), __ S, 1); - __ mul($dst$$Register, $tmp2$$Register, $dst$$Register); + __ ins(as_FloatRegister($vtmp$$reg), __ D, + as_FloatRegister($vsrc$$reg), 0, 1); + __ mulv(as_FloatRegister($vtmp$$reg), __ T2S, + as_FloatRegister($vtmp$$reg), as_FloatRegister($vsrc$$reg)); + __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 0); + __ mul($dst$$Register, $itmp$$Register, $isrc$$Register); + __ umov($itmp$$Register, as_FloatRegister($vtmp$$reg), __ S, 1); + __ mul($dst$$Register, $itmp$$Register, $dst$$Register); %} ins_pipe(pipe_class_default); %} -instruct reduce_add2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) +instruct reduce_add2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ - match(Set dst (AddReductionVF src1 src2)); + match(Set dst (AddReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "fadds $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fadds $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fadds $dst, $dst, $tmp\t# add reduction2F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_add4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) +instruct reduce_add4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) %{ - match(Set dst (AddReductionVF src1 src2)); + match(Set dst (AddReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "fadds $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fadds $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fadds $dst, $dst, $tmp\n\t" - "ins $tmp, S, $src2, 0, 2\n\t" + "ins $tmp, S, $vsrc, 0, 2\n\t" "fadds $dst, $dst, $tmp\n\t" - "ins $tmp, S, $src2, 0, 3\n\t" + "ins $tmp, S, $vsrc, 0, 3\n\t" "fadds $dst, $dst, $tmp\t# add reduction4F" %} ins_encode %{ __ fadds(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 2); + as_FloatRegister($vsrc$$reg), 0, 2); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 3); + as_FloatRegister($vsrc$$reg), 0, 3); __ fadds(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_mul2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) +instruct reduce_mul2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ - match(Set dst (MulReductionVF src1 src2)); + match(Set dst (MulReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "fmuls $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fmuls $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fmuls $dst, $dst, $tmp\t# mul reduction2F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_mul4F(vRegF dst, vRegF src1, vecX src2, vecX tmp) +instruct reduce_mul4F(vRegF dst, vRegF fsrc, vecX vsrc, vecX tmp) %{ - match(Set dst (MulReductionVF src1 src2)); + match(Set dst (MulReductionVF fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "fmuls $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fmuls $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fmuls $dst, $dst, $tmp\n\t" - "ins $tmp, S, $src2, 0, 2\n\t" + "ins $tmp, S, $vsrc, 0, 2\n\t" "fmuls $dst, $dst, $tmp\n\t" - "ins $tmp, S, $src2, 0, 3\n\t" + "ins $tmp, S, $vsrc, 0, 3\n\t" "fmuls $dst, $dst, $tmp\t# mul reduction4F" %} ins_encode %{ __ fmuls(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 2); + as_FloatRegister($vsrc$$reg), 0, 2); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ S, - as_FloatRegister($src2$$reg), 0, 3); + as_FloatRegister($vsrc$$reg), 0, 3); __ fmuls(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_add2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) +instruct reduce_add2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ - match(Set dst (AddReductionVD src1 src2)); + match(Set dst (AddReductionVD dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "faddd $dst, $src1, $src2\n\t" - "ins $tmp, D, $src2, 0, 1\n\t" + format %{ "faddd $dst, $dsrc, $vsrc\n\t" + "ins $tmp, D, $vsrc, 0, 1\n\t" "faddd $dst, $dst, $tmp\t# add reduction2D" %} ins_encode %{ __ faddd(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ faddd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_mul2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) +instruct reduce_mul2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ - match(Set dst (MulReductionVD src1 src2)); + match(Set dst (MulReductionVD dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP tmp, TEMP dst); - format %{ "fmuld $dst, $src1, $src2\n\t" - "ins $tmp, D, $src2, 0, 1\n\t" + format %{ "fmuld $dst, $dsrc, $vsrc\n\t" + "ins $tmp, D, $vsrc, 0, 1\n\t" "fmuld $dst, $dst, $tmp\t# mul reduction2D" %} ins_encode %{ __ fmuld(as_FloatRegister($dst$$reg), - as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); + as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); __ ins(as_FloatRegister($tmp$$reg), __ D, - as_FloatRegister($src2$$reg), 0, 1); + as_FloatRegister($vsrc$$reg), 0, 1); __ fmuld(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_max2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ +instruct reduce_max2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); - match(Set dst (MaxReductionV src1 src2)); + match(Set dst (MaxReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); - format %{ "fmaxs $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fmaxs $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fmaxs $dst, $dst, $tmp\t# max reduction2F" %} ins_encode %{ - __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); - __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); + __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); + __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_max4F(vRegF dst, vRegF src1, vecX src2) %{ +instruct reduce_max4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); - match(Set dst (MaxReductionV src1 src2)); + match(Set dst (MaxReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); - format %{ "fmaxv $dst, T4S, $src2\n\t" - "fmaxs $dst, $dst, $src1\t# max reduction4F" %} + format %{ "fmaxv $dst, T4S, $vsrc\n\t" + "fmaxs $dst, $dst, $fsrc\t# max reduction4F" %} ins_encode %{ - __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); - __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); + __ fmaxv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); + __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_max2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ +instruct reduce_max2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); - match(Set dst (MaxReductionV src1 src2)); + match(Set dst (MaxReductionV dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); - format %{ "fmaxd $dst, $src1, $src2\n\t" - "ins $tmp, D, $src2, 0, 1\n\t" + format %{ "fmaxd $dst, $dsrc, $vsrc\n\t" + "ins $tmp, D, $vsrc, 0, 1\n\t" "fmaxd $dst, $dst, $tmp\t# max reduction2D" %} ins_encode %{ - __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); - __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); + __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); + __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_min2F(vRegF dst, vRegF src1, vecD src2, vecD tmp) %{ +instruct reduce_min2F(vRegF dst, vRegF fsrc, vecD vsrc, vecD tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); - match(Set dst (MinReductionV src1 src2)); + match(Set dst (MinReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); - format %{ "fmins $dst, $src1, $src2\n\t" - "ins $tmp, S, $src2, 0, 1\n\t" + format %{ "fmins $dst, $fsrc, $vsrc\n\t" + "ins $tmp, S, $vsrc, 0, 1\n\t" "fmins $dst, $dst, $tmp\t# min reduction2F" %} ins_encode %{ - __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); - __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($src2$$reg), 0, 1); + __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg), as_FloatRegister($vsrc$$reg)); + __ ins(as_FloatRegister($tmp$$reg), __ S, as_FloatRegister($vsrc$$reg), 0, 1); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_min4F(vRegF dst, vRegF src1, vecX src2) %{ +instruct reduce_min4F(vRegF dst, vRegF fsrc, vecX vsrc) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); - match(Set dst (MinReductionV src1 src2)); + match(Set dst (MinReductionV fsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst); - format %{ "fminv $dst, T4S, $src2\n\t" - "fmins $dst, $dst, $src1\t# min reduction4F" %} + format %{ "fminv $dst, T4S, $vsrc\n\t" + "fmins $dst, $dst, $fsrc\t# min reduction4F" %} ins_encode %{ - __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src2$$reg)); - __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); + __ fminv(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($vsrc$$reg)); + __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($fsrc$$reg)); %} ins_pipe(pipe_class_default); %} -instruct reduce_min2D(vRegD dst, vRegD src1, vecX src2, vecX tmp) %{ +instruct reduce_min2D(vRegD dst, vRegD dsrc, vecX vsrc, vecX tmp) %{ predicate(n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); - match(Set dst (MinReductionV src1 src2)); + match(Set dst (MinReductionV dsrc vsrc)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP tmp); - format %{ "fmind $dst, $src1, $src2\n\t" - "ins $tmp, D, $src2, 0, 1\n\t" + format %{ "fmind $dst, $dsrc, $vsrc\n\t" + "ins $tmp, D, $vsrc, 0, 1\n\t" "fmind $dst, $dst, $tmp\t# min reduction2D" %} ins_encode %{ - __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); - __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($src2$$reg), 0, 1); + __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dsrc$$reg), as_FloatRegister($vsrc$$reg)); + __ ins(as_FloatRegister($tmp$$reg), __ D, as_FloatRegister($vsrc$$reg), 0, 1); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_class_default); @@ -17589,7 +17567,7 @@ instruct vsll8S_imm(vecX dst, vecX src, immI shift) %{ instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ predicate(n->as_Vector()->length() == 2 || n->as_Vector()->length() == 4); - match(Set dst (RShiftVS src (LShiftCntV shift))); + match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (4H)" %} ins_encode %{ @@ -17603,7 +17581,7 @@ instruct vsra4S_imm(vecD dst, vecD src, immI shift) %{ instruct vsra8S_imm(vecX dst, vecX src, immI shift) %{ predicate(n->as_Vector()->length() == 8); - match(Set dst (RShiftVS src (LShiftCntV shift))); + match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(INSN_COST); format %{ "sshr $dst, $src, $shift\t# vector (8H)" %} ins_encode %{ diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 67d0f60124d..a50f86b7bd8 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -2185,6 +2185,10 @@ void MacroAssembler::verify_heapbase(const char* msg) { #if 0 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed"); assert (Universe::heap() != NULL, "java heap should be initialized"); + if (!UseCompressedOops || Universe::ptr_base() == NULL) { + // rheapbase is allocated as general register + return; + } if (CheckCompressedOops) { Label ok; push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1 diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 46fe027e031..8c2a1c00692 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -1017,10 +1017,6 @@ const uint Matcher::vector_ideal_reg(int size) { return 0; } -const uint Matcher::vector_shift_count_ideal_reg(int size) { - return vector_ideal_reg(size); -} - // Limits on vector size (number of elements) loaded into vector. const int Matcher::max_vector_size(const BasicType bt) { assert(is_java_primitive(bt), "only primitive type vectors"); @@ -1087,7 +1083,7 @@ const bool Matcher::convi2l_type_required = true; // No support for generic vector operands. const bool Matcher::supports_generic_vector_operands = false; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ShouldNotReachHere(); // generic vector operands not supported return NULL; } @@ -5316,14 +5312,6 @@ instruct castII( iRegI dst ) %{ ins_pipe(empty); %} -instruct castLL( iRegL dst ) %{ - match(Set dst (CastLL dst)); - format %{ "! castLL of $dst" %} - ins_encode( /*empty encoding*/ ); - ins_cost(0); - ins_pipe(empty); -%} - //----------Arithmetic Instructions-------------------------------------------- // Addition Instructions // Register Addition diff --git a/src/hotspot/cpu/arm/methodHandles_arm.cpp b/src/hotspot/cpu/arm/methodHandles_arm.cpp index 152ecde87c6..b69efa7bbcc 100644 --- a/src/hotspot/cpu/arm/methodHandles_arm.cpp +++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/methodHandles.hpp" @@ -540,7 +541,7 @@ void trace_method_handle_stub(const char* adaptername, } void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { - if (!TraceMethodHandles) return; + if (!log_is_enabled(Info, methodhandles)) return; BLOCK_COMMENT("trace_method_handle {"); // register saving // must correspond to trace_mh_nregs and trace_mh_regs defined above diff --git a/src/hotspot/cpu/ppc/assembler_ppc.hpp b/src/hotspot/cpu/ppc/assembler_ppc.hpp index a2fcea92f03..58780fcb09c 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020 SAP SE. 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 @@ -530,6 +530,8 @@ class Assembler : public AbstractAssembler { XXLXOR_OPCODE = (60u << OPCODE_SHIFT | 154u << 3), XXLEQV_OPCODE = (60u << OPCODE_SHIFT | 186u << 3), XVDIVSP_OPCODE = (60u << OPCODE_SHIFT | 88u << 3), + XXBRD_OPCODE = (60u << OPCODE_SHIFT | 475u << 2 | 23u << 16), // XX2-FORM + XXBRW_OPCODE = (60u << OPCODE_SHIFT | 475u << 2 | 15u << 16), // XX2-FORM XVDIVDP_OPCODE = (60u << OPCODE_SHIFT | 120u << 3), XVABSSP_OPCODE = (60u << OPCODE_SHIFT | 409u << 2), XVABSDP_OPCODE = (60u << OPCODE_SHIFT | 473u << 2), @@ -2227,11 +2229,15 @@ class Assembler : public AbstractAssembler { inline void xxmrghw( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void xxmrglw( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void mtvsrd( VectorSRegister d, Register a); + inline void mfvsrd( Register d, VectorSRegister a); inline void mtvsrwz( VectorSRegister d, Register a); + inline void mfvsrwz( Register d, VectorSRegister a); inline void xxspltw( VectorSRegister d, VectorSRegister b, int ui2); inline void xxlor( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void xxlxor( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void xxleqv( VectorSRegister d, VectorSRegister a, VectorSRegister b); + inline void xxbrd( VectorSRegister d, VectorSRegister b); + inline void xxbrw( VectorSRegister d, VectorSRegister b); inline void xvdivsp( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void xvdivdp( VectorSRegister d, VectorSRegister a, VectorSRegister b); inline void xvabssp( VectorSRegister d, VectorSRegister b); diff --git a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp index 7ff30043f14..b2cae41dd78 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020 SAP SE. 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 @@ -776,11 +776,15 @@ inline void Assembler::lxvd2x( VectorSRegister d, Register s1, Register s2) { e inline void Assembler::stxvd2x( VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrs(d) | ra(0) | rb(s1)); } inline void Assembler::stxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrs(d) | ra0mem(s1) | rb(s2)); } inline void Assembler::mtvsrd( VectorSRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d) | ra(a)); } +inline void Assembler::mfvsrd( Register d, VectorSRegister a) { emit_int32( MFVSRD_OPCODE | vsrs(a) | ra(d)); } inline void Assembler::mtvsrwz( VectorSRegister d, Register a) { emit_int32( MTVSRWZ_OPCODE | vsrt(d) | ra(a)); } +inline void Assembler::mfvsrwz( Register d, VectorSRegister a) { emit_int32( MFVSRWZ_OPCODE | vsrs(a) | ra(d)); } inline void Assembler::xxspltw( VectorSRegister d, VectorSRegister b, int ui2) { emit_int32( XXSPLTW_OPCODE | vsrt(d) | vsrb(b) | xxsplt_uim(uimm(ui2,2))); } inline void Assembler::xxlor( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLOR_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } inline void Assembler::xxlxor( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLXOR_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } inline void Assembler::xxleqv( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XXLEQV_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } +inline void Assembler::xxbrd( VectorSRegister d, VectorSRegister b) { emit_int32( XXBRD_OPCODE | vsrt(d) | vsrb(b) ); } +inline void Assembler::xxbrw( VectorSRegister d, VectorSRegister b) { emit_int32( XXBRW_OPCODE | vsrt(d) | vsrb(b) ); } inline void Assembler::xvdivsp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVDIVSP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } inline void Assembler::xvdivdp( VectorSRegister d, VectorSRegister a, VectorSRegister b) { emit_int32( XVDIVDP_OPCODE | vsrt(d) | vsra(a) | vsrb(b)); } inline void Assembler::xvabssp( VectorSRegister d, VectorSRegister b) { emit_int32( XVABSSP_OPCODE | vsrt(d) | vsrb(b)); } diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp index bd742116231..e9752737b10 100644 --- a/src/hotspot/cpu/ppc/globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/globals_ppc.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2012, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,6 +112,8 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong); "Use load instructions for stack banging.") \ \ /* special instructions */ \ + product(bool, UseVectorByteReverseInstructionsPPC64, false, \ + "Use Power9 xxbr* vector byte reverse instructions.") \ \ product(bool, UseCountLeadingZerosInstructionsPPC64, true, \ "Use count leading zeros instructions.") \ diff --git a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp index 8d17f318a41..b0fb1b73625 100644 --- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp +++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2017 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,7 @@ #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/methodHandles.hpp" @@ -264,7 +265,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* DEBUG_ONLY(param_size = noreg); } - if (TraceMethodHandles) { + if (log_is_enabled(Info, methodhandles)) { if (tmp_mh != noreg) { __ mr(R23_method_handle, tmp_mh); // make stub happy } @@ -545,7 +546,7 @@ void trace_method_handle_stub(const char* adaptername, } void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { - if (!TraceMethodHandles) return; + if (!log_is_enabled(Info, methodhandles)) return; BLOCK_COMMENT("trace_method_handle {"); diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 029a212247a..d4c33d45617 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -1,6 +1,6 @@ // // Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2012, 2019 SAP SE. All rights reserved. +// Copyright (c) 2012, 2020 SAP SE. 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 @@ -2366,11 +2366,6 @@ const uint Matcher::vector_ideal_reg(int size) { } } -const uint Matcher::vector_shift_count_ideal_reg(int size) { - fatal("vector shift is not supported"); - return Node::NotAMachineReg; -} - // Limits on vector size (number of elements) loaded into vector. const int Matcher::max_vector_size(const BasicType bt) { assert(is_java_primitive(bt), "only primitive type vectors"); @@ -2451,7 +2446,7 @@ const bool Matcher::need_masked_shift_count = true; // No support for generic vector operands. const bool Matcher::supports_generic_vector_operands = false; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ShouldNotReachHere(); // generic vector operands not supported return NULL; } @@ -10890,14 +10885,6 @@ instruct castII(iRegIdst dst) %{ ins_pipe(pipe_class_default); %} -instruct castLL(iRegLdst dst) %{ - match(Set dst (CastLL dst)); - format %{ " -- \t// castLL of $dst" %} - size(0); - ins_encode( /*empty*/ ); - ins_pipe(pipe_class_default); -%} - instruct checkCastPP(iRegPdst dst) %{ match(Set dst (CheckCastPP dst)); format %{ " -- \t// checkcastPP of $dst" %} @@ -13737,6 +13724,24 @@ instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{ %} %} +instruct bytes_reverse_int_vec(iRegIdst dst, iRegIsrc src, vecX tmpV) %{ + match(Set dst (ReverseBytesI src)); + predicate(UseVectorByteReverseInstructionsPPC64); + effect(TEMP tmpV); + ins_cost(DEFAULT_COST*3); + size(12); + format %{ "MTVSRWZ $tmpV, $src\n" + "\tXXBRW $tmpV, $tmpV\n" + "\tMFVSRWZ $dst, $tmpV" %} + + ins_encode %{ + __ mtvsrwz($tmpV$$VectorSRegister, $src$$Register); + __ xxbrw($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); + __ mfvsrwz($dst$$Register, $tmpV$$VectorSRegister); + %} + ins_pipe(pipe_class_default); +%} + instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ match(Set dst (ReverseBytesL src)); ins_cost(15*DEFAULT_COST); @@ -13776,6 +13781,24 @@ instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{ %} %} +instruct bytes_reverse_long_vec(iRegLdst dst, iRegLsrc src, vecX tmpV) %{ + match(Set dst (ReverseBytesL src)); + predicate(UseVectorByteReverseInstructionsPPC64); + effect(TEMP tmpV); + ins_cost(DEFAULT_COST*3); + size(12); + format %{ "MTVSRD $tmpV, $src\n" + "\tXXBRD $tmpV, $tmpV\n" + "\tMFVSRD $dst, $tmpV" %} + + ins_encode %{ + __ mtvsrd($tmpV$$VectorSRegister, $src$$Register); + __ xxbrd($tmpV$$VectorSRegister, $tmpV$$VectorSRegister); + __ mfvsrd($dst$$Register, $tmpV$$VectorSRegister); + %} + ins_pipe(pipe_class_default); +%} + instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{ match(Set dst (ReverseBytesUS src)); ins_cost(2*DEFAULT_COST); diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp index edacc03f35d..450e9c40509 100644 --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2019 SAP SE. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020 SAP SE. 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 @@ -141,6 +141,9 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(UseCharacterCompareIntrinsics)) { FLAG_SET_ERGO(UseCharacterCompareIntrinsics, true); } + if (FLAG_IS_DEFAULT(UseVectorByteReverseInstructionsPPC64)) { + FLAG_SET_ERGO(UseVectorByteReverseInstructionsPPC64, true); + } } else { if (UseCountTrailingZerosInstructionsPPC64) { warning("UseCountTrailingZerosInstructionsPPC64 specified, but needs at least Power9."); @@ -150,6 +153,10 @@ void VM_Version::initialize() { warning("UseCharacterCompareIntrinsics specified, but needs at least Power9."); FLAG_SET_DEFAULT(UseCharacterCompareIntrinsics, false); } + if (UseVectorByteReverseInstructionsPPC64) { + warning("UseVectorByteReverseInstructionsPPC64 specified, but needs at least Power9."); + FLAG_SET_DEFAULT(UseVectorByteReverseInstructionsPPC64, false); + } } #endif diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp index ca93ef3f136..d7625b56a2c 100644 --- a/src/hotspot/cpu/s390/methodHandles_s390.cpp +++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2017, SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,7 @@ #include "asm/macroAssembler.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/methodHandles.hpp" @@ -616,7 +617,7 @@ void trace_method_handle_stub(const char* adaptername, } void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { - if (!TraceMethodHandles) { return; } + if (!log_is_enabled(Info, methodhandles)) { return; } // If arg registers are contiguous, we can use STMG/LMG. assert((Z_ARG5->encoding() - Z_ARG1->encoding() + 1) == RegisterImpl::number_of_arg_registers, "Oops"); diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index a568b4e0523..68314d6c96e 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -1610,11 +1610,6 @@ const int Matcher::min_vector_size(const BasicType bt) { return max_vector_size(bt); // Same as max. } -const uint Matcher::vector_shift_count_ideal_reg(int size) { - fatal("vector shift is not supported"); - return Node::NotAMachineReg; -} - // z/Architecture does support misaligned store/load at minimal extra cost. const bool Matcher::misaligned_vectors_ok() { return true; @@ -1669,7 +1664,7 @@ const bool Matcher::need_masked_shift_count = false; // No support for generic vector operands. const bool Matcher::supports_generic_vector_operands = false; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ShouldNotReachHere(); // generic vector operands not supported return NULL; } @@ -5439,14 +5434,6 @@ instruct castII(iRegI dst) %{ ins_pipe(pipe_class_dummy); %} -instruct castLL(iRegL dst) %{ - match(Set dst (CastLL dst)); - size(0); - format %{ "# castLL of $dst" %} - ins_encode(/*empty*/); - ins_pipe(pipe_class_dummy); -%} - //----------Conditional_store-------------------------------------------------- // Conditional-store of the updated heap-top. diff --git a/src/hotspot/cpu/sparc/methodHandles_sparc.cpp b/src/hotspot/cpu/sparc/methodHandles_sparc.cpp index 5232313c3db..d13801665ef 100644 --- a/src/hotspot/cpu/sparc/methodHandles_sparc.cpp +++ b/src/hotspot/cpu/sparc/methodHandles_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interp_masm.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/methodHandles.hpp" @@ -274,7 +275,7 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* // O4_first_arg_addr is live! - if (TraceMethodHandles) { + if (log_is_enabled(Info, methodhandles)) { if (O0_mh != noreg) __ mov(O0_mh, G3_method_handle); // make stub happy trace_method_handle_interpreter_entry(_masm, iid); @@ -576,7 +577,7 @@ void trace_method_handle_stub(const char* adaptername, } void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { - if (!TraceMethodHandles) return; + if (!log_is_enabled(Info, methodhandles)) return; BLOCK_COMMENT("trace_method_handle {"); // save: Gargs, O5_savedSP __ save_frame(16); // need space for saving required FPU state diff --git a/src/hotspot/cpu/sparc/sparc.ad b/src/hotspot/cpu/sparc/sparc.ad index 24f505ca7f1..abb3d04b47f 100644 --- a/src/hotspot/cpu/sparc/sparc.ad +++ b/src/hotspot/cpu/sparc/sparc.ad @@ -1753,11 +1753,6 @@ const uint Matcher::vector_ideal_reg(int size) { return Op_RegD; } -const uint Matcher::vector_shift_count_ideal_reg(int size) { - fatal("vector shift is not supported"); - return Node::NotAMachineReg; -} - // Limits on vector size (number of elements) loaded into vector. const int Matcher::max_vector_size(const BasicType bt) { assert(is_java_primitive(bt), "only primitive type vectors"); @@ -1821,7 +1816,7 @@ const bool Matcher::need_masked_shift_count = false; // No support for generic vector operands. const bool Matcher::supports_generic_vector_operands = false; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* original_opnd, uint ideal_reg, bool is_temp) { ShouldNotReachHere(); // generic vector operands not supported return NULL; } @@ -6812,14 +6807,6 @@ instruct castII( iRegI dst ) %{ ins_pipe(empty); %} -instruct castLL( iRegL dst ) %{ - match(Set dst (CastLL dst)); - format %{ "# castLL of $dst" %} - ins_encode( /*empty encoding*/ ); - ins_cost(0); - ins_pipe(empty); -%} - //----------Arithmetic Instructions-------------------------------------------- // Addition Instructions // Register Addition diff --git a/src/hotspot/cpu/x86/methodHandles_x86.cpp b/src/hotspot/cpu/x86/methodHandles_x86.cpp index 464895026c0..fa3e087ed3c 100644 --- a/src/hotspot/cpu/x86/methodHandles_x86.cpp +++ b/src/hotspot/cpu/x86/methodHandles_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #include "classfile/javaClasses.inline.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "prims/methodHandles.hpp" @@ -594,7 +595,7 @@ void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) { } void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { - if (!TraceMethodHandles) return; + if (!log_is_enabled(Info, methodhandles)) return; BLOCK_COMMENT(err_msg("trace_method_handle %s {", adaptername)); __ enter(); __ andptr(rsp, -16); // align stack if needed for FPU state diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 7a1b2c48a59..ec8cab21de9 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1490,7 +1490,7 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType // x86 supports generic vector operands: vec and legVec. const bool Matcher::supports_generic_vector_operands = true; -MachOper* Matcher::specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { +MachOper* Matcher::pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp) { assert(Matcher::is_generic_vector(generic_opnd), "not generic"); bool legacy = (generic_opnd->opcode() == LEGVEC); if (!VM_Version::supports_avx512vlbwdq() && // KNL @@ -1630,11 +1630,6 @@ const uint Matcher::vector_ideal_reg(int size) { return 0; } -// Only lowest bits of xmm reg are used for vector shift count. -const uint Matcher::vector_shift_count_ideal_reg(int size) { - return Op_VecS; -} - // x86 supports misaligned vectors store/load. const bool Matcher::misaligned_vectors_ok() { return true; @@ -5344,7 +5339,7 @@ instruct vpopcountI(vec dst, vec src) %{ // --------------------------------- Bitwise Ternary Logic ---------------------------------- -instruct vpternlogdB(vec dst, vec src2, vec src3, immU8 func) %{ +instruct vpternlog(vec dst, vec src2, vec src3, immU8 func) %{ match(Set dst (MacroLogicV (Binary dst src2) (Binary src3 func))); effect(TEMP dst); format %{ "vpternlogd $dst,$src2,$src3,$func\t! vector ternary logic" %} @@ -5355,7 +5350,7 @@ instruct vpternlogdB(vec dst, vec src2, vec src3, immU8 func) %{ ins_pipe( pipe_slow ); %} -instruct vpternlogdB_mem(vec dst, vec src2, memory src3, immU8 func) %{ +instruct vpternlog_mem(vec dst, vec src2, memory src3, immU8 func) %{ match(Set dst (MacroLogicV (Binary dst src2) (Binary (LoadVector src3) func))); effect(TEMP dst); format %{ "vpternlogd $dst,$src2,$src3,$func\t! vector ternary logic" %} diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 59196f6811c..f9fd9a59071 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -7237,15 +7237,6 @@ instruct castII( rRegI dst ) %{ ins_pipe( empty ); %} -instruct castLL( eRegL dst ) %{ - match(Set dst (CastLL dst)); - format %{ "#castLL of $dst" %} - ins_encode( /*empty encoding*/ ); - ins_cost(0); - ins_pipe( empty ); -%} - - // Load-locked - same as a regular pointer load when used with compare-swap instruct loadPLocked(eRegP dst, memory mem) %{ match(Set dst (LoadPLocked mem)); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 3a3fdffd3b0..222d6c563c7 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -7504,17 +7504,6 @@ instruct castII(rRegI dst) ins_pipe(empty); %} -instruct castLL(rRegL dst) -%{ - match(Set dst (CastLL dst)); - - size(0); - format %{ "# castLL of $dst" %} - ins_encode(/* empty encoding */); - ins_cost(0); - ins_pipe(empty); -%} - // LoadP-locked same as a regular LoadP when used with compare-swap instruct loadPLocked(rRegP dst, memory mem) %{ diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 0f4356b3416..64e34170719 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -141,6 +141,13 @@ static bool check_signals = true; static int SR_signum = SIGUSR2; sigset_t SR_sigset; +#ifdef __APPLE__ +static const int processor_id_unassigned = -1; +static const int processor_id_assigning = -2; +static const int processor_id_map_size = 256; +static volatile int processor_id_map[processor_id_map_size]; +static volatile int processor_id_next = 0; +#endif //////////////////////////////////////////////////////////////////////////////// // utility functions @@ -250,6 +257,13 @@ void os::Bsd::initialize_system_info() { set_processor_count(1); // fallback } +#ifdef __APPLE__ + // initialize processor id map + for (int i = 0; i < processor_id_map_size; i++) { + processor_id_map[i] = processor_id_unassigned; + } +#endif + // get physical memory via hw.memsize sysctl (hw.memsize is used // since it returns a 64 bit value) mib[0] = CTL_HW; @@ -3196,69 +3210,32 @@ int os::active_processor_count() { } #ifdef __APPLE__ -static volatile int* volatile apic_to_processor_mapping = NULL; -static volatile int next_processor_id = 0; - -static inline volatile int* get_apic_to_processor_mapping() { - volatile int* mapping = Atomic::load_acquire(&apic_to_processor_mapping); - if (mapping == NULL) { - // Calculate possible number space for APIC ids. This space is not necessarily - // in the range [0, number_of_processors). - uint total_bits = 0; - for (uint i = 0;; ++i) { - uint eax = 0xb; // Query topology leaf - uint ebx; - uint ecx = i; - uint edx; - - __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : ); - - uint level_type = (ecx >> 8) & 0xFF; - if (level_type == 0) { - // Invalid level; end of topology - break; - } - uint level_apic_id_shift = eax & ((1u << 5) - 1); - total_bits += level_apic_id_shift; - } - - uint max_apic_ids = 1u << total_bits; - mapping = NEW_C_HEAP_ARRAY(int, max_apic_ids, mtInternal); - - for (uint i = 0; i < max_apic_ids; ++i) { - mapping[i] = -1; - } - - if (!Atomic::replace_if_null(&apic_to_processor_mapping, mapping)) { - FREE_C_HEAP_ARRAY(int, mapping); - mapping = Atomic::load_acquire(&apic_to_processor_mapping); - } - } - - return mapping; -} - uint os::processor_id() { - volatile int* mapping = get_apic_to_processor_mapping(); - - uint eax = 0xb; + // Get the initial APIC id and return the associated processor id. The initial APIC + // id is limited to 8-bits, which means we can have at most 256 unique APIC ids. If + // the system has more processors (or the initial APIC ids are discontiguous) the + // APIC id will be truncated and more than one processor will potentially share the + // same processor id. This is not optimal, but unlikely to happen in practice. Should + // this become a real problem we could switch to using x2APIC ids, which are 32-bit + // wide. However, note that x2APIC is Intel-specific, and the wider number space + // would require a more complicated mapping approach. + uint eax = 0x1; uint ebx; uint ecx = 0; uint edx; __asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : ); - // Map from APIC id to a unique logical processor ID in the expected - // [0, num_processors) range. - - uint apic_id = edx; - int processor_id = Atomic::load(&mapping[apic_id]); + uint apic_id = (ebx >> 24) & (processor_id_map_size - 1); + int processor_id = Atomic::load(&processor_id_map[apic_id]); while (processor_id < 0) { - if (Atomic::cmpxchg(&mapping[apic_id], -1, -2) == -1) { - Atomic::store(&mapping[apic_id], Atomic::add(&next_processor_id, 1) - 1); + // Assign processor id to APIC id + processor_id = Atomic::cmpxchg(&processor_id_map[apic_id], processor_id_unassigned, processor_id_assigning); + if (processor_id == processor_id_unassigned) { + processor_id = Atomic::fetch_and_add(&processor_id_next, 1) % os::processor_count(); + Atomic::store(&processor_id_map[apic_id], processor_id); } - processor_id = Atomic::load(&mapping[apic_id]); } assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id"); diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 7b62e8a7e2a..5f470ce2adb 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -413,60 +413,69 @@ void os::Posix::print_uptime_info(outputStream* st) { } } - -void os::Posix::print_rlimit_info(outputStream* st) { - st->print("rlimit:"); +static void print_rlimit(outputStream* st, const char* msg, + int resource, bool output_k = false) { struct rlimit rlim; - st->print(" STACK "); - getrlimit(RLIMIT_STACK, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); + st->print(" %s ", msg); + int res = getrlimit(resource, &rlim); + if (res == -1) { + st->print("could not obtain value"); + } else { + // soft limit + if (rlim.rlim_cur == RLIM_INFINITY) { st->print("infinity"); } + else { + if (output_k) { st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); } + else { st->print(UINT64_FORMAT, uint64_t(rlim.rlim_cur)); } + } + // hard limit + st->print("/"); + if (rlim.rlim_max == RLIM_INFINITY) { st->print("infinity"); } + else { + if (output_k) { st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_max) / 1024); } + else { st->print(UINT64_FORMAT, uint64_t(rlim.rlim_max)); } + } + } +} - st->print(", CORE "); - getrlimit(RLIMIT_CORE, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); +void os::Posix::print_rlimit_info(outputStream* st) { + st->print("rlimit (soft/hard):"); + print_rlimit(st, "STACK", RLIMIT_STACK, true); + print_rlimit(st, ", CORE", RLIMIT_CORE, true); - // Isn't there on solaris #if defined(AIX) st->print(", NPROC "); st->print("%d", sysconf(_SC_CHILD_MAX)); - st->print(", THREADS "); - getrlimit(RLIMIT_THREADS, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT, uint64_t(rlim.rlim_cur)); + + print_rlimit(st, ", THREADS", RLIMIT_THREADS); #elif !defined(SOLARIS) - st->print(", NPROC "); - getrlimit(RLIMIT_NPROC, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT, uint64_t(rlim.rlim_cur)); + print_rlimit(st, ", NPROC", RLIMIT_NPROC); #endif - st->print(", NOFILE "); - getrlimit(RLIMIT_NOFILE, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT, uint64_t(rlim.rlim_cur)); + print_rlimit(st, ", NOFILE", RLIMIT_NOFILE); + print_rlimit(st, ", AS", RLIMIT_AS, true); + print_rlimit(st, ", CPU", RLIMIT_CPU); + print_rlimit(st, ", DATA", RLIMIT_DATA, true); - st->print(", AS "); - getrlimit(RLIMIT_AS, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); + // maximum size of files that the process may create + print_rlimit(st, ", FSIZE", RLIMIT_FSIZE, true); - st->print(", CPU "); - getrlimit(RLIMIT_CPU, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT, uint64_t(rlim.rlim_cur)); +#if defined(LINUX) || defined(__APPLE__) + // maximum number of bytes of memory that may be locked into RAM + // (rounded down to the nearest multiple of system pagesize) + print_rlimit(st, ", MEMLOCK", RLIMIT_MEMLOCK, true); +#endif - st->print(", DATA "); - getrlimit(RLIMIT_DATA, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); +#if defined(SOLARIS) + // maximum size of mapped address space of a process in bytes; + // if the limit is exceeded, mmap and brk fail + print_rlimit(st, ", VMEM", RLIMIT_VMEM, true); +#endif - st->print(", FSIZE "); - getrlimit(RLIMIT_FSIZE, &rlim); - if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); - else st->print(UINT64_FORMAT "k", uint64_t(rlim.rlim_cur) / 1024); + // MacOS; The maximum size (in bytes) to which a process's resident set size may grow. +#if defined(__APPLE__) + print_rlimit(st, ", RSS", RLIMIT_RSS, true); +#endif st->cr(); } diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 07d8e95a49d..de35f16da82 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -4143,7 +4143,7 @@ static void file_attribute_data_to_stat(struct stat* sbuf, WIN32_FILE_ATTRIBUTE_ static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path) { // Get required buffer size to convert to Unicode - int unicode_path_len = MultiByteToWideChar(CP_THREAD_ACP, + int unicode_path_len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, char_path, -1, NULL, 0); @@ -4153,7 +4153,7 @@ static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path) { *unicode_path = NEW_C_HEAP_ARRAY(WCHAR, unicode_path_len, mtInternal); - int result = MultiByteToWideChar(CP_THREAD_ACP, + int result = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, char_path, -1, *unicode_path, unicode_path_len); diff --git a/src/hotspot/share/aot/aotCodeHeap.cpp b/src/hotspot/share/aot/aotCodeHeap.cpp index d0badea0a63..3b7676db715 100644 --- a/src/hotspot/share/aot/aotCodeHeap.cpp +++ b/src/hotspot/share/aot/aotCodeHeap.cpp @@ -1049,7 +1049,7 @@ bool AOTCodeHeap::reconcile_dynamic_klass(AOTCompiledMethod *caller, InstanceKla InstanceKlass* dyno = InstanceKlass::cast(dyno_klass); - if (!dyno->is_unsafe_anonymous()) { + if (!dyno->is_hidden() && !dyno->is_unsafe_anonymous()) { if (_klasses_got[dyno_data->_got_index] != dyno) { // compile-time class different from runtime class, fail and deoptimize sweep_dependent_methods(holder_data); diff --git a/src/hotspot/share/aot/aotCompiledMethod.cpp b/src/hotspot/share/aot/aotCompiledMethod.cpp index aed5ebb19ce..f475d3df935 100644 --- a/src/hotspot/share/aot/aotCompiledMethod.cpp +++ b/src/hotspot/share/aot/aotCompiledMethod.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -313,7 +313,7 @@ void AOTCompiledMethod::print_on(outputStream* st) const { void AOTCompiledMethod::print_on(outputStream* st, const char* msg) const { if (st != NULL) { ttyLocker ttyl; - st->print("%7d ", (int) st->time_stamp().milliseconds()); + st->print("%7d ", (int) tty->time_stamp().milliseconds()); st->print("%4d ", _aot_id); // print compilation number st->print(" aot[%2d]", _heap->dso_id()); // Stubs have _method == NULL diff --git a/src/hotspot/share/aot/aotLoader.cpp b/src/hotspot/share/aot/aotLoader.cpp index 4b4541215da..63640e2080c 100644 --- a/src/hotspot/share/aot/aotLoader.cpp +++ b/src/hotspot/share/aot/aotLoader.cpp @@ -43,7 +43,7 @@ GrowableArray* AOTLoader::_libraries = new(ResourceObj::C_HEAP, mtCode) #define FOR_ALL_AOT_LIBRARIES(lib) for (GrowableArrayIterator lib = libraries()->begin(); lib != libraries()->end(); ++lib) void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) { - if (ik->is_unsafe_anonymous()) { + if (ik->is_hidden() || ik->is_unsafe_anonymous()) { // don't even bother return; } @@ -58,7 +58,7 @@ void AOTLoader::load_for_klass(InstanceKlass* ik, Thread* thread) { uint64_t AOTLoader::get_saved_fingerprint(InstanceKlass* ik) { assert(UseAOT, "called only when AOT is enabled"); - if (ik->is_unsafe_anonymous()) { + if (ik->is_hidden() || ik->is_unsafe_anonymous()) { // don't even bother return 0; } @@ -102,7 +102,6 @@ static const char* modules[] = { "java.base", "java.logging", "jdk.compiler", - "jdk.scripting.nashorn", "jdk.internal.vm.ci", "jdk.internal.vm.compiler" }; diff --git a/src/hotspot/share/c1/c1_LinearScan.cpp b/src/hotspot/share/c1/c1_LinearScan.cpp index 4ed81802e3a..efc9b3131c8 100644 --- a/src/hotspot/share/c1/c1_LinearScan.cpp +++ b/src/hotspot/share/c1/c1_LinearScan.cpp @@ -237,11 +237,7 @@ int LinearScan::allocate_spill_slot(bool double_word) { int result = spill_slot + LinearScan::nof_regs + frame_map()->argcount(); - // the class OopMapValue uses only 11 bits for storing the name of the - // oop location. So a stack slot bigger than 2^11 leads to an overflow - // that is not reported in product builds. Prevent this by checking the - // spill slot here (altough this value and the later used location name - // are slightly different) + // if too many slots used, bailout compilation. if (result > 2000) { bailout("too many stack slots used"); } diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 7923c5b7e52..54ea68a11a9 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -699,30 +699,22 @@ JRT_ENTRY(void, Runtime1::throw_incompatible_class_change_error(JavaThread* thre JRT_END -JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) +JRT_BLOCK_ENTRY(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) NOT_PRODUCT(_monitorenter_slowcase_cnt++;) - if (PrintBiasedLockingStatistics) { - Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); - } - Handle h_obj(thread, obj); if (!UseFastLocking) { lock->set_obj(obj); } assert(obj == lock->obj(), "must match"); - ObjectSynchronizer::enter(h_obj, lock->lock(), THREAD); + SharedRuntime::monitor_enter_helper(obj, lock->lock(), thread); JRT_END JRT_LEAF(void, Runtime1::monitorexit(JavaThread* thread, BasicObjectLock* lock)) NOT_PRODUCT(_monitorexit_slowcase_cnt++;) - assert(thread == JavaThread::current(), "threads must correspond"); assert(thread->last_Java_sp(), "last_Java_sp must be set"); - // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown - EXCEPTION_MARK; - oop obj = lock->obj(); assert(oopDesc::is_oop(obj), "must be NULL or an object"); - ObjectSynchronizer::exit(obj, lock->lock(), THREAD); + SharedRuntime::monitor_exit_helper(obj, lock->lock(), thread); JRT_END // Cf. OptoRuntime::deoptimize_caller_frame diff --git a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp index be155578090..8c426c22e0d 100644 --- a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp +++ b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,7 +80,6 @@ public: void add_allocated() { _bits = ALLOCATED; } void set_union(const ArgumentMap &am) { _bits |= am._bits; } void set_difference(const ArgumentMap &am) { _bits &= ~am._bits; } - void operator=(const ArgumentMap &am) { _bits = am._bits; } bool operator==(const ArgumentMap &am) { return _bits == am._bits; } bool operator!=(const ArgumentMap &am) { return _bits != am._bits; } }; diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp index 5c03b15f218..06fec63b020 100644 --- a/src/hotspot/share/ci/ciField.cpp +++ b/src/hotspot/share/ci/ciField.cpp @@ -223,9 +223,10 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) { holder->is_in_package("jdk/internal/foreign") || holder->is_in_package("jdk/incubator/foreign") || holder->is_in_package("java/lang")) return true; - // Trust VM unsafe anonymous classes. They are private API (jdk.internal.misc.Unsafe) - // and can't be serialized, so there is no hacking of finals going on with them. - if (holder->is_unsafe_anonymous()) + // Trust hidden classes and VM unsafe anonymous classes. They are created via + // Lookup.defineHiddenClass or the private jdk.internal.misc.Unsafe API and + // can't be serialized, so there is no hacking of finals going on with them. + if (holder->is_hidden() || holder->is_unsafe_anonymous()) return true; // Trust final fields in all boxed classes if (holder->is_box_klass()) diff --git a/src/hotspot/share/ci/ciInstanceKlass.cpp b/src/hotspot/share/ci/ciInstanceKlass.cpp index 26d8bd490ba..7412b6b5fe7 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.cpp +++ b/src/hotspot/share/ci/ciInstanceKlass.cpp @@ -63,6 +63,7 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : _has_nonstatic_fields = ik->has_nonstatic_fields(); _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods(); _is_unsafe_anonymous = ik->is_unsafe_anonymous(); + _is_hidden = ik->is_hidden(); _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields: _has_injected_fields = -1; _implementor = NULL; // we will fill these lazily @@ -73,13 +74,13 @@ ciInstanceKlass::ciInstanceKlass(Klass* k) : // InstanceKlass are created for both weak and strong metadata. Ensuring this metadata // alive covers the cases where there are weak roots without performance cost. oop holder = ik->klass_holder(); - if (ik->is_unsafe_anonymous()) { + if (ik->class_loader_data()->has_class_mirror_holder()) { // Though ciInstanceKlass records class loader oop, it's not enough to keep - // VM unsafe anonymous classes alive (loader == NULL). Klass holder should + // non-strong hidden classes and VM unsafe anonymous classes alive (loader == NULL). Klass holder should // be used instead. It is enough to record a ciObject, since cached elements are never removed // during ciObjectFactory lifetime. ciObjectFactory itself is created for // every compilation and lives for the whole duration of the compilation. - assert(holder != NULL, "holder of unsafe anonymous class is the mirror which is never null"); + assert(holder != NULL, "holder of hidden or unsafe anonymous class is the mirror which is never null"); (void)CURRENT_ENV->get_object(holder); } @@ -123,6 +124,7 @@ ciInstanceKlass::ciInstanceKlass(ciSymbol* name, _nonstatic_fields = NULL; _has_injected_fields = -1; _is_unsafe_anonymous = false; + _is_hidden = false; _loader = loader; _protection_domain = protection_domain; _is_shared = false; diff --git a/src/hotspot/share/ci/ciInstanceKlass.hpp b/src/hotspot/share/ci/ciInstanceKlass.hpp index 09f2d520ace..9ecc3da6e03 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.hpp +++ b/src/hotspot/share/ci/ciInstanceKlass.hpp @@ -56,6 +56,7 @@ private: bool _has_nonstatic_fields; bool _has_nonstatic_concrete_methods; bool _is_unsafe_anonymous; + bool _is_hidden; ciFlags _flags; jint _nonstatic_field_size; @@ -191,10 +192,14 @@ public: return _has_nonstatic_concrete_methods; } - bool is_unsafe_anonymous() { + bool is_unsafe_anonymous() const { return _is_unsafe_anonymous; } + bool is_hidden() const { + return _is_hidden; + } + ciInstanceKlass* get_canonical_holder(int offset); ciField* get_field_by_offset(int field_offset, bool is_static); ciField* get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static); diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 1092035733c..5388b4e4a96 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1092,7 +1092,7 @@ public: assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, ""); } // If this annotation name has an ID, report it (or _none). - ID annotation_index(const ClassLoaderData* loader_data, const Symbol* name); + ID annotation_index(const ClassLoaderData* loader_data, const Symbol* name, bool can_access_vm_annotations); // Set the annotation name: void set_annotation(ID id) { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); @@ -1225,6 +1225,7 @@ static void parse_annotations(const ConstantPool* const cp, const u1* buffer, int limit, AnnotationCollector* coll, ClassLoaderData* loader_data, + const bool can_access_vm_annotations, TRAPS) { assert(cp != NULL, "invariant"); @@ -1270,7 +1271,7 @@ static void parse_annotations(const ConstantPool* const cp, } // Here is where parsing particular annotations will take place. - AnnotationCollector::ID id = coll->annotation_index(loader_data, aname); + AnnotationCollector::ID id = coll->annotation_index(loader_data, aname, can_access_vm_annotations); if (AnnotationCollector::_unknown == id) continue; coll->set_annotation(id); @@ -1396,6 +1397,7 @@ void ClassFileParser::parse_field_attributes(const ClassFileStream* const cfs, runtime_visible_annotations_length, parsed_annotations, _loader_data, + _can_access_vm_annotations, CHECK); cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { @@ -2059,12 +2061,13 @@ void ClassFileParser::throwIllegalSignature(const char* type, AnnotationCollector::ID AnnotationCollector::annotation_index(const ClassLoaderData* loader_data, - const Symbol* name) { + const Symbol* name, + const bool can_access_vm_annotations) { const vmSymbols::SID sid = vmSymbols::find_sid(name); // Privileged code can use all annotations. Other code silently drops some. - const bool privileged = loader_data->is_the_null_class_loader_data() || + const bool privileged = loader_data->is_boot_class_loader_data() || loader_data->is_platform_class_loader_data() || - loader_data->is_unsafe_anonymous(); + can_access_vm_annotations; switch (sid) { case vmSymbols::VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): { if (_location != _in_method) break; // only allow for methods @@ -2671,6 +2674,7 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs, runtime_visible_annotations_length, &parsed_annotations, _loader_data, + _can_access_vm_annotations, CHECK_NULL); cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { @@ -2865,6 +2869,10 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs, if (parsed_annotations.has_any_annotations()) parsed_annotations.apply_to(methodHandle(THREAD, m)); + if (is_hidden()) { // Mark methods in hidden classes as 'hidden'. + m->set_hidden(true); + } + // Copy annotations copy_method_annotations(m->constMethod(), runtime_visible_annotations, @@ -3596,6 +3604,7 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf runtime_visible_annotations_length, parsed_annotations, _loader_data, + _can_access_vm_annotations, CHECK); cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { @@ -5592,7 +5601,9 @@ static void check_methods_for_intrinsics(const InstanceKlass* ik, } } -InstanceKlass* ClassFileParser::create_instance_klass(bool changed_by_loadhook, TRAPS) { +InstanceKlass* ClassFileParser::create_instance_klass(bool changed_by_loadhook, + const ClassInstanceInfo& cl_inst_info, + TRAPS) { if (_klass != NULL) { return _klass; } @@ -5600,7 +5611,11 @@ InstanceKlass* ClassFileParser::create_instance_klass(bool changed_by_loadhook, InstanceKlass* const ik = InstanceKlass::allocate_instance_klass(*this, CHECK_NULL); - fill_instance_klass(ik, changed_by_loadhook, CHECK_NULL); + if (is_hidden()) { + mangle_hidden_class_name(ik); + } + + fill_instance_klass(ik, changed_by_loadhook, cl_inst_info, CHECK_NULL); assert(_klass == ik, "invariant"); @@ -5626,7 +5641,10 @@ InstanceKlass* ClassFileParser::create_instance_klass(bool changed_by_loadhook, return ik; } -void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loadhook, TRAPS) { +void ClassFileParser::fill_instance_klass(InstanceKlass* ik, + bool changed_by_loadhook, + const ClassInstanceInfo& cl_inst_info, + TRAPS) { assert(ik != NULL, "invariant"); // Set name and CLD before adding to CLD @@ -5662,6 +5680,11 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa // the parser onto the InstanceKlass* apply_parsed_class_metadata(ik, _java_fields_count, CHECK); + // can only set dynamic nest-host after static nest information is set + if (cl_inst_info.dynamic_nest_host() != NULL) { + ik->set_nest_host(cl_inst_info.dynamic_nest_host(), THREAD); + } + // note that is not safe to use the fields in the parser from this point on assert(NULL == _cp, "invariant"); assert(NULL == _fields, "invariant"); @@ -5686,11 +5709,11 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa ik->set_this_class_index(_this_class_index); - if (is_unsafe_anonymous()) { + if (_is_hidden || is_unsafe_anonymous()) { // _this_class_index is a CONSTANT_Class entry that refers to this - // anonymous class itself. If this class needs to refer to its own methods or - // fields, it would use a CONSTANT_MethodRef, etc, which would reference - // _this_class_index. However, because this class is anonymous (it's + // hidden or anonymous class itself. If this class needs to refer to its own + // methods or fields, it would use a CONSTANT_MethodRef, etc, which would reference + // _this_class_index. However, because this class is hidden or anonymous (it's // not stored in SystemDictionary), _this_class_index cannot be resolved // with ConstantPool::klass_at_impl, which does a SystemDictionary lookup. // Therefore, we must eagerly resolve _this_class_index now. @@ -5706,6 +5729,9 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa assert (ik->is_unsafe_anonymous(), "should be the same"); ik->set_unsafe_anonymous_host(_unsafe_anonymous_host); } + if (_is_hidden) { + ik->set_is_hidden(); + } // Set PackageEntry for this_klass oop cl = ik->class_loader(); @@ -5785,6 +5811,7 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa Handle(THREAD, _loader_data->class_loader()), module_handle, _protection_domain, + cl_inst_info.class_data(), CHECK); assert(_all_mirandas != NULL, "invariant"); @@ -5869,7 +5896,6 @@ void ClassFileParser::update_class_name(Symbol* new_class_name) { _class_name->increment_refcount(); } - // For an unsafe anonymous class that is in the unnamed package, move it to its host class's // package by prepending its host class's package name to its class name and setting // its _class_name field. @@ -5922,8 +5948,8 @@ void ClassFileParser::fix_unsafe_anonymous_class_name(TRAPS) { } static bool relax_format_check_for(ClassLoaderData* loader_data) { - bool trusted = (loader_data->is_the_null_class_loader_data() || - SystemDictionary::is_platform_class_loader(loader_data->class_loader())); + bool trusted = loader_data->is_boot_class_loader_data() || + loader_data->is_platform_class_loader_data(); bool need_verify = // verifyAll (BytecodeVerificationLocal && BytecodeVerificationRemote) || @@ -5935,17 +5961,16 @@ static bool relax_format_check_for(ClassLoaderData* loader_data) { ClassFileParser::ClassFileParser(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, - Handle protection_domain, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo* cl_info, Publicity pub_level, TRAPS) : _stream(stream), - _requested_name(name), _class_name(NULL), _loader_data(loader_data), - _unsafe_anonymous_host(unsafe_anonymous_host), - _cp_patches(cp_patches), + _unsafe_anonymous_host(cl_info->unsafe_anonymous_host()), + _cp_patches(cl_info->cp_patches()), + _is_hidden(cl_info->is_hidden()), + _can_access_vm_annotations(cl_info->can_access_vm_annotations()), _num_patched_klasses(0), _max_num_patched_klasses(0), _orig_cp_size(0), @@ -5976,7 +6001,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream, _itable_size(0), _num_miranda_methods(0), _rt(REF_NONE), - _protection_domain(protection_domain), + _protection_domain(cl_info->protection_domain()), _access_flags(), _pub_level(pub_level), _bad_constant_seen(0), @@ -6179,10 +6204,15 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, cp_size, CHECK); _orig_cp_size = cp_size; - if (int(cp_size) + _max_num_patched_klasses > 0xffff) { - THROW_MSG(vmSymbols::java_lang_InternalError(), "not enough space for patched classes"); + if (is_hidden()) { // Add a slot for hidden class name. + assert(_max_num_patched_klasses == 0, "Sanity check"); + cp_size++; + } else { + if (int(cp_size) + _max_num_patched_klasses > 0xffff) { + THROW_MSG(vmSymbols::java_lang_InternalError(), "not enough space for patched classes"); + } + cp_size += _max_num_patched_klasses; } - cp_size += _max_num_patched_klasses; _cp = ConstantPool::allocate(_loader_data, cp_size, @@ -6233,36 +6263,67 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, Symbol* const class_name_in_cp = cp->klass_name_at(_this_class_index); assert(class_name_in_cp != NULL, "class_name can't be null"); - // Update _class_name to reflect the name in the constant pool - update_class_name(class_name_in_cp); - // Don't need to check whether this class name is legal or not. // It has been checked when constant pool is parsed. // However, make sure it is not an array type. if (_need_verify) { - guarantee_property(_class_name->char_at(0) != JVM_SIGNATURE_ARRAY, + guarantee_property(class_name_in_cp->char_at(0) != JVM_SIGNATURE_ARRAY, "Bad class name in class file %s", CHECK); } - // Checks if name in class file matches requested name - if (_requested_name != NULL && _requested_name != _class_name) { - ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_NoClassDefFoundError(), - "%s (wrong name: %s)", - _class_name->as_C_string(), - _requested_name != NULL ? _requested_name->as_C_string() : "NoName" - ); - return; - } +#ifdef ASSERT + // Basic sanity checks + assert(!(_is_hidden && (_unsafe_anonymous_host != NULL)), "mutually exclusive variants"); - // if this is an anonymous class fix up its name if it's in the unnamed + if (_unsafe_anonymous_host != NULL) { + assert(_class_name == vmSymbols::unknown_class_name(), "A named anonymous class???"); + } + if (_is_hidden) { + assert(_class_name != vmSymbols::unknown_class_name(), "hidden classes should have a special name"); + } +#endif + + // Update the _class_name as needed depending on whether this is a named, + // un-named, hidden or unsafe-anonymous class. + + if (_is_hidden) { + assert(_class_name != NULL, "Unexpected null _class_name"); +#ifdef ASSERT + if (_need_verify) { + verify_legal_class_name(_class_name, CHECK); + } +#endif + + // NOTE: !_is_hidden does not imply "findable" as it could be an old-style + // "hidden" unsafe-anonymous class + + // If this is an anonymous class fix up its name if it is in the unnamed // package. Otherwise, throw IAE if it is in a different package than // its host class. - if (_unsafe_anonymous_host != NULL) { + } else if (_unsafe_anonymous_host != NULL) { + update_class_name(class_name_in_cp); fix_unsafe_anonymous_class_name(CHECK); + + } else { + // Check if name in class file matches given name + if (_class_name != class_name_in_cp) { + if (_class_name != vmSymbols::unknown_class_name()) { + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_NoClassDefFoundError(), + "%s (wrong name: %s)", + class_name_in_cp->as_C_string(), + _class_name->as_C_string() + ); + return; + } else { + // The class name was not known by the caller so we set it from + // the value in the CP. + update_class_name(class_name_in_cp); + } + // else nothing to do: the expected class name matches what is in the CP + } } // Verification prevents us from creating names with dots in them, this @@ -6287,9 +6348,10 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, warning("DumpLoadedClassList and CDS are not supported in exploded build"); DumpLoadedClassList = NULL; } else if (SystemDictionaryShared::is_sharing_possible(_loader_data) && + !_is_hidden && _unsafe_anonymous_host == NULL) { // Only dump the classes that can be stored into CDS archive. - // Unsafe anonymous classes such as generated LambdaForm classes are also not included. + // Hidden and unsafe anonymous classes such as generated LambdaForm classes are also not included. oop class_loader = _loader_data->class_loader(); ResourceMark rm(THREAD); bool skip = false; @@ -6384,6 +6446,35 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, // all bytes in stream read and parsed } +void ClassFileParser::mangle_hidden_class_name(InstanceKlass* const ik) { + ResourceMark rm; + // Construct hidden name from _class_name, "+", and &ik. Note that we can't + // use a '/' because that confuses finding the class's package. Also, can't + // use an illegal char such as ';' because that causes serialization issues + // and issues with hidden classes that create their own hidden classes. + char addr_buf[20]; + jio_snprintf(addr_buf, 20, INTPTR_FORMAT, p2i(ik)); + size_t new_name_len = _class_name->utf8_length() + 2 + strlen(addr_buf); + char* new_name = NEW_RESOURCE_ARRAY(char, new_name_len); + jio_snprintf(new_name, new_name_len, "%s+%s", + _class_name->as_C_string(), addr_buf); + update_class_name(SymbolTable::new_symbol(new_name)); + + // Add a Utf8 entry containing the hidden name. + assert(_class_name != NULL, "Unexpected null _class_name"); + int hidden_index = _orig_cp_size; // this is an extra slot we added + _cp->symbol_at_put(hidden_index, _class_name); + + // Update this_class_index's slot in the constant pool with the new Utf8 entry. + // We have to update the resolved_klass_index and the name_index together + // so extract the existing resolved_klass_index first. + CPKlassSlot cp_klass_slot = _cp->klass_slot_at(_this_class_index); + int resolved_klass_index = cp_klass_slot.resolved_klass_index(); + _cp->unresolved_klass_at_put(_this_class_index, hidden_index, resolved_klass_index); + assert(_cp->klass_slot_at(_this_class_index).name_index() == _orig_cp_size, + "Bad name_index"); +} + void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const stream, ConstantPool* cp, TRAPS) { diff --git a/src/hotspot/share/classfile/classFileParser.hpp b/src/hotspot/share/classfile/classFileParser.hpp index 8945b29d05d..a6e48b1904d 100644 --- a/src/hotspot/share/classfile/classFileParser.hpp +++ b/src/hotspot/share/classfile/classFileParser.hpp @@ -37,6 +37,8 @@ template class Array; class ClassFileStream; class ClassLoaderData; +class ClassLoadInfo; +class ClassInstanceInfo; class CompressedLineNumberWriteStream; class ConstMethod; class FieldInfo; @@ -109,11 +111,12 @@ class ClassFileParser { typedef void unsafe_u2; const ClassFileStream* _stream; // Actual input stream - const Symbol* _requested_name; Symbol* _class_name; mutable ClassLoaderData* _loader_data; const InstanceKlass* _unsafe_anonymous_host; GrowableArray* _cp_patches; // overrides for CP entries + const bool _is_hidden; + const bool _can_access_vm_annotations; int _num_patched_klasses; int _max_num_patched_klasses; int _orig_cp_size; @@ -201,6 +204,8 @@ class ClassFileParser { void parse_stream(const ClassFileStream* const stream, TRAPS); + void mangle_hidden_class_name(InstanceKlass* const ik); + void post_process_parsed_stream(const ClassFileStream* const stream, ConstantPool* cp, TRAPS); @@ -208,7 +213,9 @@ class ClassFileParser { void prepend_host_package_name(const InstanceKlass* unsafe_anonymous_host, TRAPS); void fix_unsafe_anonymous_class_name(TRAPS); - void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, TRAPS); + void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH, + const ClassInstanceInfo& cl_inst_info, TRAPS); + void set_klass(InstanceKlass* instance); void set_class_bad_constant_seen(short bad_constant); @@ -527,21 +534,19 @@ class ClassFileParser { FieldLayoutInfo* info, TRAPS); - void update_class_name(Symbol* new_name); + void update_class_name(Symbol* new_name); public: ClassFileParser(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, - Handle protection_domain, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo* cl_info, Publicity pub_level, TRAPS); ~ClassFileParser(); - InstanceKlass* create_instance_klass(bool cf_changed_in_CFLH, TRAPS); + InstanceKlass* create_instance_klass(bool cf_changed_in_CFLH, const ClassInstanceInfo& cl_inst_info, TRAPS); const ClassFileStream* clone_stream() const; @@ -557,6 +562,7 @@ class ClassFileParser { u2 this_class_index() const { return _this_class_index; } bool is_unsafe_anonymous() const { return _unsafe_anonymous_host != NULL; } + bool is_hidden() const { return _is_hidden; } bool is_interface() const { return _access_flags.is_interface(); } const InstanceKlass* unsafe_anonymous_host() const { return _unsafe_anonymous_host; } diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 33638eb8792..9d465eb6746 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -1011,32 +1011,6 @@ int ClassLoader::crc32(int crc, const char* buf, int len) { return (*Crc32)(crc, (const jbyte*)buf, len); } -// Function add_package checks if the package of the InstanceKlass is in the -// boot loader's package entry table. If so, then it sets the classpath_index -// in the package entry record. -// -// The classpath_index field is used to find the entry on the boot loader class -// path for packages with classes loaded by the boot loader from -Xbootclasspath/a -// in an unnamed module. It is also used to indicate (for all packages whose -// classes are loaded by the boot loader) that at least one of the package's -// classes has been loaded. -bool ClassLoader::add_package(const InstanceKlass* ik, s2 classpath_index, TRAPS) { - assert(ik != NULL, "just checking"); - - PackageEntry* ik_pkg = ik->package(); - if (ik_pkg != NULL) { - PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages(); - PackageEntry* pkg_entry = pkg_entry_tbl->lookup_only(ik_pkg->name()); - if (pkg_entry != NULL) { - assert(classpath_index != -1, "Unexpected classpath_index"); - pkg_entry->set_classpath_index(classpath_index); - } else { - return false; - } - } - return true; -} - oop ClassLoader::get_system_package(const char* name, TRAPS) { // Look up the name in the boot loader's package entry table. if (name != NULL) { @@ -1283,13 +1257,12 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); Handle protection_domain; + ClassLoadInfo cl_info(protection_domain); InstanceKlass* result = KlassFactory::create_from_stream(stream, name, loader_data, - protection_domain, - NULL, // unsafe_anonymous_host - NULL, // cp_patches + cl_info, THREAD); if (HAS_PENDING_EXCEPTION) { if (DumpSharedSpaces) { @@ -1298,10 +1271,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR return NULL; } - if (!add_package(result, classpath_index, THREAD)) { - return NULL; - } - + result->set_classpath_index(classpath_index, THREAD); return result; } @@ -1331,8 +1301,8 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream Arguments::assert_is_dumping_archive(); assert(stream != NULL, "sanity"); - if (ik->is_unsafe_anonymous()) { - // We do not archive unsafe anonymous classes. + if (ik->is_hidden() || ik->is_unsafe_anonymous()) { + // We do not archive hidden or unsafe anonymous classes. return; } diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index f5a89396764..849e10d907a 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -258,15 +258,6 @@ class ClassLoader: AllStatic { bool is_boot_append, bool from_class_path_attr, TRAPS); - // If the package for InstanceKlass is in the boot loader's package entry - // table then add_package() sets the classpath_index field so that - // get_system_package() will know to return a non-null value for the - // package's location. And, so that the package will be added to the list of - // packages returned by get_system_packages(). - // For packages whose classes are loaded from the boot loader class path, the - // classpath_index indicates which entry on the boot loader class path. - static bool add_package(const InstanceKlass* ik, s2 classpath_index, TRAPS); - // Canonicalizes path names, so strcmp will work properly. This is mainly // to avoid confusing the zip library static bool get_canonical_path(const char* orig, char* out, int len); diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 123571f85d5..4534d4fe1fc 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -126,16 +126,16 @@ void ClassLoaderData::initialize_name(Handle class_loader) { _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id); } -ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) : +ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder) : _metaspace(NULL), _metaspace_lock(new Mutex(Mutex::leaf+1, "Metaspace allocation lock", true, Mutex::_safepoint_check_never)), - _unloading(false), _is_unsafe_anonymous(is_unsafe_anonymous), + _unloading(false), _has_class_mirror_holder(has_class_mirror_holder), _modified_oops(true), _accumulated_modified_oops(false), // An unsafe anonymous class loader data doesn't have anything to keep // it from being unloaded during parsing of the unsafe anonymous class. // The null-class-loader should always be kept alive. - _keep_alive((is_unsafe_anonymous || h_class_loader.is_null()) ? 1 : 0), + _keep_alive((has_class_mirror_holder || h_class_loader.is_null()) ? 1 : 0), _claim(0), _handles(), _klasses(NULL), _packages(NULL), _modules(NULL), _unnamed_module(NULL), _dictionary(NULL), @@ -150,13 +150,13 @@ ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous initialize_name(h_class_loader); } - if (!is_unsafe_anonymous) { - // The holder is initialized later for unsafe anonymous classes, and before calling anything - // that call class_loader(). + if (!has_class_mirror_holder) { + // The holder is initialized later for non-strong hidden classes and unsafe anonymous classes, + // and before calling anything that call class_loader(). initialize_holder(h_class_loader); - // A ClassLoaderData created solely for an unsafe anonymous class should never have a - // ModuleEntryTable or PackageEntryTable created for it. The defining package + // A ClassLoaderData created solely for a non-strong hidden class or unsafe anonymous class should + // never have a ModuleEntryTable or PackageEntryTable created for it. The defining package // and module for an unsafe anonymous class will be found in its host class. _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); if (h_class_loader.is_null()) { @@ -291,20 +291,20 @@ bool ClassLoaderData::try_claim(int claim) { } } -// Unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive +// Weak hidden and unsafe anonymous classes have their own ClassLoaderData that is marked to keep alive // while the class is being parsed, and if the class appears on the module fixup list. -// Due to the uniqueness that no other class shares the unsafe anonymous class' name or -// ClassLoaderData, no other non-GC thread has knowledge of the unsafe anonymous class while +// Due to the uniqueness that no other class shares the hidden or unsafe anonymous class' name or +// ClassLoaderData, no other non-GC thread has knowledge of the hidden or unsafe anonymous class while // it is being defined, therefore _keep_alive is not volatile or atomic. void ClassLoaderData::inc_keep_alive() { - if (is_unsafe_anonymous()) { + if (has_class_mirror_holder()) { assert(_keep_alive > 0, "Invalid keep alive increment count"); _keep_alive++; } } void ClassLoaderData::dec_keep_alive() { - if (is_unsafe_anonymous()) { + if (has_class_mirror_holder()) { assert(_keep_alive > 0, "Invalid keep alive decrement count"); _keep_alive--; } @@ -410,21 +410,21 @@ void ClassLoaderData::record_dependency(const Klass* k) { // Do not need to record dependency if the dependency is to a class whose // class loader data is never freed. (i.e. the dependency's class loader - // is one of the three builtin class loaders and the dependency is not - // unsafe anonymous.) + // is one of the three builtin class loaders and the dependency's class + // loader data has a ClassLoader holder, not a Class holder.) if (to_cld->is_permanent_class_loader_data()) { return; } oop to; - if (to_cld->is_unsafe_anonymous()) { - // Just return if an unsafe anonymous class is attempting to record a dependency - // to itself. (Note that every unsafe anonymous class has its own unique class + if (to_cld->has_class_mirror_holder()) { + // Just return if a non-strong hidden class or unsafe anonymous class is attempting to record a dependency + // to itself. (Note that every non-strong hidden class or unsafe anonymous class has its own unique class // loader data.) if (to_cld == from_cld) { return; } - // Unsafe anonymous class dependencies are through the mirror. + // Hidden and unsafe anonymous class dependencies are through the mirror. to = k->java_mirror(); } else { to = to_cld->class_loader(); @@ -572,7 +572,7 @@ const int _boot_loader_dictionary_size = 1009; const int _default_loader_dictionary_size = 107; Dictionary* ClassLoaderData::create_dictionary() { - assert(!is_unsafe_anonymous(), "unsafe anonymous class loader data do not have a dictionary"); + assert(!has_class_mirror_holder(), "class mirror holder cld does not have a dictionary"); int size; bool resizable = false; if (_the_null_class_loader_data == NULL) { @@ -618,7 +618,7 @@ oop ClassLoaderData::holder_no_keepalive() const { // Unloading support bool ClassLoaderData::is_alive() const { - bool alive = keep_alive() // null class loader and incomplete unsafe anonymous klasses. + bool alive = keep_alive() // null class loader and incomplete non-strong hidden class or unsafe anonymous class. || (_holder.peek() != NULL); // and not cleaned by the GC weak handle processing. return alive; @@ -716,13 +716,13 @@ ClassLoaderData::~ClassLoaderData() { // Returns true if this class loader data is for the app class loader // or a user defined system class loader. (Note that the class loader -// data may be unsafe anonymous.) +// data may have a Class holder.) bool ClassLoaderData::is_system_class_loader_data() const { return SystemDictionary::is_system_class_loader(class_loader()); } // Returns true if this class loader data is for the platform class loader. -// (Note that the class loader data may be unsafe anonymous.) +// (Note that the class loader data may have a Class holder.) bool ClassLoaderData::is_platform_class_loader_data() const { return SystemDictionary::is_platform_class_loader(class_loader()); } @@ -730,8 +730,8 @@ bool ClassLoaderData::is_platform_class_loader_data() const { // Returns true if the class loader for this class loader data is one of // the 3 builtin (boot application/system or platform) class loaders, // including a user-defined system class loader. Note that if the class -// loader data is for an unsafe anonymous class then it may get freed by a GC -// even if its class loader is one of these loaders. +// loader data is for a non-strong hidden class or unsafe anonymous class then it may +// get freed by a GC even if its class loader is one of these loaders. bool ClassLoaderData::is_builtin_class_loader_data() const { return (is_boot_class_loader_data() || SystemDictionary::is_system_class_loader(class_loader()) || @@ -740,9 +740,9 @@ bool ClassLoaderData::is_builtin_class_loader_data() const { // Returns true if this class loader data is a class loader data // that is not ever freed by a GC. It must be the CLD for one of the builtin -// class loaders and not the CLD for an unsafe anonymous class. +// class loaders and not the CLD for a non-strong hidden class or unsafe anonymous class. bool ClassLoaderData::is_permanent_class_loader_data() const { - return is_builtin_class_loader_data() && !is_unsafe_anonymous(); + return is_builtin_class_loader_data() && !has_class_mirror_holder(); } ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() { @@ -759,8 +759,8 @@ ClassLoaderMetaspace* ClassLoaderData::metaspace_non_null() { if (this == the_null_class_loader_data()) { assert (class_loader() == NULL, "Must be"); metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::BootMetaspaceType); - } else if (is_unsafe_anonymous()) { - metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::UnsafeAnonymousMetaspaceType); + } else if (has_class_mirror_holder()) { + metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ClassMirrorHolderMetaspaceType); } else if (class_loader()->is_a(SystemDictionary::reflect_DelegatingClassLoader_klass())) { metaspace = new ClassLoaderMetaspace(_metaspace_lock, Metaspace::ReflectionMetaspaceType); } else { @@ -877,8 +877,8 @@ void ClassLoaderData::free_deallocate_list_C_heap_structures() { } } -// These CLDs are to contain unsafe anonymous classes used for JSR292 -ClassLoaderData* ClassLoaderData::unsafe_anonymous_class_loader_data(Handle loader) { +// These CLDs are to contain non-strong hidden classes or unsafe anonymous classes used for JSR292 +ClassLoaderData* ClassLoaderData::has_class_mirror_holder_cld(Handle loader) { // Add a new class loader data to the graph. return ClassLoaderDataGraph::add(loader, true); } @@ -920,8 +920,8 @@ void ClassLoaderData::print_value_on(outputStream* out) const { // loader data: 0xsomeaddr of 'bootstrap' out->print("loader data: " INTPTR_FORMAT " of %s", p2i(this), loader_name_and_id()); } - if (is_unsafe_anonymous()) { - out->print(" unsafe anonymous"); + if (_has_class_mirror_holder) { + out->print(" has a class holder"); } } @@ -931,7 +931,7 @@ void ClassLoaderData::print_value() const { print_value_on(tty); } void ClassLoaderData::print_on(outputStream* out) const { out->print("ClassLoaderData CLD: " PTR_FORMAT ", loader: " PTR_FORMAT ", loader_klass: %s {", p2i(this), p2i(_class_loader.ptr_raw()), loader_name_and_id()); - if (is_unsafe_anonymous()) out->print(" unsafe anonymous"); + if (has_class_mirror_holder()) out->print(" has a class holder"); if (claimed()) out->print(" claimed"); if (is_unloading()) out->print(" unloading"); out->print(" metaspace: " INTPTR_FORMAT, p2i(metaspace_or_null())); @@ -951,8 +951,8 @@ void ClassLoaderData::verify() { assert_locked_or_safepoint(_metaspace_lock); oop cl = class_loader(); - guarantee(this == class_loader_data(cl) || is_unsafe_anonymous(), "Must be the same"); - guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || is_unsafe_anonymous(), "must be"); + guarantee(this == class_loader_data(cl) || has_class_mirror_holder(), "Must be the same"); + guarantee(cl != NULL || this == ClassLoaderData::the_null_class_loader_data() || has_class_mirror_holder(), "must be"); // Verify the integrity of the allocated space. if (metaspace_or_null() != NULL) { diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index c7d81ad7811..1b898abcc3d 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,17 +117,20 @@ class ClassLoaderData : public CHeapObj { // classes in the class loader are allocated. Mutex* _metaspace_lock; // Locks the metaspace for allocations and setup. bool _unloading; // true if this class loader goes away - bool _is_unsafe_anonymous; // CLD is dedicated to one class and that class determines the CLDs lifecycle. - // For example, an unsafe anonymous class. + bool _has_class_mirror_holder; // If true, CLD is dedicated to one class and that class determines + // the CLDs lifecycle. For example, a non-strong hidden class or an + // unsafe anonymous class. Arrays of these classes are also assigned + // to these class loader datas. // Remembered sets support for the oops in the class loader data. bool _modified_oops; // Card Table Equivalent (YC/CMS support) bool _accumulated_modified_oops; // Mod Union Equivalent (CMS support) int _keep_alive; // if this CLD is kept alive. - // Used for unsafe anonymous classes and the boot class - // loader. _keep_alive does not need to be volatile or - // atomic since there is one unique CLD per unsafe anonymous class. + // Used for non-strong hidden classes, unsafe anonymous classes and the + // boot class loader. _keep_alive does not need to be volatile or + // atomic since there is one unique CLD per non-strong hidden class + // or unsafe anonymous class. volatile int _claim; // non-zero if claimed, for example during GC traces. // To avoid applying oop closure more than once. @@ -162,7 +165,7 @@ class ClassLoaderData : public CHeapObj { void set_next(ClassLoaderData* next) { _next = next; } ClassLoaderData* next() const { return Atomic::load(&_next); } - ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous); + ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder); ~ClassLoaderData(); // The CLD are not placed in the Heap, so the Card Table or @@ -231,7 +234,7 @@ class ClassLoaderData : public CHeapObj { Mutex* metaspace_lock() const { return _metaspace_lock; } - bool is_unsafe_anonymous() const { return _is_unsafe_anonymous; } + bool has_class_mirror_holder() const { return _has_class_mirror_holder; } static void init_null_class_loader_data(); @@ -240,15 +243,15 @@ class ClassLoaderData : public CHeapObj { } // Returns true if this class loader data is for the system class loader. - // (Note that the class loader data may be unsafe anonymous.) + // (Note that the class loader data may be for a non-strong hidden class or unsafe anonymous class) bool is_system_class_loader_data() const; // Returns true if this class loader data is for the platform class loader. - // (Note that the class loader data may be unsafe anonymous.) + // (Note that the class loader data may be for a non-strong hidden class or unsafe anonymous class) bool is_platform_class_loader_data() const; // Returns true if this class loader data is for the boot class loader. - // (Note that the class loader data may be unsafe anonymous.) + // (Note that the class loader data may be for a non-strong hidden class or unsafe anonymous class) inline bool is_boot_class_loader_data() const; bool is_builtin_class_loader_data() const; @@ -269,7 +272,7 @@ class ClassLoaderData : public CHeapObj { return _unloading; } - // Used to refcount an unsafe anonymous class's CLD in order to + // Used to refcount a non-strong hidden class's or unsafe anonymous class's CLD in order to // indicate their aliveness. void inc_keep_alive(); void dec_keep_alive(); @@ -313,7 +316,7 @@ class ClassLoaderData : public CHeapObj { static ClassLoaderData* class_loader_data(oop loader); static ClassLoaderData* class_loader_data_or_null(oop loader); - static ClassLoaderData* unsafe_anonymous_class_loader_data(Handle loader); + static ClassLoaderData* has_class_mirror_holder_cld(Handle loader); // Returns Klass* of associated class loader, or NULL if associated loader is 'bootstrap'. // Also works if unloading. diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index bab44e3f2c7..971c495e70c 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -192,7 +192,7 @@ bool ClassLoaderDataGraph::_metaspace_oom = false; // Add a new class loader data node to the list. Assign the newly created // ClassLoaderData into the java/lang/ClassLoader object as a hidden field -ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsafe_anonymous) { +ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool has_class_mirror_holder) { assert_lock_strong(ClassLoaderDataGraph_lock); @@ -200,7 +200,7 @@ ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsaf // First check if another thread beat us to creating the CLD and installing // it into the loader while we were waiting for the lock. - if (!is_unsafe_anonymous && loader.not_null()) { + if (!has_class_mirror_holder && loader.not_null()) { cld = java_lang_ClassLoader::loader_data_acquire(loader()); if (cld != NULL) { return cld; @@ -212,14 +212,14 @@ ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsaf // loader oop in all collections, particularly young collections. NoSafepointVerifier no_safepoints; - cld = new ClassLoaderData(loader, is_unsafe_anonymous); + cld = new ClassLoaderData(loader, has_class_mirror_holder); // First install the new CLD to the Graph. cld->set_next(_head); Atomic::release_store(&_head, cld); // Next associate with the class_loader. - if (!is_unsafe_anonymous) { + if (!has_class_mirror_holder) { // Use OrderAccess, since readers need to get the loader_data only after // it's added to the Graph java_lang_ClassLoader::release_set_loader_data(loader(), cld); @@ -237,9 +237,9 @@ ClassLoaderData* ClassLoaderDataGraph::add_to_graph(Handle loader, bool is_unsaf return cld; } -ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_unsafe_anonymous) { +ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool has_class_mirror_holder) { MutexLocker ml(ClassLoaderDataGraph_lock); - ClassLoaderData* loader_data = add_to_graph(loader, is_unsafe_anonymous); + ClassLoaderData* loader_data = add_to_graph(loader, has_class_mirror_holder); return loader_data; } diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp index 91fe4c343ac..ef466e102fd 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,8 +56,8 @@ class ClassLoaderDataGraph : public AllStatic { static volatile size_t _num_instance_classes; static volatile size_t _num_array_classes; - static ClassLoaderData* add_to_graph(Handle class_loader, bool is_unsafe_anonymous); - static ClassLoaderData* add(Handle class_loader, bool is_unsafe_anonymous); + static ClassLoaderData* add_to_graph(Handle class_loader, bool has_class_mirror_holder); + static ClassLoaderData* add(Handle class_loader, bool has_class_mirror_holder); public: static ClassLoaderData* find_or_create(Handle class_loader); @@ -76,7 +76,7 @@ class ClassLoaderDataGraph : public AllStatic { // Walking classes through the ClassLoaderDataGraph include array classes. It also includes // classes that are allocated but not loaded, classes that have errors, and scratch classes // for redefinition. These classes are removed during the next class unloading. - // Walking the ClassLoaderDataGraph also includes unsafe anonymous classes. + // Walking the ClassLoaderDataGraph also includes hidden and unsafe anonymous classes. static void classes_do(KlassClosure* klass_closure); static void classes_do(void f(Klass* const)); static void methods_do(void f(Method*)); diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp index d42060bebb7..701c155da19 100644 --- a/src/hotspot/share/classfile/classLoaderExt.cpp +++ b/src/hotspot/share/classfile/classLoaderExt.cpp @@ -284,13 +284,12 @@ InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS) ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); Handle protection_domain; + ClassLoadInfo cl_info(protection_domain); InstanceKlass* result = KlassFactory::create_from_stream(stream, name, loader_data, - protection_domain, - NULL, // unsafe_anonymous_host - NULL, // cp_patches + cl_info, THREAD); if (HAS_PENDING_EXCEPTION) { diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp index d24dd9a41f0..36e92ff60c6 100644 --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -129,7 +129,7 @@ public: class LoaderTreeNode : public ResourceObj { - // We walk the CLDG and, for each CLD which is non-unsafe_anonymous, add + // We walk the CLDG and, for each CLD which is findable, add // a tree node. // To add a node we need its parent node; if the parent node does not yet // exist - because we have not yet encountered the CLD for the parent loader - @@ -149,6 +149,9 @@ class LoaderTreeNode : public ResourceObj { LoadedClassInfo* _anon_classes; int _num_anon_classes; + LoadedClassInfo* _hidden_classes; + int _num_hidden_classes; + // In default view, similar tree nodes (same loader class, same name or no name) // are folded into each other to make the output more readable. // _num_folded contains the number of nodes which have been folded into this @@ -177,6 +180,7 @@ class LoaderTreeNode : public ResourceObj { if (_cld->is_the_null_class_loader_data()) { st->print(" "); } else { + assert(!_cld->has_class_mirror_holder(), "_cld must be the primary cld"); if (loader_name != NULL) { st->print(" \"%s\",", loader_name->as_C_string()); } @@ -220,7 +224,7 @@ class LoaderTreeNode : public ResourceObj { if (print_classes) { if (_classes != NULL) { for (LoadedClassInfo* lci = _classes; lci; lci = lci->_next) { - // Non-unsafe anonymous classes should live in the primary CLD of its loader + // non-strong hidden and unsafe anonymous classes should not live in the primary CLD of their loaders. assert(lci->_cld == _cld, "must be"); branchtracker.print(st); @@ -258,7 +262,8 @@ class LoaderTreeNode : public ResourceObj { st->print("%*s ", indentation, ""); } st->print("%s", lci->_klass->external_name()); - // For unsafe anonymous classes, also print CLD if verbose. Should be a different one than the primary CLD. + // For unsafe anonymous classes, also print CLD if verbose. Should + // be a different one than the primary CLD. assert(lci->_cld != _cld, "must be"); if (verbose) { st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld)); @@ -267,7 +272,35 @@ class LoaderTreeNode : public ResourceObj { } branchtracker.print(st); st->print("%*s ", indentation, ""); - st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes, (_num_anon_classes == 1) ? "" : "es"); + st->print_cr("(%u unsafe anonymous class%s)", _num_anon_classes, + (_num_anon_classes == 1) ? "" : "es"); + + // Empty line + branchtracker.print(st); + st->cr(); + } + + if (_hidden_classes != NULL) { + for (LoadedClassInfo* lci = _hidden_classes; lci; lci = lci->_next) { + branchtracker.print(st); + if (lci == _hidden_classes) { // first iteration + st->print("%*s ", indentation, "Hidden Classes:"); + } else { + st->print("%*s ", indentation, ""); + } + st->print("%s", lci->_klass->external_name()); + // For non-strong hidden classes, also print CLD if verbose. Should be a + // different one than the primary CLD. + assert(lci->_cld != _cld, "must be"); + if (verbose) { + st->print(" (Loader Data: " PTR_FORMAT ")", p2i(lci->_cld)); + } + st->cr(); + } + branchtracker.print(st); + st->print("%*s ", indentation, ""); + st->print_cr("(%u hidden class%s)", _num_hidden_classes, + (_num_hidden_classes == 1) ? "" : "es"); // Empty line branchtracker.print(st); @@ -301,6 +334,7 @@ public: LoaderTreeNode(const oop loader_oop) : _loader_oop(loader_oop), _cld(NULL), _child(NULL), _next(NULL), _classes(NULL), _num_classes(0), _anon_classes(NULL), _num_anon_classes(0), + _hidden_classes(NULL), _num_hidden_classes(0), _num_folded(0) {} @@ -319,15 +353,25 @@ public: _next = info; } - void add_classes(LoadedClassInfo* first_class, int num_classes, bool is_unsafe_anonymous) { - LoadedClassInfo** p_list_to_add_to = is_unsafe_anonymous ? &_anon_classes : &_classes; + void add_classes(LoadedClassInfo* first_class, int num_classes, bool has_class_mirror_holder) { + LoadedClassInfo** p_list_to_add_to; + bool is_hidden = first_class->_klass->is_hidden(); + if (has_class_mirror_holder) { + p_list_to_add_to = is_hidden ? &_hidden_classes : &_anon_classes; + } else { + p_list_to_add_to = &_classes; + } // Search tail. while ((*p_list_to_add_to) != NULL) { p_list_to_add_to = &(*p_list_to_add_to)->_next; } *p_list_to_add_to = first_class; - if (is_unsafe_anonymous) { - _num_anon_classes += num_classes; + if (has_class_mirror_holder) { + if (is_hidden) { + _num_hidden_classes += num_classes; + } else { + _num_anon_classes += num_classes; + } } else { _num_classes += num_classes; } @@ -421,7 +465,7 @@ class LoaderInfoScanClosure : public CLDClosure { LoadedClassCollectClosure lccc(cld); const_cast(cld)->classes_do(&lccc); if (lccc._num_classes > 0) { - info->add_classes(lccc._list, lccc._num_classes, cld->is_unsafe_anonymous()); + info->add_classes(lccc._list, lccc._num_classes, cld->has_class_mirror_holder()); } } @@ -481,7 +525,7 @@ public: assert(info != NULL, "must be"); // Update CLD in node, but only if this is the primary CLD for this loader. - if (cld->is_unsafe_anonymous() == false) { + if (cld->has_class_mirror_holder() == false) { assert(info->cld() == NULL, "there should be only one primary CLD per loader"); info->set_cld(cld); } diff --git a/src/hotspot/share/classfile/classLoaderStats.cpp b/src/hotspot/share/classfile/classLoaderStats.cpp index 2ba125f2f2d..f3adad46da5 100644 --- a/src/hotspot/share/classfile/classLoaderStats.cpp +++ b/src/hotspot/share/classfile/classLoaderStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/classLoaderStats.hpp" +#include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "utilities/globalDefinitions.hpp" @@ -59,7 +60,7 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) { cls = *cls_ptr; } - if (!cld->is_unsafe_anonymous()) { + if (!cld->has_class_mirror_holder()) { cls->_cld = cld; } @@ -71,8 +72,20 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) { ClassStatsClosure csc; cld->classes_do(&csc); - if(cld->is_unsafe_anonymous()) { - cls->_anon_classes_count += csc._num_classes; + bool is_hidden = false; + if(cld->has_class_mirror_holder()) { + // if cld has a class holder then it must be either hidden or unsafe anonymous. + Klass* k = cld->klasses(); + // if it's an array class then need to see if bottom class is hidden. + if (k->is_array_klass()) { + k = ObjArrayKlass::cast(k)->bottom_klass(); + } + is_hidden = k->is_hidden(); + if (is_hidden) { + cls->_hidden_classes_count += csc._num_classes; + } else { + cls->_anon_classes_count += csc._num_classes; + } } else { cls->_classes_count = csc._num_classes; } @@ -80,9 +93,14 @@ void ClassLoaderStatsClosure::do_cld(ClassLoaderData* cld) { ClassLoaderMetaspace* ms = cld->metaspace_or_null(); if (ms != NULL) { - if(cld->is_unsafe_anonymous()) { - cls->_anon_chunk_sz += ms->allocated_chunks_bytes(); - cls->_anon_block_sz += ms->allocated_blocks_bytes(); + if(cld->has_class_mirror_holder()) { + if (is_hidden) { + cls->_hidden_chunk_sz += ms->allocated_chunks_bytes(); + cls->_hidden_block_sz += ms->allocated_blocks_bytes(); + } else { + cls->_anon_chunk_sz += ms->allocated_chunks_bytes(); + cls->_anon_block_sz += ms->allocated_blocks_bytes(); + } } else { cls->_chunk_sz = ms->allocated_chunks_bytes(); cls->_block_sz = ms->allocated_blocks_bytes(); @@ -121,6 +139,12 @@ bool ClassLoaderStatsClosure::do_entry(oop const& key, ClassLoaderStats* const& cls->_anon_classes_count, cls->_anon_chunk_sz, cls->_anon_block_sz); } + if (cls->_hidden_classes_count > 0) { + _out->print_cr(SPACE SPACE SPACE " " UINTX_FORMAT_W(6) " " SIZE_FORMAT_W(8) " " SIZE_FORMAT_W(8) " + hidden classes", + "", "", "", + cls->_hidden_classes_count, + cls->_hidden_chunk_sz, cls->_hidden_block_sz); + } return true; } diff --git a/src/hotspot/share/classfile/classLoaderStats.hpp b/src/hotspot/share/classfile/classLoaderStats.hpp index 8e37b50a2f3..c6fac17a8be 100644 --- a/src/hotspot/share/classfile/classLoaderStats.hpp +++ b/src/hotspot/share/classfile/classLoaderStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,6 +81,10 @@ public: size_t _anon_block_sz; uintx _anon_classes_count; + size_t _hidden_chunk_sz; + size_t _hidden_block_sz; + uintx _hidden_classes_count; + ClassLoaderStats() : _cld(0), _class_loader(0), @@ -90,7 +94,10 @@ public: _classes_count(0), _anon_chunk_sz(0), _anon_block_sz(0), - _anon_classes_count(0) { + _anon_classes_count(0), + _hidden_chunk_sz(0), + _hidden_block_sz(0), + _hidden_classes_count(0) { } }; diff --git a/src/hotspot/share/classfile/defaultMethods.cpp b/src/hotspot/share/classfile/defaultMethods.cpp index 6fb83924a2a..a83f94d3644 100644 --- a/src/hotspot/share/classfile/defaultMethods.cpp +++ b/src/hotspot/share/classfile/defaultMethods.cpp @@ -918,7 +918,7 @@ static void switchover_constant_pool(BytecodeConstantPool* bpool, ConstantPool* cp = bpool->create_constant_pool(CHECK); if (cp != klass->constants()) { // Copy resolved anonymous class into new constant pool. - if (klass->is_unsafe_anonymous()) { + if (klass->is_unsafe_anonymous() || klass->is_hidden()) { cp->klass_at_put(klass->this_class_index(), klass); } klass->class_loader_data()->add_to_deallocate_list(klass->constants()); diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index abd6c68d571..686dab0973e 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -354,6 +354,7 @@ bool Dictionary::is_valid_protection_domain(unsigned int hash, // since been unreferenced, so this entry should be cleared. void Dictionary::clean_cached_protection_domains() { assert_locked_or_safepoint(SystemDictionary_lock); + assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder"); if (loader_data()->is_the_null_class_loader_data()) { // Classes in the boot loader are not loaded with protection domains @@ -482,6 +483,7 @@ void Dictionary::print_on(outputStream* st) const { ResourceMark rm; assert(loader_data() != NULL, "loader data should not be null"); + assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder"); st->print_cr("Java dictionary (table_size=%d, classes=%d, resizable=%s)", table_size(), number_of_entries(), BOOL_TO_STR(_resizable)); st->print_cr("^ indicates that initiating loader is different from defining loader"); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 8035b3ccd2d..347437f8778 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -649,9 +649,14 @@ int java_lang_String::utf8_length(oop java_string) { } char* java_lang_String::as_utf8_string(oop java_string) { - typeArrayOop value = java_lang_String::value(java_string); - int length = java_lang_String::length(java_string, value); - bool is_latin1 = java_lang_String::is_latin1(java_string); + int length; + return as_utf8_string(java_string, length); +} + +char* java_lang_String::as_utf8_string(oop java_string, int& length) { + typeArrayOop value = java_lang_String::value(java_string); + length = java_lang_String::length(java_string, value); + bool is_latin1 = java_lang_String::is_latin1(java_string); if (!is_latin1) { jchar* position = (length == 0) ? NULL : value->char_at_addr(0); return UNICODE::as_utf8(position, length); @@ -661,6 +666,29 @@ char* java_lang_String::as_utf8_string(oop java_string) { } } +// Uses a provided buffer if it's sufficiently large, otherwise allocates +// a resource array to fit +char* java_lang_String::as_utf8_string_full(oop java_string, char* buf, int buflen, int& utf8_len) { + typeArrayOop value = java_lang_String::value(java_string); + int len = java_lang_String::length(java_string, value); + bool is_latin1 = java_lang_String::is_latin1(java_string); + if (!is_latin1) { + jchar *position = (len == 0) ? NULL : value->char_at_addr(0); + utf8_len = UNICODE::utf8_length(position, len); + if (utf8_len >= buflen) { + buf = NEW_RESOURCE_ARRAY(char, utf8_len + 1); + } + return UNICODE::as_utf8(position, len, buf, utf8_len + 1); + } else { + jbyte *position = (len == 0) ? NULL : value->byte_at_addr(0); + utf8_len = UNICODE::utf8_length(position, len); + if (utf8_len >= buflen) { + buf = NEW_RESOURCE_ARRAY(char, utf8_len + 1); + } + return UNICODE::as_utf8(position, len, buf, utf8_len + 1); + } +} + char* java_lang_String::as_utf8_string(oop java_string, typeArrayOop value, char* buf, int buflen) { assert(value_equals(value, java_lang_String::value(java_string)), "value must be same as java_lang_String::value(java_string)"); @@ -852,12 +880,13 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) { k->clear_has_raw_archived_mirror(); } } - create_mirror(k, Handle(), Handle(), Handle(), CHECK); + create_mirror(k, Handle(), Handle(), Handle(), Handle(), CHECK); } void java_lang_Class::initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, + Handle classData, TRAPS) { // Allocate a simple java object for a lock. // This needs to be a java object because during class initialization @@ -870,6 +899,9 @@ void java_lang_Class::initialize_mirror_fields(Klass* k, // Initialize static fields InstanceKlass::cast(k)->do_local_static_fields(&initialize_static_field, mirror, CHECK); + + // Set classData + set_class_data(mirror(), classData()); } // Set the java.lang.Module module field in the java_lang_Class mirror @@ -923,7 +955,8 @@ void java_lang_Class::allocate_fixup_lists() { } void java_lang_Class::create_mirror(Klass* k, Handle class_loader, - Handle module, Handle protection_domain, TRAPS) { + Handle module, Handle protection_domain, + Handle classData, TRAPS) { assert(k != NULL, "Use create_basic_type_mirror for primitive types"); assert(k->java_mirror() == NULL, "should only assign mirror once"); @@ -970,7 +1003,7 @@ void java_lang_Class::create_mirror(Klass* k, Handle class_loader, } else { assert(k->is_instance_klass(), "Must be"); - initialize_mirror_fields(k, mirror, protection_domain, THREAD); + initialize_mirror_fields(k, mirror, protection_domain, classData, THREAD); if (HAS_PENDING_EXCEPTION) { // If any of the fields throws an exception like OOM remove the klass field // from the mirror so GC doesn't follow it after the klass has been deallocated. @@ -1255,16 +1288,16 @@ void java_lang_Class::update_archived_primitive_mirror_native_pointers(oop archi } void java_lang_Class::update_archived_mirror_native_pointers(oop archived_mirror) { - if (MetaspaceShared::relocation_delta() != 0) { - Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset)); - archived_mirror->metadata_field_put(_klass_offset, - (Klass*)(address(k) + MetaspaceShared::relocation_delta())); + assert(MetaspaceShared::relocation_delta() != 0, "must be"); - Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset)); - if (ak != NULL) { - archived_mirror->metadata_field_put(_array_klass_offset, - (Klass*)(address(ak) + MetaspaceShared::relocation_delta())); - } + Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset)); + archived_mirror->metadata_field_put(_klass_offset, + (Klass*)(address(k) + MetaspaceShared::relocation_delta())); + + Klass* ak = ((Klass*)archived_mirror->metadata_field(_array_klass_offset)); + if (ak != NULL) { + archived_mirror->metadata_field_put(_array_klass_offset, + (Klass*)(address(ak) + MetaspaceShared::relocation_delta())); } } @@ -1291,7 +1324,6 @@ bool java_lang_Class::restore_archived_mirror(Klass *k, // mirror is archived, restore log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); assert(HeapShared::is_archived_object(m), "must be archived mirror object"); - update_archived_mirror_native_pointers(m); assert(as_Klass(m) == k, "must be"); Handle mirror(THREAD, m); @@ -1397,6 +1429,14 @@ void java_lang_Class::set_signers(oop java_class, objArrayOop signers) { java_class->obj_field_put(_signers_offset, (oop)signers); } +oop java_lang_Class::class_data(oop java_class) { + assert(_classData_offset != 0, "must be set"); + return java_class->obj_field(_classData_offset); +} +void java_lang_Class::set_class_data(oop java_class, oop class_data) { + assert(_classData_offset != 0, "must be set"); + java_class->obj_field_put(_classData_offset, class_data); +} void java_lang_Class::set_class_loader(oop java_class, oop loader) { assert(_class_loader_offset != 0, "offsets should have been initialized"); @@ -1600,6 +1640,7 @@ int java_lang_Class::classRedefinedCount_offset = -1; macro(_component_mirror_offset, k, "componentType", class_signature, false); \ macro(_module_offset, k, "module", module_signature, false); \ macro(_name_offset, k, "name", string_signature, false); \ + macro(_classData_offset, k, "classData", object_signature, false); void java_lang_Class::compute_offsets() { if (offsets_computed) { @@ -3162,7 +3203,7 @@ oop java_lang_reflect_RecordComponent::create(InstanceKlass* holder, RecordCompo char* sig = NEW_RESOURCE_ARRAY(char, sig_len); jio_snprintf(sig, sig_len, "%c%c%s", JVM_SIGNATURE_FUNC, JVM_SIGNATURE_ENDFUNC, type->as_C_string()); TempNewSymbol full_sig = SymbolTable::new_symbol(sig); - accessor_method = holder->find_instance_method(name, full_sig); + accessor_method = holder->find_instance_method(name, full_sig, Klass::find_private); } if (accessor_method != NULL) { @@ -4268,6 +4309,7 @@ int java_lang_Class::_init_lock_offset; int java_lang_Class::_signers_offset; int java_lang_Class::_name_offset; int java_lang_Class::_source_file_offset; +int java_lang_Class::_classData_offset; GrowableArray* java_lang_Class::_fixup_mirror_list = NULL; GrowableArray* java_lang_Class::_fixup_module_field_list = NULL; int java_lang_Throwable::backtrace_offset; diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 149463578f8..7766983fa58 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,6 +168,8 @@ class java_lang_String : AllStatic { // String converters static char* as_utf8_string(oop java_string); + static char* as_utf8_string(oop java_string, int& length); + static char* as_utf8_string_full(oop java_string, char* buf, int buflen, int& length); static char* as_utf8_string(oop java_string, char* buf, int buflen); static char* as_utf8_string(oop java_string, int start, int len); static char* as_utf8_string(oop java_string, typeArrayOop value, char* buf, int buflen); @@ -263,6 +265,7 @@ class java_lang_Class : AllStatic { static int _component_mirror_offset; static int _name_offset; static int _source_file_offset; + static int _classData_offset; static bool offsets_computed; static int classRedefinedCount_offset; @@ -274,7 +277,8 @@ class java_lang_Class : AllStatic { static void set_protection_domain(oop java_class, oop protection_domain); static void set_class_loader(oop java_class, oop class_loader); static void set_component_mirror(oop java_class, oop comp_mirror); - static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, TRAPS); + static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, + Handle classData, TRAPS); static void set_mirror_module_field(Klass* K, Handle mirror, Handle module, TRAPS); public: static void allocate_fixup_lists(); @@ -282,7 +286,7 @@ class java_lang_Class : AllStatic { // Instance creation static void create_mirror(Klass* k, Handle class_loader, Handle module, - Handle protection_domain, TRAPS); + Handle protection_domain, Handle classData, TRAPS); static void fixup_mirror(Klass* k, TRAPS); static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS); static void update_archived_primitive_mirror_native_pointers(oop archived_mirror) NOT_CDS_JAVA_HEAP_RETURN; @@ -330,6 +334,8 @@ class java_lang_Class : AllStatic { static oop component_mirror(oop java_class); static objArrayOop signers(oop java_class); static void set_signers(oop java_class, objArrayOop signers); + static oop class_data(oop java_class); + static void set_class_data(oop java_class, oop classData); static oop class_loader(oop java_class); static void set_module(oop java_class, oop module); @@ -1142,16 +1148,20 @@ class java_lang_invoke_MemberName: AllStatic { // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants): enum { - MN_IS_METHOD = 0x00010000, // method (not constructor) - MN_IS_CONSTRUCTOR = 0x00020000, // constructor - MN_IS_FIELD = 0x00040000, // field - MN_IS_TYPE = 0x00080000, // nested type - MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected - MN_REFERENCE_KIND_SHIFT = 24, // refKind - MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, + MN_IS_METHOD = 0x00010000, // method (not constructor) + MN_IS_CONSTRUCTOR = 0x00020000, // constructor + MN_IS_FIELD = 0x00040000, // field + MN_IS_TYPE = 0x00080000, // nested type + MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected + MN_REFERENCE_KIND_SHIFT = 24, // refKind + MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: - MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes - MN_SEARCH_INTERFACES = 0x00200000 // walk implemented interfaces + MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes + MN_SEARCH_INTERFACES = 0x00200000, // walk implemented interfaces + MN_NESTMATE_CLASS = 0x00000001, + MN_HIDDEN_CLASS = 0x00000002, + MN_STRONG_LOADER_LINK = 0x00000004, + MN_ACCESS_VM_ANNOTATIONS = 0x00000008 }; // Accessors for code generation: diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp index 10e4a6da3ea..8efe2b0ca0c 100644 --- a/src/hotspot/share/classfile/klassFactory.cpp +++ b/src/hotspot/share/classfile/klassFactory.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,22 +79,24 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook( end_ptr - ptr, cfs->source(), ClassFileStream::verify); + ClassLoadInfo cl_info(protection_domain); ClassFileParser parser(stream, class_name, loader_data, - protection_domain, - NULL, - NULL, + &cl_info, ClassFileParser::BROADCAST, // publicity level CHECK_NULL); - InstanceKlass* new_ik = parser.create_instance_klass(true /* changed_by_loadhook */, + const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr(); + InstanceKlass* new_ik = parser.create_instance_klass(true, // changed_by_loadhook + *cl_inst_info, // dynamic_nest_host and classData CHECK_NULL); + if (cached_class_file != NULL) { new_ik->set_cached_class_file(cached_class_file); } if (class_loader.is_null()) { - ClassLoader::add_package(new_ik, path_index, THREAD); + new_ik->set_classpath_index(path_index, THREAD); } return new_ik; @@ -165,9 +167,7 @@ static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, - Handle protection_domain, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo& cl_info, TRAPS) { assert(stream != NULL, "invariant"); assert(loader_data != NULL, "invariant"); @@ -183,12 +183,15 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream, // increment counter THREAD->statistical_info().incr_define_class_count(); - // Skip this processing for VM anonymous classes - if (unsafe_anonymous_host == NULL) { + assert(!(cl_info.is_hidden() && (cl_info.unsafe_anonymous_host() != NULL)), + "hidden class has an anonymous host"); + + // Skip this processing for VM hidden or anonymous classes + if (!cl_info.is_hidden() && (cl_info.unsafe_anonymous_host() == NULL)) { stream = check_class_file_load_hook(stream, name, loader_data, - protection_domain, + cl_info.protection_domain(), &cached_class_file, CHECK_NULL); } @@ -196,14 +199,12 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream, ClassFileParser parser(stream, name, loader_data, - protection_domain, - unsafe_anonymous_host, - cp_patches, + &cl_info, ClassFileParser::BROADCAST, // publicity level CHECK_NULL); - InstanceKlass* result = parser.create_instance_klass(old_stream != stream, CHECK_NULL); - assert(result == parser.create_instance_klass(old_stream != stream, THREAD), "invariant"); + const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr(); + InstanceKlass* result = parser.create_instance_klass(old_stream != stream, *cl_inst_info, CHECK_NULL); if (result == NULL) { return NULL; diff --git a/src/hotspot/share/classfile/klassFactory.hpp b/src/hotspot/share/classfile/klassFactory.hpp index 434fcd1faeb..97d49a52294 100644 --- a/src/hotspot/share/classfile/klassFactory.hpp +++ b/src/hotspot/share/classfile/klassFactory.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ class ClassFileStream; class ClassLoaderData; +class ClassLoadInfo; template class GrowableArray; class Klass; @@ -71,9 +72,7 @@ class KlassFactory : AllStatic { static InstanceKlass* create_from_stream(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, - Handle protection_domain, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo& cl_info, TRAPS); public: static InstanceKlass* check_shared_class_file_load_hook( diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index a966c0ae4c8..e394acff3db 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ bool ModuleEntry::should_show_version() { const char* loc = location()->as_C_string(); ClassLoaderData* cld = loader_data(); + assert(!cld->has_class_mirror_holder(), "module's cld should have a ClassLoader holder not a Class holder"); if ((cld->is_the_null_class_loader_data() || cld->is_platform_class_loader_data()) && (strncmp(loc, "jrt:/java.", 10) == 0)) { return false; @@ -135,6 +136,7 @@ bool ModuleEntry::can_read(ModuleEntry* m) const { // injecting dependencies that require the default read edges for resolution. if (this->has_default_read_edges() && !m->is_named()) { ClassLoaderData* cld = m->loader_data(); + assert(!cld->has_class_mirror_holder(), "module's cld should have a ClassLoader holder not a Class holder"); if (cld->is_the_null_class_loader_data() || cld->is_system_class_loader_data()) { return true; // default read edge } diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp index ed93ce59917..9240c0ebbcb 100644 --- a/src/hotspot/share/classfile/moduleEntry.hpp +++ b/src/hotspot/share/classfile/moduleEntry.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,7 +110,7 @@ public: ClassLoaderData* loader_data() const { return _loader_data; } void set_loader_data(ClassLoaderData* cld) { - assert(!cld->is_unsafe_anonymous(), "Unexpected unsafe anonymous class loader data"); + assert(!cld->has_class_mirror_holder(), "Unexpected has_class_mirror_holder cld"); _loader_data = cld; } diff --git a/src/hotspot/share/classfile/modules.cpp b/src/hotspot/share/classfile/modules.cpp index 83b0a402587..1b09052e601 100644 --- a/src/hotspot/share/classfile/modules.cpp +++ b/src/hotspot/share/classfile/modules.cpp @@ -40,49 +40,44 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" -#include "oops/instanceKlass.hpp" -#include "runtime/arguments.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.inline.hpp" -#include "runtime/reflection.hpp" #include "utilities/stringUtils.hpp" #include "utilities/utf8.hpp" -static bool verify_module_name(const char *module_name) { - if (module_name == NULL) return false; - int len = (int)strlen(module_name); +static bool verify_module_name(const char *module_name, int len) { + assert(module_name != NULL, "invariant"); return (len > 0 && len <= Symbol::max_length()); } -bool Modules::verify_package_name(const char* package_name) { - if (package_name == NULL) return false; - int len = (int)strlen(package_name); +static bool verify_package_name(const char* package_name, int len) { + assert(package_name != NULL, "Package name derived from non-null jstring can't be NULL"); return (len > 0 && len <= Symbol::max_length() && - UTF8::is_legal_utf8((const unsigned char *)package_name, len, false) && ClassFileParser::verify_unqualified_name(package_name, len, ClassFileParser::LegalClass)); } -static char* get_module_name(oop module, TRAPS) { +static char* get_module_name(oop module, int& len, TRAPS) { oop name_oop = java_lang_Module::name(module); if (name_oop == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "Null module name"); } - char* module_name = java_lang_String::as_utf8_string(name_oop); - if (!verify_module_name(module_name)) { + char* module_name = java_lang_String::as_utf8_string(name_oop, len); + if (!verify_module_name(module_name, len)) { THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), - err_msg("Invalid module name: %s", - module_name != NULL ? module_name : "NULL")); + err_msg("Invalid module name: %s", module_name)); } return module_name; } -static const char* get_module_version(jstring version) { - if (version == NULL) { +static Symbol* as_symbol(jstring str_object) { + if (str_object == NULL) { return NULL; } - return java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version)); + int len; + char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(str_object), len); + return SymbolTable::new_symbol(str, len); } ModuleEntryTable* Modules::get_module_entry_table(Handle h_loader) { @@ -100,7 +95,7 @@ static PackageEntryTable* get_package_entry_table(Handle h_loader) { } static ModuleEntry* get_module_entry(jobject module, TRAPS) { - oop m = JNIHandles::resolve(module); + oop m = JNIHandles::resolve_non_null(module); if (!java_lang_Module::is_instance(m)) { THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "module is not an instance of type java.lang.Module"); @@ -109,10 +104,10 @@ static ModuleEntry* get_module_entry(jobject module, TRAPS) { } -static PackageEntry* get_locked_package_entry(ModuleEntry* module_entry, const char* package_name, TRAPS) { +static PackageEntry* get_locked_package_entry(ModuleEntry* module_entry, const char* package_name, int len, TRAPS) { assert(Module_lock->owned_by_self(), "should have the Module_lock"); assert(package_name != NULL, "Precondition"); - TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name); + TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, len); PackageEntryTable* package_entry_table = module_entry->loader_data()->packages(); assert(package_entry_table != NULL, "Unexpected null package entry table"); PackageEntry* package_entry = package_entry_table->locked_lookup_only(pkg_symbol); @@ -124,13 +119,10 @@ static PackageEntry* get_package_entry_by_name(Symbol* package, Handle h_loader, TRAPS) { if (package != NULL) { - ResourceMark rm(THREAD); - if (Modules::verify_package_name(package->as_C_string())) { - PackageEntryTable* const package_entry_table = - get_package_entry_table(h_loader); - assert(package_entry_table != NULL, "Unexpected null package entry table"); - return package_entry_table->lookup_only(package); - } + PackageEntryTable* const package_entry_table = + get_package_entry_table(h_loader); + assert(package_entry_table != NULL, "Unexpected null package entry table"); + return package_entry_table->lookup_only(package); } return NULL; } @@ -140,43 +132,50 @@ bool Modules::is_package_defined(Symbol* package, Handle h_loader, TRAPS) { return res != NULL; } -static void define_javabase_module(jobject module, jstring version, - jstring location, const char* const* packages, - jsize num_packages, TRAPS) { - ResourceMark rm(THREAD); +// Converts the String oop to an internal package +// Will use the provided buffer if it's sufficiently large, otherwise allocates +// a resource array +// The length of the resulting string will be assigned to utf8_len +static const char* as_internal_package(oop package_string, char* buf, int buflen, int& utf8_len) { + char* package_name = java_lang_String::as_utf8_string_full(package_string, buf, buflen, utf8_len); - Handle module_handle(THREAD, JNIHandles::resolve(module)); - - // Obtain java.base's module version - const char* module_version = get_module_version(version); - TempNewSymbol version_symbol; - if (module_version != NULL) { - version_symbol = SymbolTable::new_symbol(module_version); - } else { - version_symbol = NULL; - } - - // Obtain java.base's location - const char* module_location = NULL; - TempNewSymbol location_symbol = NULL; - if (location != NULL) { - module_location = - java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location)); - if (module_location != NULL) { - location_symbol = SymbolTable::new_symbol(module_location); + // Turn all '/'s into '.'s + for (int index = 0; index < utf8_len; index++) { + if (package_name[index] == JVM_SIGNATURE_DOT) { + package_name[index] = JVM_SIGNATURE_SLASH; } } + return package_name; +} +static void define_javabase_module(Handle module_handle, jstring version, jstring location, + objArrayHandle pkgs, int num_packages, TRAPS) { + ResourceMark rm(THREAD); + + // Obtain java.base's module version + TempNewSymbol version_symbol = as_symbol(version); + + // Obtain java.base's location + TempNewSymbol location_symbol = as_symbol(location); // Check that the packages are syntactically ok. + char buf[128]; GrowableArray* pkg_list = new GrowableArray(num_packages); for (int x = 0; x < num_packages; x++) { - const char *package_name = packages[x]; - if (!Modules::verify_package_name(package_name)) { + oop pkg_str = pkgs->obj_at(x); + + if (pkg_str == NULL || pkg_str->klass() != SystemDictionary::String_klass()) { + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Bad package name")); + } + + int package_len; + const char* package_name = as_internal_package(pkg_str, buf, sizeof(buf), package_len); + if (!verify_package_name(package_name, package_len)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name)); } - Symbol* pkg_symbol = SymbolTable::new_symbol(package_name); + Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, package_len); pkg_list->append(pkg_symbol); } @@ -237,11 +236,11 @@ static void define_javabase_module(jobject module, jstring version, ModuleEntryTable::patch_javabase_entries(module_handle); log_info(module, load)(JAVA_BASE_NAME " location: %s", - module_location != NULL ? module_location : "NULL"); + location_symbol != NULL ? location_symbol->as_C_string() : "NULL"); log_debug(module)("define_javabase_module(): Definition of module: " JAVA_BASE_NAME ", version: %s, location: %s, package #: %d", - module_version != NULL ? module_version : "NULL", - module_location != NULL ? module_location : "NULL", + version_symbol != NULL ? version_symbol->as_C_string() : "NULL", + location_symbol != NULL ? location_symbol->as_C_string() : "NULL", pkg_list->length()); // packages defined to java.base @@ -268,45 +267,37 @@ void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRA } void Modules::define_module(jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, - jsize num_packages, TRAPS) { + jstring location, jobjectArray packages, TRAPS) { ResourceMark rm(THREAD); if (module == NULL) { THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null module object"); } - if (num_packages < 0) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "num_packages must be >= 0"); - } - - if (packages == NULL && num_packages > 0) { - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), - "num_packages should be zero if packages is null"); - } - - Handle module_handle(THREAD, JNIHandles::resolve(module)); + Handle module_handle(THREAD, JNIHandles::resolve_non_null(module)); if (!java_lang_Module::is_instance(module_handle())) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "module is not an instance of type java.lang.Module"); } - char* module_name = get_module_name(module_handle(), CHECK); + int module_name_len; + char* module_name = get_module_name(module_handle(), module_name_len, CHECK); if (module_name == NULL) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Module name cannot be null"); } + // Resolve packages + objArrayHandle packages_h(THREAD, objArrayOop(JNIHandles::resolve(packages))); + int num_packages = (packages_h.is_null() ? 0 : packages_h->length()); + // Special handling of java.base definition if (strcmp(module_name, JAVA_BASE_NAME) == 0) { assert(is_open == JNI_FALSE, "java.base module cannot be open"); - define_javabase_module(module, version, location, packages, num_packages, CHECK); + define_javabase_module(module_handle, version, location, packages_h, num_packages, CHECK); return; } - const char* module_version = get_module_version(version); - oop loader = java_lang_Module::loader(module_handle()); // Make sure loader is not the jdk.internal.reflect.DelegatingClassLoader. if (loader != java_lang_ClassLoader::non_reflection_class_loader(loader)) { @@ -319,20 +310,31 @@ void Modules::define_module(jobject module, jboolean is_open, jstring version, ClassLoaderData* loader_data = SystemDictionary::register_loader(h_loader); assert(loader_data != NULL, "class loader data shouldn't be null"); + // Only modules defined to either the boot or platform class loader, can define a "java/" package. + bool java_pkg_disallowed = !h_loader.is_null() && + !SystemDictionary::is_platform_class_loader(h_loader()); + // Check that the list of packages has no duplicates and that the // packages are syntactically ok. + char buf[128]; GrowableArray* pkg_list = new GrowableArray(num_packages); for (int x = 0; x < num_packages; x++) { - const char* package_name = packages[x]; - if (!verify_package_name(package_name)) { + oop pkg_str = packages_h->obj_at(x); + if (pkg_str == NULL || pkg_str->klass() != SystemDictionary::String_klass()) { + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("Bad package name")); + } + + int package_len; + const char* package_name = as_internal_package(pkg_str, buf, sizeof(buf), package_len); + if (!verify_package_name(package_name, package_len)) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid package name: %s for module: %s", package_name, module_name)); } // Only modules defined to either the boot or platform class loader, can define a "java/" package. - if (!h_loader.is_null() && - !SystemDictionary::is_platform_class_loader(h_loader()) && + if (java_pkg_disallowed && (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 && (package_name[JAVAPKG_LEN] == JVM_SIGNATURE_SLASH || package_name[JAVAPKG_LEN] == '\0'))) { const char* class_loader_name = loader_data->loader_name_and_id(); @@ -348,7 +350,7 @@ void Modules::define_module(jobject module, jboolean is_open, jstring version, THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message); } - Symbol* pkg_symbol = SymbolTable::new_symbol(package_name); + Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, package_len); pkg_list->append(pkg_symbol); } @@ -356,28 +358,15 @@ void Modules::define_module(jobject module, jboolean is_open, jstring version, assert(module_table != NULL, "module entry table shouldn't be null"); // Create symbol* entry for module name. - TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name); + TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name, module_name_len); bool dupl_modules = false; - // Create symbol* entry for module version. - TempNewSymbol version_symbol; - if (module_version != NULL) { - version_symbol = SymbolTable::new_symbol(module_version); - } else { - version_symbol = NULL; - } + // Create symbol for module version. + TempNewSymbol version_symbol = as_symbol(version); // Create symbol* entry for module location. - const char* module_location = NULL; - TempNewSymbol location_symbol = NULL; - if (location != NULL) { - module_location = - java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location)); - if (module_location != NULL) { - location_symbol = SymbolTable::new_symbol(module_location); - } - } + TempNewSymbol location_symbol = as_symbol(location); PackageEntryTable* package_table = NULL; PackageEntry* existing_pkg = NULL; @@ -439,13 +428,13 @@ void Modules::define_module(jobject module, jboolean is_open, jstring version, } log_info(module, load)("%s location: %s", module_name, - module_location != NULL ? module_location : "NULL"); + location_symbol != NULL ? location_symbol->as_C_string() : "NULL"); LogTarget(Debug, module) lt; if (lt.is_enabled()) { LogStream ls(lt); ls.print("define_module(): creation of module: %s, version: %s, location: %s, ", - module_name, module_version != NULL ? module_version : "NULL", - module_location != NULL ? module_location : "NULL"); + module_name, version_symbol != NULL ? version_symbol->as_C_string() : "NULL", + location_symbol != NULL ? location_symbol->as_C_string() : "NULL"); loader_data->print_value_on(&ls); ls.print_cr(", package #: %d", pkg_list->length()); for (int y = 0; y < pkg_list->length(); y++) { @@ -486,7 +475,6 @@ void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Class loader must be the boot class loader"); } - Handle h_loader(THREAD, loader); log_debug(module)("set_bootloader_unnamed_module(): recording unnamed module for boot loader"); @@ -499,7 +487,8 @@ void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) { java_lang_Module::set_module_entry(module_handle(), unnamed_module); } -void Modules::add_module_exports(jobject from_module, const char* package_name, jobject to_module, TRAPS) { +void Modules::add_module_exports(jobject from_module, jstring package_name, jobject to_module, TRAPS) { + if (package_name == NULL) { THROW_MSG(vmSymbols::java_lang_NullPointerException(), "package is null"); @@ -529,9 +518,14 @@ void Modules::add_module_exports(jobject from_module, const char* package_name, } PackageEntry* package_entry = NULL; + char buf[128]; + int package_len; + + ResourceMark rm(THREAD); + const char* pkg = as_internal_package(JNIHandles::resolve_non_null(package_name), buf, sizeof(buf), package_len); { MutexLocker ml(THREAD, Module_lock); - package_entry = get_locked_package_entry(from_module_entry, package_name, CHECK); + package_entry = get_locked_package_entry(from_module_entry, pkg, package_len, CHECK); // Do nothing if modules are the same // If the package is not found we'll throw an exception later if (from_module_entry != to_module_entry && @@ -542,15 +536,13 @@ void Modules::add_module_exports(jobject from_module, const char* package_name, // Handle errors and logging outside locked section if (package_entry == NULL) { - ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Package %s not found in from_module %s", - package_name != NULL ? package_name : "", + pkg != NULL ? pkg : "", from_module_entry->name()->as_C_string())); } if (log_is_enabled(Debug, module)) { - ResourceMark rm(THREAD); log_debug(module)("add_module_exports(): package %s in module %s is exported to module %s", package_entry->name()->as_C_string(), from_module_entry->name()->as_C_string(), @@ -561,7 +553,7 @@ void Modules::add_module_exports(jobject from_module, const char* package_name, } -void Modules::add_module_exports_qualified(jobject from_module, const char* package, +void Modules::add_module_exports_qualified(jobject from_module, jstring package, jobject to_module, TRAPS) { if (to_module == NULL) { THROW_MSG(vmSymbols::java_lang_NullPointerException(), @@ -675,7 +667,7 @@ jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRA } // Export package in module to all unnamed modules. -void Modules::add_module_exports_to_all_unnamed(jobject module, const char* package_name, TRAPS) { +void Modules::add_module_exports_to_all_unnamed(jobject module, jstring package_name, TRAPS) { if (module == NULL) { THROW_MSG(vmSymbols::java_lang_NullPointerException(), "module is null"); @@ -694,10 +686,14 @@ void Modules::add_module_exports_to_all_unnamed(jobject module, const char* pack if (!module_entry->is_named() || module_entry->is_open()) return; + ResourceMark rm(THREAD); + char buf[128]; + int pkg_len; + const char* pkg = as_internal_package(JNIHandles::resolve_non_null(package_name), buf, sizeof(buf), pkg_len); PackageEntry* package_entry = NULL; { MutexLocker m1(THREAD, Module_lock); - package_entry = get_locked_package_entry(module_entry, package_name, CHECK); + package_entry = get_locked_package_entry(module_entry, pkg, pkg_len, CHECK); // Mark package as exported to all unnamed modules. if (package_entry != NULL) { @@ -707,15 +703,13 @@ void Modules::add_module_exports_to_all_unnamed(jobject module, const char* pack // Handle errors and logging outside locked section if (package_entry == NULL) { - ResourceMark rm(THREAD); THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Package %s not found in module %s", - package_name != NULL ? package_name : "", + pkg != NULL ? pkg : "", module_entry->name()->as_C_string())); } if (log_is_enabled(Debug, module)) { - ResourceMark rm(THREAD); log_debug(module)("add_module_exports_to_all_unnamed(): package %s in module" " %s is exported to all unnamed modules", package_entry->name()->as_C_string(), diff --git a/src/hotspot/share/classfile/modules.hpp b/src/hotspot/share/classfile/modules.hpp index 1c668eb9f7a..434a0cfaf23 100644 --- a/src/hotspot/share/classfile/modules.hpp +++ b/src/hotspot/share/classfile/modules.hpp @@ -37,23 +37,20 @@ public: // define_module defines a module containing the specified packages. It binds the // module to its class loader by creating the ModuleEntry record in the // ClassLoader's ModuleEntry table, and creates PackageEntry records in the class - // loader's PackageEntry table. As in JVM_DefineClass the jstring format for all - // package names must use "/" and not "." + // loader's PackageEntry table. The jstring for all package names will convert "." + // to "/" // // IllegalArgumentExceptions are thrown for the following : // * Module's Class loader is not a subclass of java.lang.ClassLoader // * Module's Class loader already has a module with that name // * Module's Class loader has already defined types for any of the module's packages // * Module_name is syntactically bad - // * Packages contains an illegal package name + // * Packages contains an illegal package name or a non-String object // * A package already exists in another module for this class loader // * Module is an unnamed module - // * num_packages is negative - // * num_packages is non-zero when packages is null // NullPointerExceptions are thrown if module is null. static void define_module(jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, - jsize num_packages, TRAPS); + jstring location, jobjectArray packages, TRAPS); // Provides the java.lang.Module for the unnamed module defined // to the boot loader. @@ -67,7 +64,7 @@ public: // This either does a qualified export of package in module from_module to module // to_module or, if to_module is null, does an unqualified export of package. - // The format for the package name must use "/' not ".". + // Any "." in the package name will be converted to "/" // // Error conditions causing IlegalArgumentException to be throw : // * Module from_module does not exist @@ -75,10 +72,10 @@ public: // * Package is not syntactically correct // * Package is not defined for from_module's class loader // * Package is not in module from_module. - static void add_module_exports(jobject from_module, const char* package, jobject to_module, TRAPS); + static void add_module_exports(jobject from_module, jstring package, jobject to_module, TRAPS); // This does a qualified export of package in module from_module to module - // to_module. The format for the package name must use "/' not ".". + // to_module. Any "." in the package name will be converted to "/" // // Error conditions causing IlegalArgumentException to be throw : // * Module from_module does not exist @@ -86,7 +83,7 @@ public: // * Package is not syntactically correct // * Package is not defined for from_module's class loader // * Package is not in module from_module. - static void add_module_exports_qualified(jobject from_module, const char* package, jobject to_module, TRAPS); + static void add_module_exports_qualified(jobject from_module, jstring package, jobject to_module, TRAPS); // add_reads_module adds module to_module to the list of modules that from_module // can read. If from_module is the same as to_module then this is a no-op. @@ -111,10 +108,7 @@ public: // If either module or package is null then NullPointerException is thrown. // If module or package is bad, or module is unnamed, or package is not in // module then IllegalArgumentException is thrown. - static void add_module_exports_to_all_unnamed(jobject module, const char* package, TRAPS); - - // Return TRUE if package_name is syntactically valid, false otherwise. - static bool verify_package_name(const char *package_name); + static void add_module_exports_to_all_unnamed(jobject module, jstring package, TRAPS); // Return TRUE iff package is defined by loader static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS); diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index 8aed61c4d35..45bb641ee95 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/resolutionErrors.hpp" +#include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" @@ -42,6 +43,18 @@ void ResolutionErrorTable::add_entry(int index, unsigned int hash, add_entry(index, entry); } +// add new entry to the table +void ResolutionErrorTable::add_entry(int index, unsigned int hash, + const constantPoolHandle& pool, int cp_index, + const char* message) +{ + assert_locked_or_safepoint(SystemDictionary_lock); + assert(!pool.is_null() && message != NULL, "adding NULL obj"); + + ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, message); + add_entry(index, entry); +} + // find entry in the table ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int hash, const constantPoolHandle& pool, int cp_index) @@ -59,9 +72,10 @@ ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int h } void ResolutionErrorEntry::set_error(Symbol* e) { - assert(e != NULL, "must set a value"); _error = e; - _error->increment_refcount(); + if (_error != NULL) { + _error->increment_refcount(); + } } void ResolutionErrorEntry::set_message(Symbol* c) { @@ -71,6 +85,10 @@ void ResolutionErrorEntry::set_message(Symbol* c) { } } +void ResolutionErrorEntry::set_nest_host_error(const char* message) { + _nest_host_error = message; +} + // create new error entry ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error, @@ -80,17 +98,35 @@ ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* po entry->set_cp_index(cp_index); entry->set_error(error); entry->set_message(message); + entry->set_nest_host_error(NULL); + + return entry; +} + +// create new nest host error entry +ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, + int cp_index, const char* message) +{ + ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable::new_entry(hash, pool); + entry->set_cp_index(cp_index); + entry->set_nest_host_error(message); + entry->set_error(NULL); + entry->set_message(NULL); return entry; } void ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) { // decrement error refcount - assert(entry->error() != NULL, "error should be set"); - entry->error()->decrement_refcount(); + if (entry->error() != NULL) { + entry->error()->decrement_refcount(); + } if (entry->message() != NULL) { entry->message()->decrement_refcount(); } + if (entry->nest_host_error() != NULL) { + FREE_C_HEAP_ARRAY(char, entry->nest_host_error()); + } Hashtable::free_entry(entry); } diff --git a/src/hotspot/share/classfile/resolutionErrors.hpp b/src/hotspot/share/classfile/resolutionErrors.hpp index 772e8df342b..932543413bf 100644 --- a/src/hotspot/share/classfile/resolutionErrors.hpp +++ b/src/hotspot/share/classfile/resolutionErrors.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,6 +46,8 @@ public: ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error, Symbol* message); + ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, + const char* message); void free_entry(ResolutionErrorEntry *entry); ResolutionErrorEntry* bucket(int i) { @@ -64,6 +66,8 @@ public: void add_entry(int index, unsigned int hash, const constantPoolHandle& pool, int which, Symbol* error, Symbol* message); + void add_entry(int index, unsigned int hash, + const constantPoolHandle& pool, int which, const char* message); // find error given the constant pool and constant pool index ResolutionErrorEntry* find_entry(int index, unsigned int hash, @@ -95,6 +99,7 @@ class ResolutionErrorEntry : public HashtableEntry { int _cp_index; Symbol* _error; Symbol* _message; + const char* _nest_host_error; public: ConstantPool* pool() const { return literal(); } @@ -108,6 +113,9 @@ class ResolutionErrorEntry : public HashtableEntry { Symbol* message() const { return _message; } void set_message(Symbol* c); + const char* nest_host_error() const { return _nest_host_error; } + void set_nest_host_error(const char* message); + ResolutionErrorEntry* next() const { return (ResolutionErrorEntry*)HashtableEntry::next(); } diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index 17dfbc9599d..c2530653191 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -459,6 +459,8 @@ Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length, void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp, int names_count, const char** names, int* lengths, int* cp_indices, unsigned int* hashValues) { + // Note that c_heap will be true for non-strong hidden classes and unsafe anonymous classes + // even if their loader is the boot loader because they will have a different cld. bool c_heap = !loader_data->is_the_null_class_loader_data(); for (int i = 0; i < names_count; i++) { const char *name = names[i]; diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index db4dcb27228..15a6f0af9b8 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -111,6 +111,46 @@ oop SystemDictionary::_java_platform_loader = NULL; const int defaultProtectionDomainCacheSize = 1009; +ClassLoadInfo::ClassLoadInfo() { + _protection_domain = Handle(); + _unsafe_anonymous_host = NULL; + _cp_patches = NULL; + _class_hidden_info._dynamic_nest_host = NULL; + _class_hidden_info._class_data = Handle(); + _is_hidden = false; + _is_strong_hidden = false; + _can_access_vm_annotations = false; +} + +ClassLoadInfo::ClassLoadInfo(Handle protection_domain) { + _protection_domain = protection_domain; + _unsafe_anonymous_host = NULL; + _cp_patches = NULL; + _class_hidden_info._dynamic_nest_host = NULL; + _class_hidden_info._class_data = Handle(); + _is_hidden = false; + _is_strong_hidden = false; + _can_access_vm_annotations = false; +} + +ClassLoadInfo::ClassLoadInfo(Handle protection_domain, + const InstanceKlass* unsafe_anonymous_host, + GrowableArray* cp_patches, + InstanceKlass* dynamic_nest_host, + Handle class_data, + bool is_hidden, + bool is_strong_hidden, + bool can_access_vm_annotations) { + _protection_domain = protection_domain; + _unsafe_anonymous_host = unsafe_anonymous_host; + _cp_patches = cp_patches; + _class_hidden_info._dynamic_nest_host = dynamic_nest_host; + _class_hidden_info._class_data = class_data; + _is_hidden = is_hidden; + _is_strong_hidden = is_strong_hidden; + _can_access_vm_annotations = can_access_vm_annotations; +} + // ---------------------------------------------------------------------------- // Java-level SystemLoader and PlatformLoader @@ -822,7 +862,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // class loaders holding the ObjectLock shouldn't find the class here InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { - // Klass is already loaded, so return it after checking/adding protection domain + // Klass is already loaded, so return it after checking/adding protection domain k = check; class_has_been_loaded = true; } @@ -982,24 +1022,36 @@ Klass* SystemDictionary::find_instance_or_array_klass(Symbol* class_name, // Note: this method is much like resolve_from_stream, but // does not publish the classes via the SystemDictionary. -// Handles unsafe_DefineAnonymousClass and redefineclasses -// RedefinedClasses do not add to the class hierarchy +// Handles Lookup.defineClass hidden, unsafe_DefineAnonymousClass +// and redefineclasses. RedefinedClasses do not add to the class hierarchy. InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name, Handle class_loader, - Handle protection_domain, ClassFileStream* st, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo& cl_info, TRAPS) { EventClassLoad class_load_start_event; ClassLoaderData* loader_data; - if (unsafe_anonymous_host != NULL) { - // Create a new CLD for an unsafe anonymous class, that uses the same class loader - // as the unsafe_anonymous_host - guarantee(unsafe_anonymous_host->class_loader() == class_loader(), "should be the same"); - loader_data = ClassLoaderData::unsafe_anonymous_class_loader_data(class_loader); + + bool is_unsafe_anon_class = cl_info.unsafe_anonymous_host() != NULL; + + if (is_unsafe_anon_class) { + // - for unsafe anonymous class: create a new CLD whith a class holder that uses + // the same class loader as the unsafe_anonymous_host. + guarantee(cl_info.unsafe_anonymous_host()->class_loader() == class_loader(), + "should be the same"); + loader_data = ClassLoaderData::has_class_mirror_holder_cld(class_loader); + } else if (cl_info.is_hidden()) { + // - for hidden classes that are not strong: create a new CLD that has a class holder and + // whose loader is the Lookup class' loader. + // - for hidden class: add the class to the Lookup class' loader's CLD. + if (!cl_info.is_strong_hidden()) { + loader_data = ClassLoaderData::has_class_mirror_holder_cld(class_loader); + } else { + // This hidden class goes into the regular CLD pool for this loader. + loader_data = register_loader(class_loader); + } } else { loader_data = ClassLoaderData::class_loader_data(class_loader()); } @@ -1015,15 +1067,16 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name, InstanceKlass* k = KlassFactory::create_from_stream(st, class_name, loader_data, - protection_domain, - unsafe_anonymous_host, - cp_patches, + cl_info, CHECK_NULL); - if (unsafe_anonymous_host != NULL && k != NULL) { - // Unsafe anonymous classes must update ClassLoaderData holder (was unsafe_anonymous_host loader) - // so that they can be unloaded when the mirror is no longer referenced. - k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror())); + if ((cl_info.is_hidden() || is_unsafe_anon_class) && k != NULL) { + // Hidden classes that are not strong and unsafe anonymous classes must update + // ClassLoaderData holder so that they can be unloaded when the mirror is no + // longer referenced. + if (!cl_info.is_strong_hidden() || is_unsafe_anon_class) { + k->class_loader_data()->initialize_holder(Handle(THREAD, k->java_mirror())); + } { MutexLocker mu_r(THREAD, Compile_lock); @@ -1036,12 +1089,14 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name, // Rewrite and patch constant pool here. k->link_class(CHECK_NULL); - if (cp_patches != NULL) { - k->constants()->patch_resolved_references(cp_patches); + if (cl_info.cp_patches() != NULL) { + k->constants()->patch_resolved_references(cl_info.cp_patches()); } // If it's anonymous, initialize it now, since nobody else will. - k->eager_initialize(CHECK_NULL); + if (is_unsafe_anon_class) { + k->eager_initialize(CHECK_NULL); + } // notify jvmti if (JvmtiExport::should_post_class_load()) { @@ -1052,7 +1107,7 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name, post_class_load_event(&class_load_start_event, k, loader_data); } } - assert(unsafe_anonymous_host != NULL || NULL == cp_patches, + assert(is_unsafe_anon_class || NULL == cl_info.cp_patches(), "cp_patches only found with unsafe_anonymous_host"); return k; @@ -1107,13 +1162,8 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name, if (st->buffer() == NULL) { return NULL; } - k = KlassFactory::create_from_stream(st, - class_name, - loader_data, - protection_domain, - NULL, // unsafe_anonymous_host - NULL, // cp_patches - CHECK_NULL); + ClassLoadInfo cl_info(protection_domain); + k = KlassFactory::create_from_stream(st, class_name, loader_data, cl_info, CHECK_NULL); } assert(k != NULL, "no klass created"); @@ -1357,7 +1407,7 @@ void SystemDictionary::load_shared_class_misc(InstanceKlass* ik, ClassLoaderData // package was loaded. if (loader_data->is_the_null_class_loader_data()) { int path_index = ik->shared_classpath_index(); - ClassLoader::add_package(ik, path_index, THREAD); + ik->set_classpath_index(path_index, THREAD); } if (DumpLoadedClassList != NULL && classlist_file->is_open()) { @@ -2327,6 +2377,42 @@ Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, } } +// Add an entry to resolution error table to record an error in resolving or +// validating a nest host. This is used to construct informative error +// messages when IllegalAccessError's occur. If an entry already exists it will +// be updated with the nest host error message. +void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool, + int which, + const char* message) { + unsigned int hash = resolution_errors()->compute_hash(pool, which); + int index = resolution_errors()->hash_to_index(hash); + { + MutexLocker ml(Thread::current(), SystemDictionary_lock); + ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); + if (entry != NULL) { + assert(entry->nest_host_error() == NULL, "Nest host error message already set!"); + entry->set_nest_host_error(message); + } else { + resolution_errors()->add_entry(index, hash, pool, which, message); + } + } +} + +// Lookup any nest host error +const char* SystemDictionary::find_nest_host_error(const constantPoolHandle& pool, int which) { + unsigned int hash = resolution_errors()->compute_hash(pool, which); + int index = resolution_errors()->hash_to_index(hash); + { + MutexLocker ml(Thread::current(), SystemDictionary_lock); + ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); + if (entry != NULL) { + return entry->nest_host_error(); + } else { + return NULL; + } + } +} + // Signature constraints ensure that callers and callees agree about // the meaning of type names in their signatures. This routine is the @@ -2456,15 +2542,16 @@ static Method* unpack_method_and_appendix(Handle mname, Method* m = java_lang_invoke_MemberName::vmtarget(mname()); if (m != NULL) { oop appendix = appendix_box->obj_at(0); - if (TraceMethodHandles) { - #ifndef PRODUCT - ttyLocker ttyl; - tty->print("Linked method=" INTPTR_FORMAT ": ", p2i(m)); - m->print(); - if (appendix != NULL) { tty->print("appendix = "); appendix->print(); } - tty->cr(); - #endif //PRODUCT + LogTarget(Info, methodhandles) lt; + if (lt.develop_is_enabled()) { + ResourceMark rm(THREAD); + LogStream ls(lt); + ls.print("Linked method=" INTPTR_FORMAT ": ", p2i(m)); + m->print_on(&ls); + if (appendix != NULL) { ls.print("appendix = "); appendix->print_on(&ls); } + ls.cr(); } + (*appendix_result) = Handle(THREAD, appendix); // the target is stored in the cpCache and if a reference to this // MemberName is dropped we need a way to make sure the diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 0af6858dd9a..e3623fa85df 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -34,6 +34,53 @@ #include "runtime/signature.hpp" #include "utilities/hashtable.hpp" +class ClassInstanceInfo : public StackObj { + private: + InstanceKlass* _dynamic_nest_host; + Handle _class_data; + + public: + ClassInstanceInfo() { + _dynamic_nest_host = NULL; + _class_data = Handle(); + } + ClassInstanceInfo(InstanceKlass* dynamic_nest_host, Handle class_data) { + _dynamic_nest_host = dynamic_nest_host; + _class_data = class_data; + } + + InstanceKlass* dynamic_nest_host() const { return _dynamic_nest_host; } + Handle class_data() const { return _class_data; } + friend class ClassLoadInfo; +}; + +class ClassLoadInfo : public StackObj { + private: + Handle _protection_domain; + const InstanceKlass* _unsafe_anonymous_host; + GrowableArray* _cp_patches; + ClassInstanceInfo _class_hidden_info; + bool _is_hidden; + bool _is_strong_hidden; + bool _can_access_vm_annotations; + + public: + ClassLoadInfo(); + ClassLoadInfo(Handle protection_domain); + ClassLoadInfo(Handle protection_domain, const InstanceKlass* unsafe_anonymous_host, + GrowableArray* cp_patches, InstanceKlass* dynamic_nest_host, + Handle class_data, bool is_hidden, bool is_strong_hidden, + bool can_access_vm_annotations); + + Handle protection_domain() const { return _protection_domain; } + const InstanceKlass* unsafe_anonymous_host() const { return _unsafe_anonymous_host; } + GrowableArray* cp_patches() const { return _cp_patches; } + const ClassInstanceInfo* class_hidden_info_ptr() const { return &_class_hidden_info; } + bool is_hidden() const { return _is_hidden; } + bool is_strong_hidden() const { return _is_strong_hidden; } + bool can_access_vm_annotations() const { return _can_access_vm_annotations; } +}; + // The dictionary in each ClassLoaderData stores all loaded classes, either // initiatied by its class loader or defined by its class loader: // @@ -271,28 +318,13 @@ public: bool is_superclass, TRAPS); - // Parse new stream. This won't update the dictionary or - // class hierarchy, simply parse the stream. Used by JVMTI RedefineClasses. - // Also used by Unsafe_DefineAnonymousClass + // Parse new stream. This won't update the dictionary or class + // hierarchy, simply parse the stream. Used by JVMTI RedefineClasses + // and by Unsafe_DefineAnonymousClass and jvm_lookup_define_class. static InstanceKlass* parse_stream(Symbol* class_name, Handle class_loader, - Handle protection_domain, ClassFileStream* st, - TRAPS) { - return parse_stream(class_name, - class_loader, - protection_domain, - st, - NULL, // unsafe_anonymous_host - NULL, // cp_patches - THREAD); - } - static InstanceKlass* parse_stream(Symbol* class_name, - Handle class_loader, - Handle protection_domain, - ClassFileStream* st, - const InstanceKlass* unsafe_anonymous_host, - GrowableArray* cp_patches, + const ClassLoadInfo& cl_info, TRAPS); // Resolve from stream (called by jni_DefineClass and JVM_DefineClass) @@ -530,6 +562,11 @@ public: Symbol** message); + // Record a nest host resolution/validation error + static void add_nest_host_error(const constantPoolHandle& pool, int which, + const char* message); + static const char* find_nest_host_error(const constantPoolHandle& pool, int which); + static ProtectionDomainCacheEntry* cache_get(Handle protection_domain); protected: diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index a6140e3381b..5b86621fc8f 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -40,6 +40,7 @@ #include "memory/allocation.hpp" #include "memory/archiveUtils.hpp" #include "memory/filemap.hpp" +#include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/oopFactory.hpp" @@ -914,7 +915,7 @@ InstanceKlass* SystemDictionaryShared::lookup_from_stream(Symbol* class_name, if (!UseSharedSpaces) { return NULL; } - if (class_name == NULL) { // don't do this for anonymous classes + if (class_name == NULL) { // don't do this for hidden and unsafe anonymous classes return NULL; } if (class_loader.is_null() || @@ -1096,9 +1097,9 @@ void SystemDictionaryShared::warn_excluded(InstanceKlass* k, const char* reason) } bool SystemDictionaryShared::should_be_excluded(InstanceKlass* k) { - if (k->class_loader_data()->is_unsafe_anonymous()) { - warn_excluded(k, "Unsafe anonymous class"); - return true; // unsafe anonymous classes are not archived, skip + if (k->is_hidden() || k->is_unsafe_anonymous()) { + warn_excluded(k, "Hidden or Unsafe anonymous class"); + return true; // hidden and unsafe anonymous classes are not archived, skip } if (k->is_in_error_state()) { warn_excluded(k, "In error state"); @@ -1541,3 +1542,52 @@ bool SystemDictionaryShared::empty_dumptime_table() { } return false; } + +#if INCLUDE_CDS_JAVA_HEAP + +class ArchivedMirrorPatcher { + static void update(Klass* k) { + if (k->has_raw_archived_mirror()) { + oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow()); + if (m != NULL) { + java_lang_Class::update_archived_mirror_native_pointers(m); + } + } + } + +public: + static void update_array_klasses(Klass* ak) { + while (ak != NULL) { + update(ak); + ak = ArrayKlass::cast(ak)->higher_dimension(); + } + } + + void do_value(const RunTimeSharedClassInfo* info) { + InstanceKlass* ik = info->_klass; + update(ik); + update_array_klasses(ik->array_klasses()); + } +}; + +void SystemDictionaryShared::update_archived_mirror_native_pointers_for(RunTimeSharedDictionary* dict) { + ArchivedMirrorPatcher patcher; + dict->iterate(&patcher); +} + +void SystemDictionaryShared::update_archived_mirror_native_pointers() { + if (!HeapShared::open_archive_heap_region_mapped()) { + return; + } + if (MetaspaceShared::relocation_delta() == 0) { + return; + } + update_archived_mirror_native_pointers_for(&_builtin_dictionary); + update_archived_mirror_native_pointers_for(&_unregistered_dictionary); + + for (int t = T_BOOLEAN; t <= T_LONG; t++) { + Klass* k = Universe::typeArrayKlassObj((BasicType)t); + ArchivedMirrorPatcher::update_array_klasses(k); + } +} +#endif diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index d1a37aff7cf..86cc9f76b9b 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -222,6 +222,7 @@ private: static bool should_be_excluded(InstanceKlass* k); DEBUG_ONLY(static bool _no_class_loading_should_happen;) + public: static InstanceKlass* find_builtin_class(Symbol* class_name); @@ -326,6 +327,13 @@ public: address p = address(ptr) - SharedBaseAddress; return primitive_hash
(p); } + +#if INCLUDE_CDS_JAVA_HEAP +private: + static void update_archived_mirror_native_pointers_for(RunTimeSharedDictionary* dict); +public: + static void update_archived_mirror_native_pointers() NOT_CDS_RETURN; +#endif }; #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index 34027a7c252..a6ac7bc906b 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -48,11 +48,16 @@ VerificationType VerificationType::from_tag(u1 tag) { bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Symbol* name, Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object, TRAPS) { HandleMark hm(THREAD); - Klass* this_class = SystemDictionary::resolve_or_fail( + Klass* this_class; + if (klass->is_hidden() && klass->name() == name) { + this_class = klass; + } else { + this_class = SystemDictionary::resolve_or_fail( name, Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); - if (log_is_enabled(Debug, class, resolve)) { - Verifier::trace_class_resolution(this_class, klass); + if (log_is_enabled(Debug, class, resolve)) { + Verifier::trace_class_resolution(this_class, klass); + } } if (this_class->is_interface() && (!from_field_is_protected || @@ -65,11 +70,16 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym this_class == SystemDictionary::Cloneable_klass() || this_class == SystemDictionary::Serializable_klass(); } else if (from_is_object) { - Klass* from_class = SystemDictionary::resolve_or_fail( + Klass* from_class; + if (klass->is_hidden() && klass->name() == from_name) { + from_class = klass; + } else { + from_class = SystemDictionary::resolve_or_fail( from_name, Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); - if (log_is_enabled(Debug, class, resolve)) { - Verifier::trace_class_resolution(from_class, klass); + if (log_is_enabled(Debug, class, resolve)) { + Verifier::trace_class_resolution(from_class, klass); + } } return from_class->is_subclass_of(this_class); } diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index e409ebf8cb9..9711662698b 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -2081,6 +2081,8 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) { oop loader = current_class()->class_loader(); oop protection_domain = current_class()->protection_domain(); + assert(name_in_supers(name, current_class()), "name should be a super class"); + Klass* kls = SystemDictionary::resolve_or_fail( name, Handle(THREAD, loader), Handle(THREAD, protection_domain), true, THREAD); diff --git a/src/hotspot/share/classfile/vmSymbols.cpp b/src/hotspot/share/classfile/vmSymbols.cpp index 51cf1279505..6aa26f285b1 100644 --- a/src/hotspot/share/classfile/vmSymbols.cpp +++ b/src/hotspot/share/classfile/vmSymbols.cpp @@ -546,6 +546,7 @@ bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) { case vmIntrinsics::_isInterface: case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: + case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_Class_cast: case vmIntrinsics::_getLength: diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 617fa7df991..94c632cf7d0 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -884,6 +884,8 @@ do_name( isArray_name, "isArray") \ do_intrinsic(_isPrimitive, java_lang_Class, isPrimitive_name, void_boolean_signature, F_RN) \ do_name( isPrimitive_name, "isPrimitive") \ + do_intrinsic(_isHidden, java_lang_Class, isHidden_name, void_boolean_signature, F_RN) \ + do_name( isHidden_name, "isHidden") \ do_intrinsic(_getSuperclass, java_lang_Class, getSuperclass_name, void_class_signature, F_RN) \ do_name( getSuperclass_name, "getSuperclass") \ do_intrinsic(_Class_cast, java_lang_Class, Class_cast_name, object_object_signature, F_R) \ diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 9425806e1a2..859c583cc35 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1036,7 +1036,7 @@ bool CodeCache::is_far_target(address target) { #endif } -#ifdef INCLUDE_JVMTI +#if INCLUDE_JVMTI // RedefineClasses support for unloading nmethods that are dependent on "old" methods. // We don't really expect this table to grow very large. If it does, it can become a hashtable. static GrowableArray* old_compiled_method_table = NULL; diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 8baa3651a81..4a3e29810f3 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -278,8 +278,8 @@ class CodeCache : AllStatic { static int mark_dependents_for_evol_deoptimization(); static void mark_all_nmethods_for_evol_deoptimization(); static void flush_evol_dependents(); - static void old_nmethods_do(MetadataClosure* f); - static void unregister_old_nmethod(CompiledMethod* c); + static void old_nmethods_do(MetadataClosure* f) NOT_JVMTI_RETURN; + static void unregister_old_nmethod(CompiledMethod* c) NOT_JVMTI_RETURN; // Support for fullspeed debugging static void flush_dependents_on_method(const methodHandle& dependee); diff --git a/src/hotspot/share/code/debugInfo.cpp b/src/hotspot/share/code/debugInfo.cpp index ebb5dd6258f..df1be93371c 100644 --- a/src/hotspot/share/code/debugInfo.cpp +++ b/src/hotspot/share/code/debugInfo.cpp @@ -97,7 +97,7 @@ ScopeValue* DebugInfoReadStream::get_cached_object() { enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1, CONSTANT_OOP_CODE = 2, CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4, OBJECT_CODE = 5, OBJECT_ID_CODE = 6, - AUTO_BOX_OBJECT_CODE = 7 }; + AUTO_BOX_OBJECT_CODE = 7, MARKER_CODE = 8 }; ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) { ScopeValue* result = NULL; @@ -110,6 +110,7 @@ ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) { case OBJECT_CODE: result = stream->read_object_value(false /*is_auto_box*/); break; case AUTO_BOX_OBJECT_CODE: result = stream->read_object_value(true /*is_auto_box*/); break; case OBJECT_ID_CODE: result = stream->get_cached_object(); break; + case MARKER_CODE: result = new MarkerValue(); break; default: ShouldNotReachHere(); } return result; @@ -130,6 +131,16 @@ void LocationValue::print_on(outputStream* st) const { location().print_on(st); } +// MarkerValue + +void MarkerValue::write_on(DebugInfoWriteStream* stream) { + stream->write_int(MARKER_CODE); +} + +void MarkerValue::print_on(outputStream* st) const { + st->print("marker"); +} + // ObjectValue void ObjectValue::set_value(oop value) { diff --git a/src/hotspot/share/code/debugInfo.hpp b/src/hotspot/share/code/debugInfo.hpp index 8f2899cd45b..dae79905a93 100644 --- a/src/hotspot/share/code/debugInfo.hpp +++ b/src/hotspot/share/code/debugInfo.hpp @@ -50,6 +50,7 @@ class ScopeValue: public ResourceObj { virtual bool is_location() const { return false; } virtual bool is_object() const { return false; } virtual bool is_auto_box() const { return false; } + virtual bool is_marker() const { return false; } virtual bool is_constant_int() const { return false; } virtual bool is_constant_double() const { return false; } virtual bool is_constant_long() const { return false; } @@ -91,6 +92,19 @@ class LocationValue: public ScopeValue { void print_on(outputStream* st) const; }; +// A placeholder value that has no concrete meaning other than helping constructing +// other values. + +class MarkerValue: public ScopeValue { +public: + bool is_marker() const { return true; } + + // Serialization of debugging information + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; // An ObjectValue describes an object eliminated by escape analysis. diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index d9c1f471ac5..04cfbc90058 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -1207,7 +1207,7 @@ class ClassHierarchyWalker { ClassHierarchyWalker wf(_participants, _num_participants); Klass* w = wf.find_witness_subtype(k); if (w != NULL) { - Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature); + Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature, Klass::skip_private); if (!Dependencies::is_concrete_method(wm, w)) { // Found a concrete subtype 'w' which does not override abstract method 'm'. // Bail out because 'm' could be called with 'w' as receiver (leading to an diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 824affb2b5f..77cf75c59fc 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -592,7 +592,7 @@ CompilerCounters::CompilerCounters() { _compile_type = CompileBroker::no_compile; } -#if INCLUDE_JFR +#if INCLUDE_JFR && COMPILER2_OR_JVMCI // It appends new compiler phase names to growable array phase_names(a new CompilerPhaseType mapping // in compiler/compilerEvent.cpp) and registers it with its serializer. // @@ -608,6 +608,7 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) { jvmci_phase_names->append("NOT_A_PHASE_NAME"); CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names); first_registration = false; +#ifdef COMPILER2 } else if (compiler_type == compiler_c2) { assert(first_registration, "invariant"); // c2 must be registered first. GrowableArray* c2_phase_names = new GrowableArray(PHASE_NUM_TYPES); @@ -616,9 +617,10 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) { } CompilerEvent::PhaseEvent::register_phases(c2_phase_names); first_registration = false; +#endif // COMPILER2 } } -#endif // INCLUDE_JFR +#endif // INCLUDE_JFR && COMPILER2_OR_JVMCI // ------------------------------------------------------------------ // CompileBroker::compilation_init diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index aebe3595476..312d9ccf182 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -242,7 +242,7 @@ void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, i jlong time_queued, jlong time_started) { if (!short_form) { // Print current time - st->print("%7d ", (int)st->time_stamp().milliseconds()); + st->print("%7d ", (int)tty->time_stamp().milliseconds()); if (Verbose && time_queued != 0) { // Print time in queue and time being processed by compiler thread jlong now = os::elapsed_counter(); diff --git a/src/hotspot/share/gc/g1/g1Analytics.cpp b/src/hotspot/share/gc/g1/g1Analytics.cpp index a36e7fb131e..d57c70a9d52 100644 --- a/src/hotspot/share/gc/g1/g1Analytics.cpp +++ b/src/hotspot/share/gc/g1/g1Analytics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,7 +79,7 @@ G1Analytics::G1Analytics(const G1Predictions* predictor) : _prev_collection_pause_end_ms(0.0), _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)), _concurrent_refine_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), - _logged_cards_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), + _dirtied_cards_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)), _young_card_merge_to_scan_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), _mixed_card_merge_to_scan_ratio_seq(new TruncatedSeq(TruncatedSeqLength)), _young_cost_per_card_scan_ms_seq(new TruncatedSeq(TruncatedSeqLength)), @@ -107,7 +107,7 @@ G1Analytics::G1Analytics(const G1Predictions* predictor) : // Start with inverse of maximum STW cost. _concurrent_refine_rate_ms_seq->add(1/cost_per_logged_card_ms_defaults[0]); // Some applications have very low rates for logging cards. - _logged_cards_rate_ms_seq->add(0.0); + _dirtied_cards_rate_ms_seq->add(0.0); _young_card_merge_to_scan_ratio_seq->add(young_card_merge_to_scan_ratio_defaults[index]); _young_cost_per_card_scan_ms_seq->add(young_only_cost_per_card_scan_ms_defaults[index]); @@ -168,8 +168,8 @@ void G1Analytics::report_concurrent_refine_rate_ms(double cards_per_ms) { _concurrent_refine_rate_ms_seq->add(cards_per_ms); } -void G1Analytics::report_logged_cards_rate_ms(double cards_per_ms) { - _logged_cards_rate_ms_seq->add(cards_per_ms); +void G1Analytics::report_dirtied_cards_rate_ms(double cards_per_ms) { + _dirtied_cards_rate_ms_seq->add(cards_per_ms); } void G1Analytics::report_cost_per_card_scan_ms(double cost_per_card_ms, bool for_young_gc) { @@ -236,8 +236,8 @@ double G1Analytics::predict_concurrent_refine_rate_ms() const { return predict_zero_bounded(_concurrent_refine_rate_ms_seq); } -double G1Analytics::predict_logged_cards_rate_ms() const { - return predict_zero_bounded(_logged_cards_rate_ms_seq); +double G1Analytics::predict_dirtied_cards_rate_ms() const { + return predict_zero_bounded(_dirtied_cards_rate_ms_seq); } double G1Analytics::predict_young_card_merge_to_scan_ratio() const { diff --git a/src/hotspot/share/gc/g1/g1Analytics.hpp b/src/hotspot/share/gc/g1/g1Analytics.hpp index f3e566155b1..2acba9f9c5b 100644 --- a/src/hotspot/share/gc/g1/g1Analytics.hpp +++ b/src/hotspot/share/gc/g1/g1Analytics.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ class G1Analytics: public CHeapObj { TruncatedSeq* _rs_length_diff_seq; TruncatedSeq* _concurrent_refine_rate_ms_seq; - TruncatedSeq* _logged_cards_rate_ms_seq; + TruncatedSeq* _dirtied_cards_rate_ms_seq; // The ratio between the number of merged cards and actually scanned cards, for // young-only and mixed gcs. TruncatedSeq* _young_card_merge_to_scan_ratio_seq; @@ -115,7 +115,7 @@ public: void report_concurrent_mark_cleanup_times_ms(double ms); void report_alloc_rate_ms(double alloc_rate); void report_concurrent_refine_rate_ms(double cards_per_ms); - void report_logged_cards_rate_ms(double cards_per_ms); + void report_dirtied_cards_rate_ms(double cards_per_ms); void report_cost_per_card_scan_ms(double cost_per_remset_card_ms, bool for_young_gc); void report_cost_per_card_merge_ms(double cost_per_card_ms, bool for_young_gc); void report_card_merge_to_scan_ratio(double cards_per_entry_ratio, bool for_young_gc); @@ -131,7 +131,7 @@ public: int num_alloc_rate_ms() const; double predict_concurrent_refine_rate_ms() const; - double predict_logged_cards_rate_ms() const; + double predict_dirtied_cards_rate_ms() const; double predict_young_card_merge_to_scan_ratio() const; double predict_mixed_card_merge_to_scan_ratio() const; diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.cpp b/src/hotspot/share/gc/g1/g1BarrierSet.cpp index 62dba813d51..9243e1f319f 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.cpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.cpp @@ -157,5 +157,5 @@ void G1BarrierSet::on_thread_detach(Thread* thread) { // Flush any deferred card marks. CardTableBarrierSet::on_thread_detach(thread); G1ThreadLocalData::satb_mark_queue(thread).flush(); - G1ThreadLocalData::dirty_card_queue(thread).flush(); + G1ThreadLocalData::dirty_card_queue(thread).on_thread_detach(); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 08ee547b9b6..45fc8ae046b 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1054,10 +1054,11 @@ void G1CollectedHeap::abort_refinement() { _hot_card_cache->reset_hot_cache(); } - // Discard all remembered set updates. + // Discard all remembered set updates and reset refinement statistics. G1BarrierSet::dirty_card_queue_set().abandon_logs(); assert(G1BarrierSet::dirty_card_queue_set().num_cards() == 0, "DCQS should be empty"); + concurrent_refine()->get_and_reset_refinement_stats(); } void G1CollectedHeap::verify_after_full_collection() { @@ -2684,9 +2685,22 @@ void G1CollectedHeap::gc_prologue(bool full) { } // Fill TLAB's and such - double start = os::elapsedTime(); - ensure_parsability(true); - phase_times()->record_prepare_tlab_time_ms((os::elapsedTime() - start) * 1000.0); + { + Ticks start = Ticks::now(); + ensure_parsability(true); + Tickspan dt = Ticks::now() - start; + phase_times()->record_prepare_tlab_time_ms(dt.seconds() * MILLIUNITS); + } + + if (!full) { + // Flush dirty card queues to qset, so later phases don't need to account + // for partially filled per-thread queues and such. Not needed for full + // collections, which ignore those logs. + Ticks start = Ticks::now(); + G1BarrierSet::dirty_card_queue_set().concatenate_logs(); + Tickspan dt = Ticks::now() - start; + phase_times()->record_concatenate_dirty_card_logs_time_ms(dt.seconds() * MILLIUNITS); + } } void G1CollectedHeap::gc_epilogue(bool full) { @@ -2759,20 +2773,6 @@ void G1CollectedHeap::do_concurrent_mark() { } } -size_t G1CollectedHeap::pending_card_num() { - struct CountCardsClosure : public ThreadClosure { - size_t _cards; - CountCardsClosure() : _cards(0) {} - virtual void do_thread(Thread* t) { - _cards += G1ThreadLocalData::dirty_card_queue(t).size(); - } - } count_from_threads; - Threads::threads_do(&count_from_threads); - - G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - return dcqs.num_cards() + count_from_threads._cards; -} - bool G1CollectedHeap::is_potential_eager_reclaim_candidate(HeapRegion* r) const { // We don't nominate objects with many remembered set entries, on // the assumption that such objects are likely still live. diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 2e542d668ed..7b2463d4c94 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1465,8 +1465,6 @@ public: // Used to print information about locations in the hs_err file. virtual bool print_location(outputStream* st, void* addr) const; - - size_t pending_card_num(); }; class G1ParEvacuateFollowersClosure : public VoidClosure { diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index ee5817dab03..2607f48a127 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -408,20 +408,18 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time, dcqs.notify_if_necessary(); } -G1ConcurrentRefine::RefinementStats G1ConcurrentRefine::total_refinement_stats() const { - struct CollectData : public ThreadClosure { - Tickspan _total_time; - size_t _total_cards; - CollectData() : _total_time(), _total_cards(0) {} +G1ConcurrentRefineStats G1ConcurrentRefine::get_and_reset_refinement_stats() { + struct CollectStats : public ThreadClosure { + G1ConcurrentRefineStats _total_stats; virtual void do_thread(Thread* t) { G1ConcurrentRefineThread* crt = static_cast(t); - _total_time += crt->total_refinement_time(); - _total_cards += crt->total_refined_cards(); + G1ConcurrentRefineStats& stats = *crt->refinement_stats(); + _total_stats += stats; + stats.reset(); } } collector; - // Cast away const so we can call non-modifying closure on threads. - const_cast(this)->threads_do(&collector); - return RefinementStats(collector._total_time, collector._total_cards); + threads_do(&collector); + return collector._total_stats; } size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const { @@ -445,7 +443,7 @@ void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_ } bool G1ConcurrentRefine::do_refinement_step(uint worker_id, - size_t* total_refined_cards) { + G1ConcurrentRefineStats* stats) { G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); size_t curr_cards = dcqs.num_cards(); @@ -460,5 +458,5 @@ bool G1ConcurrentRefine::do_refinement_step(uint worker_id, // Process the next buffer, if there are enough left. return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(), deactivation_threshold(worker_id), - total_refined_cards); + stats); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp index 8a9a041578e..3f32a5c3199 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #ifndef SHARE_GC_G1_G1CONCURRENTREFINE_HPP #define SHARE_GC_G1_G1CONCURRENTREFINE_HPP +#include "gc/g1/g1ConcurrentRefineStats.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/ticks.hpp" @@ -119,13 +120,9 @@ public: // Adjust refinement thresholds based on work done during the pause and the goal time. void adjust(double logged_cards_scan_time, size_t processed_logged_cards, double goal_ms); - struct RefinementStats { - Tickspan _time; - size_t _cards; - RefinementStats(Tickspan time, size_t cards) : _time(time), _cards(cards) {} - }; - - RefinementStats total_refinement_stats() const; + // Return total of concurrent refinement stats for the + // ConcurrentRefineThreads. Also reset the stats for the threads. + G1ConcurrentRefineStats get_and_reset_refinement_stats(); // Cards in the dirty card queue set. size_t activation_threshold(uint worker_id) const; @@ -133,8 +130,8 @@ public: // Perform a single refinement step; called by the refinement // threads. Returns true if there was refinement work available. - // Increments *total_refined_cards. - bool do_refinement_step(uint worker_id, size_t* total_refined_cards); + // Updates stats. + bool do_refinement_step(uint worker_id, G1ConcurrentRefineStats* stats); // Iterate over all concurrent refinement threads applying the given closure. void threads_do(ThreadClosure *tc); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp new file mode 100644 index 00000000000..055fd8b891d --- /dev/null +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/g1/g1ConcurrentRefineStats.hpp" + +G1ConcurrentRefineStats::G1ConcurrentRefineStats() : + _refinement_time(), + _refined_cards(0), + _precleaned_cards(0), + _dirtied_cards(0) +{} + +G1ConcurrentRefineStats& +G1ConcurrentRefineStats::operator+=(const G1ConcurrentRefineStats& other) { + _refinement_time += other._refinement_time; + _refined_cards += other._refined_cards; + _precleaned_cards += other._precleaned_cards; + _dirtied_cards += other._dirtied_cards; + return *this; +} + +template +static T clipped_sub(T x, T y) { + return (x < y) ? T() : (x - y); +} + +G1ConcurrentRefineStats& +G1ConcurrentRefineStats::operator-=(const G1ConcurrentRefineStats& other) { + _refinement_time = clipped_sub(_refinement_time, other._refinement_time); + _refined_cards = clipped_sub(_refined_cards, other._refined_cards); + _precleaned_cards = clipped_sub(_precleaned_cards, other._precleaned_cards); + _dirtied_cards = clipped_sub(_dirtied_cards, other._dirtied_cards); + return *this; +} + +void G1ConcurrentRefineStats::reset() { + *this = G1ConcurrentRefineStats(); +} diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.hpp new file mode 100644 index 00000000000..d0e17301a5f --- /dev/null +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineStats.hpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_G1_G1CONCURRENTREFINESTATS_HPP +#define SHARE_GC_G1_G1CONCURRENTREFINESTATS_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.hpp" + +// Collection of statistics for concurrent refinement processing. +// Used for collecting per-thread statistics and for summaries over a +// collection of threads. +class G1ConcurrentRefineStats : public CHeapObj { + Tickspan _refinement_time; + size_t _refined_cards; + size_t _precleaned_cards; + size_t _dirtied_cards; + +public: + G1ConcurrentRefineStats(); + + // Time spent performing concurrent refinement. + Tickspan refinement_time() const { return _refinement_time; } + + // Number of refined cards. + size_t refined_cards() const { return _refined_cards; } + + // Number of cards for which refinement was skipped because some other + // thread had already refined them. + size_t precleaned_cards() const { return _precleaned_cards; } + + // Number of cards marked dirty and in need of refinement. + size_t dirtied_cards() const { return _dirtied_cards; } + + void inc_refinement_time(Tickspan t) { _refinement_time += t; } + void inc_refined_cards(size_t cards) { _refined_cards += cards; } + void inc_precleaned_cards(size_t cards) { _precleaned_cards += cards; } + void inc_dirtied_cards(size_t cards) { _dirtied_cards += cards; } + + G1ConcurrentRefineStats& operator+=(const G1ConcurrentRefineStats& other); + G1ConcurrentRefineStats& operator-=(const G1ConcurrentRefineStats& other); + + friend G1ConcurrentRefineStats operator+(G1ConcurrentRefineStats x, + const G1ConcurrentRefineStats& y) { + return x += y; + } + + friend G1ConcurrentRefineStats operator-(G1ConcurrentRefineStats x, + const G1ConcurrentRefineStats& y) { + return x -= y; + } + + void reset(); +}; + +#endif // SHARE_GC_G1_G1CONCURRENTREFINESTATS_HPP diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp index 55a274486d7..e57617114d2 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineStats.hpp" #include "gc/g1/g1ConcurrentRefineThread.hpp" #include "gc/g1/g1DirtyCardQueue.hpp" #include "gc/shared/suspendibleThreadSet.hpp" @@ -36,8 +37,7 @@ G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint ConcurrentGCThread(), _vtime_start(0.0), _vtime_accum(0.0), - _total_refinement_time(), - _total_refined_cards(0), + _refinement_stats(new G1ConcurrentRefineStats()), _worker_id(worker_id), _notifier(new Semaphore(0)), _should_notify(true), @@ -48,6 +48,11 @@ G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint create_and_start(); } +G1ConcurrentRefineThread::~G1ConcurrentRefineThread() { + delete _refinement_stats; + delete _notifier; +} + void G1ConcurrentRefineThread::wait_for_completed_buffers() { assert(this == Thread::current(), "precondition"); while (Atomic::load_acquire(&_should_notify)) { @@ -103,32 +108,35 @@ void G1ConcurrentRefineThread::run_service() { _worker_id, _cr->activation_threshold(_worker_id), G1BarrierSet::dirty_card_queue_set().num_cards()); - size_t start_total_refined_cards = _total_refined_cards; // For logging. + // For logging. + G1ConcurrentRefineStats start_stats = *_refinement_stats; + G1ConcurrentRefineStats total_stats; // Accumulate over activation. { SuspendibleThreadSetJoiner sts_join; while (!should_terminate()) { if (sts_join.should_yield()) { + // Accumulate changed stats before possible GC that resets stats. + total_stats += *_refinement_stats - start_stats; sts_join.yield(); + // Reinitialize baseline stats after safepoint. + start_stats = *_refinement_stats; continue; // Re-check for termination after yield delay. } - Ticks start_time = Ticks::now(); - bool more_work = _cr->do_refinement_step(_worker_id, &_total_refined_cards); - _total_refinement_time += (Ticks::now() - start_time); - + bool more_work = _cr->do_refinement_step(_worker_id, _refinement_stats); if (maybe_deactivate(more_work)) break; } } + total_stats += *_refinement_stats - start_stats; log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT - ", current: " SIZE_FORMAT ", refined cards: " - SIZE_FORMAT ", total refined cards: " SIZE_FORMAT, + ", current: " SIZE_FORMAT + ", refined cards: " SIZE_FORMAT, _worker_id, _cr->deactivation_threshold(_worker_id), G1BarrierSet::dirty_card_queue_set().num_cards(), - _total_refined_cards - start_total_refined_cards, - _total_refined_cards); + total_stats.refined_cards()); if (os::supports_vtime()) { _vtime_accum = (os::elapsedVTime() - _vtime_start); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp index 428c07c4250..cdcab6b2285 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp @@ -30,6 +30,7 @@ // Forward Decl. class G1ConcurrentRefine; +class G1ConcurrentRefineStats; // One or more G1 Concurrent Refinement Threads may be active if concurrent // refinement is in progress. @@ -40,8 +41,7 @@ class G1ConcurrentRefineThread: public ConcurrentGCThread { double _vtime_start; // Initial virtual time. double _vtime_accum; // Accumulated virtual time. - Tickspan _total_refinement_time; - size_t _total_refined_cards; + G1ConcurrentRefineStats* _refinement_stats; uint _worker_id; @@ -71,12 +71,14 @@ class G1ConcurrentRefineThread: public ConcurrentGCThread { public: G1ConcurrentRefineThread(G1ConcurrentRefine* cg1r, uint worker_id); + virtual ~G1ConcurrentRefineThread(); // Activate this thread. void activate(); - Tickspan total_refinement_time() const { return _total_refinement_time; } - size_t total_refined_cards() const { return _total_refined_cards; } + G1ConcurrentRefineStats* refinement_stats() const { + return _refinement_stats; + } // Total virtual time so far. double vtime_accum() { return _vtime_accum; } diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index edd3f4e9c6a..05b51af06a2 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -26,6 +26,7 @@ #include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1CardTableEntryClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentRefineStats.hpp" #include "gc/g1/g1ConcurrentRefineThread.hpp" #include "gc/g1/g1DirtyCardQueue.hpp" #include "gc/g1/g1FreeIdSet.hpp" @@ -36,6 +37,8 @@ #include "gc/shared/suspendibleThreadSet.hpp" #include "memory/iterator.hpp" #include "runtime/atomic.hpp" +#include "runtime/mutex.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" @@ -43,22 +46,37 @@ #include "utilities/globalCounter.inline.hpp" #include "utilities/macros.hpp" #include "utilities/quickSort.hpp" +#include "utilities/ticks.hpp" G1DirtyCardQueue::G1DirtyCardQueue(G1DirtyCardQueueSet* qset) : // Dirty card queues are always active, so we create them with their // active field set to true. - PtrQueue(qset, true /* active */) + PtrQueue(qset, true /* active */), + _refinement_stats(new G1ConcurrentRefineStats()) { } G1DirtyCardQueue::~G1DirtyCardQueue() { flush(); + delete _refinement_stats; +} + +void G1DirtyCardQueue::flush() { + _refinement_stats->inc_dirtied_cards(size()); + flush_impl(); +} + +void G1DirtyCardQueue::on_thread_detach() { + assert(this == &G1ThreadLocalData::dirty_card_queue(Thread::current()), "precondition"); + flush(); + dirty_card_qset()->record_detached_refinement_stats(_refinement_stats); } void G1DirtyCardQueue::handle_completed_buffer() { assert(!is_empty(), "precondition"); + _refinement_stats->inc_dirtied_cards(size()); BufferNode* node = BufferNode::make_node_from_buffer(_buf, index()); allocate_buffer(); - dirty_card_qset()->handle_completed_buffer(node); + dirty_card_qset()->handle_completed_buffer(node, _refinement_stats); } // Assumed to be zero by concurrent threads. @@ -74,15 +92,13 @@ G1DirtyCardQueueSet::G1DirtyCardQueueSet(BufferNode::Allocator* allocator) : _process_cards_threshold(ProcessCardsThresholdNever), _max_cards(MaxCardsUnlimited), _padded_max_cards(MaxCardsUnlimited), - _mutator_refined_cards_counters(NEW_C_HEAP_ARRAY(size_t, num_par_ids(), mtGC)) + _detached_refinement_stats() { - ::memset(_mutator_refined_cards_counters, 0, num_par_ids() * sizeof(size_t)); _all_active = true; } G1DirtyCardQueueSet::~G1DirtyCardQueueSet() { abandon_completed_buffers(); - FREE_C_HEAP_ARRAY(size_t, _mutator_refined_cards_counters); } // Determines how many mutator threads can process the buffers in parallel. @@ -90,14 +106,6 @@ uint G1DirtyCardQueueSet::num_par_ids() { return (uint)os::initial_active_processor_count(); } -size_t G1DirtyCardQueueSet::total_mutator_refined_cards() const { - size_t sum = 0; - for (uint i = 0; i < num_par_ids(); ++i) { - sum += _mutator_refined_cards_counters[i]; - } - return sum; -} - void G1DirtyCardQueueSet::handle_zero_index_for_thread(Thread* t) { G1ThreadLocalData::dirty_card_queue(t).handle_zero_index(); } @@ -422,7 +430,7 @@ class G1RefineBufferedCards : public StackObj { CardTable::CardValue** const _node_buffer; const size_t _node_buffer_size; const uint _worker_id; - size_t* _total_refined_cards; + G1ConcurrentRefineStats* _stats; G1RemSet* const _g1rs; static inline int compare_card(const CardTable::CardValue* p1, @@ -472,7 +480,8 @@ class G1RefineBufferedCards : public StackObj { const size_t first_clean = dst - _node_buffer; assert(first_clean >= start && first_clean <= _node_buffer_size, "invariant"); // Discarded cards are considered as refined. - *_total_refined_cards += first_clean - start; + _stats->inc_refined_cards(first_clean - start); + _stats->inc_precleaned_cards(first_clean - start); return first_clean; } @@ -488,7 +497,7 @@ class G1RefineBufferedCards : public StackObj { _g1rs->refine_card_concurrently(_node_buffer[i], _worker_id); } _node->set_index(i); - *_total_refined_cards += i - start_index; + _stats->inc_refined_cards(i - start_index); return result; } @@ -502,12 +511,12 @@ public: G1RefineBufferedCards(BufferNode* node, size_t node_buffer_size, uint worker_id, - size_t* total_refined_cards) : + G1ConcurrentRefineStats* stats) : _node(node), _node_buffer(reinterpret_cast(BufferNode::make_buffer_from_node(node))), _node_buffer_size(node_buffer_size), _worker_id(worker_id), - _total_refined_cards(total_refined_cards), + _stats(stats), _g1rs(G1CollectedHeap::heap()->rem_set()) {} bool refine() { @@ -532,12 +541,15 @@ public: bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node, uint worker_id, - size_t* total_refined_cards) { + G1ConcurrentRefineStats* stats) { + Ticks start_time = Ticks::now(); G1RefineBufferedCards buffered_cards(node, buffer_size(), worker_id, - total_refined_cards); - return buffered_cards.refine(); + stats); + bool result = buffered_cards.refine(); + stats->inc_refinement_time(Ticks::now() - start_time); + return result; } void G1DirtyCardQueueSet::handle_refined_buffer(BufferNode* node, @@ -555,7 +567,8 @@ void G1DirtyCardQueueSet::handle_refined_buffer(BufferNode* node, } } -void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node) { +void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node, + G1ConcurrentRefineStats* stats) { enqueue_completed_buffer(new_node); // No need for mutator refinement if number of cards is below limit. @@ -574,9 +587,7 @@ void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node) { // Refine cards in buffer. uint worker_id = _free_ids.claim_par_id(); // temporarily claim an id - uint counter_index = worker_id - par_ids_start(); - size_t* counter = &_mutator_refined_cards_counters[counter_index]; - bool fully_processed = refine_buffer(node, worker_id, counter); + bool fully_processed = refine_buffer(node, worker_id, stats); _free_ids.release_par_id(worker_id); // release the id // Deal with buffer after releasing id, to let another thread use id. @@ -585,14 +596,14 @@ void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node) { bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id, size_t stop_at, - size_t* total_refined_cards) { + G1ConcurrentRefineStats* stats) { // Not enough cards to trigger processing. if (Atomic::load(&_num_cards) <= stop_at) return false; BufferNode* node = get_completed_buffer(); if (node == NULL) return false; // Didn't get a buffer to process. - bool fully_processed = refine_buffer(node, worker_id, total_refined_cards); + bool fully_processed = refine_buffer(node, worker_id, stats); handle_refined_buffer(node, fully_processed); return true; } @@ -600,12 +611,15 @@ bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id, void G1DirtyCardQueueSet::abandon_logs() { assert_at_safepoint(); abandon_completed_buffers(); + _detached_refinement_stats.reset(); // Since abandon is done only at safepoints, we can safely manipulate // these queues. struct AbandonThreadLogClosure : public ThreadClosure { virtual void do_thread(Thread* t) { - G1ThreadLocalData::dirty_card_queue(t).reset(); + G1DirtyCardQueue& dcq = G1ThreadLocalData::dirty_card_queue(t); + dcq.reset(); + dcq.refinement_stats()->reset(); } } closure; Threads::threads_do(&closure); @@ -637,6 +651,40 @@ void G1DirtyCardQueueSet::concatenate_logs() { set_max_cards(old_limit); } +G1ConcurrentRefineStats G1DirtyCardQueueSet::get_and_reset_refinement_stats() { + assert_at_safepoint(); + + // Since we're at a safepoint, there aren't any races with recording of + // detached refinement stats. In particular, there's no risk of double + // counting a thread that detaches after we've examined it but before + // we've processed the detached stats. + + // Collect and reset stats for attached threads. + struct CollectStats : public ThreadClosure { + G1ConcurrentRefineStats _total_stats; + virtual void do_thread(Thread* t) { + G1DirtyCardQueue& dcq = G1ThreadLocalData::dirty_card_queue(t); + G1ConcurrentRefineStats& stats = *dcq.refinement_stats(); + _total_stats += stats; + stats.reset(); + } + } closure; + Threads::threads_do(&closure); + + // Collect and reset stats from detached threads. + MutexLocker ml(G1DetachedRefinementStats_lock, Mutex::_no_safepoint_check_flag); + closure._total_stats += _detached_refinement_stats; + _detached_refinement_stats.reset(); + + return closure._total_stats; +} + +void G1DirtyCardQueueSet::record_detached_refinement_stats(G1ConcurrentRefineStats* stats) { + MutexLocker ml(G1DetachedRefinementStats_lock, Mutex::_no_safepoint_check_flag); + _detached_refinement_stats += *stats; + stats->reset(); +} + size_t G1DirtyCardQueueSet::max_cards() const { return _max_cards; } diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp index 375676cbf53..2b8b445154d 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp @@ -27,6 +27,7 @@ #include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1FreeIdSet.hpp" +#include "gc/g1/g1ConcurrentRefineStats.hpp" #include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" #include "memory/padded.hpp" @@ -38,6 +39,8 @@ class Thread; // A ptrQueue whose elements are "oops", pointers to object heads. class G1DirtyCardQueue: public PtrQueue { + G1ConcurrentRefineStats* _refinement_stats; + protected: virtual void handle_completed_buffer(); @@ -49,10 +52,18 @@ public: ~G1DirtyCardQueue(); // Process queue entries and release resources. - void flush() { flush_impl(); } + void flush(); inline G1DirtyCardQueueSet* dirty_card_qset() const; + G1ConcurrentRefineStats* refinement_stats() const { + return _refinement_stats; + } + + // To be called by the barrier set's on_thread_detach, to notify this + // object of the corresponding state change of its owning thread. + void on_thread_detach(); + // Compiler support. static ByteSize byte_offset_of_index() { return PtrQueue::byte_offset_of_index(); @@ -215,9 +226,7 @@ class G1DirtyCardQueueSet: public PtrQueueSet { volatile size_t _padded_max_cards; static const size_t MaxCardsUnlimited = SIZE_MAX; - // Array of cumulative dirty cards refined by mutator threads. - // Array has an entry per id in _free_ids. - size_t* _mutator_refined_cards_counters; + G1ConcurrentRefineStats _detached_refinement_stats; // Verify _num_cards == sum of cards in the completed queue. void verify_num_cards() const NOT_DEBUG_RETURN; @@ -241,9 +250,10 @@ class G1DirtyCardQueueSet: public PtrQueueSet { // is a pending yield request. The node's index is updated to exclude // the processed elements, e.g. up to the element before processing // stopped, or one past the last element if the entire buffer was - // processed. Increments *total_refined_cards by the number of cards - // processed and removed from the buffer. - bool refine_buffer(BufferNode* node, uint worker_id, size_t* total_refined_cards); + // processed. Updates stats. + bool refine_buffer(BufferNode* node, + uint worker_id, + G1ConcurrentRefineStats* stats); // Deal with buffer after a call to refine_buffer. If fully processed, // deallocate the buffer. Otherwise, record it as paused. @@ -296,26 +306,23 @@ public: // Enqueue the buffer, and optionally perform refinement by the mutator. // Mutator refinement is only done by Java threads, and only if there // are more than max_cards (possibly padded) cards in the completed - // buffers. + // buffers. Updates stats. // // Mutator refinement, if performed, stops processing a buffer if // SuspendibleThreadSet::should_yield(), recording the incompletely // processed buffer for later processing of the remainder. - void handle_completed_buffer(BufferNode* node); + void handle_completed_buffer(BufferNode* node, G1ConcurrentRefineStats* stats); // If there are more than stop_at cards in the completed buffers, pop // a buffer, refine its contents, and return true. Otherwise return - // false. + // false. Updates stats. // // Stops processing a buffer if SuspendibleThreadSet::should_yield(), // recording the incompletely processed buffer for later processing of // the remainder. - // - // Increments *total_refined_cards by the number of cards processed and - // removed from the buffer. bool refine_completed_buffer_concurrently(uint worker_id, size_t stop_at, - size_t* total_refined_cards); + G1ConcurrentRefineStats* stats); // If a full collection is happening, reset partial logs, and release // completed ones: the full collection will make them all irrelevant. @@ -324,6 +331,14 @@ public: // If any threads have partial logs, add them to the global list of logs. void concatenate_logs(); + // Return the total of mutator refinement stats for all threads. + // Also resets the stats for the threads. + // precondition: at safepoint. + G1ConcurrentRefineStats get_and_reset_refinement_stats(); + + // Accumulate refinement stats from threads that are detaching. + void record_detached_refinement_stats(G1ConcurrentRefineStats* stats); + // Threshold for mutator threads to also do refinement when there // are concurrent refinement threads. size_t max_cards() const; @@ -336,9 +351,6 @@ public: // Discard artificial increase of mutator refinement threshold. void discard_max_cards_padding(); - - // Total dirty cards refined by mutator threads. - size_t total_mutator_refined_cards() const; }; inline G1DirtyCardQueueSet* G1DirtyCardQueue::dirty_card_qset() const { diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp index 88fd9a7a7c8..feb9c033ca5 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -157,6 +157,7 @@ void G1GCPhaseTimes::reset() { _cur_string_deduplication_time_ms = 0.0; _cur_prepare_tlab_time_ms = 0.0; _cur_resize_tlab_time_ms = 0.0; + _cur_concatenate_dirty_card_logs_time_ms = 0.0; _cur_derived_pointer_table_update_time_ms = 0.0; _cur_clear_ct_time_ms = 0.0; _cur_expand_heap_time_ms = 0.0; @@ -377,6 +378,8 @@ void G1GCPhaseTimes::trace_count(const char* name, size_t value) const { double G1GCPhaseTimes::print_pre_evacuate_collection_set() const { const double sum_ms = _root_region_scan_wait_time_ms + + _cur_prepare_tlab_time_ms + + _cur_concatenate_dirty_card_logs_time_ms + _recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms + _cur_region_register_time + @@ -389,6 +392,7 @@ double G1GCPhaseTimes::print_pre_evacuate_collection_set() const { debug_time("Root Region Scan Waiting", _root_region_scan_wait_time_ms); } debug_time("Prepare TLABs", _cur_prepare_tlab_time_ms); + debug_time("Concatenate Dirty Card Logs", _cur_concatenate_dirty_card_logs_time_ms); debug_time("Choose Collection Set", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms)); debug_time("Region Register", _cur_region_register_time); if (G1EagerReclaimHumongousObjects) { diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp index 5aa46240732..98680d396f6 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,6 +143,8 @@ class G1GCPhaseTimes : public CHeapObj { double _cur_prepare_tlab_time_ms; double _cur_resize_tlab_time_ms; + double _cur_concatenate_dirty_card_logs_time_ms; + double _cur_derived_pointer_table_update_time_ms; double _cur_clear_ct_time_ms; @@ -252,6 +254,10 @@ class G1GCPhaseTimes : public CHeapObj { _cur_resize_tlab_time_ms = ms; } + void record_concatenate_dirty_card_logs_time_ms(double ms) { + _cur_concatenate_dirty_card_logs_time_ms = ms; + } + void record_derived_pointer_table_update_time(double ms) { _cur_derived_pointer_table_update_time_ms = ms; } diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index 5f18cdfba0d..c046bbc0318 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -31,6 +31,7 @@ #include "gc/g1/g1ConcurrentMark.hpp" #include "gc/g1/g1ConcurrentMarkThread.inline.hpp" #include "gc/g1/g1ConcurrentRefine.hpp" +#include "gc/g1/g1ConcurrentRefineStats.hpp" #include "gc/g1/g1CollectionSetChooser.hpp" #include "gc/g1/g1HeterogeneousHeapPolicy.hpp" #include "gc/g1/g1HotCardCache.hpp" @@ -43,7 +44,7 @@ #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/shared/gcPolicyCounters.hpp" -#include "logging/logStream.hpp" +#include "logging/log.hpp" #include "runtime/arguments.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" @@ -72,10 +73,6 @@ G1Policy::G1Policy(STWGCTimer* gc_timer) : _rs_length(0), _rs_length_prediction(0), _pending_cards_at_gc_start(0), - _pending_cards_at_prev_gc_end(0), - _total_mutator_refined_cards(0), - _total_concurrent_refined_cards(0), - _total_concurrent_refinement_time(), _bytes_allocated_in_old_since_last_gc(0), _initial_mark_to_mixed(), _collection_set(NULL), @@ -432,7 +429,7 @@ void G1Policy::record_full_collection_start() { collector_state()->set_in_young_only_phase(false); collector_state()->set_in_full_gc(true); _collection_set->clear_candidates(); - record_concurrent_refinement_data(true /* is_full_collection */); + _pending_cards_at_gc_start = 0; } void G1Policy::record_full_collection_end() { @@ -462,64 +459,62 @@ void G1Policy::record_full_collection_end() { _survivor_surv_rate_group->reset(); update_young_list_max_and_target_length(); update_rs_length_prediction(); - _pending_cards_at_prev_gc_end = _g1h->pending_card_num(); _bytes_allocated_in_old_since_last_gc = 0; record_pause(FullGC, _full_collection_start_sec, end_sec); } -void G1Policy::record_concurrent_refinement_data(bool is_full_collection) { - _pending_cards_at_gc_start = _g1h->pending_card_num(); +static void log_refinement_stats(const char* kind, const G1ConcurrentRefineStats& stats) { + log_debug(gc, refine, stats) + ("%s refinement: %.2fms, refined: " SIZE_FORMAT + ", precleaned: " SIZE_FORMAT ", dirtied: " SIZE_FORMAT, + kind, + stats.refinement_time().seconds() * MILLIUNITS, + stats.refined_cards(), + stats.precleaned_cards(), + stats.dirtied_cards()); +} - // Record info about concurrent refinement thread processing. +void G1Policy::record_concurrent_refinement_stats() { + G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); + _pending_cards_at_gc_start = dcqs.num_cards(); + + // Collect per-thread stats, mostly from mutator activity. + G1ConcurrentRefineStats mut_stats = dcqs.get_and_reset_refinement_stats(); + + // Collect specialized concurrent refinement thread stats. G1ConcurrentRefine* cr = _g1h->concurrent_refine(); - G1ConcurrentRefine::RefinementStats cr_stats = cr->total_refinement_stats(); + G1ConcurrentRefineStats cr_stats = cr->get_and_reset_refinement_stats(); - Tickspan cr_time = cr_stats._time - _total_concurrent_refinement_time; - _total_concurrent_refinement_time = cr_stats._time; + G1ConcurrentRefineStats total_stats = mut_stats + cr_stats; - size_t cr_cards = cr_stats._cards - _total_concurrent_refined_cards; - _total_concurrent_refined_cards = cr_stats._cards; + log_refinement_stats("Mutator", mut_stats); + log_refinement_stats("Concurrent", cr_stats); + log_refinement_stats("Total", total_stats); - // Don't update rate if full collection. We could be in an implicit full - // collection after a non-full collection failure, in which case there - // wasn't any mutator/cr-thread activity since last recording. And if - // we're in an explicit full collection, the time since the last GC can - // be arbitrarily short, so not a very good sample. Similarly, don't - // update the rate if the current sample is empty or time is zero. - if (!is_full_collection && (cr_cards > 0) && (cr_time > Tickspan())) { - double rate = cr_cards / (cr_time.seconds() * MILLIUNITS); + // Record the rate at which cards were refined. + // Don't update the rate if the current sample is empty or time is zero. + Tickspan refinement_time = total_stats.refinement_time(); + size_t refined_cards = total_stats.refined_cards(); + if ((refined_cards > 0) && (refinement_time > Tickspan())) { + double rate = refined_cards / (refinement_time.seconds() * MILLIUNITS); _analytics->report_concurrent_refine_rate_ms(rate); + log_debug(gc, refine, stats)("Concurrent refinement rate: %.2f cards/ms", rate); } - // Record info about mutator thread processing. - G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - size_t mut_total_cards = dcqs.total_mutator_refined_cards(); - size_t mut_cards = mut_total_cards - _total_mutator_refined_cards; - _total_mutator_refined_cards = mut_total_cards; - // Record mutator's card logging rate. - // Don't update if full collection; see above. - if (!is_full_collection) { - size_t total_cards = _pending_cards_at_gc_start + cr_cards + mut_cards; - assert(_pending_cards_at_prev_gc_end <= total_cards, - "untracked cards: last pending: " SIZE_FORMAT - ", pending: " SIZE_FORMAT ", conc refine: " SIZE_FORMAT - ", mut refine:" SIZE_FORMAT, - _pending_cards_at_prev_gc_end, _pending_cards_at_gc_start, - cr_cards, mut_cards); - size_t logged_cards = total_cards - _pending_cards_at_prev_gc_end; - double logging_start_time = _analytics->prev_collection_pause_end_ms(); - double logging_end_time = Ticks::now().seconds() * MILLIUNITS; - double logging_time = logging_end_time - logging_start_time; - // Unlike above for conc-refine rate, here we should not require a - // non-empty sample, since an application could go some time with only - // young-gen or filtered out writes. But we'll ignore unusually short - // sample periods, as they may just pollute the predictions. - if (logging_time > 1.0) { // Require > 1ms sample time. - _analytics->report_logged_cards_rate_ms(logged_cards / logging_time); - } + double mut_start_time = _analytics->prev_collection_pause_end_ms(); + double mut_end_time = phase_times()->cur_collection_start_sec() * MILLIUNITS; + double mut_time = mut_end_time - mut_start_time; + // Unlike above for conc-refine rate, here we should not require a + // non-empty sample, since an application could go some time with only + // young-gen or filtered out writes. But we'll ignore unusually short + // sample periods, as they may just pollute the predictions. + if (mut_time > 1.0) { // Require > 1ms sample time. + double dirtied_rate = total_stats.dirtied_cards() / mut_time; + _analytics->report_dirtied_cards_rate_ms(dirtied_rate); + log_debug(gc, refine, stats)("Generate dirty cards rate: %.2f cards/ms", dirtied_rate); } } @@ -536,7 +531,7 @@ void G1Policy::record_collection_pause_start(double start_time_sec) { phase_times()->record_cur_collection_start_sec(start_time_sec); - record_concurrent_refinement_data(false /* is_full_collection */); + record_concurrent_refinement_stats(); _collection_set->reset_bytes_used_before(); @@ -830,7 +825,6 @@ void G1Policy::record_collection_pause_end(double pause_time_ms) { scan_logged_cards_time_goal_ms -= merge_hcc_time_ms; } - _pending_cards_at_prev_gc_end = _g1h->pending_card_num(); double const logged_cards_time = logged_cards_processing_time(); log_debug(gc, ergo, refine)("Concurrent refinement times: Logged Cards Scan time goal: %1.2fms Logged Cards Scan time: %1.2fms HCC time: %1.2fms", diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp index 2535635b0f1..b52a9f7013d 100644 --- a/src/hotspot/share/gc/g1/g1Policy.hpp +++ b/src/hotspot/share/gc/g1/g1Policy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,10 +101,6 @@ class G1Policy: public CHeapObj { size_t _rs_length_prediction; size_t _pending_cards_at_gc_start; - size_t _pending_cards_at_prev_gc_end; - size_t _total_mutator_refined_cards; - size_t _total_concurrent_refined_cards; - Tickspan _total_concurrent_refinement_time; // The amount of allocated bytes in old gen during the last mutator and the following // young GC phase. @@ -287,7 +283,8 @@ private: // Indicate that we aborted marking before doing any mixed GCs. void abort_time_to_mixed_tracking(); - void record_concurrent_refinement_data(bool is_full_collection); + // Record and log stats before not-full collection. + void record_concurrent_refinement_stats(); public: diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index e89919107b7..cc2fbbe7295 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -910,9 +910,6 @@ void G1RemSet::prepare_region_for_scan(HeapRegion* region) { } void G1RemSet::prepare_for_scan_heap_roots() { - G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - dcqs.concatenate_logs(); - _scan_state->prepare(); } diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index f78971fcc5f..6c06e3d8dff 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,12 +47,10 @@ void G1RemSetSummary::update() { G1ConcurrentRefineThread* crt = static_cast(t); _summary->set_rs_thread_vtime(_counter, crt->vtime_accum()); _counter++; - _summary->_total_concurrent_refined_cards += crt->total_refined_cards(); } } collector(this); G1CollectedHeap* g1h = G1CollectedHeap::heap(); g1h->concurrent_refine()->threads_do(&collector); - _total_mutator_refined_cards = G1BarrierSet::dirty_card_queue_set().total_mutator_refined_cards(); _num_coarsenings = HeapRegionRemSet::n_coarsenings(); set_sampling_thread_vtime(g1h->sampling_thread()->vtime_accum()); @@ -71,8 +69,6 @@ double G1RemSetSummary::rs_thread_vtime(uint thread) const { } G1RemSetSummary::G1RemSetSummary(bool should_update) : - _total_mutator_refined_cards(0), - _total_concurrent_refined_cards(0), _num_coarsenings(0), _num_vtimes(G1ConcurrentRefine::max_num_threads()), _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)), @@ -93,9 +89,6 @@ void G1RemSetSummary::set(G1RemSetSummary* other) { assert(other != NULL, "just checking"); assert(_num_vtimes == other->_num_vtimes, "just checking"); - _total_mutator_refined_cards = other->total_mutator_refined_cards(); - _total_concurrent_refined_cards = other->total_concurrent_refined_cards(); - _num_coarsenings = other->num_coarsenings(); memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes); @@ -107,9 +100,6 @@ void G1RemSetSummary::subtract_from(G1RemSetSummary* other) { assert(other != NULL, "just checking"); assert(_num_vtimes == other->_num_vtimes, "just checking"); - _total_mutator_refined_cards = other->total_mutator_refined_cards() - _total_mutator_refined_cards; - _total_concurrent_refined_cards = other->total_concurrent_refined_cards() - _total_concurrent_refined_cards; - _num_coarsenings = other->num_coarsenings() - _num_coarsenings; for (uint i = 0; i < _num_vtimes; i++) { @@ -330,14 +320,6 @@ public: }; void G1RemSetSummary::print_on(outputStream* out) { - out->print_cr(" Recent concurrent refinement statistics"); - out->print_cr(" Of " SIZE_FORMAT " refined cards:", total_refined_cards()); - out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) by concurrent refinement threads.", - total_concurrent_refined_cards(), - percent_of(total_concurrent_refined_cards(), total_refined_cards())); - out->print_cr(" " SIZE_FORMAT_W(8) " (%5.1f%%) by mutator threads.", - total_mutator_refined_cards(), - percent_of(total_mutator_refined_cards(), total_refined_cards())); out->print_cr(" Did " SIZE_FORMAT " coarsenings.", num_coarsenings()); out->print_cr(" Concurrent refinement threads times (s)"); out->print(" "); diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.hpp b/src/hotspot/share/gc/g1/g1RemSetSummary.hpp index fea8d4e489c..4208bd32b5c 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.hpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,10 +33,6 @@ class G1RemSet; // A G1RemSetSummary manages statistical information about the G1RemSet class G1RemSetSummary { -private: - size_t _total_mutator_refined_cards; - size_t _total_concurrent_refined_cards; - size_t _num_coarsenings; size_t _num_vtimes; @@ -70,18 +66,6 @@ public: return _sampling_thread_vtime; } - size_t total_mutator_refined_cards() const { - return _total_mutator_refined_cards; - } - - size_t total_concurrent_refined_cards() const { - return _total_concurrent_refined_cards; - } - - size_t total_refined_cards() const { - return total_mutator_refined_cards() + total_concurrent_refined_cards(); - } - size_t num_coarsenings() const { return _num_coarsenings; } diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp index 8f8e2e17fca..f3e8de03ab2 100644 --- a/src/hotspot/share/gc/g1/heapRegionManager.cpp +++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp @@ -342,17 +342,19 @@ bool HeapRegionManager::is_on_preferred_index(uint region_index, uint preferred_ return region_node_index == preferred_node_index; } -void HeapRegionManager::guarantee_contiguous_range(uint start, uint num_regions) { +#ifdef ASSERT +void HeapRegionManager::assert_contiguous_range(uint start, uint num_regions) { // General sanity check, regions found should either be available and empty // or not available so that we can make them available and use them. for (uint i = start; i < (start + num_regions); i++) { HeapRegion* hr = _regions.get_by_index(i); - guarantee(!is_available(i) || hr->is_free(), - "Found region sequence starting at " UINT32_FORMAT ", length " UINT32_FORMAT - " that is not free at " UINT32_FORMAT ". Hr is " PTR_FORMAT ", type is %s", - start, num_regions, i, p2i(hr), hr->get_type_str()); + assert(!is_available(i) || hr->is_free(), + "Found region sequence starting at " UINT32_FORMAT ", length " UINT32_FORMAT + " that is not free at " UINT32_FORMAT ". Hr is " PTR_FORMAT ", type is %s", + start, num_regions, i, p2i(hr), hr->get_type_str()); } } +#endif uint HeapRegionManager::find_contiguous_in_range(uint start, uint end, uint num_regions) { assert(start <= end, "precondition"); @@ -372,7 +374,7 @@ uint HeapRegionManager::find_contiguous_in_range(uint start, uint end, uint num_ break; } else if (i == unchecked) { // All regions of candidate sequence have passed check. - guarantee_contiguous_range(candidate, num_regions); + assert_contiguous_range(candidate, num_regions); return candidate; } } diff --git a/src/hotspot/share/gc/g1/heapRegionManager.hpp b/src/hotspot/share/gc/g1/heapRegionManager.hpp index d1ce9247869..010f3865b19 100644 --- a/src/hotspot/share/gc/g1/heapRegionManager.hpp +++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp @@ -105,7 +105,7 @@ class HeapRegionManager: public CHeapObj { // start index of that set, or G1_NO_HRM_INDEX. uint find_contiguous_allow_expand(uint num_regions); - void guarantee_contiguous_range(uint start, uint num_regions) ; + void assert_contiguous_range(uint start, uint num_regions) NOT_DEBUG_RETURN; // Finds the next sequence of unavailable regions starting from start_idx. Returns the // length of the sequence found. If this result is zero, no such sequence could be found, diff --git a/src/hotspot/share/gc/parallel/adjoiningGenerations.cpp b/src/hotspot/share/gc/parallel/adjoiningGenerations.cpp deleted file mode 100644 index 80bd5446dfc..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningGenerations.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/adjoiningGenerations.hpp" -#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp" -#include "gc/parallel/adjoiningVirtualSpaces.hpp" -#include "gc/parallel/parallelScavengeHeap.hpp" -#include "gc/parallel/parallelArguments.hpp" -#include "gc/shared/genArguments.hpp" -#include "logging/log.hpp" -#include "logging/logStream.hpp" -#include "memory/resourceArea.hpp" -#include "utilities/align.hpp" -#include "utilities/ostream.hpp" - -// If boundary moving is being used, create the young gen and old -// gen with ASPSYoungGen and ASPSOldGen, respectively. Revert to -// the old behavior otherwise (with PSYoungGen and PSOldGen). - -AdjoiningGenerations::AdjoiningGenerations(ReservedSpace old_young_rs) : - _virtual_spaces(new AdjoiningVirtualSpaces(old_young_rs, MinOldSize, - MinNewSize, GenAlignment)) { - size_t init_low_byte_size = OldSize; - size_t min_low_byte_size = MinOldSize; - size_t max_low_byte_size = MaxOldSize; - size_t init_high_byte_size = NewSize; - size_t min_high_byte_size = MinNewSize; - size_t max_high_byte_size = MaxNewSize; - - assert(min_low_byte_size <= init_low_byte_size && - init_low_byte_size <= max_low_byte_size, "Parameter check"); - assert(min_high_byte_size <= init_high_byte_size && - init_high_byte_size <= max_high_byte_size, "Parameter check"); - // Create the generations differently based on the option to - // move the boundary. - if (UseAdaptiveGCBoundary) { - // Initialize the adjoining virtual spaces. Then pass the - // a virtual to each generation for initialization of the - // generation. - - // Does the actual creation of the virtual spaces - _virtual_spaces->initialize(max_low_byte_size, - init_low_byte_size, - init_high_byte_size); - - // Place the young gen at the high end. Passes in the virtual space. - _young_gen = new ASPSYoungGen(_virtual_spaces->high(), - _virtual_spaces->high()->committed_size(), - min_high_byte_size, - _virtual_spaces->high_byte_size_limit()); - - // Place the old gen at the low end. Passes in the virtual space. - _old_gen = new ASPSOldGen(_virtual_spaces->low(), - _virtual_spaces->low()->committed_size(), - min_low_byte_size, - _virtual_spaces->low_byte_size_limit(), - "old", 1); - - young_gen()->initialize_work(); - assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(), - "Consistency check"); - assert(old_young_rs.size() >= young_gen()->gen_size_limit(), - "Consistency check"); - - old_gen()->initialize_work("old", 1); - assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(), - "Consistency check"); - assert(old_young_rs.size() >= old_gen()->gen_size_limit(), - "Consistency check"); - } else { - - // Layout the reserved space for the generations. - // If OldGen is allocated on nv-dimm, we need to split the reservation (this is required for windows). - ReservedSpace old_rs = - virtual_spaces()->reserved_space().first_part(max_low_byte_size, ParallelArguments::is_heterogeneous_heap() /* split */); - ReservedSpace heap_rs = - virtual_spaces()->reserved_space().last_part(max_low_byte_size); - ReservedSpace young_rs = heap_rs.first_part(max_high_byte_size); - assert(young_rs.size() == heap_rs.size(), "Didn't reserve all of the heap"); - - // Create the generations. Virtual spaces are not passed in. - _young_gen = new PSYoungGen(init_high_byte_size, - min_high_byte_size, - max_high_byte_size); - _old_gen = new PSOldGen(init_low_byte_size, - min_low_byte_size, - max_low_byte_size, - "old", 1); - - // The virtual spaces are created by the initialization of the gens. - _young_gen->initialize(young_rs, GenAlignment); - assert(young_gen()->gen_size_limit() == young_rs.size(), - "Consistency check"); - _old_gen->initialize(old_rs, GenAlignment, "old", 1); - assert(old_gen()->gen_size_limit() == old_rs.size(), "Consistency check"); - } -} - -AdjoiningGenerations::AdjoiningGenerations(): _young_gen(NULL), _old_gen(NULL), _virtual_spaces(NULL) { } - -size_t AdjoiningGenerations::reserved_byte_size() { - return virtual_spaces()->reserved_space().size(); -} - -void log_before_expansion(bool old, size_t expand_in_bytes, size_t change_in_bytes, size_t max_size) { - Log(gc, ergo, heap) log; - if (!log.is_debug()) { - return; - } - log.debug("Before expansion of %s gen with boundary move", old ? "old" : "young"); - log.debug(" Requested change: " SIZE_FORMAT_HEX " Attempted change: " SIZE_FORMAT_HEX, - expand_in_bytes, change_in_bytes); - ResourceMark rm; - LogStream ls(log.debug()); - ParallelScavengeHeap::heap()->print_on(&ls); - log.debug(" PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K); -} - -void log_after_expansion(bool old, size_t max_size) { - Log(gc, ergo, heap) log; - if (!log.is_debug()) { - return; - } - log.debug("After expansion of %s gen with boundary move", old ? "old" : "young"); - ResourceMark rm; - LogStream ls(log.debug()); - ParallelScavengeHeap::heap()->print_on(&ls); - log.debug(" PS%sGen max size: " SIZE_FORMAT "K", old ? "Old" : "Young", max_size/K); -} - -// Make checks on the current sizes of the generations and -// the constraints on the sizes of the generations. Push -// up the boundary within the constraints. A partial -// push can occur. -void AdjoiningGenerations::request_old_gen_expansion(size_t expand_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - - assert_lock_strong(ExpandHeap_lock); - assert_locked_or_safepoint(Heap_lock); - - // These sizes limit the amount the boundaries can move. Effectively, - // the generation says how much it is willing to yield to the other - // generation. - const size_t young_gen_available = young_gen()->available_for_contraction(); - const size_t old_gen_available = old_gen()->available_for_expansion(); - const size_t alignment = virtual_spaces()->alignment(); - size_t change_in_bytes = MIN3(young_gen_available, - old_gen_available, - align_up(expand_in_bytes, alignment)); - - if (change_in_bytes == 0) { - return; - } - - log_before_expansion(true, expand_in_bytes, change_in_bytes, old_gen()->max_gen_size()); - - // Move the boundary between the generations up (smaller young gen). - if (virtual_spaces()->adjust_boundary_up(change_in_bytes)) { - young_gen()->reset_after_change(); - old_gen()->reset_after_change(); - } - - // The total reserved for the generations should match the sum - // of the two even if the boundary is moving. - assert(reserved_byte_size() == - old_gen()->max_gen_size() + young_gen()->max_size(), - "Space is missing"); - young_gen()->space_invariants(); - old_gen()->space_invariants(); - - log_after_expansion(true, old_gen()->max_gen_size()); -} - -// See comments on request_old_gen_expansion() -bool AdjoiningGenerations::request_young_gen_expansion(size_t expand_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - - // If eden is not empty, the boundary can be moved but no advantage - // can be made of the move since eden cannot be moved. - if (!young_gen()->eden_space()->is_empty()) { - return false; - } - - - bool result = false; - const size_t young_gen_available = young_gen()->available_for_expansion(); - const size_t old_gen_available = old_gen()->available_for_contraction(); - const size_t alignment = virtual_spaces()->alignment(); - size_t change_in_bytes = MIN3(young_gen_available, - old_gen_available, - align_up(expand_in_bytes, alignment)); - - if (change_in_bytes == 0) { - return false; - } - - log_before_expansion(false, expand_in_bytes, change_in_bytes, young_gen()->max_size()); - - // Move the boundary between the generations down (smaller old gen). - MutexLocker x(ExpandHeap_lock); - if (virtual_spaces()->adjust_boundary_down(change_in_bytes)) { - young_gen()->reset_after_change(); - old_gen()->reset_after_change(); - result = true; - } - - // The total reserved for the generations should match the sum - // of the two even if the boundary is moving. - assert(reserved_byte_size() == - old_gen()->max_gen_size() + young_gen()->max_size(), - "Space is missing"); - young_gen()->space_invariants(); - old_gen()->space_invariants(); - - log_after_expansion(false, young_gen()->max_size()); - - return result; -} - -// Additional space is needed in the old generation. Try to move the boundary -// up to meet the need. Moves boundary up only -void AdjoiningGenerations::adjust_boundary_for_old_gen_needs( - size_t desired_free_space) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - - // Stress testing. - if (PSAdaptiveSizePolicyResizeVirtualSpaceAlot == 1) { - MutexLocker x(ExpandHeap_lock); - request_old_gen_expansion(virtual_spaces()->alignment() * 3 / 2); - } - - // Expand only if the entire generation is already committed. - if (old_gen()->virtual_space()->uncommitted_size() == 0) { - if (old_gen()->free_in_bytes() < desired_free_space) { - MutexLocker x(ExpandHeap_lock); - request_old_gen_expansion(desired_free_space); - } - } -} - -// See comment on adjust_boundary_for_old_gen_needss(). -// Adjust boundary down only. -void AdjoiningGenerations::adjust_boundary_for_young_gen_needs(size_t eden_size, - size_t survivor_size) { - - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - - // Stress testing. - if (PSAdaptiveSizePolicyResizeVirtualSpaceAlot == 0) { - request_young_gen_expansion(virtual_spaces()->alignment() * 3 / 2); - eden_size = young_gen()->eden_space()->capacity_in_bytes(); - } - - // Expand only if the entire generation is already committed. - if (young_gen()->virtual_space()->uncommitted_size() == 0) { - size_t desired_size = eden_size + 2 * survivor_size; - const size_t committed = young_gen()->virtual_space()->committed_size(); - if (desired_size > committed) { - request_young_gen_expansion(desired_size - committed); - } - } -} - -AdjoiningGenerations* AdjoiningGenerations::create_adjoining_generations(ReservedSpace old_young_rs) { - if (ParallelArguments::is_heterogeneous_heap() && UseAdaptiveGCBoundary) { - return new AdjoiningGenerationsForHeteroHeap(old_young_rs); - } else { - return new AdjoiningGenerations(old_young_rs); - } -} diff --git a/src/hotspot/share/gc/parallel/adjoiningGenerations.hpp b/src/hotspot/share/gc/parallel/adjoiningGenerations.hpp deleted file mode 100644 index c70ed10055b..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningGenerations.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_ADJOININGGENERATIONS_HPP -#define SHARE_GC_PARALLEL_ADJOININGGENERATIONS_HPP - -#include "gc/parallel/adjoiningVirtualSpaces.hpp" -#include "gc/parallel/asPSOldGen.hpp" -#include "gc/parallel/asPSYoungGen.hpp" - - -// Contains two generations that both use an AdjoiningVirtualSpaces. -// The two generations are adjacent in the reserved space for the -// heap. Each generation has a virtual space and shrinking and -// expanding of the generations can still be down with that -// virtual space as was previously done. If expanding of reserved -// size of a generation is required, the adjacent generation -// must be shrunk. Adjusting the boundary between the generations -// is called for in this class. - -class AdjoiningGenerations : public CHeapObj { - friend class VMStructs; - private: - // Move boundary up to expand old gen. Checks are made to - // determine if the move can be done with specified limits. - void request_old_gen_expansion(size_t desired_change_in_bytes); - // Move boundary down to expand young gen. - bool request_young_gen_expansion(size_t desired_change_in_bytes); - - protected: - AdjoiningGenerations(); - // The young generation and old generation, respectively - PSYoungGen* _young_gen; - PSOldGen* _old_gen; - - // The spaces used by the two generations. - AdjoiningVirtualSpaces* _virtual_spaces; - - public: - AdjoiningGenerations(ReservedSpace rs); - - // Accessors - PSYoungGen* young_gen() { return _young_gen; } - PSOldGen* old_gen() { return _old_gen; } - - AdjoiningVirtualSpaces* virtual_spaces() { return _virtual_spaces; } - - // Additional space is needed in the old generation. Check - // the available space and attempt to move the boundary if more space - // is needed. The growth is not guaranteed to occur. - void adjust_boundary_for_old_gen_needs(size_t desired_change_in_bytes); - // Similarly for a growth of the young generation. - void adjust_boundary_for_young_gen_needs(size_t eden_size, size_t survivor_size); - - // Return the total byte size of the reserved space - // for the adjoining generations. - virtual size_t reserved_byte_size(); - - // Return new AdjoiningGenerations instance based on arguments (specifically - whether heap is heterogeneous). - static AdjoiningGenerations* create_adjoining_generations(ReservedSpace rs); -}; -#endif // SHARE_GC_PARALLEL_ADJOININGGENERATIONS_HPP diff --git a/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.cpp b/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.cpp deleted file mode 100644 index a2d69a71e5b..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp" -#include "gc/parallel/adjoiningVirtualSpaces.hpp" -#include "gc/parallel/parallelArguments.hpp" -#include "gc/parallel/parallelScavengeHeap.hpp" -#include "gc/parallel/psFileBackedVirtualspace.hpp" -#include "logging/log.hpp" -#include "logging/logStream.hpp" -#include "memory/resourceArea.hpp" -#include "utilities/align.hpp" -#include "utilities/ostream.hpp" - -// Create two virtual spaces (HeteroVirtualSpaces), low() on nv-dimm memory, high() on dram. -// create ASPSOldGen and ASPSYoungGen the same way as in base class - -AdjoiningGenerationsForHeteroHeap::AdjoiningGenerationsForHeteroHeap(ReservedSpace old_young_rs) : - _total_size_limit(ParallelArguments::heap_max_size_bytes()) { - size_t init_old_byte_size = OldSize; - size_t min_old_byte_size = MinOldSize; - size_t max_old_byte_size = MaxOldSize; - size_t init_young_byte_size = NewSize; - size_t min_young_byte_size = MinNewSize; - size_t max_young_byte_size = MaxNewSize; - // create HeteroVirtualSpaces which is composed of non-overlapping virtual spaces. - HeteroVirtualSpaces* hetero_virtual_spaces = new HeteroVirtualSpaces(old_young_rs, min_old_byte_size, - min_young_byte_size, _total_size_limit); - - assert(min_old_byte_size <= init_old_byte_size && - init_old_byte_size <= max_old_byte_size, "Parameter check"); - assert(min_young_byte_size <= init_young_byte_size && - init_young_byte_size <= max_young_byte_size, "Parameter check"); - - assert(UseAdaptiveGCBoundary, "Should be used only when UseAdaptiveGCBoundary is true"); - - // Initialize the virtual spaces. Then pass a virtual space to each generation - // for initialization of the generation. - - // Does the actual creation of the virtual spaces - hetero_virtual_spaces->initialize(max_old_byte_size, init_old_byte_size, init_young_byte_size); - - _young_gen = new ASPSYoungGen(hetero_virtual_spaces->high(), - hetero_virtual_spaces->high()->committed_size() /* intial_size */, - min_young_byte_size, - hetero_virtual_spaces->max_young_size()); - - _old_gen = new ASPSOldGen(hetero_virtual_spaces->low(), - hetero_virtual_spaces->low()->committed_size() /* intial_size */, - min_old_byte_size, - hetero_virtual_spaces->max_old_size(), "old", 1); - - young_gen()->initialize_work(); - assert(young_gen()->reserved().byte_size() <= young_gen()->gen_size_limit(), "Consistency check"); - assert(old_young_rs.size() >= young_gen()->gen_size_limit(), "Consistency check"); - - old_gen()->initialize_work("old", 1); - assert(old_gen()->reserved().byte_size() <= old_gen()->gen_size_limit(), "Consistency check"); - assert(old_young_rs.size() >= old_gen()->gen_size_limit(), "Consistency check"); - - _virtual_spaces = hetero_virtual_spaces; -} - -size_t AdjoiningGenerationsForHeteroHeap::required_reserved_memory() { - // This is the size that young gen can grow to, when AdaptiveGCBoundary is true. - size_t max_yg_size = ParallelArguments::heap_max_size_bytes() - MinOldSize; - // This is the size that old gen can grow to, when AdaptiveGCBoundary is true. - size_t max_old_size = ParallelArguments::heap_max_size_bytes() - MinNewSize; - - return max_yg_size + max_old_size; -} - -// We override this function since size of reservedspace here is more than heap size and -// callers expect this function to return heap size. -size_t AdjoiningGenerationsForHeteroHeap::reserved_byte_size() { - return total_size_limit(); -} - -AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::HeteroVirtualSpaces(ReservedSpace rs, size_t min_old_byte_size, size_t min_yg_byte_size, size_t max_total_size) : - AdjoiningVirtualSpaces(rs, min_old_byte_size, min_yg_byte_size, GenAlignment), - _max_total_size(max_total_size), - _min_old_byte_size(min_old_byte_size), - _min_young_byte_size(min_yg_byte_size), - _max_old_byte_size(_max_total_size - _min_young_byte_size), - _max_young_byte_size(_max_total_size - _min_old_byte_size) { -} - -void AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::initialize(size_t initial_old_reserved_size, size_t init_old_byte_size, - size_t init_young_byte_size) { - - // This is the reserved space exclusively for old generation. - ReservedSpace low_rs = _reserved_space.first_part(_max_old_byte_size, true); - // Intially we only assign 'initial_old_reserved_size' of the reserved space to old virtual space. - low_rs = low_rs.first_part(initial_old_reserved_size); - - // This is the reserved space exclusively for young generation. - ReservedSpace high_rs = _reserved_space.last_part(_max_old_byte_size).first_part(_max_young_byte_size); - - // Carve out 'initial_young_reserved_size' of reserved space. - size_t initial_young_reserved_size = _max_total_size - initial_old_reserved_size; - high_rs = high_rs.last_part(_max_young_byte_size - initial_young_reserved_size); - - _low = new PSFileBackedVirtualSpace(low_rs, alignment(), AllocateOldGenAt); - if (!static_cast (_low)->initialize()) { - vm_exit_during_initialization("Could not map space for old generation at given AllocateOldGenAt path"); - } - - if (!_low->expand_by(init_old_byte_size)) { - vm_exit_during_initialization("Could not reserve enough space for object heap"); - } - - _high = new PSVirtualSpaceHighToLow(high_rs, alignment()); - if (!_high->expand_by(init_young_byte_size)) { - vm_exit_during_initialization("Could not reserve enough space for object heap"); - } -} - -// Since the virtual spaces are non-overlapping, there is no boundary as such. -// We replicate the same behavior and maintain the same invariants as base class 'AdjoiningVirtualSpaces' by -// increasing old generation size and decreasing young generation size by same amount. -bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_up(size_t change_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size()); - - size_t bytes_needed = change_in_bytes; - size_t uncommitted_in_old = MIN2(old_vs()->uncommitted_size(), bytes_needed); - bool old_expanded = false; - - // 1. Try to expand old within its reserved space. - if (uncommitted_in_old != 0) { - if (!old_vs()->expand_by(uncommitted_in_old)) { - return false; - } - old_expanded = true; - bytes_needed -= uncommitted_in_old; - if (bytes_needed == 0) { - return true; - } - } - - size_t bytes_to_add_in_old = 0; - - // 2. Get uncommitted memory from Young virtualspace. - size_t young_uncommitted = MIN2(young_vs()->uncommitted_size(), bytes_needed); - if (young_uncommitted > 0) { - young_vs()->set_reserved(young_vs()->reserved_low_addr() + young_uncommitted, - young_vs()->reserved_high_addr(), - young_vs()->special()); - bytes_needed -= young_uncommitted; - bytes_to_add_in_old = young_uncommitted; - } - - // 3. Get committed memory from Young virtualspace - if (bytes_needed > 0) { - size_t shrink_size = align_down(bytes_needed, young_vs()->alignment()); - bool ret = young_vs()->shrink_by(shrink_size); - assert(ret, "We should be able to shrink young space"); - young_vs()->set_reserved(young_vs()->reserved_low_addr() + shrink_size, - young_vs()->reserved_high_addr(), - young_vs()->special()); - - bytes_to_add_in_old += shrink_size; - } - - // 4. Increase size of old space - old_vs()->set_reserved(old_vs()->reserved_low_addr(), - old_vs()->reserved_high_addr() + bytes_to_add_in_old, - old_vs()->special()); - if (!old_vs()->expand_by(bytes_to_add_in_old) && !old_expanded) { - return false; - } - - DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size()); - assert(total_size_after == total_size_before, "should be equal"); - - return true; -} - -// Read comment for adjust_boundary_up() -// Increase young generation size and decrease old generation size by same amount. -bool AdjoiningGenerationsForHeteroHeap::HeteroVirtualSpaces::adjust_boundary_down(size_t change_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - DEBUG_ONLY(size_t total_size_before = young_vs()->reserved_size() + old_vs()->reserved_size()); - - size_t bytes_needed = change_in_bytes; - size_t uncommitted_in_young = MIN2(young_vs()->uncommitted_size(), bytes_needed); - bool young_expanded = false; - - // 1. Try to expand old within its reserved space. - if (uncommitted_in_young > 0) { - if (!young_vs()->expand_by(uncommitted_in_young)) { - return false; - } - young_expanded = true; - bytes_needed -= uncommitted_in_young; - if (bytes_needed == 0) { - return true; - } - } - - size_t bytes_to_add_in_young = 0; - - // 2. Get uncommitted memory from Old virtualspace. - size_t old_uncommitted = MIN2(old_vs()->uncommitted_size(), bytes_needed); - if (old_uncommitted > 0) { - old_vs()->set_reserved(old_vs()->reserved_low_addr(), - old_vs()->reserved_high_addr() - old_uncommitted, - old_vs()->special()); - bytes_needed -= old_uncommitted; - bytes_to_add_in_young = old_uncommitted; - } - - // 3. Get committed memory from Old virtualspace - if (bytes_needed > 0) { - size_t shrink_size = align_down(bytes_needed, old_vs()->alignment()); - bool ret = old_vs()->shrink_by(shrink_size); - assert(ret, "We should be able to shrink young space"); - old_vs()->set_reserved(old_vs()->reserved_low_addr(), - old_vs()->reserved_high_addr() - shrink_size, - old_vs()->special()); - - bytes_to_add_in_young += shrink_size; - } - - assert(bytes_to_add_in_young <= change_in_bytes, "should not be more than requested size"); - // 4. Increase size of young space - young_vs()->set_reserved(young_vs()->reserved_low_addr() - bytes_to_add_in_young, - young_vs()->reserved_high_addr(), - young_vs()->special()); - if (!young_vs()->expand_by(bytes_to_add_in_young) && !young_expanded) { - return false; - } - - DEBUG_ONLY(size_t total_size_after = young_vs()->reserved_size() + old_vs()->reserved_size()); - assert(total_size_after == total_size_before, "should be equal"); - - return true; -} - diff --git a/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.hpp b/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.hpp deleted file mode 100644 index 9ef3d700480..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningGenerationsForHeteroHeap.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP -#define SHARE_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP - -#include "gc/parallel/adjoiningGenerations.hpp" - -class AdjoiningGenerationsForHeteroHeap : public AdjoiningGenerations { - friend class VMStructs; -private: - // Maximum total size of the generations. This is equal to the heap size specified by user. - // When adjusting young and old generation sizes, we need ensure that sum of the generation sizes does not exceed this. - size_t _total_size_limit; - - size_t total_size_limit() const { - return _total_size_limit; - } - - // HeteroVirtualSpaces creates non-overlapping virtual spaces. Here _low and _high do not share a reserved space, i.e. there is no boundary - // separating the two virtual spaces. - class HeteroVirtualSpaces : public AdjoiningVirtualSpaces { - size_t _max_total_size; - size_t _min_old_byte_size; - size_t _min_young_byte_size; - size_t _max_old_byte_size; - size_t _max_young_byte_size; - - // Internally we access the virtual spaces using these methods. It increases readability, since we were not really - // dealing with adjoining virtual spaces separated by a boundary as is the case in base class. - // Externally they are accessed using low() and high() methods of base class. - PSVirtualSpace* young_vs() { return high(); } - PSVirtualSpace* old_vs() { return low(); } - - public: - HeteroVirtualSpaces(ReservedSpace rs, - size_t min_old_byte_size, - size_t min_young_byte_size, - size_t max_total_size); - - // Increase old generation size and decrease young generation size by same amount - bool adjust_boundary_up(size_t size_in_bytes); - // Increase young generation size and decrease old generation size by same amount - bool adjust_boundary_down(size_t size_in_bytes); - - size_t max_young_size() const { return _max_young_byte_size; } - size_t max_old_size() const { return _max_old_byte_size; } - - void initialize(size_t initial_old_reserved_size, size_t init_low_byte_size, - size_t init_high_byte_size); - }; - -public: - AdjoiningGenerationsForHeteroHeap(ReservedSpace rs); - - // Given the size policy, calculate the total amount of memory that needs to be reserved. - // We need to reserve more memory than Xmx, since we use non-overlapping virtual spaces for the young and old generations. - static size_t required_reserved_memory(); - - // Return the total byte size of the reserved space - size_t reserved_byte_size(); -}; -#endif // SHARE_GC_PARALLEL_ADJOININGGENERATIONSFORHETEROHEAP_HPP diff --git a/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.cpp b/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.cpp deleted file mode 100644 index 4e6c6c5b5be..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/adjoiningVirtualSpaces.hpp" -#include "memory/allocation.inline.hpp" -#include "runtime/java.hpp" - -AdjoiningVirtualSpaces::AdjoiningVirtualSpaces(ReservedSpace rs, - size_t min_low_byte_size, - size_t min_high_byte_size, - size_t alignment) : - _high(NULL), _low(NULL), - _reserved_space(rs), _min_low_byte_size(min_low_byte_size), - _min_high_byte_size(min_high_byte_size), - _alignment(alignment) {} - -// The maximum byte sizes are for the initial layout of the -// virtual spaces and are not the limit on the maximum bytes sizes. -void AdjoiningVirtualSpaces::initialize(size_t max_low_byte_size, - size_t init_low_byte_size, - size_t init_high_byte_size) { - - // The reserved spaces for the two parts of the virtual space. - ReservedSpace old_rs = _reserved_space.first_part(max_low_byte_size); - ReservedSpace young_rs = _reserved_space.last_part(max_low_byte_size); - - _low = new PSVirtualSpace(old_rs, alignment()); - if (!_low->expand_by(init_low_byte_size)) { - vm_exit_during_initialization("Could not reserve enough space for " - "object heap"); - } - - _high = new PSVirtualSpaceHighToLow(young_rs, alignment()); - if (!_high->expand_by(init_high_byte_size)) { - vm_exit_during_initialization("Could not reserve enough space for " - "object heap"); - } -} - -bool AdjoiningVirtualSpaces::adjust_boundary_up(size_t change_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - size_t actual_change = low()->expand_into(high(), change_in_bytes); - return actual_change != 0; -} - -bool AdjoiningVirtualSpaces::adjust_boundary_down(size_t change_in_bytes) { - assert(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary, "runtime check"); - size_t actual_change = high()->expand_into(low(), change_in_bytes); - return actual_change != 0; -} diff --git a/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.hpp b/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.hpp deleted file mode 100644 index 79782573849..00000000000 --- a/src/hotspot/share/gc/parallel/adjoiningVirtualSpaces.hpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_ADJOININGVIRTUALSPACES_HPP -#define SHARE_GC_PARALLEL_ADJOININGVIRTUALSPACES_HPP - -#include "gc/parallel/psVirtualspace.hpp" - - -// Contains two virtual spaces that each can individually span -// most of the reserved region but committed parts of which -// cannot overlap. -// -// +-------+ <--- high_boundary for H -// | | -// | H | -// | | -// | | -// | | -// --------- <--- low for H -// | | -// ========= <--- low_boundary for H, high_boundary for L -// | | -// | | -// | | -// --------- <--- high for L -// | | -// | L | -// | | -// | | -// | | -// +-------+ <--- low_boundary for L -// -// Each virtual space in the AdjoiningVirtualSpaces grows and shrink -// within its reserved region (between the low_boundary and the -// boundary) independently. If L want to grow above its high_boundary, -// then the high_boundary of L and the low_boundary of H must be -// moved up consistently. AdjoiningVirtualSpaces provide the -// interfaces for moving the this boundary. - -class AdjoiningVirtualSpaces : public CHeapObj { -protected: - // space at the high end and the low end, respectively - PSVirtualSpace* _high; - PSVirtualSpace* _low; - - // The reserved space spanned by the two spaces. - ReservedSpace _reserved_space; - - // The minimum byte size for the low space. It will not - // be shrunk below this value. - size_t _min_low_byte_size; - // Same for the high space - size_t _min_high_byte_size; - - const size_t _alignment; - - public: - // Allocates two virtual spaces that will be located at the - // high and low ends. Does no initialization. - AdjoiningVirtualSpaces(ReservedSpace rs, - size_t min_low_byte_size, - size_t min_high_byte_size, - size_t alignment); - - // accessors - virtual PSVirtualSpace* high() { return _high; } - virtual PSVirtualSpace* low() { return _low; } - ReservedSpace reserved_space() { return _reserved_space; } - size_t min_low_byte_size() { return _min_low_byte_size; } - size_t min_high_byte_size() { return _min_high_byte_size; } - size_t alignment() const { return _alignment; } - - // move boundary between the two spaces up - virtual bool adjust_boundary_up(size_t size_in_bytes); - // and down - virtual bool adjust_boundary_down(size_t size_in_bytes); - - // Maximum byte size for the high space. - size_t high_byte_size_limit() { - return _reserved_space.size() - _min_low_byte_size; - } - // Maximum byte size for the low space. - size_t low_byte_size_limit() { - return _reserved_space.size() - _min_high_byte_size; - } - - // Sets the boundaries for the virtual spaces and commits and - // initial size; - virtual void initialize(size_t max_low_byte_size, - size_t init_low_byte_size, - size_t init_high_byte_size); -}; -#endif // SHARE_GC_PARALLEL_ADJOININGVIRTUALSPACES_HPP diff --git a/src/hotspot/share/gc/parallel/asPSOldGen.cpp b/src/hotspot/share/gc/parallel/asPSOldGen.cpp deleted file mode 100644 index b29efc2041a..00000000000 --- a/src/hotspot/share/gc/parallel/asPSOldGen.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/asPSOldGen.hpp" -#include "gc/parallel/parallelScavengeHeap.hpp" -#include "gc/parallel/psAdaptiveSizePolicy.hpp" -#include "gc/shared/cardTableBarrierSet.hpp" -#include "gc/shared/genArguments.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/java.hpp" -#include "utilities/align.hpp" - -// Whereas PSOldGen takes the maximum size of the generation -// (which doesn't change in the case of PSOldGen) as a parameter, -// ASPSOldGen takes the upper limit on the size of -// the generation as a parameter. In ASPSOldGen the -// maximum size of the generation can change as the boundary -// moves. The "maximum size of the generation" is still a valid -// concept since the generation can grow and shrink within that -// maximum. There are lots of useful checks that use that -// maximum. In PSOldGen the method max_gen_size() returns -// _max_gen_size (as set by the PSOldGen constructor). This -// is how it always worked. In ASPSOldGen max_gen_size() -// returned the size of the reserved space for the generation. -// That can change as the boundary moves. Below the limit of -// the size of the generation is passed to the PSOldGen constructor -// for "_max_gen_size" (have to pass something) but it is not used later. -// -ASPSOldGen::ASPSOldGen(size_t initial_size, - size_t min_size, - size_t size_limit, - const char* gen_name, - int level) : - PSOldGen(initial_size, min_size, size_limit, gen_name, level), - _gen_size_limit(size_limit) -{} - -ASPSOldGen::ASPSOldGen(PSVirtualSpace* vs, - size_t initial_size, - size_t min_size, - size_t size_limit, - const char* gen_name, - int level) : - PSOldGen(initial_size, min_size, size_limit, gen_name, level), - _gen_size_limit(size_limit) -{ - _virtual_space = vs; -} - -void ASPSOldGen::initialize_work(const char* perf_data_name, int level) { - PSOldGen::initialize_work(perf_data_name, level); - - // The old gen can grow to gen_size_limit(). _reserve reflects only - // the current maximum that can be committed. - assert(_reserved.byte_size() <= gen_size_limit(), "Consistency check"); - - initialize_performance_counters(perf_data_name, level); -} - -void ASPSOldGen::reset_after_change() { - _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), - (HeapWord*)virtual_space()->high_boundary()); - post_resize(); -} - - -size_t ASPSOldGen::available_for_expansion() { - assert(virtual_space()->is_aligned(gen_size_limit()), "not aligned"); - assert(gen_size_limit() >= virtual_space()->committed_size(), "bad gen size"); - - size_t result = gen_size_limit() - virtual_space()->committed_size(); - size_t result_aligned = align_down(result, GenAlignment); - return result_aligned; -} - -size_t ASPSOldGen::available_for_contraction() { - size_t uncommitted_bytes = virtual_space()->uncommitted_size(); - if (uncommitted_bytes != 0) { - return uncommitted_bytes; - } - - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - PSAdaptiveSizePolicy* policy = heap->size_policy(); - const size_t working_size = - used_in_bytes() + (size_t) policy->avg_promoted()->padded_average(); - const size_t working_aligned = align_up(working_size, GenAlignment); - const size_t working_or_min = MAX2(working_aligned, min_gen_size()); - if (working_or_min > reserved().byte_size()) { - // If the used or minimum gen size (aligned up) is greater - // than the total reserved size, then the space available - // for contraction should (after proper alignment) be 0 - return 0; - } - const size_t max_contraction = - reserved().byte_size() - working_or_min; - - // Use the "increment" fraction instead of the "decrement" fraction - // to allow the other gen to expand more aggressively. The - // "decrement" fraction is conservative because its intent is to - // only reduce the footprint. - - size_t result = policy->promo_increment_aligned_down(max_contraction); - // Also adjust for inter-generational alignment - size_t result_aligned = align_down(result, GenAlignment); - - Log(gc, ergo) log; - if (log.is_trace()) { - size_t working_promoted = (size_t) policy->avg_promoted()->padded_average(); - size_t promo_increment = policy->promo_increment(max_contraction); - log.trace("ASPSOldGen::available_for_contraction: " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, result_aligned/K, result_aligned); - log.trace(" reserved().byte_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, reserved().byte_size()/K, reserved().byte_size()); - log.trace(" padded promoted " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, working_promoted/K, working_promoted); - log.trace(" used " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, used_in_bytes()/K, used_in_bytes()); - log.trace(" min_gen_size() " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, min_gen_size()/K, min_gen_size()); - log.trace(" max_contraction " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, max_contraction/K, max_contraction); - log.trace(" without alignment " SIZE_FORMAT " K / " SIZE_FORMAT_HEX, promo_increment/K, promo_increment); - log.trace(" alignment " SIZE_FORMAT_HEX, GenAlignment); - } - - assert(result_aligned <= max_contraction, "arithmetic is wrong"); - return result_aligned; -} diff --git a/src/hotspot/share/gc/parallel/asPSOldGen.hpp b/src/hotspot/share/gc/parallel/asPSOldGen.hpp deleted file mode 100644 index beaa4a80a09..00000000000 --- a/src/hotspot/share/gc/parallel/asPSOldGen.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_ASPSOLDGEN_HPP -#define SHARE_GC_PARALLEL_ASPSOLDGEN_HPP - -#include "gc/parallel/mutableSpace.hpp" -#include "gc/parallel/objectStartArray.hpp" -#include "gc/parallel/psOldGen.hpp" -#include "gc/parallel/psVirtualspace.hpp" -#include "gc/parallel/spaceCounters.hpp" -#include "gc/shared/generationCounters.hpp" - -class ASPSOldGen : public PSOldGen { - friend class VMStructs; - size_t _gen_size_limit; // Largest size the generation's reserved size - // can grow. - public: - ASPSOldGen(size_t initial_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit, - const char* gen_name, int level); - ASPSOldGen(PSVirtualSpace* vs, - size_t initial_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit, - const char* gen_name, int level); - size_t gen_size_limit() { return _gen_size_limit; } - size_t max_gen_size() { return _reserved.byte_size(); } - void set_gen_size_limit(size_t v) { _gen_size_limit = v; } - - virtual void initialize_work(const char* perf_data_name, int level); - - // After a shrink or expand reset the generation - void reset_after_change(); - - // Return number of bytes that the virtual space in the generation is willing - // to expand or contract. The results from these methods should feed into the - // decisions about adjusting the virtual space. - size_t available_for_expansion(); - size_t available_for_contraction(); - - // Accessors - void set_reserved(MemRegion v) { _reserved = v; } - - // Debugging support - virtual const char* short_name() const { return "ASPSOldGen"; } -}; - -#endif // SHARE_GC_PARALLEL_ASPSOLDGEN_HPP diff --git a/src/hotspot/share/gc/parallel/asPSYoungGen.cpp b/src/hotspot/share/gc/parallel/asPSYoungGen.cpp deleted file mode 100644 index 279c93efd48..00000000000 --- a/src/hotspot/share/gc/parallel/asPSYoungGen.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "gc/parallel/asPSYoungGen.hpp" -#include "gc/parallel/parallelScavengeHeap.hpp" -#include "gc/parallel/psScavenge.inline.hpp" -#include "gc/parallel/psYoungGen.hpp" -#include "gc/shared/gcUtil.hpp" -#include "gc/shared/genArguments.hpp" -#include "gc/shared/spaceDecorator.inline.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/java.hpp" -#include "utilities/align.hpp" - -ASPSYoungGen::ASPSYoungGen(size_t init_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit) : - PSYoungGen(init_byte_size, minimum_byte_size, byte_size_limit), - _gen_size_limit(byte_size_limit) { -} - - -ASPSYoungGen::ASPSYoungGen(PSVirtualSpace* vs, - size_t init_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit) : - //PSYoungGen(init_byte_size, minimum_byte_size, byte_size_limit), - PSYoungGen(vs->committed_size(), minimum_byte_size, byte_size_limit), - _gen_size_limit(byte_size_limit) { - - assert(vs->committed_size() == init_byte_size, "Cannot replace with"); - - _virtual_space = vs; -} - -void ASPSYoungGen::initialize_virtual_space(ReservedSpace rs, - size_t alignment) { - assert(_init_gen_size != 0, "Should have a finite size"); - _virtual_space = new PSVirtualSpaceHighToLow(rs, alignment); - if (!_virtual_space->expand_by(_init_gen_size)) { - vm_exit_during_initialization("Could not reserve enough space for object heap"); - } -} - -void ASPSYoungGen::initialize(ReservedSpace rs, size_t alignment) { - initialize_virtual_space(rs, alignment); - initialize_work(); -} - -size_t ASPSYoungGen::available_for_expansion() { - size_t current_committed_size = virtual_space()->committed_size(); - assert((gen_size_limit() >= current_committed_size), - "generation size limit is wrong"); - - size_t result = gen_size_limit() - current_committed_size; - size_t result_aligned = align_down(result, GenAlignment); - return result_aligned; -} - -// Return the number of bytes the young gen is willing give up. -// -// Future implementations could check the survivors and if to_space is in the -// right place (below from_space), take a chunk from to_space. -size_t ASPSYoungGen::available_for_contraction() { - size_t uncommitted_bytes = virtual_space()->uncommitted_size(); - if (uncommitted_bytes != 0) { - return uncommitted_bytes; - } - - if (eden_space()->is_empty()) { - // Respect the minimum size for eden and for the young gen as a whole. - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - const size_t eden_alignment = SpaceAlignment; - - assert(eden_space()->capacity_in_bytes() >= eden_alignment, - "Alignment is wrong"); - size_t eden_avail = eden_space()->capacity_in_bytes() - eden_alignment; - eden_avail = align_down(eden_avail, GenAlignment); - - assert(virtual_space()->committed_size() >= min_gen_size(), - "minimum gen size is wrong"); - size_t gen_avail = virtual_space()->committed_size() - min_gen_size(); - assert(virtual_space()->is_aligned(gen_avail), "not aligned"); - - const size_t max_contraction = MIN2(eden_avail, gen_avail); - // See comment for ASPSOldGen::available_for_contraction() - // for reasons the "increment" fraction is used. - PSAdaptiveSizePolicy* policy = heap->size_policy(); - size_t result = policy->eden_increment_aligned_down(max_contraction); - size_t result_aligned = align_down(result, GenAlignment); - - log_trace(gc, ergo)("ASPSYoungGen::available_for_contraction: " SIZE_FORMAT " K", result_aligned/K); - log_trace(gc, ergo)(" max_contraction " SIZE_FORMAT " K", max_contraction/K); - log_trace(gc, ergo)(" eden_avail " SIZE_FORMAT " K", eden_avail/K); - log_trace(gc, ergo)(" gen_avail " SIZE_FORMAT " K", gen_avail/K); - - return result_aligned; - } - - return 0; -} - -// The current implementation only considers to the end of eden. -// If to_space is below from_space, to_space is not considered. -// to_space can be. -size_t ASPSYoungGen::available_to_live() { - const size_t alignment = SpaceAlignment; - - // Include any space that is committed but is not in eden. - size_t available = pointer_delta(eden_space()->bottom(), - virtual_space()->low(), - sizeof(char)); - - const size_t eden_capacity = eden_space()->capacity_in_bytes(); - if (eden_space()->is_empty() && eden_capacity > alignment) { - available += eden_capacity - alignment; - } - return available; -} - -// Similar to PSYoungGen::resize_generation() but -// allows sum of eden_size and 2 * survivor_size to exceed _max_gen_size -// expands at the low end of the virtual space -// moves the boundary between the generations in order to expand -// some additional diagnostics -// If no additional changes are required, this can be deleted -// and the changes factored back into PSYoungGen::resize_generation(). -bool ASPSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) { - const size_t alignment = virtual_space()->alignment(); - size_t orig_size = virtual_space()->committed_size(); - bool size_changed = false; - - // There used to be a guarantee here that - // (eden_size + 2*survivor_size) <= _max_gen_size - // This requirement is enforced by the calculation of desired_size - // below. It may not be true on entry since the size of the - // eden_size is no bounded by the generation size. - - assert(max_size() == reserved().byte_size(), "max gen size problem?"); - assert(min_gen_size() <= orig_size && orig_size <= max_size(), - "just checking"); - - // Adjust new generation size - const size_t eden_plus_survivors = - align_up(eden_size + 2 * survivor_size, alignment); - size_t desired_size = clamp(eden_plus_survivors, min_gen_size(), gen_size_limit()); - assert(desired_size <= gen_size_limit(), "just checking"); - - if (desired_size > orig_size) { - // Grow the generation - size_t change = desired_size - orig_size; - HeapWord* prev_low = (HeapWord*) virtual_space()->low(); - if (!virtual_space()->expand_by(change)) { - return false; - } - if (ZapUnusedHeapArea) { - // Mangle newly committed space immediately because it - // can be done here more simply that after the new - // spaces have been computed. - HeapWord* new_low = (HeapWord*) virtual_space()->low(); - assert(new_low < prev_low, "Did not grow"); - - MemRegion mangle_region(new_low, prev_low); - SpaceMangler::mangle_region(mangle_region); - } - size_changed = true; - } else if (desired_size < orig_size) { - size_t desired_change = orig_size - desired_size; - - // How much is available for shrinking. - size_t available_bytes = limit_gen_shrink(desired_change); - size_t change = MIN2(desired_change, available_bytes); - virtual_space()->shrink_by(change); - size_changed = true; - } else { - if (orig_size == gen_size_limit()) { - log_trace(gc)("ASPSYoung generation size at maximum: " SIZE_FORMAT "K", orig_size/K); - } else if (orig_size == min_gen_size()) { - log_trace(gc)("ASPSYoung generation size at minium: " SIZE_FORMAT "K", orig_size/K); - } - } - - if (size_changed) { - reset_after_change(); - log_trace(gc)("ASPSYoung generation size changed: " SIZE_FORMAT "K->" SIZE_FORMAT "K", - orig_size/K, virtual_space()->committed_size()/K); - } - - guarantee(eden_plus_survivors <= virtual_space()->committed_size() || - virtual_space()->committed_size() == max_size(), "Sanity"); - - return true; -} - -// Similar to PSYoungGen::resize_spaces() but -// eden always starts at the low end of the committed virtual space -// current implementation does not allow holes between the spaces -// _young_generation_boundary has to be reset because it changes. -// so additional verification - -void ASPSYoungGen::resize_spaces(size_t requested_eden_size, - size_t requested_survivor_size) { - assert(UseAdaptiveSizePolicy, "sanity check"); - assert(requested_eden_size > 0 && requested_survivor_size > 0, - "just checking"); - - space_invariants(); - - // We require eden and to space to be empty - if ((!eden_space()->is_empty()) || (!to_space()->is_empty())) { - return; - } - - log_trace(gc, ergo)("PSYoungGen::resize_spaces(requested_eden_size: " - SIZE_FORMAT - ", requested_survivor_size: " SIZE_FORMAT ")", - requested_eden_size, requested_survivor_size); - log_trace(gc, ergo)(" eden: [" PTR_FORMAT ".." PTR_FORMAT ") " - SIZE_FORMAT, - p2i(eden_space()->bottom()), - p2i(eden_space()->end()), - pointer_delta(eden_space()->end(), eden_space()->bottom(), sizeof(char))); - log_trace(gc, ergo)(" from: [" PTR_FORMAT ".." PTR_FORMAT ") " - SIZE_FORMAT, - p2i(from_space()->bottom()), - p2i(from_space()->end()), - pointer_delta(from_space()->end(), from_space()->bottom(), sizeof(char))); - log_trace(gc, ergo)(" to: [" PTR_FORMAT ".." PTR_FORMAT ") " - SIZE_FORMAT, - p2i(to_space()->bottom()), - p2i(to_space()->end()), - pointer_delta( to_space()->end(), to_space()->bottom(), sizeof(char))); - - // There's nothing to do if the new sizes are the same as the current - if (requested_survivor_size == to_space()->capacity_in_bytes() && - requested_survivor_size == from_space()->capacity_in_bytes() && - requested_eden_size == eden_space()->capacity_in_bytes()) { - log_trace(gc, ergo)(" capacities are the right sizes, returning"); - return; - } - - char* eden_start = (char*)virtual_space()->low(); - char* eden_end = (char*)eden_space()->end(); - char* from_start = (char*)from_space()->bottom(); - char* from_end = (char*)from_space()->end(); - char* to_start = (char*)to_space()->bottom(); - char* to_end = (char*)to_space()->end(); - - assert(eden_start < from_start, "Cannot push into from_space"); - - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - const bool maintain_minimum = - (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size(); - - bool eden_from_to_order = from_start < to_start; - // Check whether from space is below to space - if (eden_from_to_order) { - // Eden, from, to - - log_trace(gc, ergo)(" Eden, from, to:"); - - // Set eden - // "requested_eden_size" is a goal for the size of eden - // and may not be attainable. "eden_size" below is - // calculated based on the location of from-space and - // the goal for the size of eden. from-space is - // fixed in place because it contains live data. - // The calculation is done this way to avoid 32bit - // overflow (i.e., eden_start + requested_eden_size - // may too large for representation in 32bits). - size_t eden_size; - if (maintain_minimum) { - // Only make eden larger than the requested size if - // the minimum size of the generation has to be maintained. - // This could be done in general but policy at a higher - // level is determining a requested size for eden and that - // should be honored unless there is a fundamental reason. - eden_size = pointer_delta(from_start, - eden_start, - sizeof(char)); - } else { - eden_size = MIN2(requested_eden_size, - pointer_delta(from_start, eden_start, sizeof(char))); - } - - eden_end = eden_start + eden_size; - assert(eden_end >= eden_start, "addition overflowed"); - - // To may resize into from space as long as it is clear of live data. - // From space must remain page aligned, though, so we need to do some - // extra calculations. - - // First calculate an optimal to-space - to_end = (char*)virtual_space()->high(); - to_start = (char*)pointer_delta(to_end, - (char*)requested_survivor_size, - sizeof(char)); - - // Does the optimal to-space overlap from-space? - if (to_start < (char*)from_space()->end()) { - // Calculate the minimum offset possible for from_end - size_t from_size = - pointer_delta(from_space()->top(), from_start, sizeof(char)); - - // Should we be in this method if from_space is empty? Why not the set_space method? FIX ME! - if (from_size == 0) { - from_size = SpaceAlignment; - } else { - from_size = align_up(from_size, SpaceAlignment); - } - - from_end = from_start + from_size; - assert(from_end > from_start, "addition overflow or from_size problem"); - - guarantee(from_end <= (char*)from_space()->end(), - "from_end moved to the right"); - - // Now update to_start with the new from_end - to_start = MAX2(from_end, to_start); - } - - guarantee(to_start != to_end, "to space is zero sized"); - - log_trace(gc, ergo)(" [eden_start .. eden_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(eden_start), - p2i(eden_end), - pointer_delta(eden_end, eden_start, sizeof(char))); - log_trace(gc, ergo)(" [from_start .. from_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(from_start), - p2i(from_end), - pointer_delta(from_end, from_start, sizeof(char))); - log_trace(gc, ergo)(" [ to_start .. to_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(to_start), - p2i(to_end), - pointer_delta( to_end, to_start, sizeof(char))); - } else { - // Eden, to, from - log_trace(gc, ergo)(" Eden, to, from:"); - - // To space gets priority over eden resizing. Note that we position - // to space as if we were able to resize from space, even though from - // space is not modified. - // Giving eden priority was tried and gave poorer performance. - to_end = (char*)pointer_delta(virtual_space()->high(), - (char*)requested_survivor_size, - sizeof(char)); - to_end = MIN2(to_end, from_start); - to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size, - sizeof(char)); - // if the space sizes are to be increased by several times then - // 'to_start' will point beyond the young generation. In this case - // 'to_start' should be adjusted. - to_start = MAX2(to_start, eden_start + SpaceAlignment); - - // Compute how big eden can be, then adjust end. - // See comments above on calculating eden_end. - size_t eden_size; - if (maintain_minimum) { - eden_size = pointer_delta(to_start, eden_start, sizeof(char)); - } else { - eden_size = MIN2(requested_eden_size, - pointer_delta(to_start, eden_start, sizeof(char))); - } - eden_end = eden_start + eden_size; - assert(eden_end >= eden_start, "addition overflowed"); - - // Don't let eden shrink down to 0 or less. - eden_end = MAX2(eden_end, eden_start + SpaceAlignment); - to_start = MAX2(to_start, eden_end); - - log_trace(gc, ergo)(" [eden_start .. eden_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(eden_start), - p2i(eden_end), - pointer_delta(eden_end, eden_start, sizeof(char))); - log_trace(gc, ergo)(" [ to_start .. to_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(to_start), - p2i(to_end), - pointer_delta( to_end, to_start, sizeof(char))); - log_trace(gc, ergo)(" [from_start .. from_end): " - "[" PTR_FORMAT " .. " PTR_FORMAT ") " SIZE_FORMAT, - p2i(from_start), - p2i(from_end), - pointer_delta(from_end, from_start, sizeof(char))); - } - - - guarantee((HeapWord*)from_start <= from_space()->bottom(), - "from start moved to the right"); - guarantee((HeapWord*)from_end >= from_space()->top(), - "from end moved into live data"); - assert(is_object_aligned(eden_start), "checking alignment"); - assert(is_object_aligned(from_start), "checking alignment"); - assert(is_object_aligned(to_start), "checking alignment"); - - MemRegion edenMR((HeapWord*)eden_start, (HeapWord*)eden_end); - MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end); - MemRegion fromMR((HeapWord*)from_start, (HeapWord*)from_end); - - // Let's make sure the call to initialize doesn't reset "top"! - DEBUG_ONLY(HeapWord* old_from_top = from_space()->top();) - - // For logging block below - size_t old_from = from_space()->capacity_in_bytes(); - size_t old_to = to_space()->capacity_in_bytes(); - - if (ZapUnusedHeapArea) { - // NUMA is a special case because a numa space is not mangled - // in order to not prematurely bind its address to memory to - // the wrong memory (i.e., don't want the GC thread to first - // touch the memory). The survivor spaces are not numa - // spaces and are mangled. - if (UseNUMA) { - if (eden_from_to_order) { - mangle_survivors(from_space(), fromMR, to_space(), toMR); - } else { - mangle_survivors(to_space(), toMR, from_space(), fromMR); - } - } - - // If not mangling the spaces, do some checking to verify that - // the spaces are already mangled. - // The spaces should be correctly mangled at this point so - // do some checking here. Note that they are not being mangled - // in the calls to initialize(). - // Must check mangling before the spaces are reshaped. Otherwise, - // the bottom or end of one space may have moved into an area - // covered by another space and a failure of the check may - // not correctly indicate which space is not properly mangled. - - HeapWord* limit = (HeapWord*) virtual_space()->high(); - eden_space()->check_mangled_unused_area(limit); - from_space()->check_mangled_unused_area(limit); - to_space()->check_mangled_unused_area(limit); - } - // When an existing space is being initialized, it is not - // mangled because the space has been previously mangled. - eden_space()->initialize(edenMR, - SpaceDecorator::Clear, - SpaceDecorator::DontMangle); - to_space()->initialize(toMR, - SpaceDecorator::Clear, - SpaceDecorator::DontMangle); - from_space()->initialize(fromMR, - SpaceDecorator::DontClear, - SpaceDecorator::DontMangle); - - PSScavenge::set_young_generation_boundary(eden_space()->bottom()); - - assert(from_space()->top() == old_from_top, "from top changed!"); - - log_trace(gc, ergo)("AdaptiveSizePolicy::survivor space sizes: " - "collection: %d " - "(" SIZE_FORMAT ", " SIZE_FORMAT ") -> " - "(" SIZE_FORMAT ", " SIZE_FORMAT ") ", - ParallelScavengeHeap::heap()->total_collections(), - old_from, old_to, - from_space()->capacity_in_bytes(), - to_space()->capacity_in_bytes()); - - space_invariants(); -} -void ASPSYoungGen::reset_after_change() { - assert_locked_or_safepoint(Heap_lock); - - _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), - (HeapWord*)virtual_space()->high_boundary()); - PSScavenge::set_subject_to_discovery_span(_reserved); - - HeapWord* new_eden_bottom = (HeapWord*)virtual_space()->low(); - HeapWord* eden_bottom = eden_space()->bottom(); - if (new_eden_bottom != eden_bottom) { - MemRegion eden_mr(new_eden_bottom, eden_space()->end()); - eden_space()->initialize(eden_mr, - SpaceDecorator::Clear, - SpaceDecorator::Mangle); - PSScavenge::set_young_generation_boundary(eden_space()->bottom()); - } - MemRegion cmr((HeapWord*)virtual_space()->low(), - (HeapWord*)virtual_space()->high()); - ParallelScavengeHeap::heap()->barrier_set()->card_table()->resize_covered_region(cmr); - - space_invariants(); -} diff --git a/src/hotspot/share/gc/parallel/asPSYoungGen.hpp b/src/hotspot/share/gc/parallel/asPSYoungGen.hpp deleted file mode 100644 index 2fec4013871..00000000000 --- a/src/hotspot/share/gc/parallel/asPSYoungGen.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_PARALLEL_ASPSYOUNGGEN_HPP -#define SHARE_GC_PARALLEL_ASPSYOUNGGEN_HPP - -#include "gc/parallel/mutableSpace.hpp" -#include "gc/parallel/objectStartArray.hpp" -#include "gc/parallel/psVirtualspace.hpp" -#include "gc/parallel/psYoungGen.hpp" -#include "gc/parallel/spaceCounters.hpp" -#include "gc/shared/generationCounters.hpp" -#include "gc/shared/spaceDecorator.hpp" - -class ASPSYoungGen : public PSYoungGen { - friend class VMStructs; - private: - size_t _gen_size_limit; - protected: - virtual size_t available_to_live(); - - public: - ASPSYoungGen(size_t initial_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit); - - ASPSYoungGen(PSVirtualSpace* vs, - size_t initial_byte_size, - size_t minimum_byte_size, - size_t byte_size_limit); - - void initialize(ReservedSpace rs, size_t alignment); - void initialize_virtual_space(ReservedSpace rs, size_t alignment); - - size_t gen_size_limit() { return _gen_size_limit; } - void set_gen_size_limit(size_t v) { _gen_size_limit = v; } - - bool resize_generation(size_t eden_size, size_t survivor_size); - void resize_spaces(size_t eden_size, size_t survivor_size); - - // Adjust eden to be consistent with the virtual space. - void reset_after_change(); - - // Adaptive size policy support - // Return number of bytes that the generation can expand/contract. - size_t available_for_expansion(); - size_t available_for_contraction(); - - // Accessors - void set_reserved(MemRegion v) { _reserved = v; } - - // Printing support - virtual const char* short_name() const { return "ASPSYoungGen"; } -}; - -#endif // SHARE_GC_PARALLEL_ASPSYOUNGGEN_HPP diff --git a/src/hotspot/share/gc/parallel/parallelArguments.cpp b/src/hotspot/share/gc/parallel/parallelArguments.cpp index 23dcbe52d08..7b2ae1126a1 100644 --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp @@ -122,10 +122,8 @@ void ParallelArguments::initialize_heap_flags_and_sizes() { initialize_heap_flags_and_sizes_one_pass(); - const size_t max_page_sz = os::page_size_for_region_aligned(MaxHeapSize, 8); const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old - const size_t min_page_sz = os::page_size_for_region_aligned(MinHeapSize, min_pages); - const size_t page_sz = MIN2(max_page_sz, min_page_sz); + const size_t page_sz = os::page_size_for_region_aligned(MinHeapSize, min_pages); // Can a page size be something else than a power of two? assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2"); @@ -194,18 +192,7 @@ bool ParallelArguments::is_heterogeneous_heap() { } size_t ParallelArguments::heap_reserved_size_bytes() { - if (!is_heterogeneous_heap() || !UseAdaptiveGCBoundary) { - return MaxHeapSize; - } - - // Heterogeneous heap and adaptive size gc boundary - - // This is the size that young gen can grow to, when UseAdaptiveGCBoundary is true. - size_t max_yg_size = MaxHeapSize - MinOldSize; - // This is the size that old gen can grow to, when UseAdaptiveGCBoundary is true. - size_t max_old_size = MaxHeapSize - MinNewSize; - - return max_yg_size + max_old_size; + return MaxHeapSize; } size_t ParallelArguments::heap_max_size_bytes() { diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 731eb5d0015..f814842b3e8 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -24,9 +24,6 @@ #include "precompiled.hpp" #include "code/codeCache.hpp" -#include "gc/parallel/adjoiningGenerations.hpp" -#include "gc/parallel/adjoiningGenerationsForHeteroHeap.hpp" -#include "gc/parallel/adjoiningVirtualSpaces.hpp" #include "gc/parallel/parallelArguments.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/parallel/parallelScavengeHeap.inline.hpp" @@ -81,19 +78,34 @@ jint ParallelScavengeHeap::initialize() { BarrierSet::set_barrier_set(barrier_set); // Make up the generations - // Calculate the maximum size that a generation can grow. This - // includes growth into the other generation. Note that the - // parameter _max_gen_size is kept as the maximum - // size of the generation as the boundaries currently stand. - // _max_gen_size is still used as that value. + assert(MinOldSize <= OldSize && OldSize <= MaxOldSize, "Parameter check"); + assert(MinNewSize <= NewSize && NewSize <= MaxNewSize, "Parameter check"); + + // Layout the reserved space for the generations. + // If OldGen is allocated on nv-dimm, we need to split the reservation (this is required for windows). + ReservedSpace old_rs = heap_rs.first_part(MaxOldSize, ParallelArguments::is_heterogeneous_heap() /* split */); + ReservedSpace young_rs = heap_rs.last_part(MaxOldSize); + assert(young_rs.size() == MaxNewSize, "Didn't reserve all of the heap"); + + // Create and initialize the generations. + _young_gen = new PSYoungGen( + young_rs, + NewSize, + MinNewSize, + MaxNewSize); + _old_gen = new PSOldGen( + old_rs, + OldSize, + MinOldSize, + MaxOldSize, + "old", 1); + + assert(young_gen()->gen_size_limit() == young_rs.size(),"Consistency check"); + assert(old_gen()->gen_size_limit() == old_rs.size(), "Consistency check"); + double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; - _gens = AdjoiningGenerations::create_adjoining_generations(heap_rs); - - _old_gen = _gens->old_gen(); - _young_gen = _gens->young_gen(); - const size_t eden_capacity = _young_gen->eden_space()->capacity_in_bytes(); const size_t old_capacity = _old_gen->capacity_in_bytes(); const size_t initial_promo_size = MIN2(eden_capacity, old_capacity); @@ -107,10 +119,10 @@ jint ParallelScavengeHeap::initialize() { GCTimeRatio ); - assert(ParallelArguments::is_heterogeneous_heap() || !UseAdaptiveGCBoundary || - (old_gen()->virtual_space()->high_boundary() == - young_gen()->virtual_space()->low_boundary()), - "Boundaries must meet"); + assert(ParallelArguments::is_heterogeneous_heap() || + (old_gen()->virtual_space()->high_boundary() == + young_gen()->virtual_space()->low_boundary()), + "Boundaries must meet"); // initialize the policy counters - 2 collectors, 2 generations _gc_policy_counters = new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 2, _size_policy); @@ -689,35 +701,13 @@ PSCardTable* ParallelScavengeHeap::card_table() { return static_cast(barrier_set()->card_table()); } -// Before delegating the resize to the young generation, -// the reserved space for the young and old generations -// may be changed to accommodate the desired resize. void ParallelScavengeHeap::resize_young_gen(size_t eden_size, - size_t survivor_size) { - if (UseAdaptiveGCBoundary) { - if (size_policy()->bytes_absorbed_from_eden() != 0) { - size_policy()->reset_bytes_absorbed_from_eden(); - return; // The generation changed size already. - } - gens()->adjust_boundary_for_young_gen_needs(eden_size, survivor_size); - } - + size_t survivor_size) { // Delegate the resize to the generation. _young_gen->resize(eden_size, survivor_size); } -// Before delegating the resize to the old generation, -// the reserved space for the young and old generations -// may be changed to accommodate the desired resize. void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) { - if (UseAdaptiveGCBoundary) { - if (size_policy()->bytes_absorbed_from_eden() != 0) { - size_policy()->reset_bytes_absorbed_from_eden(); - return; // The generation changed size already. - } - gens()->adjust_boundary_for_old_gen_needs(desired_free_space); - } - // Delegate the resize to the generation. _old_gen->resize(desired_free_space); } diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index 11036580552..0f818e55f7e 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -63,9 +63,6 @@ class ParallelScavengeHeap : public CollectedHeap { SoftRefPolicy _soft_ref_policy; - // Collection of generations that are adjacent in the - // space reserved for the heap. - AdjoiningGenerations* _gens; unsigned int _death_march_count; GCMemoryManager* _young_manager; @@ -92,7 +89,6 @@ class ParallelScavengeHeap : public CollectedHeap { public: ParallelScavengeHeap() : CollectedHeap(), - _gens(NULL), _death_march_count(0), _young_manager(NULL), _old_manager(NULL), @@ -135,8 +131,6 @@ class ParallelScavengeHeap : public CollectedHeap { CardTableBarrierSet* barrier_set(); PSCardTable* card_table(); - AdjoiningGenerations* gens() { return _gens; } - // Returns JNI_OK on success virtual jint initialize(); diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp index d573a4855e5..f173d49bab4 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,8 +62,7 @@ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size, _change_young_gen_for_maj_pauses(0), _old_gen_policy_is_ready(false), _young_gen_size_increment_supplement(YoungGenerationSizeSupplement), - _old_gen_size_increment_supplement(TenuredGenerationSizeSupplement), - _bytes_absorbed_from_eden(0) + _old_gen_size_increment_supplement(TenuredGenerationSizeSupplement) { // Start the timers _major_timer.start(); @@ -915,16 +914,6 @@ size_t PSAdaptiveSizePolicy::eden_increment(size_t cur_eden) { return eden_increment(cur_eden, YoungGenerationSizeIncrement); } -size_t PSAdaptiveSizePolicy::eden_increment_aligned_up(size_t cur_eden) { - size_t result = eden_increment(cur_eden, YoungGenerationSizeIncrement); - return align_up(result, _space_alignment); -} - -size_t PSAdaptiveSizePolicy::eden_increment_aligned_down(size_t cur_eden) { - size_t result = eden_increment(cur_eden); - return align_down(result, _space_alignment); -} - size_t PSAdaptiveSizePolicy::eden_increment_with_supplement_aligned_up( size_t cur_eden) { size_t result = eden_increment(cur_eden, @@ -954,16 +943,6 @@ size_t PSAdaptiveSizePolicy::promo_increment(size_t cur_promo) { return promo_increment(cur_promo, TenuredGenerationSizeIncrement); } -size_t PSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) { - size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement); - return align_up(result, _space_alignment); -} - -size_t PSAdaptiveSizePolicy::promo_increment_aligned_down(size_t cur_promo) { - size_t result = promo_increment(cur_promo, TenuredGenerationSizeIncrement); - return align_down(result, _space_alignment); -} - size_t PSAdaptiveSizePolicy::promo_increment_with_supplement_aligned_up( size_t cur_promo) { size_t result = promo_increment(cur_promo, diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp index e8f783c1c5f..1f0ae88593f 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,10 +117,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { uint _young_gen_size_increment_supplement; uint _old_gen_size_increment_supplement; - // The number of bytes absorbed from eden into the old gen by moving the - // boundary over live data. - size_t _bytes_absorbed_from_eden; - private: // Accessors @@ -193,12 +189,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { virtual GCPolicyKind kind() const { return _gc_ps_adaptive_size_policy; } public: - // Use by ASPSYoungGen and ASPSOldGen to limit boundary moving. - size_t eden_increment_aligned_up(size_t cur_eden); - size_t eden_increment_aligned_down(size_t cur_eden); - size_t promo_increment_aligned_up(size_t cur_promo); - size_t promo_increment_aligned_down(size_t cur_promo); - virtual size_t eden_increment(size_t cur_eden); virtual size_t promo_increment(size_t cur_promo); @@ -374,13 +364,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { return _live_at_last_full_gc; } - size_t bytes_absorbed_from_eden() const { return _bytes_absorbed_from_eden; } - void reset_bytes_absorbed_from_eden() { _bytes_absorbed_from_eden = 0; } - - void set_bytes_absorbed_from_eden(size_t val) { - _bytes_absorbed_from_eden = val; - } - // Update averages that are always used (even // if adaptive sizing is turned off). void update_averages(bool is_survivor_overflow, diff --git a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp index 8b173a293e6..dd9f52d2fb9 100644 --- a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp +++ b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.cpp @@ -55,10 +55,6 @@ PSGCAdaptivePolicyCounters::PSGCAdaptivePolicyCounters(const char* name_arg, _old_capacity = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, (jlong) InitialHeapSize, CHECK); - cname = PerfDataManager::counter_name(name_space(), "boundaryMoved"); - _boundary_moved = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, (jlong) 0, CHECK); - cname = PerfDataManager::counter_name(name_space(), "avgPromotedAvg"); _avg_promoted_avg_counter = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, diff --git a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp index 2e263f54840..223a039d6fe 100644 --- a/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp +++ b/src/hotspot/share/gc/parallel/psGCAdaptivePolicyCounters.hpp @@ -53,7 +53,6 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters { PerfVariable* _avg_base_footprint; PerfVariable* _live_at_last_full_gc_counter; PerfVariable* _old_capacity; - PerfVariable* _boundary_moved; PerfVariable* _change_old_gen_for_min_pauses; PerfVariable* _change_young_gen_for_maj_pauses_counter; @@ -85,9 +84,6 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters { inline void update_old_promo_size(size_t old_size) { _old_promo_size->set_value(old_size); } - inline void update_boundary_moved(int size_in_bytes) { - _boundary_moved->set_value(size_in_bytes); - } inline void update_avg_promoted_avg() { _avg_promoted_avg_counter->set_value( (jlong)(ps_size_policy()->avg_promoted()->average()) diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index e5998186576..7b40ae25895 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -38,22 +38,14 @@ #include "runtime/java.hpp" #include "utilities/align.hpp" -PSOldGen::PSOldGen(ReservedSpace rs, size_t alignment, - size_t initial_size, size_t min_size, size_t max_size, - const char* perf_data_name, int level): +PSOldGen::PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size, + size_t max_size, const char* perf_data_name, int level): _init_gen_size(initial_size), _min_gen_size(min_size), _max_gen_size(max_size) { - initialize(rs, alignment, perf_data_name, level); + initialize(rs, GenAlignment, perf_data_name, level); } -PSOldGen::PSOldGen(size_t initial_size, - size_t min_size, size_t max_size, - const char* perf_data_name, int level): - _init_gen_size(initial_size), _min_gen_size(min_size), - _max_gen_size(max_size) -{} - void PSOldGen::initialize(ReservedSpace rs, size_t alignment, const char* perf_data_name, int level) { initialize_virtual_space(rs, alignment); @@ -158,10 +150,6 @@ bool PSOldGen::is_allocated() { return virtual_space()->reserved_size() != 0; } -size_t PSOldGen::contiguous_available() const { - return object_space()->free_in_bytes() + virtual_space()->uncommitted_size(); -} - // Allocation. We report all successful allocations to the size policy // Note that the perm gen does not use this method, and should not! HeapWord* PSOldGen::allocate(size_t word_size) { @@ -374,21 +362,6 @@ size_t PSOldGen::gen_size_limit() { return _max_gen_size; } -void PSOldGen::reset_after_change() { - ShouldNotReachHere(); - return; -} - -size_t PSOldGen::available_for_expansion() { - ShouldNotReachHere(); - return 0; -} - -size_t PSOldGen::available_for_contraction() { - ShouldNotReachHere(); - return 0; -} - void PSOldGen::print() const { print_on(tty);} void PSOldGen::print_on(outputStream* st) const { st->print(" %-15s", name()); @@ -409,29 +382,10 @@ void PSOldGen::update_counters() { } } -#ifndef PRODUCT - -void PSOldGen::space_invariants() { - assert(object_space()->end() == (HeapWord*) virtual_space()->high(), - "Space invariant"); - assert(object_space()->bottom() == (HeapWord*) virtual_space()->low(), - "Space invariant"); - assert(virtual_space()->low_boundary() <= virtual_space()->low(), - "Space invariant"); - assert(virtual_space()->high_boundary() >= virtual_space()->high(), - "Space invariant"); - assert(virtual_space()->low_boundary() == (char*) _reserved.start(), - "Space invariant"); - assert(virtual_space()->high_boundary() == (char*) _reserved.end(), - "Space invariant"); - assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(), - "Space invariant"); -} -#endif - void PSOldGen::verify() { object_space()->verify(); } + class VerifyObjectStartArrayClosure : public ObjectClosure { PSOldGen* _old_gen; ObjectStartArray* _start_array; diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index 61c865e1862..61a2f32f1f6 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -38,7 +38,7 @@ class PSOldGen : public CHeapObj { friend class ParallelScavengeHeap; friend class AdjoiningGenerations; - protected: + private: MemRegion _reserved; // Used for simple containment tests PSVirtualSpace* _virtual_space; // Controls mapping and unmapping of virtual mem ObjectStartArray _start_array; // Keeps track of where objects start in a 512b block @@ -110,24 +110,20 @@ class PSOldGen : public CHeapObj { void post_resize(); - public: - // Initialize the generation. - PSOldGen(ReservedSpace rs, size_t alignment, - size_t initial_size, size_t min_size, size_t max_size, - const char* perf_data_name, int level); - - PSOldGen(size_t initial_size, size_t min_size, size_t max_size, - const char* perf_data_name, int level); - - virtual void initialize(ReservedSpace rs, size_t alignment, + void initialize(ReservedSpace rs, size_t alignment, const char* perf_data_name, int level); void initialize_virtual_space(ReservedSpace rs, size_t alignment); - virtual void initialize_work(const char* perf_data_name, int level); - virtual void initialize_performance_counters(const char* perf_data_name, int level); + void initialize_work(const char* perf_data_name, int level); + void initialize_performance_counters(const char* perf_data_name, int level); - MemRegion reserved() const { return _reserved; } - virtual size_t max_gen_size() { return _max_gen_size; } - size_t min_gen_size() { return _min_gen_size; } + public: + // Initialize the generation. + PSOldGen(ReservedSpace rs, size_t initial_size, size_t min_size, + size_t max_size, const char* perf_data_name, int level); + + MemRegion reserved() const { return _reserved; } + virtual size_t max_gen_size() { return _max_gen_size; } + size_t min_gen_size() { return _min_gen_size; } // Returns limit on the maximum size of the generation. This // is the same as _max_gen_size for PSOldGen but need not be @@ -158,9 +154,6 @@ class PSOldGen : public CHeapObj { size_t used_in_words() const { return object_space()->used_in_words(); } size_t free_in_words() const { return object_space()->free_in_words(); } - // Includes uncommitted memory - size_t contiguous_available() const; - bool is_maximal_no_gc() const { return virtual_space()->uncommitted_size() == 0; } @@ -177,26 +170,17 @@ class PSOldGen : public CHeapObj { void object_iterate(ObjectClosure* cl) { object_space()->object_iterate(cl); } // Debugging - do not use for time critical operations - virtual void print() const; + void print() const; virtual void print_on(outputStream* st) const; void verify(); void verify_object_start_array(); - // These should not used - virtual void reset_after_change(); - - // These should not used - virtual size_t available_for_expansion(); - virtual size_t available_for_contraction(); - - void space_invariants() PRODUCT_RETURN; - // Performance Counter support void update_counters(); // Printing support - virtual const char* name() const { return "ParOldGen"; } + const char* name() const { return "ParOldGen"; } // Debugging support // Save the tops of all spaces for later use during mangling. diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 8cc853e5727..ce652ffb2a3 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1039,10 +1039,6 @@ void PSParallelCompact::post_compact() ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); bool eden_empty = eden_space->is_empty(); - if (!eden_empty) { - eden_empty = absorb_live_data_from_eden(heap->size_policy(), - heap->young_gen(), heap->old_gen()); - } // Update heap occupancy information which is used as input to the soft ref // clearing policy at the next gc. @@ -1982,95 +1978,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { return true; } -bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy, - PSYoungGen* young_gen, - PSOldGen* old_gen) { - MutableSpace* const eden_space = young_gen->eden_space(); - assert(!eden_space->is_empty(), "eden must be non-empty"); - assert(young_gen->virtual_space()->alignment() == - old_gen->virtual_space()->alignment(), "alignments do not match"); - - // We also return false when it's a heterogeneous heap because old generation cannot absorb data from eden - // when it is allocated on different memory (example, nv-dimm) than young. - if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary) || - ParallelArguments::is_heterogeneous_heap()) { - return false; - } - - // Both generations must be completely committed. - if (young_gen->virtual_space()->uncommitted_size() != 0) { - return false; - } - if (old_gen->virtual_space()->uncommitted_size() != 0) { - return false; - } - - // Figure out how much to take from eden. Include the average amount promoted - // in the total; otherwise the next young gen GC will simply bail out to a - // full GC. - const size_t alignment = old_gen->virtual_space()->alignment(); - const size_t eden_used = eden_space->used_in_bytes(); - const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average(); - const size_t absorb_size = align_up(eden_used + promoted, alignment); - const size_t eden_capacity = eden_space->capacity_in_bytes(); - - if (absorb_size >= eden_capacity) { - return false; // Must leave some space in eden. - } - - const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size; - if (new_young_size < young_gen->min_gen_size()) { - return false; // Respect young gen minimum size. - } - - log_trace(gc, ergo, heap)(" absorbing " SIZE_FORMAT "K: " - "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K " - "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K " - "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ", - absorb_size / K, - eden_capacity / K, (eden_capacity - absorb_size) / K, - young_gen->from_space()->used_in_bytes() / K, - young_gen->to_space()->used_in_bytes() / K, - young_gen->capacity_in_bytes() / K, new_young_size / K); - - // Fill the unused part of the old gen. - MutableSpace* const old_space = old_gen->object_space(); - HeapWord* const unused_start = old_space->top(); - size_t const unused_words = pointer_delta(old_space->end(), unused_start); - - if (unused_words > 0) { - if (unused_words < CollectedHeap::min_fill_size()) { - return false; // If the old gen cannot be filled, must give up. - } - CollectedHeap::fill_with_objects(unused_start, unused_words); - } - - // Take the live data from eden and set both top and end in the old gen to - // eden top. (Need to set end because reset_after_change() mangles the region - // from end to virtual_space->high() in debug builds). - HeapWord* const new_top = eden_space->top(); - old_gen->virtual_space()->expand_into(young_gen->virtual_space(), - absorb_size); - young_gen->reset_after_change(); - old_space->set_top(new_top); - old_space->set_end(new_top); - old_gen->reset_after_change(); - - // Update the object start array for the filler object and the data from eden. - ObjectStartArray* const start_array = old_gen->start_array(); - for (HeapWord* p = unused_start; p < new_top; p += oop(p)->size()) { - start_array->allocate_block(p); - } - - // Could update the promoted average here, but it is not typically updated at - // full GCs and the value to use is unclear. Something like - // - // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc. - - size_policy->set_bytes_absorbed_from_eden(absorb_size); - return true; -} - class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure { private: uint _worker_id; diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 29041e51cc4..12443939b98 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -1123,12 +1123,6 @@ class PSParallelCompact : AllStatic { static void enqueue_dense_prefix_tasks(TaskQueue& task_queue, uint parallel_gc_threads); - // If objects are left in eden after a collection, try to move the boundary - // and absorb them into the old gen. Returns true if eden was emptied. - static bool absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy, - PSYoungGen* young_gen, - PSOldGen* old_gen); - // Reset time since last full gc static void reset_millis_since_last_gc(); diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index db3cfff7c4d..bd42e3b3c11 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -803,8 +803,7 @@ bool PSScavenge::should_attempt_scavenge() { return result; } -// Adaptive size policy support. When the young generation/old generation -// boundary moves, _young_generation_boundary must be reset +// Adaptive size policy support. void PSScavenge::set_young_generation_boundary(HeapWord* v) { _young_generation_boundary = v; if (UseCompressedOops) { diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp index c2e83614156..2b9e5a8905d 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.hpp +++ b/src/hotspot/share/gc/parallel/psScavenge.hpp @@ -113,8 +113,7 @@ class PSScavenge: AllStatic { static void set_survivor_overflow(bool state) { _survivor_overflow = state; } - // Adaptive size policy support. When the young generation/old generation - // boundary moves, _young_generation_boundary must be reset + // Adaptive size policy support. static void set_young_generation_boundary(HeapWord* v); // Called by parallelScavengeHeap to init the tenuring threshold diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.cpp b/src/hotspot/share/gc/parallel/psVirtualspace.cpp index eb52aab5c4a..473a1f26854 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.cpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.cpp @@ -225,120 +225,3 @@ void PSVirtualSpace::print_space_boundaries_on(outputStream* st) const { st->print_cr(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")", p2i(low_boundary()), p2i(high()), p2i(high_boundary())); } - -PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs, - size_t alignment) : - PSVirtualSpace(alignment) -{ - set_reserved(rs); - set_committed(reserved_high_addr(), reserved_high_addr()); - DEBUG_ONLY(verify()); -} - -PSVirtualSpaceHighToLow::PSVirtualSpaceHighToLow(ReservedSpace rs) { - set_reserved(rs); - set_committed(reserved_high_addr(), reserved_high_addr()); - DEBUG_ONLY(verify()); -} - -bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) { - assert(is_aligned(bytes), "arg not aligned"); - DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); - - if (uncommitted_size() < bytes) { - return false; - } - - char* const base_addr = committed_low_addr() - bytes; - bool result = special() || - os::commit_memory(base_addr, bytes, alignment(), !ExecMem); - if (result) { - _committed_low_addr -= bytes; - } - - return result; -} - -bool PSVirtualSpaceHighToLow::shrink_by(size_t bytes) { - assert(is_aligned(bytes), "arg not aligned"); - DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); - - if (committed_size() < bytes) { - return false; - } - - char* const base_addr = committed_low_addr(); - bool result = special() || os::uncommit_memory(base_addr, bytes); - if (result) { - _committed_low_addr += bytes; - } - - return result; -} - -size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space, - size_t bytes) { - assert(is_aligned(bytes), "arg not aligned"); - assert(grows_down(), "this space must grow down"); - assert(other_space->grows_up(), "other space must grow up"); - assert(reserved_low_addr() == other_space->reserved_high_addr(), - "spaces not contiguous"); - assert(special() == other_space->special(), "one space is special in memory, the other is not"); - DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this)); - DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space)); - - size_t bytes_needed = bytes; - - // First use the uncommitted region in this space. - size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed); - if (tmp_bytes > 0) { - if (expand_by(tmp_bytes)) { - bytes_needed -= tmp_bytes; - } else { - return 0; - } - } - - // Next take from the uncommitted region in the other space, and commit it. - tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed); - if (tmp_bytes > 0) { - char* const commit_base = committed_low_addr() - tmp_bytes; - if (other_space->special() || - os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) { - // Reduce the reserved region in the other space. - other_space->set_reserved(other_space->reserved_low_addr(), - other_space->reserved_high_addr() - tmp_bytes, - other_space->special()); - - // Grow both reserved and committed in this space. - _reserved_low_addr -= tmp_bytes; - _committed_low_addr -= tmp_bytes; - bytes_needed -= tmp_bytes; - } else { - return bytes - bytes_needed; - } - } - - // Finally take from the already committed region in the other space. - tmp_bytes = bytes_needed; - if (tmp_bytes > 0) { - // Reduce both committed and reserved in the other space. - other_space->set_committed(other_space->committed_low_addr(), - other_space->committed_high_addr() - tmp_bytes); - other_space->set_reserved(other_space->reserved_low_addr(), - other_space->reserved_high_addr() - tmp_bytes, - other_space->special()); - - // Grow both reserved and committed in this space. - _reserved_low_addr -= tmp_bytes; - _committed_low_addr -= tmp_bytes; - } - - return bytes; -} - -void -PSVirtualSpaceHighToLow::print_space_boundaries_on(outputStream* st) const { - st->print_cr(" (" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT "]", - p2i(high_boundary()), p2i(low()), p2i(low_boundary())); -} diff --git a/src/hotspot/share/gc/parallel/psVirtualspace.hpp b/src/hotspot/share/gc/parallel/psVirtualspace.hpp index 8fe6a03af53..853264ed62d 100644 --- a/src/hotspot/share/gc/parallel/psVirtualspace.hpp +++ b/src/hotspot/share/gc/parallel/psVirtualspace.hpp @@ -132,25 +132,6 @@ class PSVirtualSpace : public CHeapObj { char* high_boundary() const { return reserved_high_addr(); } }; -// A virtual space that grows from high addresses to low addresses. -class PSVirtualSpaceHighToLow : public PSVirtualSpace { - friend class VMStructs; - public: - PSVirtualSpaceHighToLow(ReservedSpace rs, size_t alignment); - PSVirtualSpaceHighToLow(ReservedSpace rs); - - virtual bool expand_by(size_t bytes); - virtual bool shrink_by(size_t bytes); - virtual size_t expand_into(PSVirtualSpace* space, size_t bytes); - - virtual void print_space_boundaries_on(outputStream* st) const; - -#ifndef PRODUCT - // Debugging - virtual bool grows_up() const { return false; } -#endif -}; - // // PSVirtualSpace inlines. // diff --git a/src/hotspot/share/gc/parallel/psYoungGen.cpp b/src/hotspot/share/gc/parallel/psYoungGen.cpp index b6d252629f6..23f5319a1d5 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.cpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.cpp @@ -35,7 +35,7 @@ #include "runtime/java.hpp" #include "utilities/align.hpp" -PSYoungGen::PSYoungGen(size_t initial_size, size_t min_size, size_t max_size) : +PSYoungGen::PSYoungGen(ReservedSpace rs, size_t initial_size, size_t min_size, size_t max_size) : _reserved(), _virtual_space(NULL), _eden_space(NULL), @@ -48,7 +48,9 @@ PSYoungGen::PSYoungGen(size_t initial_size, size_t min_size, size_t max_size) : _eden_counters(NULL), _from_counters(NULL), _to_counters(NULL) -{} +{ + initialize(rs, GenAlignment); +} void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) { assert(_init_gen_size != 0, "Should have a finite size"); @@ -711,16 +713,6 @@ void PSYoungGen::print_on(outputStream* st) const { st->print(" to "); to_space()->print_on(st); } -size_t PSYoungGen::available_for_expansion() { - ShouldNotReachHere(); - return 0; -} - -size_t PSYoungGen::available_for_contraction() { - ShouldNotReachHere(); - return 0; -} - size_t PSYoungGen::available_to_min_gen() { assert(virtual_space()->committed_size() >= min_gen_size(), "Invariant"); return virtual_space()->committed_size() - min_gen_size(); @@ -773,10 +765,6 @@ size_t PSYoungGen::limit_gen_shrink(size_t bytes) { return align_down(bytes, virtual_space()->alignment()); } -void PSYoungGen::reset_after_change() { - ShouldNotReachHere(); -} - void PSYoungGen::reset_survivors_after_shrink() { _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(), (HeapWord*)virtual_space()->high_boundary()); diff --git a/src/hotspot/share/gc/parallel/psYoungGen.hpp b/src/hotspot/share/gc/parallel/psYoungGen.hpp index 92e44ae6a25..efddb8f6a59 100644 --- a/src/hotspot/share/gc/parallel/psYoungGen.hpp +++ b/src/hotspot/share/gc/parallel/psYoungGen.hpp @@ -36,7 +36,7 @@ class PSYoungGen : public CHeapObj { friend class ParallelScavengeHeap; friend class AdjoiningGenerations; - protected: + private: MemRegion _reserved; PSVirtualSpace* _virtual_space; @@ -51,10 +51,10 @@ class PSYoungGen : public CHeapObj { const size_t _max_gen_size; // Performance counters - PSGenerationCounters* _gen_counters; - SpaceCounters* _eden_counters; - SpaceCounters* _from_counters; - SpaceCounters* _to_counters; + PSGenerationCounters* _gen_counters; + SpaceCounters* _eden_counters; + SpaceCounters* _from_counters; + SpaceCounters* _to_counters; // Initialize the space boundaries void compute_initial_space_boundaries(); @@ -62,44 +62,41 @@ class PSYoungGen : public CHeapObj { // Space boundary helper void set_space_boundaries(size_t eden_size, size_t survivor_size); - virtual bool resize_generation(size_t eden_size, size_t survivor_size); - virtual void resize_spaces(size_t eden_size, size_t survivor_size); + bool resize_generation(size_t eden_size, size_t survivor_size); + void resize_spaces(size_t eden_size, size_t survivor_size); // Adjust the spaces to be consistent with the virtual space. void post_resize(); - // Return number of bytes that the generation can change. - // These should not be used by PSYoungGen - virtual size_t available_for_expansion(); - virtual size_t available_for_contraction(); - // Given a desired shrinkage in the size of the young generation, // return the actual size available for shrinkage. - virtual size_t limit_gen_shrink(size_t desired_change); + size_t limit_gen_shrink(size_t desired_change); // returns the number of bytes available from the current size // down to the minimum generation size. size_t available_to_min_gen(); // Return the number of bytes available for shrinkage considering // the location the live data in the generation. - virtual size_t available_to_live(); + size_t available_to_live(); + + void initialize(ReservedSpace rs, size_t alignment); + void initialize_work(); + void initialize_virtual_space(ReservedSpace rs, size_t alignment); public: // Initialize the generation. - PSYoungGen(size_t initial_byte_size, - size_t minimum_byte_size, - size_t maximum_byte_size); - void initialize_work(); - virtual void initialize(ReservedSpace rs, size_t alignment); - virtual void initialize_virtual_space(ReservedSpace rs, size_t alignment); + PSYoungGen(ReservedSpace rs, + size_t initial_byte_size, + size_t minimum_byte_size, + size_t maximum_byte_size); - MemRegion reserved() const { return _reserved; } + MemRegion reserved() const { return _reserved; } - bool is_in(const void* p) const { - return _virtual_space->contains((void *)p); + bool is_in(const void* p) const { + return _virtual_space->contains((void *)p); } - bool is_in_reserved(const void* p) const { - return reserved().contains((void *)p); + bool is_in_reserved(const void* p) const { + return reserved().contains((void *)p); } MutableSpace* eden_space() const { return _eden_space; } @@ -131,8 +128,7 @@ class PSYoungGen : public CHeapObj { // The max this generation can grow to size_t max_size() const { return _reserved.byte_size(); } - // The max this generation can grow to if the boundary between - // the generations are allowed to move. + // The max this generation can grow to size_t gen_size_limit() const { return _max_gen_size; } bool is_maximal_no_gc() const { @@ -152,16 +148,15 @@ class PSYoungGen : public CHeapObj { void oop_iterate(OopIterateClosure* cl); void object_iterate(ObjectClosure* cl); - virtual void reset_after_change(); - virtual void reset_survivors_after_shrink(); + void reset_survivors_after_shrink(); // Performance Counter support void update_counters(); // Debugging - do not use for time critical operations void print() const; - void print_on(outputStream* st) const; - virtual const char* name() const { return "PSYoungGen"; } + virtual void print_on(outputStream* st) const; + const char* name() const { return "PSYoungGen"; } void verify(); diff --git a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp index d3726177d20..d07eadfb514 100644 --- a/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp +++ b/src/hotspot/share/gc/parallel/vmStructs_parallelgc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ #ifndef SHARE_GC_PARALLEL_VMSTRUCTS_PARALLELGC_HPP #define SHARE_GC_PARALLEL_VMSTRUCTS_PARALLELGC_HPP -#include "gc/parallel/asPSOldGen.hpp" -#include "gc/parallel/asPSYoungGen.hpp" #include "gc/parallel/immutableSpace.hpp" #include "gc/parallel/mutableSpace.hpp" #include "gc/parallel/parallelScavengeHeap.hpp" @@ -88,9 +86,7 @@ declare_toplevel_type(ImmutableSpace) \ declare_type(MutableSpace, ImmutableSpace) \ declare_toplevel_type(PSYoungGen) \ - declare_type(ASPSYoungGen, PSYoungGen) \ declare_toplevel_type(PSOldGen) \ - declare_type(ASPSOldGen, PSOldGen) \ \ /*****************************/ \ /* Parallel GC pointer types */ \ @@ -100,9 +96,7 @@ declare_toplevel_type(ImmutableSpace*) \ declare_toplevel_type(MutableSpace*) \ declare_toplevel_type(PSYoungGen*) \ - declare_toplevel_type(ASPSYoungGen*) \ declare_toplevel_type(PSOldGen*) \ - declare_toplevel_type(ASPSOldGen*) \ declare_toplevel_type(ParallelScavengeHeap*) #define VM_INT_CONSTANTS_PARALLELGC(declare_constant, \ diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index 1fea3cfa269..b2a7118e8aa 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -253,19 +253,12 @@ void CardTable::resize_covered_region(MemRegion new_region) { committed_unique_to_self(ind, MemRegion(new_end_aligned, cur_committed.end())); if (!uncommit_region.is_empty()) { - // It is not safe to uncommit cards if the boundary between - // the generations is moving. A shrink can uncommit cards - // owned by generation A but being used by generation B. - if (!UseAdaptiveGCBoundary) { - if (!os::uncommit_memory((char*)uncommit_region.start(), - uncommit_region.byte_size())) { - assert(false, "Card table contraction failed"); - // The call failed so don't change the end of the - // committed region. This is better than taking the - // VM down. - new_end_aligned = _committed[ind].end(); - } - } else { + if (!os::uncommit_memory((char*)uncommit_region.start(), + uncommit_region.byte_size())) { + assert(false, "Card table contraction failed"); + // The call failed so don't change the end of the + // committed region. This is better than taking the + // VM down. new_end_aligned = _committed[ind].end(); } } diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index a6b18855e42..c3df0b1678c 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -420,9 +420,6 @@ product(bool, UseAdaptiveSizePolicyWithSystemGC, false, \ "Include statistics from System.gc() for adaptive size policy") \ \ - product(bool, UseAdaptiveGCBoundary, false, \ - "Allow young-old boundary to move") \ - \ develop(intx, PSAdaptiveSizePolicyResizeVirtualSpaceAlot, -1, \ "Resize the virtual spaces of the young or old generations") \ range(-1, 1) \ diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index ed8727b839f..9c9be36a167 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -206,7 +206,9 @@ public: } // Maximum number of elements allowed in the queue. This is two less - // than the actual queue size, for somewhat complicated reasons. + // than the actual queue size, so that a full queue can be distinguished + // from underflow involving pop_local and concurrent pop_global operations + // in GenericTaskQueue. uint max_elems() const { return N - 2; } // Total size of queue. @@ -267,8 +269,7 @@ public: #endif private: - // Slow paths for push, pop_local. (pop_global has no fast path.) - bool push_slow(E t, uint dirty_n_elems); + // Slow path for pop_local, dealing with possible conflict with pop_global. bool pop_local_slow(uint localBot, Age oldAge); public: diff --git a/src/hotspot/share/gc/shared/taskqueue.inline.hpp b/src/hotspot/share/gc/shared/taskqueue.inline.hpp index ef209e17210..54723685c5c 100644 --- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,31 +57,23 @@ inline GenericTaskQueue::~GenericTaskQueue() { ArrayAllocator::free(const_cast(_elems), N); } -template -bool GenericTaskQueue::push_slow(E t, uint dirty_n_elems) { - if (dirty_n_elems == N - 1) { - // Actually means 0, so do the push. - uint localBot = _bottom; - // g++ complains if the volatile result of the assignment is - // unused, so we cast the volatile away. We cannot cast directly - // to void, because gcc treats that as not using the result of the - // assignment. However, casting to E& means that we trigger an - // unused-value warning. So, we cast the E& to void. - (void)const_cast(_elems[localBot] = t); - Atomic::release_store(&_bottom, increment_index(localBot)); - TASKQUEUE_STATS_ONLY(stats.record_push()); - return true; - } - return false; -} - template inline bool GenericTaskQueue::push(E t) { uint localBot = _bottom; assert(localBot < N, "_bottom out of range."); idx_t top = _age.top(); uint dirty_n_elems = dirty_size(localBot, top); - assert(dirty_n_elems < N, "n_elems out of range."); + // A dirty_size of N-1 cannot happen in push. Considering only push: + // (1) dirty_n_elems is initially 0. + // (2) push adds an element iff dirty_n_elems < max_elems(), which is N - 2. + // (3) only push adding an element can increase dirty_n_elems. + // => dirty_n_elems <= N - 2, by induction + // => dirty_n_elems < N - 1, invariant + // + // A pop_global that is concurrent with push cannot produce a state where + // dirty_size == N-1. pop_global only removes an element if dirty_elems > 0, + // so can't underflow to -1 (== N-1) with push. + assert(dirty_n_elems <= max_elems(), "n_elems out of range."); if (dirty_n_elems < max_elems()) { // g++ complains if the volatile result of the assignment is // unused, so we cast the volatile away. We cannot cast directly @@ -92,9 +84,8 @@ GenericTaskQueue::push(E t) { Atomic::release_store(&_bottom, increment_index(localBot)); TASKQUEUE_STATS_ONLY(stats.record_push()); return true; - } else { - return push_slow(t, dirty_n_elems); } + return false; // Queue is full. } template diff --git a/src/hotspot/share/gc/shared/workgroup.hpp b/src/hotspot/share/gc/shared/workgroup.hpp index a2455c01114..260a556ac02 100644 --- a/src/hotspot/share/gc/shared/workgroup.hpp +++ b/src/hotspot/share/gc/shared/workgroup.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -324,6 +324,8 @@ class SubTasksDone: public CHeapObj { // Set all tasks to unclaimed. void clear(); + NONCOPYABLE(SubTasksDone); + public: // Initializes "this" to a state in which there are "n" tasks to be // processed, none of the which are originally claimed. The number of diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index 6fa3082f97d..b8f03440e03 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -193,7 +193,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native_impl(oop obj, T* load_ad } ShenandoahMarkingContext* const marking_context = _heap->marking_context(); - if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) { + if (_heap->is_concurrent_weak_root_in_progress() && !marking_context->is_marked(obj)) { Thread* thr = Thread::current(); if (thr->is_Java_thread()) { return NULL; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp index 475d0674736..14fd869ec8a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -88,7 +88,9 @@ ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() template template void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { - assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_weak_root_in_progress() || + _heap->is_concurrent_strong_root_in_progress(), + "Only do this in root processing phase"); T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) { @@ -119,7 +121,9 @@ ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsC } void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { - assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_weak_root_in_progress() || + _heap->is_concurrent_strong_root_in_progress(), + "Only do this in root processing phase"); oop obj = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(obj)) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 07d19fc4d6b..3714b820b67 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -248,7 +248,7 @@ public: _bs(ShenandoahBarrierSet::barrier_set()->barrier_set_nmethod()) {} virtual void do_nmethod(nmethod* nm) { - assert(_heap->is_concurrent_root_in_progress(), "Only this phase"); + assert(_heap->is_concurrent_weak_root_in_progress(), "Only this phase"); if (failed()) { return; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp index e80e56b711c..0808689d9f1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -28,7 +28,6 @@ #include "code/codeCache.hpp" #include "gc/shenandoah/shenandoahSharedVariables.hpp" #include "gc/shenandoah/shenandoahLock.hpp" -#include "gc/shenandoah/shenandoahNMethod.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" #include "memory/allocation.hpp" #include "memory/iterator.hpp" @@ -36,6 +35,9 @@ class ShenandoahHeap; class ShenandoahHeapRegion; +class ShenandoahNMethodTable; +class ShenandoahNMethodTableSnapshot; +class WorkGang; class ShenandoahParallelCodeHeapIterator { friend class CodeCache; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp index 7bcbd168f75..37fe9be79d5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.cpp @@ -41,7 +41,6 @@ ShenandoahCollectionSet::ShenandoahCollectionSet(ShenandoahHeap* heap, char* hea _biased_cset_map(_map_space.base()), _heap(heap), _garbage(0), - _live_data(0), _used(0), _region_count(0), _current_index(0) { @@ -85,9 +84,8 @@ void ShenandoahCollectionSet::add_region(ShenandoahHeapRegion* r) { assert(Thread::current()->is_VM_thread(), "Must be VMThread"); assert(!is_in(r), "Already in collection set"); _cset_map[r->index()] = 1; - _region_count ++; + _region_count++; _garbage += r->garbage(); - _live_data += r->get_live_data_bytes(); _used += r->used(); // Update the region status too. State transition would be checked internally. @@ -105,7 +103,6 @@ void ShenandoahCollectionSet::clear() { #endif _garbage = 0; - _live_data = 0; _used = 0; _region_count = 0; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp index e69561f2242..bfb924671f1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.hpp @@ -43,7 +43,6 @@ private: ShenandoahHeap* const _heap; size_t _garbage; - size_t _live_data; size_t _used; size_t _region_count; @@ -78,7 +77,6 @@ public: void print_on(outputStream* out) const; size_t used() const { return _used; } - size_t live_data() const { return _live_data; } size_t garbage() const { return _garbage; } void clear(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 4a25105a5c5..c6da9794f25 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -26,12 +26,13 @@ #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" +#include "gc/shenandoah/shenandoahControlThread.hpp" #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeuristics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" -#include "gc/shenandoah/shenandoahControlThread.hpp" +#include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "gc/shenandoah/shenandoahVMOperations.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" @@ -48,6 +49,7 @@ ShenandoahControlThread::ShenandoahControlThread() : _degen_point(ShenandoahHeap::_degenerated_outside_cycle), _allocs_seen(0) { + reset_gc_id(); create_and_start(ShenandoahCriticalControlThreadPriority ? CriticalPriority : NearMaxPriority); _periodic_task.enroll(); _periodic_satb_flush_task.enroll(); @@ -173,6 +175,9 @@ void ShenandoahControlThread::run_service() { assert (!gc_requested || cause != GCCause::_last_gc_cause, "GC cause should be set"); if (gc_requested) { + // GC is starting, bump the internal ID + update_gc_id(); + heap->reset_bytes_allocated_since_gc_start(); // Use default constructor to snapshot the Metaspace state before GC. @@ -342,18 +347,32 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau // Complete marking under STW, and start evacuation heap->vmop_entry_final_mark(); - // Evacuate concurrent roots - heap->entry_roots(); + // Process weak roots that might still point to regions that would be broken by cleanup + if (heap->is_concurrent_weak_root_in_progress()) { + heap->entry_weak_roots(); + } // Final mark might have reclaimed some immediate garbage, kick cleanup to reclaim // the space. This would be the last action if there is nothing to evacuate. - heap->entry_cleanup(); + heap->entry_cleanup_early(); { ShenandoahHeapLocker locker(heap->lock()); heap->free_set()->log_status(); } + // Perform concurrent class unloading + if (heap->is_concurrent_weak_root_in_progress()) { + heap->entry_class_unloading(); + } + + // Processing strong roots + // This may be skipped if there is nothing to update/evacuate. + // If so, strong_root_in_progress would be unset. + if (heap->is_concurrent_strong_root_in_progress()) { + heap->entry_strong_roots(); + } + // Continue the cycle with evacuation and optional update-refs. // This may be skipped if there is nothing to evacuate. // If so, evac_in_progress would be unset by collection set preparation code. @@ -370,7 +389,7 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau heap->vmop_entry_final_updaterefs(); // Update references freed up collection set, kick the cleanup to reclaim the space. - heap->entry_cleanup(); + heap->entry_cleanup_complete(); } // Cycle is complete @@ -467,10 +486,20 @@ void ShenandoahControlThread::request_gc(GCCause::Cause cause) { } void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) { - _requested_gc_cause = cause; - _gc_requested.set(); + // Make sure we have at least one complete GC cycle before unblocking + // from the explicit GC request. + // + // This is especially important for weak references cleanup and/or native + // resources (e.g. DirectByteBuffers) machinery: when explicit GC request + // comes very late in the already running cycle, it would miss lots of new + // opportunities for cleanup that were made available before the caller + // requested the GC. + size_t required_gc_id = get_gc_id() + 1; + MonitorLocker ml(&_gc_waiters_lock); - while (_gc_requested.is_set()) { + while (get_gc_id() < required_gc_id) { + _gc_requested.set(); + _requested_gc_cause = cause; ml.wait(); } } @@ -566,6 +595,18 @@ void ShenandoahControlThread::set_forced_counters_update(bool value) { _force_counters_update.set_cond(value); } +void ShenandoahControlThread::reset_gc_id() { + Atomic::store(&_gc_id, (size_t)0); +} + +void ShenandoahControlThread::update_gc_id() { + Atomic::inc(&_gc_id); +} + +size_t ShenandoahControlThread::get_gc_id() { + return Atomic::load(&_gc_id); +} + void ShenandoahControlThread::print() const { print_on(tty); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp index 9c59faba024..523a1eb9be4 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp @@ -88,6 +88,8 @@ private: shenandoah_padding(0); volatile size_t _allocs_seen; shenandoah_padding(1); + volatile size_t _gc_id; + shenandoah_padding(2); bool check_cancellation_or_degen(ShenandoahHeap::ShenandoahDegenPoint point); void service_concurrent_normal_cycle(GCCause::Cause cause); @@ -99,6 +101,10 @@ private: void notify_alloc_failure_waiters(); bool is_alloc_failure_gc(); + void reset_gc_id(); + void update_gc_id(); + size_t get_gc_id(); + void notify_gc_waiters(); // Handle GC request. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index 23c3b444c07..bf63bf05a3e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -125,18 +125,10 @@ HeapWord* ShenandoahFreeSet::allocate_single(ShenandoahAllocRequest& req, bool& } } - // Try to mix the allocation into the mutator view: - if (ShenandoahAllowMixedAllocs) { - for (size_t c = _mutator_rightmost + 1; c > _mutator_leftmost; c--) { - size_t idx = c - 1; - if (is_mutator_free(idx)) { - HeapWord* result = try_allocate_in(_heap->get_region(idx), req, in_new_region); - if (result != NULL) { - return result; - } - } - } - } + // No dice. Do not try to mix mutator and GC allocations, because + // URWM moves due to GC allocations would expose unparsable mutator + // allocations. + break; } default: @@ -149,7 +141,7 @@ HeapWord* ShenandoahFreeSet::allocate_single(ShenandoahAllocRequest& req, bool& HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, ShenandoahAllocRequest& req, bool& in_new_region) { assert (!has_no_alloc_capacity(r), "Performance: should avoid full regions on this path: " SIZE_FORMAT, r->index()); - if (_heap->is_concurrent_root_in_progress() && + if (_heap->is_concurrent_weak_root_in_progress() && r->is_trash()) { return NULL; } @@ -337,7 +329,7 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) { } bool ShenandoahFreeSet::can_allocate_from(ShenandoahHeapRegion *r) { - return r->is_empty() || (r->is_trash() && !_heap->is_concurrent_root_in_progress()); + return r->is_empty() || (r->is_trash() && !_heap->is_concurrent_weak_root_in_progress()); } size_t ShenandoahFreeSet::alloc_capacity(ShenandoahHeapRegion *r) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 4a206a9b71a..c59db64f3fa 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -487,7 +487,6 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : _heap = this; log_info(gc, init)("GC threads: " UINT32_FORMAT " parallel, " UINT32_FORMAT " concurrent", ParallelGCThreads, ConcGCThreads); - log_info(gc, init)("Reference processing: %s", ParallelRefProcEnabled ? "parallel" : "serial"); BarrierSet::set_barrier_set(new ShenandoahBarrierSet(this)); @@ -555,14 +554,16 @@ void ShenandoahHeap::print_on(outputStream* st) const { proper_unit_for_byte_size(ShenandoahHeapRegion::region_size_bytes())); st->print("Status: "); - if (has_forwarded_objects()) st->print("has forwarded objects, "); - if (is_concurrent_mark_in_progress()) st->print("marking, "); - if (is_evacuation_in_progress()) st->print("evacuating, "); - if (is_update_refs_in_progress()) st->print("updating refs, "); - if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); - if (is_full_gc_in_progress()) st->print("full gc, "); - if (is_full_gc_move_in_progress()) st->print("full gc move, "); - if (is_concurrent_root_in_progress()) st->print("concurrent roots, "); + if (has_forwarded_objects()) st->print("has forwarded objects, "); + if (is_concurrent_mark_in_progress()) st->print("marking, "); + if (is_evacuation_in_progress()) st->print("evacuating, "); + if (is_update_refs_in_progress()) st->print("updating refs, "); + if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); + if (is_full_gc_in_progress()) st->print("full gc, "); + if (is_full_gc_move_in_progress()) st->print("full gc move, "); + if (is_concurrent_weak_root_in_progress()) st->print("concurrent weak roots, "); + if (is_concurrent_strong_root_in_progress() && + !is_concurrent_weak_root_in_progress()) st->print("concurrent strong roots, "); if (cancelled_gc()) { st->print("cancelled"); @@ -1234,7 +1235,7 @@ private: T o = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); - if (_heap->is_concurrent_root_in_progress() && !_marking_context->is_marked(obj)) { + if (_heap->is_concurrent_weak_root_in_progress() && !_marking_context->is_marked(obj)) { // There may be dead oops in weak roots in concurrent root phase, do not touch them. return; } @@ -1376,11 +1377,14 @@ public: ShenandoahInitMarkUpdateRegionStateClosure() : _ctx(ShenandoahHeap::heap()->marking_context()) {} void heap_region_do(ShenandoahHeapRegion* r) { + assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index()); if (r->is_active()) { - r->clear_live_data(); - _ctx->capture_top_at_mark_start(r); + // Check if region needs updating its TAMS. We have updated it already during concurrent + // reset, so it is very likely we don't need to do another write here. + if (_ctx->top_at_mark_start(r) != r->top()) { + _ctx->capture_top_at_mark_start(r); + } } else { - assert(!r->has_live(), "Region " SIZE_FORMAT " should have no live data", r->index()); assert(_ctx->top_at_mark_start(r) == r->top(), "Region " SIZE_FORMAT " should already have correct TAMS", r->index()); } @@ -1520,7 +1524,11 @@ void ShenandoahHeap::op_final_mark() { assert_pinned_region_status(); } - // Force the threads to reacquire their TLABs outside the collection set. + // Retire the TLABs, which will force threads to reacquire their TLABs after the pause. + // This is needed for two reasons. Strong one: new allocations would be with new freeset, + // which would be outside the collection set, so no cset writes would happen there. + // Weaker one: new allocations would happen past update watermark, and so less work would + // be needed for reference updates (would update the large filler instead). { ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::retire_tlabs); make_parsable(true); @@ -1622,22 +1630,23 @@ void ShenandoahHeap::op_updaterefs() { update_heap_references(true); } -void ShenandoahHeap::op_cleanup() { +void ShenandoahHeap::op_cleanup_early() { + free_set()->recycle_trash(); +} + +void ShenandoahHeap::op_cleanup_complete() { free_set()->recycle_trash(); } class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask { private: ShenandoahVMRoots _vm_roots; - ShenandoahWeakRoots _weak_roots; ShenandoahClassLoaderDataRoots _cld_roots; ShenandoahConcurrentStringDedupRoots _dedup_roots; - bool _include_weak_roots; public: - ShenandoahConcurrentRootsEvacUpdateTask(bool include_weak_roots) : - AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task"), - _include_weak_roots(include_weak_roots) { + ShenandoahConcurrentRootsEvacUpdateTask() : + AbstractGangTask("Shenandoah Evacuate/Update Concurrent Strong Roots Task") { } void work(uint worker_id) { @@ -1646,17 +1655,13 @@ public: // vm_roots and weak_roots are OopStorage backed roots, concurrent iteration // may race against OopStorage::release() calls. ShenandoahEvacUpdateOopStorageRootsClosure cl; - _vm_roots.oops_do(&cl); - - if (_include_weak_roots) { - _weak_roots.oops_do(&cl); - } + _vm_roots.oops_do(&cl, worker_id); } { ShenandoahEvacuateUpdateRootsClosure<> cl; CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong); - _cld_roots.cld_do(&clds); + _cld_roots.cld_do(&clds, worker_id); } { @@ -1726,6 +1731,20 @@ void ShenandoahEvacUpdateCleanupOopStorageRootsClosure::reset_dead_counter() { _dead_counter = 0; } +class ShenandoahIsCLDAliveClosure : public CLDClosure { +public: + void do_cld(ClassLoaderData* cld) { + cld->is_alive(); + } +}; + +class ShenandoahIsNMethodAliveClosure: public NMethodClosure { +public: + void do_nmethod(nmethod* n) { + n->is_unloading(); + } +}; + // This task not only evacuates/updates marked weak roots, but also "NULL" // dead weak roots. class ShenandoahConcurrentWeakRootsEvacUpdateTask : public AbstractGangTask { @@ -1735,64 +1754,127 @@ private: ShenandoahWeakRoot _resolved_method_table_roots; ShenandoahWeakRoot _vm_roots; + // Roots related to concurrent class unloading + ShenandoahClassLoaderDataRoots + _cld_roots; + ShenandoahConcurrentNMethodIterator _nmethod_itr; + bool _concurrent_class_unloading; + public: ShenandoahConcurrentWeakRootsEvacUpdateTask() : AbstractGangTask("Shenandoah Concurrent Weak Root Task"), _jni_roots(OopStorageSet::jni_weak(), ShenandoahPhaseTimings::JNIWeakRoots), _string_table_roots(OopStorageSet::string_table_weak(), ShenandoahPhaseTimings::StringTableRoots), _resolved_method_table_roots(OopStorageSet::resolved_method_table_weak(), ShenandoahPhaseTimings::ResolvedMethodTableRoots), - _vm_roots(OopStorageSet::vm_weak(), ShenandoahPhaseTimings::VMWeakRoots) { + _vm_roots(OopStorageSet::vm_weak(), ShenandoahPhaseTimings::VMWeakRoots), + _nmethod_itr(ShenandoahCodeRoots::table()), + _concurrent_class_unloading(ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { StringTable::reset_dead_counter(); ResolvedMethodTable::reset_dead_counter(); + if (_concurrent_class_unloading) { + MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + _nmethod_itr.nmethods_do_begin(); + } } ~ShenandoahConcurrentWeakRootsEvacUpdateTask() { StringTable::finish_dead_counter(); ResolvedMethodTable::finish_dead_counter(); + if (_concurrent_class_unloading) { + MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + _nmethod_itr.nmethods_do_end(); + } } void work(uint worker_id) { - ShenandoahEvacOOMScope oom; - // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration - // may race against OopStorage::release() calls. - ShenandoahEvacUpdateCleanupOopStorageRootsClosure cl; - _jni_roots.oops_do(&cl, worker_id); - _vm_roots.oops_do(&cl, worker_id); + { + ShenandoahEvacOOMScope oom; + // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration + // may race against OopStorage::release() calls. + ShenandoahEvacUpdateCleanupOopStorageRootsClosure cl; + _jni_roots.oops_do(&cl, worker_id); + _vm_roots.oops_do(&cl, worker_id); - cl.reset_dead_counter(); - _string_table_roots.oops_do(&cl, worker_id); - StringTable::inc_dead_counter(cl.dead_counter()); + cl.reset_dead_counter(); + _string_table_roots.oops_do(&cl, worker_id); + StringTable::inc_dead_counter(cl.dead_counter()); - cl.reset_dead_counter(); - _resolved_method_table_roots.oops_do(&cl, worker_id); - ResolvedMethodTable::inc_dead_counter(cl.dead_counter()); + cl.reset_dead_counter(); + _resolved_method_table_roots.oops_do(&cl, worker_id); + ResolvedMethodTable::inc_dead_counter(cl.dead_counter()); + } + + // If we are going to perform concurrent class unloading later on, we need to + // cleanup the weak oops in CLD and determinate nmethod's unloading state, so that we + // can cleanup immediate garbage sooner. + if (_concurrent_class_unloading) { + // Applies ShenandoahIsCLDAlive closure to CLDs, native barrier will either NULL the + // CLD's holder or evacuate it. + ShenandoahIsCLDAliveClosure is_cld_alive; + _cld_roots.cld_do(&is_cld_alive, worker_id); + + // Applies ShenandoahIsNMethodAliveClosure to registered nmethods. + // The closure calls nmethod->is_unloading(). The is_unloading + // state is cached, therefore, during concurrent class unloading phase, + // we will not touch the metadata of unloading nmethods + ShenandoahIsNMethodAliveClosure is_nmethod_alive; + _nmethod_itr.nmethods_do(&is_nmethod_alive); + } } }; -void ShenandoahHeap::op_roots() { - if (is_concurrent_root_in_progress()) { - if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - // Concurrent weak root processing - ShenandoahConcurrentWeakRootsEvacUpdateTask task; - workers()->run_task(&task); - - _unloader.unload(); +void ShenandoahHeap::op_weak_roots() { + if (is_concurrent_weak_root_in_progress()) { + // Concurrent weak root processing + ShenandoahConcurrentWeakRootsEvacUpdateTask task; + workers()->run_task(&task); + if (!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + set_concurrent_weak_root_in_progress(false); } + } +} - if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { - ShenandoahConcurrentRootsEvacUpdateTask task(!ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()); - workers()->run_task(&task); +void ShenandoahHeap::op_class_unloading() { + assert (is_concurrent_weak_root_in_progress() && + ShenandoahConcurrentRoots::should_do_concurrent_class_unloading(), + "Checked by caller"); + _unloader.unload(); + set_concurrent_weak_root_in_progress(false); +} + +void ShenandoahHeap::op_strong_roots() { + assert(is_concurrent_strong_root_in_progress(), "Checked by caller"); + ShenandoahConcurrentRootsEvacUpdateTask task; + workers()->run_task(&task); + set_concurrent_strong_root_in_progress(false); +} + +class ShenandoahResetUpdateRegionStateClosure : public ShenandoahHeapRegionClosure { +private: + ShenandoahMarkingContext* const _ctx; +public: + ShenandoahResetUpdateRegionStateClosure() : _ctx(ShenandoahHeap::heap()->marking_context()) {} + + void heap_region_do(ShenandoahHeapRegion* r) { + if (r->is_active()) { + // Reset live data and set TAMS optimistically. We would recheck these under the pause + // anyway to capture any updates that happened since now. + r->clear_live_data(); + _ctx->capture_top_at_mark_start(r); } } - set_concurrent_root_in_progress(false); -} + bool is_thread_safe() { return true; } +}; void ShenandoahHeap::op_reset() { if (ShenandoahPacing) { pacer()->setup_for_reset(); } reset_mark_bitmap(); + + ShenandoahResetUpdateRegionStateClosure cl; + parallel_heap_region_iterate(&cl); } void ShenandoahHeap::op_preclean() { @@ -1872,7 +1954,7 @@ void ShenandoahHeap::op_degenerated(ShenandoahDegenPoint point) { ShenandoahCodeRoots::disarm_nmethods(); } - op_cleanup(); + op_cleanup_early(); case _degenerated_evac: // If heuristics thinks we should do the cycle, this flag would be set, @@ -1935,7 +2017,7 @@ void ShenandoahHeap::op_degenerated(ShenandoahDegenPoint point) { } } - op_cleanup(); + op_cleanup_complete(); break; default: @@ -2014,28 +2096,44 @@ void ShenandoahHeap::set_evacuation_in_progress(bool in_progress) { set_gc_state_mask(EVACUATION, in_progress); } -void ShenandoahHeap::set_concurrent_root_in_progress(bool in_progress) { +void ShenandoahHeap::set_concurrent_strong_root_in_progress(bool in_progress) { assert(ShenandoahConcurrentRoots::can_do_concurrent_roots(), "Why set the flag?"); if (in_progress) { - _concurrent_root_in_progress.set(); + _concurrent_strong_root_in_progress.set(); } else { - _concurrent_root_in_progress.unset(); + _concurrent_strong_root_in_progress.unset(); + } +} + +void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool in_progress) { + assert(ShenandoahConcurrentRoots::can_do_concurrent_roots(), "Why set the flag?"); + if (in_progress) { + _concurrent_weak_root_in_progress.set(); + } else { + _concurrent_weak_root_in_progress.unset(); } } void ShenandoahHeap::ref_processing_init() { assert(_max_workers > 0, "Sanity"); + bool mt_processing = ParallelRefProcEnabled && (ParallelGCThreads > 1); + bool mt_discovery = _max_workers > 1; + _ref_processor = new ReferenceProcessor(&_subject_to_discovery, // is_subject_to_discovery - ParallelRefProcEnabled, // MT processing + mt_processing, // MT processing _max_workers, // Degree of MT processing - true, // MT discovery + mt_discovery, // MT discovery _max_workers, // Degree of MT discovery false, // Reference discovery is not atomic NULL, // No closure, should be installed before use true); // Scale worker threads + log_info(gc, init)("Reference processing: %s discovery, %s processing", + mt_discovery ? "parallel" : "serial", + mt_processing ? "parallel" : "serial"); + shenandoah_assert_rp_isalive_not_installed(); } @@ -2293,7 +2391,8 @@ ConcurrentGCTimer* ShenandoahHeap::gc_timer() const { void ShenandoahHeap::prepare_concurrent_roots() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { - set_concurrent_root_in_progress(true); + set_concurrent_strong_root_in_progress(!collection_set()->is_empty()); + set_concurrent_weak_root_in_progress(true); } } @@ -2411,14 +2510,7 @@ void ShenandoahHeap::op_init_updaterefs() { set_update_refs_in_progress(true); - { - ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::init_update_refs_prepare); - - make_parsable(true); - - // Reset iterator. - _update_refs_iterator.reset(); - } + _update_refs_iterator.reset(); if (ShenandoahPacing) { pacer()->setup_for_updaterefs(); @@ -2603,7 +2695,6 @@ void ShenandoahHeap::safepoint_synchronize_end() { void ShenandoahHeap::vmop_entry_init_mark() { TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark_gross); try_inject_alloc_failure(); @@ -2613,7 +2704,6 @@ void ShenandoahHeap::vmop_entry_init_mark() { void ShenandoahHeap::vmop_entry_final_mark() { TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark_gross); try_inject_alloc_failure(); @@ -2623,7 +2713,6 @@ void ShenandoahHeap::vmop_entry_final_mark() { void ShenandoahHeap::vmop_entry_init_updaterefs() { TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs_gross); try_inject_alloc_failure(); @@ -2633,7 +2722,6 @@ void ShenandoahHeap::vmop_entry_init_updaterefs() { void ShenandoahHeap::vmop_entry_final_updaterefs() { TraceCollectorStats tcs(monitoring_support()->stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs_gross); try_inject_alloc_failure(); @@ -2643,7 +2731,6 @@ void ShenandoahHeap::vmop_entry_final_updaterefs() { void ShenandoahHeap::vmop_entry_full(GCCause::Cause cause) { TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc_gross); try_inject_alloc_failure(); @@ -2653,7 +2740,6 @@ void ShenandoahHeap::vmop_entry_full(GCCause::Cause cause) { void ShenandoahHeap::vmop_degenerated(ShenandoahDegenPoint point) { TraceCollectorStats tcs(monitoring_support()->full_stw_collection_counters()); - ShenandoahGCPhase total(ShenandoahPhaseTimings::total_pause_gross); ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc_gross); VM_ShenandoahDegeneratedGC degenerated_gc((int)point); @@ -2665,7 +2751,6 @@ void ShenandoahHeap::entry_init_mark() { ShenandoahPausePhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_mark); ShenandoahWorkerScope scope(workers(), @@ -2680,7 +2765,6 @@ void ShenandoahHeap::entry_final_mark() { ShenandoahPausePhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_mark); ShenandoahWorkerScope scope(workers(), @@ -2695,7 +2779,6 @@ void ShenandoahHeap::entry_init_updaterefs() { ShenandoahPausePhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::init_update_refs); // No workers used in this phase, no setup required @@ -2708,7 +2791,6 @@ void ShenandoahHeap::entry_final_updaterefs() { ShenandoahPausePhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::final_update_refs); ShenandoahWorkerScope scope(workers(), @@ -2720,10 +2802,9 @@ void ShenandoahHeap::entry_final_updaterefs() { void ShenandoahHeap::entry_full(GCCause::Cause cause) { static const char* msg = "Pause Full"; - ShenandoahPausePhase gc_phase(msg); + ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::full_gc); ShenandoahWorkerScope scope(workers(), @@ -2736,10 +2817,9 @@ void ShenandoahHeap::entry_full(GCCause::Cause cause) { void ShenandoahHeap::entry_degenerated(int point) { ShenandoahDegenPoint dpoint = (ShenandoahDegenPoint)point; const char* msg = degen_event_message(dpoint); - ShenandoahPausePhase gc_phase(msg); + ShenandoahPausePhase gc_phase(msg, true /* log_heap_usage */); EventMark em("%s", msg); - ShenandoahGCPhase total_phase(ShenandoahPhaseTimings::total_pause); ShenandoahGCPhase phase(ShenandoahPhaseTimings::degen_gc); ShenandoahWorkerScope scope(workers(), @@ -2800,32 +2880,75 @@ void ShenandoahHeap::entry_updaterefs() { op_updaterefs(); } -void ShenandoahHeap::entry_roots() { - static const char* msg = "Concurrent roots processing"; +void ShenandoahHeap::entry_weak_roots() { + static const char* msg = "Concurrent weak roots"; ShenandoahConcurrentPhase gc_phase(msg); EventMark em("%s", msg); - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_weak_roots); ShenandoahWorkerScope scope(workers(), ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), - "concurrent root processing"); + "concurrent weak root"); try_inject_alloc_failure(); - op_roots(); + op_weak_roots(); } -void ShenandoahHeap::entry_cleanup() { +void ShenandoahHeap::entry_class_unloading() { + static const char* msg = "Concurrent class unloading"; + ShenandoahConcurrentPhase gc_phase(msg); + EventMark em("%s", msg); + + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_class_unloading); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), + "concurrent class unloading"); + + try_inject_alloc_failure(); + op_class_unloading(); +} + +void ShenandoahHeap::entry_strong_roots() { + static const char* msg = "Concurrent strong roots"; + ShenandoahConcurrentPhase gc_phase(msg); + EventMark em("%s", msg); + + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_strong_roots); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(), + "concurrent strong root"); + + try_inject_alloc_failure(); + op_strong_roots(); +} + +void ShenandoahHeap::entry_cleanup_early() { static const char* msg = "Concurrent cleanup"; ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */); EventMark em("%s", msg); - ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup); + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_early); // This phase does not use workers, no need for setup try_inject_alloc_failure(); - op_cleanup(); + op_cleanup_early(); +} + +void ShenandoahHeap::entry_cleanup_complete() { + static const char* msg = "Concurrent cleanup"; + ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */); + EventMark em("%s", msg); + + ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_cleanup_complete); + + // This phase does not use workers, no need for setup + + try_inject_alloc_failure(); + op_cleanup_complete(); } void ShenandoahHeap::entry_reset() { @@ -2863,7 +2986,7 @@ void ShenandoahHeap::entry_preclean() { void ShenandoahHeap::entry_uncommit(double shrink_before) { static const char *msg = "Concurrent uncommit"; - ShenandoahConcurrentPhase gc_phase(msg); + ShenandoahConcurrentPhase gc_phase(msg, true /* log_heap_usage */); EventMark em("%s", msg); ShenandoahGCSubPhase phase(ShenandoahPhaseTimings::conc_uncommit); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index e9c4f000df5..723b7c817be 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -276,7 +276,8 @@ private: ShenandoahSharedFlag _full_gc_in_progress; ShenandoahSharedFlag _full_gc_move_in_progress; ShenandoahSharedFlag _progress_last_gc; - ShenandoahSharedFlag _concurrent_root_in_progress; + ShenandoahSharedFlag _concurrent_strong_root_in_progress; + ShenandoahSharedFlag _concurrent_weak_root_in_progress; void set_gc_state_all_threads(char state); void set_gc_state_mask(uint mask, bool value); @@ -292,7 +293,8 @@ public: void set_full_gc_in_progress(bool in_progress); void set_full_gc_move_in_progress(bool in_progress); void set_has_forwarded_objects(bool cond); - void set_concurrent_root_in_progress(bool cond); + void set_concurrent_strong_root_in_progress(bool cond); + void set_concurrent_weak_root_in_progress(bool cond); inline bool is_stable() const; inline bool is_idle() const; @@ -305,7 +307,8 @@ public: inline bool has_forwarded_objects() const; inline bool is_gc_in_progress_mask(uint mask) const; inline bool is_stw_gc_in_progress() const; - inline bool is_concurrent_root_in_progress() const; + inline bool is_concurrent_strong_root_in_progress() const; + inline bool is_concurrent_weak_root_in_progress() const; // ---------- GC cancellation and degeneration machinery // @@ -394,10 +397,13 @@ public: void entry_reset(); void entry_mark(); void entry_preclean(); - void entry_roots(); - void entry_cleanup(); + void entry_weak_roots(); + void entry_class_unloading(); + void entry_strong_roots(); + void entry_cleanup_early(); void entry_evac(); void entry_updaterefs(); + void entry_cleanup_complete(); void entry_uncommit(double shrink_before); private: @@ -414,11 +420,14 @@ private: void op_reset(); void op_mark(); void op_preclean(); - void op_roots(); - void op_cleanup(); + void op_weak_roots(); + void op_class_unloading(); + void op_strong_roots(); + void op_cleanup_early(); void op_conc_evac(); void op_stw_evac(); void op_updaterefs(); + void op_cleanup_complete(); void op_uncommit(double shrink_before); // Messages for GC trace events, they have to be immortal for diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index edea8db3f01..eae78fabc79 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -378,8 +378,12 @@ inline bool ShenandoahHeap::is_stw_gc_in_progress() const { return is_full_gc_in_progress() || is_degenerated_gc_in_progress(); } -inline bool ShenandoahHeap::is_concurrent_root_in_progress() const { - return _concurrent_root_in_progress.is_set(); +inline bool ShenandoahHeap::is_concurrent_strong_root_in_progress() const { + return _concurrent_strong_root_in_progress.is_set(); +} + +inline bool ShenandoahHeap::is_concurrent_weak_root_in_progress() const { + return _concurrent_weak_root_in_progress.is_set(); } template diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp index 64acdef228d..2d400321aca 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp @@ -75,10 +75,11 @@ void ShenandoahMarkCompact::do_it(GCCause::Cause gc_cause) { Universe::verify(); } - // Degenerated GC may carry concurrent_root_in_progress flag when upgrading to + // Degenerated GC may carry concurrent root flags when upgrading to // full GC. We need to reset it before mutators resume. if (ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) { - heap->set_concurrent_root_in_progress(false); + heap->set_concurrent_strong_root_in_progress(false); + heap->set_concurrent_weak_root_in_progress(false); } heap->set_full_gc_in_progress(true); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp index d6e27749c81..8aaddc49f17 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp @@ -213,7 +213,7 @@ void ShenandoahNMethod::heal_nmethod(nmethod* nm) { ShenandoahKeepNMethodMetadataAliveClosure cl; data->oops_do(&cl); } - } else if (heap->is_concurrent_root_in_progress()) { + } else if (heap->is_concurrent_weak_root_in_progress()) { ShenandoahEvacOOMScope evac_scope; ShenandoahEvacuateUpdateRootsClosure<> cl; data->oops_do(&cl, true /*fix relocation*/); @@ -318,20 +318,19 @@ void ShenandoahNMethod::assert_no_oops(nmethod* nm, bool allow_dead) { ShenandoahNMethodTable::ShenandoahNMethodTable() : _heap(ShenandoahHeap::heap()), - _size(minSize), _index(0), - _iteration_in_progress(false) { - _array = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, _size, mtGC); + _itr_cnt(0) { + _list = new ShenandoahNMethodList(minSize); } ShenandoahNMethodTable::~ShenandoahNMethodTable() { - assert(_array != NULL, "Sanity"); - FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _array); + assert(_list != NULL, "Sanity"); + _list->release(); } void ShenandoahNMethodTable::register_nmethod(nmethod* nm) { assert(CodeCache_lock->owned_by_self(), "Must have CodeCache_lock held"); - assert(_index >= 0 && _index <= _size, "Sanity"); + assert(_index >= 0 && _index <= _list->size(), "Sanity"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); ShenandoahReentrantLocker data_locker(data != NULL ? data->lock() : NULL); @@ -406,12 +405,12 @@ bool ShenandoahNMethodTable::contain(nmethod* nm) const { ShenandoahNMethod* ShenandoahNMethodTable::at(int index) const { assert(index >= 0 && index < _index, "Out of bound"); - return _array[index]; + return _list->at(index); } int ShenandoahNMethodTable::index_of(nmethod* nm) const { for (int index = 0; index < length(); index ++) { - if (_array[index]->nm() == nm) { + if (at(index)->nm() == nm) { return index; } } @@ -420,14 +419,14 @@ int ShenandoahNMethodTable::index_of(nmethod* nm) const { void ShenandoahNMethodTable::remove(int idx) { shenandoah_assert_locked_or_safepoint(CodeCache_lock); - assert(!_iteration_in_progress, "Can not happen"); - assert(_index >= 0 && _index <= _size, "Sanity"); + assert(!iteration_in_progress(), "Can not happen"); + assert(_index >= 0 && _index <= _list->size(), "Sanity"); assert(idx >= 0 && idx < _index, "Out of bound"); - ShenandoahNMethod* snm = _array[idx]; - + ShenandoahNMethod* snm = _list->at(idx); + ShenandoahNMethod* tmp = _list->at(_index - 1); + _list->set(idx, tmp); _index --; - _array[idx] = _array[_index]; delete snm; } @@ -441,48 +440,34 @@ void ShenandoahNMethodTable::wait_until_concurrent_iteration_done() { void ShenandoahNMethodTable::append(ShenandoahNMethod* snm) { if (is_full()) { - int new_size = 2 * _size; - ShenandoahNMethod** old_table = _array; - + int new_size = 2 * _list->size(); // Rebuild table and replace current one rebuild(new_size); - - // An iteration is in progress over early snapshot, - // can not release the array until iteration is completed - if (!iteration_in_progress()) { - FREE_C_HEAP_ARRAY(ShenandoahNMethod*, old_table); - } } - _array[_index ++] = snm; - assert(_index >= 0 && _index <= _size, "Sanity"); + _list->set(_index++, snm); + assert(_index >= 0 && _index <= _list->size(), "Sanity"); } void ShenandoahNMethodTable::rebuild(int size) { - ShenandoahNMethod** arr = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, size, mtGC); - for (int index = 0; index < _index; index ++) { - arr[index] = _array[index]; - } - _array = arr; - _size = size; + ShenandoahNMethodList* new_list = new ShenandoahNMethodList(size); + new_list->transfer(_list, _index); + + // Release old list + _list->release(); + _list = new_list; } ShenandoahNMethodTableSnapshot* ShenandoahNMethodTable::snapshot_for_iteration() { - assert(!iteration_in_progress(), "Already in progress"); - _iteration_in_progress = true; - + _itr_cnt++; return new ShenandoahNMethodTableSnapshot(this); } void ShenandoahNMethodTable::finish_iteration(ShenandoahNMethodTableSnapshot* snapshot) { assert(iteration_in_progress(), "Why we here?"); assert(snapshot != NULL, "No snapshot"); - _iteration_in_progress = false; + _itr_cnt--; - // Table has been rebuilt during iteration, free old table - if (snapshot->_array != _array) { - FREE_C_HEAP_ARRAY(ShenandoahNMethod*, snapshot->_array); - } delete snapshot; } @@ -528,7 +513,7 @@ void ShenandoahNMethodTable::assert_nmethods_alive_and_correct() { assert_locked_or_safepoint(CodeCache_lock); for (int index = 0; index < length(); index ++) { - ShenandoahNMethod* m = _array[index]; + ShenandoahNMethod* m = _list->at(index); // Concurrent unloading may have dead nmethods to be cleaned by sweeper if (m->is_unregistered()) continue; m->assert_alive_and_correct(); @@ -536,15 +521,53 @@ void ShenandoahNMethodTable::assert_nmethods_alive_and_correct() { } #endif + +ShenandoahNMethodList::ShenandoahNMethodList(int size) : + _size(size), _ref_count(1) { + _list = NEW_C_HEAP_ARRAY(ShenandoahNMethod*, size, mtGC); +} + +ShenandoahNMethodList::~ShenandoahNMethodList() { + assert(_list != NULL, "Sanity"); + assert(_ref_count == 0, "Must be"); + FREE_C_HEAP_ARRAY(ShenandoahNMethod*, _list); +} + +void ShenandoahNMethodList::transfer(ShenandoahNMethodList* const list, int limit) { + assert(limit <= size(), "Sanity"); + ShenandoahNMethod** old_list = list->list(); + for (int index = 0; index < limit; index++) { + _list[index] = old_list[index]; + } +} + +ShenandoahNMethodList* ShenandoahNMethodList::acquire() { + assert(CodeCache_lock->owned_by_self(), "Lock must be held"); + _ref_count++; + return this; +} + +void ShenandoahNMethodList::release() { + assert(CodeCache_lock->owned_by_self(), "Lock must be held"); + _ref_count--; + if (_ref_count == 0) { + delete this; + } +} + ShenandoahNMethodTableSnapshot::ShenandoahNMethodTableSnapshot(ShenandoahNMethodTable* table) : - _heap(ShenandoahHeap::heap()), _table(table), _array(table->_array), _length(table->_index), _claimed(0) { + _heap(ShenandoahHeap::heap()), _list(table->_list->acquire()), _limit(table->_index), _claimed(0) { +} + +ShenandoahNMethodTableSnapshot::~ShenandoahNMethodTableSnapshot() { + _list->release(); } void ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure* cl) { size_t stride = 256; // educated guess - ShenandoahNMethod** list = _array; - size_t max = (size_t)_length; + ShenandoahNMethod** list = _list->list(); + size_t max = (size_t)_limit; while (_claimed < max) { size_t cur = Atomic::fetch_and_add(&_claimed, stride); size_t start = cur; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp index 97c1674de90..80dc3a3d69d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2019, 2020, Red Hat, 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 @@ -83,14 +83,40 @@ private: class ShenandoahNMethodTable; +// ShenandoahNMethodList holds registered nmethod data. The list is reference counted. +class ShenandoahNMethodList : public CHeapObj { +private: + ShenandoahNMethod** _list; + const int _size; + uint _ref_count; + +private: + ~ShenandoahNMethodList(); + +public: + ShenandoahNMethodList(int size); + + // Reference counting with CoceCache_lock held + ShenandoahNMethodList* acquire(); + void release(); + + // Transfer content from other list to 'this' list, up to the limit + void transfer(ShenandoahNMethodList* const other, int limit); + + inline int size() const; + inline ShenandoahNMethod** list() const; + inline ShenandoahNMethod* at(int index) const; + inline void set(int index, ShenandoahNMethod* snm); +}; + // An opaque snapshot of current nmethod table for iteration class ShenandoahNMethodTableSnapshot : public CHeapObj { friend class ShenandoahNMethodTable; private: ShenandoahHeap* const _heap; - ShenandoahNMethodTable* _table; - ShenandoahNMethod** const _array; - const int _length; + ShenandoahNMethodList* _list; + /* snapshot iteration limit */ + int _limit; shenandoah_padding(0); volatile size_t _claimed; @@ -98,6 +124,7 @@ private: public: ShenandoahNMethodTableSnapshot(ShenandoahNMethodTable* table); + ~ShenandoahNMethodTableSnapshot(); template void parallel_blobs_do(CodeBlobClosure *f); @@ -112,12 +139,12 @@ private: minSize = 1024 }; - ShenandoahHeap* const _heap; - ShenandoahNMethod** _array; - int _size; - int _index; - ShenandoahLock _lock; - bool _iteration_in_progress; + ShenandoahHeap* const _heap; + ShenandoahNMethodList* _list; + + int _index; + ShenandoahLock _lock; + int _itr_cnt; public: ShenandoahNMethodTable(); @@ -140,8 +167,8 @@ private: void rebuild(int size); bool is_full() const { - assert(_index <= _size, "Sanity"); - return _index == _size; + assert(_index <= _list->size(), "Sanity"); + return _index == _list->size(); } ShenandoahNMethod* at(int index) const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp index 36fafabbd3d..f7dec26a554 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahNMethod.inline.hpp @@ -79,16 +79,35 @@ ShenandoahReentrantLock* ShenandoahNMethod::lock_for_nmethod(nmethod* nm) { } bool ShenandoahNMethodTable::iteration_in_progress() const { - return _iteration_in_progress; + shenandoah_assert_locked_or_safepoint(CodeCache_lock); + return _itr_cnt > 0; +} + +int ShenandoahNMethodList::size() const { + return _size; +} + +ShenandoahNMethod* ShenandoahNMethodList::at(int index) const { + assert(index < size(), "Index out of bound"); + return _list[index]; +} + +void ShenandoahNMethodList::set(int index, ShenandoahNMethod* snm) { + assert(index < size(), "Index out of bound"); + _list[index] = snm; +} + +ShenandoahNMethod** ShenandoahNMethodList::list() const { + return _list; } template void ShenandoahNMethodTableSnapshot::parallel_blobs_do(CodeBlobClosure *f) { size_t stride = 256; // educated guess - ShenandoahNMethod** const list = _array; + ShenandoahNMethod** const list = _list->list(); - size_t max = (size_t)_length; + size_t max = (size_t)_limit; while (_claimed < max) { size_t cur = Atomic::fetch_and_add(&_claimed, stride); size_t start = cur; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index f2b02ec9e2d..d0646ab0c30 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -73,25 +73,24 @@ void ShenandoahPhaseTimings::record_workers_end(Phase phase) { return; } - guarantee(phase == init_evac || - phase == scan_roots || - phase == update_roots || - phase == final_update_refs_roots || - phase == full_gc_roots || - phase == degen_gc_update_roots || - phase == full_gc_purge_par || - phase == purge_par || - phase == _num_phases, - "only in these phases we can add per-thread phase times"); - if (phase != _num_phases) { - double s = 0; - for (uint i = 1; i < GCParPhasesSentinel; i++) { - double t = _gc_par_phases[i]->sum(); - _timing_data[phase + i + 1].add(t); // add to each line in phase - s += t; - } - _timing_data[phase + 1].add(s); // add to total for phase + assert(phase == init_evac || + phase == scan_roots || + phase == update_roots || + phase == final_update_refs_roots || + phase == full_gc_roots || + phase == degen_gc_update_roots || + phase == full_gc_purge_par || + phase == purge_par || + phase == heap_iteration_roots, + "Phase should accept accept per-thread phase times: %s", phase_name(phase)); + + double s = 0; + for (uint i = 1; i < GCParPhasesSentinel; i++) { + double t = _gc_par_phases[i]->sum(); + _timing_data[phase + i + 1].add(t); // add to each line in phase + s += t; } + _timing_data[phase + 1].add(s); // add to total for phase } void ShenandoahPhaseTimings::print_on(outputStream* out) const { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp index 192f7b7e637..6037592c819 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp @@ -57,8 +57,7 @@ class outputStream; // end #define SHENANDOAH_GC_PHASE_DO(f) \ - f(total_pause_gross, "Total Pauses (G)") \ - f(total_pause, "Total Pauses (N)") \ + f(conc_reset, "Concurrent Reset") \ \ f(init_mark_gross, "Pause Init Mark (G)") \ f(init_mark, "Pause Init Mark (N)") \ @@ -68,6 +67,9 @@ class outputStream; SHENANDOAH_GC_PAR_PHASE_DO(scan_, " S: ", f) \ f(resize_tlabs, " Resize TLABs") \ \ + f(conc_mark, "Concurrent Marking") \ + f(conc_preclean, "Concurrent Precleaning") \ + \ f(final_mark_gross, "Pause Final Mark (G)") \ f(final_mark, "Pause Final Mark (N)") \ f(update_roots, " Update Roots") \ @@ -87,10 +89,17 @@ class outputStream; f(init_evac, " Initial Evacuation") \ SHENANDOAH_GC_PAR_PHASE_DO(evac_, " E: ", f) \ \ + f(conc_weak_roots, "Concurrent Weak Roots") \ + f(conc_cleanup_early, "Concurrent Cleanup") \ + f(conc_class_unloading, "Concurrent Class Unloading") \ + f(conc_strong_roots, "Concurrent Strong Roots") \ + f(conc_evac, "Concurrent Evacuation") \ + \ f(init_update_refs_gross, "Pause Init Update Refs (G)") \ f(init_update_refs, "Pause Init Update Refs (N)") \ f(init_update_refs_retire_gclabs, " Retire GCLABs") \ - f(init_update_refs_prepare, " Prepare") \ + \ + f(conc_update_refs, "Concurrent Update Refs") \ \ f(final_update_refs_gross, "Pause Final Update Refs (G)") \ f(final_update_refs, "Pause Final Update Refs (N)") \ @@ -101,6 +110,8 @@ class outputStream; f(final_update_refs_trash_cset, " Trash Collection Set") \ f(final_update_refs_rebuild_freeset, " Rebuild Free Set") \ \ + f(conc_cleanup_complete, "Concurrent Cleanup") \ + \ f(degen_gc_gross, "Pause Degenerated GC (G)") \ f(degen_gc, "Pause Degenerated GC (N)") \ f(degen_gc_update_roots, " Degen Update Roots") \ @@ -132,20 +143,10 @@ class outputStream; f(full_gc_copy_objects_rebuild, " Rebuild Region Sets") \ f(full_gc_resize_tlabs, " Resize TLABs") \ \ - /* Longer concurrent phases at the end */ \ - f(conc_reset, "Concurrent Reset") \ - f(conc_mark, "Concurrent Marking") \ - f(conc_preclean, "Concurrent Precleaning") \ - f(conc_roots, "Concurrent Roots") \ - f(conc_evac, "Concurrent Evacuation") \ - f(conc_update_refs, "Concurrent Update Refs") \ - f(conc_cleanup, "Concurrent Cleanup") \ - \ f(conc_uncommit, "Concurrent Uncommit") \ \ - /* Unclassified */ \ - f(pause_other, "Pause Other") \ - f(conc_other, "Concurrent Other") \ + f(heap_iteration_roots, "Heap Iteration") \ + SHENANDOAH_GC_PAR_PHASE_DO(heap_iteration_roots_, " HI: ", f) \ // end class ShenandoahPhaseTimings : public CHeapObj { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp index 09d5697da22..0e69f8b27a6 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp @@ -248,7 +248,7 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) { } ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() : - ShenandoahRootProcessor(ShenandoahPhaseTimings::_num_phases), + ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots), _thread_roots(false /*is par*/) { } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp index 5baa96480c5..43558a5660e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp @@ -137,7 +137,7 @@ public: ShenandoahWeakRoots(); template - void oops_do(Closure* cl, uint worker_id = 0); + void oops_do(Closure* cl, uint worker_id); }; template <> @@ -151,7 +151,7 @@ public: ShenandoahWeakRoots(); template - void oops_do(Closure* cl, uint worker_id = 0); + void oops_do(Closure* cl, uint worker_id); template void weak_oops_do(IsAliveClosure* is_alive, KeepAliveClosure* keep_alive, uint worker_id); @@ -167,7 +167,7 @@ public: ShenandoahVMRoots(); template - void oops_do(T* cl, uint worker_id = 0); + void oops_do(T* cl, uint worker_id); }; class ShenandoahThreadRoots { @@ -214,8 +214,8 @@ public: ShenandoahClassLoaderDataRoots(); ~ShenandoahClassLoaderDataRoots(); - void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0); - void cld_do(CLDClosure* clds, uint worker_id = 0); + void always_strong_cld_do(CLDClosure* clds, uint worker_id); + void cld_do(CLDClosure* clds, uint worker_id); }; class ShenandoahRootProcessor : public StackObj { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 6914f8a46f0..66b6244861a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -79,7 +79,7 @@ class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour { public: virtual bool is_unloading(CompiledMethod* method) const { nmethod* const nm = method->as_nmethod(); - assert(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only for this phase"); + assert(ShenandoahHeap::heap()->is_concurrent_weak_root_in_progress(), "Only for this phase"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); ShenandoahReentrantLocker locker(data->lock()); ShenandoahIsUnloadingOopClosure cl; @@ -166,7 +166,7 @@ public: void ShenandoahUnload::unload() { assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?"); - if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) { + if (!ShenandoahHeap::heap()->is_concurrent_weak_root_in_progress()) { return; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp index 244cdbc51b6..b15f19eac87 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp @@ -85,8 +85,8 @@ ShenandoahGCPauseMark::ShenandoahGCPauseMark(uint gc_id, SvcGCMarker::reason_typ ); } -ShenandoahPausePhase::ShenandoahPausePhase(const char* title) : - _tracer(title), +ShenandoahPausePhase::ShenandoahPausePhase(const char* title, bool log_heap_usage) : + _tracer(title, NULL, GCCause::_no_gc, log_heap_usage), _timer(ShenandoahHeap::heap()->gc_timer()) { _timer->register_gc_pause_start(title); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp index e3a50303f8b..e6e0269e834 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp @@ -60,7 +60,7 @@ private: ConcurrentGCTimer* const _timer; public: - ShenandoahPausePhase(const char* title); + ShenandoahPausePhase(const char* title, bool log_heap_usage = false); ~ShenandoahPausePhase(); }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 01113f163b6..4191e25f5c9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -211,10 +211,6 @@ diagnostic(bool, ShenandoahElasticTLAB, true, \ "Use Elastic TLABs with Shenandoah") \ \ - diagnostic(bool, ShenandoahAllowMixedAllocs, true, \ - "Allow mixing mutator and collector allocations into a single " \ - "region. Some heuristics enable/disable it for their needs") \ - \ experimental(uintx, ShenandoahEvacReserve, 5, \ "How much of heap to reserve for evacuations. Larger values make "\ "GC evacuate more live objects on every cycle, while leaving " \ diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 811041a7acf..6db1b264369 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -388,6 +388,21 @@ JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source); +/* + * Define a class with the specified lookup class. + * lookup: Lookup class + * name: the name of the class + * buf: class bytes + * len: length of class bytes + * pd: protection domain + * init: initialize the class + * flags: properties of the class + * classData: private static pre-initialized field; may be null + */ +JNIEXPORT jclass JNICALL +JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, const jbyte *buf, + jsize len, jobject pd, jboolean init, int flags, jobject classData); + /* * Module support funcions */ @@ -399,12 +414,11 @@ JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, * is_open: specifies if module is open (currently ignored) * version: the module version * location: the module location - * packages: list of packages in the module - * num_packages: number of packages in the module + * packages: array of packages in the module */ JNIEXPORT void JNICALL JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, jsize num_packages); + jstring location, jobjectArray packages); /* * Set the boot loader's unnamed module. @@ -420,7 +434,7 @@ JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module); * to_module: module to export the package to */ JNIEXPORT void JNICALL -JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module); +JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module); /* * Do an export of a package to all unnamed modules. @@ -428,7 +442,7 @@ JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobj * package: name of the package to export to all unnamed modules */ JNIEXPORT void JNICALL -JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package); +JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package); /* * Do an unqualified export of a package. @@ -436,7 +450,7 @@ JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* p * package: name of the package to export */ JNIEXPORT void JNICALL -JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package); +JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package); /* * Add a module to the list of modules that a given module can read. @@ -474,6 +488,9 @@ JVM_IsArrayClass(JNIEnv *env, jclass cls); JNIEXPORT jboolean JNICALL JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); +JNIEXPORT jboolean JNICALL +JVM_IsHiddenClass(JNIEnv *env, jclass cls); + JNIEXPORT jint JNICALL JVM_GetClassModifiers(JNIEnv *env, jclass cls); diff --git a/src/hotspot/share/interpreter/bootstrapInfo.cpp b/src/hotspot/share/interpreter/bootstrapInfo.cpp index cfe10e58590..513882017c0 100644 --- a/src/hotspot/share/interpreter/bootstrapInfo.cpp +++ b/src/hotspot/share/interpreter/bootstrapInfo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ bool BootstrapInfo::resolve_previously_linked_invokedynamic(CallInfo& result, TR methodHandle method( THREAD, cpce->f1_as_method()); Handle appendix( THREAD, cpce->appendix_if_resolved(_pool)); result.set_handle(method, appendix, THREAD); - Exceptions::wrap_dynamic_exception(CHECK_false); + Exceptions::wrap_dynamic_exception(/* is_indy */ true, CHECK_false); return true; } else if (cpce->indy_resolution_failed()) { int encoded_index = ResolutionErrorTable::encode_cpcache_index(_indy_index); @@ -81,24 +81,28 @@ bool BootstrapInfo::resolve_previously_linked_invokedynamic(CallInfo& result, TR // - obtain the NameAndType description for the condy/indy // - prepare the BSM's static arguments Handle BootstrapInfo::resolve_bsm(TRAPS) { - if (_bsm.not_null()) return _bsm; + if (_bsm.not_null()) { + return _bsm; + } + + bool is_indy = is_method_call(); // The tag at the bootstrap method index must be a valid method handle or a method handle in error. // If it is a MethodHandleInError, a resolution error will be thrown which will be wrapped if necessary // with a BootstrapMethodError. assert(_pool->tag_at(bsm_index()).is_method_handle() || _pool->tag_at(bsm_index()).is_method_handle_in_error(), "MH not present, classfile structural constraint"); oop bsm_oop = _pool->resolve_possibly_cached_constant_at(bsm_index(), THREAD); - Exceptions::wrap_dynamic_exception(CHECK_NH); + Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH); guarantee(java_lang_invoke_MethodHandle::is_instance(bsm_oop), "classfile must supply a valid BSM"); _bsm = Handle(THREAD, bsm_oop); // Obtain NameAndType information resolve_bss_name_and_type(THREAD); - Exceptions::wrap_dynamic_exception(CHECK_NH); + Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH); // Prepare static arguments resolve_args(THREAD); - Exceptions::wrap_dynamic_exception(CHECK_NH); + Exceptions::wrap_dynamic_exception(is_indy, CHECK_NH); return _bsm; } @@ -253,7 +257,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) { st->print_cr(" argument indexes: {%s}", argbuf); } if (_bsm.not_null()) { - st->print(" resolved BSM: "); _bsm->print(); + st->print(" resolved BSM: "); _bsm->print_on(st); } // How the array of resolved arguments is printed depends highly @@ -264,7 +268,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) { objArrayOop static_args = (objArrayOop)_arg_values(); if (!static_args->is_array()) { assert(_argc == 1, "Invalid BSM _arg_values for non-array"); - st->print(" resolved arg[0]: "); static_args->print(); + st->print(" resolved arg[0]: "); static_args->print_on(st); } else if (static_args->is_objArray()) { int lines = 0; for (int i = 0; i < _argc; i++) { @@ -274,7 +278,7 @@ void BootstrapInfo::print_msg_on(outputStream* st, const char* msg) { st->print_cr(" resolved arg[%d]: ...", i); break; } - st->print(" resolved arg[%d]: ", i); x->print(); + st->print(" resolved arg[%d]: ", i); x->print_on(st); } } } else if (static_args->is_typeArray()) { diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index d596534bc38..cded39c86cb 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -436,17 +436,16 @@ Method* LinkResolver::lookup_method_in_interfaces(const LinkInfo& cp_info) { Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, Handle *appendix_result_or_null, TRAPS) { + ResourceMark rm(THREAD); Klass* klass = link_info.resolved_klass(); Symbol* name = link_info.name(); Symbol* full_signature = link_info.signature(); + LogTarget(Info, methodhandles) lt_mh; vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); - if (TraceMethodHandles) { - ResourceMark rm(THREAD); - tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s", - vmIntrinsics::name_at(iid), klass->external_name(), - name->as_C_string(), full_signature->as_C_string()); - } + log_info(methodhandles)("lookup_polymorphic_method iid=%s %s.%s%s", + vmIntrinsics::name_at(iid), klass->external_name(), + name->as_C_string(), full_signature->as_C_string()); if ((klass == SystemDictionary::MethodHandle_klass() || klass == SystemDictionary::VarHandle_klass()) && iid != vmIntrinsics::_none) { @@ -456,13 +455,10 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid); TempNewSymbol basic_signature = MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK_NULL); - if (TraceMethodHandles) { - ResourceMark rm(THREAD); - tty->print_cr("lookup_polymorphic_method %s %s => basic %s", - name->as_C_string(), - full_signature->as_C_string(), - basic_signature->as_C_string()); - } + log_info(methodhandles)("lookup_polymorphic_method %s %s => basic %s", + name->as_C_string(), + full_signature->as_C_string(), + basic_signature->as_C_string()); Method* result = SystemDictionary::find_method_handle_intrinsic(iid, basic_signature, CHECK_NULL); @@ -470,10 +466,10 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic"); assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this"); assert(basic_signature == result->signature(), "predict the result signature"); - if (TraceMethodHandles) { - ttyLocker ttyl; - tty->print("lookup_polymorphic_method => intrinsic "); - result->print_on(tty); + if (lt_mh.is_enabled()) { + LogStream ls(lt_mh); + ls.print("lookup_polymorphic_method => intrinsic "); + result->print_on(&ls); } } return result; @@ -503,13 +499,12 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, link_info.current_klass(), &appendix, CHECK_NULL); - if (TraceMethodHandles) { - ttyLocker ttyl; - tty->print("lookup_polymorphic_method => (via Java) "); - result->print_on(tty); - tty->print(" lookup_polymorphic_method => appendix = "); - if (appendix.is_null()) tty->print_cr("(none)"); - else appendix->print_on(tty); + if (lt_mh.is_enabled()) { + LogStream ls(lt_mh); + ls.print("lookup_polymorphic_method => (via Java) "); + result->print_on(&ls); + ls.print(" lookup_polymorphic_method => appendix = "); + appendix.is_null() ? ls.print_cr("(none)") : appendix->print_on(&ls); } if (result != NULL) { #ifdef ASSERT @@ -540,6 +535,21 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, return NULL; } +static void print_nest_host_error_on(stringStream* ss, Klass* ref_klass, Klass* sel_klass, TRAPS) { + assert(ref_klass->is_instance_klass(), "must be"); + assert(sel_klass->is_instance_klass(), "must be"); + InstanceKlass* ref_ik = InstanceKlass::cast(ref_klass); + InstanceKlass* sel_ik = InstanceKlass::cast(sel_klass); + const char* nest_host_error_1 = ref_ik->nest_host_error(THREAD); + const char* nest_host_error_2 = sel_ik->nest_host_error(THREAD); + if (nest_host_error_1 != NULL || nest_host_error_2 != NULL) { + ss->print(", (%s%s%s)", + (nest_host_error_1 != NULL) ? nest_host_error_1 : "", + (nest_host_error_1 != NULL && nest_host_error_2 != NULL) ? ", " : "", + (nest_host_error_2 != NULL) ? nest_host_error_2 : ""); + } +} + void LinkResolver::check_method_accessability(Klass* ref_klass, Klass* resolved_klass, Klass* sel_klass, @@ -572,24 +582,34 @@ void LinkResolver::check_method_accessability(Klass* ref_klass, sel_klass, flags, true, false, CHECK); - // Any existing exceptions that may have been thrown, for example LinkageErrors - // from nest-host resolution, have been allowed to propagate. + // Any existing exceptions that may have been thrown + // have been allowed to propagate. if (!can_access) { ResourceMark rm(THREAD); + stringStream ss; bool same_module = (sel_klass->module() == ref_klass->module()); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s tried to access %s%s%smethod '%s' (%s%s%s)", - ref_klass->external_name(), - sel_method->is_abstract() ? "abstract " : "", - sel_method->is_protected() ? "protected " : "", - sel_method->is_private() ? "private " : "", - sel_method->external_name(), - (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), - (same_module) ? "" : "; ", - (same_module) ? "" : sel_klass->class_in_module_of_loader() - ); + ss.print("class %s tried to access %s%s%smethod '%s' (%s%s%s)", + ref_klass->external_name(), + sel_method->is_abstract() ? "abstract " : "", + sel_method->is_protected() ? "protected " : "", + sel_method->is_private() ? "private " : "", + sel_method->external_name(), + (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), + (same_module) ? "" : "; ", + (same_module) ? "" : sel_klass->class_in_module_of_loader() + ); + + // For private access see if there was a problem with nest host + // resolution, and if so report that as part of the message. + if (sel_method->is_private()) { + print_nest_host_error_on(&ss, ref_klass, sel_klass, THREAD); + } + + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "%s", + ss.as_string() + ); return; } } @@ -908,19 +928,27 @@ void LinkResolver::check_field_accessability(Klass* ref_klass, if (!can_access) { bool same_module = (sel_klass->module() == ref_klass->module()); ResourceMark rm(THREAD); - Exceptions::fthrow( - THREAD_AND_LOCATION, - vmSymbols::java_lang_IllegalAccessError(), - "class %s tried to access %s%sfield %s.%s (%s%s%s)", - ref_klass->external_name(), - fd.is_protected() ? "protected " : "", - fd.is_private() ? "private " : "", - sel_klass->external_name(), - fd.name()->as_C_string(), - (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), - (same_module) ? "" : "; ", - (same_module) ? "" : sel_klass->class_in_module_of_loader() - ); + stringStream ss; + ss.print("class %s tried to access %s%sfield %s.%s (%s%s%s)", + ref_klass->external_name(), + fd.is_protected() ? "protected " : "", + fd.is_private() ? "private " : "", + sel_klass->external_name(), + fd.name()->as_C_string(), + (same_module) ? ref_klass->joint_in_module_of_loader(sel_klass) : ref_klass->class_in_module_of_loader(), + (same_module) ? "" : "; ", + (same_module) ? "" : sel_klass->class_in_module_of_loader() + ); + // For private access see if there was a problem with nest host + // resolution, and if so report that as part of the message. + if (fd.is_private()) { + print_nest_host_error_on(&ss, ref_klass, sel_klass, THREAD); + } + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_IllegalAccessError(), + "%s", + ss.as_string() + ); return; } } @@ -1669,10 +1697,10 @@ void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) { // This guy is reached from InterpreterRuntime::resolve_invokehandle. LinkInfo link_info(pool, index, CHECK); - if (TraceMethodHandles) { + if (log_is_enabled(Info, methodhandles)) { ResourceMark rm(THREAD); - tty->print_cr("resolve_invokehandle %s %s", link_info.name()->as_C_string(), - link_info.signature()->as_C_string()); + log_info(methodhandles)("resolve_invokehandle %s %s", link_info.name()->as_C_string(), + link_info.signature()->as_C_string()); } resolve_handle_call(result, link_info, CHECK); } @@ -1713,8 +1741,10 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHan resolve_dynamic_call(result, bootstrap_specifier, CHECK); - if (TraceMethodHandles) { - bootstrap_specifier.print_msg_on(tty, "resolve_invokedynamic"); + LogTarget(Debug, methodhandles, indy) lt_indy; + if (lt_indy.is_enabled()) { + LogStream ls(lt_indy); + bootstrap_specifier.print_msg_on(&ls, "resolve_invokedynamic"); } // The returned linkage result is provisional up to the moment @@ -1735,7 +1765,7 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result, // or any other reference. The resolved_method as well as the appendix // are both recorded together via CallInfo::set_handle. SystemDictionary::invoke_bootstrap_method(bootstrap_specifier, THREAD); - Exceptions::wrap_dynamic_exception(THREAD); + Exceptions::wrap_dynamic_exception(/* is_indy */ true, THREAD); if (HAS_PENDING_EXCEPTION) { if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp index fa40e07809a..4c359f07c8e 100644 --- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp +++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1460,12 +1460,11 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre Handle pd(THREAD, ik->protection_domain()); Symbol* const class_name = ik->name(); const char* const klass_name = class_name != NULL ? class_name->as_C_string() : ""; + ClassLoadInfo cl_info(pd); ClassFileParser new_parser(stream, class_name, cld, - pd, - NULL, // host klass - NULL, // cp_patches + &cl_info, ClassFileParser::INTERNAL, // internal visibility THREAD); if (HAS_PENDING_EXCEPTION) { @@ -1473,7 +1472,8 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre CLEAR_PENDING_EXCEPTION; return NULL; } - InstanceKlass* const new_ik = new_parser.create_instance_klass(false, THREAD); + const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr(); + InstanceKlass* const new_ik = new_parser.create_instance_klass(false, *cl_inst_info, THREAD); if (HAS_PENDING_EXCEPTION) { log_pending_exception(PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp index ee6f8dd3e2e..2399275712a 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -162,10 +162,9 @@ void ObjectSampleDescription::write_class_name() { if (k->is_instance_klass()) { const InstanceKlass* ik = InstanceKlass::cast(k); - if (ik->is_unsafe_anonymous()) { + if (ik->is_unsafe_anonymous() || ik->is_hidden()) { return; } - assert(!ik->is_unsafe_anonymous(), "invariant"); const Symbol* name = ik->name(); if (name != NULL) { write_text("Class Name: "); diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 81db849bdcc..f48c55c6f9e 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -219,6 +219,7 @@ stackTrace="true"> + @@ -227,6 +228,7 @@ + @@ -729,6 +731,11 @@ description="Total size of all allocated metaspace chunks for unsafe anonymous classes (each chunk has several blocks)" /> + + + @@ -1135,6 +1142,7 @@ + diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp index 526574146bc..066c1e8ede6 100644 --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -483,6 +483,9 @@ public: event.set_unsafeAnonymousClassCount(cls->_anon_classes_count); event.set_unsafeAnonymousChunkSize(cls->_anon_chunk_sz); event.set_unsafeAnonymousBlockSize(cls->_anon_block_sz); + event.set_hiddenClassCount(cls->_hidden_classes_count); + event.set_hiddenChunkSize(cls->_hidden_chunk_sz); + event.set_hiddenBlockSize(cls->_hidden_block_sz); event.commit(); return true; } diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp index fa5534b4c5e..71788c2b11c 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp @@ -137,7 +137,6 @@ static traceid method_id(KlassPtr klass, MethodPtr method) { static traceid cld_id(CldPtr cld, bool leakp) { assert(cld != NULL, "invariant"); - assert(!cld->is_unsafe_anonymous(), "invariant"); if (leakp) { SET_LEAKP(cld); } else { @@ -163,6 +162,7 @@ static ClassLoaderData* get_cld(const Klass* klass) { if (klass->is_objArray_klass()) { klass = ObjArrayKlass::cast(klass)->bottom_klass(); } + if (klass->is_non_strong_hidden()) return NULL; return is_unsafe_anonymous(klass) ? InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data(); } @@ -188,10 +188,12 @@ static int write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp) assert(_artifacts != NULL, "invariant"); assert(klass != NULL, "invariant"); writer->write(artifact_id(klass)); - writer->write(cld_id(get_cld(klass), leakp)); + ClassLoaderData* cld = get_cld(klass); + writer->write(cld != NULL ? cld_id(cld, leakp) : 0); writer->write(mark_symbol(klass, leakp)); writer->write(package_id(klass, leakp)); writer->write(get_flags(klass)); + writer->write(klass->is_hidden()); return 1; } @@ -546,7 +548,6 @@ static void clear_modules() { static int write_classloader(JfrCheckpointWriter* writer, CldPtr cld, bool leakp) { assert(cld != NULL, "invariant"); - assert(!cld->is_unsafe_anonymous(), "invariant"); // class loader type const Klass* class_loader_klass = cld->class_loader_klass(); if (class_loader_klass == NULL) { @@ -604,7 +605,7 @@ class CLDCallback : public CLDClosure { CLDCallback() {} void do_cld(ClassLoaderData* cld) { assert(cld != NULL, "invariant"); - if (cld->is_unsafe_anonymous()) { + if (cld->has_class_mirror_holder()) { return; } do_class_loader_data(cld); diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp index 541a4023ed6..657af666115 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -189,52 +189,54 @@ traceid JfrSymbolId::mark(uintptr_t hash, const char* str, bool leakp) { * caller needs ResourceMark */ -uintptr_t JfrSymbolId::unsafe_anonymous_klass_name_hash(const InstanceKlass* ik) { +uintptr_t JfrSymbolId::hidden_or_anon_klass_name_hash(const InstanceKlass* ik) { assert(ik != NULL, "invariant"); - assert(ik->is_unsafe_anonymous(), "invariant"); + assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant"); const oop mirror = ik->java_mirror_no_keepalive(); assert(mirror != NULL, "invariant"); return (uintptr_t)mirror->identity_hash(); } -static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t hash) { +static const char* create_hidden_or_anon_klass_symbol(const InstanceKlass* ik, uintptr_t hash) { assert(ik != NULL, "invariant"); - assert(ik->is_unsafe_anonymous(), "invariant"); + assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant"); assert(hash != 0, "invariant"); - char* anonymous_symbol = NULL; + char* hidden_or_anon_symbol = NULL; const oop mirror = ik->java_mirror_no_keepalive(); assert(mirror != NULL, "invariant"); char hash_buf[40]; sprintf(hash_buf, "/" UINTX_FORMAT, hash); const size_t hash_len = strlen(hash_buf); const size_t result_len = ik->name()->utf8_length(); - anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); - ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1); - assert(strlen(anonymous_symbol) == result_len, "invariant"); - strcpy(anonymous_symbol + result_len, hash_buf); - assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant"); - return anonymous_symbol; + hidden_or_anon_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1); + ik->name()->as_klass_external_name(hidden_or_anon_symbol, (int)result_len + 1); + assert(strlen(hidden_or_anon_symbol) == result_len, "invariant"); + strcpy(hidden_or_anon_symbol + result_len, hash_buf); + assert(strlen(hidden_or_anon_symbol) == result_len + hash_len, "invariant"); + return hidden_or_anon_symbol; } -bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) { +bool JfrSymbolId::is_hidden_or_anon_klass(const Klass* k) { assert(k != NULL, "invariant"); - return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous(); + return k->is_instance_klass() && + (((const InstanceKlass*)k)->is_unsafe_anonymous() || + ((const InstanceKlass*)k)->is_hidden()); } -traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const InstanceKlass* ik, bool leakp) { +traceid JfrSymbolId::mark_hidden_or_anon_klass_name(const InstanceKlass* ik, bool leakp) { assert(ik != NULL, "invariant"); - assert(ik->is_unsafe_anonymous(), "invariant"); - const uintptr_t hash = unsafe_anonymous_klass_name_hash(ik); - const char* const anonymous_klass_symbol = create_unsafe_anonymous_klass_symbol(ik, hash); - return mark(hash, anonymous_klass_symbol, leakp); + assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant"); + const uintptr_t hash = hidden_or_anon_klass_name_hash(ik); + const char* const hidden_or_anon_symbol = create_hidden_or_anon_klass_symbol(ik, hash); + return mark(hash, hidden_or_anon_symbol, leakp); } traceid JfrSymbolId::mark(const Klass* k, bool leakp) { assert(k != NULL, "invariant"); traceid symbol_id = 0; - if (is_unsafe_anonymous_klass(k)) { + if (is_hidden_or_anon_klass(k)) { assert(k->is_instance_klass(), "invariant"); - symbol_id = mark_unsafe_anonymous_klass_name((const InstanceKlass*)k, leakp); + symbol_id = mark_hidden_or_anon_klass_name((const InstanceKlass*)k, leakp); } if (0 == symbol_id) { Symbol* const sym = k->name(); @@ -276,9 +278,9 @@ traceid JfrArtifactSet::bootstrap_name(bool leakp) { return _symbol_id->bootstrap_name(leakp); } -traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass, bool leakp) { +traceid JfrArtifactSet::mark_hidden_or_anon_klass_name(const Klass* klass, bool leakp) { assert(klass->is_instance_klass(), "invariant"); - return _symbol_id->mark_unsafe_anonymous_klass_name((const InstanceKlass*)klass, leakp); + return _symbol_id->mark_hidden_or_anon_klass_name((const InstanceKlass*)klass, leakp); } traceid JfrArtifactSet::mark(uintptr_t hash, const Symbol* sym, bool leakp) { diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp index ede4c931d34..dd3141c2f1e 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -241,9 +241,9 @@ class JfrSymbolId : public JfrCHeapObj { } } - traceid mark_unsafe_anonymous_klass_name(const InstanceKlass* k, bool leakp); - bool is_unsafe_anonymous_klass(const Klass* k); - uintptr_t unsafe_anonymous_klass_name_hash(const InstanceKlass* ik); + traceid mark_hidden_or_anon_klass_name(const InstanceKlass* k, bool leakp); + bool is_hidden_or_anon_klass(const Klass* k); + uintptr_t hidden_or_anon_klass_name_hash(const InstanceKlass* ik); public: JfrSymbolId(); @@ -304,7 +304,7 @@ class JfrArtifactSet : public JfrCHeapObj { traceid mark(const Klass* klass, bool leakp); traceid mark(const Symbol* symbol, bool leakp); traceid mark(uintptr_t hash, const char* const str, bool leakp); - traceid mark_unsafe_anonymous_klass_name(const Klass* klass, bool leakp); + traceid mark_hidden_or_anon_klass_name(const Klass* klass, bool leakp); traceid bootstrap_name(bool leakp); const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const; diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp index 53564e8dca8..8a994d00b0f 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -140,7 +140,7 @@ void JfrTraceId::assign(const PackageEntry* package) { void JfrTraceId::assign(const ClassLoaderData* cld) { assert(cld != NULL, "invariant"); - if (cld->is_unsafe_anonymous()) { + if (cld->has_class_mirror_holder()) { cld->set_trace_id(0); return; } diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp index 0dea7b36896..2802ac1bc8b 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp @@ -114,7 +114,7 @@ inline traceid JfrTraceId::use(const PackageEntry* package) { inline traceid JfrTraceId::use(const ClassLoaderData* cld) { assert(cld != NULL, "invariant"); - return cld->is_unsafe_anonymous() ? 0 : set_used_and_get(cld); + return cld->has_class_mirror_holder() ? 0 : set_used_and_get(cld); } inline void JfrTraceId::set_leakp(const Klass* klass, const Method* method) { diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp index 12a9d68fd30..bf2c27b6527 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp @@ -44,6 +44,7 @@ ConstantIntValue* CodeInstaller::_int_0_scope_value = new (ResourceObj::C_ ConstantIntValue* CodeInstaller::_int_1_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(1); ConstantIntValue* CodeInstaller::_int_2_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(2); LocationValue* CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtJVMCI) LocationValue(Location()); +MarkerValue* CodeInstaller::_virtual_byte_array_marker = new (ResourceObj::C_HEAP, mtJVMCI) MarkerValue(); VMReg CodeInstaller::getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS) { if (location.is_null()) { @@ -420,6 +421,7 @@ void CodeInstaller::record_object_value(ObjectValue* sv, JVMCIObject value, Grow int id = jvmci_env()->get_VirtualObject_id(value); Klass* klass = JVMCIENV->asKlass(type); bool isLongArray = klass == Universe::longArrayKlassObj(); + bool isByteArray = klass == Universe::byteArrayKlassObj(); JVMCIObjectArray values = jvmci_env()->get_VirtualObject_values(value); JVMCIObjectArray slotKinds = jvmci_env()->get_VirtualObject_slotKinds(value); @@ -427,7 +429,24 @@ void CodeInstaller::record_object_value(ObjectValue* sv, JVMCIObject value, Grow ScopeValue* cur_second = NULL; JVMCIObject object = JVMCIENV->get_object_at(values, i); BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK); - ScopeValue* value = get_scope_value(object, type, objects, cur_second, JVMCI_CHECK); + ScopeValue* value; + if (JVMCIENV->equals(object, jvmci_env()->get_Value_ILLEGAL())) { + if (isByteArray && type == T_ILLEGAL) { + /* + * The difference between a virtualized large access and a deferred write is the kind stored in the slotKinds + * of the virtual object: in the virtualization case, the kind is illegal, in the deferred write case, the kind + * is access stack kind (an int). + */ + value = _virtual_byte_array_marker; + } else { + value = _illegal_value; + if (type == T_DOUBLE || type == T_LONG) { + cur_second = _illegal_value; + } + } + } else { + value = get_scope_value(object, type, objects, cur_second, JVMCI_CHECK); + } if (isLongArray && cur_second == NULL) { // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. @@ -435,6 +454,12 @@ void CodeInstaller::record_object_value(ObjectValue* sv, JVMCIObject value, Grow cur_second = _int_0_scope_value; } + if (isByteArray && cur_second != NULL && (type == T_DOUBLE || type == T_LONG)) { + // we are trying to write a long in a byte Array. We will need to count the illegals to restore the type of + // the thing we put inside. + cur_second = NULL; + } + if (cur_second != NULL) { sv->field_values()->append(cur_second); } diff --git a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp index 129429b830e..45f9232b3d1 100644 --- a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp +++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp @@ -204,6 +204,7 @@ private: static ConstantIntValue* _int_1_scope_value; static ConstantIntValue* _int_2_scope_value; static LocationValue* _illegal_value; + static MarkerValue* _virtual_byte_array_marker; jint pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS); void pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS); diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index 2eb83b841bb..a235c2471e1 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -262,7 +262,8 @@ public: char* as_utf8_string(JVMCIObject str, char* buf, int buflen); JVMCIObject create_string(Symbol* str, JVMCI_TRAPS) { - return create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject())); + JVMCIObject s = create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject())); + return s; } JVMCIObject create_string(const char* str, JVMCI_TRAPS); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 6503760a7f2..c23287775a3 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -382,48 +382,14 @@ address JVMCIRuntime::exception_handler_for_pc(JavaThread* thread) { return continuation; } -JRT_ENTRY_NO_ASYNC(void, JVMCIRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock)) - IF_TRACE_jvmci_3 { - char type[O_BUFLEN]; - obj->klass()->name()->as_C_string(type, O_BUFLEN); - markWord mark = obj->mark(); - TRACE_jvmci_3("%s: entered locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, mark.value(), p2i(lock)); - tty->flush(); - } - if (PrintBiasedLockingStatistics) { - Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); - } - Handle h_obj(thread, obj); - assert(oopDesc::is_oop(h_obj()), "must be NULL or an object"); - ObjectSynchronizer::enter(h_obj, lock, THREAD); - TRACE_jvmci_3("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), p2i(obj)); +JRT_BLOCK_ENTRY(void, JVMCIRuntime::monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock)) + SharedRuntime::monitor_enter_helper(obj, lock, thread); JRT_END JRT_LEAF(void, JVMCIRuntime::monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock)) - assert(thread == JavaThread::current(), "threads must correspond"); assert(thread->last_Java_sp(), "last_Java_sp must be set"); - // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown - EXCEPTION_MARK; - -#ifdef ASSERT - if (!oopDesc::is_oop(obj)) { - ResetNoHandleMark rhm; - nmethod* method = thread->last_frame().cb()->as_nmethod_or_null(); - if (method != NULL) { - tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), p2i(obj)); - } - thread->print_stack_on(tty); - assert(false, "invalid lock object pointer dected"); - } -#endif - - ObjectSynchronizer::exit(obj, lock, THREAD); - IF_TRACE_jvmci_3 { - char type[O_BUFLEN]; - obj->klass()->name()->as_C_string(type, O_BUFLEN); - TRACE_jvmci_3("%s: exited locking slow case with obj=" INTPTR_FORMAT ", type=%s, mark=" INTPTR_FORMAT ", lock=" INTPTR_FORMAT, thread->name(), p2i(obj), type, obj->mark().value(), p2i(lock)); - tty->flush(); - } + assert(oopDesc::is_oop(obj), "invalid lock object pointer dected"); + SharedRuntime::monitor_exit_helper(obj, lock, thread); JRT_END // Object.notify() fast path, caller does slow path diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 85b4b47bf85..de90ee4c28f 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -541,6 +541,7 @@ declare_constant(Deoptimization::Reason_unresolved) \ declare_constant(Deoptimization::Reason_jsr_mismatch) \ declare_constant(Deoptimization::Reason_LIMIT) \ + declare_constant(Deoptimization::_support_large_access_byte_array_virtualization) \ \ declare_constant(FieldInfo::access_flags_offset) \ declare_constant(FieldInfo::name_index_offset) \ diff --git a/src/hotspot/share/logging/log.hpp b/src/hotspot/share/logging/log.hpp index 36a6f63a7e9..3d9a2682182 100644 --- a/src/hotspot/share/logging/log.hpp +++ b/src/hotspot/share/logging/log.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -189,6 +189,11 @@ public: return LogImpl::is_level(level); } + static bool develop_is_enabled() { + NOT_PRODUCT(return is_enabled()); + PRODUCT_ONLY(return false); + } + static void print(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2) { va_list args; va_start(args, fmt); diff --git a/src/hotspot/share/logging/logPrefix.hpp b/src/hotspot/share/logging/logPrefix.hpp index 8652e7b6361..2027bf6bc29 100644 --- a/src/hotspot/share/logging/logPrefix.hpp +++ b/src/hotspot/share/logging/logPrefix.hpp @@ -82,6 +82,7 @@ DEBUG_ONLY(size_t Test_log_prefix_prefixer(char* buf, size_t len);) LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, remset, tracking)) \ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref)) \ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, ref, start)) \ + LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, refine, stats)) \ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, reloc)) \ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, start)) \ LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, symboltable)) \ diff --git a/src/hotspot/share/logging/logStream.hpp b/src/hotspot/share/logging/logStream.hpp index ea14f41cf85..2602eeaa6fc 100644 --- a/src/hotspot/share/logging/logStream.hpp +++ b/src/hotspot/share/logging/logStream.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,6 +93,10 @@ public: // LogStreamBase(level, tageset); LogStream(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {} + bool is_enabled() const { + return _log_handle.is_enabled(); + } + void write(const char* s, size_t len); }; diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index cf3383bc7dd..da9dcd2316e 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -52,6 +52,7 @@ LOG_TAG(codecache) \ LOG_TAG(compaction) \ LOG_TAG(compilation) \ + LOG_TAG(condy) \ LOG_TAG(constraints) \ LOG_TAG(constantpool) \ LOG_TAG(container) \ @@ -80,6 +81,7 @@ LOG_TAG(humongous) \ LOG_TAG(ihop) \ LOG_TAG(iklass) \ + LOG_TAG(indy) \ LOG_TAG(init) \ LOG_TAG(inlining) \ LOG_TAG(install) \ @@ -102,6 +104,7 @@ LOG_TAG(methodcomparator) \ LOG_TAG(metadata) \ LOG_TAG(metaspace) \ + LOG_TAG(methodhandles) \ LOG_TAG(mmu) \ LOG_TAG(module) \ LOG_TAG(monitorinflation) \ diff --git a/src/hotspot/share/memory/heapShared.cpp b/src/hotspot/share/memory/heapShared.cpp index 53366c22a4a..22ef0b30f98 100644 --- a/src/hotspot/share/memory/heapShared.cpp +++ b/src/hotspot/share/memory/heapShared.cpp @@ -97,6 +97,7 @@ void HeapShared::fixup_mapped_heap_regions() { FileMapInfo *mapinfo = FileMapInfo::current_info(); mapinfo->fixup_mapped_heap_regions(); set_archive_heap_region_fixed(); + SystemDictionaryShared::update_archived_mirror_native_pointers(); } unsigned HeapShared::oop_hash(oop const& p) { diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp index 3c15ba3149d..ae541f287d5 100644 --- a/src/hotspot/share/memory/metaspace.cpp +++ b/src/hotspot/share/memory/metaspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,7 @@ static const char* space_type_name(Metaspace::MetaspaceType t) { switch (t) { case Metaspace::StandardMetaspaceType: s = "Standard"; break; case Metaspace::BootMetaspaceType: s = "Boot"; break; - case Metaspace::UnsafeAnonymousMetaspaceType: s = "UnsafeAnonymous"; break; + case Metaspace::ClassMirrorHolderMetaspaceType: s = "ClassMirrorHolder"; break; case Metaspace::ReflectionMetaspaceType: s = "Reflection"; break; default: ShouldNotReachHere(); } diff --git a/src/hotspot/share/memory/metaspace.hpp b/src/hotspot/share/memory/metaspace.hpp index eda6b314c70..5861c562acb 100644 --- a/src/hotspot/share/memory/metaspace.hpp +++ b/src/hotspot/share/memory/metaspace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,8 +104,8 @@ class Metaspace : public AllStatic { ZeroMetaspaceType = 0, StandardMetaspaceType = ZeroMetaspaceType, BootMetaspaceType = StandardMetaspaceType + 1, - UnsafeAnonymousMetaspaceType = BootMetaspaceType + 1, - ReflectionMetaspaceType = UnsafeAnonymousMetaspaceType + 1, + ClassMirrorHolderMetaspaceType = BootMetaspaceType + 1, + ReflectionMetaspaceType = ClassMirrorHolderMetaspaceType + 1, MetaspaceTypeCount }; @@ -254,7 +254,7 @@ class ClassLoaderMetaspace : public CHeapObj { // Initialize the first chunk for a Metaspace. Used for // special cases such as the boot class loader, reflection - // class loader and anonymous class loader. + // class loader and hidden class loader. void initialize_first_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype); metaspace::Metachunk* get_initialization_chunk(Metaspace::MetaspaceType type, Metaspace::MetadataType mdtype); @@ -399,7 +399,7 @@ public: rf_show_loaders = (1 << 0), // Breaks report down by chunk type (small, medium, ...). rf_break_down_by_chunktype = (1 << 1), - // Breaks report down by space type (anonymous, reflection, ...). + // Breaks report down by space type (hidden, reflection, ...). rf_break_down_by_spacetype = (1 << 2), // Print details about the underlying virtual spaces. rf_show_vslist = (1 << 3), diff --git a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp index 7bae7fc657c..99ca6570889 100644 --- a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp +++ b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,7 @@ void PrintCLDMetaspaceInfoClosure::do_cld(ClassLoaderData* cld) { _out->print(UINTX_FORMAT_W(4) ": ", _num_loaders); // Print "CLD for [,] instance of " - // or "CLD for , loaded by [,] instance of " + // or "CLD for , loaded by [,] instance of " ResourceMark rm; const char* name = NULL; @@ -128,8 +128,8 @@ void PrintCLDMetaspaceInfoClosure::do_cld(ClassLoaderData* cld) { _out->print(" (unloading)"); } _out->print(":"); - if (cld->is_unsafe_anonymous()) { - _out->print(" , loaded by"); + if (cld->has_class_mirror_holder()) { + _out->print(" , loaded by"); } if (name != NULL) { _out->print(" \"%s\"", name); diff --git a/src/hotspot/share/memory/metaspace/spaceManager.cpp b/src/hotspot/share/memory/metaspace/spaceManager.cpp index 6142afa35e7..236e8cbb328 100644 --- a/src/hotspot/share/memory/metaspace/spaceManager.cpp +++ b/src/hotspot/share/memory/metaspace/spaceManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,14 +75,14 @@ size_t SpaceManager::get_initial_chunk_size(Metaspace::MetaspaceType type) const if (is_class()) { switch (type) { case Metaspace::BootMetaspaceType: requested = Metaspace::first_class_chunk_word_size(); break; - case Metaspace::UnsafeAnonymousMetaspaceType: requested = ClassSpecializedChunk; break; + case Metaspace::ClassMirrorHolderMetaspaceType: requested = ClassSpecializedChunk; break; case Metaspace::ReflectionMetaspaceType: requested = ClassSpecializedChunk; break; default: requested = ClassSmallChunk; break; } } else { switch (type) { case Metaspace::BootMetaspaceType: requested = Metaspace::first_chunk_word_size(); break; - case Metaspace::UnsafeAnonymousMetaspaceType: requested = SpecializedChunk; break; + case Metaspace::ClassMirrorHolderMetaspaceType: requested = SpecializedChunk; break; case Metaspace::ReflectionMetaspaceType: requested = SpecializedChunk; break; default: requested = SmallChunk; break; } @@ -114,15 +114,15 @@ size_t SpaceManager::calc_chunk_size(size_t word_size) { // After that a medium chunk is preferred. size_t chunk_word_size; - // Special case for unsafe anonymous metadata space. - // UnsafeAnonymous metadata space is usually small since it is used for - // class loader data's whose life cycle is governed by one class such as an - // unsafe anonymous class. The majority within 1K - 2K range and + // Special case for hidden metadata space. + // ClassMirrorHolder metadata space is usually small since it is used for + // class loader data's whose life cycle is governed by one class such as a + // non-strong hidden class or unsafe anonymous class. The majority within 1K - 2K range and // rarely about 4K (64-bits JVM). // Instead of jumping to SmallChunk after initial chunk exhausted, keeping allocation // from SpecializeChunk up to _anon_or_delegating_metadata_specialize_chunk_limit (4) // reduces space waste from 60+% to around 30%. - if ((_space_type == Metaspace::UnsafeAnonymousMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) && + if ((_space_type == Metaspace::ClassMirrorHolderMetaspaceType || _space_type == Metaspace::ReflectionMetaspaceType) && _mdtype == Metaspace::NonClassType && num_chunks_by_type(SpecializedIndex) < anon_and_delegating_metadata_specialize_chunk_limit && word_size + Metachunk::overhead() <= SpecializedChunk) { diff --git a/src/hotspot/share/memory/metaspaceTracer.cpp b/src/hotspot/share/memory/metaspaceTracer.cpp index ccb043c5dab..824ab97c8bb 100644 --- a/src/hotspot/share/memory/metaspaceTracer.cpp +++ b/src/hotspot/share/memory/metaspaceTracer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,10 +62,15 @@ void MetaspaceTracer::send_allocation_failure_event(ClassLoaderData *cld, E event; if (event.should_commit()) { event.set_classLoader(cld); - if (cld->is_unsafe_anonymous()) { - event.set_unsafeAnonymousClassLoader(true); - } else { - event.set_unsafeAnonymousClassLoader(false); + event.set_unsafeAnonymousClassLoader(false); // initialize these + event.set_hiddenClassLoader(false); + if (cld->has_class_mirror_holder()) { + assert(cld->klasses() != NULL, "unexpected NULL for cld->klasses()"); + if (cld->klasses()->is_non_strong_hidden()) { + event.set_hiddenClassLoader(true); + } else { + event.set_unsafeAnonymousClassLoader(true); + } } event.set_size(word_size * BytesPerWord); event.set_metadataType((u1) mdtype); diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp index 9063b454115..0c116801874 100644 --- a/src/hotspot/share/oops/arrayKlass.cpp +++ b/src/hotspot/share/oops/arrayKlass.cpp @@ -110,7 +110,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, Klass* super_klass, assert((module_entry != NULL) || ((module_entry == NULL) && !ModuleEntryTable::javabase_defined()), "module entry not available post " JAVA_BASE_NAME " definition"); oop module = (module_entry != NULL) ? module_entry->module() : (oop)NULL; - java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module), Handle(), CHECK); + java_lang_Class::create_mirror(k, Handle(THREAD, k->class_loader()), Handle(THREAD, module), Handle(), Handle(), CHECK); } GrowableArray* ArrayKlass::compute_secondary_supers(int num_extra_slots, diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 4e24f59b53d..4d8b587a04e 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -32,6 +32,8 @@ #include "classfile/vmSymbols.hpp" #include "interpreter/bootstrapInfo.hpp" #include "interpreter/linkResolver.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" @@ -941,7 +943,7 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, // (invocation of the BSM), of JVMS Section 5.4.3.6 occur within invoke_bootstrap_method() // for the bootstrap_specifier created above. SystemDictionary::invoke_bootstrap_method(bootstrap_specifier, THREAD); - Exceptions::wrap_dynamic_exception(THREAD); + Exceptions::wrap_dynamic_exception(/* is_indy */ false, THREAD); if (HAS_PENDING_EXCEPTION) { // Resolution failure of the dynamically-computed constant, save_and_throw_exception // will check for a LinkageError and store a DynamicConstantInError. @@ -969,8 +971,10 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, } } - if (TraceMethodHandles) { - bootstrap_specifier.print_msg_on(tty, "resolve_constant_at_impl"); + LogTarget(Debug, methodhandles, condy) lt_condy; + if (lt_condy.is_enabled()) { + LogStream ls(lt_condy); + bootstrap_specifier.print_msg_on(&ls, "resolve_constant_at_impl"); } break; } diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 296ea69328a..4eaac6a131e 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -30,6 +30,7 @@ #include "interpreter/linkResolver.hpp" #include "interpreter/rewriter.hpp" #include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" @@ -412,15 +413,18 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle& ( 1 << is_final_shift ), adapter->size_of_parameters()); - if (TraceInvokeDynamic) { - ttyLocker ttyl; - tty->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ", - invoke_code, - p2i(appendix()), - (has_appendix ? "" : " (unused)"), - p2i(adapter)); - adapter->print(); - if (has_appendix) appendix()->print(); + LogStream* log_stream = NULL; + LogStreamHandle(Debug, methodhandles, indy) lsh_indy; + if (lsh_indy.is_enabled()) { + ResourceMark rm; + log_stream = &lsh_indy; + log_stream->print_cr("set_method_handle bc=%d appendix=" PTR_FORMAT "%s method=" PTR_FORMAT " (local signature) ", + invoke_code, + p2i(appendix()), + (has_appendix ? "" : " (unused)"), + p2i(adapter)); + adapter->print_on(log_stream); + if (has_appendix) appendix()->print_on(log_stream); } // Method handle invokes and invokedynamic sites use both cp cache words. @@ -456,9 +460,9 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle& // but it is used by is_resolved, method_if_resolved, etc. set_bytecode_1(invoke_code); NOT_PRODUCT(verify(tty)); - if (TraceInvokeDynamic) { - ttyLocker ttyl; - this->print(tty, 0); + + if (log_stream != NULL) { + this->print(log_stream, 0); } assert(has_appendix == this->has_appendix(), "proper storage of appendix flag"); diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index d95bcb0d0ff..b8151fa2b3f 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -31,6 +31,7 @@ #include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.hpp" #include "classfile/moduleEntry.hpp" +#include "classfile/resolutionErrors.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" @@ -134,6 +135,7 @@ #endif // ndef DTRACE_ENABLED + static inline bool is_class_loader(const Symbol* class_name, const ClassFileParser& parser) { assert(class_name != NULL, "invariant"); @@ -153,8 +155,11 @@ static inline bool is_class_loader(const Symbol* class_name, return false; } -// called to verify that k is a member of this nest +// private: called to verify that k is a static member of this nest. +// We know that k is an instance class in the same package and hence the +// same classloader. bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { + assert(!is_hidden(), "unexpected hidden class"); if (_nest_members == NULL || _nest_members == Universe::the_empty_short_array()) { if (log_is_enabled(Trace, class, nestmates)) { ResourceMark rm(THREAD); @@ -175,7 +180,9 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { for (int i = 0; i < _nest_members->length(); i++) { int cp_index = _nest_members->at(i); if (_constants->tag_at(cp_index).is_klass()) { - Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + Klass* k2 = _constants->klass_at(cp_index, THREAD); + assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()), + "Exceptions should not be possible here"); if (k2 == k) { log_trace(class, nestmates)("- class is listed at nest_members[%d] => cp[%d]", i, cp_index); return true; @@ -186,15 +193,14 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { if (name == k->name()) { log_trace(class, nestmates)("- Found it at nest_members[%d] => cp[%d]", i, cp_index); - // Names match so check actual klass - this may trigger class loading if - // it doesn't match (though that should be impossible). But to be safe we - // have to check for a compiler thread executing here. - if (!THREAD->can_call_java() && !_constants->tag_at(cp_index).is_klass()) { - log_trace(class, nestmates)("- validation required resolution in an unsuitable thread"); - return false; - } - - Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + // Names match so check actual klass. This may trigger class loading if + // it doesn't match though that should be impossible as it means one classloader + // has defined two different classes with the same name! A compiler thread won't be + // able to perform that loading but we can't exclude the compiler threads from + // executing this logic. But it should actually be impossible to trigger loading here. + Klass* k2 = _constants->klass_at(cp_index, THREAD); + assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()), + "Exceptions should not be possible here"); if (k2 == k) { log_trace(class, nestmates)("- class is listed as a nest member"); return true; @@ -213,167 +219,210 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const { } // Return nest-host class, resolving, validating and saving it if needed. -// In cases where this is called from a thread that can not do classloading +// In cases where this is called from a thread that cannot do classloading // (such as a native JIT thread) then we simply return NULL, which in turn // causes the access check to return false. Such code will retry the access -// from a more suitable environment later. -InstanceKlass* InstanceKlass::nest_host(Symbol* validationException, TRAPS) { +// from a more suitable environment later. Otherwise the _nest_host is always +// set once this method returns. +// Any errors from nest-host resolution must be preserved so they can be queried +// from higher-level access checking code, and reported as part of access checking +// exceptions. +// VirtualMachineErrors are propagated with a NULL return. +// Under any conditions where the _nest_host can be set to non-NULL the resulting +// value of it and, if applicable, the nest host resolution/validation error, +// are idempotent. +InstanceKlass* InstanceKlass::nest_host(TRAPS) { InstanceKlass* nest_host_k = _nest_host; - if (nest_host_k == NULL) { - // need to resolve and save our nest-host class. This could be attempted - // concurrently but as the result is idempotent and we don't use the class - // then we do not need any synchronization beyond what is implicitly used - // during class loading. - if (_nest_host_index != 0) { // we have a real nest_host - // Before trying to resolve check if we're in a suitable context - if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", - this->external_name()); - } - return NULL; - } + if (nest_host_k != NULL) { + return nest_host_k; + } - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", - this->external_name(), - _constants->klass_name_at(_nest_host_index)->as_C_string()); - } + ResourceMark rm(THREAD); - Klass* k = _constants->klass_at(_nest_host_index, THREAD); - if (HAS_PENDING_EXCEPTION) { - Handle exc_h = Handle(THREAD, PENDING_EXCEPTION); - if (exc_h->is_a(SystemDictionary::NoClassDefFoundError_klass())) { - // throw a new CDNFE with the original as its cause, and a clear msg - ResourceMark rm(THREAD); - char buf[200]; - CLEAR_PENDING_EXCEPTION; - jio_snprintf(buf, sizeof(buf), - "Unable to load nest-host class (%s) of %s", - _constants->klass_name_at(_nest_host_index)->as_C_string(), - this->external_name()); - log_trace(class, nestmates)("%s - NoClassDefFoundError", buf); - THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), buf, exc_h); - } - // All other exceptions pass through (OOME, StackOverflowError, LinkageErrors etc). - return NULL; - } + // need to resolve and save our nest-host class. + if (_nest_host_index != 0) { // we have a real nest_host + // Before trying to resolve check if we're in a suitable context + if (!THREAD->can_call_java() && !_constants->tag_at(_nest_host_index).is_klass()) { + log_trace(class, nestmates)("Rejected resolution of nest-host of %s in unsuitable thread", + this->external_name()); + return NULL; // sentinel to say "try again from a different context" + } + log_trace(class, nestmates)("Resolving nest-host of %s using cp entry for %s", + this->external_name(), + _constants->klass_name_at(_nest_host_index)->as_C_string()); + + Klass* k = _constants->klass_at(_nest_host_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + stringStream ss; + char* target_host_class = _constants->klass_name_at(_nest_host_index)->as_C_string(); + ss.print("Nest host resolution of %s with host %s failed: ", + this->external_name(), target_host_class); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + const char* msg = ss.as_string(true /* on C-heap */); + constantPoolHandle cph(THREAD, constants()); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); + CLEAR_PENDING_EXCEPTION; + + log_trace(class, nestmates)("%s", msg); + } else { // A valid nest-host is an instance class in the current package that lists this - // class as a nest member. If any of these conditions are not met we post the - // requested exception type (if any) and return NULL - + // class as a nest member. If any of these conditions are not met the class is + // its own nest-host. const char* error = NULL; // JVMS 5.4.4 indicates package check comes first if (is_same_class_package(k)) { - // Now check actual membership. We can't be a member if our "host" is // not an instance class. if (k->is_instance_klass()) { nest_host_k = InstanceKlass::cast(k); + bool is_member = nest_host_k->has_nest_member(this, THREAD); + // exception is rare, perhaps impossible + if (!HAS_PENDING_EXCEPTION) { + if (is_member) { + _nest_host = nest_host_k; // save resolved nest-host value - bool is_member = nest_host_k->has_nest_member(this, CHECK_NULL); - if (is_member) { - // save resolved nest-host value - _nest_host = nest_host_k; - - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); log_trace(class, nestmates)("Resolved nest-host of %s to %s", this->external_name(), k->external_name()); + return nest_host_k; + } else { + error = "current type is not listed as a nest member"; } - return nest_host_k; + } else { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + stringStream ss; + ss.print("exception on member check: "); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + error = ss.as_string(); } + } else { + error = "host is not an instance class"; } - error = "current type is not listed as a nest member"; } else { error = "types are in different packages"; } - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates) - ("Type %s (loader: %s) is not a nest member of " - "resolved type %s (loader: %s): %s", - this->external_name(), - this->class_loader_data()->loader_name_and_id(), - k->external_name(), - k->class_loader_data()->loader_name_and_id(), - error); + // something went wrong, so record what and log it + { + stringStream ss; + ss.print("Type %s (loader: %s) is not a nest member of type %s (loader: %s): %s", + this->external_name(), + this->class_loader_data()->loader_name_and_id(), + k->external_name(), + k->class_loader_data()->loader_name_and_id(), + error); + const char* msg = ss.as_string(true /* on C-heap */); + constantPoolHandle cph(THREAD, constants()); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); + log_trace(class, nestmates)("%s", msg); } - - if (validationException != NULL && THREAD->can_call_java()) { - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - validationException, - "Type %s (loader: %s) is not a nest member of %s (loader: %s): %s", - this->external_name(), - this->class_loader_data()->loader_name_and_id(), - k->external_name(), - k->class_loader_data()->loader_name_and_id(), - error - ); - } - return NULL; - } else { - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", - this->external_name()); - } - // save resolved nest-host value - return (_nest_host = this); } + } else { + log_trace(class, nestmates)("Type %s is not part of a nest: setting nest-host to self", + this->external_name()); } - return nest_host_k; + + // Either not in an explicit nest, or else an error occurred, so + // the nest-host is set to `this`. Any thread that sees this assignment + // will also see any setting of nest_host_error(), if applicable. + return (_nest_host = this); +} + +// Dynamic nest member support: set this class's nest host to the given class. +// This occurs as part of the class definition, as soon as the instanceKlass +// has been created and doesn't require further resolution. The code: +// lookup().defineHiddenClass(bytes_for_X, NESTMATE); +// results in: +// class_of_X.set_nest_host(lookup().lookupClass().getNestHost()) +// If it has an explicit _nest_host_index or _nest_members, these will be ignored. +// We also know the "host" is a valid nest-host in the same package so we can +// assert some of those facts. +void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) { + assert(is_hidden(), "must be a hidden class"); + assert(host != NULL, "NULL nest host specified"); + assert(_nest_host == NULL, "current class has resolved nest-host"); + assert(nest_host_error(THREAD) == NULL, "unexpected nest host resolution error exists: %s", + nest_host_error(THREAD)); + assert((host->_nest_host == NULL && host->_nest_host_index == 0) || + (host->_nest_host == host), "proposed host is not a valid nest-host"); + // Can't assert this as package is not set yet: + // assert(is_same_class_package(host), "proposed host is in wrong package"); + + if (log_is_enabled(Trace, class, nestmates)) { + ResourceMark rm(THREAD); + const char* msg = ""; + // a hidden class does not expect a statically defined nest-host + if (_nest_host_index > 0) { + msg = "(the NestHost attribute in the current class is ignored)"; + } else if (_nest_members != NULL && _nest_members != Universe::the_empty_short_array()) { + msg = "(the NestMembers attribute in the current class is ignored)"; + } + log_trace(class, nestmates)("Injected type %s into the nest of %s %s", + this->external_name(), + host->external_name(), + msg); + } + // set dynamic nest host + _nest_host = host; + // Record dependency to keep nest host from being unloaded before this class. + ClassLoaderData* this_key = class_loader_data(); + this_key->record_dependency(host); } // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, // or we are k's nest_host - all of which is covered by comparing the two -// resolved_nest_hosts +// resolved_nest_hosts. +// Any exceptions (i.e. VMEs) are propagated. bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) { assert(this != k, "this should be handled by higher-level code"); // Per JVMS 5.4.4 we first resolve and validate the current class, then - // the target class k. Resolution exceptions will be passed on by upper - // layers. IncompatibleClassChangeErrors from membership validation failures - // will also be passed through. + // the target class k. - Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); - InstanceKlass* cur_host = nest_host(icce, CHECK_false); + InstanceKlass* cur_host = nest_host(CHECK_false); if (cur_host == NULL) { return false; } - Klass* k_nest_host = k->nest_host(icce, CHECK_false); + Klass* k_nest_host = k->nest_host(CHECK_false); if (k_nest_host == NULL) { return false; } bool access = (cur_host == k_nest_host); - if (log_is_enabled(Trace, class, nestmates)) { - ResourceMark rm(THREAD); - log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", - this->external_name(), - access ? "" : "NOT ", - k->external_name()); - } - + ResourceMark rm(THREAD); + log_trace(class, nestmates)("Class %s does %shave nestmate access to %s", + this->external_name(), + access ? "" : "NOT ", + k->external_name()); return access; } +const char* InstanceKlass::nest_host_error(TRAPS) { + if (_nest_host_index == 0) { + return NULL; + } else { + constantPoolHandle cph(THREAD, constants()); + return SystemDictionary::find_nest_host_error(cph, (int)_nest_host_index); + } +} + InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { + bool is_hidden_or_anonymous = parser.is_hidden() || parser.is_unsafe_anonymous(); const int size = InstanceKlass::size(parser.vtable_size(), parser.itable_size(), nonstatic_oop_map_size(parser.total_oop_map_count()), parser.is_interface(), parser.is_unsafe_anonymous(), - should_store_fingerprint(parser.is_unsafe_anonymous())); + should_store_fingerprint(is_hidden_or_anonymous)); const Symbol* const class_name = parser.class_name(); assert(class_name != NULL, "invariant"); @@ -447,6 +496,7 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, Klass set_vtable_length(parser.vtable_size()); set_kind(kind); set_access_flags(parser.access_flags()); + if (parser.is_hidden()) set_is_hidden(); set_is_unsafe_anonymous(parser.is_unsafe_anonymous()); set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), false)); @@ -2276,7 +2326,7 @@ bool InstanceKlass::supers_have_passed_fingerprint_checks() { return true; } -bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) { +bool InstanceKlass::should_store_fingerprint(bool is_hidden_or_anonymous) { #if INCLUDE_AOT // We store the fingerprint into the InstanceKlass only in the following 2 cases: if (CalculateClassFingerprint) { @@ -2287,8 +2337,8 @@ bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) { // (2) We are running -Xshare:dump or -XX:ArchiveClassesAtExit to create a shared archive return true; } - if (UseAOT && is_unsafe_anonymous) { - // (3) We are using AOT code from a shared library and see an unsafe anonymous class + if (UseAOT && is_hidden_or_anonymous) { + // (3) We are using AOT code from a shared library and see a hidden or unsafe anonymous class return true; } #endif @@ -2581,6 +2631,7 @@ void InstanceKlass::release_C_heap_structures() { // Decrement symbol reference counts associated with the unloaded class. if (_name != NULL) _name->decrement_refcount(); + // unreference array name derived from this class name (arrays of an unloaded // class can't be referenced anymore). if (_array_name != NULL) _array_name->decrement_refcount(); @@ -2631,6 +2682,15 @@ const char* InstanceKlass::signature_name() const { dest[dest_index++] = src[src_index++]; } + if (is_hidden()) { // Replace the last '+' with a '.'. + for (int index = (int)src_length; index > 0; index--) { + if (dest[index] == '+') { + dest[index] = JVM_SIGNATURE_DOT; + break; + } + } + } + // If we have a hash, append it for (int hash_index = 0; hash_index < hash_len; ) { dest[dest_index++] = hash_buf[hash_index++]; @@ -2649,6 +2709,25 @@ ModuleEntry* InstanceKlass::module() const { return unsafe_anonymous_host()->module(); } + if (is_hidden() && + in_unnamed_package() && + class_loader_data()->has_class_mirror_holder()) { + // For a non-strong hidden class defined to an unnamed package, + // its (class held) CLD will not have an unnamed module created for it. + // Two choices to find the correct ModuleEntry: + // 1. If hidden class is within a nest, use nest host's module + // 2. Find the unnamed module off from the class loader + // For now option #2 is used since a nest host is not set until + // after the instance class is created in jvm_lookup_define_class(). + if (class_loader_data()->is_boot_class_loader_data()) { + return ClassLoaderData::the_null_class_loader_data()->unnamed_module(); + } else { + oop module = java_lang_ClassLoader::unnamedModule(class_loader_data()->class_loader()); + assert(java_lang_Module::is_instance(module), "Not an instance of java.lang.Module"); + return java_lang_Module::module_entry(module); + } + } + // Class is in a named package if (!in_unnamed_package()) { return _package_entry->module(); @@ -2661,7 +2740,10 @@ ModuleEntry* InstanceKlass::module() const { void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS) { // ensure java/ packages only loaded by boot or platform builtin loaders - check_prohibited_package(name(), loader_data, CHECK); + // not needed for shared class since CDS does not archive prohibited classes. + if (!is_shared()) { + check_prohibited_package(name(), loader_data, CHECK); + } TempNewSymbol pkg_name = pkg_entry != NULL ? pkg_entry->name() : ClassLoader::package_from_class_name(name()); @@ -2712,6 +2794,23 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_ } } +// Function set_classpath_index checks if the package of the InstanceKlass is in the +// boot loader's package entry table. If so, then it sets the classpath_index +// in the package entry record. +// +// The classpath_index field is used to find the entry on the boot loader class +// path for packages with classes loaded by the boot loader from -Xbootclasspath/a +// in an unnamed module. It is also used to indicate (for all packages whose +// classes are loaded by the boot loader) that at least one of the package's +// classes has been loaded. +void InstanceKlass::set_classpath_index(s2 path_index, TRAPS) { + if (_package_entry != NULL) { + DEBUG_ONLY(PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages();) + assert(pkg_entry_tbl->lookup_only(_package_entry->name()) == _package_entry, "Should be same"); + assert(path_index != -1, "Unexpected classpath_index"); + _package_entry->set_classpath_index(path_index); + } +} // different versions of is_same_class_package @@ -2859,7 +2958,7 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA *inner_is_member = true; } if (NULL == outer_klass) { - // It may be unsafe anonymous; try for that. + // It may be a local or anonymous class; try for that. int encl_method_class_idx = enclosing_method_class_index(); if (encl_method_class_idx != 0) { Klass* ok = i_cp->klass_at(encl_method_class_idx, CHECK_NULL); diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 6f5345ac4e2..7a1547a33ec 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -195,7 +195,10 @@ class InstanceKlass: public Klass { // that is the nest-host of this class. This data has not been validated. jushort _nest_host_index; - // Resolved nest-host klass: either true nest-host or self if we are not nested. + // Resolved nest-host klass: either true nest-host or self if we are not + // nested, or an error occurred resolving or validating the nominated + // nest-host. Can also be set directly by JDK API's that establish nest + // relationships. // By always being set it makes nest-member access checks simpler. InstanceKlass* _nest_host; @@ -469,6 +472,8 @@ class InstanceKlass: public Klass { // nest-host index jushort nest_host_index() const { return _nest_host_index; } void set_nest_host_index(u2 i) { _nest_host_index = i; } + // dynamic nest member support + void set_nest_host(InstanceKlass* host, TRAPS); // record components Array* record_components() const { return _record_components; } @@ -482,9 +487,13 @@ private: bool has_nest_member(InstanceKlass* k, TRAPS) const; public: - // Returns nest-host class, resolving and validating it if needed - // Returns NULL if an exception occurs during loading, or validation fails - InstanceKlass* nest_host(Symbol* validationException, TRAPS); + // Used to construct informative IllegalAccessError messages at a higher level, + // if there was an issue resolving or validating the nest host. + // Returns NULL if there was no error. + const char* nest_host_error(TRAPS); + // Returns nest-host class, resolving and validating it if needed. + // Returns NULL if resolution is not possible from the calling context. + InstanceKlass* nest_host(TRAPS); // Check if this klass is a nestmate of k - resolves this nest-host and k's bool has_nestmate_access_to(InstanceKlass* k, TRAPS); @@ -510,8 +519,15 @@ public: PackageEntry* package() const { return _package_entry; } ModuleEntry* module() const; bool in_unnamed_package() const { return (_package_entry == NULL); } - void set_package(PackageEntry* p) { _package_entry = p; } void set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS); + // If the package for the InstanceKlass is in the boot loader's package entry + // table then sets the classpath_index field so that + // get_system_package() will know to return a non-null value for the + // package's location. And, so that the package will be added to the list of + // packages returned by get_system_packages(). + // For packages whose classes are loaded from the boot loader class path, the + // classpath_index indicates which entry on the boot loader class path. + void set_classpath_index(s2 path_index, TRAPS); bool is_same_class_package(const Klass* class2) const; bool is_same_class_package(oop other_class_loader, const Symbol* other_class_name) const; @@ -610,11 +626,11 @@ public: // find a local method, but skip static methods Method* find_instance_method(const Symbol* name, const Symbol* signature, - PrivateLookupMode private_mode = find_private) const; + PrivateLookupMode private_mode) const; static Method* find_instance_method(const Array* methods, const Symbol* name, const Symbol* signature, - PrivateLookupMode private_mode = find_private); + PrivateLookupMode private_mode); // find a local method (returns NULL if not found) Method* find_local_method(const Symbol* name, @@ -812,8 +828,8 @@ public: } bool supers_have_passed_fingerprint_checks(); - static bool should_store_fingerprint(bool is_unsafe_anonymous); - bool should_store_fingerprint() const { return should_store_fingerprint(is_unsafe_anonymous()); } + static bool should_store_fingerprint(bool is_hidden_or_anonymous); + bool should_store_fingerprint() const { return should_store_fingerprint(is_hidden() || is_unsafe_anonymous()); } bool has_stored_fingerprint() const; uint64_t get_stored_fingerprint() const; void store_fingerprint(uint64_t fingerprint); diff --git a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp index ee3679c70aa..eaf5f61c4ae 100644 --- a/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp +++ b/src/hotspot/share/oops/instanceMirrorKlass.inline.hpp @@ -1,4 +1,5 @@ -/* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +/* + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,10 +52,9 @@ void InstanceMirrorKlass::oop_oop_iterate(oop obj, OopClosureType* closure) { Klass* klass = java_lang_Class::as_Klass_raw(obj); // We'll get NULL for primitive mirrors. if (klass != NULL) { - if (klass->is_instance_klass() && - InstanceKlass::cast(klass)->is_unsafe_anonymous()) { - // An unsafe anonymous class doesn't have its own class loader, so - // when handling the java mirror for the class we need to make sure its class + if (klass->is_instance_klass() && klass->class_loader_data()->has_class_mirror_holder()) { + // A non-strong hidden class or an unsafe anonymous class doesn't have its own class loader, + // so when handling the java mirror for the class we need to make sure its class // loader data is claimed, this is done by calling do_cld explicitly. // For non-anonymous classes the call to do_cld is made when the class // loader itself is handled. diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 2f2abe8e2ca..81f460f907f 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -608,7 +608,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec // gotten an OOM later but keep the mirror if it was created. if (java_mirror() == NULL) { log_trace(cds, mirror)("Recreate mirror for %s", external_name()); - java_lang_Class::create_mirror(this, loader, module_handle, protection_domain, CHECK); + java_lang_Class::create_mirror(this, loader, module_handle, protection_domain, Handle(), CHECK); } } @@ -672,6 +672,20 @@ void Klass::check_array_allocation_length(int length, int max_length, TRAPS) { } } +// Replace the last '+' char with '/'. +static char* convert_hidden_name_to_java(Symbol* name) { + size_t name_len = name->utf8_length(); + char* result = NEW_RESOURCE_ARRAY(char, name_len + 1); + name->as_klass_external_name(result, (int)name_len + 1); + for (int index = (int)name_len; index > 0; index--) { + if (result[index] == '+') { + result[index] = JVM_SIGNATURE_SLASH; + break; + } + } + return result; +} + // In product mode, this function doesn't have virtual function calls so // there might be some performance advantage to handling InstanceKlass here. const char* Klass::external_name() const { @@ -688,7 +702,14 @@ const char* Klass::external_name() const { strcpy(result + name_len, addr_buf); assert(strlen(result) == name_len + addr_len, ""); return result; + + } else if (ik->is_hidden()) { + char* result = convert_hidden_name_to_java(name()); + return result; } + } else if (is_objArray_klass() && ObjArrayKlass::cast(this)->bottom_klass()->is_hidden()) { + char* result = convert_hidden_name_to_java(name()); + return result; } if (name() == NULL) return ""; return name()->as_klass_external_name(); @@ -696,6 +717,18 @@ const char* Klass::external_name() const { const char* Klass::signature_name() const { if (name() == NULL) return ""; + if (is_objArray_klass() && ObjArrayKlass::cast(this)->bottom_klass()->is_hidden()) { + size_t name_len = name()->utf8_length(); + char* result = NEW_RESOURCE_ARRAY(char, name_len + 1); + name()->as_C_string(result, (int)name_len + 1); + for (int index = (int)name_len; index > 0; index--) { + if (result[index] == '+') { + result[index] = JVM_SIGNATURE_DOT; + break; + } + } + return result; + } return name()->as_C_string(); } diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index d1e2d2bfc37..598d33d8ee6 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -615,6 +615,10 @@ protected: void set_has_miranda_methods() { _access_flags.set_has_miranda_methods(); } bool is_shared() const { return access_flags().is_shared_class(); } // shadows MetaspaceObj::is_shared)() void set_is_shared() { _access_flags.set_is_shared_class(); } + bool is_hidden() const { return access_flags().is_hidden_class(); } + void set_is_hidden() { _access_flags.set_is_hidden_class(); } + bool is_non_strong_hidden() const { return access_flags().is_hidden_class() && + class_loader_data()->has_class_mirror_holder(); } bool is_cloneable() const; void set_is_cloneable(); diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index ce4c222eed0..9b7f63c9ff3 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -38,6 +38,7 @@ #include "interpreter/oopMapCache.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" @@ -1417,9 +1418,8 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, InstanceKlass* holder = SystemDictionary::MethodHandle_klass(); Symbol* name = MethodHandles::signature_polymorphic_intrinsic_name(iid); assert(iid == MethodHandles::signature_polymorphic_name_id(name), ""); - if (TraceMethodHandles) { - tty->print_cr("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string()); - } + + log_info(methodhandles)("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string()); // invariant: cp->symbol_at_put is preceded by a refcount increment (more usually a lookup) name->increment_refcount(); @@ -1470,9 +1470,10 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, m->set_vtable_index(Method::nonvirtual_vtable_index); m->link_method(m, CHECK_(empty)); - if (TraceMethodHandles && (Verbose || WizardMode)) { - ttyLocker ttyl; - m->print_on(tty); + if (log_is_enabled(Info, methodhandles) && (Verbose || WizardMode)) { + LogTarget(Info, methodhandles) lt; + LogStream ls(lt); + m->print_on(&ls); } return m; diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 21c390a1894..5b912ca6f5d 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -892,9 +892,10 @@ public: _flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline); } - bool is_hidden() { + bool is_hidden() const { return (_flags & _hidden) != 0; } + void set_hidden(bool x) { _flags = x ? (_flags | _hidden) : (_flags & ~_hidden); } diff --git a/src/hotspot/share/oops/oopsHierarchy.hpp b/src/hotspot/share/oops/oopsHierarchy.hpp index b6d5122f8cb..a359d13946c 100644 --- a/src/hotspot/share/oops/oopsHierarchy.hpp +++ b/src/hotspot/share/oops/oopsHierarchy.hpp @@ -126,6 +126,7 @@ struct PrimitiveConversions::Translate : public TrueType { class type##Oop : public oop { \ public: \ type##Oop() : oop() {} \ + type##Oop(const type##Oop& o) : oop(o) {} \ type##Oop(const oop& o) : oop(o) {} \ type##Oop(const volatile oop& o) : oop(o) {} \ type##Oop(const void* p) : oop(p) {} \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 4495409c2eb..9495ac2fb43 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -602,6 +602,7 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virt case vmIntrinsics::_isInterface: case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: + case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: case vmIntrinsics::_floatToRawIntBits: diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp index c5fd283cac3..26f3cb1345c 100644 --- a/src/hotspot/share/opto/castnode.cpp +++ b/src/hotspot/share/opto/castnode.cpp @@ -63,14 +63,6 @@ const Type* ConstraintCastNode::Value(PhaseGVN* phase) const { if (rt->empty()) assert(ft == Type::TOP, "special case #2"); break; } - case Op_CastLL: - { - const Type* t1 = phase->type(in(1)); - if (t1 == Type::TOP) assert(ft == Type::TOP, "special case #1"); - const Type* rt = t1->join_speculative(_type); - if (rt->empty()) assert(ft == Type::TOP, "special case #2"); - break; - } case Op_CastPP: if (phase->type(in(1)) == TypePtr::NULL_PTR && _type->isa_ptr() && _type->is_ptr()->_ptr == TypePtr::NotNull) @@ -104,11 +96,6 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, cast->set_req(0, c); return cast; } - case Op_CastLL: { - Node* cast = new CastLLNode(n, t, carry_dependency); - cast->set_req(0, c); - return cast; - } case Op_CastPP: { Node* cast = new CastPPNode(n, t, carry_dependency); cast->set_req(0, c); @@ -292,45 +279,6 @@ void CastIINode::dump_spec(outputStream* st) const { } #endif -Node* CastLLNode::Ideal(PhaseGVN* phase, bool can_reshape) { - Node* progress = ConstraintCastNode::Ideal(phase, can_reshape); - if (progress != NULL) { - return progress; - } - - // Same as in CastIINode::Ideal but for TypeLong instead of TypeInt - if (can_reshape && !phase->C->major_progress()) { - const TypeLong* this_type = this->type()->is_long(); - const TypeLong* in_type = phase->type(in(1))->isa_long(); - if (in_type != NULL && this_type != NULL && - (in_type->_lo != this_type->_lo || - in_type->_hi != this_type->_hi)) { - jlong lo1 = this_type->_lo; - jlong hi1 = this_type->_hi; - int w1 = this_type->_widen; - - if (lo1 >= 0) { - // Keep a range assertion of >=0. - lo1 = 0; hi1 = max_jlong; - } else if (hi1 < 0) { - // Keep a range assertion of <0. - lo1 = min_jlong; hi1 = -1; - } else { - lo1 = min_jlong; hi1 = max_jlong; - } - const TypeLong* wtype = TypeLong::make(MAX2(in_type->_lo, lo1), - MIN2(in_type->_hi, hi1), - MAX2((int)in_type->_widen, w1)); - if (wtype != type()) { - set_type(wtype); - return this; - } - } - } - return NULL; -} - - //============================================================================= //------------------------------Identity--------------------------------------- // If input is already higher or equal to cast type, then this is an identity. diff --git a/src/hotspot/share/opto/castnode.hpp b/src/hotspot/share/opto/castnode.hpp index 19b9c7a2eda..e4fe29a438e 100644 --- a/src/hotspot/share/opto/castnode.hpp +++ b/src/hotspot/share/opto/castnode.hpp @@ -91,19 +91,6 @@ class CastIINode: public ConstraintCastNode { #endif }; -//------------------------------CastLLNode------------------------------------- -// cast long to long (different range) -class CastLLNode: public ConstraintCastNode { - public: - CastLLNode(Node* n, const Type* t, bool carry_dependency = false) - : ConstraintCastNode(n, t, carry_dependency) { - init_class_id(Class_CastLL); - } - virtual int Opcode() const; - virtual uint ideal_reg() const { return Op_RegL; } - virtual Node* Ideal(PhaseGVN* phase, bool can_reshape); -}; - //------------------------------CastPPNode------------------------------------- // cast pointer to pointer (different type) class CastPPNode: public ConstraintCastNode { diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 27fca06216d..a71f527655b 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -1915,13 +1915,12 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Wait until after parsing for the type information to propagate from the casts. assert(can_reshape, "Invalid during parsing"); const Type* phi_type = bottom_type(); - assert(phi_type->isa_int() || phi_type->isa_long() || phi_type->isa_ptr(), "bad phi type"); - // Add casts to carry the control dependency of the Phi that is going away + assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type"); + // Add casts to carry the control dependency of the Phi that is + // going away Node* cast = NULL; if (phi_type->isa_int()) { cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true); - } else if (phi_type->isa_long()) { - cast = ConstraintCastNode::make_cast(Op_CastLL, r, uin, phi_type, true); } else { const Type* uin_type = phase->type(uin); if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index e90d93777b6..f0a12ef1dfd 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -61,7 +61,6 @@ macro(CallLeafNoFP) macro(CallRuntime) macro(CallStaticJava) macro(CastII) -macro(CastLL) macro(CastX2P) macro(CastP2X) macro(CastPP) diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 832729229fc..9838473ecbf 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -1365,37 +1365,35 @@ Node* GraphKit::null_check_common(Node* value, BasicType type, // Cast obj to not-null on this path, if there is no null_control. // (If there is a null_control, a non-null value may come back to haunt us.) - return cast_not_null(value, (null_control == NULL || (*null_control) == top())); + if (type == T_OBJECT) { + Node* cast = cast_not_null(value, false); + if (null_control == NULL || (*null_control) == top()) + replace_in_map(value, cast); + value = cast; + } + + return value; } //------------------------------cast_not_null---------------------------------- // Cast obj to not-null on this path Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) { - Node* cast = NULL; - const Type* t = _gvn.type(obj); - if (t->make_ptr() != NULL) { - const Type* t_not_null = t->join_speculative(TypePtr::NOTNULL); - // Object is already not-null? - if (t == t_not_null) { - return obj; - } - cast = ConstraintCastNode::make_cast(Op_CastPP, control(), obj, t_not_null, false); - } else if (t->isa_int() != NULL) { - cast = ConstraintCastNode::make_cast(Op_CastII, control(), obj, TypeInt::INT, true); - } else if (t->isa_long() != NULL) { - cast = ConstraintCastNode::make_cast(Op_CastLL, control(), obj, TypeLong::LONG, true); - } else { - fatal("unexpected type: %s", type2name(t->basic_type())); - } - cast = _gvn.transform(cast); + const Type *t = _gvn.type(obj); + const Type *t_not_null = t->join_speculative(TypePtr::NOTNULL); + // Object is already not-null? + if( t == t_not_null ) return obj; + + Node *cast = new CastPPNode(obj,t_not_null); + cast->init_req(0, control()); + cast = _gvn.transform( cast ); // Scan for instances of 'obj' in the current JVM mapping. // These instances are known to be not-null after the test. - if (do_replace_in_map) { + if (do_replace_in_map) replace_in_map(obj, cast); - } - return cast; + + return cast; // Return casted value } // Sometimes in intrinsics, we implicitly know an object is not null diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index d23fc03f465..de0efd13b91 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -186,6 +186,7 @@ class LibraryCallKit : public GraphKit { int modifier_mask, int modifier_bits, RegionNode* region); Node* generate_interface_guard(Node* kls, RegionNode* region); + Node* generate_hidden_class_guard(Node* kls, RegionNode* region); Node* generate_array_guard(Node* kls, RegionNode* region) { return generate_array_guard_common(kls, region, false, false); } @@ -783,6 +784,7 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_isInterface: case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: + case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: return inline_native_Class_query(intrinsic_id()); @@ -3084,6 +3086,9 @@ Node* LibraryCallKit::generate_access_flags_guard(Node* kls, int modifier_mask, Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_access_flags_guard(kls, JVM_ACC_INTERFACE, 0, region); } +Node* LibraryCallKit::generate_hidden_class_guard(Node* kls, RegionNode* region) { + return generate_access_flags_guard(kls, JVM_ACC_IS_HIDDEN_CLASS, 0, region); +} //-------------------------inline_native_Class_query------------------- bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { @@ -3119,6 +3124,9 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { prim_return_value = intcon(1); expect_prim = true; // obviously break; + case vmIntrinsics::_isHidden: + prim_return_value = intcon(0); + break; case vmIntrinsics::_getSuperclass: prim_return_value = null(); return_type = TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR); @@ -3211,6 +3219,16 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { query_value = intcon(0); // "normal" path produces false break; + case vmIntrinsics::_isHidden: + // (To verify this code sequence, check the asserts in JVM_IsHiddenClass.) + if (generate_hidden_class_guard(kls, region) != NULL) + // A guard was added. If the guard is taken, it was an hidden class. + phi->add_req(intcon(1)); + // If we fall through, it's a plain class. + query_value = intcon(0); + break; + + case vmIntrinsics::_getSuperclass: // The rules here are somewhat unfortunate, but we can still do better // with random logic than with a JNI call. diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index 8989c28755b..4b9916cdfb1 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -2450,21 +2450,6 @@ void Matcher::do_postselect_cleanup() { // Generic machine operands elision. //---------------------------------------------------------------------- -// Convert (leg)Vec to (leg)Vec[SDXYZ]. -MachOper* Matcher::specialize_vector_operand_helper(MachNode* m, uint opnd_idx, const TypeVect* vt) { - MachOper* original_opnd = m->_opnds[opnd_idx]; - uint ideal_reg = vt->ideal_reg(); - // Handle special cases. - // LShiftCntV/RShiftCntV report wide vector type, but Matcher::vector_shift_count_ideal_reg() as ideal register (see vectornode.hpp). - // Look for shift count use sites as well (at vector shift nodes). - int opc = m->ideal_Opcode(); - if ((VectorNode::is_vector_shift_count(opc) && opnd_idx == 0) || // DEF operand of LShiftCntV/RShiftCntV - (VectorNode::is_vector_shift(opc) && opnd_idx == 2)) { // shift operand of a vector shift node - ideal_reg = Matcher::vector_shift_count_ideal_reg(vt->length_in_bytes()); - } - return Matcher::specialize_generic_vector_operand(original_opnd, ideal_reg, false); -} - // Compute concrete vector operand for a generic TEMP vector mach node based on its user info. void Matcher::specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx) { assert(use->in(idx) == tmp, "not a user"); @@ -2474,7 +2459,7 @@ void Matcher::specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx) { tmp->_opnds[0] = use->_opnds[0]->clone(); } else { uint ideal_vreg = vector_ideal_reg(C->max_vector_size()); - tmp->_opnds[0] = specialize_generic_vector_operand(tmp->_opnds[0], ideal_vreg, true); + tmp->_opnds[0] = Matcher::pd_specialize_generic_vector_operand(tmp->_opnds[0], ideal_vreg, true /*is_temp*/); } } @@ -2495,7 +2480,9 @@ MachOper* Matcher::specialize_vector_operand(MachNode* m, uint opnd_idx) { } } } - return specialize_vector_operand_helper(m, opnd_idx, def->bottom_type()->is_vect()); + assert(def->bottom_type()->isa_vect(), "not a vector"); + uint ideal_vreg = def->bottom_type()->ideal_reg(); + return Matcher::pd_specialize_generic_vector_operand(m->_opnds[opnd_idx], ideal_vreg, false /*is_temp*/); } void Matcher::specialize_mach_node(MachNode* m) { diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp index 05e6e162a42..140ce9642d8 100644 --- a/src/hotspot/share/opto/matcher.hpp +++ b/src/hotspot/share/opto/matcher.hpp @@ -336,7 +336,6 @@ public: // Vector ideal reg static const uint vector_ideal_reg(int len); - static const uint vector_shift_count_ideal_reg(int len); // CPU supports misaligned vectors store/load. static const bool misaligned_vectors_ok(); @@ -520,10 +519,8 @@ public: void specialize_mach_node(MachNode* m); void specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx); MachOper* specialize_vector_operand(MachNode* m, uint opnd_idx); - MachOper* specialize_vector_operand_helper(MachNode* m, uint opnd_idx, const TypeVect* vt); - - static MachOper* specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp); + static MachOper* pd_specialize_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg, bool is_temp); static bool is_generic_reg2reg_move(MachNode* m); static bool is_generic_vector(MachOper* opnd); diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 7e0000f98dc..dc889ee6fc0 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -52,7 +52,6 @@ class CallNode; class CallRuntimeNode; class CallStaticJavaNode; class CastIINode; -class CastLLNode; class CatchNode; class CatchProjNode; class CheckCastPPNode; @@ -667,8 +666,7 @@ public: DEFINE_CLASS_ID(Phi, Type, 0) DEFINE_CLASS_ID(ConstraintCast, Type, 1) DEFINE_CLASS_ID(CastII, ConstraintCast, 0) - DEFINE_CLASS_ID(CastLL, ConstraintCast, 1) - DEFINE_CLASS_ID(CheckCastPP, ConstraintCast, 2) + DEFINE_CLASS_ID(CheckCastPP, ConstraintCast, 1) DEFINE_CLASS_ID(CMove, Type, 3) DEFINE_CLASS_ID(SafePointScalarObject, Type, 4) DEFINE_CLASS_ID(DecodeNarrowPtr, Type, 5) @@ -811,7 +809,6 @@ public: DEFINE_CLASS_QUERY(CatchProj) DEFINE_CLASS_QUERY(CheckCastPP) DEFINE_CLASS_QUERY(CastII) - DEFINE_CLASS_QUERY(CastLL) DEFINE_CLASS_QUERY(ConstraintCast) DEFINE_CLASS_QUERY(ClearArray) DEFINE_CLASS_QUERY(CMove) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 206af6f0e1e..16d3899ba80 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -774,12 +774,13 @@ bool ReductionNode::implemented(int opc, uint vlen, BasicType bt) { return false; } -MacroLogicVNode* MacroLogicVNode::make(PhaseGVN& gvn, Node* v1, Node* v2, Node* v3, +MacroLogicVNode* MacroLogicVNode::make(PhaseGVN& gvn, Node* in1, Node* in2, Node* in3, uint truth_table, const TypeVect* vt) { assert(truth_table <= 0xFF, "invalid"); - assert(v1->bottom_type() == vt, "mismatch"); - assert(v2->bottom_type() == vt, "mismatch"); - assert(v3->bottom_type() == vt, "mismatch"); + assert(in1->bottom_type()->is_vect()->length_in_bytes() == vt->length_in_bytes(), "mismatch"); + assert(in2->bottom_type()->is_vect()->length_in_bytes() == vt->length_in_bytes(), "mismatch"); + assert(in3->bottom_type()->is_vect()->length_in_bytes() == vt->length_in_bytes(), "mismatch"); Node* fn = gvn.intcon(truth_table); - return new MacroLogicVNode(v1, v2, v3, fn, vt); + return new MacroLogicVNode(in1, in2, in3, fn, vt); } + diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 9564f531c48..d6ceacf10b1 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -596,7 +596,6 @@ class LShiftCntVNode : public VectorNode { public: LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} virtual int Opcode() const; - virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } }; //------------------------------RShiftCntVNode--------------------------------- @@ -605,10 +604,8 @@ class RShiftCntVNode : public VectorNode { public: RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {} virtual int Opcode() const; - virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); } }; - //------------------------------AndVNode--------------------------------------- // Vector and integer class AndVNode : public VectorNode { diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 608517721a7..ca52fef5ff1 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -989,6 +989,154 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name, return (jclass) JNIHandles::make_local(env, k->java_mirror()); } +enum { + NESTMATE = java_lang_invoke_MemberName::MN_NESTMATE_CLASS, + HIDDEN_CLASS = java_lang_invoke_MemberName::MN_HIDDEN_CLASS, + STRONG_LOADER_LINK = java_lang_invoke_MemberName::MN_STRONG_LOADER_LINK, + ACCESS_VM_ANNOTATIONS = java_lang_invoke_MemberName::MN_ACCESS_VM_ANNOTATIONS +}; + +/* + * Define a class with the specified flags that indicates if it's a nestmate, + * hidden, or strongly referenced from class loader. + */ +static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *name, + const jbyte *buf, jsize len, jobject pd, + jboolean init, int flags, jobject classData, TRAPS) { + assert(THREAD->is_Java_thread(), "must be a JavaThread"); + JavaThread* jt = (JavaThread*) THREAD; + ResourceMark rm(THREAD); + + Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup)); + // Lookup class must be a non-null instance + if (lookup_k == NULL) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null"); + } + assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass"); + + Handle class_loader (THREAD, lookup_k->class_loader()); + + bool is_nestmate = (flags & NESTMATE) == NESTMATE; + bool is_hidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS; + bool is_strong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK; + bool vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS; + + InstanceKlass* host_class = NULL; + if (is_nestmate) { + host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL); + } + + log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s", + name, + is_nestmate ? "with dynamic nest-host " : "non-nestmate", + is_nestmate ? host_class->external_name() : "", + is_hidden ? "hidden" : "not hidden", + is_strong ? "strong" : "weak", + vm_annotations ? "with vm annotations" : "without vm annotation"); + + if (!is_hidden) { + // classData is only applicable for hidden classes + if (classData != NULL) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for hidden classes"); + } + if (is_nestmate) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "dynamic nestmate is only applicable for hidden classes"); + } + if (!is_strong) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "an ordinary class must be strongly referenced by its defining loader"); + } + if (vm_annotations) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for hidden classes"); + } + if (flags != STRONG_LOADER_LINK) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), + err_msg("invalid flag 0x%x", flags)); + } + } + + + // Since exceptions can be thrown, class initialization can take place + // if name is NULL no check for class name in .class stream has to be made. + TempNewSymbol class_name = NULL; + if (name != NULL) { + const int str_len = (int)strlen(name); + if (str_len > Symbol::max_length()) { + // It's impossible to create this class; the name cannot fit + // into the constant pool. + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_NoClassDefFoundError(), + "Class name exceeds maximum length of %d: %s", + Symbol::max_length(), + name); + return 0; + } + class_name = SymbolTable::new_symbol(name, str_len); + } + + Handle protection_domain (THREAD, JNIHandles::resolve(pd)); + const char* source = is_nestmate ? host_class->external_name() : "__JVM_LookupDefineClass__"; + ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify); + + Klass* defined_k; + InstanceKlass* ik = NULL; + if (!is_hidden) { + defined_k = SystemDictionary::resolve_from_stream(class_name, + class_loader, + protection_domain, + &st, + CHECK_NULL); + + if (log_is_enabled(Debug, class, resolve) && defined_k != NULL) { + trace_class_resolution(defined_k); + } + ik = InstanceKlass::cast(defined_k); + } else { // hidden + Handle classData_h(THREAD, JNIHandles::resolve(classData)); + ClassLoadInfo cl_info(protection_domain, + NULL, // unsafe_anonymous_host + NULL, // cp_patches + host_class, + classData_h, + is_hidden, + is_strong, + vm_annotations); + defined_k = SystemDictionary::parse_stream(class_name, + class_loader, + &st, + cl_info, + CHECK_NULL); + if (defined_k == NULL) { + THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a hidden class"); + } + + ik = InstanceKlass::cast(defined_k); + + // The hidden class loader data has been artificially been kept alive to + // this point. The mirror and any instances of this class have to keep + // it alive afterwards. + ik->class_loader_data()->dec_keep_alive(); + + if (is_nestmate && log_is_enabled(Debug, class, nestmates)) { + ModuleEntry* module = ik->module(); + const char * module_name = module->is_named() ? module->name()->as_C_string() : UNNAMED_MODULE; + log_debug(class, nestmates)("Dynamic nestmate: %s/%s, nest_host %s, %s", + module_name, + ik->external_name(), + host_class->external_name(), + ik->is_hidden() ? "is hidden" : "is not hidden"); + } + } + assert(Reflection::is_same_class_package(lookup_k, defined_k), + "lookup class and defined class are in different packages"); + + if (init) { + ik->initialize(CHECK_NULL); + } else { + ik->link_class(CHECK_NULL); + } + + return (jclass) JNIHandles::make_local(env, defined_k->java_mirror()); +} JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)) JVMWrapper("JVM_DefineClass"); @@ -996,6 +1144,29 @@ JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD); JVM_END +/* + * Define a class with the specified lookup class. + * lookup: Lookup class + * name: the name of the class + * buf: class bytes + * len: length of class bytes + * pd: protection domain + * init: initialize the class + * flags: properties of the class + * classData: private static pre-initialized field + */ +JVM_ENTRY(jclass, JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, const jbyte *buf, + jsize len, jobject pd, jboolean initialize, int flags, jobject classData)) + JVMWrapper("JVM_LookupDefineClass"); + + if (lookup == NULL) { + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null"); + } + + assert(buf != NULL, "buf must not be NULL"); + + return jvm_lookup_define_class(env, lookup, name, buf, len, pd, initialize, flags, classData, THREAD); +JVM_END JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)) JVMWrapper("JVM_DefineClassWithSource"); @@ -1058,9 +1229,9 @@ JVM_END // Module support ////////////////////////////////////////////////////////////////////////////// JVM_ENTRY(void, JVM_DefineModule(JNIEnv *env, jobject module, jboolean is_open, jstring version, - jstring location, const char* const* packages, jsize num_packages)) + jstring location, jobjectArray packages)) JVMWrapper("JVM_DefineModule"); - Modules::define_module(module, is_open, version, location, packages, num_packages, CHECK); + Modules::define_module(module, is_open, version, location, packages, CHECK); JVM_END JVM_ENTRY(void, JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module)) @@ -1068,17 +1239,17 @@ JVM_ENTRY(void, JVM_SetBootLoaderUnnamedModule(JNIEnv *env, jobject module)) Modules::set_bootloader_unnamed_module(module, CHECK); JVM_END -JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, const char* package, jobject to_module)) +JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module)) JVMWrapper("JVM_AddModuleExports"); Modules::add_module_exports_qualified(from_module, package, to_module, CHECK); JVM_END -JVM_ENTRY(void, JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, const char* package)) +JVM_ENTRY(void, JVM_AddModuleExportsToAllUnnamed(JNIEnv *env, jobject from_module, jstring package)) JVMWrapper("JVM_AddModuleExportsToAllUnnamed"); Modules::add_module_exports_to_all_unnamed(from_module, package, CHECK); JVM_END -JVM_ENTRY(void, JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, const char* package)) +JVM_ENTRY(void, JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package)) JVMWrapper("JVM_AddModuleExportsToAll"); Modules::add_module_exports(from_module, package, NULL, CHECK); JVM_END @@ -1158,6 +1329,15 @@ JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) return result; JVM_END +JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls)) + JVMWrapper("JVM_IsHiddenClass"); + oop mirror = JNIHandles::resolve_non_null(cls); + if (java_lang_Class::is_primitive(mirror)) { + return JNI_FALSE; + } + Klass* k = java_lang_Class::as_Klass(mirror); + return k->is_hidden(); +JVM_END JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls)) JVMWrapper("JVM_GetClassSigners"); @@ -1425,7 +1605,7 @@ JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)) = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)) )->compute_enclosing_class(&inner_is_member, CHECK_NULL); if (outer_klass == NULL) return NULL; // already a top-level class - if (!inner_is_member) return NULL; // an anonymous class (inside a method) + if (!inner_is_member) return NULL; // a hidden or unsafe anonymous class (inside a method) return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror()); } JVM_END @@ -1875,8 +2055,7 @@ JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current)) Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); assert(c->is_instance_klass(), "must be"); InstanceKlass* ck = InstanceKlass::cast(c); - // Don't post exceptions if validation fails - InstanceKlass* host = ck->nest_host(NULL, THREAD); + InstanceKlass* host = ck->nest_host(THREAD); return (jclass) (host == NULL ? NULL : JNIHandles::make_local(THREAD, host->java_mirror())); } @@ -1886,62 +2065,77 @@ JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current)) { // current is not a primitive or array class JVMWrapper("JVM_GetNestMembers"); + ResourceMark rm(THREAD); Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); assert(c->is_instance_klass(), "must be"); InstanceKlass* ck = InstanceKlass::cast(c); - // Get the nest host for this nest - throw ICCE if validation fails - Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError(); - InstanceKlass* host = ck->nest_host(icce, CHECK_NULL); + InstanceKlass* host = ck->nest_host(THREAD); + log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s", + ck->external_name(), host->external_name()); { JvmtiVMObjectAllocEventCollector oam; Array* members = host->nest_members(); int length = members == NULL ? 0 : members->length(); + + log_trace(class, nestmates)(" - host has %d listed nest members", length); + // nest host is first in the array so make it one bigger objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length + 1, CHECK_NULL); - objArrayHandle result (THREAD, r); + objArrayHandle result(THREAD, r); result->obj_at_put(0, host->java_mirror()); if (length != 0) { - int i; - for (i = 0; i < length; i++) { - int cp_index = members->at(i); - Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL); - if (k->is_instance_klass()) { - InstanceKlass* nest_host_k = - InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL); - if (nest_host_k == host) { - result->obj_at_put(i+1, k->java_mirror()); - } - else { - // k's nest host is legal but it isn't our host so - // throw ICCE - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - icce, - "Nest member %s in %s declares a different nest host of %s", - k->external_name(), - host->external_name(), - nest_host_k->external_name() - ); - return NULL; - } - } - else { - // we have a bad nest member entry - throw ICCE - ResourceMark rm(THREAD); - Exceptions::fthrow(THREAD_AND_LOCATION, - icce, - "Class %s can not be a nest member of %s", - k->external_name(), - host->external_name() - ); - return NULL; - } + int count = 0; + for (int i = 0; i < length; i++) { + int cp_index = members->at(i); + Klass* k = host->constants()->klass_at(cp_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) { + return NULL; // propagate VMEs + } + if (log_is_enabled(Trace, class, nestmates)) { + stringStream ss; + char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string(); + ss.print(" - resolution of nest member %s failed: ", target_member_class); + java_lang_Throwable::print(PENDING_EXCEPTION, &ss); + log_trace(class, nestmates)("%s", ss.as_string()); + } + CLEAR_PENDING_EXCEPTION; + continue; + } + if (k->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(k); + InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL); + if (nest_host_k == host) { + result->obj_at_put(count+1, k->java_mirror()); + count++; + log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name()); + } else { + log_trace(class, nestmates)(" - skipping member %s with different host %s", + ik->external_name(), nest_host_k->external_name()); + } + } else { + log_trace(class, nestmates)(" - skipping member %s that is not an instance class", + k->external_name()); + } + } + if (count < length) { + // we had invalid entries so we need to compact the array + log_trace(class, nestmates)(" - compacting array from length %d to %d", + length + 1, count + 1); + + objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(), + count + 1, CHECK_NULL); + objArrayHandle result2(THREAD, r2); + for (int i = 0; i < count + 1; i++) { + result2->obj_at_put(i, result->obj_at(i)); + } + return (jobjectArray)JNIHandles::make_local(THREAD, result2()); } } else { - assert(host == ck, "must be singleton nest"); + assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate"); } return (jobjectArray)JNIHandles::make_local(THREAD, result()); } diff --git a/src/hotspot/share/prims/jvmti.xml b/src/hotspot/share/prims/jvmti.xml index 5f90917857c..1131bcfa1b3 100644 --- a/src/hotspot/share/prims/jvmti.xml +++ b/src/hotspot/share/prims/jvmti.xml @@ -1,7 +1,7 @@ - - - - -JDI Type Signatures - - - - - -

JDI Type Signatures

- - - - - - -
JDI Type Signatures
Type Signature -Java Type -
Zboolean -
Bbyte -
Cchar -
Sshort -
Iint -
Jlong -
Ffloat -
Ddouble -
L fully-qualified-class -; -fully-qualified-class -
[ type - -type[] -
-( arg-types ) ret-type - -method type (including constructors) -
-

For example, the Java method: -

    long f (int n, String s, int[] arr);
-
has the following type signature: -
    (ILjava/lang/String;[I)J
-
- - diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java b/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java index 9819d133fb9..e236da0838a 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/event/ClassUnloadEvent.java @@ -42,12 +42,21 @@ import com.sun.jdi.VirtualMachine; public interface ClassUnloadEvent extends Event { /** - * Returns the name of the class that has been unloaded. + * Returns the {@linkplain com.sun.jdi.Type#name() name of the class} + * that has been unloaded. The returned string may not be a + * binary name. + * + * @see Class#getName() */ public String className(); /** - * Returns the JNI-style signature of the class that has been unloaded. + * Returns the {@linkplain com.sun.jdi.Type#signature() type signature of the class} + * that has been unloaded. The result is of the same + * form as the string returned by {@link Class#descriptorString()}. + * If this class can be described nominally, the returned string is a + * type descriptor conforming to JVMS {@jvms 4.3.2}; otherwise, the returned string + * is not a type descriptor. */ public String classSignature(); } diff --git a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/PatternReferenceTypeSpec.java b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/PatternReferenceTypeSpec.java index a74082dda7b..0e6f8ab82ff 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/PatternReferenceTypeSpec.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/PatternReferenceTypeSpec.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,6 +101,28 @@ class PatternReferenceTypeSpec implements ReferenceTypeSpec { } private void checkClassName(String className) throws ClassNotFoundException { + int slashIdx = className.indexOf("/"); + + // Slash is present in hidden class names only. It looks like p.Foo/0x1234. + if (slashIdx != -1) { + // A hidden class name is ending with a slash following by a suffix. + int lastSlashIdx = className.lastIndexOf("/"); + int lastDotIdx = className.lastIndexOf("."); + + // There must be just one slash with a following suffix but no dots. + if (slashIdx != lastSlashIdx || lastDotIdx > slashIdx || slashIdx + 1 == className.length()) { + throw new ClassNotFoundException(); + } + // Check prefix and suffix separately. + String[] parts = className.split("/"); + assert parts.length == 2; + className = parts[0]; + String hcSuffix = parts[1]; + if (!isUnqualifiedName(hcSuffix)) { + throw new ClassNotFoundException(); + } + } + // Do stricter checking of class name validity on deferred // because if the name is invalid, it will // never match a future loaded class, and we'll be silent @@ -118,6 +140,14 @@ class PatternReferenceTypeSpec implements ReferenceTypeSpec { } } + private boolean isUnqualifiedName(String s) { + if (s.length() == 0) { + return false; + } + // unqualified names should have no characters: ".;/[" + return !s.matches("[.;/\091]*"); // \091 is '[' + } + private boolean isJavaIdentifier(String s) { if (s.length() == 0) { return false; diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/EventSetImpl.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/EventSetImpl.java index 1d32bb42bb2..8c562a7c739 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/EventSetImpl.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/EventSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -425,8 +425,19 @@ public class EventSetImpl extends ArrayList implements EventSet { } public String className() { - return classSignature.substring(1, classSignature.length()-1) - .replace('/', '.'); + assert classSignature.startsWith("L") && classSignature.endsWith(";"); + + // trim leading "L" and trailing ";" + String name = classSignature.substring(1, classSignature.length() - 1); + int index = name.indexOf("."); // check if it is a hidden class + if (index < 0) { + return name.replace('/', '.'); + } else { + // map the type descriptor from: "L" + N + "." + + ";" + // to class name: N.replace('/', '.') + "/" + + return name.substring(0, index).replace('/', '.') + + "/" + name.substring(index + 1); + } } public String classSignature() { diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java index 1f6b5ef6afb..197c2d291d4 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/JNITypeParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,38 +43,45 @@ public class JNITypeParser { this.signature = signature; } - static String typeNameToSignature(String signature) { + static String typeNameToSignature(String typeName) { StringBuilder sb = new StringBuilder(); - int firstIndex = signature.indexOf('['); + int firstIndex = typeName.indexOf('['); int index = firstIndex; while (index != -1) { sb.append('['); - index = signature.indexOf('[', index + 1); + index = typeName.indexOf('[', index + 1); } if (firstIndex != -1) { - signature = signature.substring(0, firstIndex); + typeName = typeName.substring(0, firstIndex); } - if (signature.equals("boolean")) { + if (typeName.equals("boolean")) { sb.append('Z'); - } else if (signature.equals("byte")) { + } else if (typeName.equals("byte")) { sb.append('B'); - } else if (signature.equals("char")) { + } else if (typeName.equals("char")) { sb.append('C'); - } else if (signature.equals("short")) { + } else if (typeName.equals("short")) { sb.append('S'); - } else if (signature.equals("int")) { + } else if (typeName.equals("int")) { sb.append('I'); - } else if (signature.equals("long")) { + } else if (typeName.equals("long")) { sb.append('J'); - } else if (signature.equals("float")) { + } else if (typeName.equals("float")) { sb.append('F'); - } else if (signature.equals("double")) { + } else if (typeName.equals("double")) { sb.append('D'); } else { sb.append('L'); - sb.append(signature.replace('.', '/')); + index = typeName.indexOf("/"); // check if it's a hidden class + if (index < 0) { + sb.append(typeName.replace('.', '/')); + } else { + sb.append(typeName.substring(0, index).replace('.', '/')); + sb.append("."); + sb.append(typeName.substring(index + 1)); + } sb.append(';'); } @@ -203,7 +210,14 @@ public class JNITypeParser { currentIndex); String retVal = signature.substring(currentIndex, endClass); - retVal = retVal.replace('/','.'); + int index = retVal.indexOf("."); + if (index < 0) { + retVal = retVal.replace('/', '.'); + } else { + // hidden class + retVal = retVal.substring(0, index).replace('/', '.') + + "/" + retVal.substring(index + 1); + } currentIndex = endClass + 1; return retVal; diff --git a/src/jdk.jdi/share/native/libdt_shmem/shmemBase.h b/src/jdk.jdi/share/native/libdt_shmem/shmemBase.h index 104e263fb18..0187dd38b51 100644 --- a/src/jdk.jdi/share/native/libdt_shmem/shmemBase.h +++ b/src/jdk.jdi/share/native/libdt_shmem/shmemBase.h @@ -49,16 +49,11 @@ jint shmemBase_receivePacket(SharedMemoryConnection *, jdwpPacket *packet); jint shmemBase_name(SharedMemoryTransport *, char **name); jint shmemBase_getlasterror(char *msg, jint size); -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - #ifdef DEBUG #define SHMEM_ASSERT(expression) \ do { \ if (!(expression)) { \ - exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \ + exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ } \ } while (0) #else @@ -68,7 +63,7 @@ do { \ #define SHMEM_GUARANTEE(expression) \ do { \ if (!(expression)) { \ - exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \ + exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \ } \ } while (0) diff --git a/src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c b/src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c index 056dce648f7..a73808e4983 100644 --- a/src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c +++ b/src/jdk.jdi/windows/native/libdt_shmem/shmem_md.c @@ -30,11 +30,6 @@ #include "sysShmem.h" #include "shmemBase.h" /* for exitTransportWithError */ -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - /* * These functions are not completely universal. For now, they are used * exclusively for Jbug's shared memory transport mechanism. They have @@ -49,7 +44,7 @@ static HANDLE memHandle = NULL; if (!(expression)) { \ exitTransportWithError \ ("\"%s\", line %d: assertion failure\n", \ - THIS_FILE, __DATE__, __LINE__); \ + __FILE__, __DATE__, __LINE__); \ } \ } #else diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.h b/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.h index e25908c5592..4126b76f226 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/error_messages.h @@ -42,36 +42,31 @@ const char * jvmtiErrorText(jvmtiError); const char * eventText(int); const char * jdwpErrorText(jdwpError); -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - #define EXIT_ERROR(error, msg) \ { \ print_message(stderr, "JDWP exit error ", "\n", \ "%s(%d): %s [%s:%d]", \ jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \ - THIS_FILE, __LINE__); \ + __FILE__, __LINE__); \ debugInit_exit((jvmtiError)error, msg); \ } #define JDI_ASSERT(expression) \ do { \ if (gdata && gdata->assertOn && !(expression)) { \ - jdiAssertionFailed(THIS_FILE, __LINE__, #expression); \ + jdiAssertionFailed(__FILE__, __LINE__, #expression); \ } \ } while (0) #define JDI_ASSERT_MSG(expression, msg) \ do { \ if (gdata && gdata->assertOn && !(expression)) { \ - jdiAssertionFailed(THIS_FILE, __LINE__, msg); \ + jdiAssertionFailed(__FILE__, __LINE__, msg); \ } \ } while (0) #define JDI_ASSERT_FAILED(msg) \ - jdiAssertionFailed(THIS_FILE, __LINE__, msg) + jdiAssertionFailed(__FILE__, __LINE__, msg) void do_pause(void); diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/log_messages.h b/src/jdk.jdwp.agent/share/native/libjdwp/log_messages.h index 129fab66cd5..3f79bfcea1a 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/log_messages.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/log_messages.h @@ -33,15 +33,10 @@ void finish_logging(); #define LOG_NULL ((void)0) -/* Use THIS_FILE when it is available. */ -#ifndef THIS_FILE - #define THIS_FILE __FILE__ -#endif - #ifdef JDWP_LOGGING #define _LOG(flavor,args) \ - (log_message_begin(flavor,THIS_FILE,__LINE__), \ + (log_message_begin(flavor,__FILE__,__LINE__), \ log_message_end args) #define LOG_TEST(flag) (gdata->log_flags & (flag)) diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.c b/src/jdk.jdwp.agent/share/native/libjdwp/util.c index da439913071..429760218fa 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.c @@ -992,6 +992,10 @@ convertSignatureToClassname(char *convert) char c = *p; if (c == '/') { *(p-1) = '.'; + } else if (c == '.') { + // class signature of a hidden class is "Ljava/lang/Foo.1234;" + // map to "java.lang.Foo/1234" + *(p-1) = '/'; } else { *(p-1) = c; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java index 39b33d1d702..87fd16c8e68 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java @@ -504,7 +504,7 @@ public class RecordedObject { * conversion * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final short getShort(String name) { Object o = getValue(name, true); @@ -551,7 +551,7 @@ public class RecordedObject { * conversion * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final int getInt(String name) { Object o = getValue(name, true); @@ -604,7 +604,7 @@ public class RecordedObject { * conversion * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final float getFloat(String name) { Object o = getValue(name); @@ -654,7 +654,7 @@ public class RecordedObject { * conversion * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final long getLong(String name) { Object o = getValue(name, true); @@ -710,7 +710,7 @@ public class RecordedObject { * conversion * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final double getDouble(String name) { Object o = getValue(name); @@ -755,7 +755,7 @@ public class RecordedObject { * isn't of type {@code String} * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final String getString(String name) { return getTypedValue(name, "java.lang.String"); @@ -782,7 +782,7 @@ public class RecordedObject { * value can't be converted to a {@code Duration} object * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final Duration getDuration(String name) { Object o = getValue(name); @@ -813,7 +813,7 @@ public class RecordedObject { return getDuration(Short.toUnsignedLong((Byte) u), name); } } - throw newIllegalArgumentException(name, "java,time.Duration"); + throw newIllegalArgumentException(name, "java.time.Duration"); } private Duration getDuration(long timespan, String name) throws InternalError { @@ -861,7 +861,7 @@ public class RecordedObject { * value can't be converted to an {@code Instant} object * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final Instant getInstant(String name) { Object o = getValue(name, true); @@ -931,7 +931,7 @@ public class RecordedObject { * isn't of type {@code Class} * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final RecordedClass getClass(String name) { return getTypedValue(name, "java.lang.Class"); @@ -955,7 +955,7 @@ public class RecordedObject { * isn't of type {@code Thread} * * @see #hasField(String) - * @set #getValue(String) + * @see #getValue(String) */ public final RecordedThread getThread(String name) { return getTypedValue(name, "java.lang.Thread"); diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTreeImpl.java b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java similarity index 60% rename from src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTreeImpl.java rename to src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java index b2b5ce4cc55..5e1abebc5bb 100644 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTreeImpl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,30 +23,34 @@ * questions. */ -package jdk.nashorn.api.tree; +package jdk.jfr.events; -import jdk.nashorn.internal.ir.BreakNode; +import jdk.internal.misc.VM.BufferPool; -final class BreakTreeImpl extends StatementTreeImpl implements BreakTree { - private final String label; +import jdk.jfr.*; +import jdk.jfr.internal.Type; - BreakTreeImpl(final BreakNode node) { - super(node); - this.label = node.getLabelName(); +@Category({ "Java Application", "Statistics" }) +public abstract class AbstractBufferStatisticsEvent extends AbstractJDKEvent { + + AbstractBufferStatisticsEvent() { + BufferPool bufferPool = getBufferPool(); + + count = bufferPool.getCount(); + totalCapacity = bufferPool.getTotalCapacity(); + memoryUsed = bufferPool.getMemoryUsed(); } - @Override - public Tree.Kind getKind() { - return Tree.Kind.BREAK; - } + @Label("Count") + public long count; - @Override - public String getLabel() { - return label; - } + @Label("Total Capacity") + @DataAmount + public long totalCapacity; - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitBreak(this, data); - } + @Label("Memory Used") + @DataAmount + public long memoryUsed; + + abstract BufferPool getBufferPool(); } diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTreeImpl.java b/src/jdk.jfr/share/classes/jdk/jfr/events/DirectBufferStatisticsEvent.java similarity index 53% rename from src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTreeImpl.java rename to src/jdk.jfr/share/classes/jdk/jfr/events/DirectBufferStatisticsEvent.java index 820c1fb392b..400b6af8abd 100644 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTreeImpl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/DirectBufferStatisticsEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,37 +23,33 @@ * questions. */ -package jdk.nashorn.api.tree; +package jdk.jfr.events; -import jdk.nashorn.internal.ir.Expression; +import jdk.internal.misc.VM; +import jdk.internal.misc.VM.BufferPool; -final class ArrayAccessTreeImpl extends ExpressionTreeImpl implements ArrayAccessTree { +import jdk.jfr.*; +import jdk.jfr.internal.Type; - private final ExpressionTree base, index; +@Name(Type.EVENT_NAME_PREFIX + "DirectBufferStatistics") +@Label("Direct Buffer Statistics") +@Description("Statistics of direct buffer") +public final class DirectBufferStatisticsEvent extends AbstractBufferStatisticsEvent { - ArrayAccessTreeImpl(final Expression node, final ExpressionTree base, final ExpressionTree index) { - super(node); - this.base = base; - this.index = index; + private static final BufferPool DIRECT_BUFFER_POOL = VM.getBufferPools().stream() + .filter(p -> "direct".equals(p.getName())) + .findFirst().get(); + + public DirectBufferStatisticsEvent() { + this.maxCapacity = VM.maxDirectMemory(); } - @Override - public Tree.Kind getKind() { - return Tree.Kind.ARRAY_ACCESS; - } + @Label("Maximum Capacity") + @Description("Maximum direct buffer capacity the process can use") + @DataAmount + public long maxCapacity; - @Override - public ExpressionTree getExpression() { - return base; - } - - @Override - public ExpressionTree getIndex() { - return index; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitArrayAccess(this, data); + BufferPool getBufferPool() { + return DIRECT_BUFFER_POOL; } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index 0553759d2ca..c3f19358301 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -39,7 +39,7 @@ import jdk.jfr.internal.handlers.EventHandler; public final class JVM { private static final JVM jvm = new JVM(); - // JVM signals file changes by doing Object#notifu on this object + // JVM signals file changes by doing Object#notify on this object static final Object FILE_DELTA_CHANGE = new Object(); static final long RESERVED_CLASS_ID_LIMIT = 500; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/RequestEngine.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/RequestEngine.java index fa5374ba41f..6a28fb3cd1a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/RequestEngine.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RequestEngine.java @@ -281,9 +281,10 @@ public final class RequestEngine { static void setFlushInterval(long millis) { // Don't accept shorter interval than 1 s. - long interval = millis < 1000 ? 1000 : millis; + long interval = millis < 1000 ? 1000 : millis; + boolean needNotify = interval < flushInterval; flushInterval = interval; - if (interval < flushInterval) { + if (needNotify) { synchronized (JVM.FILE_DELTA_CHANGE) { JVM.FILE_DELTA_CHANGE.notifyAll(); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java index df85a4985bd..c7e0a8aeb41 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdConfigure.java @@ -79,10 +79,10 @@ final class DCmdConfigure extends AbstractDCmd { ", stackdepth=" + stackDepth + ", globalbuffercount=" + globalBufferCount + ", globalbuffersize=" + globalBufferSize + - ", thread_buffer_size" + threadBufferSize + - ", memorysize" + memorySize + + ", thread_buffer_size=" + threadBufferSize + + ", memorysize=" + memorySize + ", maxchunksize=" + maxChunkSize + - ", samplethreads" + sampleThreads); + ", samplethreads=" + sampleThreads); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java index 15088b986e5..24f926153c2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdDump.java @@ -79,7 +79,7 @@ final class DCmdDump extends AbstractDCmd { ", maxage=" + maxAge + ", maxsize=" + maxSize + ", begin=" + begin + - ", end" + end + + ", end=" + end + ", path-to-gc-roots=" + pathToGcRoots); } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java index d46e682b752..b858bfb6a8c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdStart.java @@ -91,9 +91,9 @@ final class DCmdStart extends AbstractDCmd { ", disk=" + disk+ ", filename=" + path + ", maxage=" + maxAge + - ", flush=" + flush + + ", flush-interval=" + flush + ", maxsize=" + maxSize + - ", dumponexit =" + dumpOnExit + + ", dumponexit=" + dumpOnExit + ", path-to-gc-roots=" + pathToGcRoots); } if (name != null) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java index f05e1d17c85..d0a36156076 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java @@ -31,6 +31,7 @@ import java.util.List; import jdk.jfr.Event; import jdk.jfr.events.ActiveRecordingEvent; import jdk.jfr.events.ActiveSettingEvent; +import jdk.jfr.events.DirectBufferStatisticsEvent; import jdk.jfr.events.ErrorThrownEvent; import jdk.jfr.events.ExceptionStatisticsEvent; import jdk.jfr.events.ExceptionThrownEvent; @@ -76,7 +77,8 @@ public final class JDKEvents { jdk.internal.event.TLSHandshakeEvent.class, jdk.internal.event.X509CertificateEvent.class, jdk.internal.event.X509ValidationEvent.class, - jdk.internal.event.ProcessStartEvent.class + jdk.internal.event.ProcessStartEvent.class, + DirectBufferStatisticsEvent.class }; // This is a list of the classes with instrumentation code that should be applied. @@ -93,6 +95,7 @@ public final class JDKEvents { private static final Class[] targetClasses = new Class[instrumentationClasses.length]; private static final JVM jvm = JVM.getJVM(); private static final Runnable emitExceptionStatistics = JDKEvents::emitExceptionStatistics; + private static final Runnable emitDirectBufferStatistics = JDKEvents::emitDirectBufferStatistics; private static boolean initializationTriggered; @SuppressWarnings("unchecked") @@ -107,6 +110,7 @@ public final class JDKEvents { } initializationTriggered = true; RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics); + RequestEngine.addTrustedJDKHook(DirectBufferStatisticsEvent.class, emitDirectBufferStatistics); } } catch (Exception e) { Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not initialize JDK events. " + e.getMessage()); @@ -163,5 +167,11 @@ public final class JDKEvents { public static void remove() { RequestEngine.removeHook(JDKEvents::emitExceptionStatistics); + RequestEngine.removeHook(emitDirectBufferStatistics); + } + + private static void emitDirectBufferStatistics() { + DirectBufferStatisticsEvent e = new DirectBufferStatisticsEvent(); + e.commit(); } } diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 236c7932e44..71bd0f6715d 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -768,6 +768,10 @@ true + + true + 5 s + diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index d9d3330e82c..9d1d3d71c50 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -768,6 +768,10 @@ true
+ + true + 5 s + diff --git a/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java b/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java index d40c53d3b0f..87eb64a266d 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -162,7 +162,6 @@ class JImageTask { private static final int EXIT_OK = 0; // No errors. private static final int EXIT_ERROR = 1; // Completed but reported errors. private static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches. - private static final int EXIT_SYSERR = 3; // System error or resource exhaustion. private static final int EXIT_ABNORMAL = 4; // Terminated abnormally. int run(String[] args) { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java index b5368f806a9..8989a28ca1a 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,15 +29,11 @@ import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.DataOutputStream; -import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.io.UncheckedIOException; -import java.io.Writer; import java.lang.module.ModuleDescriptor; import java.nio.charset.StandardCharsets; import java.nio.file.FileAlreadyExistsException; @@ -55,16 +51,19 @@ import java.util.Objects; import java.util.Optional; import java.util.Properties; import java.util.Set; -import static java.util.stream.Collectors.*; import jdk.tools.jlink.internal.BasicImageWriter; import jdk.tools.jlink.internal.ExecutableImage; import jdk.tools.jlink.internal.Platform; +import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolEntry; import jdk.tools.jlink.plugin.ResourcePoolEntry.Type; import jdk.tools.jlink.plugin.ResourcePoolModule; -import jdk.tools.jlink.plugin.PluginException; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.toSet; /** * @@ -441,13 +440,6 @@ public final class DefaultImageBuilder implements ImageBuilder { Files.copy(in, dstFile); } - private void writeSymEntry(Path dstFile, Path target) throws IOException { - Objects.requireNonNull(dstFile); - Objects.requireNonNull(target); - Files.createDirectories(Objects.requireNonNull(dstFile.getParent())); - Files.createLink(dstFile, target); - } - /* * Create a symbolic link to the given target if the target platform * supports symbolic link; otherwise, it will create a tiny file @@ -515,13 +507,6 @@ public final class DefaultImageBuilder implements ImageBuilder { } } - private static void createUtf8File(File file, String content) throws IOException { - try (OutputStream fout = new FileOutputStream(file); - Writer output = new OutputStreamWriter(fout, "UTF-8")) { - output.write(content); - } - } - @Override public ExecutableImage getExecutableImage() { return new DefaultExecutableImage(root, modules); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/BasicImageWriter.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/BasicImageWriter.java index 37f09160b87..ca576227692 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/BasicImageWriter.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/BasicImageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,6 @@ import jdk.internal.jimage.ImageStringsReader; public final class BasicImageWriter { public static final String MODULES_IMAGE_NAME = "modules"; - private final static int RETRY_LIMIT = 1000; - private ByteOrder byteOrder; private ImageStringsWriter strings; private int length; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java index 59205ac02ae..d24054bafc3 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/DirArchive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,8 +75,6 @@ public class DirArchive implements Archive { } } - private static final String MODULE_INFO = "module-info.class"; - private final Path dirPath; private final String moduleName; private final List open = new ArrayList<>(); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java index 09cb531970e..aa26f3dc5e4 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,17 +25,16 @@ package jdk.tools.jlink.internal; import java.io.DataOutputStream; - import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; + import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.Plugin.Category; +import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; /** diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java index 6a24564a04c..3222bc53aae 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,30 +28,19 @@ import java.io.DataOutputStream; import java.io.IOException; import java.lang.module.ModuleDescriptor; import java.nio.ByteOrder; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.internal.jimage.decompressor.Decompressor; import jdk.internal.module.ModuleInfo.Attributes; import jdk.internal.module.ModuleTarget; -import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.builder.ImageBuilder; +import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; -import jdk.tools.jlink.plugin.ResourcePoolModule; import jdk.tools.jlink.plugin.ResourcePoolEntry; -import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl; +import jdk.tools.jlink.plugin.ResourcePoolModule; /** * Plugins Stack. Plugins entry point to apply transformations onto resources diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java index e8cb2d7a52b..c9794042c31 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,7 @@ package jdk.tools.jlink.internal; import java.lang.module.Configuration; import java.lang.module.ModuleFinder; import java.nio.ByteOrder; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -37,10 +35,9 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import jdk.internal.module.ModulePath; +import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.builder.ImageBuilder; /** * API to call jlink. diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java index beba588a8c2..75f44ef6356 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,7 +92,6 @@ public class JlinkTask { // So, clear previous values, if any. task.options.modulePath.clear(); String[] dirs = arg.split(File.pathSeparator); - int i = 0; Arrays.stream(dirs) .map(Paths::get) .forEach(task.options.modulePath::add); @@ -734,36 +733,6 @@ public class JlinkTask { return sb.toString(); } - private static String getBomHeader() { - StringBuilder sb = new StringBuilder(); - sb.append("#").append(new Date()).append("\n"); - sb.append("#Please DO NOT Modify this file").append("\n"); - return sb.toString(); - } - - private String genBOMContent() throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append(getBomHeader()); - StringBuilder command = new StringBuilder(); - for (String c : optionsHelper.getInputCommand()) { - command.append(c).append(" "); - } - sb.append("command").append(" = ").append(command); - sb.append("\n"); - - return sb.toString(); - } - - private static String genBOMContent(JlinkConfiguration config, - PluginsConfiguration plugins) - throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append(getBomHeader()); - sb.append(config); - sb.append(plugins); - return sb.toString(); - } - private static class ImageHelper implements ImageProvider { final ByteOrder order; final Path packagedModulesPath; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java index 26914aca208..1d94075e95c 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,10 +55,12 @@ public class Main { } public static class JlinkToolProvider implements ToolProvider { + @Override public String name() { return "jlink"; } + @Override public int run(PrintWriter out, PrintWriter err, String... args) { return Main.run(out, err, args); } diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java index ff05abc89b0..3cabb0de98f 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModularJarArchive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ import jdk.tools.jlink.internal.Archive.Entry.EntryType; public class ModularJarArchive extends JarArchive { private static final String JAR_EXT = ".jar"; - private static final String MODULE_INFO = "module-info.class"; public ModularJarArchive(String mn, Path jmod, Runtime.Version version) { super(mn, jmod, version); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginRepository.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginRepository.java index b12bf00df96..568bde86a22 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginRepository.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginRepository.java @@ -114,7 +114,6 @@ public final class PluginRepository { ModuleLayer pluginsLayer) { Objects.requireNonNull(name); Objects.requireNonNull(pluginsLayer); - @SuppressWarnings("unchecked") T provider = null; List javaProviders = getPlugins(clazz, pluginsLayer); for(T factory : javaProviders) { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java index 66ab836aa99..e3f54788370 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,18 +30,13 @@ import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.ByteBuffer; -import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import jdk.tools.jlink.plugin.PluginException; + import jdk.tools.jlink.plugin.ResourcePool; -import jdk.tools.jlink.plugin.ResourcePoolEntry; import jdk.tools.jlink.plugin.ResourcePoolModule; final class ResourcePoolConfiguration { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java index 11305951926..72694f7184d 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,8 +65,6 @@ public final class TaskHelper { public static final String JLINK_BUNDLE = "jdk.tools.jlink.resources.jlink"; public static final String JIMAGE_BUNDLE = "jdk.tools.jimage.resources.jimage"; - private static final String DEFAULTS_PROPERTY = "jdk.jlink.defaults"; - public final class BadArgs extends Exception { static final long serialVersionUID = 8765093759964640721L; @@ -206,16 +204,17 @@ public final class TaskHelper { } private static class PluginOption extends Option { - public PluginOption(boolean hasArg, - Processing processing, boolean hidden, String name, String shortname) { + public PluginOption(boolean hasArg, Processing processing, + boolean hidden, String name, String shortname) { super(hasArg, processing, hidden, name, shortname, false); } - public PluginOption(boolean hasArg, - Processing processing, boolean hidden, String name) { + public PluginOption(boolean hasArg, Processing processing, + boolean hidden, String name) { super(hasArg, processing, hidden, name, "", false); } + @Override public String resourcePrefix() { return "plugin.opt."; } @@ -510,26 +509,10 @@ public final class TaskHelper { this.options = options; } - private boolean hasArgument(String optionName) throws BadArgs { - Option opt = getOption(optionName); - if (opt == null) { - opt = pluginOptions.getOption(optionName); - if (opt == null) { - throw new BadArgs("err.unknown.option", optionName). - showUsage(true); - } - } - return opt.hasArg; - } - public boolean shouldListPlugins() { return pluginOptions.listPlugins; } - private String getPluginsPath(String[] args) throws BadArgs { - return null; - } - /** * Handles all options. This method stops processing the argument * at the first non-option argument i.e. not starts with `-`, or diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java index fd0dc135263..c91e7f9052d 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,8 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; + import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Plugin.Category; public class Utils { diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java index afee31fb20b..26c70f3f617 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,6 @@ package jdk.tools.jlink.internal.plugins; -import java.io.*; -import java.nio.charset.*; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import jdk.tools.jlink.plugin.*; - /** * Plugin to add VM command-line options, by storing them in a resource * that's read by the VM at startup diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java index ed1e9dff4f1..fd9ad8176ce 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,14 @@ package jdk.tools.jlink.internal.plugins; -import java.io.*; -import java.nio.charset.*; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import jdk.tools.jlink.plugin.*; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.function.Function; + +import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; +import jdk.tools.jlink.plugin.ResourcePoolEntry; /** * Base plugin to add a resource diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java index b274226e98b..e38032a0745 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.util.Map; import java.util.Set; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; import jdk.tools.jlink.plugin.ResourcePoolEntry.Type; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java index 12457dcc9ae..9526f8144a5 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,11 +38,11 @@ import java.util.stream.Collectors; import jdk.tools.jlink.internal.Platform; import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; -import jdk.tools.jlink.plugin.ResourcePoolModule; import jdk.tools.jlink.plugin.ResourcePoolEntry; -import jdk.tools.jlink.plugin.PluginException; +import jdk.tools.jlink.plugin.ResourcePoolModule; /** * @@ -103,7 +103,6 @@ public final class ExcludeVMPlugin implements Plugin { */ private List getVMs(ResourcePoolModule javaBase, String[] jvmlibs) { List ret = javaBase.entries().filter((t) -> { - String path = t.path(); for (String jvmlib : jvmlibs) { if (t.path().endsWith("/" + jvmlib)) { return true; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java index 2d01497da9d..5b4f8d3a17d 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,13 +37,14 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.stream.Stream; -import jdk.internal.access.SharedSecrets; + import jdk.internal.access.JavaLangInvokeAccess; -import jdk.tools.jlink.plugin.ResourcePoolEntry; +import jdk.internal.access.SharedSecrets; +import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; -import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.ResourcePoolEntry; /** * Plugin to generate java.lang.invoke classes. @@ -289,7 +290,6 @@ public final class GenerateJLIClassesPlugin implements Plugin { return out.build(); } - @SuppressWarnings("unchecked") private void generateBMHClass(String types, ResourcePoolBuilder out) { try { // Generate class diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java index a4533159b2f..99635d988d4 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -283,7 +283,6 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor { } private boolean stripUnsupportedLocales(byte[] bytes, ClassReader cr) { - char[] buf = new char[cr.getMaxStringLength()]; boolean[] modified = new boolean[1]; IntStream.range(1, cr.getItemCount()) diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java index aa5660fb5fe..7cbc15818fb 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.ToIntFunction; -import jdk.tools.jlink.plugin.PluginException; + +import jdk.tools.jlink.internal.Utils; +import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; import jdk.tools.jlink.plugin.ResourcePoolEntry; -import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.internal.Utils; /** * diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java index 30fc0e96e3d..784851cac6a 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -442,6 +442,7 @@ public final class SystemModulesPlugin implements Plugin { int flags, String version) { return new ModuleVisitor(Opcodes.ASM7) { + @Override public void visitPackage(String pn) { packages.add(pn); } @@ -1708,6 +1709,7 @@ public final class SystemModulesPlugin implements Plugin { /** * Loads an Enum field. */ + @Override void visitElement(T t, MethodVisitor mv) { mv.visitFieldInsn(GETSTATIC, className, t.toString(), "L" + className + ";"); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java index 0221dcd9996..cafaafc5001 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,18 +25,25 @@ package jdk.tools.jlink.internal.plugins; -import java.io.*; -import java.nio.charset.*; -import java.util.*; -import java.util.function.*; -import java.util.stream.*; -import jdk.tools.jlink.plugin.*; -import jdk.internal.org.objectweb.asm.*; +import java.util.Map; -import static java.lang.System.out; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.tools.jlink.plugin.Plugin; +import jdk.tools.jlink.plugin.ResourcePool; +import jdk.tools.jlink.plugin.ResourcePoolBuilder; +import jdk.tools.jlink.plugin.ResourcePoolEntry; /** * Base plugin to update a static field in java.lang.VersionProps + * + * Fields to be updated must not be final such that values are not constant + * replaced at compile time and initialization code is generated. + * We assume that the initialization code only has ldcs, method calls and + * field instructions. */ abstract class VersionPropsPlugin implements Plugin { @@ -113,6 +120,7 @@ abstract class VersionPropsPlugin implements Plugin { cr.accept(new ClassVisitor(Opcodes.ASM7, cw) { + @Override public MethodVisitor visitMethod(int access, String name, String desc, @@ -127,7 +135,33 @@ abstract class VersionPropsPlugin implements Plugin { sig, xs)) { + private Object pendingLDC = null; + private void flushPendingLDC() { + if (pendingLDC != null) { + super.visitLdcInsn(pendingLDC); + pendingLDC = null; + } + } + + @Override + public void visitLdcInsn(Object value) { + flushPendingLDC(); + pendingLDC = value; + } + + @Override + public void visitMethodInsn(int opcode, + String owner, + String name, + String descriptor, + boolean isInterface) { + flushPendingLDC(); + super.visitMethodInsn(opcode, owner, name, + descriptor, isInterface); + } + + @Override public void visitFieldInsn(int opcode, String owner, String name, @@ -136,11 +170,21 @@ abstract class VersionPropsPlugin implements Plugin { if (opcode == Opcodes.PUTSTATIC && name.equals(field)) { - // Discard the original value - super.visitInsn(Opcodes.POP); - // Load the value that we want + // assert that there is a pending ldc + // for the old value + if (pendingLDC == null) { + throw new AssertionError("No load " + + "instruction found for field " + field + + " in static initializer of " + + VERSION_PROPS_CLASS); + } + // forget about it + pendingLDC = null; + // and add an ldc for the new value super.visitLdcInsn(value); redefined = true; + } else { + flushPendingLDC(); } super.visitFieldInsn(opcode, owner, name, desc); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java index 9e1b1df4fff..0c46c030b04 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,10 +24,10 @@ */ package jdk.tools.jlink.plugin; -import java.util.Collections; import java.util.EnumSet; import java.util.Map; import java.util.Set; + import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; /** diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java index 285da60a55e..1ef9bb04ab0 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package jdk.tools.jlink.plugin; import java.nio.ByteOrder; -import java.util.Map; import java.util.Optional; import java.util.function.Function; import java.util.stream.Stream; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolBuilder.java index 6374ba71bb4..513ab3da2fe 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolBuilder.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,6 @@ */ package jdk.tools.jlink.plugin; -import java.nio.ByteOrder; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Stream; - /** * Resource pool builder to build a resource pool by incrementally * adding a set of resources one at a time. diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolModule.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolModule.java index a129210f9d2..2c754aff957 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolModule.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.lang.module.ModuleDescriptor; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; -import jdk.internal.module.ModuleTarget; /** * Link-time representation of a module. diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java index 48f144d62a8..0410d024bc6 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java @@ -35,53 +35,30 @@ import java.io.PrintWriter; import java.io.UncheckedIOException; import java.lang.module.Configuration; import java.lang.module.FindException; -import java.lang.module.ModuleReader; -import java.lang.module.ModuleReference; -import java.lang.module.ModuleFinder; import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor.Exports; import java.lang.module.ModuleDescriptor.Opens; import java.lang.module.ModuleDescriptor.Provides; -import java.lang.module.ModuleDescriptor.Requires; import java.lang.module.ModuleDescriptor.Version; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReader; +import java.lang.module.ModuleReference; import java.lang.module.ResolutionException; import java.lang.module.ResolvedModule; import java.net.URI; -import java.nio.file.FileSystems; -import java.nio.file.FileVisitOption; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.InvalidPathException; -import java.nio.file.Path; -import java.nio.file.PathMatcher; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.MissingResourceException; -import java.util.Optional; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; -import java.util.stream.Collectors; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; diff --git a/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java b/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java index 1d069607d05..9018187ea38 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jmod/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,10 +50,12 @@ public class Main { } public static class JmodToolProvider implements ToolProvider { + @Override public String name() { return "jmod"; } + @Override public int run(PrintWriter out, PrintWriter err, String... args) { return Main.run(out, err, args); } diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index f9f756069ff..181a9e6d20a 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -25,7 +25,6 @@ package jdk.internal.jshell.tool; - import jdk.jshell.SourceCodeAnalysis.Documentation; import jdk.jshell.SourceCodeAnalysis.QualifiedNames; import jdk.jshell.SourceCodeAnalysis.Suggestion; @@ -146,13 +145,34 @@ class ConsoleIOContext extends IOContext { completionState.actionCount++; return super.readBinding(keys, local); } + @Override + protected boolean insertCloseParen() { + Object oldIndent = getVariable(INDENTATION); + try { + setVariable(INDENTATION, 0); + return super.insertCloseParen(); + } finally { + setVariable(INDENTATION, oldIndent); + } + } + @Override + protected boolean insertCloseSquare() { + Object oldIndent = getVariable(INDENTATION); + try { + setVariable(INDENTATION, 0); + return super.insertCloseSquare(); + } finally { + setVariable(INDENTATION, oldIndent); + } + } }; reader.setOpt(Option.DISABLE_EVENT_EXPANSION); reader.setParser((line, cursor, context) -> { if (!allowIncompleteInputs && !repl.isComplete(line)) { - throw new EOFError(cursor, cursor, line); + int pendingBraces = countPendingOpenBraces(line); + throw new EOFError(cursor, cursor, line, null, pendingBraces, null); } return new ArgumentLine(line, cursor); }); @@ -283,6 +303,11 @@ class ConsoleIOContext extends IOContext { return count; } + @Override + public void setIndent(int indent) { + in.variable(LineReader.INDENTATION, indent); + } + private static final String FIXES_SHORTCUT = "\033\133\132"; //Shift-TAB private static final String LINE_SEPARATOR = System.getProperty("line.separator"); @@ -937,6 +962,25 @@ class ConsoleIOContext extends IOContext { return inputBytes[inputBytesPointer++]; } + private int countPendingOpenBraces(String code) { + int pendingBraces = 0; + com.sun.tools.javac.util.Context ctx = + new com.sun.tools.javac.util.Context(); + com.sun.tools.javac.parser.ScannerFactory scannerFactory = + com.sun.tools.javac.parser.ScannerFactory.instance(ctx); + com.sun.tools.javac.parser.Scanner scanner = + scannerFactory.newScanner(code, false); + + while (true) { + switch (scanner.token().kind) { + case LBRACE: pendingBraces++; break; + case RBRACE: pendingBraces--; break; + case EOF: return pendingBraces; + } + scanner.nextToken(); + } + } + /** * A possible action which the user can choose to perform. */ diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java index a4a4e616b61..09862cf4df5 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java @@ -56,6 +56,8 @@ abstract class IOContext implements AutoCloseable { public abstract int readUserInput() throws IOException; + public void setIndent(int indent) {} + class InputInterruptedException extends Exception { private static final long serialVersionUID = 1L; } diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index d8be3651b87..0adad76bddd 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -230,15 +230,17 @@ public class JShellTool implements MessageHandler { static final String STARTUP_KEY = "STARTUP"; static final String EDITOR_KEY = "EDITOR"; - static final String FEEDBACK_KEY = "FEEDBACK"; static final String MODE_KEY = "MODE"; + static final String FEEDBACK_KEY = "FEEDBACK"; static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE"; + public static final String INDENT_KEY = "INDENT"; static final Pattern BUILTIN_FILE_PATTERN = Pattern.compile("\\w+"); static final String BUILTIN_FILE_PATH_FORMAT = "/jdk/jshell/tool/resources/%s.jsh"; static final String INT_PREFIX = "int $$exit$$ = "; static final int OUTPUT_WIDTH = 72; + static final int DEFAULT_INDENT = 4; // match anything followed by whitespace private static final Pattern OPTION_PRE_PATTERN = @@ -910,6 +912,12 @@ public class JShellTool implements MessageHandler { } } + private String indent() { + String indentValue = prefs.get(INDENT_KEY); + if (indentValue == null) indentValue = Integer.toString(DEFAULT_INDENT); + return indentValue; + } + /** * The entry point into the JShell tool. * @@ -968,6 +976,14 @@ public class JShellTool implements MessageHandler { Runtime.getRuntime().addShutdownHook(shutdownHook); // execute from user input try (IOContext in = new ConsoleIOContext(this, cmdin, console)) { + int indent; + try { + String indentValue = indent(); + indent = Integer.parseInt(indentValue); + } catch (NumberFormatException ex) { + indent = DEFAULT_INDENT; + } + in.setIndent(indent); while (regenerateOnDeath) { if (!live) { resetState(); @@ -1830,7 +1846,8 @@ public class JShellTool implements MessageHandler { SET_MODE_OPTIONS_COMPLETION_PROVIDER)), "prompt", feedback.modeCompletions(), "editor", fileCompletions(Files::isExecutable), - "start", FILE_COMPLETION_PROVIDER), + "start", FILE_COMPLETION_PROVIDER, + "indent", EMPTY_COMPLETION_PROVIDER), STARTSWITH_MATCHER))); registerCommand(new Command("/?", "help.quest", @@ -1941,7 +1958,7 @@ public class JShellTool implements MessageHandler { // --- Command implementations --- private static final String[] SET_SUBCOMMANDS = new String[]{ - "format", "truncation", "feedback", "mode", "prompt", "editor", "start"}; + "format", "truncation", "feedback", "mode", "prompt", "editor", "start", "indent"}; final boolean cmdSet(String arg) { String cmd = "/set"; @@ -1958,6 +1975,7 @@ public class JShellTool implements MessageHandler { case "_blank": { // show top-level settings new SetEditor().set(); + showIndent(); showSetStart(); setFeedback(this, at); // no args so shows feedback setting hardmsg("jshell.msg.set.show.mode.settings"); @@ -1978,6 +1996,23 @@ public class JShellTool implements MessageHandler { return new SetEditor(at).set(); case "start": return setStart(at); + case "indent": + String value = at.next(); + if (value != null) { + try { + int indent = Integer.parseInt(value); + String indentValue = Integer.toString(indent); + prefs.put(INDENT_KEY, indentValue); + input.setIndent(indent); + fluffmsg("jshell.msg.set.indent.set", indentValue); + } catch (NumberFormatException ex) { + errormsg("jshell.err.invalid.indent", value); + return false; + } + } else { + showIndent(); + } + return true; default: errormsg("jshell.err.arg", cmd, at.val()); return false; @@ -2252,6 +2287,10 @@ public class JShellTool implements MessageHandler { hard(sb.toString()); } + private void showIndent() { + hard("/set indent %s", indent()); + } + boolean cmdDebug(String arg) { if (arg.isEmpty()) { debug = !debug; diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties index 2a6f924f7a7..dd21e320317 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties @@ -54,6 +54,8 @@ jshell.err.command.ambiguous = Command: ''{0}'' is ambiguous: {1} jshell.msg.set.restore = Setting new options and restoring state. jshell.msg.set.editor.set = Editor set to: {0} jshell.msg.set.editor.retain = Editor setting retained: {0} +jshell.msg.set.indent.set = Indent level set to: {0} +jshell.err.invalid.indent = Invalid indent level: {0} jshell.err.no.builtin.editor = Built-in editor not available. jshell.err.cant.launch.editor = Cannot launch built-in editor -- unexpected exception: {0} jshell.msg.try.set.editor = See ''/help /set editor'' to use external editor. @@ -516,6 +518,8 @@ the command prompt, the feedback mode to use, or the format of output.\n\ Set the maximum length of a displayed value\n\n\ /set format "" ...\n\t\ Configure a feedback mode by setting the format of a field when the selector matches\n\n\ +/set indent \n\t\ + Set the number of spaces that should be used to automatically indent snippets\n\n\ /set\n\t\ Show editor, start, and feedback settings as /set commands.\n\t\ To show the settings of any of the above, omit the set value\n\n\ @@ -1136,6 +1140,18 @@ More than one may be specified, for example:\n\ \n\t\ /set start -retain DEFAULT PRINTING +help.set.indent.summary =\ +Specify the number of spaces that should be used to indent snippets + +help.set.indent =\ +Specify the number of spaces that should be used to indent snippets:\n\ +\n\t\ +/set indent \n\ +\n\ +Show the indent setting:\n\ +\n\t\ +/set indent\n\ + startup.feedback = \ /set mode verbose -command \n\ \n\ diff --git a/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java b/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java index 6db2e23f1ae..5044135dc0c 100644 --- a/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java +++ b/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java @@ -72,6 +72,12 @@ class OperatingSystemImpl extends BaseOperatingSystemImpl if (containerMetrics != null) { long memSwapLimit = containerMetrics.getMemoryAndSwapLimit(); long memLimit = containerMetrics.getMemoryLimit(); + long deltaLimit = memSwapLimit - memLimit; + // Return 0 when memSwapLimit == memLimit, which means no swap space is allowed. + // And the same for memSwapLimit < memLimit. + if (deltaLimit <= 0) { + return 0; + } if (memSwapLimit >= 0 && memLimit >= 0) { for (int attempt = 0; attempt < MAX_ATTEMPTS_NUMBER; attempt++) { long memSwapUsage = containerMetrics.getMemoryAndSwapUsage(); @@ -80,8 +86,12 @@ class OperatingSystemImpl extends BaseOperatingSystemImpl // We read "memory usage" and "memory and swap usage" not atomically, // and it's possible to get the negative value when subtracting these two. // If this happens just retry the loop for a few iterations. - if ((memSwapUsage - memUsage) >= 0) { - return memSwapLimit - memLimit - (memSwapUsage - memUsage); + long deltaUsage = memSwapUsage - memUsage; + if (deltaUsage >= 0) { + long freeSwap = deltaLimit - deltaUsage; + if (freeSwap >= 0) { + return freeSwap; + } } } } diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java deleted file mode 100644 index 3a67c554a5b..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintStream; -import java.io.Writer; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import jdk.internal.org.jline.reader.Candidate; -import jdk.internal.org.jline.reader.CompletingParsedLine; -import jdk.internal.org.jline.reader.EOFError; -import jdk.internal.org.jline.reader.History; -import jdk.internal.org.jline.reader.LineReader; -import jdk.internal.org.jline.reader.LineReader.Option; -import jdk.internal.org.jline.reader.LineReaderBuilder; -import jdk.internal.org.jline.reader.Parser; -import jdk.internal.org.jline.reader.Parser.ParseContext; -import jdk.internal.org.jline.reader.Widget; -import jdk.internal.org.jline.reader.impl.LineReaderImpl; -import jdk.internal.org.jline.reader.impl.completer.ArgumentCompleter.ArgumentLine; -import jdk.internal.org.jline.terminal.Attributes.LocalFlag; -import jdk.internal.org.jline.terminal.Terminal; - -class Console implements AutoCloseable { - private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB - private final LineReader in; - private final File historyFile; - - Console(final InputStream cmdin, final PrintStream cmdout, final File historyFile, - final NashornCompleter completer, final Function docHelper) throws IOException { - this.historyFile = historyFile; - - Parser parser = (line, cursor, context) -> { - if (context == ParseContext.COMPLETE) { - List candidates = new ArrayList<>(); - int anchor = completer.complete(line, cursor, candidates); - anchor = Math.min(anchor, line.length()); - return new CompletionLine(line.substring(anchor), cursor, candidates); - } else if (!completer.isComplete(line)) { - throw new EOFError(cursor, cursor, line); - } - return new ArgumentLine(line, cursor); - }; - in = LineReaderBuilder.builder() - .option(Option.DISABLE_EVENT_EXPANSION, true) - .completer((in, line, candidates) -> candidates.addAll(((CompletionLine) line).candidates)) - .parser(parser) - .build(); - if (historyFile.exists()) { - StringBuilder line = new StringBuilder(); - for (String h : Files.readAllLines(historyFile.toPath())) { - if (line.length() > 0) { - line.append("\n"); - } - line.append(h); - try { - parser.parse(line.toString(), line.length()); - in.getHistory().add(line.toString()); - line.delete(0, line.length()); - } catch (EOFError e) { - //continue; - } - } - if (line.length() > 0) { - in.getHistory().add(line.toString()); - } - } - Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory)); - bind(DOCUMENTATION_SHORTCUT, ()->showDocumentation(docHelper)); - } - - String readLine(final String prompt, final String continuationPrompt) throws IOException { - in.setVariable(LineReader.SECONDARY_PROMPT_PATTERN, continuationPrompt); - return in.readLine(prompt); - } - - String readUserLine(final String prompt) throws IOException { - Parser prevParser = in.getParser(); - - try { - ((LineReaderImpl) in).setParser((line, cursor, context) -> new ArgumentLine(line, cursor)); - return in.readLine(prompt); - } finally { - ((LineReaderImpl) in).setParser(prevParser); - } - } - - @Override - public void close() { - saveHistory(); - } - - private void saveHistory() { - try (Writer out = Files.newBufferedWriter(historyFile.toPath())) { - String lineSeparator = System.getProperty("line.separator"); - - out.write(StreamSupport.stream(getHistory().spliterator(), false) - .map(e -> e.line()) - .collect(Collectors.joining(lineSeparator))); - } catch (final IOException exp) {} - } - - History getHistory() { - return in.getHistory(); - } - - boolean terminalEditorRunning() { - Terminal terminal = in.getTerminal(); - return !terminal.getAttributes().getLocalFlag(LocalFlag.ICANON); - } - - void suspend() { - } - - void resume() { - } - - private void bind(String shortcut, Widget action) { - in.getKeyMaps().get(LineReader.MAIN).bind(action, shortcut); - } - - private boolean showDocumentation(final Function docHelper) { - final String buffer = in.getBuffer().toString(); - final int cursor = in.getBuffer().cursor(); - final String doc = docHelper.apply(buffer.substring(0, cursor)); - if (doc != null) { - in.getTerminal().writer().println(); - in.printAbove(doc); - return true; - } else { - return false; - } - } - - private static final class CompletionLine extends ArgumentLine implements CompletingParsedLine { - public final List candidates; - - public CompletionLine(String word, int cursor, List candidates) { - super(word, cursor); - this.candidates = candidates; - } - - public CharSequence escape(CharSequence candidate, boolean complete) { - return candidate; - } - - public int rawWordCursor() { - return word().length(); - } - - public int rawWordLength() { - return word().length(); - } - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java deleted file mode 100644 index 18640879cbf..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/EditObject.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Consumer; -import java.util.ServiceLoader; -import jdk.nashorn.api.scripting.AbstractJSObject; -import jdk.internal.editor.spi.BuildInEditorProvider; -import jdk.nashorn.internal.runtime.JSType; -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - -/* - * "edit" top level script function which shows an external Window - * for editing and evaluating scripts from it. - */ -final class EditObject extends AbstractJSObject { - private static final Set props; - static { - final HashSet s = new HashSet<>(); - s.add("editor"); - props = Collections.unmodifiableSet(s); - } - - private final Console console; - private final Consumer errorHandler; - private final Consumer evaluator; - private String editor; - - EditObject(final Console console, final Consumer errorHandler, - final Consumer evaluator) { - this.console = console; - this.errorHandler = errorHandler; - this.evaluator = evaluator; - } - - @Override - public Object getDefaultValue(final Class hint) { - if (hint == String.class) { - return toString(); - } - return UNDEFINED; - } - - @Override - public String toString() { - return "function edit() { [native code] }"; - } - - @Override - public Set keySet() { - return props; - } - - @Override - public Object getMember(final String name) { - if (name.equals("editor")) { - return editor; - } - return UNDEFINED; - } - - @Override - public void setMember(final String name, final Object value) { - if (name.equals("editor")) { - this.editor = value != null && value != UNDEFINED? JSType.toString(value) : ""; - } - } - - // called whenever user 'saves' script in editor - class SaveHandler implements Consumer { - private String lastStr; // last seen code - - SaveHandler(final String str) { - this.lastStr = str; - } - - @Override - public void accept(final String str) { - // ignore repeated save of the same code! - if (! str.equals(lastStr)) { - this.lastStr = str; - // evaluate the new code - evaluator.accept(str); - } - } - } - - @Override - public Object call(final Object thiz, final Object... args) { - final String initText = args.length > 0? JSType.toString(args[0]) : ""; - final SaveHandler saveHandler = new SaveHandler(initText); - if (editor != null && !editor.isEmpty()) { - ExternalEditor.edit(editor, errorHandler, initText, saveHandler, console); - } else { - try { - ServiceLoader sl - = ServiceLoader.load(BuildInEditorProvider.class); - //find the highest ranking provider - BuildInEditorProvider provider = null; - for (BuildInEditorProvider p : sl){ - if (provider == null || p.rank() > provider.rank()) { - provider = p; - } - } - if (provider != null) { - provider.edit(null, initText, saveHandler, errorHandler); - } else { - errorHandler.accept(Main.getMessage("jjs.err.no.builtin.editor")); - } - } catch (RuntimeException ex) { - errorHandler.accept(Main.getMessage("jjs.err.cant.launch.editor")); - } - } - return UNDEFINED; - } - - @Override - public boolean isFunction() { - return true; - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/ExternalEditor.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/ExternalEditor.java deleted file mode 100644 index c046a350aa9..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/ExternalEditor.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.ClosedWatchServiceException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; -import java.util.List; -import java.util.function.Consumer; -import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE; -import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE; -import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY; - -final class ExternalEditor { - private final Consumer errorHandler; - private final Consumer saveHandler; - private final Console input; - - private WatchService watcher; - private Thread watchedThread; - private Path dir; - private Path tmpfile; - - ExternalEditor(final Consumer errorHandler, final Consumer saveHandler, final Console input) { - this.errorHandler = errorHandler; - this.saveHandler = saveHandler; - this.input = input; - } - - private void edit(final String cmd, final String initialText) { - try { - setupWatch(initialText); - launch(cmd); - } catch (IOException ex) { - errorHandler.accept(ex.getMessage()); - } - } - - /** - * Creates a WatchService and registers the given directory - */ - private void setupWatch(final String initialText) throws IOException { - this.watcher = FileSystems.getDefault().newWatchService(); - this.dir = Files.createTempDirectory("REPL"); - this.tmpfile = Files.createTempFile(dir, null, ".js"); - Files.write(tmpfile, initialText.getBytes(Charset.forName("UTF-8"))); - dir.register(watcher, - ENTRY_CREATE, - ENTRY_DELETE, - ENTRY_MODIFY); - watchedThread = new Thread(() -> { - for (;;) { - WatchKey key; - try { - key = watcher.take(); - } catch (final ClosedWatchServiceException ex) { - break; - } catch (final InterruptedException ex) { - continue; // tolerate an intrupt - } - - if (!key.pollEvents().isEmpty()) { - if (!input.terminalEditorRunning()) { - saveFile(); - } - } - - boolean valid = key.reset(); - if (!valid) { - errorHandler.accept("Invalid key"); - break; - } - } - }); - watchedThread.start(); - } - - private void launch(final String cmd) throws IOException { - ProcessBuilder pb = new ProcessBuilder(cmd, tmpfile.toString()); - pb = pb.inheritIO(); - - try { - input.suspend(); - Process process = pb.start(); - process.waitFor(); - } catch (final IOException ex) { - errorHandler.accept("process IO failure: " + ex.getMessage()); - } catch (final InterruptedException ex) { - errorHandler.accept("process interrupt: " + ex.getMessage()); - } finally { - try { - watcher.close(); - watchedThread.join(); //so that saveFile() is finished. - saveFile(); - } catch (InterruptedException ex) { - errorHandler.accept("process interrupt: " + ex.getMessage()); - } finally { - input.resume(); - } - } - } - - private void saveFile() { - List lines; - try { - lines = Files.readAllLines(tmpfile); - } catch (final IOException ex) { - errorHandler.accept("Failure read edit file: " + ex.getMessage()); - return ; - } - StringBuilder sb = new StringBuilder(); - for (String ln : lines) { - sb.append(ln); - sb.append('\n'); - } - saveHandler.accept(sb.toString()); - } - - static void edit(final String cmd, final Consumer errorHandler, final String initialText, - final Consumer saveHandler, final Console input) { - ExternalEditor ed = new ExternalEditor(errorHandler, saveHandler, input); - ed.edit(cmd, initialText); - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java deleted file mode 100644 index 149e5883b8e..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/HistoryObject.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UncheckedIOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -import jdk.internal.org.jline.reader.History; -import jdk.nashorn.api.scripting.AbstractJSObject; -import jdk.nashorn.api.scripting.JSObject; -import jdk.nashorn.internal.runtime.JSType; -import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - -/* - * A script friendly object that exposes history of commands to scripts. - */ -final class HistoryObject extends AbstractJSObject { - private static final Set props; - static { - final HashSet s = new HashSet<>(); - s.add("clear"); - s.add("forEach"); - s.add("load"); - s.add("print"); - s.add("save"); - s.add("size"); - s.add("toString"); - props = Collections.unmodifiableSet(s); - } - - private final History hist; - private final PrintWriter err; - private final Consumer evaluator; - - HistoryObject(final History hist, final PrintWriter err, - final Consumer evaluator) { - this.hist = hist; - this.err = err; - this.evaluator = evaluator; - } - - @Override - public boolean isFunction() { - return true; - } - - @Override - public Object call(final Object thiz, final Object... args) { - if (args.length > 0) { - int index = JSType.toInteger(args[0]); - if (index < 0) { - index += (hist.size() - 1); - } else { - index--; - } - - if (index >= 0 && index < (hist.size() - 1)) { - final CharSequence src = hist.get(index); - var it = hist.iterator(); - while (it.hasNext()) { - it.next(); - } - it.remove(); - hist.add(src.toString()); - err.println(src); - evaluator.accept(src.toString()); - } else { - var it = hist.iterator(); - while (it.hasNext()) { - it.next(); - } - it.remove(); - err.println("no history entry @ " + (index + 1)); - } - } - return UNDEFINED; - } - - @Override - public Object getMember(final String name) { - switch (name) { - case "clear": - return (Runnable) () -> { - try { - hist.purge(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - }; - case "forEach": - return (Function)this::iterate; - case "load": - return (Consumer)this::load; - case "print": - return (Runnable)this::print; - case "save": - return (Consumer)this::save; - case "size": - return hist.size(); - case "toString": - return (Supplier)this::toString; - } - return UNDEFINED; - } - - @Override - public Object getDefaultValue(final Class hint) { - if (hint == String.class) { - return toString(); - } - return UNDEFINED; - } - - @Override - public String toString() { - final StringBuilder buf = new StringBuilder(); - for (History.Entry e : hist) { - buf.append(e.line()).append('\n'); - } - return buf.toString(); - } - - @Override - public Set keySet() { - return props; - } - - private void save(final Object obj) { - final File file = getFile(obj); - try (final PrintWriter pw = new PrintWriter(file)) { - for (History.Entry e : hist) { - pw.println(e.line()); - } - } catch (final IOException exp) { - throw new RuntimeException(exp); - } - } - - private void load(final Object obj) { - final File file = getFile(obj); - String item = null; - try (final BufferedReader r = new BufferedReader(new FileReader(file))) { - while ((item = r.readLine()) != null) { - hist.add(item); - } - } catch (final IOException exp) { - throw new RuntimeException(exp); - } - } - - private void print() { - for (History.Entry e : hist) { - System.out.printf("%3d %s\n", e.index() + 1, e.line()); - } - } - - private Object iterate(final JSObject func) { - for (History.Entry e : hist) { - if (JSType.toBoolean(func.call(this, e.line().toString()))) { - break; // return true from callback to skip iteration - } - } - return UNDEFINED; - } - - private static File getFile(final Object obj) { - File file = null; - if (obj instanceof String) { - file = new File((String)obj); - } else if (obj instanceof File) { - file = (File)obj; - } else { - throw typeError("not.a.file", JSType.toString(obj)); - } - - return file; - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JavacPackagesHelper.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JavacPackagesHelper.java deleted file mode 100644 index d5a22dffeff..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JavacPackagesHelper.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.IOException; -import java.io.File; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.tools.JavaCompiler; -import javax.tools.JavaFileManager.Location; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; -import javax.tools.ToolProvider; -import jdk.nashorn.internal.runtime.Context; - -/** - * A javac package helper that uses javac to complete package names. - */ -final class JavacPackagesHelper extends PackagesHelper { - // JavaCompiler may be null on certain platforms (eg. JRE) - private static final JavaCompiler compiler; - static { - // Use javac only if security manager is not around! - compiler = System.getSecurityManager() == null? ToolProvider.getSystemJavaCompiler() : null; - } - - /** - * Is this class available? - * - * @return true if javac is available - */ - static boolean isAvailable() { - return compiler != null; - } - - private final boolean modulePathSet; - private final StandardJavaFileManager fm; - private final Set fileKinds; - - /** - * Construct a new JavacPackagesHelper. - * - * @param context the current Nashorn Context - */ - JavacPackagesHelper(final Context context) throws IOException { - super(context); - final String modulePath = context.getEnv()._module_path; - this.modulePathSet = modulePath != null && !modulePath.isEmpty(); - if (isAvailable()) { - final String classPath = context.getEnv()._classpath; - fm = compiler.getStandardFileManager(null, null, null); - fileKinds = EnumSet.of(JavaFileObject.Kind.CLASS); - - if (this.modulePathSet) { - fm.setLocation(StandardLocation.MODULE_PATH, getFiles(modulePath)); - } - - if (classPath != null && !classPath.isEmpty()) { - fm.setLocation(StandardLocation.CLASS_PATH, getFiles(classPath)); - } else { - // no classpath set. Make sure that it is empty and not any default like "." - fm.setLocation(StandardLocation.CLASS_PATH, Collections.emptyList()); - } - } else { - // javac is not available - caller should have checked! - throw new IllegalStateException("JavacPackagesHelper is not available!"); - } - } - - - @Override - void close() throws IOException { - if (fm != null) { - fm.close(); - } - } - - @Override - Set listPackage(final String pkg) throws IOException { - final Set props = new HashSet<>(); - listPackage(StandardLocation.PLATFORM_CLASS_PATH, pkg, props); - if (this.modulePathSet) { - for (Set locs : fm.listLocationsForModules(StandardLocation.MODULE_PATH)) { - for (Location loc : locs) { - listPackage(loc, pkg, props); - } - } - } - listPackage(StandardLocation.CLASS_PATH, pkg, props); - return props; - } - - private void listPackage(final Location loc, final String pkg, final Set props) - throws IOException { - for (JavaFileObject file : fm.list(loc, pkg, fileKinds, true)) { - final String binaryName = fm.inferBinaryName(loc, file); - // does not start with the given package prefix - if (!binaryName.startsWith(pkg + ".")) { - continue; - } - - final int nextDot = binaryName.indexOf('.', pkg.length() + 1); - final int start = pkg.length() + 1; - - if (nextDot != -1) { - // subpackage - eg. "regex" for "java.util" - final String pkgName = binaryName.substring(start, nextDot); - if (isPackageAccessible(binaryName.substring(0, nextDot))) { - props.add(binaryName.substring(start, nextDot)); - } - } else { - // class - filter out nested, inner, anonymous, local classes. - // Dynalink supported public nested classes as properties of - // StaticClass object anyway. We don't want to expose those - // "$" internal names as properties of package object. - - final String clsName = binaryName.substring(start); - if (clsName.indexOf('$') == -1 && isClassAccessible(binaryName)) { - props.add(clsName); - } - } - } - } - - // return list of File objects for the given class path - private static List getFiles(final String classPath) { - return Stream.of(classPath.split(File.pathSeparator)) - .map(File::new) - .collect(Collectors.toList()); - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JrtPackagesHelper.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JrtPackagesHelper.java deleted file mode 100644 index 4a7e3fd2e57..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/JrtPackagesHelper.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.IOException; -import java.net.URI; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.util.HashSet; -import java.util.Set; -import jdk.nashorn.internal.runtime.Context; - -/** - * A java packages helper that uses jrt file system. - */ -final class JrtPackagesHelper extends PackagesHelper { - private final FileSystem jrtfs; - - /** - * Construct a new JrtPackagesHelper. - * - * @param context the current Nashorn Context - */ - JrtPackagesHelper(final Context context) throws IOException { - super(context); - jrtfs = FileSystems.getFileSystem(URI.create("jrt:/")); - } - - @Override - void close() throws IOException { - } - - @Override - Set listPackage(final String pkg) throws IOException { - final Set props = new HashSet<>(); - // look for the /packages/ directory - Path pkgDir = jrtfs.getPath("/packages/" + pkg); - if (Files.exists(pkgDir)) { - String pkgSlashName = pkg.replace('.', '/'); - try (DirectoryStream ds = Files.newDirectoryStream(pkgDir)) { - // it has module links under which this package occurs - for (Path mod : ds) { - // get the package directory under /modules - Path pkgUnderMod = jrtfs.getPath(mod.toString() + "/" + pkgSlashName); - try (DirectoryStream ds2 = Files.newDirectoryStream(pkgUnderMod)) { - for (Path p : ds2) { - String str = p.getFileName().toString(); - // get rid of ".class", if any - if (str.endsWith(".class")) { - final String clsName = str.substring(0, str.length() - ".class".length()); - if (clsName.indexOf('$') == -1 && isClassAccessible(pkg + "." + clsName)) { - props.add(str); - } - } else if (isPackageAccessible(pkg + "." + str)) { - props.add(str); - } - } - } - } - } - } - return props; - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java deleted file mode 100644 index 36abf212dc2..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Main.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; - -import java.io.File; -import java.io.InputStream; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.URI; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.function.Consumer; - -import jdk.internal.org.jline.reader.UserInterruptException; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.objects.NativeJava; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.NativeJavaPackage; -import jdk.nashorn.internal.runtime.Property; -import jdk.nashorn.internal.runtime.ScriptEnvironment; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptingFunctions; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.tools.Shell; - -/** - * Interactive command line Shell for Nashorn. - */ -@Deprecated(since="11", forRemoval=true) -public final class Main extends Shell { - private Main() {} - - private static final String DOC_PROPERTY_NAME = "__doc__"; - - static final boolean DEBUG = Boolean.getBoolean("nashorn.jjs.debug"); - - // file where history is persisted. - private static final File HIST_FILE = new File(new File(System.getProperty("user.home")), ".jjs.history"); - - /** - * Main entry point with the default input, output and error streams. - * - * @param args The command line arguments - */ - public static void main(final String[] args) { - try { - final int exitCode = main(System.in, System.out, System.err, args); - if (exitCode != SUCCESS) { - System.exit(exitCode); - } - } catch (final IOException e) { - System.err.println(e); //bootstrapping, Context.err may not exist - System.exit(IO_ERROR); - } - } - - /** - * Starting point for executing a {@code Shell}. Starts a shell with the - * given arguments and streams and lets it run until exit. - * - * @param in input stream for Shell - * @param out output stream for Shell - * @param err error stream for Shell - * @param args arguments to Shell - * - * @return exit code - * - * @throws IOException if there's a problem setting up the streams - */ - public static int main(final InputStream in, final OutputStream out, final OutputStream err, final String[] args) throws IOException { - return new Main().run(in, out, err, args); - } - - - /** - * read-eval-print loop for Nashorn shell. - * - * @param context the nashorn context - * @param global global scope object to use - * @return return code - */ - protected int readEvalPrint(final Context context, final Global global) { - final ScriptEnvironment env = context.getEnv(); - final String prompt = bundle.getString("shell.prompt"); - final String prompt2 = bundle.getString("shell.prompt2"); - final PrintWriter err = context.getErr(); - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - final PropertiesHelper propsHelper = new PropertiesHelper(context); - - if (globalChanged) { - Context.setGlobal(global); - } - - // jjs.js is read and evaluated. The result of the evaluation is an "exports" object. This is done - // to avoid polluting javascript global scope. These are internal funtions are retrieved from the - // 'exports' object and used from here. - final ScriptObject jjsObj = (ScriptObject)context.eval(global, readJJSScript(), global, ""); - - final boolean isHeadless = (boolean) ScriptRuntime.apply((ScriptFunction) jjsObj.get("isHeadless"), null); - final ScriptFunction fileChooserFunc = isHeadless? null : (ScriptFunction) jjsObj.get("chooseFile"); - - final NashornCompleter completer = new NashornCompleter(context, global, this, propsHelper, fileChooserFunc); - final ScriptFunction browseFunc = isHeadless? null : (ScriptFunction) jjsObj.get("browse"); - - final ScriptFunction javadoc = (ScriptFunction) jjsObj.get("javadoc"); - - try (final Console in = new Console(System.in, System.out, HIST_FILE, completer, - str -> { - try { - final Object res = context.eval(global, str, global, ""); - if (res != null && res != UNDEFINED) { - // Special case Java types: show the javadoc for the class. - if (!isHeadless && NativeJava.isType(UNDEFINED, res)) { - final String typeName = NativeJava.typeName(UNDEFINED, res).toString(); - final String url = typeName.replace('.', '/').replace('$', '.') + ".html"; - openBrowserForJavadoc(browseFunc, url); - } else if (!isHeadless && res instanceof NativeJavaPackage) { - final String pkgName = ((NativeJavaPackage)res).getName(); - final String url = pkgName.replace('.', '/') + "/package-summary.html"; - openBrowserForJavadoc(browseFunc, url); - } else if (NativeJava.isJavaMethod(UNDEFINED, res)) { - ScriptRuntime.apply(javadoc, UNDEFINED, res); - return ""; // javadoc function already prints javadoc - } else if (res instanceof ScriptObject) { - final ScriptObject sobj = (ScriptObject)res; - if (sobj.has(DOC_PROPERTY_NAME)) { - return toString(sobj.get(DOC_PROPERTY_NAME), global); - } else if (sobj instanceof ScriptFunction) { - return ((ScriptFunction)sobj).getDocumentation(); - } - } - - // FIXME: better than toString for other cases? - return toString(res, global); - } - } catch (Exception ignored) { - } - return null; - })) { - - global.addShellBuiltins(); - - // redefine readLine to use jline Console's readLine! - ScriptingFunctions.setReadLineHelper(str-> { - try { - return in.readUserLine(str); - } catch (final IOException ioExp) { - throw new UncheckedIOException(ioExp); - } - }); - - if (System.getSecurityManager() == null) { - final Consumer evaluator = str -> { - // could be called from different thread (GUI), we need to handle Context set/reset - final Global _oldGlobal = Context.getGlobal(); - final boolean _globalChanged = (_oldGlobal != global); - if (_globalChanged) { - Context.setGlobal(global); - } - try { - evalImpl(context, global, str, err, env._dump_on_error); - } finally { - if (_globalChanged) { - Context.setGlobal(_oldGlobal); - } - } - }; - - // expose history object for reflecting on command line history - global.addOwnProperty("history", Property.NOT_ENUMERABLE, new HistoryObject(in.getHistory(), err, evaluator)); - - // 'edit' command - global.addOwnProperty("edit", Property.NOT_ENUMERABLE, new EditObject(in, err::println, evaluator)); - } - - while (true) { - String source; - try { - source = in.readLine(prompt, prompt2); - } catch (final IOException ioe) { - err.println(ioe.toString()); - if (env._dump_on_error) { - ioe.printStackTrace(err); - } - return IO_ERROR; - } catch (final UserInterruptException ex) { - break; - } - - if (source == null) { - break; - } - - if (source.isEmpty()) { - continue; - } - - try { - final Object res = context.eval(global, source, global, ""); - if (res != UNDEFINED) { - err.println(toString(res, global)); - } - } catch (final Exception exp) { - // Is this a ECMAScript SyntaxError at last column (of the single line)? - // If so, it is because parser expected more input but got EOF. Try to - // to more lines from the user (multiline edit support). - - if (completer.isSyntaxErrorAt(exp, 1, source.length())) { - final String fullSrc = completer.readMoreLines(source, exp, in, prompt2, err); - - // check if we succeeded in getting complete code. - if (fullSrc != null && !fullSrc.isEmpty()) { - evalImpl(context, global, fullSrc, err, env._dump_on_error); - } // else ignore, error reported already by 'completer.readMoreLines' - } else { - - // can't read more lines to have parseable/complete code. - err.println(exp); - if (env._dump_on_error) { - exp.printStackTrace(err); - } - } - } - } - } catch (final Exception e) { - err.println(e); - if (env._dump_on_error) { - e.printStackTrace(err); - } - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - try { - propsHelper.close(); - } catch (final Exception exp) { - if (DEBUG) { - exp.printStackTrace(); - } - } - } - - return SUCCESS; - } - - static String getMessage(final String id) { - return bundle.getString(id); - } - - private void evalImpl(final Context context, final Global global, final String source, - final PrintWriter err, final boolean doe) { - try { - final Object res = context.eval(global, source, global, ""); - if (res != UNDEFINED) { - err.println(toString(res, global)); - } - } catch (final Exception e) { - err.println(e); - if (doe) { - e.printStackTrace(err); - } - } - } - - private static String JAVADOC_BASE = "https://docs.oracle.com/javase/%d/docs/api/"; - private static void openBrowserForJavadoc(ScriptFunction browse, String relativeUrl) { - try { - final URI uri = new URI(String.format(JAVADOC_BASE, Runtime.version().feature()) + relativeUrl); - ScriptRuntime.apply(browse, null, uri); - } catch (Exception ignored) { - } - } - - private static String readJJSScript() { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public String run() { - try { - final InputStream resStream = Main.class.getResourceAsStream("resources/jjs.js"); - if (resStream == null) { - throw new RuntimeException("resources/jjs.js is missing!"); - } - return new String(Source.readFully(resStream)); - } catch (final IOException exp) { - throw new RuntimeException(exp); - } - } - }); - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java deleted file mode 100644 index 7f0db66332e..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/NashornCompleter.java +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.File; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.regex.Pattern; - -import jdk.internal.org.jline.reader.Candidate; -import jdk.internal.org.jline.reader.Completer; -import jdk.internal.org.jline.reader.LineReader; -import jdk.internal.org.jline.reader.ParsedLine; -import jdk.internal.org.jline.reader.UserInterruptException; -import jdk.nashorn.api.tree.AssignmentTree; -import jdk.nashorn.api.tree.BinaryTree; -import jdk.nashorn.api.tree.CompilationUnitTree; -import jdk.nashorn.api.tree.CompoundAssignmentTree; -import jdk.nashorn.api.tree.ConditionalExpressionTree; -import jdk.nashorn.api.tree.ExpressionTree; -import jdk.nashorn.api.tree.ExpressionStatementTree; -import jdk.nashorn.api.tree.FunctionCallTree; -import jdk.nashorn.api.tree.IdentifierTree; -import jdk.nashorn.api.tree.InstanceOfTree; -import jdk.nashorn.api.tree.MemberSelectTree; -import jdk.nashorn.api.tree.NewTree; -import jdk.nashorn.api.tree.SimpleTreeVisitorES5_1; -import jdk.nashorn.api.tree.Tree; -import jdk.nashorn.api.tree.UnaryTree; -import jdk.nashorn.api.tree.Parser; -import jdk.nashorn.api.scripting.NashornException; -import jdk.nashorn.tools.PartialParser; -import jdk.nashorn.internal.objects.NativeSyntaxError; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.ECMAException; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ScriptEnvironment; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptRuntime; - -/** - * A simple source completer for nashorn. Handles code completion for - * expressions as well as handles incomplete single line code. - */ -final class NashornCompleter { - private final Context context; - private final Global global; - private final ScriptEnvironment env; - private final PartialParser partialParser; - private final PropertiesHelper propsHelper; - private final ScriptFunction fileChooserFunc; - private final Parser parser; - private static final boolean BACKSLASH_FILE_SEPARATOR = File.separatorChar == '\\'; - - NashornCompleter(final Context context, final Global global, - final PartialParser partialParser, final PropertiesHelper propsHelper, - final ScriptFunction fileChooserFunc) { - this.context = context; - this.global = global; - this.env = context.getEnv(); - this.partialParser = partialParser; - this.propsHelper = propsHelper; - this.fileChooserFunc = fileChooserFunc; - this.parser = createParser(env); - } - - - /** - * Is this a ECMAScript SyntaxError thrown for parse issue at the given line and column? - * - * @param exp Throwable to check - * @param line line number to check - * @param column column number to check - * - * @return true if the given Throwable is a ECMAScript SyntaxError at given line, column - */ - boolean isSyntaxErrorAt(final Throwable exp, final int line, final int column) { - if (exp instanceof ECMAException) { - final ECMAException eexp = (ECMAException)exp; - if (eexp.getThrown() instanceof NativeSyntaxError) { - return isParseErrorAt(eexp.getCause(), line, column); - } - } - - return false; - } - - /** - * Is this a parse error at the given line and column? - * - * @param exp Throwable to check - * @param line line number to check - * @param column column number to check - * - * @return true if the given Throwable is a parser error at given line, column - */ - boolean isParseErrorAt(final Throwable exp, final int line, final int column) { - if (exp instanceof NashornException) { - final NashornException nexp = (NashornException)exp; - return nexp.getLineNumber() == line && nexp.getColumnNumber() == column; - } - return false; - } - - - /** - * Read more lines of code if we got SyntaxError at EOF and we can it fine by - * by reading more lines of code from the user. This is used for multiline editing. - * - * @param firstLine First line of code from the user - * @param exp Exception thrown by evaluting first line code - * @param in Console to get read more lines from the user - * @param prompt Prompt to be printed to read more lines from the user - * @param err PrintWriter to print any errors in the proecess of reading - * - * @return Complete code read from the user including the first line. This is null - * if any error or the user discarded multiline editing by Ctrl-C. - */ - String readMoreLines(final String firstLine, final Exception exp, final Console in, - final String prompt, final PrintWriter err) { - int line = 1; - final StringBuilder buf = new StringBuilder(firstLine); - while (true) { - buf.append('\n'); - String curLine = null; - try { - curLine = in.readLine(prompt, prompt); - buf.append(curLine); - line++; - } catch (final Throwable th) { - if (th instanceof UserInterruptException) { - // Ctrl-C from user - discard the whole thing silently! - return null; - } else { - // print anything else -- but still discard the code - err.println(th); - if (env._dump_on_error) { - th.printStackTrace(err); - } - return null; - } - } - - final String allLines = buf.toString(); - try { - parser.parse("", allLines, null); - } catch (final Exception pexp) { - // Do we have a parse error at the end of current line? - // If so, read more lines from the console. - if (isParseErrorAt(pexp, line, curLine.length())) { - continue; - } else { - // print anything else and bail out! - err.println(pexp); - if (env._dump_on_error) { - pexp.printStackTrace(err); - } - return null; - } - } - - // We have complete parseable code! - return buf.toString(); - } - } - - public boolean isComplete(String input) { - try { - parser.parse("", input, null); - } catch (final Exception pexp) { - // Do we have a parse error at the end of current line? - // If so, read more lines from the console. - int line = input.split("\n").length; - int lastLineLen = input.length() - (input.lastIndexOf("\n") + 1); - - if (isParseErrorAt(pexp, line, lastLineLen)) { - return false; - } - } - return true; - } - - // Pattern to match a unfinished member selection expression. object part and "." - // but property name missing pattern. - private static final Pattern SELECT_PROP_MISSING = Pattern.compile(".*\\.\\s*"); - - // Pattern to match load call - private static final Pattern LOAD_CALL = Pattern.compile("\\s*load\\s*\\(\\s*"); - - public int complete(String test, int cursor, List candidates) { - // check that cursor is at the end of test string. Do not complete in the middle! - if (cursor != test.length()) { - return cursor; - } - - // get the start of the last expression embedded in the given code - // using the partial parsing support - so that we can complete expressions - // inside statements, function call argument lists, array index etc. - final int exprStart = partialParser.getLastExpressionStart(context, test); - if (exprStart == -1) { - return cursor; - } - - - // extract the last expression string - final String exprStr = test.substring(exprStart); - - // do we have an incomplete member selection expression that misses property name? - final boolean endsWithDot = SELECT_PROP_MISSING.matcher(exprStr).matches(); - - // If this is an incomplete member selection, then it is not legal code. - // Make it legal by adding a random property name "x" to it. - final String completeExpr = endsWithDot? exprStr + "x" : exprStr; - - final ExpressionTree topExpr = getTopLevelExpression(parser, completeExpr); - if (topExpr == null) { - // Special case for load call that looks like "load(" with optional whitespaces. - // If we have a fileChooserFunc then call it, so that the user can select a file. - if (fileChooserFunc != null && LOAD_CALL.matcher(test).matches()) { - String name = readFileName(context.getErr()); - if (name != null) { - // handle '\' file separator - if (BACKSLASH_FILE_SEPARATOR) { - name = name.replace("\\", "\\\\"); - } - candidates.add(createCandidate("\"" + name + "\")")); - return cursor + name.length() + 3; - } - } - - // did not parse to be a top level expression, no suggestions! - return cursor; - } - - - // Find 'right most' expression of the top level expression - final Tree rightMostExpr = getRightMostExpression(topExpr); - if (rightMostExpr instanceof MemberSelectTree) { - return completeMemberSelect(exprStr, cursor, candidates, (MemberSelectTree)rightMostExpr, endsWithDot); - } else if (rightMostExpr instanceof IdentifierTree) { - return completeIdentifier(exprStr, cursor, candidates, (IdentifierTree)rightMostExpr); - } else { - // expression that we cannot handle for completion - return cursor; - } - } - - // Internals only below this point - - // read file name from the user using by showing a swing file chooser diablog - private String readFileName(final PrintWriter err) { - try { - final Object res = ScriptRuntime.apply(fileChooserFunc, null); - return res instanceof String? (String)res : null; - } catch (final Exception e) { - err.println(e); - if (Main.DEBUG) { - e.printStackTrace(); - } - } - return null; - } - - // fill properties of the incomplete member expression - private int completeMemberSelect(final String exprStr, final int cursor, final List candidates, - final MemberSelectTree select, final boolean endsWithDot) { - final ExpressionTree objExpr = select.getExpression(); - final String objExprCode = exprStr.substring((int)objExpr.getStartPosition(), (int)objExpr.getEndPosition()); - - // try to evaluate the object expression part as a script - Object obj = null; - try { - obj = context.eval(global, objExprCode, global, ""); - } catch (Exception exp) { - // throw away the exception - this is during tab-completion - if (Main.DEBUG) { - exp.printStackTrace(); - } - } - - if (obj != null && obj != ScriptRuntime.UNDEFINED) { - if (endsWithDot) { - // no user specified "prefix". List all properties of the object - propsHelper.getProperties(obj).stream().map(this::createCandidate).forEach(candidates::add); - return cursor; - } else { - // list of properties matching the user specified prefix - final String prefix = select.getIdentifier(); - propsHelper.getProperties(obj, prefix).stream().map(this::createCandidate).forEach(candidates::add); - return cursor - prefix.length(); - } - } - - return cursor; - } - - // fill properties for the given (partial) identifer - private int completeIdentifier(final String test, final int cursor, final List candidates, - final IdentifierTree ident) { - final String name = ident.getName(); - propsHelper.getProperties(global, name).stream().map(this::createCandidate).forEach(candidates::add); - return cursor - name.length(); - } - - // returns ExpressionTree if the given code parses to a top level expression. - // Or else returns null. - private ExpressionTree getTopLevelExpression(final Parser parser, final String code) { - try { - final CompilationUnitTree cut = parser.parse("", code, null); - final List stats = cut.getSourceElements(); - if (stats.size() == 1) { - final Tree stat = stats.get(0); - if (stat instanceof ExpressionStatementTree) { - return ((ExpressionStatementTree)stat).getExpression(); - } - } - } catch (final NashornException ignored) { - // ignore any parser error. This is for completion anyway! - // And user will get that error later when the expression is evaluated. - } - - return null; - } - - // get the right most expreesion of the given expression - private Tree getRightMostExpression(final ExpressionTree expr) { - return expr.accept(new SimpleTreeVisitorES5_1() { - @Override - public Tree visitAssignment(final AssignmentTree at, final Void v) { - return getRightMostExpression(at.getExpression()); - } - - @Override - public Tree visitCompoundAssignment(final CompoundAssignmentTree cat, final Void v) { - return getRightMostExpression(cat.getExpression()); - } - - @Override - public Tree visitConditionalExpression(final ConditionalExpressionTree cet, final Void v) { - return getRightMostExpression(cet.getFalseExpression()); - } - - @Override - public Tree visitBinary(final BinaryTree bt, final Void v) { - return getRightMostExpression(bt.getRightOperand()); - } - - @Override - public Tree visitIdentifier(final IdentifierTree ident, final Void v) { - return ident; - } - - - @Override - public Tree visitInstanceOf(final InstanceOfTree it, final Void v) { - return it.getType(); - } - - - @Override - public Tree visitMemberSelect(final MemberSelectTree select, final Void v) { - return select; - } - - @Override - public Tree visitNew(final NewTree nt, final Void v) { - final ExpressionTree call = nt.getConstructorExpression(); - if (call instanceof FunctionCallTree) { - final ExpressionTree func = ((FunctionCallTree)call).getFunctionSelect(); - // Is this "new Foo" or "new obj.Foo" with no user arguments? - // If so, we may be able to do completion of constructor name. - if (func.getEndPosition() == nt.getEndPosition()) { - return func; - } - } - return null; - } - - @Override - public Tree visitUnary(final UnaryTree ut, final Void v) { - return getRightMostExpression(ut.getExpression()); - } - }, null); - } - - // create a Parser instance that uses compatible command line options of the - // current ScriptEnvironment being used for REPL. - private static Parser createParser(final ScriptEnvironment env) { - final List args = new ArrayList<>(); - if (env._const_as_var) { - args.add("--const-as-var"); - } - - if (env._no_syntax_extensions) { - args.add("-nse"); - } - - if (env._scripting) { - args.add("-scripting"); - } - - if (env._strict) { - args.add("-strict"); - } - - if (env._es6) { - args.add("--language=es6"); - } - - return Parser.create(args.toArray(new String[0])); - } - - private Candidate createCandidate(String value) { - return new Candidate(value, value, null, null, null, null, false); - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PackagesHelper.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PackagesHelper.java deleted file mode 100644 index f14e97db147..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PackagesHelper.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.lang.reflect.Modifier; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import jdk.nashorn.internal.runtime.Context; - -/** - * Abstract helper class to compute properties of a Java package object. Properties of - * package object are (simple) top level class names in that java package and - * immediate subpackages of that package. - */ -abstract class PackagesHelper { - private final Context context; - - /** - * Construct a new PackagesHelper. - * - * @param context the current Nashorn Context - */ - PackagesHelper(final Context context) throws IOException { - this.context = context; - } - - static PackagesHelper create(final Context context) throws IOException { - return isJavacHelperAvailable()? new JavacPackagesHelper(context) : new JrtPackagesHelper(context); - } - - // LRU cache for java package properties lists - private final LinkedHashMap> propsCache = - new LinkedHashMap>(32, 0.75f, true) { - private static final int CACHE_SIZE = 100; - private static final long serialVersionUID = 1; - - @Override - protected boolean removeEldestEntry(final Map.Entry> eldest) { - return size() > CACHE_SIZE; - } - }; - - /** - * Return the list of properties of the given Java package or package prefix - * - * @param pkg Java package name or package prefix name - * @return the list of properties of the given Java package or package prefix - */ - final List getPackageProperties(final String pkg) { - // check the cache first - if (propsCache.containsKey(pkg)) { - return propsCache.get(pkg); - } - - try { - // make sorted list of properties - final List props = new ArrayList<>(listPackage(pkg)); - Collections.sort(props); - propsCache.put(pkg, props); - return props; - } catch (final IOException exp) { - if (Main.DEBUG) { - exp.printStackTrace(); - } - return Collections.emptyList(); - } - } - - /** - * Close resources (like file system) used, if any. - */ - abstract void close() throws IOException; - - /** - * Return the set of properties of a given package object. - * - * @param pkg package start string - * @return set of properties of the given Java package - */ - abstract Set listPackage(final String pkg) throws IOException; - - final boolean isClassAccessible(final String className) { - try { - final Class clz = context.findClass(className); - return Modifier.isPublic(clz.getModifiers()); - } catch (final ClassNotFoundException cnfe) { - } - return false; - } - - final boolean isPackageAccessible(final String pkgName) { - try { - Context.checkPackageAccess(pkgName); - return true; - } catch (final SecurityException se) { - return false; - } - } - - private static boolean isJavacHelperAvailable() { - try { - boolean result = JavacPackagesHelper.isAvailable(); - if (Main.DEBUG && !result) { - System.err.println("javac packages helper is not available"); - } - return result; - } catch (final LinkageError err) { - if (Main.DEBUG) { - System.err.println("javac packages helper is not available"); - err.printStackTrace(); - } - return false; - } - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java deleted file mode 100644 index bc95844bb28..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/PropertiesHelper.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.tools.jjs; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.WeakHashMap; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.NativeJavaPackage; -import jdk.nashorn.internal.runtime.PropertyMap; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.objects.NativeJava; - -/* - * A helper class to get properties of a given object for source code completion. - */ -final class PropertiesHelper { - // Java package properties helper, may be null - private PackagesHelper pkgsHelper; - // cached properties list - private final WeakHashMap> propsCache = new WeakHashMap<>(); - - /** - * Construct a new PropertiesHelper. - * - * @param context the current nashorn Context - */ - PropertiesHelper(final Context context) { - try { - this.pkgsHelper = PackagesHelper.create(context); - } catch (final IOException exp) { - if (Main.DEBUG) { - exp.printStackTrace(); - } - this.pkgsHelper = null; - } - } - - void close() throws Exception { - propsCache.clear(); - pkgsHelper.close(); - } - - /** - * returns the list of properties of the given object. - * - * @param obj object whose property list is returned - * @return the list of properties of the given object - */ - List getProperties(final Object obj) { - assert obj != null && obj != ScriptRuntime.UNDEFINED; - - // wrap JS primitives as objects before gettting properties - if (JSType.isPrimitive(obj)) { - return getProperties(JSType.toScriptObject(obj)); - } - - // Handle Java package prefix case first. Should do it before checking - // for its super class ScriptObject! - if (obj instanceof NativeJavaPackage) { - if (pkgsHelper != null) { - return pkgsHelper.getPackageProperties(((NativeJavaPackage)obj).getName()); - } else { - return Collections.emptyList(); - } - } - - // script object - all inherited and non-enumerable, non-index properties - if (obj instanceof ScriptObject) { - final ScriptObject sobj = (ScriptObject)obj; - final PropertyMap pmap = sobj.getMap(); - if (propsCache.containsKey(pmap)) { - return propsCache.get(pmap); - } - final String[] keys = sobj.getAllKeys(); - List props = Arrays.asList(keys); - props = props.stream() - .filter(s -> Character.isJavaIdentifierStart(s.charAt(0))) - .collect(Collectors.toList()); - Collections.sort(props); - // cache properties against the PropertyMap - propsCache.put(pmap, props); - return props; - } - - // java class case - don't refer to StaticClass directly - if (NativeJava.isType(ScriptRuntime.UNDEFINED, obj)) { - if (propsCache.containsKey(obj)) { - return propsCache.get(obj); - } - final List props = NativeJava.getProperties(obj); - Collections.sort(props); - // cache properties against the StaticClass representing the class - propsCache.put(obj, props); - return props; - } - - // any other Java object - final Class clazz = obj.getClass(); - if (propsCache.containsKey(clazz)) { - return propsCache.get(clazz); - } - - final List props = NativeJava.getProperties(obj); - Collections.sort(props); - // cache properties against the Class object - propsCache.put(clazz, props); - return props; - } - - // This method creates a regex Pattern to use to do CamelCase - // matching. The pattern is derived from user supplied string - // containing one or more upper case characters in it. - private static Pattern makeCamelCasePattern(final String str) { - assert !str.isEmpty(); - - final char[] chars = str.toCharArray(); - final StringBuilder buf = new StringBuilder(); - boolean seenUpperCase = false; - - // Skip first char for case check. Even if it is upper case, - // we do not want to put lower case matching pattern before - // the first letter! - buf.append(chars[0]); - - for (int idx = 1; idx < chars.length; idx++) { - final char ch = chars[idx]; - if (ch >= 'A' && ch <= 'Z') { - seenUpperCase = true; - buf.append("[^A-Z]*"); - } - buf.append(ch); - } - - if (seenUpperCase) { - // match anything at the end! - buf.append(".*"); - try { - return Pattern.compile(buf.toString()); - } catch (Exception exp) { - } - } - - return null; - } - - /** - * Returns the list of properties of the given object that start with the given prefix. - * - * @param obj object whose property list is returned - * @param prefix property prefix to be matched - * @return the list of properties of the given object - */ - List getProperties(final Object obj, final String prefix) { - assert prefix != null && !prefix.isEmpty(); - List allProps = getProperties(obj); - List props = allProps.stream() - .filter(s -> s.startsWith(prefix)) - .collect(Collectors.toList()); - - // If no match, try CamelCase completion.. - if (props.isEmpty()) { - final Pattern pat = makeCamelCasePattern(prefix); - if (pat != null) { - return allProps.stream() - .filter(s -> pat.matcher(s).matches()) - .collect(Collectors.toList()); - } - } - - return props; - } -} diff --git a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/resources/jjs.js b/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/resources/jjs.js deleted file mode 100644 index 848230b83e6..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/resources/jjs.js +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -(function () { - -// Check if java.desktop module is available and we're running in non-headless mode. -// We access AWT via script to avoid direct dependency on java.desktop module. -function isHeadless() { - var GraphicsEnvironment = java.awt.GraphicsEnvironment; - return Java.isType(GraphicsEnvironment)? GraphicsEnvironment.isHeadless() : true; -} - - -// Function that shows a JFileChooser dialog and returns the file name chosen (if chosen). -// We access swing from script to avoid direct dependency on java.desktop module. -function chooseFile() { - var JFileChooser = javax.swing.JFileChooser; - if (!Java.isType(JFileChooser)) { - return null; - } - - var ExtensionFilter = javax.swing.filechooser.FileNameExtensionFilter; - function run() { - var chooser = new JFileChooser(); - chooser.fileFilter = new ExtensionFilter('JavaScript Files', 'js'); - var retVal = chooser.showOpenDialog(null); - return retVal == JFileChooser.APPROVE_OPTION ? - chooser.selectedFile.absolutePath : null; - } - - var FutureTask = java.util.concurrent.FutureTask; - var fileChooserTask = new FutureTask(run); - javax.swing.SwingUtilities.invokeLater(fileChooserTask); - - return fileChooserTask.get(); -} - -// Function that opens up the desktop browser application with the given URI. -// We access AWT from script to avoid direct dependency on java.desktop module. -function browse(uri) { - var Desktop = java.awt.Desktop; - if (Java.isType(Desktop)) { - Desktop.desktop.browse(uri); - } -} - -function printDoc(list) { - list.forEach(function(doc) { - print(); - print(doc.signature()); - print(); - print(doc.javadoc()); - }); -} - -var JShell = null; -var jshell = null; - -function javadoc(obj) { - var str = String(obj); - if (!JShell) { - // first time - resolve JShell class - JShell = Packages.jdk.jshell.JShell; - // if JShell class is available, create an instance - jshell = Java.isType(JShell)? JShell.create() : null; - } - - if (!jshell) { - // we don't have jshell. Just print the default! - return print(str); - } - - /* - * A java method object's String representation looks something like this: - * - * For an overloaded method: - * - * [jdk.dynalink.beans.OverloadedDynamicMethod - * String java.lang.System.getProperty(String,String) - * String java.lang.System.getProperty(String) - * ] - * - * For a non-overloaded method: - * - * [jdk.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)] - * - * jshell expects "java.lang.System.getProperty(" or "java.lang.System.exit(" - * to retrieve the javadoc comment(s) for the method. - */ - var javaCode = str.split(" ")[2]; // stuff after second whitespace char - javaCode = javaCode.substring(0, javaCode.indexOf('(') + 1); // strip argument types - - try { - var analysis = jshell.sourceCodeAnalysis(); - var docList = analysis.documentation(javaCode, javaCode.length, true); - if (!docList.isEmpty()) { - return printDoc(docList); - } - - /* - * May be the method is a Java instance method. In such a case, jshell expects - * a valid starting portion of an instance method call expression. We cast null - * to Java object and call method on it. i.e., We pass something like this: - * - * "((java.io.PrintStream)null).println(" - */ - var javaType = javaCode.substring(0, javaCode.lastIndexOf('.')); - javaCode = "((" + javaType + ")null)" + javaCode.substring(javaCode.lastIndexOf('.')); - docList = analysis.documentation(javaCode, javaCode.length, true); - if (!docList.isEmpty()) { - return printDoc(docList); - } - } catch (e) { - } - print(str); -} - -return { - isHeadless: isHeadless, - chooseFile: chooseFile, - browse: browse, - javadoc: javadoc -}; - -})(); diff --git a/src/jdk.scripting.nashorn.shell/share/classes/module-info.java b/src/jdk.scripting.nashorn.shell/share/classes/module-info.java deleted file mode 100644 index 5bc8b0b71ea..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/classes/module-info.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * Defines Nashorn shell module. - * - *

This module includes the command line tool {@index jjs jjs tool} - * to invoke the Nashorn engine. - * - * @toolGuide jjs - * - * @moduleGraph - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -module jdk.scripting.nashorn.shell { - requires static java.compiler; - requires jdk.internal.le; - requires jdk.scripting.nashorn; - requires jdk.internal.ed; - uses jdk.internal.editor.spi.BuildInEditorProvider; -} - diff --git a/src/jdk.scripting.nashorn.shell/share/man/jjs.1 b/src/jdk.scripting.nashorn.shell/share/man/jjs.1 deleted file mode 100644 index ffeefcd5255..00000000000 --- a/src/jdk.scripting.nashorn.shell/share/man/jjs.1 +++ /dev/null @@ -1,247 +0,0 @@ -.\" Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.3.1 -.\" -.TH "JJS" "1" "2020" "JDK 14" "JDK Commands" -.hy -.SH NAME -.PP -jjs \- command\-line tool to invoke the Nashorn engine -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] The \f[CB]jjs\f[R] tool and the Nashorn engine are -deprecated in JDK 11 in preparation for removal in a future release. -.PP -\f[CB]jjs\f[R] [\f[I]options\f[R]] \f[I]script\-files\f[R] [\f[CB]\-\-\f[R] -\f[I]arguments\f[R]] -.TP -.B \f[I]options\f[R] -This represents one or more options of the \f[CB]jjs\f[R] command, -separated by spaces. -See \f[B]Options for the jjs Command\f[R]. -.RS -.RE -.TP -.B \f[I]script\-files\f[R] -This represents one or more script files that you want to interpret -using the Nashorn engine, separated by spaces. -If no files are specified, then an interactive shell is started. -.RS -.RE -.TP -.B \f[I]arguments\f[R] -All values after the double hyphen marker (\f[CB]\-\-\f[R]) are passed -through to the script or the interactive shell as arguments. -These values can be accessed by using the \f[CB]arguments\f[R] property. -.RS -.RE -.SH DESCRIPTION -.PP -The \f[CB]jjs\f[R] command\-line tool is used to invoke the Nashorn -engine. -You can use it to interpret one or several script files, or to run an -interactive shell. -.SH OPTIONS FOR THE JJS COMMAND -.PP -The options of the \f[CB]jjs\f[R] command control the conditions under -which scripts are interpreted by Nashorn engine. -.TP -.B \f[CB]\-D\f[R]\f[I]name\f[R]\f[CB]=\f[R]\f[I]value\f[R] -Sets a system property to be passed to the script by assigning a value -to a property name. -The following example shows how to invoke Nashorn engine in interactive -mode and assign \f[CB]myValue\f[R] to the property named \f[CB]myKey\f[R]: -.RS -.IP -.nf -\f[CB] ->>\ jjs\ \-DmyKey=myValue -jjs>\ java.lang.System.getProperty("myKey") -myValue -jjs> -\f[R] -.fi -.PP -This option can be repeated to set multiple properties. -.RE -.TP -.B \f[CB]\-\-add\-modules\f[R] \f[I]modules\f[R] -Specifies the root user Java modules. -.RS -.RE -.TP -.B \f[CB]\-cp\f[R] \f[I]path\f[R] or \f[CB]\-classpath\f[R] \f[I]path\f[R] -Specifies the path to the supporting class files. -To set multiple paths, the option can be repeated, or you can separate -each path with the following character: -.RS -.IP \[bu] 2 -\f[B]Oracle Solaris, Linux, and OS X:\f[R] Colon (\f[CB]:\f[R]) -.IP \[bu] 2 -\f[B]Windows:\f[R] Semicolon (\f[CB];\f[R]) -.RE -.TP -.B \f[CB]\-doe=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] or \f[CB]\-dump\-on\-error=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Provides a full stack trace when an error occurs. -By default, only a brief error message is printed. -The default parameter is \f[CB]false\f[R]. -.RS -.RE -.TP -.B \f[CB]\-fv=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] or \f[CB]\-fullversion=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Prints the full Nashorn version string. -The default parameter is \f[CB]false\f[R]. -.RS -.RE -.TP -.B \f[CB]\-fx=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Launches the script as a JavaFX application. -The default parameter is \f[CB]false\f[R]. -.RS -.PP -\f[B]Note:\f[R] -.PP -You must explicitly add the JavaFX modules to launch the script as a -JavaFX application. -The following example specifies the location of the JavaFX modules and -adds them with the \f[CB]\-\-module\-path\f[R] and -\f[CB]\-\-add\-modules\f[R] options: -.IP -.nf -\f[CB] -jjs\ \-fx\ \-\-module\-path\ /SOMEDIR/javafx\-sdk\-11/lib\ \-\-add\-modules\ javafx.controls\ HelloWorld.js -\f[R] -.fi -.PP -The following example uses the \f[CB]jlink\f[R] command to create a custom -runtime image that contains the JavaFX modules. -The example then launches a script as a JavaFX application without -specifying the JavaFX modules in the \f[CB]jjs\f[R] command: -.IP -.nf -\f[CB] -jlink\ \-\-module\-path\ /SOMEDIR/javafx\-jmods\-11\ \-\-add\-modules\ jdk.scripting.nashorn,jdk.scripting.nashorn.shell,javafx.controls\ \-\-output\ /SOMEDIR/myjdk - -/SOMEDIR/myjdk/bin/jjs\ \-fx\ HelloWorld.js -\f[R] -.fi -.PP -If you don\[aq]t explicitly specify the JavaFX modules, then the -\f[CB]jjs\f[R] command prints a message and exits: -.IP -.nf -\f[CB] -jjs\ \-fx\ HelloWorld.js - -JavaFX\ is\ not\ available. -\f[R] -.fi -.RE -.TP -.B \f[CB]\-h\f[R] or \f[CB]\-help\f[R] -Prints the list of options and their descriptions. -.RS -.RE -.TP -.B \f[CB]\-\-language=\f[R][\f[CB]es5\f[R]|\f[CB]es6\f[R]] -Specifies the ECMAScript language version. -The default version is ES5. -.RS -.RE -.TP -.B \f[CB]\-\-module\-path\f[R] \f[I]path\f[R] -Specifies where to find user Java modules. -.RS -.RE -.TP -.B \f[CB]\-ot=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] or \f[CB]\-optimistic\-types=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Enables or disables optimistic type assumptions with deoptimizing -recompilation. -This makes the compiler try, for any program symbol whose type can\[aq]t -be proven at compile time, to type it as narrowly and primitively as -possible. -If the runtime encounters an error because the symbol type is too -narrow, then a wider method is generated until a steady stage is -reached. -While this produces as optimal Java bytecode as possible, erroneous type -guesses will lead to longer warmup. -Optimistic typing is currently enabled by default, but it can be -disabled for faster startup performance. -The default parameter is \f[CB]true\f[R]. -.RS -.RE -.TP -.B \f[CB]\-scripting=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Enables a shell scripting features. -The default parameter is \f[CB]true\f[R]. -.RS -.RE -.TP -.B \f[CB]\-strict=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Enables a strict mode, which enforces stronger adherence to the standard -(ECMAScript Edition 5.1), making it easier to detect common coding -errors. -The default parameter is \f[CB]false\f[R]. -.RS -.RE -.TP -.B \f[CB]\-t=\f[R]\f[I]zone\f[R] or \f[CB]\-timezone=\f[R]\f[I]zone\f[R] -Sets the specified time zone for script execution. -It overrides the time zone set in the OS and used by the \f[CB]Date\f[R] -object. -The default \f[I]zone\f[R] is \f[CB]America/Los_Angeles\f[R]. -.RS -.RE -.TP -.B \f[CB]\-v=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] or\f[CB]\-version=\f[R][\f[CB]true\f[R]|\f[CB]false\f[R]] -Prints the Nashorn version string. -The default parameter is \f[CB]false\f[R]. -.RS -.RE -.SH EXAMPLE OF RUNNING A SCRIPT WITH NASHORN -.IP -.nf -\f[CB] -jjs\ script.js -\f[R] -.fi -.SH EXAMPLE OF RUNNING NASHORN IN INTERACTIVE MODE -.IP -.nf -\f[CB] ->>\ jjs -jjs>\ println("Hello,\ World!") -Hello,\ World! -jjs>\ quit() ->> -\f[R] -.fi -.SH EXAMPLE OF PASSING ARGUMENTS TO NASHORN -.IP -.nf -\f[CB] ->>\ jjs\ \-\-\ a\ b\ c -jjs>\ arguments.join(",\ ") -a,\ b,\ c -jjs> -\f[R] -.fi diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java deleted file mode 100644 index 5123f0badf0..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/linker/NashornLinkerExporter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package jdk.nashorn.api.linker; - -import java.util.List; -import jdk.dynalink.linker.GuardingDynamicLinker; -import jdk.dynalink.linker.GuardingDynamicLinkerExporter; -import jdk.nashorn.internal.runtime.linker.Bootstrap; - -/** - * This linker exporter is a service provider that exports Nashorn Dynalink - * linkers to external users. Other language runtimes that use Dynalink - * can use the linkers exported by this provider to support tight integration - * of Nashorn objects. - */ -@Deprecated(since="11", forRemoval=true) -public final class NashornLinkerExporter extends GuardingDynamicLinkerExporter { - /** - * The default constructor. - */ - public NashornLinkerExporter() {} - - /** - * Returns a list of exported nashorn specific linkers. - * - * @return list of exported nashorn specific linkers - */ - @Override - public List get() { - return Bootstrap.getExposedLinkers(); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/AbstractJSObject.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/AbstractJSObject.java deleted file mode 100644 index fe5620b8dde..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/AbstractJSObject.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.Collection; -import java.util.Collections; -import java.util.Objects; -import java.util.Set; - -/** - * This is the base class for nashorn ScriptObjectMirror class. - * - * This class can also be subclassed by an arbitrary Java class. Nashorn will - * treat objects of such classes just like nashorn script objects. Usual nashorn - * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be delegated - * to appropriate method call of this class. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public abstract class AbstractJSObject implements JSObject { - /** - * The default constructor. - */ - public AbstractJSObject() {} - - /** - * @implSpec This implementation always throws UnsupportedOperationException - */ - @Override - public Object call(final Object thiz, final Object... args) { - throw new UnsupportedOperationException("call"); - } - - /** - * @implSpec This implementation always throws UnsupportedOperationException - */ - @Override - public Object newObject(final Object... args) { - throw new UnsupportedOperationException("newObject"); - } - - /** - * @implSpec This imlementation always throws UnsupportedOperationException - */ - @Override - public Object eval(final String s) { - throw new UnsupportedOperationException("eval"); - } - - /** - * @implSpec This implementation always returns null - */ - @Override - public Object getMember(final String name) { - Objects.requireNonNull(name); - return null; - } - - /** - * @implSpec This implementation always returns null - */ - @Override - public Object getSlot(final int index) { - return null; - } - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean hasMember(final String name) { - Objects.requireNonNull(name); - return false; - } - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean hasSlot(final int slot) { - return false; - } - - /** - * @implSpec This implementation is a no-op - */ - @Override - public void removeMember(final String name) { - Objects.requireNonNull(name); - //empty - } - - /** - * @implSpec This implementation is a no-op - */ - @Override - public void setMember(final String name, final Object value) { - Objects.requireNonNull(name); - //empty - } - - /** - * @implSpec This implementation is a no-op - */ - @Override - public void setSlot(final int index, final Object value) { - //empty - } - - // property and value iteration - - /** - * @implSpec This implementation returns empty set - */ - @Override - public Set keySet() { - return Collections.emptySet(); - } - - /** - * @implSpec This implementation returns empty set - */ - @Override - public Collection values() { - return Collections.emptySet(); - } - - // JavaScript instanceof check - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean isInstance(final Object instance) { - return false; - } - - @Override - public boolean isInstanceOf(final Object clazz) { - if (clazz instanceof JSObject) { - return ((JSObject)clazz).isInstance(this); - } - - return false; - } - - @Override - public String getClassName() { - return getClass().getName(); - } - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean isFunction() { - return false; - } - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean isStrictFunction() { - return false; - } - - /** - * @implSpec This implementation always returns false - */ - @Override - public boolean isArray() { - return false; - } - - /** - * Returns this object's numeric value. - * - * @return this object's numeric value. - * @deprecated use {@link #getDefaultValue(Class)} with {@link Number} hint instead. - */ - @Override @Deprecated - public double toNumber() { - return Double.NaN; - } - - /** - * When passed an {@link AbstractJSObject}, invokes its {@link #getDefaultValue(Class)} method. When passed any - * other {@link JSObject}, it will obtain its {@code [[DefaultValue]]} method as per ECMAScript 5.1 section - * 8.6.2. - * - * @param jsobj the {@link JSObject} whose {@code [[DefaultValue]]} is obtained. - * @param hint the type hint. Should be either {@code null}, {@code Number.class} or {@code String.class}. - * @return this object's default value. - * @throws UnsupportedOperationException if the conversion can't be performed. The engine will convert this - * exception into a JavaScript {@code TypeError}. - * @deprecated use {@link JSObject#getDefaultValue(Class)} instead. - */ - @Deprecated - public static Object getDefaultValue(final JSObject jsobj, final Class hint) { - return jsobj.getDefaultValue(hint); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ClassFilter.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ClassFilter.java deleted file mode 100644 index c4a4ca440fb..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ClassFilter.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.scripting; - -/** - * Class filter (optional) to be used by nashorn script engine. - * jsr-223 program embedding nashorn script can set ClassFilter instance - * to be used when an engine instance is created. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public interface ClassFilter { - /** - * Should the Java class of the specified name be exposed to scripts? - * @param className is the fully qualified name of the java class being - * checked. This will not be null. Only non-array class names will be - * passed. - * @return true if the java class can be exposed to scripts false otherwise - */ - public boolean exposeToScripts(String className); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/DefaultValueImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/DefaultValueImpl.java deleted file mode 100644 index c01dcb41f3f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/DefaultValueImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import jdk.nashorn.internal.runtime.JSType; - -/** - * Default implementation of {@link JSObject#getDefaultValue(Class)}. Isolated into a separate class mostly so - * that we can have private static instances of function name arrays, something we couldn't declare without it - * being visible in {@link JSObject} interface. - */ -class DefaultValueImpl { - private static final String[] DEFAULT_VALUE_FNS_NUMBER = new String[] { "valueOf", "toString" }; - private static final String[] DEFAULT_VALUE_FNS_STRING = new String[] { "toString", "valueOf" }; - - static Object getDefaultValue(final JSObject jsobj, final Class hint) throws UnsupportedOperationException { - final boolean isNumber = hint == null || hint == Number.class; - for(final String methodName: isNumber ? DEFAULT_VALUE_FNS_NUMBER : DEFAULT_VALUE_FNS_STRING) { - final Object objMember = jsobj.getMember(methodName); - if (objMember instanceof JSObject) { - final JSObject member = (JSObject)objMember; - if (member.isFunction()) { - final Object value = member.call(jsobj); - if (JSType.isPrimitive(value)) { - return value; - } - } - } - } - throw new UnsupportedOperationException(isNumber ? "cannot.get.default.number" : "cannot.get.default.string"); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/Formatter.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/Formatter.java deleted file mode 100644 index 2cacbb581d8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/Formatter.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Formatter is a class to get the type conversion between javascript types and - * java types for the format (sprintf) method working. - * - *

In javascript the type for numbers can be different from the format type - * specifier. For format type '%d', '%o', '%x', '%X' double need to be - * converted to integer. For format type 'e', 'E', 'f', 'g', 'G', 'a', 'A' - * integer needs to be converted to double. - * - *

Format type "%c" and javascript string needs special handling. - * - *

The javascript date objects can be handled if they are type double (the - * related javascript code will convert with Date.getTime() to double). So - * double date types are converted to long. - * - *

Pattern and the logic for parameter position: java.util.Formatter - * - */ -final class Formatter { - - private Formatter() { - } - - /** - * Method which converts javascript types to java types for the - * String.format method (jrunscript function sprintf). - * - * @param format a format string - * @param args arguments referenced by the format specifiers in format - * @return a formatted string - */ - static String format(final String format, final Object[] args) { - final Matcher m = FS_PATTERN.matcher(format); - int positionalParameter = 1; - - while (m.find()) { - int index = index(m.group(1)); - final boolean previous = isPreviousArgument(m.group(2)); - final char conversion = m.group(6).charAt(0); - - // skip over some formats - if (index < 0 || previous - || conversion == 'n' || conversion == '%') { - continue; - } - - // index 0 here means take a positional parameter - if (index == 0) { - index = positionalParameter++; - } - - // out of index, String.format will handle - if (index > args.length) { - continue; - } - - // current argument - final Object arg = args[index - 1]; - - // for date we convert double to long - if (m.group(5) != null) { - // convert double to long - if (arg instanceof Double) { - args[index - 1] = ((Double) arg).longValue(); - } - } else { - // we have to convert some types - switch (conversion) { - case 'd': - case 'o': - case 'x': - case 'X': - if (arg instanceof Double) { - // convert double to long - args[index - 1] = ((Double) arg).longValue(); - } else if (arg instanceof String - && ((String) arg).length() > 0) { - // convert string (first character) to int - args[index - 1] = (int) ((String) arg).charAt(0); - } - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - case 'a': - case 'A': - if (arg instanceof Integer) { - // convert integer to double - args[index - 1] = ((Integer) arg).doubleValue(); - } - break; - case 'c': - if (arg instanceof Double) { - // convert double to integer - args[index - 1] = ((Double) arg).intValue(); - } else if (arg instanceof String - && ((String) arg).length() > 0) { - // get the first character from string - args[index - 1] = (int) ((String) arg).charAt(0); - } - break; - default: - break; - } - } - } - - return String.format(format, args); - } - - /** - * Method to parse the integer of the argument index. - * - * @param s string to parse - * @return -1 if parsing failed, 0 if string is null, > 0 integer - */ - private static int index(final String s) { - int index = -1; - - if (s != null) { - try { - index = Integer.parseInt(s.substring(0, s.length() - 1)); - } catch (final NumberFormatException e) { - //ignored - } - } else { - index = 0; - } - - return index; - } - - /** - * Method to check if a string contains '<'. This is used to find out if - * previous parameter is used. - * - * @param s string to check - * @return true if '<' is in the string, else false - */ - private static boolean isPreviousArgument(final String s) { - return (s != null && s.indexOf('<') >= 0); - } - - // %[argument_index$][flags][width][.precision][t]conversion - private static final String formatSpecifier = - "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"; - // compiled format string - private static final Pattern FS_PATTERN; - - static { - FS_PATTERN = Pattern.compile(formatSpecifier); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/JSObject.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/JSObject.java deleted file mode 100644 index 61502657ec1..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/JSObject.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.Collection; -import java.util.Set; -import jdk.nashorn.internal.runtime.JSType; - -/** - * This interface can be implemented by an arbitrary Java class. Nashorn will - * treat objects of such classes just like nashorn script objects. Usual nashorn - * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be delegated - * to appropriate method call of this interface. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public interface JSObject { - /** - * Call this object as a JavaScript function. This is equivalent to - * 'func.apply(thiz, args)' in JavaScript. - * - * @param thiz 'this' object to be passed to the function. This may be null. - * @param args arguments to method - * @return result of call - */ - public Object call(final Object thiz, final Object... args); - - /** - * Call this 'constructor' JavaScript function to create a new object. - * This is equivalent to 'new func(arg1, arg2...)' in JavaScript. - * - * @param args arguments to method - * @return result of constructor call - */ - public Object newObject(final Object... args); - - /** - * Evaluate a JavaScript expression. - * - * @param s JavaScript expression to evaluate - * @return evaluation result - */ - public Object eval(final String s); - - /** - * Retrieves a named member of this JavaScript object. - * - * @param name of member - * @return member - * @throws NullPointerException if name is null - */ - public Object getMember(final String name); - - /** - * Retrieves an indexed member of this JavaScript object. - * - * @param index index slot to retrieve - * @return member - */ - public Object getSlot(final int index); - - /** - * Does this object have a named member? - * - * @param name name of member - * @return true if this object has a member of the given name - */ - public boolean hasMember(final String name); - - /** - * Does this object have a indexed property? - * - * @param slot index to check - * @return true if this object has a slot - */ - public boolean hasSlot(final int slot); - - /** - * Remove a named member from this JavaScript object - * - * @param name name of the member - * @throws NullPointerException if name is null - */ - public void removeMember(final String name); - - /** - * Set a named member in this JavaScript object - * - * @param name name of the member - * @param value value of the member - * @throws NullPointerException if name is null - */ - public void setMember(final String name, final Object value); - - /** - * Set an indexed member in this JavaScript object - * - * @param index index of the member slot - * @param value value of the member - */ - public void setSlot(final int index, final Object value); - - // property and value iteration - - /** - * Returns the set of all property names of this object. - * - * @return set of property names - */ - public Set keySet(); - - /** - * Returns the set of all property values of this object. - * - * @return set of property values. - */ - public Collection values(); - - // JavaScript instanceof check - - /** - * Checking whether the given object is an instance of 'this' object. - * - * @param instance instance to check - * @return true if the given 'instance' is an instance of this 'function' object - */ - public boolean isInstance(final Object instance); - - /** - * Checking whether this object is an instance of the given 'clazz' object. - * - * @param clazz clazz to check - * @return true if this object is an instance of the given 'clazz' - */ - public boolean isInstanceOf(final Object clazz); - - /** - * ECMA [[Class]] property - * - * @return ECMA [[Class]] property value of this object - */ - public String getClassName(); - - /** - * Is this a function object? - * - * @return if this mirror wraps a ECMAScript function instance - */ - public boolean isFunction(); - - /** - * Is this a 'use strict' function object? - * - * @return true if this mirror represents a ECMAScript 'use strict' function - */ - public boolean isStrictFunction(); - - /** - * Is this an array object? - * - * @return if this mirror wraps a ECMAScript array object - */ - public boolean isArray(); - - /** - * Returns this object's numeric value. - * - * @return this object's numeric value. - * @deprecated use {@link #getDefaultValue(Class)} with {@link Number} hint instead. - */ - @Deprecated - default double toNumber() { - return JSType.toNumber(JSType.toPrimitive(this, Number.class)); - } - - /** - * Implements this object's {@code [[DefaultValue]]} method as per ECMAScript 5.1 section 8.6.2. - * - * @param hint the type hint. Should be either {@code null}, {@code Number.class} or {@code String.class}. - * @return this object's default value. - * @throws UnsupportedOperationException if the conversion can't be performed. The engine will convert this - * exception into a JavaScript {@code TypeError}. - */ - default Object getDefaultValue(final Class hint) throws UnsupportedOperationException { - return DefaultValueImpl.getDefaultValue(this, hint); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java deleted file mode 100644 index 87a997d71a2..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.ArrayList; -import java.util.List; -import jdk.nashorn.internal.codegen.CompilerConstants; -import jdk.nashorn.internal.runtime.ECMAErrors; -import jdk.nashorn.internal.runtime.ScriptObject; - -/** - * This is base exception for all Nashorn exceptions. These originate from - * user's ECMAScript code. Example: script parse errors, exceptions thrown from - * scripts. Note that ScriptEngine methods like "eval", "invokeMethod", - * "invokeFunction" will wrap this as ScriptException and throw it. But, there - * are cases where user may need to access this exception (or implementation - * defined subtype of this). For example, if java interface is implemented by a - * script object or Java access to script object properties via java.util.Map - * interface. In these cases, user code will get an instance of this or - * implementation defined subclass. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -@SuppressWarnings("serial") -public abstract class NashornException extends RuntimeException { - private static final long serialVersionUID = 1L; - - // script file name - private String fileName; - // script line number - private int line; - // are the line and fileName unknown? - private boolean lineAndFileNameUnknown; - // script column number - private int column; - // underlying ECMA error object - lazily initialized - private Object ecmaError; - - /** - * Constructor to initialize error message, file name, line and column numbers. - * - * @param msg exception message - * @param fileName file name - * @param line line number - * @param column column number - */ - protected NashornException(final String msg, final String fileName, final int line, final int column) { - this(msg, null, fileName, line, column); - } - - /** - * Constructor to initialize error message, cause exception, file name, line and column numbers. - * - * @param msg exception message - * @param cause exception cause - * @param fileName file name - * @param line line number - * @param column column number - */ - protected NashornException(final String msg, final Throwable cause, final String fileName, final int line, final int column) { - super(msg, cause == null ? null : cause); - this.fileName = fileName; - this.line = line; - this.column = column; - } - - /** - * Constructor to initialize error message and cause exception. - * - * @param msg exception message - * @param cause exception cause - */ - protected NashornException(final String msg, final Throwable cause) { - super(msg, cause == null ? null : cause); - // Hard luck - no column number info - this.column = -1; - // We can retrieve the line number and file name from the stack trace if needed - this.lineAndFileNameUnknown = true; - } - - /** - * Get the source file name for this {@code NashornException} - * - * @return the file name - */ - public final String getFileName() { - ensureLineAndFileName(); - return fileName; - } - - /** - * Set the source file name for this {@code NashornException} - * - * @param fileName the file name - */ - public final void setFileName(final String fileName) { - this.fileName = fileName; - lineAndFileNameUnknown = false; - } - - /** - * Get the line number for this {@code NashornException} - * - * @return the line number - */ - public final int getLineNumber() { - ensureLineAndFileName(); - return line; - } - - /** - * Set the line number for this {@code NashornException} - * - * @param line the line number - */ - public final void setLineNumber(final int line) { - lineAndFileNameUnknown = false; - this.line = line; - } - - /** - * Get the column for this {@code NashornException} - * - * @return the column number - */ - public final int getColumnNumber() { - return column; - } - - /** - * Set the column for this {@code NashornException} - * - * @param column the column number - */ - public final void setColumnNumber(final int column) { - this.column = column; - } - - /** - * Returns array javascript stack frames from the given exception object. - * - * @param exception exception from which stack frames are retrieved and filtered - * @return array of javascript stack frames - */ - public static StackTraceElement[] getScriptFrames(final Throwable exception) { - final StackTraceElement[] frames = exception.getStackTrace(); - final List filtered = new ArrayList<>(); - for (final StackTraceElement st : frames) { - if (ECMAErrors.isScriptFrame(st)) { - final String className = "<" + st.getFileName() + ">"; - String methodName = st.getMethodName(); - if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) { - methodName = ""; - } else { - methodName = stripMethodName(methodName); - } - - filtered.add(new StackTraceElement(className, methodName, - st.getFileName(), st.getLineNumber())); - } - } - return filtered.toArray(new StackTraceElement[0]); - } - - private static String stripMethodName(final String methodName) { - String name = methodName; - - final int nestedSeparator = name.lastIndexOf(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName()); - if (nestedSeparator >= 0) { - name = name.substring(nestedSeparator + 1); - } - - final int idSeparator = name.indexOf(CompilerConstants.ID_FUNCTION_SEPARATOR.symbolName()); - if (idSeparator >= 0) { - name = name.substring(0, idSeparator); - } - - return name.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName()) ? "" : name; - } - - /** - * Return a formatted script stack trace string with frames information separated by '\n' - * - * @param exception exception for which script stack string is returned - * @return formatted stack trace string - */ - public static String getScriptStackString(final Throwable exception) { - final StringBuilder buf = new StringBuilder(); - final StackTraceElement[] frames = getScriptFrames(exception); - for (final StackTraceElement st : frames) { - buf.append("\tat "); - buf.append(st.getMethodName()); - buf.append(" ("); - buf.append(st.getFileName()); - buf.append(':'); - buf.append(st.getLineNumber()); - buf.append(")\n"); - } - final int len = buf.length(); - // remove trailing '\n' - if (len > 0) { - assert buf.charAt(len - 1) == '\n'; - buf.deleteCharAt(len - 1); - } - return buf.toString(); - } - - /** - * Get the thrown object. Subclass responsibility - * @return thrown object - */ - protected Object getThrown() { - return null; - } - - /** - * Initialization function for ECMA errors. Stores the error - * in the ecmaError field of this class. It is only initialized - * once, and then reused - * - * @param global the global - * @return initialized exception - */ - NashornException initEcmaError(final ScriptObject global) { - if (ecmaError != null) { - return this; // initialized already! - } - - final Object thrown = getThrown(); - if (thrown instanceof ScriptObject) { - setEcmaError(ScriptObjectMirror.wrap(thrown, global)); - } else { - setEcmaError(thrown); - } - - return this; - } - - /** - * Return the underlying ECMA error object, if available. - * - * @return underlying ECMA Error object's mirror or whatever was thrown - * from script such as a String, Number or a Boolean. - */ - public Object getEcmaError() { - return ecmaError; - } - - /** - * Return the underlying ECMA error object, if available. - * - * @param ecmaError underlying ECMA Error object's mirror or whatever was thrown - * from script such as a String, Number or a Boolean. - */ - public void setEcmaError(final Object ecmaError) { - this.ecmaError = ecmaError; - } - - private void ensureLineAndFileName() { - if (lineAndFileNameUnknown) { - for (final StackTraceElement ste : getStackTrace()) { - if (ECMAErrors.isScriptFrame(ste)) { - // Whatever here is compiled from JavaScript code - fileName = ste.getFileName(); - line = ste.getLineNumber(); - return; - } - } - - lineAndFileNameUnknown = false; - } - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java deleted file mode 100644 index 98bb960542b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static jdk.nashorn.internal.runtime.Source.sourceFor; - -import java.io.IOException; -import java.io.Reader; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; -import java.text.MessageFormat; -import java.util.Locale; -import java.util.Objects; -import java.util.ResourceBundle; -import javax.script.AbstractScriptEngine; -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptException; -import javax.script.SimpleBindings; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ErrorManager; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; -import jdk.nashorn.internal.runtime.options.Options; - -/** - * JSR-223 compliant script engine for Nashorn. Instances are not created directly, but rather returned through - * {@link NashornScriptEngineFactory#getScriptEngine()}. Note that this engine implements the {@link Compilable} and - * {@link Invocable} interfaces, allowing for efficient precompilation and repeated execution of scripts. - * @see NashornScriptEngineFactory - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { - /** - * Key used to associate Nashorn global object mirror with arbitrary Bindings instance. - */ - public static final String NASHORN_GLOBAL = "nashorn.global"; - - // commonly used access control context objects - private static AccessControlContext createPermAccCtxt(final String permName) { - final Permissions perms = new Permissions(); - perms.add(new RuntimePermission(permName)); - return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) }); - } - - private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT); - private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL); - - // the factory that created this engine - private final ScriptEngineFactory factory; - // underlying nashorn Context - 1:1 with engine instance - private final Context nashornContext; - // do we want to share single Nashorn global instance across ENGINE_SCOPEs? - private final boolean _global_per_engine; - // This is the initial default Nashorn global object. - // This is used as "shared" global if above option is true. - private final Global global; - - // Nashorn script engine error message management - private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages"; - - private static final ResourceBundle MESSAGES_BUNDLE; - static { - MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault()); - } - - // helper to get Nashorn script engine error message - private static String getMessage(final String msgId, final String... args) { - try { - return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args); - } catch (final java.util.MissingResourceException e) { - throw new RuntimeException("no message resource found for message id: "+ msgId); - } - } - - NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { - assert args != null : "null argument array"; - this.factory = factory; - final Options options = new Options("nashorn"); - options.process(args); - - // throw ParseException on first error from script - final ErrorManager errMgr = new Context.ThrowErrorManager(); - // create new Nashorn Context - this.nashornContext = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Context run() { - try { - return new Context(options, errMgr, appLoader, classFilter); - } catch (final RuntimeException e) { - if (Context.DEBUG) { - e.printStackTrace(); - } - throw e; - } - } - }, CREATE_CONTEXT_ACC_CTXT); - - if (!nashornContext.getEnv()._no_deprecation_warning) { - System.err.println("Warning: Nashorn engine is planned to be removed from a future JDK release"); - } - - // cache this option that is used often - this._global_per_engine = nashornContext.getEnv()._global_per_engine; - - // create new global object - this.global = createNashornGlobal(); - // set the default ENGINE_SCOPE object for the default context - context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE); - } - - @Override - public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException { - return evalImpl(makeSource(reader, ctxt), ctxt); - } - - @Override - public Object eval(final String script, final ScriptContext ctxt) throws ScriptException { - return evalImpl(makeSource(script, ctxt), ctxt); - } - - @Override - public ScriptEngineFactory getFactory() { - return factory; - } - - @Override - public Bindings createBindings() { - if (_global_per_engine) { - // just create normal SimpleBindings. - // We use same 'global' for all Bindings. - return new SimpleBindings(); - } - return createGlobalMirror(); - } - - // Compilable methods - - @Override - public CompiledScript compile(final Reader reader) throws ScriptException { - return asCompiledScript(makeSource(reader, context)); - } - - @Override - public CompiledScript compile(final String str) throws ScriptException { - return asCompiledScript(makeSource(str, context)); - } - - // Invocable methods - - @Override - public Object invokeFunction(final String name, final Object... args) - throws ScriptException, NoSuchMethodException { - return invokeImpl(null, name, args); - } - - @Override - public Object invokeMethod(final Object thiz, final String name, final Object... args) - throws ScriptException, NoSuchMethodException { - if (thiz == null) { - throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); - } - return invokeImpl(thiz, name, args); - } - - @Override - public T getInterface(final Class clazz) { - return getInterfaceInner(null, clazz); - } - - @Override - public T getInterface(final Object thiz, final Class clazz) { - if (thiz == null) { - throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); - } - return getInterfaceInner(thiz, clazz); - } - - // Implementation only below this point - - private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException { - try { - return sourceFor(getScriptName(ctxt), reader); - } catch (final IOException e) { - throw new ScriptException(e); - } - } - - private static Source makeSource(final String src, final ScriptContext ctxt) { - return sourceFor(getScriptName(ctxt), src); - } - - private static String getScriptName(final ScriptContext ctxt) { - final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); - return (val != null) ? val.toString() : ""; - } - - private T getInterfaceInner(final Object thiz, final Class clazz) { - assert !(thiz instanceof ScriptObject) : "raw ScriptObject not expected here"; - - if (clazz == null || !clazz.isInterface()) { - throw new IllegalArgumentException(getMessage("interface.class.expected")); - } - - // perform security access check as early as possible - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (! Modifier.isPublic(clazz.getModifiers())) { - throw new SecurityException(getMessage("implementing.non.public.interface", clazz.getName())); - } - Context.checkPackageAccess(clazz); - } - - ScriptObject realSelf = null; - Global realGlobal = null; - if(thiz == null) { - // making interface out of global functions - realSelf = realGlobal = getNashornGlobalFrom(context); - } else if (thiz instanceof ScriptObjectMirror) { - final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz; - realSelf = mirror.getScriptObject(); - realGlobal = mirror.getHomeGlobal(); - if (! isOfContext(realGlobal, nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } - } - - if (realSelf == null) { - throw new IllegalArgumentException(getMessage("interface.on.non.script.object")); - } - - try { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != realGlobal); - try { - if (globalChanged) { - Context.setGlobal(realGlobal); - } - - if (! isInterfaceImplemented(clazz, realSelf)) { - return null; - } - return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz, - MethodHandles.publicLookup()).invoke(realSelf)); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } catch(final RuntimeException|Error e) { - throw e; - } catch(final Throwable t) { - throw new RuntimeException(t); - } - } - - // Retrieve nashorn Global object for a given ScriptContext object - private Global getNashornGlobalFrom(final ScriptContext ctxt) { - if (_global_per_engine) { - // shared single global object for all ENGINE_SCOPE Bindings - return global; - } - - final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE); - // is this Nashorn's own Bindings implementation? - if (bindings instanceof ScriptObjectMirror) { - final Global glob = globalFromMirror((ScriptObjectMirror)bindings); - if (glob != null) { - return glob; - } - } - - // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it! - final Object scope = bindings.get(NASHORN_GLOBAL); - if (scope instanceof ScriptObjectMirror) { - final Global glob = globalFromMirror((ScriptObjectMirror)scope); - if (glob != null) { - return glob; - } - } - - // We didn't find associated nashorn global mirror in the Bindings given! - // Create new global instance mirror and associate with the Bindings. - final ScriptObjectMirror mirror = createGlobalMirror(); - bindings.put(NASHORN_GLOBAL, mirror); - // Since we created this global explicitly for the non-default script context we set the - // current script context in global permanently so that invokes work as expected. See JDK-8150219 - mirror.getHomeGlobal().setInitScriptContext(ctxt); - return mirror.getHomeGlobal(); - } - - // Retrieve nashorn Global object from a given ScriptObjectMirror - private Global globalFromMirror(final ScriptObjectMirror mirror) { - final ScriptObject sobj = mirror.getScriptObject(); - if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) { - return (Global)sobj; - } - - return null; - } - - // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object - private ScriptObjectMirror createGlobalMirror() { - final Global newGlobal = createNashornGlobal(); - return new ScriptObjectMirror(newGlobal, newGlobal); - } - - // Create a new Nashorn Global object - private Global createNashornGlobal() { - final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Global run() { - try { - return nashornContext.newGlobal(); - } catch (final RuntimeException e) { - if (Context.DEBUG) { - e.printStackTrace(); - } - throw e; - } - } - }, CREATE_GLOBAL_ACC_CTXT); - - nashornContext.initGlobal(newGlobal, this); - - return newGlobal; - } - - private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { - Objects.requireNonNull(name); - assert !(selfObject instanceof ScriptObject) : "raw ScriptObject not expected here"; - - Global invokeGlobal = null; - ScriptObjectMirror selfMirror = null; - if (selfObject instanceof ScriptObjectMirror) { - selfMirror = (ScriptObjectMirror)selfObject; - if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) { - throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); - } - invokeGlobal = selfMirror.getHomeGlobal(); - } else if (selfObject == null) { - // selfObject is null => global function call - final Global ctxtGlobal = getNashornGlobalFrom(context); - invokeGlobal = ctxtGlobal; - selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal); - } - - if (selfMirror != null) { - try { - return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args)); - } catch (final Exception e) { - final Throwable cause = e.getCause(); - if (cause instanceof NoSuchMethodException) { - throw (NoSuchMethodException)cause; - } - throwAsScriptException(e, invokeGlobal); - throw new AssertionError("should not reach here"); - } - } - - // Non-script object passed as selfObject - throw new IllegalArgumentException(getMessage("interface.on.non.script.object")); - } - - private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException { - return evalImpl(compileImpl(src, ctxt), ctxt); - } - - private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { - return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt)); - } - - private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != ctxtGlobal); - try { - if (globalChanged) { - Context.setGlobal(ctxtGlobal); - } - - final ScriptFunction script = mgcs.getFunction(ctxtGlobal); - final ScriptContext oldCtxt = ctxtGlobal.getScriptContext(); - ctxtGlobal.setScriptContext(ctxt); - try { - return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal)); - } finally { - ctxtGlobal.setScriptContext(oldCtxt); - } - } catch (final Exception e) { - throwAsScriptException(e, ctxtGlobal); - throw new AssertionError("should not reach here"); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException { - if (script == null) { - return null; - } - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != ctxtGlobal); - try { - if (globalChanged) { - Context.setGlobal(ctxtGlobal); - } - - final ScriptContext oldCtxt = ctxtGlobal.getScriptContext(); - ctxtGlobal.setScriptContext(ctxt); - try { - return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal)); - } finally { - ctxtGlobal.setScriptContext(oldCtxt); - } - } catch (final Exception e) { - throwAsScriptException(e, ctxtGlobal); - throw new AssertionError("should not reach here"); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException { - if (e instanceof ScriptException) { - throw (ScriptException)e; - } else if (e instanceof NashornException) { - final NashornException ne = (NashornException)e; - final ScriptException se = new ScriptException( - ne.getMessage(), ne.getFileName(), - ne.getLineNumber(), ne.getColumnNumber()); - ne.initEcmaError(global); - se.initCause(e); - throw se; - } else if (e instanceof RuntimeException) { - throw (RuntimeException)e; - } else { - // wrap any other exception as ScriptException - throw new ScriptException(e); - } - } - - private CompiledScript asCompiledScript(final Source source) throws ScriptException { - final Context.MultiGlobalCompiledScript mgcs; - final ScriptFunction func; - final Global oldGlobal = Context.getGlobal(); - final Global newGlobal = getNashornGlobalFrom(context); - final boolean globalChanged = (oldGlobal != newGlobal); - try { - if (globalChanged) { - Context.setGlobal(newGlobal); - } - - mgcs = nashornContext.compileScript(source); - func = mgcs.getFunction(newGlobal); - } catch (final Exception e) { - throwAsScriptException(e, newGlobal); - throw new AssertionError("should not reach here"); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - - return new CompiledScript() { - @Override - public Object eval(final ScriptContext ctxt) throws ScriptException { - final Global globalObject = getNashornGlobalFrom(ctxt); - // Are we running the script in the same global in which it was compiled? - if (func.getScope() == globalObject) { - return evalImpl(func, ctxt, globalObject); - } - - // different global - return evalImpl(mgcs, ctxt, globalObject); - } - @Override - public ScriptEngine getEngine() { - return NashornScriptEngine.this; - } - }; - } - - private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { - return compileImpl(source, getNashornGlobalFrom(ctxt)); - } - - private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != newGlobal); - try { - if (globalChanged) { - Context.setGlobal(newGlobal); - } - - return nashornContext.compileScript(source, newGlobal); - } catch (final Exception e) { - throwAsScriptException(e, newGlobal); - throw new AssertionError("should not reach here"); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - private static boolean isInterfaceImplemented(final Class iface, final ScriptObject sobj) { - for (final Method method : iface.getMethods()) { - // ignore methods of java.lang.Object class - if (method.getDeclaringClass() == Object.class) { - continue; - } - - // skip check for default methods - non-abstract, interface methods - if (! Modifier.isAbstract(method.getModifiers())) { - continue; - } - - final Object obj = sobj.get(method.getName()); - if (! (obj instanceof ScriptFunction)) { - return false; - } - } - return true; - } - - private static boolean isOfContext(final Global global, final Context context) { - return global.isOfContext(context); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java deleted file mode 100644 index 47e05bf3acb..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.Version; - -/** - * JSR-223 compliant script engine factory for Nashorn. The engine answers for: - *
    - *
  • names {@code "nashorn"}, {@code "Nashorn"}, {@code "js"}, {@code "JS"}, {@code "JavaScript"}, - * {@code "javascript"}, {@code "ECMAScript"}, and {@code "ecmascript"};
  • - *
  • MIME types {@code "application/javascript"}, {@code "application/ecmascript"}, {@code "text/javascript"}, and - * {@code "text/ecmascript"};
  • - *
  • as well as for the extension {@code "js"}.
  • - *
- * Programs executing in engines created using {@link #getScriptEngine(String[])} will have the passed arguments - * accessible as a global variable named {@code "arguments"}. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public final class NashornScriptEngineFactory implements ScriptEngineFactory { - @Override - public String getEngineName() { - return (String) getParameter(ScriptEngine.ENGINE); - } - - @Override - public String getEngineVersion() { - return (String) getParameter(ScriptEngine.ENGINE_VERSION); - } - - @Override - public List getExtensions() { - return Collections.unmodifiableList(extensions); - } - - @Override - public String getLanguageName() { - return (String) getParameter(ScriptEngine.LANGUAGE); - } - - @Override - public String getLanguageVersion() { - return (String) getParameter(ScriptEngine.LANGUAGE_VERSION); - } - - @Override - public String getMethodCallSyntax(final String obj, final String method, final String... args) { - final StringBuilder sb = new StringBuilder(). - append(Objects.requireNonNull(obj)).append('.'). - append(Objects.requireNonNull(method)).append('('); - final int len = args.length; - - if (len > 0) { - sb.append(Objects.requireNonNull(args[0])); - } - for (int i = 1; i < len; i++) { - sb.append(',').append(Objects.requireNonNull(args[i])); - } - sb.append(')'); - - return sb.toString(); - } - - @Override - public List getMimeTypes() { - return Collections.unmodifiableList(mimeTypes); - } - - @Override - public List getNames() { - return Collections.unmodifiableList(names); - } - - @Override - public String getOutputStatement(final String toDisplay) { - return "print(" + toDisplay + ")"; - } - - @Override - public Object getParameter(final String key) { - switch (key) { - case ScriptEngine.NAME: - return "javascript"; - case ScriptEngine.ENGINE: - return "Oracle Nashorn"; - case ScriptEngine.ENGINE_VERSION: - return Version.version(); - case ScriptEngine.LANGUAGE: - return "ECMAScript"; - case ScriptEngine.LANGUAGE_VERSION: - return "ECMA - 262 Edition 5.1"; - case "THREADING": - // The engine implementation is not thread-safe. Can't be - // used to execute scripts concurrently on multiple threads. - return null; - default: - return null; - } - } - - @Override - public String getProgram(final String... statements) { - Objects.requireNonNull(statements); - final StringBuilder sb = new StringBuilder(); - - for (final String statement : statements) { - sb.append(Objects.requireNonNull(statement)).append(';'); - } - - return sb.toString(); - } - - // default options passed to Nashorn script engine - private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" }; - - @Override - public ScriptEngine getScriptEngine() { - try { - return new NashornScriptEngine(this, DEFAULT_OPTIONS, getAppClassLoader(), null); - } catch (final RuntimeException e) { - if (Context.DEBUG) { - e.printStackTrace(); - } - throw e; - } - } - - /** - * Create a new Script engine initialized with the given class loader. - * - * @param appLoader class loader to be used as script "app" class loader. - * @return newly created script engine. - * @throws SecurityException - * if the security manager's {@code checkPermission} - * denies {@code RuntimePermission("nashorn.setConfig")} - */ - public ScriptEngine getScriptEngine(final ClassLoader appLoader) { - return newEngine(DEFAULT_OPTIONS, appLoader, null); - } - - /** - * Create a new Script engine initialized with the given class filter. - * - * @param classFilter class filter to use. - * @return newly created script engine. - * @throws NullPointerException if {@code classFilter} is {@code null} - * @throws SecurityException - * if the security manager's {@code checkPermission} - * denies {@code RuntimePermission("nashorn.setConfig")} - */ - public ScriptEngine getScriptEngine(final ClassFilter classFilter) { - return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), Objects.requireNonNull(classFilter)); - } - - /** - * Create a new Script engine initialized with the given arguments. - * - * @param args arguments array passed to script engine. - * @return newly created script engine. - * @throws NullPointerException if {@code args} is {@code null} - * @throws SecurityException - * if the security manager's {@code checkPermission} - * denies {@code RuntimePermission("nashorn.setConfig")} - */ - public ScriptEngine getScriptEngine(final String... args) { - return newEngine(Objects.requireNonNull(args), getAppClassLoader(), null); - } - - /** - * Create a new Script engine initialized with the given arguments and the given class loader. - * - * @param args arguments array passed to script engine. - * @param appLoader class loader to be used as script "app" class loader. - * @return newly created script engine. - * @throws NullPointerException if {@code args} is {@code null} - * @throws SecurityException - * if the security manager's {@code checkPermission} - * denies {@code RuntimePermission("nashorn.setConfig")} - */ - public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) { - return newEngine(Objects.requireNonNull(args), appLoader, null); - } - - /** - * Create a new Script engine initialized with the given arguments, class loader and class filter. - * - * @param args arguments array passed to script engine. - * @param appLoader class loader to be used as script "app" class loader. - * @param classFilter class filter to use. - * @return newly created script engine. - * @throws NullPointerException if {@code args} or {@code classFilter} is {@code null} - * @throws SecurityException - * if the security manager's {@code checkPermission} - * denies {@code RuntimePermission("nashorn.setConfig")} - */ - public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { - return newEngine(Objects.requireNonNull(args), appLoader, Objects.requireNonNull(classFilter)); - } - - private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { - checkConfigPermission(); - try { - return new NashornScriptEngine(this, args, appLoader, classFilter); - } catch (final RuntimeException e) { - if (Context.DEBUG) { - e.printStackTrace(); - } - throw e; - } - } - - // -- Internals only below this point - - private static void checkConfigPermission() { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission(Context.NASHORN_SET_CONFIG)); - } - } - - private static final List names; - private static final List mimeTypes; - private static final List extensions; - - static { - names = immutableList( - "nashorn", "Nashorn", - "js", "JS", - "JavaScript", "javascript", - "ECMAScript", "ecmascript" - ); - - mimeTypes = immutableList( - "application/javascript", - "application/ecmascript", - "text/javascript", - "text/ecmascript" - ); - - extensions = immutableList("js"); - } - - private static List immutableList(final String... elements) { - return Collections.unmodifiableList(Arrays.asList(elements)); - } - - private static ClassLoader getAppClassLoader() { - // Revisit: script engine implementation needs the capability to - // find the class loader of the context in which the script engine - // is running so that classes will be found and loaded properly - final ClassLoader ccl = Thread.currentThread().getContextClassLoader(); - return (ccl == null)? NashornScriptEngineFactory.class.getClassLoader() : ccl; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java deleted file mode 100644 index 0e82a12cf91..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ /dev/null @@ -1,925 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.nio.ByteBuffer; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.Callable; -import javax.script.Bindings; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.ConsString; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ECMAException; -import jdk.nashorn.internal.runtime.JSONListAdapter; -import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.arrays.ArrayData; -import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; - -/** - * Mirror object that wraps a given Nashorn Script object. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public final class ScriptObjectMirror extends AbstractJSObject implements Bindings { - private static AccessControlContext getContextAccCtxt() { - final Permissions perms = new Permissions(); - perms.add(new RuntimePermission(Context.NASHORN_GET_CONTEXT)); - return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) }); - } - - private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt(); - - private final ScriptObject sobj; - private final Global global; - private final boolean strict; - private final boolean jsonCompatible; - - @Override - public boolean equals(final Object other) { - if (other instanceof ScriptObjectMirror) { - return sobj.equals(((ScriptObjectMirror)other).sobj); - } - - return false; - } - - @Override - public int hashCode() { - return sobj.hashCode(); - } - - @Override - public String toString() { - return inGlobal(new Callable() { - @Override - public String call() { - return ScriptRuntime.safeToString(sobj); - } - }); - } - - // JSObject methods - - @Override - public Object call(final Object thiz, final Object... args) { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - - try { - if (globalChanged) { - Context.setGlobal(global); - } - - if (sobj instanceof ScriptFunction) { - final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args; - final Object self = globalChanged? wrapLikeMe(thiz, oldGlobal) : thiz; - return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global))); - } - - throw new RuntimeException("not a function: " + toString()); - } catch (final NashornException ne) { - throw ne.initEcmaError(global); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - @Override - public Object newObject(final Object... args) { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - - try { - if (globalChanged) { - Context.setGlobal(global); - } - - if (sobj instanceof ScriptFunction) { - final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args; - return wrapLikeMe(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global))); - } - - throw new RuntimeException("not a constructor: " + toString()); - } catch (final NashornException ne) { - throw ne.initEcmaError(global); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - @Override - public Object eval(final String s) { - return inGlobal(new Callable() { - @Override - public Object call() { - final Context context = AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public Context run() { - return Context.getContext(); - } - }, GET_CONTEXT_ACC_CTXT); - return wrapLikeMe(context.eval(global, s, sobj, null)); - } - }); - } - - /** - * Call member function - * @param functionName function name - * @param args arguments - * @return return value of function - */ - public Object callMember(final String functionName, final Object... args) { - Objects.requireNonNull(functionName); - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - - try { - if (globalChanged) { - Context.setGlobal(global); - } - - final Object val = sobj.get(functionName); - if (val instanceof ScriptFunction) { - final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args; - return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global))); - } else if (val instanceof JSObject && ((JSObject)val).isFunction()) { - return ((JSObject)val).call(sobj, args); - } - - throw new NoSuchMethodException("No such function " + functionName); - } catch (final NashornException ne) { - throw ne.initEcmaError(global); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - @Override - public Object getMember(final String name) { - Objects.requireNonNull(name); - return inGlobal(new Callable() { - @Override public Object call() { - return wrapLikeMe(sobj.get(name)); - } - }); - } - - @Override - public Object getSlot(final int index) { - return inGlobal(new Callable() { - @Override public Object call() { - return wrapLikeMe(sobj.get(index)); - } - }); - } - - @Override - public boolean hasMember(final String name) { - Objects.requireNonNull(name); - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.has(name); - } - }); - } - - @Override - public boolean hasSlot(final int slot) { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.has(slot); - } - }); - } - - @Override - public void removeMember(final String name) { - remove(Objects.requireNonNull(name)); - } - - @Override - public void setMember(final String name, final Object value) { - put(Objects.requireNonNull(name), value); - } - - @Override - public void setSlot(final int index, final Object value) { - inGlobal(new Callable() { - @Override public Void call() { - sobj.set(index, unwrap(value, global), getCallSiteFlags()); - return null; - } - }); - } - - /** - * Nashorn extension: setIndexedPropertiesToExternalArrayData. - * set indexed properties be exposed from a given nio ByteBuffer. - * - * @param buf external buffer - should be a nio ByteBuffer - */ - public void setIndexedPropertiesToExternalArrayData(final ByteBuffer buf) { - inGlobal(new Callable() { - @Override public Void call() { - sobj.setArray(ArrayData.allocate(buf)); - return null; - } - }); - } - - @Override - public boolean isInstance(final Object instance) { - if (! (instance instanceof ScriptObjectMirror)) { - return false; - } - - final ScriptObjectMirror mirror = (ScriptObjectMirror)instance; - // if not belongs to my global scope, return false - if (global != mirror.global) { - return false; - } - - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isInstance(mirror.sobj); - } - }); - } - - @Override - public String getClassName() { - return sobj.getClassName(); - } - - @Override - public boolean isFunction() { - return sobj instanceof ScriptFunction; - } - - @Override - public boolean isStrictFunction() { - return isFunction() && ((ScriptFunction)sobj).isStrict(); - } - - @Override - public boolean isArray() { - return sobj.isArray(); - } - - // javax.script.Bindings methods - - @Override - public void clear() { - inGlobal(new Callable() { - @Override public Object call() { - sobj.clear(strict); - return null; - } - }); - } - - @Override - public boolean containsKey(final Object key) { - checkKey(key); - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.containsKey(key); - } - }); - } - - @Override - public boolean containsValue(final Object value) { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.containsValue(unwrap(value, global)); - } - }); - } - - @Override - public Set> entrySet() { - return inGlobal(new Callable>>() { - @Override public Set> call() { - final Iterator iter = sobj.propertyIterator(); - final Set> entries = new LinkedHashSet<>(); - - while (iter.hasNext()) { - final String key = iter.next(); - final Object value = translateUndefined(wrapLikeMe(sobj.get(key))); - entries.add(new AbstractMap.SimpleImmutableEntry<>(key, value)); - } - - return Collections.unmodifiableSet(entries); - } - }); - } - - @Override - public Object get(final Object key) { - checkKey(key); - return inGlobal(new Callable() { - @Override public Object call() { - return translateUndefined(wrapLikeMe(sobj.get(key))); - } - }); - } - - @Override - public boolean isEmpty() { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isEmpty(); - } - }); - } - - @Override - public Set keySet() { - return inGlobal(new Callable>() { - @Override public Set call() { - final Iterator iter = sobj.propertyIterator(); - final Set keySet = new LinkedHashSet<>(); - - while (iter.hasNext()) { - keySet.add(iter.next()); - } - - return Collections.unmodifiableSet(keySet); - } - }); - } - - @Override - public Object put(final String key, final Object value) { - checkKey(key); - final ScriptObject oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - return inGlobal(new Callable() { - @Override public Object call() { - final Object modValue = globalChanged? wrapLikeMe(value, oldGlobal) : value; - return translateUndefined(wrapLikeMe(sobj.put(key, unwrap(modValue, global), strict))); - } - }); - } - - @Override - public void putAll(final Map map) { - Objects.requireNonNull(map); - final ScriptObject oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - inGlobal(new Callable() { - @Override public Object call() { - for (final Map.Entry entry : map.entrySet()) { - final Object value = entry.getValue(); - final Object modValue = globalChanged? wrapLikeMe(value, oldGlobal) : value; - final String key = entry.getKey(); - checkKey(key); - sobj.set(key, unwrap(modValue, global), getCallSiteFlags()); - } - return null; - } - }); - } - - @Override - public Object remove(final Object key) { - checkKey(key); - return inGlobal(new Callable() { - @Override public Object call() { - return translateUndefined(wrapLikeMe(sobj.remove(key, strict))); - } - }); - } - - /** - * Delete a property from this object. - * - * @param key the property to be deleted - * - * @return if the delete was successful or not - */ - public boolean delete(final Object key) { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.delete(unwrap(key, global), strict); - } - }); - } - - @Override - public int size() { - return inGlobal(new Callable() { - @Override public Integer call() { - return sobj.size(); - } - }); - } - - @Override - public Collection values() { - return inGlobal(new Callable>() { - @Override public Collection call() { - final List values = new ArrayList<>(size()); - final Iterator iter = sobj.valueIterator(); - - while (iter.hasNext()) { - values.add(translateUndefined(wrapLikeMe(iter.next()))); - } - - return Collections.unmodifiableList(values); - } - }); - } - - // Support for ECMAScript Object API on mirrors - - /** - * Return the __proto__ of this object. - * @return __proto__ object. - */ - public Object getProto() { - return inGlobal(new Callable() { - @Override public Object call() { - return wrapLikeMe(sobj.getProto()); - } - }); - } - - /** - * Set the __proto__ of this object. - * @param proto new proto for this object - */ - public void setProto(final Object proto) { - inGlobal(new Callable() { - @Override public Void call() { - sobj.setPrototypeOf(unwrap(proto, global)); - return null; - } - }); - } - - /** - * ECMA 8.12.1 [[GetOwnProperty]] (P) - * - * @param key property key - * - * @return Returns the Property Descriptor of the named own property of this - * object, or undefined if absent. - */ - public Object getOwnPropertyDescriptor(final String key) { - return inGlobal(new Callable() { - @Override public Object call() { - return wrapLikeMe(sobj.getOwnPropertyDescriptor(key)); - } - }); - } - - /** - * return an array of own property keys associated with the object. - * - * @param all True if to include non-enumerable keys. - * @return Array of keys. - */ - public String[] getOwnKeys(final boolean all) { - return inGlobal(new Callable() { - @Override public String[] call() { - return sobj.getOwnKeys(all); - } - }); - } - - /** - * Flag this script object as non extensible - * - * @return the object after being made non extensible - */ - public ScriptObjectMirror preventExtensions() { - return inGlobal(new Callable() { - @Override public ScriptObjectMirror call() { - sobj.preventExtensions(); - return ScriptObjectMirror.this; - } - }); - } - - /** - * Check if this script object is extensible - * @return true if extensible - */ - public boolean isExtensible() { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isExtensible(); - } - }); - } - - /** - * ECMAScript 15.2.3.8 - seal implementation - * @return the sealed script object - */ - public ScriptObjectMirror seal() { - return inGlobal(new Callable() { - @Override public ScriptObjectMirror call() { - sobj.seal(); - return ScriptObjectMirror.this; - } - }); - } - - /** - * Check whether this script object is sealed - * @return true if sealed - */ - public boolean isSealed() { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isSealed(); - } - }); - } - - /** - * ECMA 15.2.39 - freeze implementation. Freeze this script object - * @return the frozen script object - */ - public ScriptObjectMirror freeze() { - return inGlobal(new Callable() { - @Override public ScriptObjectMirror call() { - sobj.freeze(); - return ScriptObjectMirror.this; - } - }); - } - - /** - * Check whether this script object is frozen - * @return true if frozen - */ - public boolean isFrozen() { - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isFrozen(); - } - }); - } - - /** - * Utility to check if given object is ECMAScript undefined value - * - * @param obj object to check - * @return true if 'obj' is ECMAScript undefined value - */ - public static boolean isUndefined(final Object obj) { - return obj == ScriptRuntime.UNDEFINED; - } - - /** - * Utility to convert this script object to the given type. - * - * @param destination type to convert to - * @param type destination type to convert to - * @return converted object - */ - public T to(final Class type) { - return inGlobal(new Callable() { - @Override - public T call() { - return type.cast(ScriptUtils.convert(sobj, type)); - } - }); - } - - /** - * Make a script object mirror on given object if needed. - * - * @param obj object to be wrapped/converted - * @param homeGlobal global to which this object belongs. - * @return wrapped/converted object - */ - public static Object wrap(final Object obj, final Object homeGlobal) { - return wrap(obj, homeGlobal, false); - } - - /** - * Make a script object mirror on given object if needed. The created wrapper will implement - * the Java {@code List} interface if {@code obj} is a JavaScript {@code Array} object; - * this is compatible with Java JSON libraries expectations. Arrays retrieved through its - * properties (transitively) will also implement the list interface. - * - * @param obj object to be wrapped/converted - * @param homeGlobal global to which this object belongs. - * @return wrapped/converted object - */ - public static Object wrapAsJSONCompatible(final Object obj, final Object homeGlobal) { - return wrap(obj, homeGlobal, true); - } - - /** - * Make a script object mirror on given object if needed. - * - * @param obj object to be wrapped/converted - * @param homeGlobal global to which this object belongs. - * @param jsonCompatible if true, the created wrapper will implement the Java {@code List} interface if - * {@code obj} is a JavaScript {@code Array} object. Arrays retrieved through its properties (transitively) - * will also implement the list interface. - * @return wrapped/converted object - */ - private static Object wrap(final Object obj, final Object homeGlobal, final boolean jsonCompatible) { - if(obj instanceof ScriptObject) { - if (!(homeGlobal instanceof Global)) { - return obj; - } - final ScriptObject sobj = (ScriptObject)obj; - final Global global = (Global)homeGlobal; - final ScriptObjectMirror mirror = new ScriptObjectMirror(sobj, global, jsonCompatible); - if (jsonCompatible && sobj.isArray()) { - return new JSONListAdapter(mirror, global); - } - return mirror; - } else if(obj instanceof ConsString) { - return obj.toString(); - } else if (jsonCompatible && obj instanceof ScriptObjectMirror) { - // Since choosing JSON compatible representation is an explicit decision on user's part, if we're asked to - // wrap a mirror that was not JSON compatible, explicitly create its compatible counterpart following the - // principle of least surprise. - return ((ScriptObjectMirror)obj).asJSONCompatible(); - } - return obj; - } - - /** - * Wraps the passed object with the same jsonCompatible flag as this mirror. - * @param obj the object - * @param homeGlobal the object's home global. - * @return a wrapper for the object. - */ - private Object wrapLikeMe(final Object obj, final Object homeGlobal) { - return wrap(obj, homeGlobal, jsonCompatible); - } - - /** - * Wraps the passed object with the same home global and jsonCompatible flag as this mirror. - * @param obj the object - * @return a wrapper for the object. - */ - private Object wrapLikeMe(final Object obj) { - return wrapLikeMe(obj, global); - } - - /** - * Unwrap a script object mirror if needed. - * - * @param obj object to be unwrapped - * @param homeGlobal global to which this object belongs - * @return unwrapped object - */ - public static Object unwrap(final Object obj, final Object homeGlobal) { - if (obj instanceof ScriptObjectMirror) { - final ScriptObjectMirror mirror = (ScriptObjectMirror)obj; - return (mirror.global == homeGlobal)? mirror.sobj : obj; - } else if (obj instanceof JSONListAdapter) { - return ((JSONListAdapter)obj).unwrap(homeGlobal); - } - - return obj; - } - - /** - * Wrap an array of object to script object mirrors if needed. - * - * @param args array to be unwrapped - * @param homeGlobal global to which this object belongs - * @return wrapped array - */ - public static Object[] wrapArray(final Object[] args, final Object homeGlobal) { - return wrapArray(args, homeGlobal, false); - } - - private static Object[] wrapArray(final Object[] args, final Object homeGlobal, final boolean jsonCompatible) { - if (args == null || args.length == 0) { - return args; - } - - final Object[] newArgs = new Object[args.length]; - int index = 0; - for (final Object obj : args) { - newArgs[index] = wrap(obj, homeGlobal, jsonCompatible); - index++; - } - return newArgs; - } - - private Object[] wrapArrayLikeMe(final Object[] args, final Object homeGlobal) { - return wrapArray(args, homeGlobal, jsonCompatible); - } - - /** - * Unwrap an array of script object mirrors if needed. - * - * @param args array to be unwrapped - * @param homeGlobal global to which this object belongs - * @return unwrapped array - */ - public static Object[] unwrapArray(final Object[] args, final Object homeGlobal) { - if (args == null || args.length == 0) { - return args; - } - - final Object[] newArgs = new Object[args.length]; - int index = 0; - for (final Object obj : args) { - newArgs[index] = unwrap(obj, homeGlobal); - index++; - } - return newArgs; - } - - /** - * Are the given objects mirrors to same underlying object? - * - * @param obj1 first object - * @param obj2 second object - * @return true if obj1 and obj2 are identical script objects or mirrors of it. - */ - public static boolean identical(final Object obj1, final Object obj2) { - final Object o1 = (obj1 instanceof ScriptObjectMirror)? - ((ScriptObjectMirror)obj1).sobj : obj1; - - final Object o2 = (obj2 instanceof ScriptObjectMirror)? - ((ScriptObjectMirror)obj2).sobj : obj2; - - return o1 == o2; - } - - // package-privates below this. - - ScriptObjectMirror(final ScriptObject sobj, final Global global) { - this(sobj, global, false); - } - - private ScriptObjectMirror(final ScriptObject sobj, final Global global, final boolean jsonCompatible) { - assert sobj != null : "ScriptObjectMirror on null!"; - assert global != null : "home Global is null"; - - this.sobj = sobj; - this.global = global; - this.strict = global.isStrictContext(); - this.jsonCompatible = jsonCompatible; - } - - // accessors for script engine - ScriptObject getScriptObject() { - return sobj; - } - - Global getHomeGlobal() { - return global; - } - - static Object translateUndefined(final Object obj) { - return (obj == ScriptRuntime.UNDEFINED)? null : obj; - } - - private int getCallSiteFlags() { - return strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; - } - - // internals only below this. - private V inGlobal(final Callable callable) { - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - if (globalChanged) { - Context.setGlobal(global); - } - try { - return callable.call(); - } catch (final NashornException ne) { - throw ne.initEcmaError(global); - } catch (final RuntimeException e) { - throw e; - } catch (final Exception e) { - throw new AssertionError("Cannot happen", e); - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - } - - /** - * Ensures the key is not null, empty string, or a non-String object. The contract of the {@link Bindings} - * interface requires that these are not accepted as keys. - * @param key the key to check - * @throws NullPointerException if key is null - * @throws ClassCastException if key is not a String - * @throws IllegalArgumentException if key is empty string - */ - private static void checkKey(final Object key) { - Objects.requireNonNull(key, "key can not be null"); - - if (!(key instanceof String)) { - throw new ClassCastException("key should be a String. It is " + key.getClass().getName() + " instead."); - } else if (((String)key).length() == 0) { - throw new IllegalArgumentException("key can not be empty"); - } - } - - @Override @Deprecated - public double toNumber() { - return inGlobal(new Callable() { - @Override public Double call() { - return JSType.toNumber(sobj); - } - }); - } - - @Override - public Object getDefaultValue(final Class hint) { - return inGlobal(new Callable() { - @Override public Object call() { - try { - return sobj.getDefaultValue(hint); - } catch (final ECMAException e) { - // We're catching ECMAException (likely TypeError), and translating it to - // UnsupportedOperationException. This in turn will be translated into TypeError of the - // caller's Global by JSType#toPrimitive(JSObject,Class) therefore ensuring that it's - // recognized as "instanceof TypeError" in the caller. - throw new UnsupportedOperationException(e.getMessage(), e); - } - } - }); - } - - private ScriptObjectMirror asJSONCompatible() { - if (this.jsonCompatible) { - return this; - } - return new ScriptObjectMirror(sobj, global, true); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java deleted file mode 100644 index 7859131c62d..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.lang.invoke.MethodHandle; -import jdk.dynalink.beans.StaticClass; -import jdk.dynalink.linker.LinkerServices; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.linker.Bootstrap; - -/** - * Utilities that are to be called from script code. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public final class ScriptUtils { - private ScriptUtils() {} - - /** - * Returns AST as JSON compatible string. This is used to - * implement "parse" function in resources/parse.js script. - * - * @param code code to be parsed - * @param name name of the code source (used for location) - * @param includeLoc tells whether to include location information for nodes or not - * @return JSON string representation of AST of the supplied code - */ - public static String parse(final String code, final String name, final boolean includeLoc) { - return ScriptRuntime.parse(code, name, includeLoc); - } - - /** - * Method which converts javascript types to java types for the - * String.format method (jrunscript function sprintf). - * - * @param format a format string - * @param args arguments referenced by the format specifiers in format - * @return a formatted string - */ - public static String format(final String format, final Object[] args) { - return Formatter.format(format, args); - } - - /** - * Create a wrapper function that calls {@code func} synchronized on {@code sync} or, if that is undefined, - * {@code self}. Used to implement "sync" function in resources/mozilla_compat.js. - * - * @param func the function to wrap - * @param sync the object to synchronize on - * @return a synchronizing wrapper function - * @throws IllegalArgumentException if func does not represent a script function - */ - public static Object makeSynchronizedFunction(final Object func, final Object sync) { - final Object unwrapped = unwrap(func); - if (unwrapped instanceof ScriptFunction) { - return ((ScriptFunction)unwrapped).createSynchronized(unwrap(sync)); - } - - throw new IllegalArgumentException(); - } - - /** - * Make a script object mirror on given object if needed. - * - * @param obj object to be wrapped - * @return wrapped object - * @throws IllegalArgumentException if obj cannot be wrapped - */ - public static ScriptObjectMirror wrap(final Object obj) { - if (obj instanceof ScriptObjectMirror) { - return (ScriptObjectMirror)obj; - } - - if (obj instanceof ScriptObject) { - final ScriptObject sobj = (ScriptObject)obj; - return (ScriptObjectMirror) ScriptObjectMirror.wrap(sobj, Context.getGlobal()); - } - - throw new IllegalArgumentException(); - } - - /** - * Unwrap a script object mirror if needed. - * - * @param obj object to be unwrapped - * @return unwrapped object - */ - public static Object unwrap(final Object obj) { - if (obj instanceof ScriptObjectMirror) { - return ScriptObjectMirror.unwrap(obj, Context.getGlobal()); - } - - return obj; - } - - /** - * Wrap an array of object to script object mirrors if needed. - * - * @param args array to be unwrapped - * @return wrapped array - */ - public static Object[] wrapArray(final Object[] args) { - if (args == null || args.length == 0) { - return args; - } - - return ScriptObjectMirror.wrapArray(args, Context.getGlobal()); - } - - /** - * Unwrap an array of script object mirrors if needed. - * - * @param args array to be unwrapped - * @return unwrapped array - */ - public static Object[] unwrapArray(final Object[] args) { - if (args == null || args.length == 0) { - return args; - } - - return ScriptObjectMirror.unwrapArray(args, Context.getGlobal()); - } - - /** - * Convert the given object to the given type. - * - * @param obj object to be converted - * @param type destination type to convert to. type is either a Class - * or nashorn representation of a Java type returned by Java.type() call in script. - * @return converted object - */ - public static Object convert(final Object obj, final Object type) { - if (obj == null) { - return null; - } - - final Class clazz; - if (type instanceof Class) { - clazz = (Class)type; - } else if (type instanceof StaticClass) { - clazz = ((StaticClass)type).getRepresentedClass(); - } else { - throw new IllegalArgumentException("type expected"); - } - - final LinkerServices linker = Bootstrap.getLinkerServices(); - final Object objToConvert = unwrap(obj); - final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(), clazz); - if (converter == null) { - // no supported conversion! - throw new UnsupportedOperationException("conversion not supported"); - } - - try { - return converter.invoke(objToConvert); - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/URLReader.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/URLReader.java deleted file mode 100644 index 3383e66f5c0..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/URLReader.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.io.CharArrayReader; -import java.io.IOException; -import java.io.Reader; -import java.net.URL; -import java.nio.charset.Charset; -import java.util.Objects; -import jdk.nashorn.internal.runtime.Source; - -/** - * A Reader that reads from a URL. Used to make sure that the reader - * reads content from given URL and can be trusted to do so. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 1.8u40 - */ -@Deprecated(since="11", forRemoval=true) -public final class URLReader extends Reader { - // underlying URL - private final URL url; - // Charset used to convert - private final Charset cs; - - // lazily initialized underlying reader for URL - private Reader reader; - - /** - * Constructor - * - * @param url URL for this URLReader - * @throws NullPointerException if url is null - */ - public URLReader(final URL url) { - this(url, (Charset)null); - } - - /** - * Constructor - * - * @param url URL for this URLReader - * @param charsetName Name of the Charset used to convert bytes to chars - * @throws NullPointerException if url is null - */ - public URLReader(final URL url, final String charsetName) { - this(url, Charset.forName(charsetName)); - } - - /** - * Constructor - * - * @param url URL for this URLReader - * @param cs Charset used to convert bytes to chars - * @throws NullPointerException if url is null - */ - public URLReader(final URL url, final Charset cs) { - this.url = Objects.requireNonNull(url); - this.cs = cs; - } - - @Override - public int read(final char cbuf[], final int off, final int len) throws IOException { - return getReader().read(cbuf, off, len); - } - - @Override - public void close() throws IOException { - getReader().close(); - } - - /** - * URL of this reader - * @return the URL from which this reader reads. - */ - public URL getURL() { - return url; - } - - /** - * Charset used by this reader - * - * @return the Charset used to convert bytes to chars - */ - public Charset getCharset() { - return cs; - } - - // lazily initialize char array reader using URL content - private Reader getReader() throws IOException { - synchronized (lock) { - if (reader == null) { - reader = new CharArrayReader(Source.readFully(url, cs)); - } - } - - return reader; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/package-info.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/package-info.java deleted file mode 100644 index 95781bddb5c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/package-info.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * This package provides the {@code javax.script} integration, which is the preferred way to use Nashorn. - * You will ordinarily do this to obtain an instance of a Nashorn script engine: - *
- * import javax.script.*;
- * ...
- * ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn");
- * 
- *

Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable} - * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. In addition, - * this package provides nashorn specific extension classes, interfaces and methods. See - * {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details. - * - * @since 1.8u40 - */ -package jdk.nashorn.api.scripting; diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/resources/Messages.properties b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/resources/Messages.properties deleted file mode 100644 index 10bd88f1b9d..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/resources/Messages.properties +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -thiz.cannot.be.null=script object 'this' for getMethod, getInterface calls can not be null -interface.class.expected=interface Class expected in getInterface -interface.on.non.script.object=getInterface cannot be called on non-script object -no.current.nashorn.global=no current Global instance for nashorn -implementing.non.public.interface=Cannot implement non-public interface: {0} -script.object.from.another.engine=Script object belongs to another script engine - diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTree.java deleted file mode 100644 index d1554ebc283..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayAccessTree.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an array access expression. - * - * For example: - *

- *   expression [ index ]
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ArrayAccessTree extends ExpressionTree { - /** - * Returns the array that is accessed. - * - * @return the array that is accessed - */ - ExpressionTree getExpression(); - - /** - * Returns the index of the array element accessed. - * - * @return the index expression - */ - ExpressionTree getIndex(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTree.java deleted file mode 100644 index 048f48dafb5..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTree.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * Represents ECMAScript array literal expression. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ArrayLiteralTree extends ExpressionTree { - /** - * Returns the list of Array element expressions. - * - * @return array element expressions - */ - public List getElements(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTreeImpl.java deleted file mode 100644 index e690324508b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ArrayLiteralTreeImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.LiteralNode; - -final class ArrayLiteralTreeImpl extends ExpressionTreeImpl - implements ArrayLiteralTree { - private final List elements; - ArrayLiteralTreeImpl(final LiteralNode node, final List elements) { - super(node); - this.elements = elements; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.ARRAY_LITERAL; - } - - @Override - public List getElements() { - return elements; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitArrayLiteral(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTree.java deleted file mode 100644 index c87eabbae56..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTree.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an assignment expression. - * - * For example: - *
- *   variable = expression
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface AssignmentTree extends ExpressionTree { - /** - * Returns the left hand side (LHS) of this assignment. - * - * @return left hand side (LHS) expression - */ - ExpressionTree getVariable(); - - /** - * Returns the right hand side (RHS) of this assignment. - * - * @return right hand side (RHS) expression - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTreeImpl.java deleted file mode 100644 index 94ef39962ed..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/AssignmentTreeImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.BinaryNode; - -final class AssignmentTreeImpl extends ExpressionTreeImpl implements AssignmentTree { - private final Tree.Kind kind; - private final ExpressionTree var, expr; - - AssignmentTreeImpl(final BinaryNode node, final ExpressionTree left, final ExpressionTree right) { - super(node); - assert node.isAssignment() : "assignment node expected"; - this.var = left; - this.expr = right; - this.kind = getOperator(node.tokenType()); - } - - @Override - public Tree.Kind getKind() { - return kind; - } - - @Override - public ExpressionTree getVariable() { - return var; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitAssignment(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTree.java deleted file mode 100644 index 61fcfa775e6..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTree.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a binary expression. - * Use {@link #getKind getKind} to determine the kind of operator. - * - * For example: - *
- *   leftOperand operator rightOperand
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface BinaryTree extends ExpressionTree { - /** - * Returns left hand side (LHS) of this binary expression. - * - * @return left hand side (LHS) of this binary expression - */ - ExpressionTree getLeftOperand(); - - /** - * Returns right hand side (RHS) of this binary expression. - * - * @return right hand side (RHS) of this binary expression - */ - ExpressionTree getRightOperand(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTreeImpl.java deleted file mode 100644 index cad9db2ac5b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BinaryTreeImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.BinaryNode; - -class BinaryTreeImpl extends ExpressionTreeImpl implements BinaryTree { - private final Tree.Kind kind; - private final ExpressionTree left, right; - - BinaryTreeImpl(final BinaryNode node, final ExpressionTree left, final ExpressionTree right) { - super(node); - assert !node.isAssignment() : "assignment node"; - this.left = left; - this.right = right; - this.kind = getOperator(node.tokenType()); - } - - @Override - public Tree.Kind getKind() { - return kind; - } - - @Override - public ExpressionTree getLeftOperand() { - return left; - } - - @Override - public ExpressionTree getRightOperand() { - return right; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitBinary(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTree.java deleted file mode 100644 index aa04fad0661..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTree.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a statement block. - * - * For example: - *
- *   { }
- *
- *   { statements }
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface BlockTree extends StatementTree { - /** - * Returns the list of statements in this block. - * - * @return the list of statements in this block - */ - List getStatements(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTreeImpl.java deleted file mode 100644 index c74a0eaa099..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BlockTreeImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.BlockStatement; - -final class BlockTreeImpl extends StatementTreeImpl implements BlockTree { - private final List statements; - - BlockTreeImpl(final BlockStatement node, final List statements) { - super(node); - this.statements = statements; - } - - BlockTreeImpl(final Block node, final List statements) { - super(node); - this.statements = statements; - } - - @Override - public Kind getKind() { - return Kind.BLOCK; - } - - @Override - public List getStatements() { - return statements; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitBlock(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTree.java deleted file mode 100644 index 5e797539cf5..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/BreakTree.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'break' statement. - * - * For example: - *
- *   break;
- *
- *   break label ;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface BreakTree extends GotoTree { - /** - * Label associated with this break statement. This is null - * if there is no label associated with this break statement. - * - * @return label associated with this break statement. - */ - @Override - String getLabel(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTree.java deleted file mode 100644 index d5d4524d5df..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTree.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a 'case' in a 'switch' statement. - * - * For example: - *
- *   case expression :
- *       statements
- *
- *   default :
- *       statements
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface CaseTree extends Tree { - /** - * Case expression of this 'case' statement. - * - * @return null if and only if this Case is {@code default:} - */ - ExpressionTree getExpression(); - - /** - * Return the list of statements for this 'case'. - * - * @return list of statements for this 'case' - */ - List getStatements(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTreeImpl.java deleted file mode 100644 index 4f12f413ec5..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CaseTreeImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.CaseNode; - -final class CaseTreeImpl extends TreeImpl implements CaseTree { - private final ExpressionTree expression; - private final List statements; - - public CaseTreeImpl(final CaseNode node, - final ExpressionTree expression, - final List statements) { - super(node); - this.expression = expression; - this.statements = statements; - } - - @Override - public Kind getKind() { - return Kind.CASE; - } - - @Override - public ExpressionTree getExpression() { - return expression; - } - - @Override - public List getStatements() { - return statements; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitCase(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTree.java deleted file mode 100644 index a3ed5bd25ce..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTree.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'catch' block in a 'try' statement. - * - * For example: - *
- *   catch ( parameter )
- *       block
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface CatchTree extends Tree { - /** - * Returns the catch parameter identifier or parameter binding pattern of the exception caught. - * - * @return the catch parameter identifier or parameter binding pattern - */ - ExpressionTree getParameter(); - - /** - * Returns the code block of this catch block. - * - * @return the code block - */ - BlockTree getBlock(); - - /** - * Returns the optional catch condition expression. This is null - * if this is an unconditional catch statement. - * - * @return the optional catch condition expression. - */ - ExpressionTree getCondition(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTreeImpl.java deleted file mode 100644 index f392d59ad25..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CatchTreeImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.CatchNode; - -final class CatchTreeImpl extends TreeImpl implements CatchTree { - private final ExpressionTree param; - private final BlockTree block; - private final ExpressionTree condition; - - CatchTreeImpl(final CatchNode node, - final ExpressionTree param, - final BlockTree block, - final ExpressionTree condition) { - super(node); - this.param = param; - this.block = block; - this.condition = condition; - } - - @Override - public Kind getKind() { - return Kind.CATCH; - } - - @Override - public ExpressionTree getParameter() { - return param; - } - - @Override - public BlockTree getBlock() { - return block; - } - - @Override - public ExpressionTree getCondition() { - return condition; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitCatch(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTree.java deleted file mode 100644 index cf2571f2b96..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTree.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node that represents a class declaration. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ClassDeclarationTree extends StatementTree { - - /** - * Class identifier. - * - * @return the class identifier - */ - IdentifierTree getName(); - - /** - * The expression of the {@code extends} clause. Optional. - * - * @return the class heritage - */ - ExpressionTree getClassHeritage(); - - /** - * Get the constructor method definition. - * - * @return the constructor - */ - PropertyTree getConstructor(); - - /** - * Get other property definitions except for the constructor. - * - * @return the class elements - */ - List getClassElements(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTreeImpl.java deleted file mode 100644 index 824f677483b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassDeclarationTreeImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.VarNode; - -final class ClassDeclarationTreeImpl extends StatementTreeImpl implements ClassDeclarationTree { - - private final IdentifierTree name; - private final ExpressionTree classHeritage; - private final PropertyTree constructor; - private final List classElements; - - ClassDeclarationTreeImpl(final VarNode node, final IdentifierTree name, - final ExpressionTree classHeritage, final PropertyTree constructor, - final List classElements) { - super(node); - this.name = name; - this.classHeritage = classHeritage; - this.constructor = constructor; - this.classElements = classElements; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.CLASS; - } - - @Override - public IdentifierTree getName() { - return name; - } - - @Override - public ExpressionTree getClassHeritage() { - return classHeritage; - } - - @Override - public PropertyTree getConstructor() { - return constructor; - } - - @Override - public List getClassElements() { - return classElements; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitClassDeclaration(this, data); - } -} \ No newline at end of file diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTree.java deleted file mode 100644 index ec693d45ba7..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTree.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node that represents a class expression. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ClassExpressionTree extends ExpressionTree { - /** - * Class identifier. Optional. - * - * @return the class identifier - */ - IdentifierTree getName(); - - /** - * The expression of the {@code extends} clause. Optional. - * - * @return the class heritage - */ - ExpressionTree getClassHeritage(); - - /** - * Get the constructor method definition. - * - * @return the constructor - */ - PropertyTree getConstructor(); - - /** - * Get other property definitions except for the constructor. - * - * @return the class elements - */ - List getClassElements(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTreeImpl.java deleted file mode 100644 index c4108c969c5..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ClassExpressionTreeImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.ClassNode; - -final class ClassExpressionTreeImpl extends ExpressionTreeImpl implements ClassExpressionTree { - - private final IdentifierTree name; - private final ExpressionTree classHeritage; - private final PropertyTree constructor; - private final List classElements; - - ClassExpressionTreeImpl(final ClassNode cn, final IdentifierTree name, - final ExpressionTree classHeritage, final PropertyTree constructor, - final List classElements) { - super(cn); - this.name = name; - this.classHeritage = classHeritage; - this.constructor = constructor; - this.classElements = classElements; - } - - @Override - public Kind getKind() { - return Kind.CLASS_EXPRESSION; - } - - @Override - public IdentifierTree getName() { - return name; - } - - @Override - public ExpressionTree getClassHeritage() { - return classHeritage; - } - - @Override - public PropertyTree getConstructor() { - return constructor; - } - - @Override - public List getClassElements() { - return classElements; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitClassExpression(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTree.java deleted file mode 100644 index fb424b76737..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTree.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * Represents the abstract syntax tree for compilation units (source - * files) - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface CompilationUnitTree extends Tree { - /** - * Return the list of source elements in this compilation unit. - * - * @return the list of source elements in this compilation unit - */ - List getSourceElements(); - - /** - * Return the source name of this script compilation unit. - * - * @return the source name of this script compilation unit - */ - String getSourceName(); - - /** - * Returns if this is a ECMAScript "strict" compilation unit or not. - * - * @return true if this compilation unit is declared "strict" - */ - boolean isStrict(); - - /** - * Returns the line map for this compilation unit, if available. - * Returns null if the line map is not available. - * - * @return the line map for this compilation unit - */ - LineMap getLineMap(); - - /** - * Return the {@link ModuleTree} associated with this compilation unit. This is null, - * if there is no module information from this compilation unit. - * - * @return the Module info or null - */ - ModuleTree getModule(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTreeImpl.java deleted file mode 100644 index 552a4c5816e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompilationUnitTreeImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.FunctionNode; - -final class CompilationUnitTreeImpl extends TreeImpl - implements CompilationUnitTree { - private final FunctionNode funcNode; - private final List elements; - private final ModuleTree module; - - CompilationUnitTreeImpl(final FunctionNode node, - final List elements, - final ModuleTree module) { - super(node); - this.funcNode = node; - assert funcNode.getKind() == FunctionNode.Kind.SCRIPT || - funcNode.getKind() == FunctionNode.Kind.MODULE : - "script or module function expected"; - this.elements = elements; - this.module = module; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.COMPILATION_UNIT; - } - - @Override - public List getSourceElements() { - return elements; - } - - @Override - public String getSourceName() { - return funcNode.getSourceName(); - } - - @Override - public boolean isStrict() { - return funcNode.isStrict(); - } - - @Override - public LineMap getLineMap() { - return new LineMapImpl(funcNode.getSource()); - } - - @Override - public ModuleTree getModule() { - return module; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitCompilationUnit(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTree.java deleted file mode 100644 index 53d70be4060..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTree.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for compound assignment operator. - * Use {@link #getKind getKind} to determine the kind of operator. - * - * For example: - *
- *   variable operator expression
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface CompoundAssignmentTree extends ExpressionTree { - /** - * Returns the left hand side (LHS) of this assignment. - * - * @return left hand side (LHS) expression - */ - ExpressionTree getVariable(); - - /** - * Returns the right hand side (RHS) of this assignment. - * - * @return right hand side (RHS) expression - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTreeImpl.java deleted file mode 100644 index 3916377de9b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/CompoundAssignmentTreeImpl.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.BinaryNode; - -final class CompoundAssignmentTreeImpl extends ExpressionTreeImpl implements CompoundAssignmentTree { - - private final ExpressionTree var, expr; - private final Kind kind; - - CompoundAssignmentTreeImpl(final BinaryNode node, final ExpressionTree left, final ExpressionTree right) { - super(node); - assert node.isAssignment() : "not an assignment node"; - this.var = left; - this.expr = right; - this.kind = getOperator(node.tokenType()); - assert kind != Tree.Kind.ASSIGNMENT : "compound assignment expected"; - } - - @Override - public Kind getKind() { - return kind; - } - - @Override - public ExpressionTree getVariable() { - return var; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitCompoundAssignment(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTree.java deleted file mode 100644 index 5f90b61b43b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTree.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for the conditional operator ? :. - * - * For example: - *
- *   condition ? trueExpression : falseExpression
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ConditionalExpressionTree extends ExpressionTree { - /** - * Returns the condition expression of this ternary expression. - * - * @return the condition expression - */ - ExpressionTree getCondition(); - - /** - * Returns the true part of this ternary expression. - * - * @return the 'true' part expression - */ - ExpressionTree getTrueExpression(); - - /** - * Returns the false part of this ternary expression. - * - * @return the 'false' part expression - */ - ExpressionTree getFalseExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTreeImpl.java deleted file mode 100644 index 152c61086ff..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalExpressionTreeImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.TernaryNode; - -final class ConditionalExpressionTreeImpl extends ExpressionTreeImpl implements ConditionalExpressionTree { - private final ExpressionTree condExpr, trueExpr, falseExpr; - - ConditionalExpressionTreeImpl(final TernaryNode node, - final ExpressionTree condExpr, final ExpressionTree trueExpr, - final ExpressionTree falseExpr) { - super(node); - this.condExpr = condExpr; - this.trueExpr = trueExpr; - this.falseExpr = falseExpr; - - } - - @Override - public Kind getKind() { - return Kind.CONDITIONAL_EXPRESSION; - } - - @Override - public ExpressionTree getCondition() { - return condExpr; - } - - @Override - public ExpressionTree getTrueExpression() { - return trueExpr; - } - - @Override - public ExpressionTree getFalseExpression() { - return falseExpr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitConditionalExpression(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalLoopTree.java deleted file mode 100644 index ef5ac559310..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ConditionalLoopTree.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A mixin for conditional "loop" statements. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ConditionalLoopTree extends LoopTree { - /** - * Returns the condition expression of this 'loop' statement. - * - * @return the condition expression - */ - ExpressionTree getCondition(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTree.java deleted file mode 100644 index 28b4f9f8485..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTree.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'continue' statement. - * - * For example: - *
- *   continue;
- *   continue label ;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ContinueTree extends GotoTree { - /** - * Label associated with this continue statement. This is null - * if there is no label associated with this continue statement. - * - * @return label associated with this continue statement. - */ - @Override - String getLabel(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTreeImpl.java deleted file mode 100644 index b974cb7350a..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ContinueTreeImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ContinueNode; - -final class ContinueTreeImpl extends StatementTreeImpl implements ContinueTree { - private final String label; - - ContinueTreeImpl(final ContinueNode node) { - super(node); - this.label = node.getLabelName(); - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.CONTINUE; - } - - @Override - public String getLabel() { - return label; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitContinue(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTree.java deleted file mode 100644 index 052b0b7d632..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTree.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'debugger' statement. - * - * For example: - *
- *     debugger;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface DebuggerTree extends StatementTree { -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTreeImpl.java deleted file mode 100644 index 45eda3ed124..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DebuggerTreeImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.DebuggerNode; - -final class DebuggerTreeImpl extends StatementTreeImpl implements DebuggerTree { - DebuggerTreeImpl(final DebuggerNode node) { - super(node); - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.DEBUGGER; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitDebugger(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DestructuringDeclTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DestructuringDeclTreeImpl.java deleted file mode 100644 index c6963019655..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DestructuringDeclTreeImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ExpressionStatement; -import jdk.nashorn.internal.parser.TokenType; - -// This implementation of VariableTree represents a destructuring declaration -final class DestructuringDeclTreeImpl extends StatementTreeImpl - implements VariableTree { - - private final TokenType declType; - private final ExpressionTree lhs; - private final ExpressionTree init; - - DestructuringDeclTreeImpl(final ExpressionStatement exprStat, final ExpressionTree lhs, final ExpressionTree init) { - super(exprStat); - assert exprStat.destructuringDeclarationType() != null : "expecting a destructuring decl. statement"; - - this.declType = exprStat.destructuringDeclarationType(); - this.lhs = lhs; - this.init = init; - } - - @Override - public Kind getKind() { - return Kind.VARIABLE; - } - - @Override - public ExpressionTree getBinding() { - return lhs; - } - - @Override - public ExpressionTree getInitializer() { - return init; - } - - @Override - public boolean isConst() { - return declType == TokenType.CONST; - } - - @Override - public boolean isLet() { - return declType == TokenType.LET; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitVariable(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Diagnostic.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Diagnostic.java deleted file mode 100644 index 0528c333a49..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Diagnostic.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * Interface for diagnostics from tools. A diagnostic usually reports - * a problem at a specific position in a source file. However, not - * all diagnostics are associated with a position or a file. - * - *

A position is a zero-based character offset from the beginning of - * a file. Negative values (except {@link #NOPOS}) are not valid - * positions. - * - *

Line and column numbers begin at 1. Negative values (except - * {@link #NOPOS}) and 0 are not valid line or column numbers. - * - *

Line terminator is as defined in ECMAScript specification which is one - * of { \u000A, \u000B, \u2028, \u2029 }. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface Diagnostic { - - /** - * Kinds of diagnostics, for example, error or warning. - * - * The kind of a diagnostic can be used to determine how the - * diagnostic should be presented to the user. For example, - * errors might be colored red or prefixed with the word "Error", - * while warnings might be colored yellow or prefixed with the - * word "Warning". There is no requirement that the Kind - * should imply any inherent semantic meaning to the message - * of the diagnostic: for example, a tool might provide an - * option to report all warnings as errors. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ - @Deprecated(since="11", forRemoval=true) - enum Kind { - /** - * Problem which prevents the tool's normal completion. - */ - ERROR, - /** - * Problem which does not usually prevent the tool from - * completing normally. - */ - WARNING, - /** - * Problem similar to a warning, but is mandated by the tool's - * specification. For example, the Java™ Language - * Specification mandates warnings on certain - * unchecked operations and the use of deprecated methods. - */ - MANDATORY_WARNING, - /** - * Informative message from the tool. - */ - NOTE, - /** - * Diagnostic which does not fit within the other kinds. - */ - OTHER, - } - - /** - * Used to signal that no position is available. - */ - public final static long NOPOS = -1; - - /** - * Gets the kind of this diagnostic, for example, error or - * warning. - * @return the kind of this diagnostic - */ - Kind getKind(); - - /** - * Gets a character offset from the beginning of the source object - * associated with this diagnostic that indicates the location of - * the problem. In addition, the following must be true: - * - *

{@code getStartPostion() <= getPosition()} - *

{@code getPosition() <= getEndPosition()} - * - * @return character offset from beginning of source; {@link - * #NOPOS} if no location is suitable - */ - long getPosition(); - - /** - * Gets the source file name. - * - * @return the file name or null if not available - */ - String getFileName(); - - /** - * Gets the line number of the character offset returned by - * {@linkplain #getPosition()}. - * - * @return a line number or {@link #NOPOS} if and only if {@link - * #getPosition()} returns {@link #NOPOS} - */ - long getLineNumber(); - - /** - * Gets the column number of the character offset returned by - * {@linkplain #getPosition()}. - * - * @return a column number or {@link #NOPOS} if and only if {@link - * #getPosition()} returns {@link #NOPOS} - */ - long getColumnNumber(); - - /** - * Gets a diagnostic code indicating the type of diagnostic. The - * code is implementation-dependent and might be {@code null}. - * - * @return a diagnostic code - */ - String getCode(); - - /** - * Gets a message for this diagnostic. - * - * @return a message - */ - String getMessage(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticImpl.java deleted file mode 100644 index ee4eadf7f9b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticImpl.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.parser.Token; -import jdk.nashorn.internal.runtime.ParserException; - -final class DiagnosticImpl implements Diagnostic { - private final ParserException exp; - private final Kind kind; - - DiagnosticImpl(final ParserException exp, final Kind kind) { - this.exp = exp; - this.kind = kind; - } - - @Override - public Kind getKind() { - return kind; - } - - @Override - public long getPosition() { - return exp.getPosition(); - } - - @Override - public String getFileName() { - return exp.getFileName(); - } - - @Override - public long getLineNumber() { - return exp.getLineNumber(); - } - - @Override - public long getColumnNumber() { - return exp.getColumnNumber(); - } - - @Override - public String getCode() { - final long token = exp.getToken(); - return (token < 0)? null : Token.toString(null, token, true); - } - - @Override - public String getMessage() { - return exp.getMessage(); - } - - @Override - public String toString() { - return getMessage(); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticListener.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticListener.java deleted file mode 100644 index 8c3d3bbff60..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DiagnosticListener.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * Interface for receiving diagnostics from Nashorn parser. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -@FunctionalInterface -public interface DiagnosticListener { - /** - * Invoked whenever a parsing problem is found. - * - * @param diagnostic additional information errors, warnings detected during parsing. - */ - void report(Diagnostic diagnostic); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTree.java deleted file mode 100644 index 96d08644e1c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTree.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'do' statement. - * - * For example: - *

- *   do
- *       statement
- *   while ( expression );
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface DoWhileLoopTree extends ConditionalLoopTree { - /** - * Returns the condition expression of this do-while statement. - * - * @return the condition expression - */ - @Override - ExpressionTree getCondition(); - - /** - * The statement contained within this do-while statement. - * - * @return the statement - */ - @Override - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTreeImpl.java deleted file mode 100644 index a86ca9d5273..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/DoWhileLoopTreeImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.WhileNode; - -final class DoWhileLoopTreeImpl extends StatementTreeImpl implements DoWhileLoopTree { - private final ExpressionTree cond; - private final StatementTree stat; - - DoWhileLoopTreeImpl(final WhileNode node, final ExpressionTree cond, final StatementTree stat) { - super(node); - assert node.isDoWhile() : "do while expected"; - this.cond = cond; - this.stat = stat; - } - - @Override - public Kind getKind() { - return Kind.DO_WHILE_LOOP; - } - - @Override - public ExpressionTree getCondition() { - return cond; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitDoWhileLoop(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTree.java deleted file mode 100644 index 6de96b5559b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTree.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an empty (skip) statement. - * - * For example: - *
- *    ;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface EmptyStatementTree extends StatementTree {} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTreeImpl.java deleted file mode 100644 index c5d689dc94f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/EmptyStatementTreeImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.EmptyNode; - -final class EmptyStatementTreeImpl extends StatementTreeImpl implements EmptyStatementTree { - EmptyStatementTreeImpl(final EmptyNode node) { - super(node); - } - - @Override - public Kind getKind() { - return Kind.EMPTY_STATEMENT; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitEmptyStatement(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTree.java deleted file mode 100644 index 79b9c6c3151..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTree.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node to stand in for a malformed expression. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ErroneousTree extends ExpressionTree { -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTreeImpl.java deleted file mode 100644 index bee4feeab00..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ErroneousTreeImpl.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ErrorNode; - -final class ErroneousTreeImpl extends ExpressionTreeImpl implements ErroneousTree { - ErroneousTreeImpl(final ErrorNode errorNode) { - super(errorNode); - } - - @Override - public Kind getKind() { - return Kind.ERROR; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitErroneous(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTree.java deleted file mode 100644 index d6c96c1d5ef..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTree.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A Tree node for export entry in Module information. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ -@Deprecated(since="11", forRemoval=true) -public interface ExportEntryTree extends Tree { - /** - * Returns the entry's export name. - * - * @return the export name - */ - public IdentifierTree getExportName(); - - /** - * Returns the entry's module request. - * - * @return the module request - */ - public IdentifierTree getModuleRequest(); - - /** - * Returns the entry's import name. - * - * @return the import name - */ - public IdentifierTree getImportName(); - - /** - * Returns the entry's local name. - * - * @return the local name - */ - public IdentifierTree getLocalName(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTreeImpl.java deleted file mode 100644 index 04d2ead5745..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExportEntryTreeImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; -import java.util.stream.Collectors; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.Module; -import static jdk.nashorn.api.tree.ModuleTreeImpl.identOrNull; - -final class ExportEntryTreeImpl extends TreeImpl implements ExportEntryTree { - private final long startPos, endPos; - private final IdentifierTree exportName; - private final IdentifierTree moduleRequest; - private final IdentifierTree importName; - private final IdentifierTree localName; - - private ExportEntryTreeImpl(final long startPos, final long endPos, - final IdentifierTree exportName, - final IdentifierTree moduleRequest, - final IdentifierTree importName, - final IdentifierTree localName) { - super(null); // no underlying Node! - this.startPos = startPos; - this.endPos = endPos; - this.exportName = exportName; - this.moduleRequest = moduleRequest; - this.importName = importName; - this.localName = localName; - } - - private static ExportEntryTreeImpl createExportEntry(final Module.ExportEntry entry) { - return new ExportEntryTreeImpl(entry.getStartPosition(), - entry.getEndPosition(), - identOrNull(entry.getExportName()), - identOrNull(entry.getModuleRequest()), - identOrNull(entry.getImportName()), - identOrNull(entry.getLocalName())); - } - - static List createExportList(final List exportList) { - return exportList.stream(). - map(ExportEntryTreeImpl::createExportEntry). - collect(Collectors.toList()); - } - - @Override - public Kind getKind() { - return Tree.Kind.EXPORT_ENTRY; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitExportEntry(this, data); - } - - @Override - public long getStartPosition() { - return startPos; - } - - @Override - public long getEndPosition() { - return endPos; - } - - @Override - public IdentifierTree getExportName() { - return exportName; - } - - @Override - public IdentifierTree getModuleRequest() { - return moduleRequest; - } - - @Override - public IdentifierTree getImportName() { - return importName; - } - - @Override - public IdentifierTree getLocalName() { - return localName; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTree.java deleted file mode 100644 index d7bbd28ab8e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTree.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an expression statement. - * - * For example: - *
- *   expression ;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ExpressionStatementTree extends StatementTree { - /** - * Returns the expression of this expression statement. - * - * @return the expression - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTreeImpl.java deleted file mode 100644 index a3a602f3e61..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionStatementTreeImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ExpressionStatement; - -final class ExpressionStatementTreeImpl extends StatementTreeImpl implements ExpressionStatementTree { - private final ExpressionTree expr; - - ExpressionStatementTreeImpl(final ExpressionStatement es, final ExpressionTree expr) { - super(es); - this.expr = expr; - } - - @Override - public Kind getKind() { - return Kind.EXPRESSION_STATEMENT; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitExpressionStatement(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTree.java deleted file mode 100644 index 69752f1d193..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTree.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node used as the base class for the different types of - * expressions. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ExpressionTree extends Tree {} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTreeImpl.java deleted file mode 100644 index 3024f51ea8d..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ExpressionTreeImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.Expression; - -abstract class ExpressionTreeImpl extends TreeImpl implements ExpressionTree { - ExpressionTreeImpl(final Expression expr) { - super(expr); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTree.java deleted file mode 100644 index c34c64fcc1f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTree.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for for..in statement - * - * For example: - *
- *   for ( variable in expression )
- *       statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ForInLoopTree extends LoopTree { - /** - * The for..in left hand side expression. - * - * @return the left hand side expression - */ - ExpressionTree getVariable(); - - /** - * The object or array being whose properties are iterated. - * - * @return the object or array expression being iterated - */ - ExpressionTree getExpression(); - - /** - * The statement contained in this for..in statement. - * - * @return the statement - */ - @Override - StatementTree getStatement(); - - /** - * Returns if this is a for..each..in statement or not. - * - * @return true if this is a for..each..in statement - */ - boolean isForEach(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTreeImpl.java deleted file mode 100644 index 3ba38eb757e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForInLoopTreeImpl.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ForNode; - -final class ForInLoopTreeImpl extends StatementTreeImpl implements ForInLoopTree { - private final ExpressionTree lhsExpr; - private final ExpressionTree expr; - private final StatementTree stat; - private final boolean forEach; - - ForInLoopTreeImpl(final ForNode node, - final ExpressionTree lhsExpr, - final ExpressionTree expr, - final StatementTree stat) { - super(node); - assert node.isForIn() : "for ..in expected"; - this.lhsExpr = lhsExpr; - this.expr = expr; - this.stat = stat; - this.forEach = node.isForEach(); - } - - @Override - public Kind getKind() { - return Kind.FOR_IN_LOOP; - } - - @Override - public ExpressionTree getVariable() { - return lhsExpr; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public boolean isForEach() { - return forEach; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitForInLoop(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTree.java deleted file mode 100644 index d9466463f97..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTree.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a basic 'for' loop statement. - * - * For example: - *
- *   for ( initializer ; condition ; update )
- *       statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ForLoopTree extends ConditionalLoopTree { - /** - * Returns the initializer expression of this 'for' statement. - * - * @return the initializer expression - */ - ExpressionTree getInitializer(); - - /** - * Returns the condition expression of this 'for' statement. - * - * @return the condition expression - */ - @Override - ExpressionTree getCondition(); - - /** - * Returns the update expression of this 'for' statement. - * - * @return the update expression - */ - ExpressionTree getUpdate(); - - /** - * Returns the statement contained in this 'for' statement. - * - * @return the statement - */ - @Override - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTreeImpl.java deleted file mode 100644 index 4cedbe19eed..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForLoopTreeImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ForNode; - -final class ForLoopTreeImpl extends StatementTreeImpl implements ForLoopTree { - private final ExpressionTree init; - private final ExpressionTree cond; - private final ExpressionTree update; - private final StatementTree stat; - - ForLoopTreeImpl(final ForNode node, - final ExpressionTree init, - final ExpressionTree cond, - final ExpressionTree update, - final StatementTree stat) { - super(node); - assert !node.isForIn() : "for statement expected"; - this.init = init; - this.cond = cond; - this.update = update; - this.stat = stat; - } - - @Override - public Kind getKind() { - return Kind.FOR_LOOP; - } - - @Override - public ExpressionTree getInitializer() { - return init; - } - - @Override - public ExpressionTree getCondition() { - return cond; - } - - @Override - public ExpressionTree getUpdate() { - return update; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitForLoop(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTree.java deleted file mode 100644 index b6dd4241712..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTree.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for for..of statement. - * - * For example: - *
- *   for ( variable of expression )
- *       statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ForOfLoopTree extends LoopTree { - /** - * The for..of left hand side expression. - * - * @return the left hand side expression - */ - ExpressionTree getVariable(); - - /** - * The object or array being whose properties are iterated. - * - * @return the object or array expression being iterated - */ - ExpressionTree getExpression(); - - /** - * The statement contained in this for..of statement. - * - * @return the statement - */ - @Override - StatementTree getStatement(); -} - diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTreeImpl.java deleted file mode 100644 index e2306e51c1e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ForOfLoopTreeImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ForNode; - -final class ForOfLoopTreeImpl extends StatementTreeImpl implements ForOfLoopTree { - private final ExpressionTree lhsExpr; - private final ExpressionTree expr; - private final StatementTree stat; - - ForOfLoopTreeImpl(final ForNode node, - final ExpressionTree lhsExpr, - final ExpressionTree expr, - final StatementTree stat) { - super(node); - assert node.isForIn() : "for ..in expected"; - this.lhsExpr = lhsExpr; - this.expr = expr; - this.stat = stat; - } - - @Override - public Kind getKind() { - return Kind.FOR_IN_LOOP; - } - - @Override - public ExpressionTree getVariable() { - return lhsExpr; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitForOfLoop(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTree.java deleted file mode 100644 index 713a21fd497..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTree.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a function call expression. - * - * For example: - *
- *   identifier ( arguments )
- *
- *   this . identifier ( arguments )
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface FunctionCallTree extends ExpressionTree { - /** - * Returns the function being called. - * - * @return the function being called - */ - ExpressionTree getFunctionSelect(); - - /** - * Returns the list of arguments being passed to this function call. - * - * @return the list of argument expressions - */ - List getArguments(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTreeImpl.java deleted file mode 100644 index aaeb930d1b8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionCallTreeImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.CallNode; - -class FunctionCallTreeImpl extends ExpressionTreeImpl implements FunctionCallTree { - private final List arguments; - private final ExpressionTree function; - FunctionCallTreeImpl(final CallNode node, - final ExpressionTree function, - final List arguments) { - super(node); - this.function = function; - this.arguments = arguments; - } - - @Override - public Kind getKind() { - return Kind.FUNCTION_INVOCATION; - } - - @Override - public ExpressionTree getFunctionSelect() { - return function; - } - - @Override - public List getArguments() { - return arguments; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitFunctionCall(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTree.java deleted file mode 100644 index 19442de1f98..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTree.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a function declaration. - * - * For example: - *
- *   function name
- *      ( parameters )
- *      body
- * 
- * - *
- *   function* name
- *      ( parameters )
- *      body
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface FunctionDeclarationTree extends StatementTree { - /** - * Returns the name of the function being declared. - * - * @return name the function declared - */ - IdentifierTree getName(); - - /** - * Returns the parameters of this function. - * - * @return the list of parameters - */ - List getParameters(); - - /** - * Returns the body of code of this function. - * - * @return the body of code - */ - BlockTree getBody(); - - /** - * Is this a strict function? - * - * @return true if this function is strict - */ - boolean isStrict(); - - /** - * Is this a generator function? - * - * @return true if this is a generator function - */ - boolean isGenerator(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTreeImpl.java deleted file mode 100644 index 592e4dce9ea..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionDeclarationTreeImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.VarNode; - -final class FunctionDeclarationTreeImpl extends StatementTreeImpl - implements FunctionDeclarationTree { - private final FunctionNode funcNode; - private final IdentifierTree funcName; - private final List params; - private final BlockTree body; - - FunctionDeclarationTreeImpl(final VarNode node, - final List params, - final BlockTree body) { - super(node); - assert node.getInit() instanceof FunctionNode : "function expected"; - funcNode = (FunctionNode)node.getInit(); - assert funcNode.isDeclared() : "function declaration expected"; - funcName = funcNode.isAnonymous()? null : new IdentifierTreeImpl(node.getName()); - this.params = params; - this.body = body; - } - - @Override - public Kind getKind() { - return Kind.FUNCTION; - } - - @Override - public IdentifierTree getName() { - return funcName; - } - - @Override - public List getParameters() { - return params; - } - - @Override - public BlockTree getBody() { - return body; - } - - @Override - public boolean isStrict() { - return funcNode.isStrict(); - } - - @Override - public boolean isGenerator() { - return funcNode.getKind() == FunctionNode.Kind.GENERATOR; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitFunctionDeclaration(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTree.java deleted file mode 100644 index 07e931f0526..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTree.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for function expressions including arrow functions. - * - * For example: - *
- *   var func = function
- *      ( parameters )
- *      body
- * 
- * - *
- *   var func = (x) => x+1
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface FunctionExpressionTree extends ExpressionTree { - /** - * Returns the name of the function being declared. - * - * @return name the function declared - */ - IdentifierTree getName(); - - /** - * Returns the parameters of this function. - * - * @return the list of parameters - */ - List getParameters(); - - /** - * Returns the body of this function. This may be a {@link BlockTree} when this - * function has a block body. This is an {@link ExpressionTree} when the function body - * is a concise expression as in an expression arrow, or in an expression closure. - * - * @return the body of this function - */ - Tree getBody(); - - /** - * Is this a strict function? - * - * @return true if this function is strict - */ - boolean isStrict(); - - /** - * Is this a arrow function? - * - * @return true if this is a arrow function - */ - boolean isArrow(); - - /** - * Is this a generator function? - * - * @return true if this is a generator function - */ - boolean isGenerator(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTreeImpl.java deleted file mode 100644 index 57b060b6464..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/FunctionExpressionTreeImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.FunctionNode; - -final class FunctionExpressionTreeImpl extends ExpressionTreeImpl - implements FunctionExpressionTree { - private final FunctionNode funcNode; - private final IdentifierTree funcName; - private final List params; - private final Tree body; - - FunctionExpressionTreeImpl(final FunctionNode node, - final List params, - final BlockTree body) { - super(node); - funcNode = node; - assert !funcNode.isDeclared() || funcNode.isAnonymous() : "function expression expected"; - - final FunctionNode.Kind kind = node.getKind(); - if (node.isAnonymous() || kind == FunctionNode.Kind.GETTER || kind == FunctionNode.Kind.SETTER) { - funcName = null; - } else { - funcName = new IdentifierTreeImpl(node.getIdent()); - } - - this.params = params; - if (node.getFlag(FunctionNode.HAS_EXPRESSION_BODY)) { - final StatementTree first = body.getStatements().get(0); - assert first instanceof ReturnTree : "consise func. expression should have a return statement"; - this.body = ((ReturnTree)first).getExpression(); - } else { - this.body = body; - } - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.FUNCTION_EXPRESSION; - } - - @Override - public IdentifierTree getName() { - return funcName; - } - - @Override - public List getParameters() { - return params; - } - - @Override - public Tree getBody() { - return body; - } - - @Override - public boolean isStrict() { - return funcNode.isStrict(); - } - - @Override - public boolean isArrow() { - return funcNode.getKind() == FunctionNode.Kind.ARROW; - } - - @Override - public boolean isGenerator() { - return funcNode.getKind() == FunctionNode.Kind.GENERATOR; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitFunctionExpression(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/GotoTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/GotoTree.java deleted file mode 100644 index c23ede97a98..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/GotoTree.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a statement that jumps to a target. Note that - * ECMAScript does not support a goto statement. But, this Tree - * type serves as a super interface for {@link BreakTree} and - * {@link ContinueTree}. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface GotoTree extends StatementTree { - /** - * Label associated with this goto statement. This is null - * if there is no label associated with this goto statement. - * - * @return label associated with this goto statement. - */ - String getLabel(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java deleted file mode 100644 index 55bedf37b5c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IRTranslator.java +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.BlockStatement; -import jdk.nashorn.internal.ir.BreakNode; -import jdk.nashorn.internal.ir.CallNode; -import jdk.nashorn.internal.ir.CaseNode; -import jdk.nashorn.internal.ir.CatchNode; -import jdk.nashorn.internal.ir.ClassNode; -import jdk.nashorn.internal.ir.ContinueNode; -import jdk.nashorn.internal.ir.DebuggerNode; -import jdk.nashorn.internal.ir.EmptyNode; -import jdk.nashorn.internal.ir.ErrorNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.ExpressionStatement; -import jdk.nashorn.internal.ir.ForNode; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IfNode; -import jdk.nashorn.internal.ir.IndexNode; -import jdk.nashorn.internal.ir.LabelNode; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ObjectNode; -import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReturnNode; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.SplitNode; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.SwitchNode; -import jdk.nashorn.internal.ir.TemplateLiteral; -import jdk.nashorn.internal.ir.TernaryNode; -import jdk.nashorn.internal.ir.ThrowNode; -import jdk.nashorn.internal.ir.TryNode; -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.VarNode; -import jdk.nashorn.internal.ir.WhileNode; -import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor; -import jdk.nashorn.internal.parser.Lexer; -import jdk.nashorn.internal.parser.TokenType; - -/** - * This class translates from nashorn IR Node objects - * to nashorn parser API Tree objects. - */ -final class IRTranslator extends SimpleNodeVisitor { - - public IRTranslator() { - } - - // currently translated Statement - private StatementTreeImpl curStat; - // currently translated Expression - private ExpressionTreeImpl curExpr; - - // entry point for translator - CompilationUnitTree translate(final FunctionNode node) { - if (node == null) { - return null; - } - - assert node.getKind() == FunctionNode.Kind.SCRIPT || - node.getKind() == FunctionNode.Kind.MODULE : - "script or module function expected"; - - final Block body = node.getBody(); - return new CompilationUnitTreeImpl(node, - translateStats(body != null? getOrderedStatements(body.getStatements()) : null), - translateModule(node)); - } - - @Override - public boolean enterAccessNode(final AccessNode accessNode) { - curExpr = new MemberSelectTreeImpl(accessNode, translateExpr(accessNode.getBase())); - return false; - } - - @Override - public boolean enterBlock(final Block block) { - return handleBlock(block, false); - } - - @Override - public boolean enterBinaryNode(final BinaryNode binaryNode) { - if (binaryNode.isAssignment()) { - final ExpressionTree srcTree = translateExpr(binaryNode.getAssignmentSource()); - final ExpressionTree destTree = translateExpr(binaryNode.getAssignmentDest()); - - if (binaryNode.isTokenType(TokenType.ASSIGN)) { - curExpr = new AssignmentTreeImpl(binaryNode, destTree, srcTree); - } else { - curExpr = new CompoundAssignmentTreeImpl(binaryNode, destTree, srcTree); - } - } else { - final ExpressionTree leftTree = translateExpr(binaryNode.lhs()); - final ExpressionTree rightTree = translateExpr(binaryNode.rhs()); - - if (binaryNode.isTokenType(TokenType.INSTANCEOF)) { - curExpr = new InstanceOfTreeImpl(binaryNode, leftTree, rightTree); - } else { - curExpr = new BinaryTreeImpl(binaryNode, leftTree, rightTree); - } - } - - return false; - } - - @Override - public boolean enterBreakNode(final BreakNode breakNode) { - curStat = new BreakTreeImpl(breakNode); - return false; - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - curExpr = null; - callNode.getFunction().accept(this); - final ExpressionTree funcTree = curExpr; - final List argTrees = translateExprs(callNode.getArgs()); - curExpr = new FunctionCallTreeImpl(callNode, funcTree, argTrees); - return false; - } - - @Override - public boolean enterCaseNode(final CaseNode caseNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterCatchNode(final CatchNode catchNode) { - assert false : "should not reach here"; - return false; - } - - @Override - public boolean enterContinueNode(final ContinueNode continueNode) { - curStat = new ContinueTreeImpl(continueNode); - return false; - } - - @Override - public boolean enterDebuggerNode(final DebuggerNode debuggerNode) { - curStat = new DebuggerTreeImpl(debuggerNode); - return false; - } - - @Override - public boolean enterEmptyNode(final EmptyNode emptyNode) { - curStat = new EmptyStatementTreeImpl(emptyNode); - return false; - } - - @Override - public boolean enterErrorNode(final ErrorNode errorNode) { - curExpr = new ErroneousTreeImpl(errorNode); - return false; - } - - @Override - public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { - if (expressionStatement.destructuringDeclarationType() != null) { - final ExpressionTree expr = translateExpr(expressionStatement.getExpression()); - assert expr instanceof AssignmentTree : "destructuring decl. statement does not have assignment"; - final AssignmentTree assign = (AssignmentTree)expr; - curStat = new DestructuringDeclTreeImpl(expressionStatement, assign.getVariable(), assign.getExpression()); - } else { - curStat = new ExpressionStatementTreeImpl(expressionStatement, - translateExpr(expressionStatement.getExpression())); - } - return false; - } - - @Override - public boolean enterBlockStatement(final BlockStatement blockStatement) { - final Block block = blockStatement.getBlock(); - if (blockStatement.isSynthetic()) { - assert block != null && block.getStatements() != null && block.getStatements().size() == 1; - curStat = translateStat(block.getStatements().get(0)); - } else { - curStat = new BlockTreeImpl(blockStatement, - translateStats(block != null? block.getStatements() : null)); - } - return false; - } - - @Override - public boolean enterForNode(final ForNode forNode) { - if (forNode.isForIn()) { - curStat = new ForInLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } else if (forNode.isForOf()) { - curStat = new ForOfLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } else { - curStat = new ForLoopTreeImpl(forNode, - translateExpr(forNode.getInit()), - translateExpr(forNode.getTest()), - translateExpr(forNode.getModify()), - translateBlock(forNode.getBody())); - } - - return false; - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - assert !functionNode.isDeclared() || functionNode.isAnonymous() : "should not reach here for function declaration"; - - final List paramTrees = translateParameters(functionNode); - final BlockTree blockTree = (BlockTree) translateBlock(functionNode.getBody(), true); - curExpr = new FunctionExpressionTreeImpl(functionNode, paramTrees, blockTree); - - return false; - } - - @Override - public boolean enterIdentNode(final IdentNode identNode) { - curExpr = new IdentifierTreeImpl(identNode); - return false; - } - - @Override - public boolean enterIfNode(final IfNode ifNode) { - curStat = new IfTreeImpl(ifNode, - translateExpr(ifNode.getTest()), - translateBlock(ifNode.getPass()), - translateBlock(ifNode.getFail())); - return false; - } - - @Override - public boolean enterIndexNode(final IndexNode indexNode) { - curExpr = new ArrayAccessTreeImpl(indexNode, - translateExpr(indexNode.getBase()), - translateExpr(indexNode.getIndex())); - return false; - } - - @Override - public boolean enterLabelNode(final LabelNode labelNode) { - curStat = new LabeledStatementTreeImpl(labelNode, - translateBlock(labelNode.getBody())); - return false; - } - - @Override - public boolean enterLiteralNode(final LiteralNode literalNode) { - final Object value = literalNode.getValue(); - if (value instanceof Lexer.RegexToken) { - curExpr = new RegExpLiteralTreeImpl(literalNode); - } else if (literalNode.isArray()) { - final List exprNodes = literalNode.getElementExpressions(); - final List exprTrees = new ArrayList<>(exprNodes.size()); - for (final Node node : exprNodes) { - if (node == null) { - exprTrees.add(null); - } else { - curExpr = null; - node.accept(this); - assert curExpr != null : "null for " + node; - exprTrees.add(curExpr); - } - } - curExpr = new ArrayLiteralTreeImpl(literalNode, exprTrees); - } else { - curExpr = new LiteralTreeImpl(literalNode); - } - - return false; - } - - @Override - public boolean enterObjectNode(final ObjectNode objectNode) { - final List propNodes = objectNode.getElements(); - final List propTrees = translateProperties(propNodes); - curExpr = new ObjectLiteralTreeImpl(objectNode, propTrees); - return false; - } - - @Override - public boolean enterPropertyNode(final PropertyNode propertyNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterReturnNode(final ReturnNode returnNode) { - curStat = new ReturnTreeImpl(returnNode, - translateExpr(returnNode.getExpression())); - return false; - } - - @Override - public boolean enterRuntimeNode(final RuntimeNode runtimeNode) { - assert false : "should not reach here: RuntimeNode"; - return false; - } - - @Override - public boolean enterSplitNode(final SplitNode splitNode) { - assert false : "should not reach here!"; - return false; - } - - @Override - public boolean enterSwitchNode(final SwitchNode switchNode) { - final List caseNodes = switchNode.getCases(); - final List caseTrees = new ArrayList<>(caseNodes.size()); - for (final CaseNode caseNode : caseNodes) { - final Block body = caseNode.getBody(); - caseTrees.add( - new CaseTreeImpl(caseNode, - translateExpr(caseNode.getTest()), - translateStats(body != null? body.getStatements() : null))); - } - - curStat = new SwitchTreeImpl(switchNode, - translateExpr(switchNode.getExpression()), - caseTrees); - return false; - } - - @Override - public boolean enterTemplateLiteral(final TemplateLiteral templateLiteral) { - curExpr = new TemplateLiteralTreeImpl(templateLiteral, translateExprs(templateLiteral.getExpressions())); - return false; - } - - @Override - public boolean enterTernaryNode(final TernaryNode ternaryNode) { - curExpr = new ConditionalExpressionTreeImpl(ternaryNode, - translateExpr(ternaryNode.getTest()), - translateExpr(ternaryNode.getTrueExpression()), - translateExpr(ternaryNode.getFalseExpression())); - return false; - } - - @Override - public boolean enterThrowNode(final ThrowNode throwNode) { - curStat = new ThrowTreeImpl(throwNode, - translateExpr(throwNode.getExpression())); - return false; - } - - @Override - public boolean enterTryNode(final TryNode tryNode) { - final List catchNodes = tryNode.getCatches(); - final List catchTrees = new ArrayList<>(catchNodes.size()); - for (final CatchNode catchNode : catchNodes) { - catchTrees.add(new CatchTreeImpl(catchNode, - translateExpr(catchNode.getException()), - (BlockTree) translateBlock(catchNode.getBody()), - translateExpr(catchNode.getExceptionCondition()))); - } - - curStat = new TryTreeImpl(tryNode, - (BlockTree) translateBlock(tryNode.getBody()), - catchTrees, - (BlockTree) translateBlock(tryNode.getFinallyBody())); - - return false; - } - - @Override - public boolean enterUnaryNode(final UnaryNode unaryNode) { - if (unaryNode.isTokenType(TokenType.NEW)) { - curExpr = new NewTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else if (unaryNode.isTokenType(TokenType.YIELD) || - unaryNode.isTokenType(TokenType.YIELD_STAR)) { - curExpr = new YieldTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else if (unaryNode.isTokenType(TokenType.SPREAD_ARGUMENT) || - unaryNode.isTokenType(TokenType.SPREAD_ARRAY)) { - curExpr = new SpreadTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } else { - curExpr = new UnaryTreeImpl(unaryNode, - translateExpr(unaryNode.getExpression())); - } - return false; - } - - @Override - public boolean enterVarNode(final VarNode varNode) { - final Expression initNode = varNode.getInit(); - if (initNode instanceof FunctionNode && ((FunctionNode)initNode).isDeclared()) { - final FunctionNode funcNode = (FunctionNode) initNode; - - final List paramTrees = translateParameters(funcNode); - final BlockTree blockTree = (BlockTree) translateBlock(funcNode.getBody(), true); - curStat = new FunctionDeclarationTreeImpl(varNode, paramTrees, blockTree); - } else if (initNode instanceof ClassNode && ((ClassNode)initNode).isStatement()) { - final ClassNode classNode = (ClassNode) initNode; - - curStat = new ClassDeclarationTreeImpl(varNode, - translateIdent(classNode.getIdent()), - translateExpr(classNode.getClassHeritage()), - translateProperty(classNode.getConstructor()), - translateProperties(classNode.getClassElements())); - } else { - curStat = new VariableTreeImpl(varNode, translateIdent(varNode.getName()), translateExpr(initNode)); - } - - return false; - } - - @Override - public boolean enterWhileNode(final WhileNode whileNode) { - final ExpressionTree condTree = translateExpr(whileNode.getTest()); - final StatementTree statTree = translateBlock(whileNode.getBody()); - - if (whileNode.isDoWhile()) { - curStat = new DoWhileLoopTreeImpl(whileNode, condTree, statTree); - } else { - curStat = new WhileLoopTreeImpl(whileNode, condTree, statTree); - } - - return false; - } - - @Override - public boolean enterWithNode(final WithNode withNode) { - curStat = new WithTreeImpl(withNode, - translateExpr(withNode.getExpression()), - translateBlock(withNode.getBody())); - - return false; - } - - /** - * Callback for entering a ClassNode - * - * @param classNode the node - * @return true if traversal should continue and node children be traversed, false otherwise - */ - @Override - public boolean enterClassNode(final ClassNode classNode) { - assert !classNode.isStatement(): "should not reach here for class declaration"; - final IdentNode className = classNode.getIdent(); - curExpr = new ClassExpressionTreeImpl(classNode, - className != null? translateIdent(className) : null, - translateExpr(classNode.getClassHeritage()), - translateProperty(classNode.getConstructor()), - translateProperties(classNode.getClassElements())); - - return false; - } - - private StatementTree translateBlock(final Block blockNode) { - return translateBlock(blockNode, false); - } - - private StatementTree translateBlock(final Block blockNode, final boolean sortStats) { - if (blockNode == null) { - return null; - } - curStat = null; - handleBlock(blockNode, sortStats); - return curStat; - } - - private boolean handleBlock(final Block block, final boolean sortStats) { - // FIXME: revisit this! - if (block.isSynthetic()) { - final int statCount = block.getStatementCount(); - switch (statCount) { - case 0: { - final EmptyNode emptyNode = new EmptyNode(-1, block.getToken(), block.getFinish()); - curStat = new EmptyStatementTreeImpl(emptyNode); - return false; - } - case 1: { - curStat = translateStat(block.getStatements().get(0)); - return false; - } - default: { - // fall through - break; - } - } - } - - final List stats = block.getStatements(); - curStat = new BlockTreeImpl(block, - translateStats(sortStats? getOrderedStatements(stats) : stats)); - return false; - } - - private List getOrderedStatements(final List stats) { - final List statList = new ArrayList<>(stats); - statList.sort(Comparator.comparingInt(Node::getSourceOrder)); - return statList; - } - - private List translateStats(final List stats) { - if (stats == null) { - return null; - } - final List statTrees = new ArrayList<>(stats.size()); - for (final Statement stat : stats) { - curStat = null; - stat.accept(this); - assert curStat != null; - statTrees.add(curStat); - } - return statTrees; - } - - private List translateParameters(final FunctionNode func) { - final Map paramExprs = func.getParameterExpressions(); - if (paramExprs != null) { - final List params = func.getParameters(); - final List exprTrees = new ArrayList<>(params.size()); - for (final IdentNode ident : params) { - final Expression expr = paramExprs.containsKey(ident)? paramExprs.get(ident) : ident; - curExpr = null; - expr.accept(this); - assert curExpr != null; - exprTrees.add(curExpr); - } - return exprTrees; - } else { - return translateExprs(func.getParameters()); - } - } - - private List translateExprs(final List exprs) { - if (exprs == null) { - return null; - } - final List exprTrees = new ArrayList<>(exprs.size()); - for (final Expression expr : exprs) { - curExpr = null; - expr.accept(this); - assert curExpr != null; - exprTrees.add(curExpr); - } - return exprTrees; - } - - private ExpressionTreeImpl translateExpr(final Expression expr) { - if (expr == null) { - return null; - } - - curExpr = null; - expr.accept(this); - assert curExpr != null : "null for " + expr; - return curExpr; - } - - private StatementTreeImpl translateStat(final Statement stat) { - if (stat == null) { - return null; - } - - curStat = null; - stat.accept(this); - assert curStat != null : "null for " + stat; - return curStat; - } - - private static IdentifierTree translateIdent(final IdentNode ident) { - return new IdentifierTreeImpl(ident); - } - - private List translateProperties(final List propNodes) { - final List propTrees = new ArrayList<>(propNodes.size()); - for (final PropertyNode propNode : propNodes) { - propTrees.add(translateProperty(propNode)); - } - return propTrees; - } - - private PropertyTree translateProperty(final PropertyNode propNode) { - return new PropertyTreeImpl(propNode, - translateExpr(propNode.getKey()), - translateExpr(propNode.getValue()), - (FunctionExpressionTree) translateExpr(propNode.getGetter()), - (FunctionExpressionTree) translateExpr(propNode.getSetter())); - } - - private ModuleTree translateModule(final FunctionNode func) { - return func.getKind() == FunctionNode.Kind.MODULE? - ModuleTreeImpl.create(func) : null; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTree.java deleted file mode 100644 index d6684fb9307..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTree.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an identifier expression. - * - * For example: - *
- *   name
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface IdentifierTree extends ExpressionTree { - /** - * Returns the name of this identifier. - * - * @return the name of this identifier - */ - String getName(); - - /** - * Is this a rest parameter for a function or rest elements of an array? - * - * @return true if this is a rest parameter - */ - boolean isRestParameter(); - - /** - * Is this super identifier? - * - * @return true if this is super identifier - */ - boolean isSuper(); - - /** - * Is this 'this' identifier? - * - * @return true if this is 'this' identifier - */ - boolean isThis(); - - /** - * Is this "*" used in module export entry? - * - * @return true if this "*" used in module export entry? - */ - boolean isStar(); - - /** - * Is this "default" used in module export entry? - * - * @return true if this 'default' used in module export entry? - */ - boolean isDefault(); - - /** - * Is this "*default*" used in module export entry? - * - * @return true if this '*default*' used in module export entry? - */ - boolean isStarDefaultStar(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTreeImpl.java deleted file mode 100644 index a2af0dda856..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IdentifierTreeImpl.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.Module; - -final class IdentifierTreeImpl extends ExpressionTreeImpl implements IdentifierTree { - private final String name; - - IdentifierTreeImpl(final IdentNode node) { - super(node); - this.name = node.getName(); - } - - @Override - public Kind getKind() { - return Kind.IDENTIFIER; - } - - @Override - public String getName() { - return name; - } - - @Override - public boolean isRestParameter() { - return ((IdentNode)node).isRestParameter(); - } - - @Override - public boolean isSuper() { - final IdentNode ident = (IdentNode)node; - return ident.isDirectSuper() || "super".equals(ident.getName()); - } - - @Override - public boolean isThis() { - return "this".equals(((IdentNode)node).getName()); - } - - @Override - public boolean isStar() { - return Module.STAR_NAME.equals(((IdentNode)node).getName()); - } - - @Override - public boolean isDefault() { - return Module.DEFAULT_NAME.equals(((IdentNode)node).getName()); - } - - @Override - public boolean isStarDefaultStar() { - return Module.DEFAULT_EXPORT_BINDING_NAME.equals(((IdentNode)node).getName()); - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitIdentifier(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTree.java deleted file mode 100644 index e515dc0d539..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTree.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an 'if' statement. - * - * For example: - *
- *   if ( condition )
- *      thenStatement
- *
- *   if ( condition )
- *       thenStatement
- *   else
- *       elseStatement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface IfTree extends StatementTree { - /** - * Returns the condition expression of this 'if' statement. - * - * @return the condition expression - */ - ExpressionTree getCondition(); - - /** - * Returns the 'then' statement of this 'if' statement. - * - * @return the 'then' statement - */ - StatementTree getThenStatement(); - - /** - * Returns the then statement of this 'if' statement. - * null if this if statement has no else branch. - * - * @return the 'else' statement - */ - StatementTree getElseStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTreeImpl.java deleted file mode 100644 index f095531fad5..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/IfTreeImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.IfNode; - -final class IfTreeImpl extends StatementTreeImpl implements IfTree { - private final ExpressionTree cond; - private final StatementTree thenStat; - private final StatementTree elseStat; - IfTreeImpl(final IfNode node, final ExpressionTree cond, - final StatementTree thenStat, final StatementTree elseStat) { - super(node); - this.cond = cond; - this.thenStat = thenStat; - this.elseStat = elseStat; - } - - @Override - public Kind getKind() { - return Kind.IF; - } - - @Override - public ExpressionTree getCondition() { - return cond; - } - - @Override - public StatementTree getThenStatement() { - return thenStat; - } - - /** - * @return null if this if statement has no else branch. - */ - @Override - public StatementTree getElseStatement() { - return elseStat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitIf(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTree.java deleted file mode 100644 index 91212ff9f49..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTree.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A Tree node for import entry of Module information. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ -@Deprecated(since="11", forRemoval=true) -public interface ImportEntryTree extends Tree { - /** - * Returns the entry's module request. - * - * @return the module request - */ - public IdentifierTree getModuleRequest(); - - /** - * Returns the entry's import name. - * - * @return the import name - */ - public IdentifierTree getImportName(); - - /** - * Returns the entry's local name. - * - * @return the local name - */ - public IdentifierTree getLocalName(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTreeImpl.java deleted file mode 100644 index c0a023032db..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ImportEntryTreeImpl.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; -import java.util.stream.Collectors; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.Module; -import static jdk.nashorn.api.tree.ModuleTreeImpl.identOrNull; - -final class ImportEntryTreeImpl extends TreeImpl implements ImportEntryTree { - private final long startPos, endPos; - private final IdentifierTree moduleRequest; - private final IdentifierTree importName; - private final IdentifierTree localName; - - private ImportEntryTreeImpl(final long startPos, final long endPos, - final IdentifierTree moduleRequest, - final IdentifierTree importName, - final IdentifierTree localName) { - super(null); // No underlying Node! - this.startPos = startPos; - this.endPos = endPos; - this.moduleRequest = moduleRequest; - this.importName = importName; - this.localName = localName; - } - - private static ImportEntryTreeImpl createImportEntry(final Module.ImportEntry entry) { - return new ImportEntryTreeImpl(entry.getStartPosition(), - entry.getEndPosition(), - identOrNull(entry.getModuleRequest()), - identOrNull(entry.getImportName()), - identOrNull(entry.getLocalName())); - } - - static List createImportList(final List importList) { - return importList.stream(). - map(ImportEntryTreeImpl::createImportEntry). - collect(Collectors.toList()); - } - - @Override - public Kind getKind() { - return Tree.Kind.IMPORT_ENTRY; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitImportEntry(this, data); - } - - @Override - public long getStartPosition() { - return startPos; - } - - @Override - public long getEndPosition() { - return endPos; - } - - @Override - public IdentifierTree getModuleRequest() { - return moduleRequest; - } - - @Override - public IdentifierTree getImportName() { - return importName; - } - - @Override - public IdentifierTree getLocalName() { - return localName; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTree.java deleted file mode 100644 index bf721fdce6b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTree.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for an 'instanceof' expression. - * - * For example: - *
- *   expression instanceof type
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface InstanceOfTree extends ExpressionTree { - /** - * Returns the expression whose type is being checked. - * - * @return the expression whose type is being checked - */ - ExpressionTree getExpression(); - - /** - * Returns the type expression. - * - * @return the type expression - */ - Tree getType(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTreeImpl.java deleted file mode 100644 index 34714145ef8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/InstanceOfTreeImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.parser.TokenType; - -final class InstanceOfTreeImpl extends BinaryTreeImpl implements InstanceOfTree { - InstanceOfTreeImpl(final BinaryNode node, - final ExpressionTree expr, - final ExpressionTree type) { - super(node, expr, type); - assert node.isTokenType(TokenType.INSTANCEOF) : "instanceof expected"; - } - - @Override - public Kind getKind() { - return Kind.INSTANCE_OF; - } - - @Override - public ExpressionTree getExpression() { - return getLeftOperand(); - } - - @Override - public Tree getType() { - return getRightOperand(); - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitInstanceOf(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTree.java deleted file mode 100644 index 39f2e9bf749..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTree.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a labeled statement. - * - * For example: - *
- *   label : statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface LabeledStatementTree extends StatementTree { - /** - * Returns the label associated with this statement. - * - * @return the label - */ - String getLabel(); - - /** - * Returns the statement being labeled. - * - * @return the statement labeled - */ - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTreeImpl.java deleted file mode 100644 index 796dd4e5b74..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LabeledStatementTreeImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.LabelNode; - -final class LabeledStatementTreeImpl extends StatementTreeImpl - implements LabeledStatementTree { - private final String name; - private final StatementTree stat; - - LabeledStatementTreeImpl(final LabelNode node, final StatementTree stat) { - super(node); - this.name = node.getLabelName(); - this.stat = stat; - } - - @Override - public Kind getKind() { - return Kind.LABELED_STATEMENT; - } - - @Override - public String getLabel() { - return name; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitLabeledStatement(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMap.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMap.java deleted file mode 100644 index 08476e7dccc..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMap.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * Provides methods to convert between character positions and line numbers - * for a compilation unit. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface LineMap { - /** - * Find the line containing a position; a line termination - * character is on the line it terminates. - * - * @param pos character offset of the position - * @return the line number of pos (first line is 1) - */ - long getLineNumber(long pos); - - /** - * Find the column for a character position. - * Tab characters preceding the position on the same line - * will be expanded when calculating the column number. - * - * @param pos character offset of the position - * @return the tab-expanded column number of pos (first column is 1) - */ - long getColumnNumber(long pos); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMapImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMapImpl.java deleted file mode 100644 index 7cfa4abca9b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LineMapImpl.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.runtime.Source; - -final class LineMapImpl implements LineMap { - private final Source source; - - LineMapImpl(final Source source) { - this.source = source; - } - - @Override - public long getLineNumber(final long pos) { - return source.getLine((int)pos); - } - - @Override - public long getColumnNumber(final long pos) { - return source.getColumn((int)pos); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTree.java deleted file mode 100644 index 9378bb24dc0..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTree.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a literal expression. - * Use {@link #getKind getKind} to determine the kind of literal. - * - * For example: - *
- *   value
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface LiteralTree extends ExpressionTree { - /** - * Returns the value of this literal. - * - * @return the value of this literal - */ - Object getValue(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTreeImpl.java deleted file mode 100644 index 3335a4cb0df..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LiteralTreeImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.LiteralNode; - -final class LiteralTreeImpl extends ExpressionTreeImpl implements LiteralTree { - private final Object value; - private final Kind kind; - LiteralTreeImpl(final LiteralNode node) { - super(node); - this.kind = literalKind(node); - this.value = node.getValue(); - } - - @Override - public Kind getKind() { - return kind; - } - - @Override - public Object getValue() { - return value; - } - - private static Kind literalKind(final LiteralNode node) { - if (node.isBoolean()) { - return Kind.BOOLEAN_LITERAL; - } else if (node.isNumeric()) { - return Kind.NUMBER_LITERAL; - } else if (node.isString()) { - return Kind.STRING_LITERAL; - } else if (node.isNull()) { - return Kind.NULL_LITERAL; - } else { - throw new AssertionError("should not reach here: " + node.getValue()); - } - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitLiteral(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LoopTree.java deleted file mode 100644 index 2b0d38dfb1b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/LoopTree.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A mixin for "loop" statements. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface LoopTree extends StatementTree { - /** - * Returns the statement contained in this 'loop' statement. - * - * @return the statement - */ - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTree.java deleted file mode 100644 index 70f779f07b0..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTree.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a member access expression. - * - * For example: - *
- *   expression . identifier
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface MemberSelectTree extends ExpressionTree { - /** - * The object expression whose member is being selected. - * - * @return the object whose member is selected - */ - ExpressionTree getExpression(); - - /** - * Returns the name of the property. - * - * @return the name of the property - */ - String getIdentifier(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTreeImpl.java deleted file mode 100644 index 61b6f403bd8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/MemberSelectTreeImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.AccessNode; - -final class MemberSelectTreeImpl extends ExpressionTreeImpl - implements MemberSelectTree { - private final String ident; - private final ExpressionTree expr; - MemberSelectTreeImpl(final AccessNode node, final ExpressionTree expr) { - super(node); - this.ident = node.getProperty(); - this.expr = expr; - } - - @Override - public Kind getKind() { - return Kind.MEMBER_SELECT; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public String getIdentifier() { - return ident; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitMemberSelect(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTree.java deleted file mode 100644 index 52e06483f0e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTree.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A Tree node for Module information. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ -@Deprecated(since="11", forRemoval=true) -public interface ModuleTree extends Tree { - /** - * Returns the list of import entries. - * - * @return the import entries - */ - public List getImportEntries(); - - /** - * Returns the list of local export entries. - * - * @return the local export entries - */ - public List getLocalExportEntries(); - - /** - * Returns the list of indirect export entries. - * - * @return the indirect export entries - */ - public List getIndirectExportEntries(); - - /** - * Returns the list of star export entries. - * - * @return the star export entries - */ - public List getStarExportEntries(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTreeImpl.java deleted file mode 100644 index df32b0914b8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ModuleTreeImpl.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.util.List; -import java.util.stream.Collectors; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.Module; -import static jdk.nashorn.api.tree.ExportEntryTreeImpl.createExportList; -import static jdk.nashorn.api.tree.ImportEntryTreeImpl.createImportList; - -final class ModuleTreeImpl extends TreeImpl implements ModuleTree { - - private final Module mod; - private final List imports; - private final List localExports; - private final List indirectExports; - private final List starExports; - - private ModuleTreeImpl(final FunctionNode func, - final List imports, - final List localExports, - final List indirectExports, - final List starExports) { - super(func); - assert func.getKind() == FunctionNode.Kind.MODULE : "module function node expected"; - this.mod = func.getModule(); - this.imports = imports; - this.localExports = localExports; - this.indirectExports = indirectExports; - this.starExports = starExports; - } - - static ModuleTreeImpl create(final FunctionNode func) { - final Module mod = func.getModule(); - return new ModuleTreeImpl(func, - createImportList(mod.getImportEntries()), - createExportList(mod.getLocalExportEntries()), - createExportList(mod.getIndirectExportEntries()), - createExportList(mod.getStarExportEntries())); - } - - @Override - public Kind getKind() { - return Tree.Kind.MODULE; - } - - @Override - public List getImportEntries() { - return imports; - } - - @Override - public List getLocalExportEntries() { - return localExports; - } - - @Override - public List getIndirectExportEntries() { - return indirectExports; - } - - @Override - public List getStarExportEntries() { - return starExports; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitModule(this, data); - } - - static IdentifierTree identOrNull(final IdentNode node) { - return node != null? new IdentifierTreeImpl(node) : null; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTree.java deleted file mode 100644 index 06ebb4fe080..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTree.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node to declare a new instance of a class. - * - * For example: - *
- *   new identifier ( )
- *
- *   new identifier ( arguments )
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface NewTree extends ExpressionTree { - /** - * Returns the constructor expression of this 'new' expression. - * - * @return the constructor expression of this 'new' expression - */ - ExpressionTree getConstructorExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTreeImpl.java deleted file mode 100644 index 4bfec68ec43..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/NewTreeImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.parser.TokenType; - -final class NewTreeImpl extends ExpressionTreeImpl implements NewTree { - private final ExpressionTree constrExpr; - - NewTreeImpl(final UnaryNode node, final ExpressionTree constrExpr) { - super(node); - assert (node.isTokenType(TokenType.NEW)) : "new expected"; - this.constrExpr = constrExpr; - } - - @Override - public Kind getKind() { - return Kind.NEW; - } - - @Override - public ExpressionTree getConstructorExpression() { - return constrExpr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitNew(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTree.java deleted file mode 100644 index 402669fd8d4..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTree.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * Represents ECMAScript object literal expression. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ObjectLiteralTree extends ExpressionTree { - /** - * Returns the list of properties of this object literal. - * - * @return the list of properties of this object literal - */ - public List getProperties(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTreeImpl.java deleted file mode 100644 index cc0dfdf0d20..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ObjectLiteralTreeImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.ObjectNode; - -final class ObjectLiteralTreeImpl extends ExpressionTreeImpl - implements ObjectLiteralTree { - private final List props; - ObjectLiteralTreeImpl(final ObjectNode node, final List props) { - super(node); - this.props = props; - } - - @Override - public Kind getKind() { - return Kind.OBJECT_LITERAL; - } - - @Override - public List getProperties() { - return props; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitObjectLiteral(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParenthesizedTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParenthesizedTree.java deleted file mode 100644 index d27a8a5f2db..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParenthesizedTree.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a parenthesized expression. Note: parentheses - * not be preserved by the parser. - * - * For example: - *
- *   ( expression )
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ParenthesizedTree extends ExpressionTree { - /** - * Returns the expression within the parenthesis. - * - * @return the expression within the parenthesis - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Parser.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Parser.java deleted file mode 100644 index 40aef0a9d27..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Parser.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.io.File; -import java.io.IOException; -import java.io.Reader; -import java.net.URL; -import java.nio.file.Path; -import jdk.nashorn.api.scripting.NashornException; -import jdk.nashorn.api.scripting.ScriptObjectMirror; - -/** - * Represents nashorn ECMAScript parser instance. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface Parser { - /** - * Parses the source file and returns compilation unit tree - * - * @param file source file to parse - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if file is null - * @throws IOException if parse source read fails - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final File file, final DiagnosticListener listener) throws IOException, NashornException; - - /** - * Parses the source Path and returns compilation unit tree - * - * @param path source Path to parse - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if path is null - * @throws IOException if parse source read fails - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException; - - /** - * Parses the source url and returns compilation unit tree - * - * @param url source file to parse - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if url is null - * @throws IOException if parse source read fails - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException; - - /** - * Parses the reader and returns compilation unit tree - * - * @param name name of the source file to parse - * @param reader from which source is read - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if name or reader is null - * @throws IOException if parse source read fails - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final String name, Reader reader, final DiagnosticListener listener) throws IOException, NashornException; - - /** - * Parses the string source and returns compilation unit tree - * - * @param name of the source - * @param code string source - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if name or code is null - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final String name, String code, final DiagnosticListener listener) throws NashornException; - - /** - * Parses the source from script object and returns compilation unit tree - * - * @param scriptObj script object whose script and name properties are used for script source - * @param listener to receive diagnostic messages from the parser. This can be null. - * if null is passed, a NashornException is thrown on the first parse error. - * @return compilation unit tree - * @throws NullPointerException if scriptObj is null - * @throws NashornException is thrown if no listener is supplied and parser encounters error - */ - public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException; - - /** - * Factory method to create a new instance of Parser. - * - * @param options configuration options to initialize the Parser. - * Currently the following options are supported: - * - *
- *
"--const-as-var"
treat "const" declaration as "var"
- *
"-dump-on-error" or "-doe"
dump stack trace on error
- *
"--empty-statements"
include empty statement nodes
- *
"--no-syntax-extensions" or "-nse"
disable ECMAScript syntax extensions
- *
"-scripting"
enable scripting mode extensions
- *
"-strict"
enable ECMAScript strict mode
- *
"--language=es6"
enable ECMAScript 6 parsing mode
- *
"--es6-module"
enable ECMAScript 6 module parsing mode. This option implies --language=es6
- *
- * - * @throws NullPointerException if options array or any of its element is null - * @throws IllegalArgumentException on unsupported option value. - * @return a new Parser instance. - */ - public static Parser create(final String... options) throws IllegalArgumentException { - options.getClass(); - for (final String opt : options) { - switch (opt) { - case "--const-as-var": - case "-dump-on-error": - case "-doe": - case "--empty-statements": - case "--no-syntax-extensions": - case "-nse": - case "-scripting": - case "-strict": - case "--language=es6": - case "--es6-module": - break; - default: - throw new IllegalArgumentException(opt); - } - } - - return new ParserImpl(options); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java deleted file mode 100644 index 5a10526fe5b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ParserImpl.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Reader; -import java.net.URL; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.Map; -import java.util.Objects; -import jdk.nashorn.api.scripting.NashornException; -import jdk.nashorn.api.scripting.ScriptObjectMirror; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ErrorManager; -import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.ParserException; -import jdk.nashorn.internal.runtime.ScriptEnvironment; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.options.Options; - -final class ParserImpl implements Parser { - - private final ScriptEnvironment env; - private final boolean moduleMode; - - ParserImpl(final String... args) throws IllegalArgumentException { - Objects.requireNonNull(args); - - // handle the parser specific "--es6-module" option - boolean seenModuleOption = false; - for (int idx = 0; idx < args.length; idx++) { - final String opt = args[idx]; - if (opt.equals("--es6-module")) { - seenModuleOption = true; - /* - * Nashorn parser does not understand parser API specific - * option. This option implies --language=es6. So, we change - * the option to --language=es6. Note that if user specified - * --language=es6 explicitly, that is okay. Nashorn tolerates - * repeated options! - */ - args[idx] = "--language=es6"; - break; - } - } - this.moduleMode = seenModuleOption; - - // append "--parse-only to signal to the Nashorn that it - // is being used in "parse only" mode. - final String[] newArgs = Arrays.copyOf(args, args.length + 1, String[].class); - newArgs[args.length] = "--parse-only"; - final Options options = new Options("nashorn"); - options.process(newArgs); - this.env = new ScriptEnvironment(options, - new PrintWriter(System.out), new PrintWriter(System.err)); - } - - @Override - public CompilationUnitTree parse(final File file, final DiagnosticListener listener) throws IOException, NashornException { - if (moduleMode) { - return parseModule(file, listener); - } - final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file); - return translate(makeParser(src, listener).parse()); - } - - @Override - public CompilationUnitTree parse(final Path path, final DiagnosticListener listener) throws IOException, NashornException { - if (moduleMode) { - return parseModule(path, listener); - } - final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path); - return translate(makeParser(src, listener).parse()); - } - - @Override - public CompilationUnitTree parse(final URL url, final DiagnosticListener listener) throws IOException, NashornException { - if (moduleMode) { - return parseModule(url, listener); - } - final Source src = Source.sourceFor(url.toString(), url); - return translate(makeParser(src, listener).parse()); - } - - @Override - public CompilationUnitTree parse(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException { - if (moduleMode) { - return parseModule(name, reader, listener); - } - final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader)); - return translate(makeParser(src, listener).parse()); - } - - @Override - public CompilationUnitTree parse(final String name, final String code, final DiagnosticListener listener) throws NashornException { - if (moduleMode) { - return parseModule(name, code, listener); - } - final Source src = Source.sourceFor(name, code); - return translate(makeParser(src, listener).parse()); - } - - @Override - public CompilationUnitTree parse(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException { - if (moduleMode) { - return parseModule(scriptObj, listener); - } - final Map map = Objects.requireNonNull(scriptObj); - if (map.containsKey("script") && map.containsKey("name")) { - final String script = JSType.toString(map.get("script")); - final String name = JSType.toString(map.get("name")); - final Source src = Source.sourceFor(name, script); - return translate(makeParser(src, listener).parse()); - } else { - throw new IllegalArgumentException("can't find 'script' and 'name' properties"); - } - } - - private CompilationUnitTree parseModule(final File file, final DiagnosticListener listener) throws IOException, NashornException { - final Source src = Source.sourceFor(Objects.requireNonNull(file).getName(), file); - return makeModule(src, listener); - } - - private CompilationUnitTree parseModule(final Path path, final DiagnosticListener listener) throws IOException, NashornException { - final Source src = Source.sourceFor(Objects.requireNonNull(path).toString(), path); - return makeModule(src, listener); - } - - private CompilationUnitTree parseModule(final URL url, final DiagnosticListener listener) throws IOException, NashornException { - final Source src = Source.sourceFor(url.toString(), url); - return makeModule(src, listener); - } - - private CompilationUnitTree parseModule(final String name, final Reader reader, final DiagnosticListener listener) throws IOException, NashornException { - final Source src = Source.sourceFor(Objects.requireNonNull(name), Objects.requireNonNull(reader)); - return makeModule(src, listener); - } - - private CompilationUnitTree parseModule(final String name, final String code, final DiagnosticListener listener) throws NashornException { - final Source src = Source.sourceFor(name, code); - return makeModule(src, listener); - } - - private CompilationUnitTree parseModule(final ScriptObjectMirror scriptObj, final DiagnosticListener listener) throws NashornException { - final Map map = Objects.requireNonNull(scriptObj); - if (map.containsKey("script") && map.containsKey("name")) { - final String script = JSType.toString(map.get("script")); - final String name = JSType.toString(map.get("name")); - final Source src = Source.sourceFor(name, script); - return makeModule(src, listener); - } else { - throw new IllegalArgumentException("can't find 'script' and 'name' properties"); - } - } - - private CompilationUnitTree makeModule(final Source src, final DiagnosticListener listener) { - final FunctionNode modFunc = makeParser(src, listener).parseModule(src.getName()); - return new IRTranslator().translate(modFunc); - } - - private jdk.nashorn.internal.parser.Parser makeParser(final Source source, final DiagnosticListener listener) { - final ErrorManager errMgr = listener != null ? new ListenerErrorManager(listener) : new Context.ThrowErrorManager(); - return new jdk.nashorn.internal.parser.Parser(env, source, errMgr); - } - - private static class ListenerErrorManager extends ErrorManager { - - private final DiagnosticListener listener; - - ListenerErrorManager(final DiagnosticListener listener) { - // null check - listener.getClass(); - this.listener = listener; - } - - @Override - public void error(final String msg) { - error(new ParserException(msg)); - } - - @Override - public void error(final ParserException e) { - listener.report(new DiagnosticImpl(e, Diagnostic.Kind.ERROR)); - } - - @Override - public void warning(final String msg) { - warning(new ParserException(msg)); - } - - @Override - public void warning(final ParserException e) { - listener.report(new DiagnosticImpl(e, Diagnostic.Kind.WARNING)); - } - } - - private static CompilationUnitTree translate(final FunctionNode node) { - return new IRTranslator().translate(node); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTree.java deleted file mode 100644 index c23119c8e2d..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTree.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * To represent property setting in an object literal tree. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface PropertyTree extends Tree { - /** - * Returns the name of this property. - * - * @return the name of the property - */ - public ExpressionTree getKey(); - - /** - * Returns the value of this property. This is null for accessor properties. - * - * @return the value of the property - */ - public ExpressionTree getValue(); - - /** - * Returns the setter function of this property if this - * is an accessor property. This is null for data properties. - * - * @return the setter function of the property - */ - public FunctionExpressionTree getGetter(); - - /** - * Returns the getter function of this property if this - * is an accessor property. This is null for data properties. - * - * @return the getter function of the property - */ - public FunctionExpressionTree getSetter(); - - /** - * Is this a class static property? - * - * @return true if this is a static property - */ - public boolean isStatic(); - - /** - * Is this a computed property? - * - * @return true if this is a computed property - */ - public boolean isComputed(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTreeImpl.java deleted file mode 100644 index 1ba734ec731..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/PropertyTreeImpl.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.PropertyNode; - -final class PropertyTreeImpl extends TreeImpl implements PropertyTree { - private final ExpressionTree key; - private final ExpressionTree value; - private final FunctionExpressionTree getter; - private final FunctionExpressionTree setter; - private final boolean isStatic, isComputed; - - PropertyTreeImpl(final PropertyNode node, - final ExpressionTree key, - final ExpressionTree value, - final FunctionExpressionTree getter, - final FunctionExpressionTree setter) { - super(node); - this.key = key; - this.value = value; - this.getter = getter; - this.setter = setter; - this.isStatic = node.isStatic(); - this.isComputed = node.isComputed(); - } - - @Override - public Kind getKind() { - return Kind.PROPERTY; - } - - @Override - public ExpressionTree getKey() { - return key; - } - - @Override - public ExpressionTree getValue() { - return value; - } - - @Override - public FunctionExpressionTree getGetter() { - return getter; - } - - @Override - public FunctionExpressionTree getSetter() { - return setter; - } - - @Override - public boolean isStatic() { - return isStatic; - } - - @Override - public boolean isComputed() { - return isComputed; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitProperty(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTree.java deleted file mode 100644 index 152b9bad676..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTree.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * Represents regular expression literal in the source code. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface RegExpLiteralTree extends ExpressionTree { - /** - * Regular expression pattern to match. - * - * @return regular expression pattern - */ - public String getPattern(); - - /** - * Regular expression matching options. - * - * @return options like "i" for ignoreCase used - */ - public String getOptions(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTreeImpl.java deleted file mode 100644 index 451147a95bc..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/RegExpLiteralTreeImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.parser.Lexer; - -final class RegExpLiteralTreeImpl extends ExpressionTreeImpl - implements RegExpLiteralTree { - private final String pattern; - private final String options; - RegExpLiteralTreeImpl(final LiteralNode node) { - super(node); - assert node.getValue() instanceof Lexer.RegexToken : "regexp expected"; - final Lexer.RegexToken regex = (Lexer.RegexToken) node.getValue(); - this.pattern = regex.getExpression(); - this.options = regex.getOptions(); - } - - @Override - public Kind getKind() { - return Kind.REGEXP_LITERAL; - } - - @Override - public String getPattern() { - return pattern; - } - - @Override - public String getOptions() { - return options; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitRegExpLiteral(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTree.java deleted file mode 100644 index 0689c49abcc..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTree.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'return' statement. - * - * For example: - *
- *   return;
- *   return expression;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ReturnTree extends StatementTree { - /** - * Returns the expression being returned. This is null if no value - * is being returned. i.e., empty return statement. - * - * @return the returned expression - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTreeImpl.java deleted file mode 100644 index 9eab46416e7..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ReturnTreeImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ReturnNode; - -final class ReturnTreeImpl extends StatementTreeImpl implements ReturnTree { - private final ExpressionTree expr; - - ReturnTreeImpl(final ReturnNode returnNode, final ExpressionTree expr) { - super(returnNode); - this.expr = expr; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.RETURN; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitReturn(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES5_1.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES5_1.java deleted file mode 100644 index 43705803a67..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES5_1.java +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A simple implementation of the TreeVisitor for ECMAScript edition 5.1. - * - *

The visit methods corresponding to ES 5.1 language constructs walk the - * "components" of the given tree by calling accept method passing the - * current visitor and the additional parameter. - * - *

For constructs introduced in later versions, {@code visitUnknown} - * is called instead which throws {@link UnknownTreeException}. - * - *

Methods in this class may be overridden subject to their - * general contract. Note that annotating methods in concrete - * subclasses with {@link java.lang.Override @Override} will help - * ensure that methods are overridden as intended. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @param the return type of this visitor's methods. Use {@link - * Void} for visitors that do not need to return results. - * @param

the type of the additional parameter to this visitor's - * methods. Use {@code Void} for visitors that do not need an - * additional parameter. - */ -@Deprecated(since="11", forRemoval=true) -public class SimpleTreeVisitorES5_1 implements TreeVisitor { - @Override - public R visitAssignment(final AssignmentTree node, final P r) { - node.getVariable().accept(this, r); - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitCompoundAssignment(final CompoundAssignmentTree node, final P r) { - node.getVariable().accept(this, r); - node.getExpression().accept(this, r); - return null; - } - - /** - * Visits a {@code ModuleTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitModule(final ModuleTree node, final P p) { - return visitUnknown(node, p); - } - - /** - * Visits an {@code ExportEntryTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitExportEntry(final ExportEntryTree node, final P p) { - return visitUnknown(node, p); - } - - /** - * Visits an {@code ImportEntryTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitImportEntry(final ImportEntryTree node, final P p) { - return visitUnknown(node, p); - } - - @Override - public R visitBinary(final BinaryTree node, final P r) { - node.getLeftOperand().accept(this, r); - node.getRightOperand().accept(this, r); - return null; - } - - @Override - public R visitBlock(final BlockTree node, final P r) { - node.getStatements().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitBreak(final BreakTree node, final P r) { - return null; - } - - @Override - public R visitCase(final CaseTree node, final P r) { - final Tree caseVal = node.getExpression(); - if (caseVal != null) { - caseVal.accept(this, r); - } - - node.getStatements().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitCatch(final CatchTree node, final P r) { - final Tree cond = node.getCondition(); - if (cond != null) { - cond.accept(this, r); - } - node.getParameter().accept(this, r); - node.getBlock().accept(this, r); - return null; - } - - /** - * Visits a {@code ClassDeclarationTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitClassDeclaration(final ClassDeclarationTree node, final P p) { - return visitUnknown(node, p); - } - - /** - * Visits a {@code ClassExpressionTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitClassExpression(final ClassExpressionTree node, final P p) { - return visitUnknown(node, p); - } - - @Override - public R visitConditionalExpression(final ConditionalExpressionTree node, final P r) { - node.getCondition().accept(this, r); - node.getTrueExpression().accept(this, r); - node.getFalseExpression().accept(this, r); - return null; - } - - @Override - public R visitContinue(final ContinueTree node, final P r) { - return null; - } - - @Override - public R visitDebugger(final DebuggerTree node, final P r) { - return null; - } - - @Override - public R visitDoWhileLoop(final DoWhileLoopTree node, final P r) { - node.getStatement().accept(this, r); - node.getCondition().accept(this, r); - return null; - } - - @Override - public R visitErroneous(final ErroneousTree node, final P r) { - return null; - } - - @Override - public R visitExpressionStatement(final ExpressionStatementTree node, final P r) { - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitForLoop(final ForLoopTree node, final P r) { - final Tree init = node.getInitializer(); - if (init != null) { - init.accept(this, r); - } - - final Tree cond = node.getCondition(); - if (cond != null) { - cond.accept(this, r); - } - - final Tree update = node.getUpdate(); - if (update != null) { - update.accept(this, r); - } - - node.getStatement().accept(this, r); - return null; - } - - @Override - public R visitForInLoop(final ForInLoopTree node, final P r) { - node.getVariable().accept(this, r); - node.getExpression().accept(this, r); - final StatementTree stat = node.getStatement(); - if (stat != null) { - stat.accept(this, r); - } - return null; - } - - /** - * Visits a {@code ForOfLoopTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitForOfLoop(final ForOfLoopTree node, final P p) { - return visitUnknown(node, p); - } - - @Override - public R visitFunctionCall(final FunctionCallTree node, final P r) { - node.getFunctionSelect().accept(this, r); - node.getArguments().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitFunctionDeclaration(final FunctionDeclarationTree node, final P r) { - node.getParameters().forEach((tree) -> { - tree.accept(this, r); - }); - node.getBody().accept(this, r); - return null; - } - - @Override - public R visitFunctionExpression(final FunctionExpressionTree node, final P r) { - node.getParameters().forEach((tree) -> { - tree.accept(this, r); - }); - node.getBody().accept(this, r); - return null; - } - - @Override - public R visitIdentifier(final IdentifierTree node, final P r) { - return null; - } - - @Override - public R visitIf(final IfTree node, final P r) { - node.getCondition().accept(this, r); - node.getThenStatement().accept(this, r); - final Tree elseStat = node.getElseStatement(); - if (elseStat != null) { - elseStat.accept(this, r); - } - return null; - } - - @Override - public R visitArrayAccess(final ArrayAccessTree node, final P r) { - node.getExpression().accept(this, r); - node.getIndex().accept(this, r); - return null; - } - - @Override - public R visitArrayLiteral(final ArrayLiteralTree node, final P r) { - node.getElements().stream().filter((tree) -> (tree != null)).forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitLabeledStatement(final LabeledStatementTree node, final P r) { - node.getStatement().accept(this, r); - return null; - } - - @Override - public R visitLiteral(final LiteralTree node, final P r) { - return null; - } - - @Override - public R visitParenthesized(final ParenthesizedTree node, final P r) { - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitReturn(final ReturnTree node, final P r) { - final Tree retExpr = node.getExpression(); - if (retExpr != null) { - retExpr.accept(this, r); - } - return null; - } - - @Override - public R visitMemberSelect(final MemberSelectTree node, final P r) { - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitNew(final NewTree node, final P r) { - node.getConstructorExpression().accept(this, r); - return null; - } - - @Override - public R visitObjectLiteral(final ObjectLiteralTree node, final P r) { - node.getProperties().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitProperty(final PropertyTree node, final P r) { - final FunctionExpressionTree getter = node.getGetter(); - if (getter != null) { - getter.accept(this, r); - } - final ExpressionTree key = node.getKey(); - if (key != null) { - key.accept(this, r); - } - - final FunctionExpressionTree setter = node.getSetter(); - if (setter != null) { - setter.accept(this, r); - } - - final ExpressionTree value = node.getValue(); - if (value != null) { - value.accept(this, r); - } - return null; - } - - @Override - public R visitRegExpLiteral(final RegExpLiteralTree node, final P r) { - return null; - } - - /** - * Visits a {@code TemplateLiteralTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitTemplateLiteral(final TemplateLiteralTree node, final P p) { - return visitUnknown(node, p); - } - - @Override - public R visitEmptyStatement(final EmptyStatementTree node, final P r) { - return null; - } - - /** - * Visits a {@code SpreadTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitSpread(final SpreadTree node, final P p) { - return visitUnknown(node, p); - } - - @Override - public R visitSwitch(final SwitchTree node, final P r) { - node.getExpression().accept(this, r); - node.getCases().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitThrow(final ThrowTree node, final P r) { - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitCompilationUnit(final CompilationUnitTree node, final P r) { - node.getSourceElements().forEach((tree) -> { - tree.accept(this, r); - }); - return null; - } - - @Override - public R visitTry(final TryTree node, final P r) { - node.getBlock().accept(this, r); - node.getCatches().forEach((tree) -> { - tree.accept(this, r); - }); - - final Tree finallyBlock = node.getFinallyBlock(); - if (finallyBlock != null) { - finallyBlock.accept(this, r); - } - return null; - } - - @Override - public R visitInstanceOf(final InstanceOfTree node, final P r) { - node.getType().accept(this, r); - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitUnary(final UnaryTree node, final P r) { - node.getExpression().accept(this, r); - return null; - } - - @Override - public R visitVariable(final VariableTree node, final P r) { - if (node.getInitializer() != null) { - node.getInitializer().accept(this, r); - } - return null; - } - - @Override - public R visitWhileLoop(final WhileLoopTree node, final P r) { - node.getCondition().accept(this, r); - node.getStatement().accept(this, r); - return null; - } - - @Override - public R visitWith(final WithTree node, final P r) { - node.getScope().accept(this, r); - node.getStatement().accept(this, r); - return null; - } - - /** - * Visits a {@code YieldTree} tree by calling {@code - * visitUnknown}. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return the result of {@code visitUnknown} - */ - @Override - public R visitYield(final YieldTree node, final P p) { - return visitUnknown(node, p); - } - - /** - * {@inheritDoc} - * - * @implSpec The default implementation of this method in {@code - * SimpleTreeVisitorES5_1} will always throw {@code - * UnknownTypeException}. This behavior is not required of a - * subclass. - * - * @param node {@inheritDoc} - * @param p {@inheritDoc} - * @return abnormal return by throwing exception always - * @throws UnknownTreeException - * a visitor implementation may optionally throw this exception - */ - @Override - public R visitUnknown(final Tree node, final P p) { - // unknown in ECMAScript 5.1 edition - throw new UnknownTreeException(node, p); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES6.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES6.java deleted file mode 100644 index d535f41a751..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SimpleTreeVisitorES6.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A simple implementation of the TreeVisitor for ECMAScript edition 6. - * - *

The visit methods corresponding to ES 6 language constructs walk the - * "components" of the given tree by calling accept method passing the - * current visitor and the additional parameter. - * - *

For constructs introduced in later versions, {@code visitUnknown} - * is called instead which throws {@link UnknownTreeException}. - * - *

Methods in this class may be overridden subject to their - * general contract. Note that annotating methods in concrete - * subclasses with {@link java.lang.Override @Override} will help - * ensure that methods are overridden as intended. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @param the return type of this visitor's methods. Use {@link - * Void} for visitors that do not need to return results. - * @param

the type of the additional parameter to this visitor's - * methods. Use {@code Void} for visitors that do not need an - * additional parameter. - */ -@Deprecated(since="11", forRemoval=true) -public class SimpleTreeVisitorES6 extends SimpleTreeVisitorES5_1 { - @Override - public R visitCompilationUnit(final CompilationUnitTree node, final P r) { - final ModuleTree mod = node.getModule(); - if (mod != null) { - mod.accept(this, r); - } - return super.visitCompilationUnit(node, r); - } - - /** - * Visit Module tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitModule(final ModuleTree node, final P p) { - node.getImportEntries().forEach(e -> visitImportEntry(e, p)); - node.getLocalExportEntries().forEach(e -> visitExportEntry(e, p)); - node.getIndirectExportEntries().forEach(e -> visitExportEntry(e, p)); - node.getStarExportEntries().forEach(e -> visitExportEntry(e, p)); - return null; - } - - /** - * Visit Module ExportEntry tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitExportEntry(final ExportEntryTree node, final P p) { - return null; - } - - /** - * Visit Module ImportEntry tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitImportEntry(final ImportEntryTree node, final P p) { - return null; - } - - /** - * Visit class statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitClassDeclaration(final ClassDeclarationTree node, final P p) { - node.getName().accept(this, p); - final ExpressionTree heritage = node.getClassHeritage(); - if (heritage != null) { - heritage.accept(this, p); - } - final PropertyTree constructor = node.getConstructor(); - if (constructor != null) { - constructor.accept(this, p); - } - final List elements = node.getClassElements(); - if (elements != null) { - for (final PropertyTree prop : elements) { - prop.accept(this, p); - } - } - - return null; - } - - /** - * Visit class expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitClassExpression(final ClassExpressionTree node, final P p) { - node.getName().accept(this, p); - final ExpressionTree heritage = node.getClassHeritage(); - if (heritage != null) { - heritage.accept(this, p); - } - final PropertyTree constructor = node.getConstructor(); - if (constructor != null) { - constructor.accept(this, p); - } - final List elements = node.getClassElements(); - if (elements != null) { - for (final PropertyTree prop : elements) { - prop.accept(this, p); - } - } - - return null; - } - - /** - * Visit for..of statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitForOfLoop(final ForOfLoopTree node, final P p) { - node.getVariable().accept(this, p); - node.getExpression().accept(this, p); - final StatementTree stat = node.getStatement(); - if (stat != null) { - stat.accept(this, p); - } - return null; - } - - /** - * Visit 'yield' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitYield(final YieldTree node, final P p) { - node.getExpression().accept(this, p); - return null; - } - - /** - * Visit 'spread' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitSpread(final SpreadTree node, final P p) { - node.getExpression().accept(this, p); - return null; - } - - /** - * Visit template literal tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - @Override - public R visitTemplateLiteral(final TemplateLiteralTree node, final P p) { - final List expressions = node.getExpressions(); - for (final ExpressionTree expr : expressions) { - expr.accept(this, p); - } - return null; - } - - @Override - public R visitVariable(final VariableTree node, final P r) { - final ExpressionTree expr = node.getBinding(); - if (expr != null) { - expr.accept(this, r); - } - super.visitVariable(node, r); - return null; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTree.java deleted file mode 100644 index 45b4263cbb8..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTree.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for spread operator in array elements, function call arguments. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ -@Deprecated(since="11", forRemoval=true) -public interface SpreadTree extends ExpressionTree { - /** - * Returns the expression that is being spread. - * - * @return The expression that is being spread. - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTreeImpl.java deleted file mode 100644 index a01601f7097..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SpreadTreeImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.Expression; - -final class SpreadTreeImpl extends ExpressionTreeImpl - implements SpreadTree { - - private final ExpressionTree expr; - - SpreadTreeImpl(final Expression exprNode, final ExpressionTree expr) { - super(exprNode); - this.expr = expr; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.SPREAD; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitSpread(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTree.java deleted file mode 100644 index f2d0bf740ea..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTree.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node used as the base class for the different kinds of - * statements. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface StatementTree extends Tree { -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTreeImpl.java deleted file mode 100644 index 338b23ba260..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/StatementTreeImpl.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.Statement; - -abstract class StatementTreeImpl extends TreeImpl implements StatementTree { - StatementTreeImpl(final Statement stat) { - super(stat); - } - - StatementTreeImpl(final Block stat) { - super(stat); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTree.java deleted file mode 100644 index dc15265222e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTree.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a 'switch' statement. - * - * For example: - *

- *   switch ( expression ) {
- *     cases
- *   }
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface SwitchTree extends StatementTree { - /** - * Returns the expression on which this statement switches. - * - * @return the switch expression - */ - ExpressionTree getExpression(); - - - /** - * Returns the list of 'case' statements. - * - * @return the 'case' statements - */ - List getCases(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTreeImpl.java deleted file mode 100644 index 19b23f9a39b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/SwitchTreeImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.SwitchNode; - -final class SwitchTreeImpl extends StatementTreeImpl implements SwitchTree { - private final ExpressionTree expr; - private final List cases; - SwitchTreeImpl(final SwitchNode node, - final ExpressionTree expr, - final List cases) { - super(node); - this.expr = expr; - this.cases = cases; - } - - @Override - public Kind getKind() { - return Kind.SWITCH; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public List getCases() { - return cases; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitSwitch(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTree.java deleted file mode 100644 index ad799a698c1..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTree.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for template literal strings. - * - * For example: - *
- * `This is a String with ${computed} values in it`
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - * - */ -@Deprecated(since="11", forRemoval=true) -public interface TemplateLiteralTree extends ExpressionTree { - /** - * Returns the list of expressions in this template string - * - * @return the list of expressions in this template string - */ - List getExpressions(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTreeImpl.java deleted file mode 100644 index 87de44a14a6..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TemplateLiteralTreeImpl.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.Expression; - -final class TemplateLiteralTreeImpl extends ExpressionTreeImpl - implements TemplateLiteralTree { - - private final List expressions; - - TemplateLiteralTreeImpl(final Expression node, final List expressions) { - super(node); - this.expressions = expressions; - } - - @Override - public Kind getKind() { - return Kind.TEMPLATE_LITERAL; - } - - @Override - public List getExpressions() { - return expressions; - } - - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitTemplateLiteral(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTree.java deleted file mode 100644 index b7d4870593f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTree.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'throw' statement. - * - * For example: - *
- *   throw expression;
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface ThrowTree extends StatementTree { - /** - * Returns the expression being thrown. - * - * @return the expression being thrown. - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTreeImpl.java deleted file mode 100644 index 8d0776fcdc1..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/ThrowTreeImpl.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.ThrowNode; - -final class ThrowTreeImpl extends StatementTreeImpl implements ThrowTree { - private final ExpressionTree expr; - ThrowTreeImpl(final ThrowNode node, final ExpressionTree expr) { - super(node); - this.expr = expr; - } - - @Override - public Kind getKind() { - return Kind.THROW; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitThrow(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Tree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Tree.java deleted file mode 100644 index d732f187104..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/Tree.java +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * Common interface for all nodes in an abstract syntax tree. - * - *

WARNING: This interface and its sub-interfaces are - * subject to change as the ECMAScript programming language evolves. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface Tree { - - /** - * Enumerates all kinds of trees. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - */ - @Deprecated(since="11", forRemoval=true) - public enum Kind { - /** - * Used for instances of {@link ArrayAccessTree}. - */ - ARRAY_ACCESS(ArrayAccessTree.class), - - /** - * Used for instances of {@link ArrayLiteralTree}. - */ - ARRAY_LITERAL(ArrayLiteralTree.class), - - /** - * Used for instances of {@link AssignmentTree}. - */ - ASSIGNMENT(AssignmentTree.class), - - /** - * Used for instances of {@link BlockTree}. - */ - BLOCK(BlockTree.class), - - /** - * Used for instances of {@link BreakTree}. - */ - BREAK(BreakTree.class), - - /** - * Used for instances of {@link ClassDeclarationTree}. - */ - CLASS(ClassDeclarationTree.class), - - /** - * Used for instances of {@link ClassExpressionTree}. - */ - CLASS_EXPRESSION(ClassExpressionTree.class), - - /** - * Used for instances of {@link CaseTree}. - */ - CASE(CaseTree.class), - - /** - * Used for instances of {@link CatchTree}. - */ - CATCH(CatchTree.class), - - /** - * Used for instances of {@link CompilationUnitTree}. - */ - COMPILATION_UNIT(CompilationUnitTree.class), - - /** - * Used for instances of {@link ConditionalExpressionTree}. - */ - CONDITIONAL_EXPRESSION(ConditionalExpressionTree.class), - - /** - * Used for instances of {@link ContinueTree}. - */ - CONTINUE(ContinueTree.class), - - /** - * Used for instances of {@link DoWhileLoopTree}. - */ - DO_WHILE_LOOP(DoWhileLoopTree.class), - - /** - * Used for instances of {@link DebuggerTree}. - */ - DEBUGGER(DebuggerTree.class), - - /** - * Used for instances of {@link ForInLoopTree}. - */ - FOR_IN_LOOP(ForInLoopTree.class), - - /** - * Used for instances of {@link FunctionExpressionTree}. - */ - FUNCTION_EXPRESSION(FunctionExpressionTree.class), - - /** - * Used for instances of {@link ErroneousTree}. - */ - ERROR(ErroneousTree.class), - - /** - * Used for instances of {@link ExpressionStatementTree}. - */ - EXPRESSION_STATEMENT(ExpressionStatementTree.class), - - /** - * Used for instances of {@link MemberSelectTree}. - */ - MEMBER_SELECT(MemberSelectTree.class), - - /** - * Used for instances of {@link ForLoopTree}. - */ - FOR_LOOP(ForLoopTree.class), - - /** - * Used for instances of {@link IdentifierTree}. - */ - IDENTIFIER(IdentifierTree.class), - - /** - * Used for instances of {@link IfTree}. - */ - IF(IfTree.class), - - /** - * Used for instances of {@link InstanceOfTree}. - */ - INSTANCE_OF(InstanceOfTree.class), - - /** - * Used for instances of {@link LabeledStatementTree}. - */ - LABELED_STATEMENT(LabeledStatementTree.class), - - /** - * Used for instances of {@link ModuleTree}. - */ - MODULE(ModuleTree.class), - - /** - * Used for instances of {@link ExportEntryTree}. - */ - EXPORT_ENTRY(ExportEntryTree.class), - - /** - * Used for instances of {@link ImportEntryTree}. - */ - IMPORT_ENTRY(ImportEntryTree.class), - - /** - * Used for instances of {@link FunctionDeclarationTree}. - */ - FUNCTION(FunctionDeclarationTree.class), - - /** - * Used for instances of {@link FunctionCallTree}. - */ - FUNCTION_INVOCATION(FunctionCallTree.class), - - /** - * Used for instances of {@link NewTree}. - */ - NEW(NewTree.class), - - /** - * Used for instances of {@link ObjectLiteralTree}. - */ - OBJECT_LITERAL(ObjectLiteralTree.class), - - /** - * Used for instances of {@link ParenthesizedTree}. - */ - PARENTHESIZED(ParenthesizedTree.class), - - /** - * Used for instances of {@link PropertyTree}. - */ - PROPERTY(PropertyTree.class), - - /** - * Used for instances of {@link RegExpLiteralTree}. - */ - REGEXP_LITERAL(RegExpLiteralTree.class), - - /** - * Used for instances of {@link TemplateLiteralTree}. - */ - TEMPLATE_LITERAL(TemplateLiteralTree.class), - - /** - * Used for instances of {@link ReturnTree}. - */ - RETURN(ReturnTree.class), - - /** - * Used for instances of {@link EmptyStatementTree}. - */ - EMPTY_STATEMENT(EmptyStatementTree.class), - - /** - * Used for instances of {@link SwitchTree}. - */ - SWITCH(SwitchTree.class), - - /** - * Used for instances of {@link ThrowTree}. - */ - THROW(ThrowTree.class), - - /** - * Used for instances of {@link TryTree}. - */ - TRY(TryTree.class), - - /** - * Used for instances of {@link VariableTree}. - */ - VARIABLE(VariableTree.class), - - /** - * Used for instances of {@link WhileLoopTree}. - */ - WHILE_LOOP(WhileLoopTree.class), - - /** - * Used for instances of {@link WithTree}. - */ - WITH(WithTree.class), - - /** - * Used for instances of {@link UnaryTree} representing postfix - * increment operator {@code ++}. - */ - POSTFIX_INCREMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing postfix - * decrement operator {@code --}. - */ - POSTFIX_DECREMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing prefix - * increment operator {@code ++}. - */ - PREFIX_INCREMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing prefix - * decrement operator {@code --}. - */ - PREFIX_DECREMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing unary plus - * operator {@code +}. - */ - UNARY_PLUS(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing unary minus - * operator {@code -}. - */ - UNARY_MINUS(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing bitwise - * complement operator {@code ~}. - */ - BITWISE_COMPLEMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing logical - * complement operator {@code !}. - */ - LOGICAL_COMPLEMENT(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing logical - * delete operator {@code delete}. - */ - DELETE(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing logical - * typeof operator {@code typeof}. - */ - TYPEOF(UnaryTree.class), - - /** - * Used for instances of {@link UnaryTree} representing logical - * void operator {@code void}. - */ - VOID(UnaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * comma {@code ,}. - */ - COMMA(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * multiplication {@code *}. - */ - MULTIPLY(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * division {@code /}. - */ - DIVIDE(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * remainder {@code %}. - */ - REMAINDER(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * addition or string concatenation {@code +}. - */ - PLUS(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * subtraction {@code -}. - */ - MINUS(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * left shift {@code <<}. - */ - LEFT_SHIFT(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * right shift {@code >>}. - */ - RIGHT_SHIFT(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * unsigned right shift {@code >>>}. - */ - UNSIGNED_RIGHT_SHIFT(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * less-than {@code <}. - */ - LESS_THAN(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * greater-than {@code >}. - */ - GREATER_THAN(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * less-than-equal {@code <=}. - */ - LESS_THAN_EQUAL(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * greater-than-equal {@code >=}. - */ - GREATER_THAN_EQUAL(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * in operator {@code in}. - */ - IN(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * equal-to {@code ==}. - */ - EQUAL_TO(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * not-equal-to {@code !=}. - */ - NOT_EQUAL_TO(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * equal-to {@code ===}. - */ - STRICT_EQUAL_TO(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * not-equal-to {@code !==}. - */ - STRICT_NOT_EQUAL_TO(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * bitwise and logical "and" {@code &}. - */ - AND(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * bitwise and logical "xor" {@code ^}. - */ - XOR(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * bitwise and logical "or" {@code |}. - */ - OR(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * conditional-and {@code &&}. - */ - CONDITIONAL_AND(BinaryTree.class), - - /** - * Used for instances of {@link BinaryTree} representing - * conditional-or {@code ||}. - */ - CONDITIONAL_OR(BinaryTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * multiplication assignment {@code *=}. - */ - MULTIPLY_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * division assignment {@code /=}. - */ - DIVIDE_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * remainder assignment {@code %=}. - */ - REMAINDER_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * addition or string concatenation assignment {@code +=}. - */ - PLUS_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * subtraction assignment {@code -=}. - */ - MINUS_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * left shift assignment {@code <<=}. - */ - LEFT_SHIFT_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * right shift assignment {@code >>=}. - */ - RIGHT_SHIFT_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * unsigned right shift assignment {@code >>>=}. - */ - UNSIGNED_RIGHT_SHIFT_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * bitwise and logical "and" assignment {@code &=}. - */ - AND_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * bitwise and logical "xor" assignment {@code ^=}. - */ - XOR_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link CompoundAssignmentTree} representing - * bitwise and logical "or" assignment {@code |=}. - */ - OR_ASSIGNMENT(CompoundAssignmentTree.class), - - /** - * Used for instances of {@link SpreadTree} representing - * spread "operator" for arrays and function call arguments. - */ - SPREAD(SpreadTree.class), - - /** - * Used for instances of {@link YieldTree} representing (generator) - * yield expression {@code yield expr}. - */ - YIELD(YieldTree.class), - - /** - * Used for instances of {@link LiteralTree} representing - * a number literal expression of type {@code double}. - */ - NUMBER_LITERAL(LiteralTree.class), - - /** - * Used for instances of {@link LiteralTree} representing - * a boolean literal expression of type {@code boolean}. - */ - BOOLEAN_LITERAL(LiteralTree.class), - - /** - * Used for instances of {@link LiteralTree} representing - * a string literal expression of type {@link String}. - */ - STRING_LITERAL(LiteralTree.class), - - /** - * Used for instances of {@link LiteralTree} representing - * the use of {@code null}. - */ - NULL_LITERAL(LiteralTree.class), - - /** - * An implementation-reserved node. This is the not the node - * you are looking for. - */ - OTHER(null); - - Kind(final Class intf) { - associatedInterface = intf; - } - - /** - * Returns the associated interface type that uses this kind. - * @return the associated interface - */ - public Class asInterface() { - return associatedInterface; - } - - /** - * Returns if this is a literal tree kind or not. - * - * @return true if this is a literal tree kind, false otherwise - */ - public boolean isLiteral() { - return associatedInterface == LiteralTree.class; - } - - /** - * Returns if this is an expression tree kind or not. - * - * @return true if this is an expression tree kind, false otherwise - */ - public boolean isExpression() { - return ExpressionTree.class.isAssignableFrom(associatedInterface); - } - - /** - * Returns if this is a statement tree kind or not. - * - * @return true if this is a statement tree kind, false otherwise - */ - public boolean isStatement() { - return StatementTree.class.isAssignableFrom(associatedInterface); - } - - private final Class associatedInterface; - } - - /** - * Start character offset of this Tree within the source. - * - * @return the position - */ - long getStartPosition(); - - /** - * End character offset of this Tree within the source. - * - * @return the position - */ - long getEndPosition(); - - /** - * Gets the kind of this tree. - * - * @return the kind of this tree. - */ - Kind getKind(); - - /** - * Accept method used to implement the visitor pattern. The - * visitor pattern is used to implement operations on trees. - * - * @param result type of this operation. - * @param type of additional data. - * @param visitor tree visitor - * @param data additional data passed to visitor methods - * @return the value from visitor's visit methods - */ - R accept(TreeVisitor visitor, D data); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java deleted file mode 100644 index 5ec1e224234..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.Node; - -import jdk.nashorn.internal.parser.TokenType; - -abstract class TreeImpl implements Tree { - protected final Node node; - - TreeImpl(final Node node) { - this.node = node; - } - - @Override - public long getStartPosition() { - return node.getStart(); - } - - @Override - public long getEndPosition() { - return node.getFinish(); - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitUnknown(this, data); - } - - static Kind getOperator(final TokenType tt) { - switch(tt) { - case NEW: - return Kind.NEW; - case NOT: - return Kind.LOGICAL_COMPLEMENT; - case NE: - return Kind.NOT_EQUAL_TO; - case NE_STRICT: - return Kind.STRICT_NOT_EQUAL_TO; - case MOD: - return Kind.REMAINDER; - case ASSIGN_MOD: - return Kind.REMAINDER_ASSIGNMENT; - case BIT_AND: - return Kind.AND; - case AND: - return Kind.CONDITIONAL_AND; - case ASSIGN_BIT_AND: - return Kind.AND_ASSIGNMENT; - case MUL: - return Kind.MULTIPLY; - case ASSIGN_MUL: - return Kind.MULTIPLY_ASSIGNMENT; - case POS: - return Kind.UNARY_PLUS; - case ADD: - return Kind.PLUS; - case INCPREFIX: - return Kind.PREFIX_INCREMENT; - case INCPOSTFIX: - return Kind.POSTFIX_INCREMENT; - case ASSIGN_ADD: - return Kind.PLUS_ASSIGNMENT; - case NEG: - return Kind.UNARY_MINUS; - case SUB: - return Kind.MINUS; - case DECPREFIX: - return Kind.PREFIX_DECREMENT; - case DECPOSTFIX: - return Kind.POSTFIX_DECREMENT; - case ASSIGN_SUB: - return Kind.MINUS_ASSIGNMENT; - case DIV: - return Kind.DIVIDE; - case ASSIGN_DIV: - return Kind.DIVIDE_ASSIGNMENT; - case LT: - return Kind.LESS_THAN; - case SHL: - return Kind.LEFT_SHIFT; - case ASSIGN_SHL: - return Kind.LEFT_SHIFT_ASSIGNMENT; - case LE: - return Kind.LESS_THAN_EQUAL; - case ASSIGN: - return Kind.ASSIGNMENT; - case EQ: - return Kind.EQUAL_TO; - case EQ_STRICT: - return Kind.STRICT_EQUAL_TO; - case GT: - return Kind.GREATER_THAN; - case GE: - return Kind.GREATER_THAN_EQUAL; - case SAR: - return Kind.RIGHT_SHIFT; - case ASSIGN_SAR: - return Kind.RIGHT_SHIFT_ASSIGNMENT; - case SHR: - return Kind.UNSIGNED_RIGHT_SHIFT; - case ASSIGN_SHR: - return Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT; - case TERNARY: - return Kind.CONDITIONAL_EXPRESSION; - case BIT_XOR: - return Kind.XOR; - case ASSIGN_BIT_XOR: - return Kind.XOR_ASSIGNMENT; - case BIT_OR: - return Kind.OR; - case ASSIGN_BIT_OR: - return Kind.OR_ASSIGNMENT; - case OR: - return Kind.CONDITIONAL_OR; - case BIT_NOT: - return Kind.BITWISE_COMPLEMENT; - case DELETE: - return Kind.DELETE; - case SPREAD_ARRAY: - case SPREAD_ARGUMENT: - return Kind.SPREAD; - case TYPEOF: - return Kind.TYPEOF; - case VOID: - return Kind.VOID; - case YIELD: - return Kind.YIELD; - case IN: - return Kind.IN; - case INSTANCEOF: - return Kind.INSTANCE_OF; - case COMMARIGHT: - return Kind.COMMA; - default: - throw new AssertionError("should not reach here: " + tt); - } - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeVisitor.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeVisitor.java deleted file mode 100644 index 677df34fe2f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TreeVisitor.java +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A visitor of trees, in the style of the visitor design pattern. - * Classes implementing this interface are used to operate - * on a tree when the kind of tree is unknown at compile time. - * When a visitor is passed to an tree's {@link Tree#accept - * accept} method, the visitXyz method most applicable - * to that tree is invoked. - * - *

Classes implementing this interface may or may not throw a - * {@code NullPointerException} if the additional parameter {@code p} - * is {@code null}; see documentation of the implementing class for - * details. - * - *

WARNING: It is possible that methods will be added to - this interface to accommodate new, currently unknown, language - structures added to future versions of the ECMAScript programming - language. When new visit methods are added for new Tree subtypes, - default method bodies will be introduced which will call visitUnknown - method as a fallback. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @param the return type of this visitor's methods. Use {@link - * Void} for visitors that do not need to return results. - * @param

the type of the additional parameter to this visitor's - * methods. Use {@code Void} for visitors that do not need an - * additional parameter. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface TreeVisitor { - /** - * Visit assignment tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitAssignment(AssignmentTree node, P p); - - /** - * Visit compound assignment tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitCompoundAssignment(CompoundAssignmentTree node, P p); - - /** - * Visit binary expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitBinary(BinaryTree node, P p); - - /** - * Visit block statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitBlock(BlockTree node, P p); - - /** - * Visit break statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitBreak(BreakTree node, P p); - - /** - * Visit case statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitCase(CaseTree node, P p); - - /** - * Visit catch block statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitCatch(CatchTree node, P p); - - /** - * Visit class statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitClassDeclaration(ClassDeclarationTree node, P p); - - /** - * Visit class expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitClassExpression(ClassExpressionTree node, P p); - - /** - * Visit conditional expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitConditionalExpression(ConditionalExpressionTree node, P p); - - /** - * Visit continue statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitContinue(ContinueTree node, P p); - - /** - * Visit debugger statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitDebugger(DebuggerTree node, P p); - - /** - * Visit do-while statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitDoWhileLoop(DoWhileLoopTree node, P p); - - /** - * Visit error expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitErroneous(ErroneousTree node, P p); - - /** - * Visit expression statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitExpressionStatement(ExpressionStatementTree node, P p); - - /** - * Visit 'for' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitForLoop(ForLoopTree node, P p); - - /** - * Visit for..in statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitForInLoop(ForInLoopTree node, P p); - - /** - * Visit for..of statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitForOfLoop(ForOfLoopTree node, P p); - - /** - * Visit function call expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitFunctionCall(FunctionCallTree node, P p); - - /** - * Visit function declaration tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitFunctionDeclaration(FunctionDeclarationTree node, P p); - - /** - * Visit function expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitFunctionExpression(FunctionExpressionTree node, P p); - - /** - * Visit identifier tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitIdentifier(IdentifierTree node, P p); - - /** - * Visit 'if' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitIf(IfTree node, P p); - - /** - * Visit array access expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitArrayAccess(ArrayAccessTree node, P p); - - /** - * Visit array literal expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitArrayLiteral(ArrayLiteralTree node, P p); - - /** - * Visit labeled statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitLabeledStatement(LabeledStatementTree node, P p); - - /** - * Visit literal expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitLiteral(LiteralTree node, P p); - - /** - * Visit parenthesized expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitParenthesized(ParenthesizedTree node, P p); - - /** - * Visit return statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitReturn(ReturnTree node, P p); - - /** - * Visit member select expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitMemberSelect(MemberSelectTree node, P p); - - /** - * Visit 'new' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitNew(NewTree node, P p); - - /** - * Visit object literal tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitObjectLiteral(ObjectLiteralTree node, P p); - - /** - * Visit a property of an object literal expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitProperty(PropertyTree node, P p); - - /** - * Visit regular expression literal tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitRegExpLiteral(RegExpLiteralTree node, P p); - - /** - * Visit template literal tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitTemplateLiteral(TemplateLiteralTree node, P p); - - /** - * Visit an empty statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitEmptyStatement(EmptyStatementTree node, P p); - - /** - * Visit 'spread' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitSpread(SpreadTree node, P p); - - /** - * Visit 'switch' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitSwitch(SwitchTree node, P p); - - /** - * Visit 'throw' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitThrow(ThrowTree node, P p); - - /** - * Visit compilation unit tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitCompilationUnit(CompilationUnitTree node, P p); - - /** - * Visit Module tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitModule(ModuleTree node, P p); - - /** - * Visit Module ExportEntry tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitExportEntry(ExportEntryTree node, P p); - - /** - * Visit Module ImportEntry tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitImportEntry(ImportEntryTree node, P p); - - /** - * Visit 'try' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitTry(TryTree node, P p); - - /** - * Visit 'instanceof' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitInstanceOf(InstanceOfTree node, P p); - - /** - * Visit unary expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitUnary(UnaryTree node, P p); - - /** - * Visit variable declaration tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitVariable(VariableTree node, P p); - - /** - * Visit 'while' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitWhileLoop(WhileLoopTree node, P p); - - /** - * Visit 'with' statement tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitWith(WithTree node, P p); - - /** - * Visit 'yield' expression tree. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitYield(YieldTree node, P p); - - /** - * Visit unknown expression/statement tree. This fallback will be - * called if new Tree subtypes are introduced in future. A specific - * implementation may throw {{@linkplain UnknownTreeException unknown tree exception} - * if the visitor implementation was for an older language version. - * - * @param node node being visited - * @param p extra parameter passed to the visitor - * @return value from the visitor - */ - R visitUnknown(Tree node, P p); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTree.java deleted file mode 100644 index 8aaad475dfa..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTree.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; - -/** - * A tree node for a 'try' statement. - * - * For example: - *

- *   try
- *       block
- *   catches
- *   finally
- *       finallyBlock
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface TryTree extends StatementTree { - /** - * Returns the 'try' block of this 'try' statement. - * - * @return the 'try' block - */ - BlockTree getBlock(); - - /** - * Returns the list of 'catch' statements associated with this 'try'. - * - * @return the list of 'catch' statements associated with this 'try'. - */ - List getCatches(); - - /** - * Returns the 'finally' block associated with this 'try'. This is - * null if there is no 'finally' block associated with this 'try'. - * - * @return the 'finally' block associated with this 'try'. - */ - BlockTree getFinallyBlock(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTreeImpl.java deleted file mode 100644 index e9aafff762c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/TryTreeImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import java.util.List; -import jdk.nashorn.internal.ir.TryNode; - -final class TryTreeImpl extends StatementTreeImpl implements TryTree { - private final BlockTree block; - private final List catches; - private final BlockTree finallyBlock; - TryTreeImpl(final TryNode node, - final BlockTree block, - final List catches, - final BlockTree finallyBlock) { - super(node); - this.block = block; - this.catches = catches; - this.finallyBlock = finallyBlock; - } - - @Override - public Kind getKind() { - return Kind.TRY; - } - - @Override - public BlockTree getBlock() { - return block; - } - - @Override - public List getCatches() { - return catches; - } - - @Override - public BlockTree getFinallyBlock() { - return finallyBlock; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitTry(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTree.java deleted file mode 100644 index bcc6eb0817f..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTree.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for postfix and unary expressions. - * Use {@link #getKind getKind} to determine the kind of operator. - * - * For example: - *
- *   operator expression
- *
- *   expression operator
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface UnaryTree extends ExpressionTree { - /** - * Returns the expression operated by the unary operator. - * - * @return The expression operated by the unary operator. - */ - ExpressionTree getExpression(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTreeImpl.java deleted file mode 100644 index 6b72c24221b..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnaryTreeImpl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.UnaryNode; - -class UnaryTreeImpl extends ExpressionTreeImpl implements UnaryTree { - private final ExpressionTree expr; - private final Kind kind; - UnaryTreeImpl(final UnaryNode node, final ExpressionTree expr) { - super(node); - this.expr = expr; - this.kind = getOperator(node.tokenType()); - } - - @Override - public Kind getKind() { - return kind; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitUnary(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnknownTreeException.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnknownTreeException.java deleted file mode 100644 index fc601585416..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/UnknownTreeException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - - -/** - * Indicates that an unknown kind of Tree was encountered. This - * can occur if the language evolves and new kinds of Trees are - * added to the {@code Tree} hierarchy. May be thrown by a - * {@linkplain TreeVisitor tree visitor} to indicate that the - * visitor was created for a prior version of the language. - * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public class UnknownTreeException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private transient final Tree tree; - private transient final Object parameter; - - /** - * Creates a new {@code UnknownTreeException}. The {@code p} - * parameter may be used to pass in an additional argument with - * information about the context in which the unknown element was - * encountered; for example, the visit methods of {@link - * TreeVisitor} may pass in their additional parameter. - * - * @param t the unknown tree, may be {@code null} - * @param p an additional parameter, may be {@code null} - */ - public UnknownTreeException(final Tree t, final Object p) { - super("Unknown tree: " + t); - this.tree = t; - this.parameter = p; - } - - /** - * Returns the unknown tree. - * The value may be unavailable if this exception has been - * serialized and then read back in. - * - * @return the unknown element, or {@code null} if unavailable - */ - public Tree getUnknownTree() { - return tree; - } - - /** - * Returns the additional argument. - * The value may be unavailable if this exception has been - * serialized and then read back in. - * - * @return the additional argument - */ - public Object getArgument() { - return parameter; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTree.java deleted file mode 100644 index e055ebdfada..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTree.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a variable declaration statement. - * - * For example: - *
- *   var name [ initializer ] ;
- *   var binding_pattern [ initializer ];
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface VariableTree extends StatementTree { - /** - * Returns the binding of this declaration. This is an {@link IdentifierTree} - * for a binding identifier case (simple variable declaration). - * This is an {@link ObjectLiteralTree} or a {@link ArrayLiteralTree} for a - * destructuring declaration. - * - * @return the binding expression of this declaration - */ - ExpressionTree getBinding(); - - /** - * Returns the initial value expression for this variable. This is - * null if no initial value for this variable. - * - * @return the initial value expression - */ - ExpressionTree getInitializer(); - - /** - * Is this a const declaration? - * - * @return true if this is a const declaration - */ - boolean isConst(); - - /** - * Is this a let declaration? - * - * @return true if this is a let declaration - */ - boolean isLet(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTreeImpl.java deleted file mode 100644 index a1e6f6f7e89..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/VariableTreeImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.VarNode; - -final class VariableTreeImpl extends StatementTreeImpl implements VariableTree { - private final IdentifierTree ident; - private final ExpressionTree init; - - VariableTreeImpl(final VarNode node, final IdentifierTree ident, final ExpressionTree init) { - super(node); - this.ident = ident; - this.init = init; - } - - @Override - public Kind getKind() { - return Kind.VARIABLE; - } - - @Override - public ExpressionTree getBinding() { - return ident; - } - - @Override - public ExpressionTree getInitializer() { - return init; - } - - @Override - public boolean isConst() { - return ((VarNode)node).isConst(); - } - - @Override - public boolean isLet() { - return ((VarNode)node).isLet(); - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitVariable(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTree.java deleted file mode 100644 index cfda191692e..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTree.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'while' loop statement. - * - * For example: - *
- *   while ( condition )
- *     statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface WhileLoopTree extends ConditionalLoopTree { - /** - * The condition expression of this 'while' statement. - * - * @return the condition expression - */ - @Override - ExpressionTree getCondition(); - - /** - * The statement contained in this 'while' statement. - * - * @return the statement contained - */ - @Override - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTreeImpl.java deleted file mode 100644 index 3bc1507d2d2..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WhileLoopTreeImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.WhileNode; - -final class WhileLoopTreeImpl extends StatementTreeImpl implements WhileLoopTree { - private final ExpressionTree cond; - private final StatementTree stat; - - WhileLoopTreeImpl(final WhileNode node, final ExpressionTree cond, final StatementTree stat) { - super(node); - assert !node.isDoWhile() : "while expected"; - this.cond = cond; - this.stat = stat; - } - - @Override - public Tree.Kind getKind() { - return Tree.Kind.WHILE_LOOP; - } - - @Override - public ExpressionTree getCondition() { - return cond; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitWhileLoop(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTree.java deleted file mode 100644 index f08085b2d2c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTree.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for a 'with' statement. - * - * For example: - *
- *   with ( scope )
- *     statement
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface WithTree extends StatementTree { - /** - * The scope object expression for this 'with' statement. - * - * @return the scope object - */ - ExpressionTree getScope(); - - /** - * The statement contained in this 'with' statement. - * - * @return the statement contained - */ - StatementTree getStatement(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTreeImpl.java deleted file mode 100644 index 4b726551a27..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/WithTreeImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.WithNode; - -final class WithTreeImpl extends StatementTreeImpl implements WithTree { - private final ExpressionTree scope; - private final StatementTree stat; - WithTreeImpl(final WithNode node, final ExpressionTree scope, - final StatementTree stat) { - super(node); - this.scope = scope; - this.stat = stat; - } - - @Override - public Kind getKind() { - return Kind.WITH; - } - - @Override - public ExpressionTree getScope() { - return scope; - } - - @Override - public StatementTree getStatement() { - return stat; - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitWith(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTree.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTree.java deleted file mode 100644 index 8ba8e20113c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTree.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.tree; - -/** - * A tree node for yield expressions used in generator functions. - * - * For example: - *
- * function* id(){
- *     var index = 0;
- *     while(index < 10)
- *         yield index++;
- * }
- * 
- * - * @deprecated Nashorn JavaScript script engine and APIs, and the jjs tool - * are deprecated with the intent to remove them in a future release. - * - * @since 9 - */ -@Deprecated(since="11", forRemoval=true) -public interface YieldTree extends ExpressionTree { - /** - * Returns the expression that is yielded. - * - * @return The expression that is yielded. - */ - ExpressionTree getExpression(); - - /** - * Is this a yield * expression in a generator function? - * - * For example: - *
-     * function* id(){
-     *     yield 1;
-     *     yield * anotherGeneratorFunc();
-     *     yield 10;
-     * }
-     * 
- * - * - * @return true if this is a yield * expression - */ - boolean isStar(); -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTreeImpl.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTreeImpl.java deleted file mode 100644 index aea75d81a4c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/YieldTreeImpl.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.tree; - -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.parser.TokenType; - -final class YieldTreeImpl extends ExpressionTreeImpl - implements YieldTree { - - private final ExpressionTree expr; - - YieldTreeImpl(final Expression exprNode, final ExpressionTree expr) { - super(exprNode); - this.expr = expr; - } - - @Override - public Kind getKind() { - return Kind.YIELD; - } - - @Override - public ExpressionTree getExpression() { - return expr; - } - - @Override - public boolean isStar() { - return ((UnaryNode) node).isTokenType(TokenType.YIELD_STAR); - } - - @Override - public R accept(final TreeVisitor visitor, final D data) { - return visitor.visitYield(this, data); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/package-info.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/package-info.java deleted file mode 100644 index 832de0b0596..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/tree/package-info.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - *

- * Nashorn parser API provides interfaces to represent ECMAScript source code - * as abstract syntax trees (AST) and Parser to parse ECMAScript source scripts. - *

- *

- * Using parser API user can write Java code to access parse tree - * representation of ECMAScript source. Script source may be a file, - * a URL or a String. Unless stated otherwise null argument in methods of this - * package result in NullPointerException being thrown. - *

- * - *
- * 
- * import jdk.nashorn.api.tree.*;
- * import java.io.File;
- *
- * // Simple example that prints warning on 'with' statements
- * public class Main {
- *     public static void main(String[] args) throws Exception {
- *         // Create a new parser instance
- *         Parser parser = Parser.create();
- *         File sourceFile = new File(args[0]);
- *
- *         // Parse given source File using parse method.
- *         // Pass a diagnostic listener to print error messages.
- *         CompilationUnitTree cut = parser.parse(sourceFile,
- *             (d) -> { System.out.println(d); });
- *
- *         if (cut != null) {
- *             // call Tree.accept method passing a SimpleTreeVisitor
- *             cut.accept(new SimpleTreeVisitor<Void, Void>() {
- *                 // visit method for 'with' statement
- *                 public Void visitWith(WithTree wt, Void v) {
- *                     // print warning on 'with' statement
- *                     System.out.println("Warning: using 'with' statement!");
- *                     return null;
- *                 }
- *             }, null);
- *         }
- *     }
- * }
- * 
- * 
- * - * @since 9 - */ -package jdk.nashorn.api.tree; - diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/AssertsEnabled.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/AssertsEnabled.java deleted file mode 100644 index e4752658146..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/AssertsEnabled.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal; - -/** - * Class that exposes the current state of asserts. - */ -public final class AssertsEnabled { - private static boolean assertsEnabled = false; - static { - assert assertsEnabled = true; // Intentional side effect - } - - /** - * Returns true if asserts are enabled - * @return true if asserts are enabled - */ - public static boolean assertsEnabled() { - return assertsEnabled; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/IntDeque.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/IntDeque.java deleted file mode 100644 index 477afcf94ae..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/IntDeque.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal; - -/** - * Small helper class for fast int deques - */ -public class IntDeque { - private int[] deque = new int[16]; - private int nextFree = 0; - - /** - * Push an int value - * @param value value - */ - public void push(final int value) { - if (nextFree == deque.length) { - final int[] newDeque = new int[nextFree * 2]; - System.arraycopy(deque, 0, newDeque, 0, nextFree); - deque = newDeque; - } - deque[nextFree++] = value; - } - - /** - * Pop an int value - * @return value - */ - public int pop() { - return deque[--nextFree]; - } - - /** - * Peek - * @return top value - */ - public int peek() { - return deque[nextFree - 1]; - } - - /** - * Get the value of the top element and increment it. - * @return top value - */ - public int getAndIncrement() { - return deque[nextFree - 1]++; - } - - /** - * Decrement the value of the top element and return it. - * @return decremented top value - */ - public int decrementAndGet() { - return --deque[nextFree - 1]; - } - - /** - * Check if deque is empty - * @return true if empty - */ - public boolean isEmpty() { - return nextFree == 0; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/WeakValueCache.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/WeakValueCache.java deleted file mode 100644 index b1a1671e224..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/WeakValueCache.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.function.Function; - -/** - * This class provides a map based cache with weakly referenced values. Cleared references are - * purged from the underlying map when values are retrieved or created. - * It uses a {@link java.util.HashMap} to store values and needs to be externally synchronized. - * - * @param the key type - * @param the value type - */ -public final class WeakValueCache { - - private final HashMap> map = new HashMap<>(); - private final ReferenceQueue refQueue = new ReferenceQueue<>(); - - /** - * Returns the value associated with {@code key}, or {@code null} if no such value exists. - * - * @param key the key - * @return the value or null if none exists - */ - public V get(final K key) { - // Remove cleared entries - for (;;) { - final KeyValueReference ref = (KeyValueReference) refQueue.poll(); - if (ref == null) { - break; - } - map.remove(ref.key, ref); - } - - final KeyValueReference ref = map.get(key); - if (ref != null) { - return ref.get(); - } - return null; - } - - /** - * Returns the value associated with {@code key}, or creates and returns a new value if - * no value exists using the {@code creator} function. - * - * @param key the key - * @param creator function to create a new value - * @return the existing value, or a new one if none existed - */ - public V getOrCreate(final K key, final Function creator) { - V value = get(key); - - if (value == null) { - // Define a new value if it does not exist - value = creator.apply(key); - map.put(key, new KeyValueReference<>(key, value)); - } - - return value; - } - - private static class KeyValueReference extends WeakReference { - final K key; - - KeyValueReference(final K key, final V value) { - super(value); - this.key = key; - } - } - -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ApplySpecialization.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ApplySpecialization.java deleted file mode 100644 index 51abacdbbe6..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ApplySpecialization.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; -import static jdk.nashorn.internal.codegen.CompilerConstants.EXPLODED_ARGUMENT_PREFIX; - -import java.lang.invoke.MethodType; -import java.net.URL; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.CallNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.logging.DebugLogger; -import jdk.nashorn.internal.runtime.logging.Loggable; -import jdk.nashorn.internal.runtime.logging.Logger; -import jdk.nashorn.internal.runtime.options.Options; - -/** - * An optimization that attempts to turn applies into calls. This pattern - * is very common for fake class instance creation, and apply - * introduces expensive args collection and boxing - * - *
- * var Class = {
- *     create: function() {
- *         return function() { //vararg
- *             this.initialize.apply(this, arguments);
- *         }
- *     }
- * };
- *
- * Color = Class.create();
- *
- * Color.prototype = {
- *    red: 0, green: 0, blue: 0,
- *    initialize: function(r,g,b) {
- *        this.red = r;
- *        this.green = g;
- *        this.blue = b;
- *    }
- * }
- *
- * new Color(17, 47, 11);
- * 
- */ - -@Logger(name="apply2call") -public final class ApplySpecialization extends SimpleNodeVisitor implements Loggable { - - private static final boolean USE_APPLY2CALL = Options.getBooleanProperty("nashorn.apply2call", true); - - private final DebugLogger log; - - private final Compiler compiler; - - private final Set changed = new HashSet<>(); - - private final Deque> explodedArguments = new ArrayDeque<>(); - - private final Deque callSiteTypes = new ArrayDeque<>(); - - private static final String ARGUMENTS = ARGUMENTS_VAR.symbolName(); - - /** - * Apply specialization optimization. Try to explode arguments and call - * applies as calls if they just pass on the "arguments" array and - * "arguments" doesn't escape. - * - * @param compiler compiler - */ - public ApplySpecialization(final Compiler compiler) { - this.compiler = compiler; - this.log = initLogger(compiler.getContext()); - } - - @Override - public DebugLogger getLogger() { - return log; - } - - @Override - public DebugLogger initLogger(final Context context) { - return context.getLogger(this.getClass()); - } - - @SuppressWarnings("serial") - private static class TransformFailedException extends RuntimeException { - TransformFailedException(final FunctionNode fn, final String message) { - super(massageURL(fn.getSource().getURL()) + '.' + fn.getName() + " => " + message, null, false, false); - } - } - - @SuppressWarnings("serial") - private static class AppliesFoundException extends RuntimeException { - AppliesFoundException() { - super("applies_found", null, false, false); - } - } - - private static final AppliesFoundException HAS_APPLIES = new AppliesFoundException(); - - private boolean hasApplies(final FunctionNode functionNode) { - try { - functionNode.accept(new SimpleNodeVisitor() { - @Override - public boolean enterFunctionNode(final FunctionNode fn) { - return fn == functionNode; - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - if (isApply(callNode)) { - throw HAS_APPLIES; - } - return true; - } - }); - } catch (final AppliesFoundException e) { - return true; - } - - log.fine("There are no applies in ", DebugLogger.quote(functionNode.getName()), " - nothing to do."); - return false; // no applies - } - - /** - * Arguments may only be used as args to the apply. Everything else is disqualified - * We cannot control arguments if they escape from the method and go into an unknown - * scope, thus we are conservative and treat any access to arguments outside the - * apply call as a case of "we cannot apply the optimization". - */ - private static void checkValidTransform(final FunctionNode functionNode) { - - final Set argumentsFound = new HashSet<>(); - final Deque> stack = new ArrayDeque<>(); - - //ensure that arguments is only passed as arg to apply - functionNode.accept(new SimpleNodeVisitor() { - - private boolean isCurrentArg(final Expression expr) { - return !stack.isEmpty() && stack.peek().contains(expr); //args to current apply call - } - - private boolean isArguments(final Expression expr) { - if (expr instanceof IdentNode && ARGUMENTS.equals(((IdentNode)expr).getName())) { - argumentsFound.add(expr); - return true; - } - return false; - } - - private boolean isParam(final String name) { - for (final IdentNode param : functionNode.getParameters()) { - if (param.getName().equals(name)) { - return true; - } - } - return false; - } - - @Override - public Node leaveIdentNode(final IdentNode identNode) { - if (isParam(identNode.getName())) { - throw new TransformFailedException(lc.getCurrentFunction(), "parameter: " + identNode.getName()); - } - // it's OK if 'argument' occurs as the current argument of an apply - if (isArguments(identNode) && !isCurrentArg(identNode)) { - throw new TransformFailedException(lc.getCurrentFunction(), "is 'arguments': " + identNode.getName()); - } - return identNode; - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - final Set callArgs = new HashSet<>(); - if (isApply(callNode)) { - final List argList = callNode.getArgs(); - if (argList.size() != 2 || !isArguments(argList.get(argList.size() - 1))) { - throw new TransformFailedException(lc.getCurrentFunction(), "argument pattern not matched: " + argList); - } - callArgs.addAll(callNode.getArgs()); - } - stack.push(callArgs); - return true; - } - - @Override - public Node leaveCallNode(final CallNode callNode) { - stack.pop(); - return callNode; - } - }); - } - - @Override - public boolean enterCallNode(final CallNode callNode) { - return !explodedArguments.isEmpty(); - } - - @Override - public Node leaveCallNode(final CallNode callNode) { - //apply needs to be a global symbol or we don't allow it - - final List newParams = explodedArguments.peek(); - if (isApply(callNode)) { - final List newArgs = new ArrayList<>(); - for (final Expression arg : callNode.getArgs()) { - if (arg instanceof IdentNode && ARGUMENTS.equals(((IdentNode)arg).getName())) { - newArgs.addAll(newParams); - } else { - newArgs.add(arg); - } - } - - changed.add(lc.getCurrentFunction().getId()); - - final CallNode newCallNode = callNode.setArgs(newArgs).setIsApplyToCall(); - - if (log.isEnabled()) { - log.fine("Transformed ", - callNode, - " from apply to call => ", - newCallNode, - " in ", - DebugLogger.quote(lc.getCurrentFunction().getName())); - } - - return newCallNode; - } - - return callNode; - } - - private void pushExplodedArgs(final FunctionNode functionNode) { - int start = 0; - - final MethodType actualCallSiteType = compiler.getCallSiteType(functionNode); - if (actualCallSiteType == null) { - throw new TransformFailedException(lc.getCurrentFunction(), "No callsite type"); - } - assert actualCallSiteType.parameterType(actualCallSiteType.parameterCount() - 1) != Object[].class : "error vararg callsite passed to apply2call " + functionNode.getName() + " " + actualCallSiteType; - - final TypeMap ptm = compiler.getTypeMap(); - if (ptm.needsCallee()) { - start++; - } - - start++; // we always use this - - assert functionNode.getNumOfParams() == 0 : "apply2call on function with named paramaters!"; - final List newParams = new ArrayList<>(); - final long to = actualCallSiteType.parameterCount() - start; - for (int i = 0; i < to; i++) { - newParams.add(new IdentNode(functionNode.getToken(), functionNode.getFinish(), EXPLODED_ARGUMENT_PREFIX.symbolName() + (i))); - } - - callSiteTypes.push(actualCallSiteType); - explodedArguments.push(newParams); - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - // Cheap tests first - if (!( - // is the transform globally enabled? - USE_APPLY2CALL - - // Are we compiling lazily? We can't known the number and types of the actual parameters at - // the caller when compiling eagerly, so this only works with on-demand compilation. - && compiler.isOnDemandCompilation() - - // Does the function even reference the "arguments" identifier (without redefining it)? If not, - // it trivially can't have an expression of form "f.apply(self, arguments)" that this transform - // is targeting. - && functionNode.needsArguments() - - // Does the function have eval? If so, it can arbitrarily modify arguments so we can't touch it. - && !functionNode.hasEval() - - // Finally, does the function declare any parameters explicitly? We don't support that. It could - // be done, but has some complications. Therefore only a function with no explicit parameters - // is considered. - && functionNode.getNumOfParams() == 0)) - { - return false; - } - - if (!Global.isBuiltinFunctionPrototypeApply()) { - log.fine("Apply transform disabled: apply/call overridden"); - assert !Global.isBuiltinFunctionPrototypeCall() : "call and apply should have the same SwitchPoint"; - return false; - } - - if (!hasApplies(functionNode)) { - return false; - } - - if (log.isEnabled()) { - log.info("Trying to specialize apply to call in '", - functionNode.getName(), - "' params=", - functionNode.getParameters(), - " id=", - functionNode.getId(), - " source=", - massageURL(functionNode.getSource().getURL())); - } - - try { - checkValidTransform(functionNode); - pushExplodedArgs(functionNode); - } catch (final TransformFailedException e) { - log.info("Failure: ", e.getMessage()); - return false; - } - - return true; - } - - /** - * Try to do the apply to call transformation - * @return true if successful, false otherwise - */ - @Override - public Node leaveFunctionNode(final FunctionNode functionNode) { - FunctionNode newFunctionNode = functionNode; - final String functionName = newFunctionNode.getName(); - - if (changed.contains(newFunctionNode.getId())) { - newFunctionNode = newFunctionNode.clearFlag(lc, FunctionNode.USES_ARGUMENTS). - setFlag(lc, FunctionNode.HAS_APPLY_TO_CALL_SPECIALIZATION). - setParameters(lc, explodedArguments.peek()); - - if (log.isEnabled()) { - log.info("Success: ", - massageURL(newFunctionNode.getSource().getURL()), - '.', - functionName, - "' id=", - newFunctionNode.getId(), - " params=", - callSiteTypes.peek()); - } - } - - callSiteTypes.pop(); - explodedArguments.pop(); - - return newFunctionNode; - } - - private static boolean isApply(final CallNode callNode) { - final Expression f = callNode.getFunction(); - return f instanceof AccessNode && "apply".equals(((AccessNode)f).getProperty()); - } - - private static String massageURL(final URL url) { - if (url == null) { - return ""; - } - final String str = url.toString(); - final int slash = str.lastIndexOf('/'); - if (slash == -1) { - return str; - } - return str.substring(slash + 1); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java deleted file mode 100644 index f01c7f9c259..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java +++ /dev/null @@ -1,976 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; -import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; -import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.RETURN; -import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; -import static jdk.nashorn.internal.codegen.CompilerConstants.SWITCH_TAG_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; -import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; -import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE; -import static jdk.nashorn.internal.ir.Symbol.IS_CONST; -import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF; -import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; -import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; -import static jdk.nashorn.internal.ir.Symbol.IS_LET; -import static jdk.nashorn.internal.ir.Symbol.IS_PARAM; -import static jdk.nashorn.internal.ir.Symbol.IS_PROGRAM_LEVEL; -import static jdk.nashorn.internal.ir.Symbol.IS_SCOPE; -import static jdk.nashorn.internal.ir.Symbol.IS_THIS; -import static jdk.nashorn.internal.ir.Symbol.IS_VAR; -import static jdk.nashorn.internal.ir.Symbol.KINDMASK; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BaseNode; -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.CatchNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.ForNode; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IndexNode; -import jdk.nashorn.internal.ir.LexicalContextNode; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.RuntimeNode.Request; -import jdk.nashorn.internal.ir.Splittable; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.SwitchNode; -import jdk.nashorn.internal.ir.Symbol; -import jdk.nashorn.internal.ir.TryNode; -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.VarNode; -import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor; -import jdk.nashorn.internal.parser.TokenType; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ECMAErrors; -import jdk.nashorn.internal.runtime.ErrorManager; -import jdk.nashorn.internal.runtime.JSErrorType; -import jdk.nashorn.internal.runtime.ParserException; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.logging.DebugLogger; -import jdk.nashorn.internal.runtime.logging.Loggable; -import jdk.nashorn.internal.runtime.logging.Logger; - -/** - * This visitor assigns symbols to identifiers denoting variables. It does few more minor calculations that are only - * possible after symbols have been assigned; such is the transformation of "delete" and "typeof" operators into runtime - * nodes and counting of number of properties assigned to "this" in constructor functions. This visitor is also notable - * for what it doesn't do, most significantly it does no type calculations as in JavaScript variables can change types - * during runtime and as such symbols don't have types. Calculation of expression types is performed by a separate - * visitor. - */ -@Logger(name="symbols") -final class AssignSymbols extends SimpleNodeVisitor implements Loggable { - private final DebugLogger log; - private final boolean debug; - - private static boolean isParamOrVar(final IdentNode identNode) { - final Symbol symbol = identNode.getSymbol(); - return symbol.isParam() || symbol.isVar(); - } - - private static String name(final Node node) { - final String cn = node.getClass().getName(); - final int lastDot = cn.lastIndexOf('.'); - if (lastDot == -1) { - return cn; - } - return cn.substring(lastDot + 1); - } - - /** - * Checks if various symbols that were provisionally marked as needing a slot ended up unused, and marks them as not - * needing a slot after all. - * @param functionNode the function node - * @return the passed in node, for easy chaining - */ - private static FunctionNode removeUnusedSlots(final FunctionNode functionNode) { - if (!functionNode.needsCallee()) { - functionNode.compilerConstant(CALLEE).setNeedsSlot(false); - } - if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) { - functionNode.compilerConstant(SCOPE).setNeedsSlot(false); - } - // Named function expressions that end up not referencing themselves won't need a local slot for the self symbol. - if(functionNode.isNamedFunctionExpression() && !functionNode.usesSelfSymbol()) { - final Symbol selfSymbol = functionNode.getBody().getExistingSymbol(functionNode.getIdent().getName()); - if(selfSymbol != null && selfSymbol.isFunctionSelf()) { - selfSymbol.setNeedsSlot(false); - selfSymbol.clearFlag(Symbol.IS_VAR); - } - } - return functionNode; - } - - private final Deque> thisProperties = new ArrayDeque<>(); - private final Map globalSymbols = new HashMap<>(); //reuse the same global symbol - private final Compiler compiler; - private final boolean isOnDemand; - - public AssignSymbols(final Compiler compiler) { - this.compiler = compiler; - this.log = initLogger(compiler.getContext()); - this.debug = log.isEnabled(); - this.isOnDemand = compiler.isOnDemandCompilation(); - } - - @Override - public DebugLogger getLogger() { - return log; - } - - @Override - public DebugLogger initLogger(final Context context) { - return context.getLogger(this.getClass()); - } - - /** - * Define symbols for all variable declarations at the top of the function scope. This way we can get around - * problems like - * - * while (true) { - * break; - * if (true) { - * var s; - * } - * } - * - * to an arbitrary nesting depth. - * - * see NASHORN-73 - * - * @param functionNode the FunctionNode we are entering - * @param body the body of the FunctionNode we are entering - */ - private void acceptDeclarations(final FunctionNode functionNode, final Block body) { - // This visitor will assign symbol to all declared variables. - body.accept(new SimpleNodeVisitor() { - @Override - protected boolean enterDefault(final Node node) { - // Don't bother visiting expressions; var is a statement, it can't be inside an expression. - // This will also prevent visiting nested functions (as FunctionNode is an expression). - return !(node instanceof Expression); - } - - @Override - public Node leaveVarNode(final VarNode varNode) { - final IdentNode ident = varNode.getName(); - final boolean blockScoped = varNode.isBlockScoped(); - if (blockScoped && lc.inUnprotectedSwitchContext()) { - throwUnprotectedSwitchError(varNode); - } - final Block block = blockScoped ? lc.getCurrentBlock() : body; - final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags()); - if (varNode.isFunctionDeclaration()) { - symbol.setIsFunctionDeclaration(); - } - return varNode.setName(ident.setSymbol(symbol)); - } - }); - } - - private IdentNode compilerConstantIdentifier(final CompilerConstants cc) { - return createImplicitIdentifier(cc.symbolName()).setSymbol(lc.getCurrentFunction().compilerConstant(cc)); - } - - /** - * Creates an ident node for an implicit identifier within the function (one not declared in the script source - * code). These identifiers are defined with function's token and finish. - * @param name the name of the identifier - * @return an ident node representing the implicit identifier. - */ - private IdentNode createImplicitIdentifier(final String name) { - final FunctionNode fn = lc.getCurrentFunction(); - return new IdentNode(fn.getToken(), fn.getFinish(), name); - } - - private Symbol createSymbol(final String name, final int flags) { - if ((flags & Symbol.KINDMASK) == IS_GLOBAL) { - //reuse global symbols so they can be hashed - Symbol global = globalSymbols.get(name); - if (global == null) { - global = new Symbol(name, flags); - globalSymbols.put(name, global); - } - return global; - } - return new Symbol(name, flags); - } - - /** - * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically - * used to create assignment of {@code :callee} to the function name symbol in self-referential function - * expressions as well as for assignment of {@code :arguments} to {@code arguments}. - * - * @param name the ident node identifying the variable to initialize - * @param initConstant the compiler constant it is initialized to - * @param fn the function node the assignment is for - * @return a var node with the appropriate assignment - */ - private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { - final IdentNode init = compilerConstantIdentifier(initConstant); - assert init.getSymbol() != null && init.getSymbol().isBytecodeLocal(); - - final VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); - - final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); - assert nameSymbol != null; - - return (VarNode)synthVar.setName(name.setSymbol(nameSymbol)).accept(this); - } - - private FunctionNode createSyntheticInitializers(final FunctionNode functionNode) { - final List syntheticInitializers = new ArrayList<>(2); - - // Must visit the new var nodes in the context of the body. We could also just set the new statements into the - // block and then revisit the entire block, but that seems to be too much double work. - final Block body = functionNode.getBody(); - lc.push(body); - try { - if (functionNode.usesSelfSymbol()) { - // "var fn = :callee" - syntheticInitializers.add(createSyntheticInitializer(functionNode.getIdent(), CALLEE, functionNode)); - } - - if (functionNode.needsArguments()) { - // "var arguments = :arguments" - syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), - ARGUMENTS, functionNode)); - } - - if (syntheticInitializers.isEmpty()) { - return functionNode; - } - - for(final ListIterator it = syntheticInitializers.listIterator(); it.hasNext();) { - it.set((VarNode)it.next().accept(this)); - } - } finally { - lc.pop(body); - } - - final List stmts = body.getStatements(); - final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); - newStatements.addAll(syntheticInitializers); - newStatements.addAll(stmts); - return functionNode.setBody(lc, body.setStatements(lc, newStatements)); - } - - /** - * Defines a new symbol in the given block. - * - * @param block the block in which to define the symbol - * @param name name of symbol. - * @param origin origin node - * @param symbolFlags Symbol flags. - * - * @return Symbol for given name or null for redefinition. - */ - private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) { - int flags = symbolFlags; - final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0; - final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL; - - Symbol symbol; - final FunctionNode function; - if (isBlockScope) { - // block scoped variables always live in current block, no need to look for existing symbols in parent blocks. - symbol = block.getExistingSymbol(name); - function = lc.getCurrentFunction(); - } else { - symbol = findSymbol(block, name); - function = lc.getFunction(block); - } - - // Global variables are implicitly always scope variables too. - if (isGlobal) { - flags |= IS_SCOPE; - } - - if (lc.getCurrentFunction().isProgram()) { - flags |= IS_PROGRAM_LEVEL; - } - - final boolean isParam = (flags & KINDMASK) == IS_PARAM; - final boolean isVar = (flags & KINDMASK) == IS_VAR; - - if (symbol != null) { - // Symbol was already defined. Check if it needs to be redefined. - if (isParam) { - if (!isLocal(function, symbol)) { - // Not defined in this function. Create a new definition. - symbol = null; - } else if (symbol.isParam()) { - // Duplicate parameter. Null return will force an error. - throwParserException(ECMAErrors.getMessage("syntax.error.duplicate.parameter", name), origin); - } - } else if (isVar) { - if (isBlockScope) { - // Check redeclaration in same block - if (symbol.hasBeenDeclared()) { - throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin); - } else { - symbol.setHasBeenDeclared(); - // Set scope flag on top-level block scoped symbols - if (function.isProgram() && function.getBody() == block) { - symbol.setIsScope(); - } - } - } else if ((flags & IS_INTERNAL) != 0) { - // Always create a new definition. - symbol = null; - } else { - // Found LET or CONST in parent scope of same function - s SyntaxError - if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) { - throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin); - } - // Not defined in this function. Create a new definition. - if (!isLocal(function, symbol) || symbol.less(IS_VAR)) { - symbol = null; - } - } - } - } - - if (symbol == null) { - // If not found, then create a new one. - final Block symbolBlock; - - // Determine where to create it. - if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) { - symbolBlock = block; //internal vars are always defined in the block closest to them - } else if (isGlobal) { - symbolBlock = lc.getOutermostFunction().getBody(); - } else { - symbolBlock = lc.getFunctionBody(function); - } - - // Create and add to appropriate block. - symbol = createSymbol(name, flags); - symbolBlock.putSymbol(symbol); - - if ((flags & IS_SCOPE) == 0) { - // Initial assumption; symbol can lose its slot later - symbol.setNeedsSlot(true); - } - } else if (symbol.less(flags)) { - symbol.setFlags(flags); - } - - return symbol; - } - - private T end(final T node) { - return end(node, true); - } - - private T end(final T node, final boolean printNode) { - if (debug) { - final StringBuilder sb = new StringBuilder(); - - sb.append("[LEAVE "). - append(name(node)). - append("] "). - append(printNode ? node.toString() : ""). - append(" in '"). - append(lc.getCurrentFunction().getName()). - append('\''); - - if (node instanceof IdentNode) { - final Symbol symbol = ((IdentNode)node).getSymbol(); - if (symbol == null) { - sb.append(" "); - } else { - sb.append(" '); - } - } - - log.unindent(); - log.info(sb); - } - - return node; - } - - @Override - public boolean enterBlock(final Block block) { - start(block); - - if (lc.isFunctionBody()) { - assert !block.hasSymbols(); - final FunctionNode fn = lc.getCurrentFunction(); - if (isUnparsedFunction(fn)) { - // It's a skipped nested function. Just mark the symbols being used by it as being in use. - for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) { - nameIsUsed(name, null); - } - // Don't bother descending into it, it must be empty anyway. - assert block.getStatements().isEmpty(); - return false; - } - - enterFunctionBody(); - } - - return true; - } - - private boolean isUnparsedFunction(final FunctionNode fn) { - return isOnDemand && fn != lc.getOutermostFunction(); - } - - @Override - public boolean enterCatchNode(final CatchNode catchNode) { - final IdentNode exception = catchNode.getExceptionIdentifier(); - final Block block = lc.getCurrentBlock(); - - start(catchNode); - - // define block-local exception variable - final String exname = exception.getName(); - // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its - // symbol is naturally internal, and should be treated as such. - final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName()); - // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to - // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block. - final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE); - symbol.clearFlag(IS_LET); - - return true; - } - - private void enterFunctionBody() { - final FunctionNode functionNode = lc.getCurrentFunction(); - final Block body = lc.getCurrentBlock(); - - initFunctionWideVariables(functionNode, body); - acceptDeclarations(functionNode, body); - defineFunctionSelfSymbol(functionNode, body); - } - - private void defineFunctionSelfSymbol(final FunctionNode functionNode, final Block body) { - // Function self-symbol is only declared as a local variable for named function expressions. Declared functions - // don't need it as they are local variables in their declaring scope. - if (!functionNode.isNamedFunctionExpression()) { - return; - } - - final String name = functionNode.getIdent().getName(); - assert name != null; // As it's a named function expression. - - if (body.getExistingSymbol(name) != null) { - // Body already has a declaration for the name. It's either a parameter "function x(x)" or a - // top-level variable "function x() { ... var x; ... }". - return; - } - - defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE); - if(functionNode.allVarsInScope()) { // basically, has deep eval - // We must conservatively presume that eval'd code can dynamically use the function symbol. - lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL); - } - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - start(functionNode, false); - - thisProperties.push(new HashSet()); - - // Every function has a body, even the ones skipped on reparse (they have an empty one). We're - // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that - // are used in them. - assert functionNode.getBody() != null; - - return true; - } - - @Override - public boolean enterVarNode(final VarNode varNode) { - start(varNode); - // Normally, a symbol assigned in a var statement is not live for its RHS. Since we also represent function - // declarations as VarNodes, they are exception to the rule, as they need to have the symbol visible to the - // body of the declared function for self-reference. - if (varNode.isFunctionDeclaration()) { - defineVarIdent(varNode); - } - return true; - } - - @Override - public Node leaveVarNode(final VarNode varNode) { - if (!varNode.isFunctionDeclaration()) { - defineVarIdent(varNode); - } - return super.leaveVarNode(varNode); - } - - private void defineVarIdent(final VarNode varNode) { - final IdentNode ident = varNode.getName(); - final int flags; - if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) { - flags = IS_SCOPE; - } else { - flags = 0; - } - defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | flags); - } - - private Symbol exceptionSymbol() { - return newObjectInternal(EXCEPTION_PREFIX); - } - - /** - * This has to run before fix assignment types, store any type specializations for - * parameters, then turn them into objects for the generic version of this method. - * - * @param functionNode functionNode - */ - private FunctionNode finalizeParameters(final FunctionNode functionNode) { - final List newParams = new ArrayList<>(); - final boolean isVarArg = functionNode.isVarArg(); - - final Block body = functionNode.getBody(); - for (final IdentNode param : functionNode.getParameters()) { - final Symbol paramSymbol = body.getExistingSymbol(param.getName()); - assert paramSymbol != null; - assert paramSymbol.isParam() : paramSymbol + " " + paramSymbol.getFlags(); - newParams.add(param.setSymbol(paramSymbol)); - - // parameters should not be slots for a function that uses variable arity signature - if (isVarArg) { - paramSymbol.setNeedsSlot(false); - } - } - - return functionNode.setParameters(lc, newParams); - } - - /** - * Search for symbol in the lexical context starting from the given block. - * @param name Symbol name. - * @return Found symbol or null if not found. - */ - private Symbol findSymbol(final Block block, final String name) { - for (final Iterator blocks = lc.getBlocks(block); blocks.hasNext();) { - final Symbol symbol = blocks.next().getExistingSymbol(name); - if (symbol != null) { - return symbol; - } - } - return null; - } - - /** - * Marks the current function as one using any global symbol. The function and all its parent functions will all be - * marked as needing parent scope. - * @see FunctionNode#needsParentScope() - */ - private void functionUsesGlobalSymbol() { - for (final Iterator fns = lc.getFunctions(); fns.hasNext();) { - lc.setFlag(fns.next(), FunctionNode.USES_ANCESTOR_SCOPE); - } - } - - /** - * Marks the current function as one using a scoped symbol. The block defining the symbol will be marked as needing - * its own scope to hold the variable. If the symbol is defined outside of the current function, it and all - * functions up to (but not including) the function containing the defining block will be marked as needing parent - * function scope. - * @see FunctionNode#needsParentScope() - */ - private void functionUsesScopeSymbol(final Symbol symbol) { - final String name = symbol.getName(); - for (final Iterator contextNodeIter = lc.getAllNodes(); contextNodeIter.hasNext(); ) { - final LexicalContextNode node = contextNodeIter.next(); - if (node instanceof Block) { - final Block block = (Block)node; - if (block.getExistingSymbol(name) != null) { - assert lc.contains(block); - lc.setBlockNeedsScope(block); - break; - } - } else if (node instanceof FunctionNode) { - lc.setFlag(node, FunctionNode.USES_ANCESTOR_SCOPE); - } - } - } - - /** - * Declares that the current function is using the symbol. - * @param symbol the symbol used by the current function. - */ - private void functionUsesSymbol(final Symbol symbol) { - assert symbol != null; - if (symbol.isScope()) { - if (symbol.isGlobal()) { - functionUsesGlobalSymbol(); - } else { - functionUsesScopeSymbol(symbol); - } - } else { - assert !symbol.isGlobal(); // Every global is also scope - } - } - - private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) { - defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true); - } - - private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) { - initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE); - initCompileConstant(THIS, body, IS_PARAM | IS_THIS | HAS_OBJECT_VALUE); - - if (functionNode.isVarArg()) { - initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE); - if (functionNode.needsArguments()) { - initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE); - defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE); - } - } - - initParameters(functionNode, body); - initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE); - initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL); - } - - /** - * Initialize parameters for function node. - * @param functionNode the function node - */ - private void initParameters(final FunctionNode functionNode, final Block body) { - final boolean isVarArg = functionNode.isVarArg(); - final boolean scopeParams = functionNode.allVarsInScope() || isVarArg; - for (final IdentNode param : functionNode.getParameters()) { - final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM); - if(scopeParams) { - // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored. - // It will force creation of scopes where they would otherwise not necessarily be needed (functions - // using arguments object and other variable arity functions). Tracked by JDK-8038942. - symbol.setIsScope(); - assert symbol.hasSlot(); - if(isVarArg) { - symbol.setNeedsSlot(false); - } - } - } - } - - /** - * Is the symbol local to (that is, defined in) the specified function? - * @param function the function - * @param symbol the symbol - * @return true if the symbol is defined in the specified function - */ - private boolean isLocal(final FunctionNode function, final Symbol symbol) { - final FunctionNode definingFn = lc.getDefiningFunction(symbol); - assert definingFn != null; - return definingFn == function; - } - - @Override - public Node leaveBinaryNode(final BinaryNode binaryNode) { - if (binaryNode.isTokenType(TokenType.ASSIGN)) { - return leaveASSIGN(binaryNode); - } - return super.leaveBinaryNode(binaryNode); - } - - private Node leaveASSIGN(final BinaryNode binaryNode) { - // If we're assigning a property of the this object ("this.foo = ..."), record it. - final Expression lhs = binaryNode.lhs(); - if (lhs instanceof AccessNode) { - final AccessNode accessNode = (AccessNode) lhs; - final Expression base = accessNode.getBase(); - if (base instanceof IdentNode) { - final Symbol symbol = ((IdentNode)base).getSymbol(); - if(symbol.isThis()) { - thisProperties.peek().add(accessNode.getProperty()); - } - } - } - return binaryNode; - } - - @Override - public Node leaveUnaryNode(final UnaryNode unaryNode) { - if (unaryNode.tokenType() == TokenType.TYPEOF) { - return leaveTYPEOF(unaryNode); - } else { - return super.leaveUnaryNode(unaryNode); - } - } - - @Override - public Node leaveForNode(final ForNode forNode) { - if (forNode.isForInOrOf()) { - return forNode.setIterator(lc, newObjectInternal(ITERATOR_PREFIX)); //NASHORN-73 - } - - return end(forNode); - } - - @Override - public Node leaveFunctionNode(final FunctionNode functionNode) { - final FunctionNode finalizedFunction; - if (isUnparsedFunction(functionNode)) { - finalizedFunction = functionNode; - } else { - finalizedFunction = - markProgramBlock( - removeUnusedSlots( - createSyntheticInitializers( - finalizeParameters( - lc.applyTopFlags(functionNode)))) - .setThisProperties(lc, thisProperties.pop().size())); - } - return finalizedFunction; - } - - @Override - public Node leaveIdentNode(final IdentNode identNode) { - if (identNode.isPropertyName()) { - return identNode; - } - - final Symbol symbol = nameIsUsed(identNode.getName(), identNode); - - if (!identNode.isInitializedHere()) { - symbol.increaseUseCount(); - } - - IdentNode newIdentNode = identNode.setSymbol(symbol); - - // If a block-scoped var is used before its declaration mark it as dead. - // We can only statically detect this for local vars, cross-function symbols require runtime checks. - if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) { - newIdentNode = newIdentNode.markDead(); - } - - return end(newIdentNode); - } - - private Symbol nameIsUsed(final String name, final IdentNode origin) { - final Block block = lc.getCurrentBlock(); - - Symbol symbol = findSymbol(block, name); - - //If an existing symbol with the name is found, use that otherwise, declare a new one - if (symbol != null) { - log.info("Existing symbol = ", symbol); - if (symbol.isFunctionSelf()) { - final FunctionNode functionNode = lc.getDefiningFunction(symbol); - assert functionNode != null; - assert lc.getFunctionBody(functionNode).getExistingSymbol(CALLEE.symbolName()) != null; - lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL); - } - - // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already) - maybeForceScope(symbol); - } else { - log.info("No symbol exists. Declare as global: ", name); - symbol = defineSymbol(block, name, origin, IS_GLOBAL | IS_SCOPE); - } - - functionUsesSymbol(symbol); - return symbol; - } - - @Override - public Node leaveSwitchNode(final SwitchNode switchNode) { - // We only need a symbol for the tag if it's not an integer switch node - if(!switchNode.isUniqueInteger()) { - return switchNode.setTag(lc, newObjectInternal(SWITCH_TAG_PREFIX)); - } - return switchNode; - } - - @Override - public Node leaveTryNode(final TryNode tryNode) { - assert tryNode.getFinallyBody() == null; - - end(tryNode); - - return tryNode.setException(lc, exceptionSymbol()); - } - - private Node leaveTYPEOF(final UnaryNode unaryNode) { - final Expression rhs = unaryNode.getExpression(); - - final List args = new ArrayList<>(); - if (rhs instanceof IdentNode && !isParamOrVar((IdentNode)rhs)) { - args.add(compilerConstantIdentifier(SCOPE)); - args.add(LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName())); //null - } else { - args.add(rhs); - args.add(LiteralNode.newInstance(unaryNode)); //null, do not reuse token of identifier rhs, it can be e.g. 'this' - } - - final Node runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args); - - end(unaryNode); - - return runtimeNode; - } - - private FunctionNode markProgramBlock(final FunctionNode functionNode) { - if (isOnDemand || !functionNode.isProgram()) { - return functionNode; - } - - return functionNode.setBody(lc, functionNode.getBody().setFlag(lc, Block.IS_GLOBAL_SCOPE)); - } - - /** - * If the symbol isn't already a scope symbol, but it needs to be (see {@link #symbolNeedsToBeScope(Symbol)}, it is - * promoted to a scope symbol and its block marked as needing a scope. - * @param symbol the symbol that might be scoped - */ - private void maybeForceScope(final Symbol symbol) { - if (!symbol.isScope() && symbolNeedsToBeScope(symbol)) { - Symbol.setSymbolIsScope(lc, symbol); - } - } - - private Symbol newInternal(final CompilerConstants cc, final int flags) { - return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73 - } - - private Symbol newObjectInternal(final CompilerConstants cc) { - return newInternal(cc, HAS_OBJECT_VALUE); - } - - private boolean start(final Node node) { - return start(node, true); - } - - private boolean start(final Node node, final boolean printNode) { - if (debug) { - final StringBuilder sb = new StringBuilder(); - - sb.append("[ENTER "). - append(name(node)). - append("] "). - append(printNode ? node.toString() : ""). - append(" in '"). - append(lc.getCurrentFunction().getName()). - append("'"); - log.info(sb); - log.indent(); - } - - return true; - } - - /** - * Determines if the symbol has to be a scope symbol. In general terms, it has to be a scope symbol if it can only - * be reached from the current block by traversing a function node, a split node, or a with node. - * @param symbol the symbol checked for needing to be a scope symbol - * @return true if the symbol has to be a scope symbol. - */ - private boolean symbolNeedsToBeScope(final Symbol symbol) { - if (symbol.isThis() || symbol.isInternal()) { - return false; - } - - final FunctionNode func = lc.getCurrentFunction(); - if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) { - return true; - } - - boolean previousWasBlock = false; - for (final Iterator it = lc.getAllNodes(); it.hasNext();) { - final LexicalContextNode node = it.next(); - if (node instanceof FunctionNode || isSplitLiteral(node)) { - // We reached the function boundary or a splitting boundary without seeing a definition for the symbol. - // It needs to be in scope. - return true; - } else if (node instanceof WithNode) { - if (previousWasBlock) { - // We reached a WithNode; the symbol must be scoped. Note that if the WithNode was not immediately - // preceded by a block, this means we're currently processing its expression, not its body, - // therefore it doesn't count. - return true; - } - previousWasBlock = false; - } else if (node instanceof Block) { - if (((Block)node).getExistingSymbol(symbol.getName()) == symbol) { - // We reached the block that defines the symbol without reaching either the function boundary, or a - // WithNode. The symbol need not be scoped. - return false; - } - previousWasBlock = true; - } else { - previousWasBlock = false; - } - } - throw new AssertionError(); - } - - private static boolean isSplitLiteral(final LexicalContextNode expr) { - return expr instanceof Splittable && ((Splittable) expr).getSplitRanges() != null; - } - - private void throwUnprotectedSwitchError(final VarNode varNode) { - // Block scoped declarations in switch statements without explicit blocks should be declared - // in a common block that contains all the case clauses. We cannot support this without a - // fundamental rewrite of how switch statements are handled (case nodes contain blocks and are - // directly contained by switch node). As a temporary solution we throw a reference error here. - final String msg = ECMAErrors.getMessage("syntax.error.unprotected.switch.declaration", varNode.isLet() ? "let" : "const"); - throwParserException(msg, varNode); - } - - private void throwParserException(final String message, final Node origin) { - if (origin == null) { - throw new ParserException(message); - } - final Source source = compiler.getSource(); - final long token = origin.getToken(); - final int line = source.getLine(origin.getStart()); - final int column = source.getColumn(origin.getStart()); - final String formatted = ErrorManager.format(message, source, line, column, token); - throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token); - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/BranchOptimizer.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/BranchOptimizer.java deleted file mode 100644 index 99862fe92a1..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.codegen.Condition.EQ; -import static jdk.nashorn.internal.codegen.Condition.GE; -import static jdk.nashorn.internal.codegen.Condition.GT; -import static jdk.nashorn.internal.codegen.Condition.LE; -import static jdk.nashorn.internal.codegen.Condition.LT; -import static jdk.nashorn.internal.codegen.Condition.NE; -import static jdk.nashorn.internal.parser.TokenType.NOT; - -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.JoinPredecessorExpression; -import jdk.nashorn.internal.ir.LocalVariableConversion; -import jdk.nashorn.internal.ir.UnaryNode; - -/** - * Branch optimizer for CodeGenerator. Given a jump condition this helper - * class attempts to simplify the control flow - */ -final class BranchOptimizer { - - private final CodeGenerator codegen; - private final MethodEmitter method; - - BranchOptimizer(final CodeGenerator codegen, final MethodEmitter method) { - this.codegen = codegen; - this.method = method; - } - - void execute(final Expression node, final Label label, final boolean state) { - branchOptimizer(node, label, state); - } - - private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) { - if (unaryNode.isTokenType(NOT)) { - branchOptimizer(unaryNode.getExpression(), label, !state); - } else { - loadTestAndJump(unaryNode, label, state); - } - } - - private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { - final Expression lhs = binaryNode.lhs(); - final Expression rhs = binaryNode.rhs(); - - switch (binaryNode.tokenType()) { - case AND: - if (state) { - final Label skip = new Label("skip"); - optimizeLogicalOperand(lhs, skip, false, false); - optimizeLogicalOperand(rhs, label, true, true); - method.label(skip); - } else { - optimizeLogicalOperand(lhs, label, false, false); - optimizeLogicalOperand(rhs, label, false, true); - } - return; - - case OR: - if (state) { - optimizeLogicalOperand(lhs, label, true, false); - optimizeLogicalOperand(rhs, label, true, true); - } else { - final Label skip = new Label("skip"); - optimizeLogicalOperand(lhs, skip, true, false); - optimizeLogicalOperand(rhs, label, false, true); - method.label(skip); - } - return; - - case EQ: - case EQ_STRICT: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? EQ : NE, true, label); - return; - - case NE: - case NE_STRICT: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? NE : EQ, true, label); - return; - - case GE: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? GE : LT, false, label); - return; - - case GT: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? GT : LE, false, label); - return; - - case LE: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? LE : GT, true, label); - return; - - case LT: - codegen.loadComparisonOperands(binaryNode); - method.conditionalJump(state ? LT : GE, true, label); - return; - - default: - break; - } - - loadTestAndJump(binaryNode, label, state); - } - - private void optimizeLogicalOperand(final Expression expr, final Label label, final boolean state, final boolean isRhs) { - final JoinPredecessorExpression jpexpr = (JoinPredecessorExpression)expr; - if(LocalVariableConversion.hasLiveConversion(jpexpr)) { - final Label after = new Label("after"); - branchOptimizer(jpexpr.getExpression(), after, !state); - method.beforeJoinPoint(jpexpr); - method._goto(label); - method.label(after); - if(isRhs) { - method.beforeJoinPoint(jpexpr); - } - } else { - branchOptimizer(jpexpr.getExpression(), label, state); - } - } - private void branchOptimizer(final Expression node, final Label label, final boolean state) { - if (node instanceof BinaryNode) { - branchOptimizer((BinaryNode)node, label, state); - return; - } - - if (node instanceof UnaryNode) { - branchOptimizer((UnaryNode)node, label, state); - return; - } - - loadTestAndJump(node, label, state); - } - - private void loadTestAndJump(final Expression node, final Label label, final boolean state) { - codegen.loadExpressionAsBoolean(node); - if (state) { - method.ifne(label); - } else { - method.ifeq(label); - } - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CacheAst.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CacheAst.java deleted file mode 100644 index 6f66ea34c2c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CacheAst.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import java.util.ArrayDeque; -import java.util.Collections; -import java.util.Deque; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor; -import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; - -class CacheAst extends SimpleNodeVisitor { - private final Deque dataStack = new ArrayDeque<>(); - - private final Compiler compiler; - - CacheAst(final Compiler compiler) { - this.compiler = compiler; - assert !compiler.isOnDemandCompilation(); - } - - @Override - public boolean enterFunctionNode(final FunctionNode functionNode) { - final int id = functionNode.getId(); - // It isn't necessary to keep a stack of RecompilableScriptFunctionData, but then we'd need to do a - // potentially transitive lookup with compiler.getScriptFunctionData(id) for deeper functions; this way - // we keep it constant time. - dataStack.push(dataStack.isEmpty() ? compiler.getScriptFunctionData(id) : dataStack.peek().getScriptFunctionData(id)); - return true; - } - - @Override - public Node leaveFunctionNode(final FunctionNode functionNode) { - final RecompilableScriptFunctionData data = dataStack.pop(); - if (functionNode.isSplit()) { - // NOTE: cache only split function ASTs from eager pass. Caching non-split functions would require - // some additional work, namely creating the concept of "uncacheable" function and reworking - // ApplySpecialization to ensure that functions undergoing apply-to-call transformations are not - // cacheable as well as recomputing Symbol.useCount when caching the eagerly parsed AST. - // Recomputing Symbol.useCount would be needed so it will only reflect uses from within the - // function being cached (and not reflect uses from its own nested functions or functions it is - // nested in). This is consistent with the count an on-demand recompilation of the function would - // produce. This is important as the decision to emit shared scope calls is based on this count, - // and if it is not matched between a previous version of the code and its deoptimizing rest-of - // compilation, it can result in rest-of not emitting a shared scope call where a previous version - // of the code (compiled from a cached eager pre-pass seeing higher (global) useCount) would emit - // it, causing a mismatch in stack shapes between previous code and its rest-of. - data.setCachedAst(functionNode); - } - - if (!dataStack.isEmpty() && ((dataStack.peek().getFunctionFlags() & FunctionNode.IS_SPLIT) != 0)) { - // Return a function node with no body so that caching outer functions doesn't hold on to nested - // functions' bodies. Note we're doing this only for functions directly nested inside split - // functions, since we're only caching the split ones. It is not necessary to limit body removal - // to just these functions, but it's a cheap way to prevent unnecessary AST mutations. - return functionNode.setBody(lc, functionNode.getBody().setStatements(null, Collections.emptyList())); - } - return functionNode; - } -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ClassEmitter.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ClassEmitter.java deleted file mode 100644 index c01ddcb644c..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/ClassEmitter.java +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; -import static jdk.internal.org.objectweb.asm.Opcodes.ACC_VARARGS; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEINTERFACE; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESPECIAL; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; -import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; -import static jdk.internal.org.objectweb.asm.Opcodes.H_NEWINVOKESPECIAL; -import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; -import static jdk.nashorn.internal.codegen.CompilerConstants.CLINIT; -import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_SUFFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; -import static jdk.nashorn.internal.codegen.CompilerConstants.INIT; -import static jdk.nashorn.internal.codegen.CompilerConstants.SET_MAP; -import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE; -import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; -import static jdk.nashorn.internal.codegen.CompilerConstants.className; -import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; -import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; -import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Set; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.MethodVisitor; -import jdk.internal.org.objectweb.asm.util.TraceClassVisitor; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.debug.NashornClassReader; -import jdk.nashorn.internal.ir.debug.NashornTextifier; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.PropertyMap; -import jdk.nashorn.internal.runtime.RewriteException; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.Source; - -/** - * The interface responsible for speaking to ASM, emitting classes, - * fields and methods. - *

- * This file contains the ClassEmitter, which is the master object - * responsible for writing byte codes. It utilizes a MethodEmitter - * for method generation, which also the NodeVisitors own, to keep - * track of the current code generator and what it is doing. - *

- * There is, however, nothing stopping you from using this in a - * completely self contained environment, for example in ObjectGenerator - * where there are no visitors or external hooks. - *

- * MethodEmitter makes it simple to generate code for methods without - * having to do arduous type checking. It maintains a type stack - * and will pick the appropriate operation for all operations sent to it - * We also allow chained called to a MethodEmitter for brevity, e.g. - * it is legal to write _new(className).dup() or - * load(slot).load(slot2).xor().store(slot3); - *

- * If running with assertions enabled, any type conflict, such as different - * bytecode stack sizes or operating on the wrong type will be detected - * and an error thrown. - *

- * There is also a very nice debug interface that can emit formatted - * bytecodes that have been written. This is enabled by setting the - * environment "nashorn.codegen.debug" to true, or --log=codegen:{@literal } - * - * @see Compiler - */ -public class ClassEmitter { - /** Default flags for class generation - public class */ - private static final EnumSet DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC); - - /** Sanity check flag - have we started on a class? */ - private boolean classStarted; - - /** Sanity check flag - have we ended this emission? */ - private boolean classEnded; - - /** - * Sanity checks - which methods have we currently - * started for generation in this class? - */ - private final HashSet methodsStarted; - - /** The ASM classwriter that we use for all bytecode operations */ - protected final ClassWriter cw; - - /** The script environment */ - protected final Context context; - - /** Compile unit class name. */ - private String unitClassName; - - /** Set of constants access methods required. */ - private Set> constantMethodNeeded; - - private int methodCount; - - private int initCount; - - private int clinitCount; - - private int fieldCount; - - private final Set methodNames; - - /** - * Constructor - only used internally in this class as it breaks - * abstraction towards ASM or other code generator below. - * - * @param env script environment - * @param cw ASM classwriter - */ - private ClassEmitter(final Context context, final ClassWriter cw) { - this.context = context; - this.cw = cw; - this.methodsStarted = new HashSet<>(); - this.methodNames = new HashSet<>(); - } - - /** - * Return the method names encountered. - * - * @return method names - */ - public Set getMethodNames() { - return Collections.unmodifiableSet(methodNames); - } - - /** - * Constructor. - * - * @param env script environment - * @param className name of class to weave - * @param superClassName super class name for class - * @param interfaceNames names of interfaces implemented by this class, or - * {@code null} if none - */ - ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) { - this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS)); - cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames); - } - - /** - * Constructor from the compiler. - * - * @param env Script environment - * @param sourceName Source name - * @param unitClassName Compile unit class name. - * @param strictMode Should we generate this method in strict mode - */ - ClassEmitter(final Context context, final String sourceName, final String unitClassName, final boolean strictMode) { - this(context, - new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { - private static final String OBJECT_CLASS = "java/lang/Object"; - - @Override - protected String getCommonSuperClass(final String type1, final String type2) { - try { - return super.getCommonSuperClass(type1, type2); - } catch (final RuntimeException e) { - if (isScriptObject(Compiler.SCRIPTS_PACKAGE, type1) && isScriptObject(Compiler.SCRIPTS_PACKAGE, type2)) { - return className(ScriptObject.class); - } - return OBJECT_CLASS; - } - } - }); - - this.unitClassName = unitClassName; - this.constantMethodNeeded = new HashSet<>(); - - cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, unitClassName, null, pathName(jdk.nashorn.internal.scripts.JS.class.getName()), null); - cw.visitSource(sourceName, null); - - defineCommonStatics(strictMode); - } - - Context getContext() { - return context; - } - - /** - * @return the name of the compile unit class name. - */ - String getUnitClassName() { - return unitClassName; - } - - /** - * Get the method count, including init and clinit methods. - * - * @return method count - */ - public int getMethodCount() { - return methodCount; - } - - /** - * Get the clinit count. - * - * @return clinit count - */ - public int getClinitCount() { - return clinitCount; - } - - /** - * Get the init count. - * - * @return init count - */ - public int getInitCount() { - return initCount; - } - - /** - * Get the field count. - * - * @return field count - */ - public int getFieldCount() { - return fieldCount; - } - - /** - * Convert a binary name to a package/class name. - * - * @param name Binary name. - * - * @return Package/class name. - */ - private static String pathName(final String name) { - return name.replace('.', '/'); - } - - /** - * Define the static fields common in all scripts. - * - * @param strictMode Should we generate this method in strict mode - */ - private void defineCommonStatics(final boolean strictMode) { - // source - used to store the source data (text) for this script. Shared across - // compile units. Set externally by the compiler. - field(EnumSet.of(Flag.PRIVATE, Flag.STATIC), SOURCE.symbolName(), Source.class); - - // constants - used to the constants array for this script. Shared across - // compile units. Set externally by the compiler. - field(EnumSet.of(Flag.PRIVATE, Flag.STATIC), CONSTANTS.symbolName(), Object[].class); - - // strictMode - was this script compiled in strict mode. Set externally by the compiler. - field(EnumSet.of(Flag.PUBLIC, Flag.STATIC, Flag.FINAL), STRICT_MODE.symbolName(), boolean.class, strictMode); - } - - /** - * Define static utilities common needed in scripts. These are per compile - * unit and therefore have to be defined here and not in code gen. - */ - private void defineCommonUtilities() { - assert unitClassName != null; - - if (constantMethodNeeded.contains(String.class)) { - // $getString - get the ith entry from the constants table and cast to String. - final MethodEmitter getStringMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), GET_STRING.symbolName(), String.class, int.class); - getStringMethod.begin(); - getStringMethod.getStatic(unitClassName, CONSTANTS.symbolName(), CONSTANTS.descriptor()) - .load(Type.INT, 0) - .arrayload() - .checkcast(String.class) - ._return(); - getStringMethod.end(); - } - - if (constantMethodNeeded.contains(PropertyMap.class)) { - // $getMap - get the ith entry from the constants table and cast to PropertyMap. - final MethodEmitter getMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), GET_MAP.symbolName(), PropertyMap.class, int.class); - getMapMethod.begin(); - getMapMethod.loadConstants() - .load(Type.INT, 0) - .arrayload() - .checkcast(PropertyMap.class) - ._return(); - getMapMethod.end(); - - // $setMap - overwrite an existing map. - final MethodEmitter setMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), SET_MAP.symbolName(), void.class, int.class, PropertyMap.class); - setMapMethod.begin(); - setMapMethod.loadConstants() - .load(Type.INT, 0) - .load(Type.OBJECT, 1) - .arraystore(); - setMapMethod.returnVoid(); - setMapMethod.end(); - } - - // $getXXXX$array - get the ith entry from the constants table and cast to XXXX[]. - for (final Class clazz : constantMethodNeeded) { - if (clazz.isArray()) { - defineGetArrayMethod(clazz); - } - } - } - - /** - * Constructs a primitive specific method for getting the ith entry from the - * constants table as an array. - * - * @param clazz Array class. - */ - private void defineGetArrayMethod(final Class clazz) { - assert unitClassName != null; - - final String methodName = getArrayMethodName(clazz); - final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, clazz, int.class); - - getArrayMethod.begin(); - getArrayMethod.getStatic(unitClassName, CONSTANTS.symbolName(), CONSTANTS.descriptor()) - .load(Type.INT, 0) - .arrayload() - .checkcast(clazz) - .invoke(virtualCallNoLookup(clazz, "clone", Object.class)) - .checkcast(clazz) - ._return(); - getArrayMethod.end(); - } - - - /** - * Generate the name of a get array from constant pool method. - * - * @param clazz Name of array class. - * - * @return Method name. - */ - static String getArrayMethodName(final Class clazz) { - assert clazz.isArray(); - return GET_ARRAY_PREFIX.symbolName() + clazz.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.symbolName(); - } - - /** - * Ensure a get constant method is issued for the class. - * - * @param clazz Class of constant. - */ - void needGetConstantMethod(final Class clazz) { - constantMethodNeeded.add(clazz); - } - - /** - * Inspect class name and decide whether we are generating a ScriptObject class. - * - * @param scriptPrefix the script class prefix for the current script - * @param type the type to check - * - * @return {@code true} if type is ScriptObject - */ - private static boolean isScriptObject(final String scriptPrefix, final String type) { - if (type.startsWith(scriptPrefix)) { - return true; - } else if (type.equals(CompilerConstants.className(ScriptObject.class))) { - return true; - } else if (type.startsWith(Compiler.OBJECTS_PACKAGE)) { - return true; - } - - return false; - } - - /** - * Call at beginning of class emission. - */ - public void begin() { - classStarted = true; - } - - /** - * Call at end of class emission. - */ - public void end() { - assert classStarted : "class not started for " + unitClassName; - - if (unitClassName != null) { - final MethodEmitter initMethod = init(EnumSet.of(Flag.PRIVATE)); - initMethod.begin(); - initMethod.load(Type.OBJECT, 0); - initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class); - initMethod.returnVoid(); - initMethod.end(); - - defineCommonUtilities(); - } - - cw.visitEnd(); - classStarted = false; - classEnded = true; - assert methodsStarted.isEmpty() : "methodsStarted not empty " + methodsStarted; - } - - /** - * Disassemble an array of byte code. - * - * @param bytecode byte array representing bytecode - * - * @return disassembly as human readable string - */ - static String disassemble(final byte[] bytecode) { - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (final PrintWriter pw = new PrintWriter(baos)) { - final NashornClassReader cr = new NashornClassReader(bytecode); - final Context ctx = AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Context run() { - return Context.getContext(); - } - }); - final TraceClassVisitor tcv = new TraceClassVisitor(null, new NashornTextifier(ctx.getEnv(), cr), pw); - cr.accept(tcv, 0); - } - - final String str = new String(baos.toByteArray()); - return str; - } - - /** - * Call back from MethodEmitter for method start. - * - * @see MethodEmitter - * - * @param method method emitter. - */ - void beginMethod(final MethodEmitter method) { - assert !methodsStarted.contains(method); - methodsStarted.add(method); - } - - /** - * Call back from MethodEmitter for method end. - * - * @see MethodEmitter - * - * @param method - */ - void endMethod(final MethodEmitter method) { - assert methodsStarted.contains(method); - methodsStarted.remove(method); - } - - /** - * Add a new method to the class - defaults to public method. - * - * @param methodName name of method - * @param rtype return type of the method - * @param ptypes parameter types the method - * - * @return method emitter to use for weaving this method - */ - MethodEmitter method(final String methodName, final Class rtype, final Class... ptypes) { - return method(DEFAULT_METHOD_FLAGS, methodName, rtype, ptypes); //TODO why public default ? - } - - /** - * Add a new method to the class - defaults to public method. - * - * @param methodFlags access flags for the method - * @param methodName name of method - * @param rtype return type of the method - * @param ptypes parameter types the method - * - * @return method emitter to use for weaving this method - */ - MethodEmitter method(final EnumSet methodFlags, final String methodName, final Class rtype, final Class... ptypes) { - methodCount++; - methodNames.add(methodName); - return new MethodEmitter(this, methodVisitor(methodFlags, methodName, rtype, ptypes)); - } - - /** - * Add a new method to the class - defaults to public method. - * - * @param methodName name of method - * @param descriptor descriptor of method - * - * @return method emitter to use for weaving this method - */ - MethodEmitter method(final String methodName, final String descriptor) { - return method(DEFAULT_METHOD_FLAGS, methodName, descriptor); - } - - /** - * Add a new method to the class - defaults to public method. - * - * @param methodFlags access flags for the method - * @param methodName name of method - * @param descriptor descriptor of method - * - * @return method emitter to use for weaving this method - */ - MethodEmitter method(final EnumSet methodFlags, final String methodName, final String descriptor) { - methodCount++; - methodNames.add(methodName); - return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null)); - } - - /** - * Add a new method to the class, representing a function node. - * - * @param functionNode the function node to generate a method for - * - * @return method emitter to use for weaving this method - */ - MethodEmitter method(final FunctionNode functionNode) { - methodCount++; - methodNames.add(functionNode.getName()); - final FunctionSignature signature = new FunctionSignature(functionNode); - final MethodVisitor mv = cw.visitMethod( - ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0), - functionNode.getName(), - signature.toString(), - null, - null); - - return new MethodEmitter(this, mv, functionNode); - } - - /** - * Add a new method to the class, representing a rest-of version of the - * function node. - * - * @param functionNode the function node to generate a method for - * - * @return method emitter to use for weaving this method - */ - MethodEmitter restOfMethod(final FunctionNode functionNode) { - methodCount++; - methodNames.add(functionNode.getName()); - final MethodVisitor mv = cw.visitMethod( - ACC_PUBLIC | ACC_STATIC, - functionNode.getName(), - Type.getMethodDescriptor(functionNode.getReturnType().getTypeClass(), RewriteException.class), - null, - null); - - return new MethodEmitter(this, mv, functionNode); - } - - - /** - * Start generating the method in the class. - * - * @return method emitter to use for weaving - */ - MethodEmitter clinit() { - clinitCount++; - return method(EnumSet.of(Flag.STATIC), CLINIT.symbolName(), void.class); - } - - /** - * Start generating an ()V method in the class. - * - * @return method emitter to use for weaving ()V - */ - MethodEmitter init() { - initCount++; - return method(INIT.symbolName(), void.class); - } - - /** - * Start generating an ()V method in the class. - * - * @param ptypes parameter types for constructor - * @return method emitter to use for weaving ()V - */ - MethodEmitter init(final Class... ptypes) { - initCount++; - return method(INIT.symbolName(), void.class, ptypes); - } - - /** - * Start generating an (...)V method in the class. - * - * @param flags access flags for the constructor - * @param ptypes parameter types for the constructor - * - * @return method emitter to use for weaving (...)V - */ - MethodEmitter init(final EnumSet flags, final Class... ptypes) { - initCount++; - return method(flags, INIT.symbolName(), void.class, ptypes); - } - - /** - * Add a field to the class, initialized to a value. - * - * @param fieldFlags flags, e.g. should it be static or public etc - * @param fieldName name of field - * @param fieldType the type of the field - * @param value the value - * - * @see ClassEmitter.Flag - */ - final void field(final EnumSet fieldFlags, final String fieldName, final Class fieldType, final Object value) { - fieldCount++; - cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd(); - } - - /** - * Add a field to the class. - * - * @param fieldFlags access flags for the field - * @param fieldName name of field - * @param fieldType type of the field - * - * @see ClassEmitter.Flag - */ - final void field(final EnumSet fieldFlags, final String fieldName, final Class fieldType) { - field(fieldFlags, fieldName, fieldType, null); - } - - /** - * Add a field to the class - defaults to public. - * - * @param fieldName name of field - * @param fieldType type of field - */ - final void field(final String fieldName, final Class fieldType) { - field(EnumSet.of(Flag.PUBLIC), fieldName, fieldType, null); - } - - /** - * Return a bytecode array from this ClassEmitter. The ClassEmitter must - * have been ended (having its end function called) for this to work. - * - * @return byte code array for generated class, {@code null} if class - * generation hasn't been ended with {@link ClassEmitter#end()}. - */ - byte[] toByteArray() { - assert classEnded; - if (!classEnded) { - return null; - } - - return cw.toByteArray(); - } - - /** - * Abstraction for flags used in class emission. We provide abstraction - * separating these from the underlying bytecode emitter. Flags are provided - * for method handles, protection levels, static/virtual fields/methods. - */ - static enum Flag { - /** method handle with static access */ - HANDLE_STATIC(H_INVOKESTATIC), - /** method handle with new invoke special access */ - HANDLE_NEWSPECIAL(H_NEWINVOKESPECIAL), - /** method handle with invoke special access */ - HANDLE_SPECIAL(H_INVOKESPECIAL), - /** method handle with invoke virtual access */ - HANDLE_VIRTUAL(H_INVOKEVIRTUAL), - /** method handle with invoke interface access */ - HANDLE_INTERFACE(H_INVOKEINTERFACE), - - /** final access */ - FINAL(ACC_FINAL), - /** static access */ - STATIC(ACC_STATIC), - /** public access */ - PUBLIC(ACC_PUBLIC), - /** private access */ - PRIVATE(ACC_PRIVATE); - - private final int value; - - private Flag(final int value) { - this.value = value; - } - - /** - * Get the value of this flag - * @return the int value - */ - int getValue() { - return value; - } - - /** - * Return the corresponding ASM flag value for an enum set of flags. - * - * @param flags enum set of flags - * - * @return an integer value representing the flags intrinsic values - * or:ed together - */ - static int getValue(final EnumSet flags) { - int v = 0; - for (final Flag flag : flags) { - v |= flag.getValue(); - } - return v; - } - } - - private MethodVisitor methodVisitor(final EnumSet flags, final String methodName, final Class rtype, final Class... ptypes) { - return cw.visitMethod(Flag.getValue(flags), methodName, methodDescriptor(rtype, ptypes), null, null); - } - -} diff --git a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java deleted file mode 100644 index 21228296588..00000000000 --- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java +++ /dev/null @@ -1,5588 +0,0 @@ -/* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE; -import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; -import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; -import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; -import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; -import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; -import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX; -import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; -import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; -import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup; -import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; -import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; -import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; -import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; -import static jdk.nashorn.internal.ir.Symbol.HAS_SLOT; -import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; -import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; -import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_DECLARE; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT; -import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE; - -import java.io.PrintWriter; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collection; -import java.util.Collections; -import java.util.Deque; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.function.Supplier; -import jdk.nashorn.internal.AssertsEnabled; -import jdk.nashorn.internal.IntDeque; -import jdk.nashorn.internal.codegen.ClassEmitter.Flag; -import jdk.nashorn.internal.codegen.CompilerConstants.Call; -import jdk.nashorn.internal.codegen.types.ArrayType; -import jdk.nashorn.internal.codegen.types.Type; -import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BaseNode; -import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Block; -import jdk.nashorn.internal.ir.BlockStatement; -import jdk.nashorn.internal.ir.BreakNode; -import jdk.nashorn.internal.ir.CallNode; -import jdk.nashorn.internal.ir.CaseNode; -import jdk.nashorn.internal.ir.CatchNode; -import jdk.nashorn.internal.ir.ContinueNode; -import jdk.nashorn.internal.ir.EmptyNode; -import jdk.nashorn.internal.ir.Expression; -import jdk.nashorn.internal.ir.ExpressionStatement; -import jdk.nashorn.internal.ir.ForNode; -import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.GetSplitState; -import jdk.nashorn.internal.ir.IdentNode; -import jdk.nashorn.internal.ir.IfNode; -import jdk.nashorn.internal.ir.IndexNode; -import jdk.nashorn.internal.ir.JoinPredecessorExpression; -import jdk.nashorn.internal.ir.JumpStatement; -import jdk.nashorn.internal.ir.JumpToInlinedFinally; -import jdk.nashorn.internal.ir.LabelNode; -import jdk.nashorn.internal.ir.LexicalContext; -import jdk.nashorn.internal.ir.LexicalContextNode; -import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; -import jdk.nashorn.internal.ir.LiteralNode.PrimitiveLiteralNode; -import jdk.nashorn.internal.ir.LocalVariableConversion; -import jdk.nashorn.internal.ir.LoopNode; -import jdk.nashorn.internal.ir.Node; -import jdk.nashorn.internal.ir.ObjectNode; -import jdk.nashorn.internal.ir.Optimistic; -import jdk.nashorn.internal.ir.PropertyNode; -import jdk.nashorn.internal.ir.ReturnNode; -import jdk.nashorn.internal.ir.RuntimeNode; -import jdk.nashorn.internal.ir.RuntimeNode.Request; -import jdk.nashorn.internal.ir.SetSplitState; -import jdk.nashorn.internal.ir.SplitReturn; -import jdk.nashorn.internal.ir.Splittable; -import jdk.nashorn.internal.ir.Statement; -import jdk.nashorn.internal.ir.SwitchNode; -import jdk.nashorn.internal.ir.Symbol; -import jdk.nashorn.internal.ir.TernaryNode; -import jdk.nashorn.internal.ir.ThrowNode; -import jdk.nashorn.internal.ir.TryNode; -import jdk.nashorn.internal.ir.UnaryNode; -import jdk.nashorn.internal.ir.VarNode; -import jdk.nashorn.internal.ir.WhileNode; -import jdk.nashorn.internal.ir.WithNode; -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; -import jdk.nashorn.internal.ir.visitor.SimpleNodeVisitor; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.parser.Lexer.RegexToken; -import jdk.nashorn.internal.parser.TokenType; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.Debug; -import jdk.nashorn.internal.runtime.ECMAException; -import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.OptimisticReturnFilters; -import jdk.nashorn.internal.runtime.PropertyMap; -import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; -import jdk.nashorn.internal.runtime.RewriteException; -import jdk.nashorn.internal.runtime.Scope; -import jdk.nashorn.internal.runtime.ScriptEnvironment; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.Undefined; -import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; -import jdk.nashorn.internal.runtime.arrays.ArrayData; -import jdk.nashorn.internal.runtime.linker.LinkerCallSite; -import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; -import jdk.nashorn.internal.runtime.logging.DebugLogger; -import jdk.nashorn.internal.runtime.logging.Loggable; -import jdk.nashorn.internal.runtime.logging.Logger; -import jdk.nashorn.internal.runtime.options.Options; - -/** - * This is the lowest tier of the code generator. It takes lowered ASTs emitted - * from Lower and emits Java byte code. The byte code emission logic is broken - * out into MethodEmitter. MethodEmitter works internally with a type stack, and - * keeps track of the contents of the byte code stack. This way we avoid a large - * number of special cases on the form - *

- * if (type == INT) {
- *     visitInsn(ILOAD, slot);
- * } else if (type == DOUBLE) {
- *     visitInsn(DOUBLE, slot);
- * }
- * 
- * This quickly became apparent when the code generator was generalized to work - * with all types, and not just numbers or objects. - *

- * The CodeGenerator visits nodes only once and emits bytecode for them. - */ -@Logger(name="codegen") -final class CodeGenerator extends NodeOperatorVisitor implements Loggable { - - private static final Type SCOPE_TYPE = Type.typeFor(ScriptObject.class); - - private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class); - - private static final Call CREATE_REWRITE_EXCEPTION = CompilerConstants.staticCallNoLookup(RewriteException.class, - "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class); - private static final Call CREATE_REWRITE_EXCEPTION_REST_OF = CompilerConstants.staticCallNoLookup(RewriteException.class, - "create", RewriteException.class, UnwarrantedOptimismException.class, Object[].class, String[].class, int[].class); - - private static final Call ENSURE_INT = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, - "ensureInt", int.class, Object.class, int.class); - private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class, - "ensureNumber", double.class, Object.class, int.class); - - private static final Call CREATE_FUNCTION_OBJECT = CompilerConstants.staticCallNoLookup(ScriptFunction.class, - "create", ScriptFunction.class, Object[].class, int.class, ScriptObject.class); - private static final Call CREATE_FUNCTION_OBJECT_NO_SCOPE = CompilerConstants.staticCallNoLookup(ScriptFunction.class, - "create", ScriptFunction.class, Object[].class, int.class); - - private static final Call TO_NUMBER_FOR_EQ = CompilerConstants.staticCallNoLookup(JSType.class, - "toNumberForEq", double.class, Object.class); - private static final Call TO_NUMBER_FOR_STRICT_EQ = CompilerConstants.staticCallNoLookup(JSType.class, - "toNumberForStrictEq", double.class, Object.class); - - - private static final Class ITERATOR_CLASS = Iterator.class; - static { - assert ITERATOR_CLASS == CompilerConstants.ITERATOR_PREFIX.type(); - } - private static final Type ITERATOR_TYPE = Type.typeFor(ITERATOR_CLASS); - private static final Type EXCEPTION_TYPE = Type.typeFor(CompilerConstants.EXCEPTION_PREFIX.type()); - - private static final Integer INT_ZERO = 0; - - /** Constant data & installation. The only reason the compiler keeps this is because it is assigned - * by reflection in class installation */ - private final Compiler compiler; - - /** Is the current code submitted by 'eval' call? */ - private final boolean evalCode; - - /** Call site flags given to the code generator to be used for all generated call sites */ - private final int callSiteFlags; - - /** How many regexp fields have been emitted */ - private int regexFieldCount; - - /** Line number for last statement. If we encounter a new line number, line number bytecode information - * needs to be generated */ - private int lastLineNumber = -1; - - /** When should we stop caching regexp expressions in fields to limit bytecode size? */ - private static final int MAX_REGEX_FIELDS = 2 * 1024; - - /** Current method emitter */ - private MethodEmitter method; - - /** Current compile unit */ - private CompileUnit unit; - - private final DebugLogger log; - - /** From what size should we use spill instead of fields for JavaScript objects? */ - static final int OBJECT_SPILL_THRESHOLD = Options.getIntProperty("nashorn.spill.threshold", 256); - - private final Set emittedMethods = new HashSet<>(); - - // Function Id -> ContinuationInfo. Used by compilation of rest-of function only. - private ContinuationInfo continuationInfo; - - private final Deque