mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 10:23:28 +00:00
Merge
This commit is contained in:
commit
bd2fef5689
@ -117,6 +117,17 @@ ifeq ($(MODULE), java.base)
|
||||
--hash-modules '^(?!$(EXCLUDE_PATTERN)$$)'
|
||||
endif
|
||||
endif
|
||||
else # not java.base
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
# Only java.base needs to include the MSVC*_DLLs. Make sure no other module
|
||||
# tries to include them (typically imported ones).
|
||||
ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCR_DLL))), )
|
||||
JMOD_FLAGS += --exclude '$(notdir $(MSVCR_DLL))'
|
||||
endif
|
||||
ifneq ($(wildcard $(LIBS_DIR)/$(notdir $(MSVCP_DLL))), )
|
||||
JMOD_FLAGS += --exclude '$(notdir $(MSVCP_DLL))'
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Changes to the jmod tool itself should also trigger a rebuild of all jmods.
|
||||
@ -133,18 +144,21 @@ ifeq ($(INTERIM_JMOD), true)
|
||||
DEPS := $(filter-out $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/classlist, $(DEPS))
|
||||
endif
|
||||
|
||||
JMOD_FLAGS += --exclude '**{_the.*,_*.marker,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}'
|
||||
|
||||
# Create jmods in a temp dir and then move them into place to keep the
|
||||
# module path in $(IMAGES_OUTPUTDIR)/jmods valid at all times.
|
||||
$(JMODS_DIR)/$(MODULE).jmod: $(DEPS)
|
||||
$(call LogWarn, Creating $(patsubst $(OUTPUTDIR)/%, %, $@))
|
||||
$(call MakeDir, $(JMODS_DIR) $(JMODS_TEMPDIR))
|
||||
$(RM) $@ $(JMODS_TEMPDIR)/$(notdir $@)
|
||||
$(JMOD) create \
|
||||
--module-version $(VERSION_SHORT) \
|
||||
--target-platform '$(OPENJDK_MODULE_TARGET_PLATFORM)' \
|
||||
--module-path $(JMODS_DIR) \
|
||||
--exclude '**{_the.*,_*.marker,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
|
||||
$(JMOD_FLAGS) $(JMODS_TEMPDIR)/$(notdir $@)
|
||||
$(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/jmods/$(MODULE).jmod, \
|
||||
$(JMOD) create \
|
||||
--module-version $(VERSION_SHORT) \
|
||||
--target-platform '$(OPENJDK_MODULE_TARGET_PLATFORM)' \
|
||||
--module-path $(JMODS_DIR) \
|
||||
$(JMOD_FLAGS) $(JMODS_TEMPDIR)/$(notdir $@) \
|
||||
)
|
||||
$(MV) $(JMODS_TEMPDIR)/$(notdir $@) $@
|
||||
|
||||
TARGETS += $(JMODS_DIR)/$(MODULE).jmod
|
||||
|
||||
@ -522,7 +522,6 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL],
|
||||
if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then
|
||||
AC_MSG_RESULT([ok])
|
||||
MSVC_DLL="$POSSIBLE_MSVC_DLL"
|
||||
BASIC_FIXUP_PATH(MSVC_DLL)
|
||||
AC_MSG_CHECKING([for $DLL_NAME])
|
||||
AC_MSG_RESULT([$MSVC_DLL])
|
||||
else
|
||||
|
||||
@ -297,7 +297,7 @@ define SetupCompileNativeFileBody
|
||||
endif
|
||||
|
||||
$$($1_OBJ): $$($1_SRC_FILE) $$($$($1_BASE)_COMPILE_VARDEPS_FILE) \
|
||||
$$($1_VARDEPS_FILE) | $$($$($1_BASE)_BUILD_INFO)
|
||||
$$($$($1_BASE)_EXTRA_DEPS) $$($1_VARDEPS_FILE) | $$($$($1_BASE)_BUILD_INFO)
|
||||
$$(call LogInfo, Compiling $$($1_FILENAME) (for $$($$($1_BASE)_BASENAME)))
|
||||
$$(call MakeDir, $$(@D))
|
||||
ifneq ($(TOOLCHAIN_TYPE), microsoft)
|
||||
@ -366,6 +366,7 @@ endef
|
||||
# EXCLUDE_PATTERN exclude files matching any of these substrings
|
||||
# EXTRA_FILES List of extra files not in any of the SRC dirs
|
||||
# EXTRA_OBJECT_FILES List of extra object files to include when linking
|
||||
# EXTRA_DEPS List of extra dependencies to be added to each compiled file
|
||||
# VERSIONINFO_RESOURCE Input file for RC. Setting this implies that RC will be run
|
||||
# RC_FLAGS flags for RC.
|
||||
# EMBED_MANIFEST if true, embed manifest on Windows.
|
||||
@ -904,20 +905,22 @@ define SetupNativeCompilationBody
|
||||
|
||||
$1_IMPORT_LIBRARY := $$($1_OBJECT_DIR)/$$($1_NAME).lib
|
||||
$1_EXTRA_LDFLAGS += "-implib:$$($1_IMPORT_LIBRARY)"
|
||||
# To properly trigger downstream dependants of the import library, just as
|
||||
# for debug files, we must have a recipe in the rule. To avoid rerunning
|
||||
# the recipe every time have it touch the target. If an import library
|
||||
# file is deleted by something external, explicitly delete the target to
|
||||
# trigger a rebuild of both.
|
||||
ifneq ($$(wildcard $$($1_IMPORT_LIBRARY)), $$($1_IMPORT_LIBRARY))
|
||||
$$(call LogDebug, Deleting $$($1_BASENAME) because import library is missing)
|
||||
$$(shell $(RM) $$($1_TARGET))
|
||||
endif
|
||||
$$($1_IMPORT_LIBRARY): $$($1_TARGET)
|
||||
ifeq ($$($1_TYPE), LIBRARY)
|
||||
# To properly trigger downstream dependants of the import library, just as
|
||||
# for debug files, we must have a recipe in the rule. To avoid rerunning
|
||||
# the recipe every time have it touch the target. If an import library
|
||||
# file is deleted by something external, explicitly delete the target to
|
||||
# trigger a rebuild of both.
|
||||
ifneq ($$(wildcard $$($1_IMPORT_LIBRARY)), $$($1_IMPORT_LIBRARY))
|
||||
$$(call LogDebug, Deleting $$($1_BASENAME) because import library is missing)
|
||||
$$(shell $(RM) $$($1_TARGET))
|
||||
endif
|
||||
$$($1_IMPORT_LIBRARY): $$($1_TARGET)
|
||||
$$(if $$(CORRECT_FUNCTION_IN_RECIPE_EVALUATION), \
|
||||
$$(if $$(wildcard $$@), , $$(error $$@ was not created for $$<)) \
|
||||
)
|
||||
$(TOUCH) $$@
|
||||
endif
|
||||
endif
|
||||
|
||||
$1_VARDEPS := $$($1_LD) $$($1_SYSROOT_LDFLAGS) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) \
|
||||
|
||||
@ -54,4 +54,56 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
TARGETS += $(patsubst $(DTRACE_SOURCE_DIR)/%.d, \
|
||||
$(DTRACE_GENSRC_DIR)/%.h, $(wildcard $(DTRACE_SOURCE_DIR)/*.d))
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
############################################################################
|
||||
# First we need to generate the dtraceGenOffsets tool. When run, this will
|
||||
# produce two header files and a C++ file. Note that generateJvmOffsets.cpp
|
||||
# is using the same JVM_CFLAGS as libjvm.so.
|
||||
|
||||
# Include support files that will setup JVM compiler flags.
|
||||
include lib/JvmFeatures.gmk
|
||||
include lib/JvmFlags.gmk
|
||||
|
||||
# We cannot compile until the JVMTI gensrc has finished
|
||||
JVMTI_H := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.h
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
|
||||
NAME := dtraceGenOffsets, \
|
||||
TYPE := EXECUTABLE, \
|
||||
SRC := $(TOPDIR)/make/hotspot/src/native/dtrace, \
|
||||
TOOLCHAIN := $(TOOLCHAIN_BUILD), \
|
||||
LDFLAGS := -m64, \
|
||||
CFLAGS := -m64 $(JVM_CFLAGS), \
|
||||
EXTRA_DEPS := $(JVMTI_H), \
|
||||
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
|
||||
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
|
||||
))
|
||||
|
||||
DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
|
||||
|
||||
# Argument 1: Output filename
|
||||
# Argument 2: dtrace-gen-offset tool command line option
|
||||
define SetupDtraceOffsetsGeneration
|
||||
$1: $$(BUILD_DTRACE_GEN_OFFSETS)
|
||||
$$(call LogInfo, Generating dtrace $2 file $$(@F))
|
||||
$$(call MakeDir, $$(@D))
|
||||
$$(call ExecuteWithLog, $$@, ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@ ) )
|
||||
|
||||
TARGETS += $1
|
||||
endef
|
||||
|
||||
JVM_OFFSETS_H := $(DTRACE_GENSRC_DIR)/JvmOffsets.h
|
||||
JVM_OFFSETS_CPP := $(DTRACE_GENSRC_DIR)/JvmOffsets.cpp
|
||||
JVM_OFFSETS_INDEX_H := $(DTRACE_GENSRC_DIR)/JvmOffsetsIndex.h
|
||||
|
||||
############################################################################
|
||||
# Run the dtrace-gen-offset tool to generate these three files.
|
||||
# The generated JvmOffsets.cpp is compiled with the rest of libjvm.
|
||||
# The header files are used by libjvm_db and jhelper.d, respectively.
|
||||
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header))
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index))
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table))
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
60
make/hotspot/lib/CompileDtraceLibraries.gmk
Normal file
60
make/hotspot/lib/CompileDtraceLibraries.gmk
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright (c) 2013, 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.
|
||||
#
|
||||
|
||||
ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
|
||||
############################################################################
|
||||
# Build the stand-alone dtrace libraries.
|
||||
|
||||
LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
|
||||
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
|
||||
NAME := jvm_dtrace, \
|
||||
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
|
||||
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_dtrace, \
|
||||
CFLAGS := -m64 -G -mt -KPIC, \
|
||||
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
|
||||
LIBS := $(LIBDL) -lthread -ldoor, \
|
||||
MAPFILE := $(TOPDIR)/make/mapfiles/libjvm_dtrace/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
|
||||
))
|
||||
|
||||
# Note that libjvm_db.c has tests for COMPILER2, but this was never set by
|
||||
# the old build.
|
||||
LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
|
||||
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
|
||||
NAME := jvm_db, \
|
||||
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
|
||||
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_db, \
|
||||
CFLAGS := -I$(DTRACE_GENSRC_DIR) -m64 -G -mt -KPIC, \
|
||||
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
|
||||
MAPFILE := $(TOPDIR)/make/mapfiles/libjvm_db/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
|
||||
|
||||
endif
|
||||
endif
|
||||
@ -1,39 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2016, 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.
|
||||
#
|
||||
|
||||
ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
# These files are are generated by CompileDtrace.gmk but consumed by
|
||||
# CompileJvm.gmk
|
||||
DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o
|
||||
DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o
|
||||
DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ)
|
||||
|
||||
# Since we cannot generate JvmOffsets.cpp as part of the gensrc step,
|
||||
# we need this special hook to get it to compile with the rest of libjvm.
|
||||
JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp
|
||||
DTRACE_EXTRA_SOURCE_FILES := $(JVM_OFFSETS_CPP)
|
||||
endif
|
||||
endif
|
||||
@ -24,11 +24,13 @@
|
||||
#
|
||||
|
||||
# Include support files that will setup compiler flags due to the selected
|
||||
# jvm feature set, and specific file overrides.
|
||||
# jvm feature set, specific file overrides, and general flags.
|
||||
include lib/JvmFeatures.gmk
|
||||
include lib/JvmOverrideFiles.gmk
|
||||
include lib/JvmFlags.gmk
|
||||
|
||||
$(eval $(call IncludeCustomExtension, hotspot/lib/CompileJvm.gmk))
|
||||
# Include support files that will setup DTRACE_EXTRA_OBJECT_FILES.
|
||||
include lib/JvmDtraceObjects.gmk
|
||||
|
||||
################################################################################
|
||||
# Setup compilation of the main Hotspot native library (libjvm).
|
||||
@ -39,71 +41,6 @@ JVM_MAPFILE := $(JVM_OUTPUTDIR)/mapfile
|
||||
################################################################################
|
||||
# Platform independent setup
|
||||
|
||||
# This variable may be added to by a custom extension
|
||||
JVM_SRC_ROOTS += $(TOPDIR)/src/hotspot
|
||||
|
||||
JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
|
||||
$d/share \
|
||||
$d/os/$(HOTSPOT_TARGET_OS) \
|
||||
$d/os/$(HOTSPOT_TARGET_OS_TYPE) \
|
||||
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
$d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
))) \
|
||||
$(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles \
|
||||
$(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles \
|
||||
#
|
||||
|
||||
JVM_CFLAGS_INCLUDES += \
|
||||
$(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \
|
||||
-I$(JVM_VARIANT_OUTPUTDIR)/gensrc \
|
||||
-I$(TOPDIR)/src/hotspot/share/precompiled \
|
||||
-I$(TOPDIR)/src/hotspot/share/include \
|
||||
-I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjimage \
|
||||
#
|
||||
|
||||
# INCLUDE_SUFFIX_* is only meant for including the proper
|
||||
# platform files. Don't use it to guard code. Use the value of
|
||||
# HOTSPOT_TARGET_CPU_DEFINE etc. instead.
|
||||
# Remaining TARGET_ARCH_* is needed to select the cpu specific
|
||||
# sources for 64-bit ARM ports (arm versus aarch64).
|
||||
JVM_CFLAGS_TARGET_DEFINES += \
|
||||
-DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
-DINCLUDE_SUFFIX_OS=_$(HOTSPOT_TARGET_OS) \
|
||||
-DINCLUDE_SUFFIX_CPU=_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
-DINCLUDE_SUFFIX_COMPILER=_$(HOTSPOT_TOOLCHAIN_TYPE) \
|
||||
-DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \
|
||||
-D$(HOTSPOT_TARGET_CPU_DEFINE) \
|
||||
-DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \
|
||||
#
|
||||
|
||||
ifeq ($(DEBUG_LEVEL), release)
|
||||
# For hotspot, release builds differ internally between "optimized" and "product"
|
||||
# in that "optimize" does not define PRODUCT.
|
||||
ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized)
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT
|
||||
endif
|
||||
else ifeq ($(DEBUG_LEVEL), fastdebug)
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DASSERT
|
||||
ifeq ($(filter $(OPENJDK_TARGET_OS), windows aix), )
|
||||
# NOTE: Old build did not define CHECK_UNHANDLED_OOPS on Windows and AIX.
|
||||
JVM_CFLAGS_DEBUGLEVEL += -DCHECK_UNHANDLED_OOPS
|
||||
endif
|
||||
else ifeq ($(DEBUG_LEVEL), slowdebug)
|
||||
# _NMT_NOINLINE_ informs NMT that no inlining is done by the compiler
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DASSERT -D_NMT_NOINLINE_
|
||||
endif
|
||||
|
||||
JVM_CFLAGS += \
|
||||
$(JVM_CFLAGS_DEBUGLEVEL) \
|
||||
$(JVM_CFLAGS_TARGET_DEFINES) \
|
||||
$(JVM_CFLAGS_FEATURES) \
|
||||
$(JVM_CFLAGS_INCLUDES) \
|
||||
$(EXTRA_CFLAGS) \
|
||||
#
|
||||
|
||||
JVM_LDFLAGS += \
|
||||
$(SHARED_LIBRARY_FLAGS) \
|
||||
$(JVM_LDFLAGS_FEATURES) \
|
||||
@ -142,11 +79,6 @@ CFLAGS_VM_VERSION := \
|
||||
-DCPU='"$(OPENJDK_TARGET_CPU_VM_VERSION)"' \
|
||||
#
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
ifeq ($(USE_PRECOMPILED_HEADER), false)
|
||||
JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Platform specific setup
|
||||
|
||||
@ -214,7 +146,6 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
|
||||
SRC := $(JVM_SRC_DIRS), \
|
||||
EXTRA_FILES := $(DTRACE_EXTRA_SOURCE_FILES), \
|
||||
EXCLUDES := $(JVM_EXCLUDES), \
|
||||
EXCLUDE_FILES := $(JVM_EXCLUDE_FILES), \
|
||||
EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 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
|
||||
@ -31,11 +31,8 @@ include NativeCompilation.gmk
|
||||
|
||||
include HotspotCommon.gmk
|
||||
|
||||
# The dtrace setup must be done both before and after CompileJvm.gmk, due to
|
||||
# intricate dependencies.
|
||||
include lib/CompileDtracePreJvm.gmk
|
||||
include lib/CompileJvm.gmk
|
||||
include lib/CompileDtracePostJvm.gmk
|
||||
include lib/CompileDtraceLibraries.gmk
|
||||
|
||||
ifeq ($(BUILD_GTEST), true)
|
||||
include lib/CompileGtest.gmk
|
||||
|
||||
@ -23,64 +23,26 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
# Support for dtrace integration with libjvm, and stand-alone dtrace library
|
||||
# compilation.
|
||||
|
||||
ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
##############################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
|
||||
############################################################################
|
||||
# Integrate with libjvm. Here we generate three object files which are
|
||||
# Integrate with libjvm. Here we generate two object files which are
|
||||
# linked with libjvm.so. This step is complicated from a dependency
|
||||
# perspective, since it needs the rest of the compiled object files from the
|
||||
# libjvm compilation, but the output is object files that are to be included
|
||||
# when linking libjvm.so. So this generation must happen as a part of the
|
||||
# libjvm compilation.
|
||||
# perspective. We add these two files to the linking of libjvm using
|
||||
# EXTRA_OBJECT_FILES, but they need to be created outside the call to
|
||||
# SetupNativeCompilation. Also, one of the files is dependent on compiled
|
||||
# object files from the libjvm compilation, so this generation must happen
|
||||
# as a part of the libjvm compilation.
|
||||
|
||||
# First we need to generate the dtraceGenOffsets tool. When run, this will
|
||||
# produce more header files and a C++ file.
|
||||
DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o
|
||||
DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o
|
||||
|
||||
# Note that generateJvmOffsets.cpp must be compiled as if it were a file
|
||||
# in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise
|
||||
# this would preferrably have been done as a part of GensrcDtrace.gmk.
|
||||
$(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \
|
||||
NAME := dtraceGenOffsets, \
|
||||
TYPE := EXECUTABLE, \
|
||||
SRC := $(TOPDIR)/make/hotspot/src/native/dtrace, \
|
||||
TOOLCHAIN := $(TOOLCHAIN_BUILD), \
|
||||
LDFLAGS := -m64, \
|
||||
CFLAGS := -m64 $(JVM_CFLAGS), \
|
||||
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
|
||||
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
|
||||
))
|
||||
|
||||
DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
|
||||
|
||||
# Argument 1: Output filename
|
||||
# Argument 2: dtrace-gen-offset tool command line option
|
||||
define SetupDtraceOffsetsGeneration
|
||||
$1: $$(BUILD_DTRACE_GEN_OFFSETS)
|
||||
$$(call LogInfo, Generating dtrace $2 file $$(@F))
|
||||
$$(call MakeDir, $$(@D))
|
||||
$$(call ExecuteWithLog, $$@, ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@ ) )
|
||||
|
||||
TARGETS += $1
|
||||
endef
|
||||
|
||||
JVM_OFFSETS_H := $(DTRACE_SUPPORT_DIR)/JvmOffsets.h
|
||||
JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp
|
||||
JVM_OFFSETS_INDEX_H := $(DTRACE_SUPPORT_DIR)/JvmOffsetsIndex.h
|
||||
|
||||
# Run the dtrace-gen-offset tool to generate these three files.
|
||||
# The generated JvmOffsets.cpp is compiled with the rest of libjvm.
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header))
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index))
|
||||
$(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table))
|
||||
DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ)
|
||||
|
||||
############################################################################
|
||||
# Generate DTRACE_OBJ which is linked with libjvm.so.
|
||||
# Generate DTRACE_OBJ which is linked with libjvm.so. It depends on a set of
|
||||
# object files from the compilation.
|
||||
|
||||
# Concatenate all *.d files into a single file
|
||||
DTRACE_SOURCE_FILES := $(addprefix $(TOPDIR)/src/hotspot/os/posix/dtrace/, \
|
||||
@ -138,13 +100,17 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
############################################################################
|
||||
# Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so.
|
||||
|
||||
JHELPER_DTRACE_SRC := $(TOPDIR)/src/hotspot/os/solaris/dtrace/jhelper.d
|
||||
|
||||
# jhelper.d includes JvmOffsetsIndex.h which was created by the gensrc step.
|
||||
DTRACE_GENSRC_DIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/dtracefiles
|
||||
JVM_OFFSETS_INDEX_H := $(DTRACE_GENSRC_DIR)/JvmOffsetsIndex.h
|
||||
|
||||
# Unfortunately dtrace generates incorrect types for some symbols in
|
||||
# dtrace_jhelper.o, resulting in "warning: symbol X has differing types"
|
||||
# See JDK-6890703 for details.
|
||||
# We work around this by fixing the types for these symbols using elfedit,
|
||||
# after dtrace has generated the .o file.
|
||||
JHELPER_DTRACE_SRC := $(TOPDIR)/src/hotspot/os/solaris/dtrace/jhelper.d
|
||||
|
||||
GetElfeditCommands = \
|
||||
$(foreach symbol, \
|
||||
$(shell $(GREP) ^extern $(JHELPER_DTRACE_SRC) | $(AWK) '{ gsub(";","") ; print $$3 }'), \
|
||||
@ -156,7 +122,7 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
$(call LogInfo, Running dtrace for $(<F))
|
||||
$(call MakeDir, $(DTRACE_SUPPORT_DIR))
|
||||
$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, \
|
||||
($(CPP) $(DTRACE_CPP_FLAGS) -I$(DTRACE_SUPPORT_DIR) $^ \
|
||||
($(CPP) $(DTRACE_CPP_FLAGS) -I$(DTRACE_GENSRC_DIR) $^ \
|
||||
> $(DTRACE_SUPPORT_DIR)/$(@F).d))
|
||||
$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \
|
||||
-s $(DTRACE_SUPPORT_DIR)/$(@F).d)
|
||||
@ -164,40 +130,5 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
$(call ExecuteWithLog, $@.elfedit, $(ELFEDIT) $(call GetElfeditCommands) $@)
|
||||
endif
|
||||
|
||||
############################################################################
|
||||
# Build the stand-alone dtrace libraries
|
||||
|
||||
LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \
|
||||
NAME := jvm_dtrace, \
|
||||
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
|
||||
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_dtrace, \
|
||||
CFLAGS := -m64 -G -mt -KPIC, \
|
||||
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
|
||||
LIBS := $(LIBDL) -lthread -ldoor, \
|
||||
MAPFILE := $(TOPDIR)/make/mapfiles/libjvm_dtrace/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
|
||||
))
|
||||
|
||||
LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db
|
||||
|
||||
# Note that libjvm_db.c has tests for COMPILER2, but this was never set by
|
||||
# the old build.
|
||||
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \
|
||||
NAME := jvm_db, \
|
||||
OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \
|
||||
SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_db, \
|
||||
CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \
|
||||
-m64 -G -mt -KPIC, \
|
||||
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
|
||||
MAPFILE := $(TOPDIR)/make/mapfiles/libjvm_db/mapfile-vers, \
|
||||
OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
|
||||
))
|
||||
|
||||
# We need the generated JvmOffsets.h before we can compile the libjvm_db source code.
|
||||
$(BUILD_LIBJVM_DB_ALL_OBJS): $(JVM_OFFSETS_H)
|
||||
|
||||
TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
|
||||
endif
|
||||
endif
|
||||
97
make/hotspot/lib/JvmFlags.gmk
Normal file
97
make/hotspot/lib/JvmFlags.gmk
Normal file
@ -0,0 +1,97 @@
|
||||
#
|
||||
# Copyright (c) 2013, 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.
|
||||
#
|
||||
|
||||
$(eval $(call IncludeCustomExtension, hotspot/lib/JvmFlags.gmk))
|
||||
|
||||
################################################################################
|
||||
# Setup JVM_CFLAGS. These are shared between GensrcDtrace.gmk and CompileJvm.gmk.
|
||||
|
||||
# This variable may be added to by a custom extension
|
||||
JVM_SRC_ROOTS += $(TOPDIR)/src/hotspot
|
||||
|
||||
JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
|
||||
$d/share \
|
||||
$d/os/$(HOTSPOT_TARGET_OS) \
|
||||
$d/os/$(HOTSPOT_TARGET_OS_TYPE) \
|
||||
$d/cpu/$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
$d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
))) \
|
||||
$(JVM_VARIANT_OUTPUTDIR)/gensrc
|
||||
#
|
||||
|
||||
JVM_CFLAGS_INCLUDES += \
|
||||
$(patsubst %,-I%,$(JVM_SRC_DIRS)) \
|
||||
-I$(TOPDIR)/src/hotspot/share/precompiled \
|
||||
-I$(TOPDIR)/src/hotspot/share/include \
|
||||
-I$(TOPDIR)/src/hotspot/os/$(HOTSPOT_TARGET_OS_TYPE)/include \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \
|
||||
-I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \
|
||||
-I$(TOPDIR)/src/java.base/share/native/libjimage \
|
||||
#
|
||||
|
||||
# INCLUDE_SUFFIX_* is only meant for including the proper
|
||||
# platform files. Don't use it to guard code. Use the value of
|
||||
# HOTSPOT_TARGET_CPU_DEFINE etc. instead.
|
||||
# Remaining TARGET_ARCH_* is needed to select the cpu specific
|
||||
# sources for 64-bit ARM ports (arm versus aarch64).
|
||||
JVM_CFLAGS_TARGET_DEFINES += \
|
||||
-DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
-DINCLUDE_SUFFIX_OS=_$(HOTSPOT_TARGET_OS) \
|
||||
-DINCLUDE_SUFFIX_CPU=_$(HOTSPOT_TARGET_CPU_ARCH) \
|
||||
-DINCLUDE_SUFFIX_COMPILER=_$(HOTSPOT_TOOLCHAIN_TYPE) \
|
||||
-DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \
|
||||
-D$(HOTSPOT_TARGET_CPU_DEFINE) \
|
||||
-DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \
|
||||
#
|
||||
|
||||
ifeq ($(DEBUG_LEVEL), release)
|
||||
# For hotspot, release builds differ internally between "optimized" and "product"
|
||||
# in that "optimize" does not define PRODUCT.
|
||||
ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized)
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT
|
||||
endif
|
||||
else ifeq ($(DEBUG_LEVEL), fastdebug)
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DASSERT
|
||||
ifeq ($(filter $(OPENJDK_TARGET_OS), windows aix), )
|
||||
# NOTE: Old build did not define CHECK_UNHANDLED_OOPS on Windows and AIX.
|
||||
JVM_CFLAGS_DEBUGLEVEL += -DCHECK_UNHANDLED_OOPS
|
||||
endif
|
||||
else ifeq ($(DEBUG_LEVEL), slowdebug)
|
||||
# _NMT_NOINLINE_ informs NMT that no inlining is done by the compiler
|
||||
JVM_CFLAGS_DEBUGLEVEL := -DASSERT -D_NMT_NOINLINE_
|
||||
endif
|
||||
|
||||
JVM_CFLAGS += \
|
||||
$(JVM_CFLAGS_DEBUGLEVEL) \
|
||||
$(JVM_CFLAGS_TARGET_DEFINES) \
|
||||
$(JVM_CFLAGS_FEATURES) \
|
||||
$(JVM_CFLAGS_INCLUDES) \
|
||||
$(EXTRA_CFLAGS) \
|
||||
#
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
ifeq ($(USE_PRECOMPILED_HEADER), false)
|
||||
JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
|
||||
endif
|
||||
@ -31,29 +31,23 @@
|
||||
* GENOFFS_SCCS_VER 34
|
||||
*/
|
||||
|
||||
#include "generateJvmOffsets.h"
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* A workaround for private and protected fields */
|
||||
#define private public
|
||||
#define protected public
|
||||
|
||||
#include <proc_service.h>
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "code/pcDesc.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "memory/heap.hpp"
|
||||
#include "memory/memRegion.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "memory/virtualspace.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "runtime/vmStructs.hpp"
|
||||
#include "utilities/accessFlags.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
typedef enum GEN_variant {
|
||||
GEN_OFFSET = 0,
|
||||
GEN_INDEX = 1,
|
||||
GEN_TABLE = 2
|
||||
} GEN_variant;
|
||||
|
||||
#ifdef COMPILER1
|
||||
#ifdef ASSERT
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@ $(eval $(call SetupJdkExecutable, BUILD_UNPACKEXE, \
|
||||
CFLAGS_solaris := -KPIC, \
|
||||
CFLAGS_macosx := -fPIC, \
|
||||
DISABLED_WARNINGS_gcc := unused-result implicit-fallthrough, \
|
||||
DISABLED_WARNINGS_microsoft := 4005, \
|
||||
LDFLAGS := $(UNPACKEXE_ZIPOBJS) \
|
||||
$(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
|
||||
@ -543,7 +543,7 @@ else
|
||||
DISABLED_WARNINGS_solstudio := \
|
||||
E_STATEMENT_NOT_REACHED \
|
||||
E_END_OF_LOOP_CODE_NOT_REACHED, \
|
||||
DISABLED_WARNINGS_microsoft := 4267 4244, \
|
||||
DISABLED_WARNINGS_microsoft := 4267 4244 4312, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
))
|
||||
|
||||
@ -155,10 +155,10 @@ endif
|
||||
################################################################################
|
||||
# Create the jsig library
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||
ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
|
||||
ifeq ($(STATIC_BUILD), false)
|
||||
|
||||
LIBJSIG_SRC_DIR := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/native/libjsig
|
||||
LIBJSIG_SRC_DIR := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjsig
|
||||
LIBJSIG_MAPFILE := $(wildcard $(TOPDIR)/make/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS))
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), linux)
|
||||
|
||||
@ -50,6 +50,7 @@ ifneq ($(OPENJDK_TARGET_OS), aix)
|
||||
|
||||
LIBJSOUND_CFLAGS := \
|
||||
-I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
|
||||
$(ALSA_CFLAGS) \
|
||||
$(LIBJAVA_HEADER_FLAGS) \
|
||||
$(foreach dir, $(LIBJSOUND_SRC_DIRS), -I$(dir)) \
|
||||
-DX_PLATFORM=X_$(OPENJDK_TARGET_OS_UPPERCASE) \
|
||||
|
||||
@ -45,6 +45,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
NAME := javaaccessbridge$1, \
|
||||
SRC := $(JAVA_AB_SRCDIR), \
|
||||
OPTIMIZATION := LOW, \
|
||||
DISABLED_WARNINGS_microsoft := 4311 4302 4312, \
|
||||
CFLAGS := $(CFLAGS_JDKLIB) $(ACCESSBRIDGE_CFLAGS) \
|
||||
$(addprefix -I,$(JAVA_AB_SRCDIR)) \
|
||||
-I$(ROOT_SRCDIR)/include/bridge \
|
||||
@ -69,6 +70,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
NAME := windowsaccessbridge$1, \
|
||||
SRC := $(WIN_AB_SRCDIR), \
|
||||
OPTIMIZATION := LOW, \
|
||||
DISABLED_WARNINGS_microsoft := 4311 4302 4312, \
|
||||
CFLAGS := $(filter-out -MD, $(CFLAGS_JDKLIB)) -MT $(ACCESSBRIDGE_CFLAGS) \
|
||||
$(addprefix -I,$(WIN_AB_SRCDIR)) \
|
||||
-I$(ROOT_SRCDIR)/include/bridge \
|
||||
|
||||
@ -40,6 +40,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBUNPACK, \
|
||||
$(LIBJAVA_HEADER_FLAGS), \
|
||||
CFLAGS_release := -DPRODUCT, \
|
||||
DISABLED_WARNINGS_gcc := implicit-fallthrough, \
|
||||
DISABLED_WARNINGS_microsoft := 4005, \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LDFLAGS_windows := -map:$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpack.map -debug, \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2005, 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
|
||||
@ -28,7 +28,6 @@ SUNWprivate_1.1 {
|
||||
global:
|
||||
JVM_begin_signal_setting;
|
||||
JVM_end_signal_setting;
|
||||
JVM_get_libjsig_version;
|
||||
JVM_get_signal_action;
|
||||
sigaction;
|
||||
signal;
|
||||
|
||||
@ -2101,8 +2101,6 @@ static jint *pending_signals = NULL;
|
||||
static int *preinstalled_sigs = NULL;
|
||||
static struct sigaction *chainedsigactions = NULL;
|
||||
static Semaphore* sig_sem = NULL;
|
||||
typedef int (*version_getting_t)();
|
||||
version_getting_t os::Solaris::get_libjsig_version = NULL;
|
||||
|
||||
int os::sigexitnum_pd() {
|
||||
assert(Sigexit > 0, "signal memory not yet initialized");
|
||||
@ -3968,13 +3966,7 @@ void os::Solaris::install_signal_handlers() {
|
||||
dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
|
||||
get_signal_action = CAST_TO_FN_PTR(get_signal_t,
|
||||
dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
|
||||
get_libjsig_version = CAST_TO_FN_PTR(version_getting_t,
|
||||
dlsym(RTLD_DEFAULT, "JVM_get_libjsig_version"));
|
||||
libjsig_is_loaded = true;
|
||||
if (os::Solaris::get_libjsig_version != NULL) {
|
||||
int libjsigversion = (*os::Solaris::get_libjsig_version)();
|
||||
assert(libjsigversion == JSIG_VERSION_1_4_1, "libjsig version mismatch");
|
||||
}
|
||||
assert(UseSignalChaining, "should enable signal-chaining");
|
||||
}
|
||||
if (libjsig_is_loaded) {
|
||||
|
||||
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* CopyrightVersion 1.2 */
|
||||
|
||||
/* This is a special library that should be loaded before libc &
|
||||
* libthread to interpose the signal handler installation functions:
|
||||
* sigaction(), signal(), sigset().
|
||||
* Used for signal-chaining. See RFE 4381843.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define MASK(sig) ((uint64_t)1 << (sig-1)) // 0 is not a signal.
|
||||
// Check whether all signals fit into jvmsigs. -1 as MASK shifts by -1.
|
||||
#if (64 < NSIG-1)
|
||||
#error "Not all signals can be encoded in jvmsigs. Adapt its type!"
|
||||
#endif
|
||||
static struct sigaction sact[NSIG]; /* saved signal handlers */
|
||||
static uint64_t jvmsigs = 0; /* signals used by jvm */
|
||||
|
||||
/* used to synchronize the installation of signal handlers */
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_t tid = 0;
|
||||
|
||||
typedef void (*sa_handler_t)(int);
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
typedef sa_handler_t (*signal_t)(int, sa_handler_t);
|
||||
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
|
||||
|
||||
static signal_t os_signal = 0; /* os's version of signal()/sigset() */
|
||||
static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
|
||||
|
||||
static bool jvm_signal_installing = false;
|
||||
static bool jvm_signal_installed = false;
|
||||
|
||||
static void signal_lock() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
/* When the jvm is installing its set of signal handlers, threads
|
||||
* other than the jvm thread should wait */
|
||||
if (jvm_signal_installing) {
|
||||
if (tid != pthread_self()) {
|
||||
pthread_cond_wait(&cond, &mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_unlock() {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
|
||||
bool is_sigset) {
|
||||
if (os_signal == NULL) {
|
||||
if (!is_sigset) {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
|
||||
} else {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset");
|
||||
}
|
||||
if (os_signal == NULL) {
|
||||
printf("%s\n", dlerror());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return (*os_signal)(sig, disp);
|
||||
}
|
||||
|
||||
static void save_signal_handler(int sig, sa_handler_t disp) {
|
||||
sigset_t set;
|
||||
sact[sig].sa_handler = disp;
|
||||
sigemptyset(&set);
|
||||
sact[sig].sa_mask = set;
|
||||
sact[sig].sa_flags = 0;
|
||||
}
|
||||
|
||||
static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
sa_handler_t oldhandler;
|
||||
bool sigused;
|
||||
|
||||
signal_lock();
|
||||
|
||||
sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
oldhandler = sact[sig].sa_handler;
|
||||
save_signal_handler(sig, disp);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
} else if (sig < NSIG && jvm_signal_installing) {
|
||||
/* jvm is installing its signal handlers. Install the new
|
||||
* handlers and save the old ones. jvm uses sigaction().
|
||||
* Leave the piece here just in case. */
|
||||
oldhandler = call_os_signal(sig, disp, is_sigset);
|
||||
save_signal_handler(sig, oldhandler);
|
||||
|
||||
/* Record the signals used by jvm */
|
||||
jvmsigs |= MASK(sig);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
} else {
|
||||
/* jvm has no relation with this signal (yet). Install the
|
||||
* the handler. */
|
||||
oldhandler = call_os_signal(sig, disp, is_sigset);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
}
|
||||
}
|
||||
|
||||
sa_handler_t signal(int sig, sa_handler_t disp) {
|
||||
return set_signal(sig, disp, false);
|
||||
}
|
||||
|
||||
sa_handler_t sigset(int sig, sa_handler_t disp) {
|
||||
return set_signal(sig, disp, true);
|
||||
}
|
||||
|
||||
static int call_os_sigaction(int sig, const struct sigaction *act,
|
||||
struct sigaction *oact) {
|
||||
if (os_sigaction == NULL) {
|
||||
os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction");
|
||||
if (os_sigaction == NULL) {
|
||||
printf("%s\n", dlerror());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return (*os_sigaction)(sig, act, oact);
|
||||
}
|
||||
|
||||
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
||||
int res;
|
||||
bool sigused;
|
||||
struct sigaction oldAct;
|
||||
|
||||
signal_lock();
|
||||
|
||||
sigused = (sig < NSIG) && ((MASK(sig) & jvmsigs) != 0);
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
if (oact != NULL) {
|
||||
*oact = sact[sig];
|
||||
}
|
||||
if (act != NULL) {
|
||||
sact[sig] = *act;
|
||||
}
|
||||
|
||||
signal_unlock();
|
||||
return 0;
|
||||
} else if (sig < NSIG && jvm_signal_installing) {
|
||||
/* jvm is installing its signal handlers. Install the new
|
||||
* handlers and save the old ones. */
|
||||
res = call_os_sigaction(sig, act, &oldAct);
|
||||
sact[sig] = oldAct;
|
||||
if (oact != NULL) {
|
||||
*oact = oldAct;
|
||||
}
|
||||
|
||||
/* Record the signals used by jvm */
|
||||
jvmsigs |= MASK(sig);
|
||||
|
||||
signal_unlock();
|
||||
return res;
|
||||
} else {
|
||||
/* jvm has no relation with this signal (yet). Install the
|
||||
* the handler. */
|
||||
res = call_os_sigaction(sig, act, oact);
|
||||
|
||||
signal_unlock();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* The three functions for the jvm to call into */
|
||||
void JVM_begin_signal_setting() {
|
||||
signal_lock();
|
||||
jvm_signal_installing = true;
|
||||
tid = pthread_self();
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
void JVM_end_signal_setting() {
|
||||
signal_lock();
|
||||
jvm_signal_installed = true;
|
||||
jvm_signal_installing = false;
|
||||
pthread_cond_broadcast(&cond);
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
struct sigaction *JVM_get_signal_action(int sig) {
|
||||
/* Does race condition make sense here? */
|
||||
if ((MASK(sig) & jvmsigs) != 0) {
|
||||
return &sact[sig];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -1,237 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/* CopyrightVersion 1.2 */
|
||||
|
||||
/* This is a special library that should be loaded before libc &
|
||||
* libthread to interpose the signal handler installation functions:
|
||||
* sigaction(), signal(), sigset().
|
||||
* Used for signal-chaining. See RFE 4381843.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MASK(sig) ((uint32_t)1 << (sig-1)) // 0 is not a signal.
|
||||
#if (32 < NSIG-1)
|
||||
#error "Not all signals can be encoded in jvmsigs. Adapt its type!"
|
||||
#endif
|
||||
static struct sigaction sact[NSIG]; /* saved signal handlers */
|
||||
static uint32_t jvmsigs = 0; /* signals used by jvm */
|
||||
static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
|
||||
|
||||
/* used to synchronize the installation of signal handlers */
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_t tid = 0;
|
||||
|
||||
typedef void (*sa_handler_t)(int);
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
typedef sa_handler_t (*signal_t)(int, sa_handler_t);
|
||||
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
|
||||
|
||||
static signal_t os_signal = 0; /* os's version of signal()/sigset() */
|
||||
static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
|
||||
|
||||
static bool jvm_signal_installing = false;
|
||||
static bool jvm_signal_installed = false;
|
||||
|
||||
static void signal_lock() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
/* When the jvm is installing its set of signal handlers, threads
|
||||
* other than the jvm thread should wait */
|
||||
if (jvm_signal_installing) {
|
||||
if (tid != pthread_self()) {
|
||||
pthread_cond_wait(&cond, &mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_unlock() {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
|
||||
bool is_sigset) {
|
||||
sa_handler_t res;
|
||||
|
||||
if (os_signal == NULL) {
|
||||
if (!is_sigset) {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
|
||||
} else {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset");
|
||||
}
|
||||
if (os_signal == NULL) {
|
||||
printf("%s\n", dlerror());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
reentry = true;
|
||||
res = (*os_signal)(sig, disp);
|
||||
reentry = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void save_signal_handler(int sig, sa_handler_t disp) {
|
||||
sigset_t set;
|
||||
sact[sig].sa_handler = disp;
|
||||
sigemptyset(&set);
|
||||
sact[sig].sa_mask = set;
|
||||
sact[sig].sa_flags = 0;
|
||||
}
|
||||
|
||||
static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
sa_handler_t oldhandler;
|
||||
bool sigused;
|
||||
|
||||
signal_lock();
|
||||
|
||||
sigused = (MASK(sig) & jvmsigs) != 0;
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
oldhandler = sact[sig].sa_handler;
|
||||
save_signal_handler(sig, disp);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
} else if (jvm_signal_installing) {
|
||||
/* jvm is installing its signal handlers. Install the new
|
||||
* handlers and save the old ones. jvm uses sigaction().
|
||||
* Leave the piece here just in case. */
|
||||
oldhandler = call_os_signal(sig, disp, is_sigset);
|
||||
save_signal_handler(sig, oldhandler);
|
||||
|
||||
/* Record the signals used by jvm */
|
||||
jvmsigs |= MASK(sig);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
} else {
|
||||
/* jvm has no relation with this signal (yet). Install the
|
||||
* the handler. */
|
||||
oldhandler = call_os_signal(sig, disp, is_sigset);
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
}
|
||||
}
|
||||
|
||||
sa_handler_t signal(int sig, sa_handler_t disp) {
|
||||
return set_signal(sig, disp, false);
|
||||
}
|
||||
|
||||
sa_handler_t sigset(int sig, sa_handler_t disp) {
|
||||
printf("sigset() is not supported by BSD");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int call_os_sigaction(int sig, const struct sigaction *act,
|
||||
struct sigaction *oact) {
|
||||
if (os_sigaction == NULL) {
|
||||
os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction");
|
||||
if (os_sigaction == NULL) {
|
||||
printf("%s\n", dlerror());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return (*os_sigaction)(sig, act, oact);
|
||||
}
|
||||
|
||||
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
||||
int res;
|
||||
bool sigused;
|
||||
struct sigaction oldAct;
|
||||
|
||||
if (reentry) {
|
||||
return call_os_sigaction(sig, act, oact);
|
||||
}
|
||||
|
||||
signal_lock();
|
||||
|
||||
sigused = (MASK(sig) & jvmsigs) != 0;
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
if (oact != NULL) {
|
||||
*oact = sact[sig];
|
||||
}
|
||||
if (act != NULL) {
|
||||
sact[sig] = *act;
|
||||
}
|
||||
|
||||
signal_unlock();
|
||||
return 0;
|
||||
} else if (jvm_signal_installing) {
|
||||
/* jvm is installing its signal handlers. Install the new
|
||||
* handlers and save the old ones. */
|
||||
res = call_os_sigaction(sig, act, &oldAct);
|
||||
sact[sig] = oldAct;
|
||||
if (oact != NULL) {
|
||||
*oact = oldAct;
|
||||
}
|
||||
|
||||
/* Record the signals used by jvm */
|
||||
jvmsigs |= MASK(sig);
|
||||
|
||||
signal_unlock();
|
||||
return res;
|
||||
} else {
|
||||
/* jvm has no relation with this signal (yet). Install the
|
||||
* the handler. */
|
||||
res = call_os_sigaction(sig, act, oact);
|
||||
|
||||
signal_unlock();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* The three functions for the jvm to call into */
|
||||
void JVM_begin_signal_setting() {
|
||||
signal_lock();
|
||||
jvm_signal_installing = true;
|
||||
tid = pthread_self();
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
void JVM_end_signal_setting() {
|
||||
signal_lock();
|
||||
jvm_signal_installed = true;
|
||||
jvm_signal_installing = false;
|
||||
pthread_cond_broadcast(&cond);
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
struct sigaction *JVM_get_signal_action(int sig) {
|
||||
/* Does race condition make sense here? */
|
||||
if ((MASK(sig) & jvmsigs) != 0) {
|
||||
return &sact[sig];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -42,7 +42,6 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import sun.nio.cs.HistoricallyNamedCharset;
|
||||
import sun.nio.cs.ArrayDecoder;
|
||||
import sun.nio.cs.ArrayEncoder;
|
||||
import sun.nio.cs.StandardCharsets;
|
||||
|
||||
import static java.lang.String.LATIN1;
|
||||
import static java.lang.String.UTF16;
|
||||
@ -52,9 +51,6 @@ import static java.lang.Character.highSurrogate;
|
||||
import static java.lang.Character.lowSurrogate;
|
||||
import static java.lang.Character.isSupplementaryCodePoint;
|
||||
import static java.lang.StringUTF16.putChar;
|
||||
import static java.nio.charset.StandardCharsets.ISO_8859_1;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
/**
|
||||
* Utility class for string encoding and decoding.
|
||||
@ -70,6 +66,10 @@ class StringCoding {
|
||||
private static final ThreadLocal<SoftReference<StringEncoder>> encoder =
|
||||
new ThreadLocal<>();
|
||||
|
||||
private static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
|
||||
private static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
|
||||
private static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
|
||||
|
||||
private static <T> T deref(ThreadLocal<SoftReference<T>> tl) {
|
||||
SoftReference<T> sr = tl.get();
|
||||
if (sr == null)
|
||||
|
||||
@ -609,7 +609,7 @@ public abstract class Charset
|
||||
if (cs != null)
|
||||
defaultCharset = cs;
|
||||
else
|
||||
defaultCharset = StandardCharsets.UTF_8;
|
||||
defaultCharset = sun.nio.cs.UTF_8.INSTANCE;
|
||||
}
|
||||
}
|
||||
return defaultCharset;
|
||||
|
||||
@ -34,22 +34,28 @@ package java.nio.charset;
|
||||
*/
|
||||
public final class StandardCharsets {
|
||||
|
||||
// To avoid accidental eager initialization of often unused Charsets
|
||||
// from happening while the VM is booting up, which may delay
|
||||
// initialization of VM components, we should generally avoid depending
|
||||
// on this class from elsewhere in java.base.
|
||||
|
||||
private StandardCharsets() {
|
||||
throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
|
||||
* Unicode character set
|
||||
*/
|
||||
public static final Charset US_ASCII = new sun.nio.cs.US_ASCII();
|
||||
public static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
|
||||
/**
|
||||
* ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
|
||||
*/
|
||||
public static final Charset ISO_8859_1 = new sun.nio.cs.ISO_8859_1();
|
||||
public static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
|
||||
/**
|
||||
* Eight-bit UCS Transformation Format
|
||||
*/
|
||||
public static final Charset UTF_8 = new sun.nio.cs.UTF_8();
|
||||
public static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
|
||||
/**
|
||||
* Sixteen-bit UCS Transformation Format, big-endian byte order
|
||||
*/
|
||||
|
||||
@ -208,7 +208,7 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
*/
|
||||
public ArrayDeque(Collection<? extends E> c) {
|
||||
this(c.size());
|
||||
addAll(c);
|
||||
copyElements(c);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,10 +322,14 @@ public class ArrayDeque<E> extends AbstractCollection<E>
|
||||
final int s, needed;
|
||||
if ((needed = (s = size()) + c.size() + 1 - elements.length) > 0)
|
||||
grow(needed);
|
||||
c.forEach(this::addLast);
|
||||
copyElements(c);
|
||||
return size() > s;
|
||||
}
|
||||
|
||||
private void copyElements(Collection<? extends E> c) {
|
||||
c.forEach(this::addLast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element at the front of this deque.
|
||||
*
|
||||
|
||||
@ -141,8 +141,8 @@ package java.util;
|
||||
* <p>Deques can also be used as LIFO (Last-In-First-Out) stacks. This
|
||||
* interface should be used in preference to the legacy {@link Stack} class.
|
||||
* When a deque is used as a stack, elements are pushed and popped from the
|
||||
* beginning of the deque. Stack methods are precisely equivalent to
|
||||
* {@code Deque} methods as indicated in the table below:
|
||||
* beginning of the deque. Stack methods are equivalent to {@code Deque}
|
||||
* methods as indicated in the table below:
|
||||
*
|
||||
* <table class="striped">
|
||||
* <caption>Comparison of Stack and Deque methods</caption>
|
||||
@ -163,7 +163,7 @@ package java.util;
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">{@link #peek() peek()}</th>
|
||||
* <td>{@link #peekFirst() peekFirst()}</td>
|
||||
* <td>{@link #getFirst() getFirst()}</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
|
||||
@ -2883,7 +2883,7 @@ public class CompletableFuture<T> implements Future<T>, CompletionStage<T> {
|
||||
STACK = l.findVarHandle(CompletableFuture.class, "stack", Completion.class);
|
||||
NEXT = l.findVarHandle(Completion.class, "next", Completion.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -6383,7 +6383,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
|
||||
ABASE = U.arrayBaseOffset(Node[].class);
|
||||
int scale = U.arrayIndexScale(Node[].class);
|
||||
if ((scale & (scale - 1)) != 0)
|
||||
throw new Error("array index scale not a power of two");
|
||||
throw new ExceptionInInitializerError("array index scale not a power of two");
|
||||
ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -1671,7 +1671,7 @@ public class ConcurrentLinkedDeque<E>
|
||||
NEXT = l.findVarHandle(Node.class, "next", Node.class);
|
||||
ITEM = l.findVarHandle(Node.class, "item", Object.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1069,7 +1069,7 @@ public class ConcurrentLinkedQueue<E> extends AbstractQueue<E>
|
||||
ITEM = l.findVarHandle(Node.class, "item", Object.class);
|
||||
NEXT = l.findVarHandle(Node.class, "next", Node.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3412,7 +3412,7 @@ public class ConcurrentSkipListMap<K,V> extends AbstractMap<K,V>
|
||||
VAL = l.findVarHandle(Node.class, "val", Object.class);
|
||||
RIGHT = l.findVarHandle(Index.class, "right", Index.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
package java.util.concurrent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
@ -134,17 +133,17 @@ public class CopyOnWriteArrayList<E>
|
||||
* @throws NullPointerException if the specified collection is null
|
||||
*/
|
||||
public CopyOnWriteArrayList(Collection<? extends E> c) {
|
||||
Object[] elements;
|
||||
Object[] es;
|
||||
if (c.getClass() == CopyOnWriteArrayList.class)
|
||||
elements = ((CopyOnWriteArrayList<?>)c).getArray();
|
||||
es = ((CopyOnWriteArrayList<?>)c).getArray();
|
||||
else {
|
||||
elements = c.toArray();
|
||||
es = c.toArray();
|
||||
// defend against c.toArray (incorrectly) not returning Object[]
|
||||
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
|
||||
if (elements.getClass() != Object[].class)
|
||||
elements = Arrays.copyOf(elements, elements.length, Object[].class);
|
||||
if (es.getClass() != Object[].class)
|
||||
es = Arrays.copyOf(es, es.length, Object[].class);
|
||||
}
|
||||
setArray(elements);
|
||||
setArray(es);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -180,20 +179,19 @@ public class CopyOnWriteArrayList<E>
|
||||
* static version of indexOf, to allow repeated calls without
|
||||
* needing to re-acquire array each time.
|
||||
* @param o element to search for
|
||||
* @param elements the array
|
||||
* @param index first index to search
|
||||
* @param fence one past last index to search
|
||||
* @param es the array
|
||||
* @param from first index to search
|
||||
* @param to one past last index to search
|
||||
* @return index of element, or -1 if absent
|
||||
*/
|
||||
private static int indexOf(Object o, Object[] elements,
|
||||
int index, int fence) {
|
||||
private static int indexOfRange(Object o, Object[] es, int from, int to) {
|
||||
if (o == null) {
|
||||
for (int i = index; i < fence; i++)
|
||||
if (elements[i] == null)
|
||||
for (int i = from; i < to; i++)
|
||||
if (es[i] == null)
|
||||
return i;
|
||||
} else {
|
||||
for (int i = index; i < fence; i++)
|
||||
if (o.equals(elements[i]))
|
||||
for (int i = from; i < to; i++)
|
||||
if (o.equals(es[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -202,18 +200,19 @@ public class CopyOnWriteArrayList<E>
|
||||
/**
|
||||
* static version of lastIndexOf.
|
||||
* @param o element to search for
|
||||
* @param elements the array
|
||||
* @param index first index to search
|
||||
* @param es the array
|
||||
* @param from index of first element of range, last element to search
|
||||
* @param to one past last element of range, first element to search
|
||||
* @return index of element, or -1 if absent
|
||||
*/
|
||||
private static int lastIndexOf(Object o, Object[] elements, int index) {
|
||||
private static int lastIndexOfRange(Object o, Object[] es, int from, int to) {
|
||||
if (o == null) {
|
||||
for (int i = index; i >= 0; i--)
|
||||
if (elements[i] == null)
|
||||
for (int i = to - 1; i >= from; i--)
|
||||
if (es[i] == null)
|
||||
return i;
|
||||
} else {
|
||||
for (int i = index; i >= 0; i--)
|
||||
if (o.equals(elements[i]))
|
||||
for (int i = to - 1; i >= from; i--)
|
||||
if (o.equals(es[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@ -228,16 +227,15 @@ public class CopyOnWriteArrayList<E>
|
||||
* @return {@code true} if this list contains the specified element
|
||||
*/
|
||||
public boolean contains(Object o) {
|
||||
Object[] elements = getArray();
|
||||
return indexOf(o, elements, 0, elements.length) >= 0;
|
||||
return indexOf(o) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int indexOf(Object o) {
|
||||
Object[] elements = getArray();
|
||||
return indexOf(o, elements, 0, elements.length);
|
||||
Object[] es = getArray();
|
||||
return indexOfRange(o, es, 0, es.length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,16 +254,16 @@ public class CopyOnWriteArrayList<E>
|
||||
* @throws IndexOutOfBoundsException if the specified index is negative
|
||||
*/
|
||||
public int indexOf(E e, int index) {
|
||||
Object[] elements = getArray();
|
||||
return indexOf(e, elements, index, elements.length);
|
||||
Object[] es = getArray();
|
||||
return indexOfRange(e, es, index, es.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public int lastIndexOf(Object o) {
|
||||
Object[] elements = getArray();
|
||||
return lastIndexOf(o, elements, elements.length - 1);
|
||||
Object[] es = getArray();
|
||||
return lastIndexOfRange(o, es, 0, es.length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -285,8 +283,8 @@ public class CopyOnWriteArrayList<E>
|
||||
* than or equal to the current size of this list
|
||||
*/
|
||||
public int lastIndexOf(E e, int index) {
|
||||
Object[] elements = getArray();
|
||||
return lastIndexOf(e, elements, index);
|
||||
Object[] es = getArray();
|
||||
return lastIndexOfRange(e, es, 0, index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,8 +320,7 @@ public class CopyOnWriteArrayList<E>
|
||||
* @return an array containing all the elements in this list
|
||||
*/
|
||||
public Object[] toArray() {
|
||||
Object[] elements = getArray();
|
||||
return Arrays.copyOf(elements, elements.length);
|
||||
return getArray().clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -366,12 +363,12 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
if (a.length < len)
|
||||
return (T[]) Arrays.copyOf(elements, len, a.getClass());
|
||||
return (T[]) Arrays.copyOf(es, len, a.getClass());
|
||||
else {
|
||||
System.arraycopy(elements, 0, a, 0, len);
|
||||
System.arraycopy(es, 0, a, 0, len);
|
||||
if (a.length > len)
|
||||
a[len] = null;
|
||||
return a;
|
||||
@ -406,17 +403,13 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public E set(int index, E element) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
E oldValue = elementAt(elements, index);
|
||||
Object[] es = getArray();
|
||||
E oldValue = elementAt(es, index);
|
||||
|
||||
if (oldValue != element) {
|
||||
int len = elements.length;
|
||||
Object[] newElements = Arrays.copyOf(elements, len);
|
||||
newElements[index] = element;
|
||||
setArray(newElements);
|
||||
} else {
|
||||
// Not quite a no-op; ensures volatile write semantics
|
||||
setArray(elements);
|
||||
es = es.clone();
|
||||
es[index] = element;
|
||||
setArray(es);
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
@ -430,11 +423,11 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public boolean add(E e) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] newElements = Arrays.copyOf(elements, len + 1);
|
||||
newElements[len] = e;
|
||||
setArray(newElements);
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
es = Arrays.copyOf(es, len + 1);
|
||||
es[len] = e;
|
||||
setArray(es);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -448,18 +441,18 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public void add(int index, E element) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
if (index > len || index < 0)
|
||||
throw new IndexOutOfBoundsException(outOfBounds(index, len));
|
||||
Object[] newElements;
|
||||
int numMoved = len - index;
|
||||
if (numMoved == 0)
|
||||
newElements = Arrays.copyOf(elements, len + 1);
|
||||
newElements = Arrays.copyOf(es, len + 1);
|
||||
else {
|
||||
newElements = new Object[len + 1];
|
||||
System.arraycopy(elements, 0, newElements, 0, index);
|
||||
System.arraycopy(elements, index, newElements, index + 1,
|
||||
System.arraycopy(es, 0, newElements, 0, index);
|
||||
System.arraycopy(es, index, newElements, index + 1,
|
||||
numMoved);
|
||||
}
|
||||
newElements[index] = element;
|
||||
@ -476,19 +469,20 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public E remove(int index) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
E oldValue = elementAt(elements, index);
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
E oldValue = elementAt(es, index);
|
||||
int numMoved = len - index - 1;
|
||||
Object[] newElements;
|
||||
if (numMoved == 0)
|
||||
setArray(Arrays.copyOf(elements, len - 1));
|
||||
newElements = Arrays.copyOf(es, len - 1);
|
||||
else {
|
||||
Object[] newElements = new Object[len - 1];
|
||||
System.arraycopy(elements, 0, newElements, 0, index);
|
||||
System.arraycopy(elements, index + 1, newElements, index,
|
||||
newElements = new Object[len - 1];
|
||||
System.arraycopy(es, 0, newElements, 0, index);
|
||||
System.arraycopy(es, index + 1, newElements, index,
|
||||
numMoved);
|
||||
setArray(newElements);
|
||||
}
|
||||
setArray(newElements);
|
||||
return oldValue;
|
||||
}
|
||||
}
|
||||
@ -507,7 +501,7 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
Object[] snapshot = getArray();
|
||||
int index = indexOf(o, snapshot, 0, snapshot.length);
|
||||
int index = indexOfRange(o, snapshot, 0, snapshot.length);
|
||||
return index >= 0 && remove(o, snapshot, index);
|
||||
}
|
||||
|
||||
@ -532,7 +526,7 @@ public class CopyOnWriteArrayList<E>
|
||||
return false;
|
||||
if (current[index] == o)
|
||||
break findIndex;
|
||||
index = indexOf(o, current, index, len);
|
||||
index = indexOfRange(o, current, index, len);
|
||||
if (index < 0)
|
||||
return false;
|
||||
}
|
||||
@ -560,19 +554,19 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
void removeRange(int fromIndex, int toIndex) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
|
||||
if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
|
||||
throw new IndexOutOfBoundsException();
|
||||
int newlen = len - (toIndex - fromIndex);
|
||||
int numMoved = len - toIndex;
|
||||
if (numMoved == 0)
|
||||
setArray(Arrays.copyOf(elements, newlen));
|
||||
setArray(Arrays.copyOf(es, newlen));
|
||||
else {
|
||||
Object[] newElements = new Object[newlen];
|
||||
System.arraycopy(elements, 0, newElements, 0, fromIndex);
|
||||
System.arraycopy(elements, toIndex, newElements,
|
||||
System.arraycopy(es, 0, newElements, 0, fromIndex);
|
||||
System.arraycopy(es, toIndex, newElements,
|
||||
fromIndex, numMoved);
|
||||
setArray(newElements);
|
||||
}
|
||||
@ -587,7 +581,7 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public boolean addIfAbsent(E e) {
|
||||
Object[] snapshot = getArray();
|
||||
return indexOf(e, snapshot, 0, snapshot.length) < 0
|
||||
return indexOfRange(e, snapshot, 0, snapshot.length) < 0
|
||||
&& addIfAbsent(e, snapshot);
|
||||
}
|
||||
|
||||
@ -606,7 +600,7 @@ public class CopyOnWriteArrayList<E>
|
||||
if (current[i] != snapshot[i]
|
||||
&& Objects.equals(e, current[i]))
|
||||
return false;
|
||||
if (indexOf(e, current, common, len) >= 0)
|
||||
if (indexOfRange(e, current, common, len) >= 0)
|
||||
return false;
|
||||
}
|
||||
Object[] newElements = Arrays.copyOf(current, len + 1);
|
||||
@ -627,10 +621,10 @@ public class CopyOnWriteArrayList<E>
|
||||
* @see #contains(Object)
|
||||
*/
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
for (Object e : c) {
|
||||
if (indexOf(e, elements, 0, len) < 0)
|
||||
if (indexOfRange(e, es, 0, len) < 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -694,18 +688,18 @@ public class CopyOnWriteArrayList<E>
|
||||
if (cs.length == 0)
|
||||
return 0;
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
int added = 0;
|
||||
// uniquify and compact elements in cs
|
||||
for (int i = 0; i < cs.length; ++i) {
|
||||
Object e = cs[i];
|
||||
if (indexOf(e, elements, 0, len) < 0 &&
|
||||
indexOf(e, cs, 0, added) < 0)
|
||||
if (indexOfRange(e, es, 0, len) < 0 &&
|
||||
indexOfRange(e, cs, 0, added) < 0)
|
||||
cs[added++] = e;
|
||||
}
|
||||
if (added > 0) {
|
||||
Object[] newElements = Arrays.copyOf(elements, len + added);
|
||||
Object[] newElements = Arrays.copyOf(es, len + added);
|
||||
System.arraycopy(cs, 0, newElements, len, added);
|
||||
setArray(newElements);
|
||||
}
|
||||
@ -739,15 +733,16 @@ public class CopyOnWriteArrayList<E>
|
||||
if (cs.length == 0)
|
||||
return false;
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
Object[] newElements;
|
||||
if (len == 0 && cs.getClass() == Object[].class)
|
||||
setArray(cs);
|
||||
newElements = cs;
|
||||
else {
|
||||
Object[] newElements = Arrays.copyOf(elements, len + cs.length);
|
||||
newElements = Arrays.copyOf(es, len + cs.length);
|
||||
System.arraycopy(cs, 0, newElements, len, cs.length);
|
||||
setArray(newElements);
|
||||
}
|
||||
setArray(newElements);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -771,8 +766,8 @@ public class CopyOnWriteArrayList<E>
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
Object[] cs = c.toArray();
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
if (index > len || index < 0)
|
||||
throw new IndexOutOfBoundsException(outOfBounds(index, len));
|
||||
if (cs.length == 0)
|
||||
@ -780,11 +775,11 @@ public class CopyOnWriteArrayList<E>
|
||||
int numMoved = len - index;
|
||||
Object[] newElements;
|
||||
if (numMoved == 0)
|
||||
newElements = Arrays.copyOf(elements, len + cs.length);
|
||||
newElements = Arrays.copyOf(es, len + cs.length);
|
||||
else {
|
||||
newElements = new Object[len + cs.length];
|
||||
System.arraycopy(elements, 0, newElements, 0, index);
|
||||
System.arraycopy(elements, index,
|
||||
System.arraycopy(es, 0, newElements, 0, index);
|
||||
System.arraycopy(es, index,
|
||||
newElements, index + cs.length,
|
||||
numMoved);
|
||||
}
|
||||
@ -866,14 +861,14 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
public void replaceAll(UnaryOperator<E> operator) {
|
||||
Objects.requireNonNull(operator);
|
||||
synchronized (lock) {
|
||||
replaceAll(operator, 0, getArray().length);
|
||||
replaceAllRange(operator, 0, getArray().length);
|
||||
}
|
||||
}
|
||||
|
||||
void replaceAll(UnaryOperator<E> operator, int i, int end) {
|
||||
void replaceAllRange(UnaryOperator<E> operator, int i, int end) {
|
||||
// assert Thread.holdsLock(lock);
|
||||
Objects.requireNonNull(operator);
|
||||
final Object[] es = getArray().clone();
|
||||
for (; i < end; i++)
|
||||
es[i] = operator.apply(elementAt(es, i));
|
||||
@ -882,12 +877,12 @@ public class CopyOnWriteArrayList<E>
|
||||
|
||||
public void sort(Comparator<? super E> c) {
|
||||
synchronized (lock) {
|
||||
sort(c, 0, getArray().length);
|
||||
sortRange(c, 0, getArray().length);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void sort(Comparator<? super E> c, int i, int end) {
|
||||
void sortRange(Comparator<? super E> c, int i, int end) {
|
||||
// assert Thread.holdsLock(lock);
|
||||
final Object[] es = getArray().clone();
|
||||
Arrays.sort(es, i, end, (Comparator<Object>)c);
|
||||
@ -908,12 +903,12 @@ public class CopyOnWriteArrayList<E>
|
||||
|
||||
s.defaultWriteObject();
|
||||
|
||||
Object[] elements = getArray();
|
||||
Object[] es = getArray();
|
||||
// Write out array length
|
||||
s.writeInt(elements.length);
|
||||
s.writeInt(es.length);
|
||||
|
||||
// Write out all elements in the proper order.
|
||||
for (Object element : elements)
|
||||
for (Object element : es)
|
||||
s.writeObject(element);
|
||||
}
|
||||
|
||||
@ -935,12 +930,12 @@ public class CopyOnWriteArrayList<E>
|
||||
// Read in array length and allocate array
|
||||
int len = s.readInt();
|
||||
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, len);
|
||||
Object[] elements = new Object[len];
|
||||
Object[] es = new Object[len];
|
||||
|
||||
// Read in all elements in the proper order.
|
||||
for (int i = 0; i < len; i++)
|
||||
elements[i] = s.readObject();
|
||||
setArray(elements);
|
||||
es[i] = s.readObject();
|
||||
setArray(es);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -986,6 +981,15 @@ public class CopyOnWriteArrayList<E>
|
||||
return !it.hasNext();
|
||||
}
|
||||
|
||||
private static int hashCodeOfRange(Object[] es, int from, int to) {
|
||||
int hashCode = 1;
|
||||
for (int i = from; i < to; i++) {
|
||||
Object x = es[i];
|
||||
hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode());
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this list.
|
||||
*
|
||||
@ -994,10 +998,8 @@ public class CopyOnWriteArrayList<E>
|
||||
* @return the hash code value for this list
|
||||
*/
|
||||
public int hashCode() {
|
||||
int hashCode = 1;
|
||||
for (Object x : getArray())
|
||||
hashCode = 31 * hashCode + (x == null ? 0 : x.hashCode());
|
||||
return hashCode;
|
||||
Object[] es = getArray();
|
||||
return hashCodeOfRange(es, 0, es.length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1037,12 +1039,12 @@ public class CopyOnWriteArrayList<E>
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
if (index < 0 || index > len)
|
||||
throw new IndexOutOfBoundsException(outOfBounds(index, len));
|
||||
|
||||
return new COWIterator<E>(elements, index);
|
||||
return new COWIterator<E>(es, index);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,9 +1072,9 @@ public class CopyOnWriteArrayList<E>
|
||||
/** Index of element to be returned by subsequent call to next. */
|
||||
private int cursor;
|
||||
|
||||
COWIterator(Object[] elements, int initialCursor) {
|
||||
COWIterator(Object[] es, int initialCursor) {
|
||||
cursor = initialCursor;
|
||||
snapshot = elements;
|
||||
snapshot = es;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
@ -1102,7 +1104,7 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
public int previousIndex() {
|
||||
return cursor-1;
|
||||
return cursor - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1133,14 +1135,13 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
final int size = snapshot.length;
|
||||
for (int i = cursor; i < size; i++) {
|
||||
action.accept((E) snapshot[i]);
|
||||
}
|
||||
int i = cursor;
|
||||
cursor = size;
|
||||
for (; i < size; i++)
|
||||
action.accept(elementAt(snapshot, i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1161,136 +1162,264 @@ public class CopyOnWriteArrayList<E>
|
||||
*/
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
synchronized (lock) {
|
||||
Object[] elements = getArray();
|
||||
int len = elements.length;
|
||||
if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
|
||||
Object[] es = getArray();
|
||||
int len = es.length;
|
||||
int size = toIndex - fromIndex;
|
||||
if (fromIndex < 0 || toIndex > len || size < 0)
|
||||
throw new IndexOutOfBoundsException();
|
||||
return new COWSubList<E>(this, fromIndex, toIndex);
|
||||
return new COWSubList(es, fromIndex, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sublist for CopyOnWriteArrayList.
|
||||
*/
|
||||
private static class COWSubList<E>
|
||||
extends AbstractList<E>
|
||||
implements RandomAccess
|
||||
{
|
||||
private final CopyOnWriteArrayList<E> l;
|
||||
private class COWSubList implements List<E>, RandomAccess {
|
||||
private final int offset;
|
||||
private int size;
|
||||
private Object[] expectedArray;
|
||||
|
||||
// only call this holding l's lock
|
||||
COWSubList(CopyOnWriteArrayList<E> list,
|
||||
int fromIndex, int toIndex) {
|
||||
// assert Thread.holdsLock(list.lock);
|
||||
l = list;
|
||||
expectedArray = l.getArray();
|
||||
offset = fromIndex;
|
||||
size = toIndex - fromIndex;
|
||||
COWSubList(Object[] es, int offset, int size) {
|
||||
// assert Thread.holdsLock(lock);
|
||||
expectedArray = es;
|
||||
this.offset = offset;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
// only call this holding l's lock
|
||||
private void checkForComodification() {
|
||||
// assert Thread.holdsLock(l.lock);
|
||||
if (l.getArray() != expectedArray)
|
||||
// assert Thread.holdsLock(lock);
|
||||
if (getArray() != expectedArray)
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
private Object[] getArrayChecked() {
|
||||
// assert Thread.holdsLock(l.lock);
|
||||
Object[] a = l.getArray();
|
||||
// assert Thread.holdsLock(lock);
|
||||
Object[] a = getArray();
|
||||
if (a != expectedArray)
|
||||
throw new ConcurrentModificationException();
|
||||
return a;
|
||||
}
|
||||
|
||||
// only call this holding l's lock
|
||||
private void rangeCheck(int index) {
|
||||
// assert Thread.holdsLock(l.lock);
|
||||
// assert Thread.holdsLock(lock);
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException(outOfBounds(index, size));
|
||||
}
|
||||
|
||||
private void rangeCheckForAdd(int index) {
|
||||
// assert Thread.holdsLock(lock);
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException(outOfBounds(index, size));
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
return Arrays.copyOfRange(es, offset, offset + size);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
if (a.length < size)
|
||||
return (T[]) Arrays.copyOfRange(
|
||||
es, offset, offset + size, a.getClass());
|
||||
else {
|
||||
System.arraycopy(es, offset, a, 0, size);
|
||||
if (a.length > size)
|
||||
a[size] = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
public int indexOf(Object o) {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
int i = indexOfRange(o, es, offset, offset + size);
|
||||
return (i == -1) ? -1 : i - offset;
|
||||
}
|
||||
|
||||
public int lastIndexOf(Object o) {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
int i = lastIndexOfRange(o, es, offset, offset + size);
|
||||
return (i == -1) ? -1 : i - offset;
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return indexOf(o) >= 0;
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
for (Object o : c)
|
||||
if (indexOfRange(o, es, offset, offset + size) < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return Arrays.toString(toArray());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
return hashCodeOfRange(es, offset, offset + size);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof List))
|
||||
return false;
|
||||
Iterator<?> it = ((List<?>)o).iterator();
|
||||
|
||||
final Object[] es;
|
||||
final int offset;
|
||||
final int size;
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
offset = this.offset;
|
||||
size = this.size;
|
||||
}
|
||||
|
||||
for (int i = offset, end = offset + size; i < end; i++)
|
||||
if (!it.hasNext() || !Objects.equals(es[i], it.next()))
|
||||
return false;
|
||||
return !it.hasNext();
|
||||
}
|
||||
|
||||
public E set(int index, E element) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
E x = l.set(offset + index, element);
|
||||
expectedArray = l.getArray();
|
||||
E x = CopyOnWriteArrayList.this.set(offset + index, element);
|
||||
expectedArray = getArray();
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public E get(int index) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
return l.get(offset + index);
|
||||
return CopyOnWriteArrayList.this.get(offset + index);
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean add(E element) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
l.add(offset + size, element);
|
||||
expectedArray = l.getArray();
|
||||
CopyOnWriteArrayList.this.add(offset + size, element);
|
||||
expectedArray = getArray();
|
||||
size++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void add(int index, E element) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException
|
||||
(outOfBounds(index, size));
|
||||
l.add(offset + index, element);
|
||||
expectedArray = l.getArray();
|
||||
rangeCheckForAdd(index);
|
||||
CopyOnWriteArrayList.this.add(offset + index, element);
|
||||
expectedArray = getArray();
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
final Object[] oldArray = getArrayChecked();
|
||||
boolean modified = l.addAll(offset + size, c);
|
||||
size += (expectedArray = l.getArray()).length - oldArray.length;
|
||||
boolean modified =
|
||||
CopyOnWriteArrayList.this.addAll(offset + size, c);
|
||||
size += (expectedArray = getArray()).length - oldArray.length;
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
synchronized (lock) {
|
||||
rangeCheckForAdd(index);
|
||||
final Object[] oldArray = getArrayChecked();
|
||||
boolean modified =
|
||||
CopyOnWriteArrayList.this.addAll(offset + index, c);
|
||||
size += (expectedArray = getArray()).length - oldArray.length;
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
l.removeRange(offset, offset + size);
|
||||
expectedArray = l.getArray();
|
||||
removeRange(offset, offset + size);
|
||||
expectedArray = getArray();
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public E remove(int index) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
rangeCheck(index);
|
||||
checkForComodification();
|
||||
E result = l.remove(offset + index);
|
||||
expectedArray = l.getArray();
|
||||
E result = CopyOnWriteArrayList.this.remove(offset + index);
|
||||
expectedArray = getArray();
|
||||
size--;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
int index = indexOf(o);
|
||||
if (index == -1)
|
||||
@ -1301,36 +1430,35 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
synchronized (l.lock) {
|
||||
checkForComodification();
|
||||
return new COWSubListIterator<E>(l, 0, offset, size);
|
||||
}
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
public ListIterator<E> listIterator() {
|
||||
return listIterator(0);
|
||||
}
|
||||
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException
|
||||
(outOfBounds(index, size));
|
||||
return new COWSubListIterator<E>(l, index, offset, size);
|
||||
rangeCheckForAdd(index);
|
||||
return new COWSubListIterator<E>(
|
||||
CopyOnWriteArrayList.this, index, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
if (fromIndex < 0 || toIndex > size || fromIndex > toIndex)
|
||||
throw new IndexOutOfBoundsException();
|
||||
return new COWSubList<E>(l, fromIndex + offset,
|
||||
toIndex + offset);
|
||||
return new COWSubList(expectedArray, fromIndex + offset, toIndex - fromIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
int i, end; final Object[] es;
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
es = getArrayChecked();
|
||||
i = offset;
|
||||
end = i + size;
|
||||
@ -1340,19 +1468,18 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
public void replaceAll(UnaryOperator<E> operator) {
|
||||
Objects.requireNonNull(operator);
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
l.replaceAll(operator, offset, offset + size);
|
||||
expectedArray = l.getArray();
|
||||
replaceAllRange(operator, offset, offset + size);
|
||||
expectedArray = getArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void sort(Comparator<? super E> c) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
checkForComodification();
|
||||
l.sort(c, offset, offset + size);
|
||||
expectedArray = l.getArray();
|
||||
sortRange(c, offset, offset + size);
|
||||
expectedArray = getArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1372,16 +1499,17 @@ public class CopyOnWriteArrayList<E>
|
||||
}
|
||||
|
||||
private boolean bulkRemove(Predicate<? super E> filter) {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
final Object[] oldArray = getArrayChecked();
|
||||
boolean modified = l.bulkRemove(filter, offset, offset + size);
|
||||
size += (expectedArray = l.getArray()).length - oldArray.length;
|
||||
boolean modified = CopyOnWriteArrayList.this.bulkRemove(
|
||||
filter, offset, offset + size);
|
||||
size += (expectedArray = getArray()).length - oldArray.length;
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
|
||||
public Spliterator<E> spliterator() {
|
||||
synchronized (l.lock) {
|
||||
synchronized (lock) {
|
||||
return Spliterators.spliterator(
|
||||
getArrayChecked(), offset, offset + size,
|
||||
Spliterator.IMMUTABLE | Spliterator.ORDERED);
|
||||
@ -1398,7 +1526,7 @@ public class CopyOnWriteArrayList<E>
|
||||
COWSubListIterator(List<E> l, int index, int offset, int size) {
|
||||
this.offset = offset;
|
||||
this.size = size;
|
||||
it = l.listIterator(index+offset);
|
||||
it = l.listIterator(index + offset);
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
@ -1447,7 +1575,7 @@ public class CopyOnWriteArrayList<E>
|
||||
@SuppressWarnings("unchecked")
|
||||
public void forEachRemaining(Consumer<? super E> action) {
|
||||
Objects.requireNonNull(action);
|
||||
while (nextIndex() < size) {
|
||||
while (hasNext()) {
|
||||
action.accept(it.next());
|
||||
}
|
||||
}
|
||||
|
||||
@ -775,7 +775,7 @@ public abstract class CountedCompleter<T> extends ForkJoinTask<T> {
|
||||
PENDING = l.findVarHandle(CountedCompleter.class, "pending", int.class);
|
||||
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -641,7 +641,7 @@ public class Exchanger<V> {
|
||||
MATCH = l.findVarHandle(Node.class, "match", Object.class);
|
||||
AA = MethodHandles.arrayElementVarHandle(Node[].class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1540,7 +1540,7 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
STATUS = l.findVarHandle(ForkJoinTask.class, "status", int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -526,7 +526,7 @@ public class FutureTask<V> implements RunnableFuture<V> {
|
||||
RUNNER = l.findVarHandle(FutureTask.class, "runner", Thread.class);
|
||||
WAITERS = l.findVarHandle(FutureTask.class, "waiters", WaitNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -1739,7 +1739,7 @@ public class LinkedTransferQueue<E> extends AbstractQueue<E>
|
||||
NEXT = l.findVarHandle(Node.class, "next", Node.class);
|
||||
WAITER = l.findVarHandle(Node.class, "waiter", Thread.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -1137,7 +1137,7 @@ public class Phaser {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
STATE = l.findVarHandle(Phaser.class, "state", long.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -1014,7 +1014,7 @@ public class PriorityBlockingQueue<E> extends AbstractQueue<E>
|
||||
"allocationSpinLock",
|
||||
int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1096,7 +1096,7 @@ public class SubmissionPublisher<T> implements Publisher<T>,
|
||||
if (cap > 0) {
|
||||
boolean added;
|
||||
if (n >= cap && cap < maxCapacity) // resize
|
||||
added = growAndoffer(item, a, t);
|
||||
added = growAndOffer(item, a, t);
|
||||
else if (n >= cap || unowned) // need volatile CAS
|
||||
added = QA.compareAndSet(a, i, null, item);
|
||||
else { // can use release mode
|
||||
@ -1115,7 +1115,7 @@ public class SubmissionPublisher<T> implements Publisher<T>,
|
||||
* Tries to expand buffer and add item, returning true on
|
||||
* success. Currently fails only if out of memory.
|
||||
*/
|
||||
final boolean growAndoffer(T item, Object[] a, int t) {
|
||||
final boolean growAndOffer(T item, Object[] a, int t) {
|
||||
int cap = 0, newCap = 0;
|
||||
Object[] newArray = null;
|
||||
if (a != null && (cap = a.length) > 0 && (newCap = cap << 1) > 0) {
|
||||
@ -1466,7 +1466,7 @@ public class SubmissionPublisher<T> implements Publisher<T>,
|
||||
long.class);
|
||||
QA = MethodHandles.arrayElementVarHandle(Object[].class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -293,7 +293,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
|
||||
SMATCH = l.findVarHandle(SNode.class, "match", SNode.class);
|
||||
SNEXT = l.findVarHandle(SNode.class, "next", SNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -516,7 +516,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
SHEAD = l.findVarHandle(TransferStack.class, "head", SNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -583,7 +583,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
|
||||
QITEM = l.findVarHandle(QNode.class, "item", Object.class);
|
||||
QNEXT = l.findVarHandle(QNode.class, "next", QNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -830,7 +830,7 @@ public class SynchronousQueue<E> extends AbstractQueue<E>
|
||||
QCLEANME = l.findVarHandle(TransferQueue.class, "cleanMe",
|
||||
QNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ public class AtomicBoolean implements java.io.Serializable {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
VALUE = l.findVarHandle(AtomicBoolean.class, "value", int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -199,7 +199,7 @@ public class AtomicMarkableReference<V> {
|
||||
PAIR = l.findVarHandle(AtomicMarkableReference.class, "pair",
|
||||
Pair.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -199,7 +199,7 @@ public class AtomicStampedReference<V> {
|
||||
PAIR = l.findVarHandle(AtomicStampedReference.class, "pair",
|
||||
Pair.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -144,7 +144,7 @@ abstract class Striped64 extends Number {
|
||||
MethodHandles.Lookup l = MethodHandles.lookup();
|
||||
VALUE = l.findVarHandle(Cell.class, "value", long.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -396,13 +396,13 @@ abstract class Striped64 extends Number {
|
||||
try {
|
||||
return MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}});
|
||||
THREAD_PROBE = l.findVarHandle(Thread.class,
|
||||
"threadLocalRandomProbe", int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1830,7 +1830,7 @@ public abstract class AbstractQueuedLongSynchronizer
|
||||
HEAD = l.findVarHandle(AbstractQueuedLongSynchronizer.class, "head", Node.class);
|
||||
TAIL = l.findVarHandle(AbstractQueuedLongSynchronizer.class, "tail", Node.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -555,7 +555,7 @@ public abstract class AbstractQueuedSynchronizer
|
||||
THREAD = l.findVarHandle(Node.class, "thread", Thread.class);
|
||||
WAITSTATUS = l.findVarHandle(Node.class, "waitStatus", int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2308,7 +2308,7 @@ public abstract class AbstractQueuedSynchronizer
|
||||
HEAD = l.findVarHandle(AbstractQueuedSynchronizer.class, "head", Node.class);
|
||||
TAIL = l.findVarHandle(AbstractQueuedSynchronizer.class, "tail", Node.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
|
||||
// Reduce the risk of rare disastrous classloading in first call to
|
||||
|
||||
@ -1614,7 +1614,7 @@ public class StampedLock implements java.io.Serializable {
|
||||
WNEXT = l.findVarHandle(WNode.class, "next", WNode.class);
|
||||
WCOWAIT = l.findVarHandle(WNode.class, "cowait", WNode.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new Error(e);
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5809,10 +5809,21 @@ NEXT: while (i <= last) {
|
||||
static final Node lastAccept = new LastNode();
|
||||
|
||||
/**
|
||||
* Creates a predicate which can be used to match a string.
|
||||
* Creates a predicate that tests if this pattern is found in a given input
|
||||
* string.
|
||||
*
|
||||
* @return The predicate which can be used for matching on a string
|
||||
* @apiNote
|
||||
* This method creates a predicate that behaves as if it creates a matcher
|
||||
* from the input sequence and then calls {@code find}, for example a
|
||||
* predicate of the form:
|
||||
* <pre>{@code
|
||||
* s -> matcher(s).find();
|
||||
* }</pre>
|
||||
*
|
||||
* @return The predicate which can be used for finding a match on a
|
||||
* subsequence of a string
|
||||
* @since 1.8
|
||||
* @see Matcher#find
|
||||
*/
|
||||
public Predicate<String> asPredicate() {
|
||||
return s -> matcher(s).find();
|
||||
|
||||
@ -39,6 +39,8 @@ public class ISO_8859_1
|
||||
extends Charset
|
||||
implements HistoricallyNamedCharset
|
||||
{
|
||||
public static final ISO_8859_1 INSTANCE = new ISO_8859_1();
|
||||
|
||||
public ISO_8859_1() {
|
||||
super("ISO-8859-1", StandardCharsets.aliases_ISO_8859_1());
|
||||
}
|
||||
|
||||
@ -83,9 +83,9 @@ public class StandardCharsets extends CharsetProvider {
|
||||
Map<String,Charset> map = cache;
|
||||
if (map == null) {
|
||||
map = new Cache();
|
||||
map.put("utf-8", java.nio.charset.StandardCharsets.UTF_8);
|
||||
map.put("iso-8859-1", java.nio.charset.StandardCharsets.ISO_8859_1);
|
||||
map.put("us-ascii", java.nio.charset.StandardCharsets.US_ASCII);
|
||||
map.put("utf-8", UTF_8.INSTANCE);
|
||||
map.put("iso-8859-1", ISO_8859_1.INSTANCE);
|
||||
map.put("us-ascii", US_ASCII.INSTANCE);
|
||||
map.put("utf-16", java.nio.charset.StandardCharsets.UTF_16);
|
||||
map.put("utf-16be", java.nio.charset.StandardCharsets.UTF_16BE);
|
||||
map.put("utf-16le", java.nio.charset.StandardCharsets.UTF_16LE);
|
||||
@ -122,15 +122,19 @@ public class StandardCharsets extends CharsetProvider {
|
||||
private Charset lookup(String charsetName) {
|
||||
init();
|
||||
|
||||
// By checking these built-ins we can avoid initializing Aliases and
|
||||
// Classes eagerly during bootstrap
|
||||
// By checking these built-ins we can avoid initializing Aliases,
|
||||
// Classes and Cache eagerly during bootstrap.
|
||||
//
|
||||
// Initialization of java.nio.charset.StandardCharsets should be
|
||||
// avoided here to minimize time spent in System.initPhase1, as it
|
||||
// may delay initialization of performance critical VM subsystems.
|
||||
String csn;
|
||||
if (charsetName.equals("UTF-8")) {
|
||||
return java.nio.charset.StandardCharsets.UTF_8;
|
||||
return UTF_8.INSTANCE;
|
||||
} else if (charsetName.equals("US-ASCII")) {
|
||||
return java.nio.charset.StandardCharsets.US_ASCII;
|
||||
return US_ASCII.INSTANCE;
|
||||
} else if (charsetName.equals("ISO-8859-1")) {
|
||||
return java.nio.charset.StandardCharsets.ISO_8859_1;
|
||||
return ISO_8859_1.INSTANCE;
|
||||
} else {
|
||||
csn = canonicalize(toLower(charsetName));
|
||||
}
|
||||
|
||||
@ -36,6 +36,8 @@ public class US_ASCII
|
||||
extends Charset
|
||||
implements HistoricallyNamedCharset
|
||||
{
|
||||
public static final US_ASCII INSTANCE = new US_ASCII();
|
||||
|
||||
public US_ASCII() {
|
||||
super("US-ASCII", StandardCharsets.aliases_US_ASCII());
|
||||
}
|
||||
|
||||
@ -55,6 +55,9 @@ import java.nio.charset.CodingErrorAction;
|
||||
*/
|
||||
|
||||
public final class UTF_8 extends Unicode {
|
||||
|
||||
public static final UTF_8 INSTANCE = new UTF_8();
|
||||
|
||||
public UTF_8() {
|
||||
super("UTF-8", StandardCharsets.aliases_UTF_8());
|
||||
}
|
||||
|
||||
@ -774,8 +774,10 @@ newStringUTF8(JNIEnv *env, const char *str)
|
||||
return newSizedStringJava(env, str, len);
|
||||
}
|
||||
|
||||
/* Initialize the fast encoding from the encoding name. */
|
||||
void
|
||||
/* Initialize the fast encoding from the encoding name.
|
||||
* Export InitializeEncoding so that the VM can initialize it if required.
|
||||
*/
|
||||
JNIEXPORT void
|
||||
InitializeEncoding(JNIEnv *env, const char *encname)
|
||||
{
|
||||
jclass strClazz = NULL;
|
||||
|
||||
@ -388,7 +388,7 @@ enum {
|
||||
|
||||
int getFastEncoding();
|
||||
|
||||
void InitializeEncoding(JNIEnv *env, const char *name);
|
||||
JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);
|
||||
|
||||
void* getProcessHandle();
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 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
|
||||
@ -22,42 +23,56 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* CopyrightVersion 1.2 */
|
||||
|
||||
/* This is a special library that should be loaded before libc &
|
||||
* libthread to interpose the signal handler installation functions:
|
||||
* sigaction(), signal(), sigset().
|
||||
* Used for signal-chaining. See RFE 4381843.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <thread.h>
|
||||
#include <synch.h>
|
||||
#include "jni.h"
|
||||
#include "jvm_md.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
#if (__STDC_VERSION__ >= 199901L)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#ifdef SOLARIS
|
||||
#define MAX_SIGNALS (SIGRTMAX+1)
|
||||
|
||||
/* On solaris, MAX_SIGNALS is a macro, not a constant, so we must allocate sact dynamically. */
|
||||
static struct sigaction *sact = (struct sigaction *)NULL; /* saved signal handlers */
|
||||
static sigset_t jvmsigs;
|
||||
#else
|
||||
#define MAX_SIGNALS NSIG
|
||||
|
||||
/* used to synchronize the installation of signal handlers */
|
||||
static mutex_t mutex = DEFAULTMUTEX;
|
||||
static cond_t cond = DEFAULTCV;
|
||||
static thread_t tid = 0;
|
||||
static struct sigaction sact[MAX_SIGNALS]; /* saved signal handlers */
|
||||
#endif
|
||||
|
||||
static sigset_t jvmsigs; /* Signals used by jvm. */
|
||||
|
||||
#ifdef MACOSX
|
||||
static __thread bool reentry = false; /* prevent reentry deadlock (per-thread) */
|
||||
#endif
|
||||
|
||||
/* Used to synchronize the installation of signal handlers. */
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_t tid = 0;
|
||||
|
||||
typedef void (*sa_handler_t)(int);
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
typedef sa_handler_t (*signal_t)(int, sa_handler_t);
|
||||
typedef sa_handler_t (*signal_function_t)(int, sa_handler_t);
|
||||
typedef int (*sigaction_t)(int, const struct sigaction *, struct sigaction *);
|
||||
|
||||
static signal_t os_signal = 0; /* os's version of signal()/sigset() */
|
||||
static signal_function_t os_signal = 0; /* os's version of signal()/sigset() */
|
||||
static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
|
||||
|
||||
static bool jvm_signal_installing = false;
|
||||
@ -66,65 +81,79 @@ static bool jvm_signal_installed = false;
|
||||
|
||||
/* assume called within signal_lock */
|
||||
static void allocate_sact() {
|
||||
size_t maxsignum;
|
||||
maxsignum = SIGRTMAX;
|
||||
#ifdef SOLARIS
|
||||
if (sact == NULL) {
|
||||
sact = (struct sigaction *)malloc((maxsignum+1) * (size_t)sizeof(struct sigaction));
|
||||
memset(sact, 0, (maxsignum+1) * (size_t)sizeof(struct sigaction));
|
||||
sact = (struct sigaction *)malloc((MAX_SIGNALS) * (size_t)sizeof(struct sigaction));
|
||||
if (sact == NULL) {
|
||||
printf("%s\n", "libjsig.so unable to allocate memory");
|
||||
exit(0);
|
||||
}
|
||||
memset(sact, 0, (MAX_SIGNALS) * (size_t)sizeof(struct sigaction));
|
||||
}
|
||||
|
||||
if (sact == NULL) {
|
||||
printf("%s\n", "libjsig.so unable to allocate memory");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sigemptyset(&jvmsigs);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void signal_lock() {
|
||||
mutex_lock(&mutex);
|
||||
pthread_mutex_lock(&mutex);
|
||||
/* When the jvm is installing its set of signal handlers, threads
|
||||
* other than the jvm thread should wait */
|
||||
* other than the jvm thread should wait. */
|
||||
if (jvm_signal_installing) {
|
||||
if (tid != thr_self()) {
|
||||
cond_wait(&cond, &mutex);
|
||||
if (tid != pthread_self()) {
|
||||
pthread_cond_wait(&cond, &mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_unlock() {
|
||||
mutex_unlock(&mutex);
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
|
||||
bool is_sigset) {
|
||||
sa_handler_t res;
|
||||
|
||||
if (os_signal == NULL) {
|
||||
if (!is_sigset) {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
|
||||
os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal");
|
||||
} else {
|
||||
os_signal = (signal_t)dlsym(RTLD_NEXT, "sigset");
|
||||
os_signal = (signal_function_t)dlsym(RTLD_NEXT, "sigset");
|
||||
}
|
||||
if (os_signal == NULL) {
|
||||
printf("%s\n", dlerror());
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
return (*os_signal)(sig, disp);
|
||||
|
||||
#ifdef MACOSX
|
||||
/* On macosx, the OS implementation of signal calls sigaction.
|
||||
* Make sure we do not deadlock with ourself. (See JDK-8072147). */
|
||||
reentry = true;
|
||||
#endif
|
||||
|
||||
res = (*os_signal)(sig, disp);
|
||||
|
||||
#ifdef MACOSX
|
||||
reentry = false;
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void save_signal_handler(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
sigset_t set;
|
||||
if (sact == NULL) {
|
||||
allocate_sact();
|
||||
}
|
||||
|
||||
sact[sig].sa_handler = disp;
|
||||
sigemptyset(&set);
|
||||
sact[sig].sa_mask = set;
|
||||
if (!is_sigset) {
|
||||
#ifdef SOLARIS
|
||||
sact[sig].sa_flags = SA_NODEFER;
|
||||
if (sig != SIGILL && sig != SIGTRAP && sig != SIGPWR) {
|
||||
sact[sig].sa_flags |= SA_RESETHAND;
|
||||
}
|
||||
#else
|
||||
sact[sig].sa_flags = 0;
|
||||
#endif
|
||||
} else {
|
||||
sact[sig].sa_flags = 0;
|
||||
}
|
||||
@ -132,26 +161,28 @@ static void save_signal_handler(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
|
||||
static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
sa_handler_t oldhandler;
|
||||
bool sigused;
|
||||
bool sigblocked;
|
||||
|
||||
signal_lock();
|
||||
if (sact == NULL) {
|
||||
allocate_sact();
|
||||
}
|
||||
allocate_sact();
|
||||
|
||||
if (jvm_signal_installed && sigismember(&jvmsigs, sig)) {
|
||||
sigused = sigismember(&jvmsigs, sig);
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
if (is_sigset) {
|
||||
/* We won't honor the SIG_HOLD request to change the signal mask */
|
||||
sigblocked = sigismember(&(sact[sig].sa_mask), sig);
|
||||
}
|
||||
oldhandler = sact[sig].sa_handler;
|
||||
save_signal_handler(sig, disp, is_sigset);
|
||||
|
||||
#ifdef SOLARIS
|
||||
if (is_sigset && sigblocked) {
|
||||
/* We won't honor the SIG_HOLD request to change the signal mask */
|
||||
oldhandler = SIG_HOLD;
|
||||
}
|
||||
#endif
|
||||
|
||||
signal_unlock();
|
||||
return oldhandler;
|
||||
@ -178,11 +209,26 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) {
|
||||
}
|
||||
|
||||
sa_handler_t signal(int sig, sa_handler_t disp) {
|
||||
if (sig < 0 || sig >= MAX_SIGNALS) {
|
||||
errno = EINVAL;
|
||||
return SIG_ERR;
|
||||
}
|
||||
|
||||
return set_signal(sig, disp, false);
|
||||
}
|
||||
|
||||
sa_handler_t sigset(int sig, sa_handler_t disp) {
|
||||
#ifdef _ALLBSD_SOURCE
|
||||
printf("sigset() is not supported by BSD");
|
||||
exit(0);
|
||||
#else
|
||||
if (sig < 0 || sig >= MAX_SIGNALS) {
|
||||
errno = EINVAL;
|
||||
return (sa_handler_t)-1;
|
||||
}
|
||||
|
||||
return set_signal(sig, disp, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int call_os_sigaction(int sig, const struct sigaction *act,
|
||||
@ -199,14 +245,25 @@ static int call_os_sigaction(int sig, const struct sigaction *act,
|
||||
|
||||
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
||||
int res;
|
||||
bool sigused;
|
||||
struct sigaction oldAct;
|
||||
|
||||
if (sig < 0 || sig >= MAX_SIGNALS) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MACOSX
|
||||
if (reentry) {
|
||||
return call_os_sigaction(sig, act, oact);
|
||||
}
|
||||
#endif
|
||||
|
||||
signal_lock();
|
||||
|
||||
if (sact == NULL ) {
|
||||
allocate_sact();
|
||||
}
|
||||
if (jvm_signal_installed && sigismember(&jvmsigs, sig)) {
|
||||
allocate_sact();
|
||||
sigused = sigismember(&jvmsigs, sig);
|
||||
if (jvm_signal_installed && sigused) {
|
||||
/* jvm has installed its signal handler for this signal. */
|
||||
/* Save the handler. Don't really install it. */
|
||||
if (oact != NULL) {
|
||||
@ -227,7 +284,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
||||
*oact = oldAct;
|
||||
}
|
||||
|
||||
/* Record the signals used by jvm */
|
||||
/* Record the signals used by jvm. */
|
||||
sigaddset(&jvmsigs, sig);
|
||||
|
||||
signal_unlock();
|
||||
@ -242,37 +299,28 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
|
||||
}
|
||||
}
|
||||
|
||||
/* The four functions for the jvm to call into */
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_begin_signal_setting() {
|
||||
/* The three functions for the jvm to call into. */
|
||||
void JVM_begin_signal_setting() {
|
||||
signal_lock();
|
||||
sigemptyset(&jvmsigs);
|
||||
jvm_signal_installing = true;
|
||||
tid = thr_self();
|
||||
tid = pthread_self();
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_end_signal_setting() {
|
||||
void JVM_end_signal_setting() {
|
||||
signal_lock();
|
||||
jvm_signal_installed = true;
|
||||
jvm_signal_installing = false;
|
||||
cond_broadcast(&cond);
|
||||
pthread_cond_broadcast(&cond);
|
||||
signal_unlock();
|
||||
}
|
||||
|
||||
JNIEXPORT struct sigaction * JNICALL
|
||||
JVM_get_signal_action(int sig) {
|
||||
if (sact == NULL) {
|
||||
allocate_sact();
|
||||
}
|
||||
struct sigaction *JVM_get_signal_action(int sig) {
|
||||
allocate_sact();
|
||||
/* Does race condition make sense here? */
|
||||
if (sigismember(&jvmsigs, sig)) {
|
||||
return &sact[sig];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
JVM_get_libjsig_version() {
|
||||
return JSIG_VERSION_1_4_1;
|
||||
}
|
||||
@ -746,12 +746,7 @@ class SynthParser extends DefaultHandler {
|
||||
value = lookup(aValue, Object.class);
|
||||
break;
|
||||
case 1: // boolean
|
||||
if (aValue.toUpperCase().equals("TRUE")) {
|
||||
value = Boolean.TRUE;
|
||||
}
|
||||
else {
|
||||
value = Boolean.FALSE;
|
||||
}
|
||||
value = Boolean.parseBoolean(aValue);
|
||||
break;
|
||||
case 2: // dimension
|
||||
StringTokenizer tok = new StringTokenizer(aValue);
|
||||
@ -939,11 +934,11 @@ class SynthParser extends DefaultHandler {
|
||||
": destinationInsets must be top left bottom right");
|
||||
}
|
||||
else if (key.equals(ATTRIBUTE_PAINT_CENTER)) {
|
||||
paintCenter = value.toLowerCase().equals("true");
|
||||
paintCenter = Boolean.parseBoolean(value);
|
||||
paintCenterSpecified = true;
|
||||
}
|
||||
else if (key.equals(ATTRIBUTE_STRETCH)) {
|
||||
stretch = value.toLowerCase().equals("true");
|
||||
stretch = Boolean.parseBoolean(value);
|
||||
stretchSpecified = true;
|
||||
}
|
||||
else if (key.equals(ATTRIBUTE_DIRECTION)) {
|
||||
@ -989,7 +984,7 @@ class SynthParser extends DefaultHandler {
|
||||
}
|
||||
}
|
||||
else if (key.equals(ATTRIBUTE_CENTER)) {
|
||||
center = value.toLowerCase().equals("true");
|
||||
center = Boolean.parseBoolean(value);
|
||||
}
|
||||
}
|
||||
if (painter == null) {
|
||||
|
||||
@ -90,7 +90,7 @@ assertTLSValue( jvmtiEnv * jvmtienv,
|
||||
jthread thread,
|
||||
const void * expected) {
|
||||
jvmtiError error;
|
||||
void * test = (void *) 0x99999999UL;
|
||||
void * test = (void *) 0x99999999ULL;
|
||||
|
||||
/* now check if we do a fetch we get what we wrote */
|
||||
error = (*jvmtienv)->GetThreadLocalStorage(
|
||||
|
||||
@ -55,10 +55,10 @@ class MemoryPoolImpl implements MemoryPoolMXBean {
|
||||
private long usageThreshold;
|
||||
private long collectionThreshold;
|
||||
|
||||
private boolean usageSensorRegistered;
|
||||
private boolean gcSensorRegistered;
|
||||
private Sensor usageSensor;
|
||||
private Sensor gcSensor;
|
||||
private boolean usageSensorRegistered; // VM-initialized to false
|
||||
private boolean gcSensorRegistered; // VM-initialized to false
|
||||
private final Sensor usageSensor;
|
||||
private final Sensor gcSensor;
|
||||
|
||||
MemoryPoolImpl(String name, boolean isHeap, long usageThreshold,
|
||||
long gcThreshold) {
|
||||
@ -72,8 +72,6 @@ class MemoryPoolImpl implements MemoryPoolMXBean {
|
||||
this.collectionThresholdSupported = (gcThreshold >= 0);
|
||||
this.usageSensor = new PoolSensor(this, name + " usage sensor");
|
||||
this.gcSensor = new CollectionSensor(this, name + " collection sensor");
|
||||
this.usageSensorRegistered = false;
|
||||
this.gcSensorRegistered = false;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -290,7 +288,7 @@ class MemoryPoolImpl implements MemoryPoolMXBean {
|
||||
* unless the memory usage has returned below the threshold.
|
||||
*/
|
||||
class PoolSensor extends Sensor {
|
||||
MemoryPoolImpl pool;
|
||||
final MemoryPoolImpl pool;
|
||||
|
||||
PoolSensor(MemoryPoolImpl pool, String name) {
|
||||
super(name);
|
||||
@ -316,10 +314,10 @@ class MemoryPoolImpl implements MemoryPoolMXBean {
|
||||
* when the memory usage of a memory pool after GC is crossing
|
||||
* the collection threshold.
|
||||
* The VM will trigger this sensor in subsequent crossing
|
||||
* regardless if the memory usage has changed siince the previous GC.
|
||||
* regardless if the memory usage has changed since the previous GC.
|
||||
*/
|
||||
class CollectionSensor extends Sensor {
|
||||
MemoryPoolImpl pool;
|
||||
final MemoryPoolImpl pool;
|
||||
CollectionSensor(MemoryPoolImpl pool, String name) {
|
||||
super(name);
|
||||
this.pool = pool;
|
||||
|
||||
@ -48,10 +48,10 @@ import java.util.HashMap;
|
||||
*/
|
||||
|
||||
public abstract class Sensor {
|
||||
private Object lock;
|
||||
private String name;
|
||||
private long count;
|
||||
private boolean on;
|
||||
private final Object lock = new Object();
|
||||
private final String name;
|
||||
private long count; // VM-initialized to 0
|
||||
private boolean on; // VM-initialized to false
|
||||
|
||||
/**
|
||||
* Constructs a {@code Sensor} object.
|
||||
@ -60,9 +60,6 @@ public abstract class Sensor {
|
||||
*/
|
||||
public Sensor(String name) {
|
||||
this.name = name;
|
||||
this.count = 0;
|
||||
this.on = false;
|
||||
this.lock = new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 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
|
||||
@ -26,8 +26,7 @@
|
||||
package sun.security.krb5.internal.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import sun.security.action.GetBooleanAction;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
@ -45,15 +44,21 @@ import sun.security.util.DerValue;
|
||||
public final class KerberosString {
|
||||
/**
|
||||
* RFC 4120 defines KerberosString as GeneralString (IA5String), which
|
||||
* only includes ASCII characters. However, other implementations have been
|
||||
* known to use GeneralString to contain UTF-8 encoding. To interop
|
||||
* with these implementations, the following system property is defined.
|
||||
* When set as true, KerberosString is encoded as UTF-8. Note that this
|
||||
* only affects the byte encoding, the tag of the ASN.1 type is still
|
||||
* GeneralString.
|
||||
* only includes ASCII characters. However, most implementations have been
|
||||
* known to use GeneralString to contain UTF-8 encoding. The following
|
||||
* system property is defined. When set as true, KerberosString is encoded
|
||||
* as UTF-8. Otherwise, it's ASCII. The default is true.
|
||||
*
|
||||
* Note that this only affects the byte encoding, the tag of the ASN.1
|
||||
* type is still GeneralString.
|
||||
*/
|
||||
public static final boolean MSNAME = AccessController.doPrivileged(
|
||||
new GetBooleanAction("sun.security.krb5.msinterop.kstring"));
|
||||
public static final boolean MSNAME;
|
||||
|
||||
static {
|
||||
String prop = GetPropertyAction.privilegedGetProperty(
|
||||
"sun.security.krb5.msinterop.kstring", "true");
|
||||
MSNAME = Boolean.parseBoolean(prop);
|
||||
}
|
||||
|
||||
private final String s;
|
||||
|
||||
|
||||
@ -42,6 +42,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
|
||||
@ -72,6 +74,8 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
|
||||
*/
|
||||
protected IndexBuilder indexbuilder;
|
||||
|
||||
protected Navigation navBar;
|
||||
|
||||
/**
|
||||
* This constructor will be used by {@link SplitIndexWriter}. Initializes
|
||||
* path to this file and relative path from this file.
|
||||
@ -85,17 +89,7 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
|
||||
IndexBuilder indexbuilder) {
|
||||
super(configuration, path);
|
||||
this.indexbuilder = indexbuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index label for navigation bar.
|
||||
*
|
||||
* @return a content tree for the tree label
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkIndex() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.indexLabel);
|
||||
return li;
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.INDEX, path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -45,6 +45,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
|
||||
@ -214,23 +215,6 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter {
|
||||
*/
|
||||
protected abstract Content getDeprecatedLink(Element member);
|
||||
|
||||
/**
|
||||
* Get the navigation summary link.
|
||||
*
|
||||
* @param typeElement the TypeElement to be documented
|
||||
* @param link true if its a link else the label to be printed
|
||||
* @return a content tree for the navigation summary link.
|
||||
*/
|
||||
protected abstract Content getNavSummaryLink(TypeElement typeElement, boolean link);
|
||||
|
||||
/**
|
||||
* Add the navigation detail link.
|
||||
*
|
||||
* @param link true if its a link else the label to be printed
|
||||
* @param liNav the content tree to which the navigation detail link will be added
|
||||
*/
|
||||
protected abstract void addNavDetailLink(boolean link, Content liNav);
|
||||
|
||||
/**
|
||||
* Add the member name to the content tree.
|
||||
*
|
||||
@ -474,41 +458,6 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the navigation detail link.
|
||||
*
|
||||
* @param members the members to be linked
|
||||
* @param liNav the content tree to which the navigation detail link will be added
|
||||
*/
|
||||
protected void addNavDetailLink(SortedSet<Element> members, Content liNav) {
|
||||
addNavDetailLink(!members.isEmpty(), liNav);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the navigation summary link.
|
||||
*
|
||||
* @param members members to be linked
|
||||
* @param visibleMemberMap the visible inherited members map
|
||||
* @param liNav the content tree to which the navigation summary link will be added
|
||||
*/
|
||||
protected void addNavSummaryLink(SortedSet<? extends Element> members,
|
||||
VisibleMemberMap visibleMemberMap, Content liNav) {
|
||||
if (!members.isEmpty()) {
|
||||
liNav.addContent(getNavSummaryLink(null, true));
|
||||
return;
|
||||
}
|
||||
|
||||
TypeElement superClass = utils.getSuperClass(typeElement);
|
||||
while (superClass != null) {
|
||||
if (visibleMemberMap.hasMembers(superClass)) {
|
||||
liNav.addContent(getNavSummaryLink(superClass, true));
|
||||
return;
|
||||
}
|
||||
superClass = utils.getSuperClass(superClass);
|
||||
}
|
||||
liNav.addContent(getNavSummaryLink(null, false));
|
||||
}
|
||||
|
||||
protected void serialWarning(Element e, String key, String a1, String a2) {
|
||||
if (configuration.serialwarn) {
|
||||
configuration.messages.warning(e, key, a1, a2);
|
||||
|
||||
@ -37,6 +37,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
@ -61,6 +63,8 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
|
||||
*/
|
||||
protected SortedMap<ModuleElement, Set<PackageElement>> modules;
|
||||
|
||||
protected Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor. Also initializes the modules variable.
|
||||
*
|
||||
@ -71,6 +75,7 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
|
||||
DocPath filename) {
|
||||
super(configuration, filename);
|
||||
modules = configuration.modulePackages;
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.OVERVIEW, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,18 +256,6 @@ public abstract class AbstractModuleIndexWriter extends HtmlDocletWriter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns highlighted "Overview", in the navigation bar as this is the
|
||||
* overview page.
|
||||
*
|
||||
* @return a Content object to be added to the documentation tree
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkContents() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.overviewLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing. This will be overridden in ModuleIndexFrameWriter.
|
||||
*
|
||||
|
||||
@ -33,6 +33,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
@ -58,6 +60,8 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
|
||||
*/
|
||||
protected SortedSet<PackageElement> packages;
|
||||
|
||||
protected Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor. Also initializes the packages variable.
|
||||
*
|
||||
@ -68,6 +72,7 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
|
||||
DocPath filename) {
|
||||
super(configuration, filename);
|
||||
packages = configuration.packages;
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.OVERVIEW, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,18 +178,6 @@ public abstract class AbstractPackageIndexWriter extends HtmlDocletWriter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns highlighted "Overview", in the navigation bar as this is the
|
||||
* overview page.
|
||||
*
|
||||
* @return a Content object to be added to the documentation tree
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkContents() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.overviewLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing. This will be overridden.
|
||||
*
|
||||
|
||||
@ -184,14 +184,4 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
protected void addPartialInfo(TypeElement typeElement, Content contentTree) {
|
||||
addPreQualifiedStrongClassLink(LinkInfoImpl.Kind.TREE, typeElement, contentTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree label for the navigation bar.
|
||||
*
|
||||
* @return a content tree for the tree label
|
||||
*/
|
||||
protected Content getNavLinkTree() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.treeLabel);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeFieldWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -285,31 +285,6 @@ public class AnnotationTypeFieldWriterImpl extends AbstractMemberWriter
|
||||
member, utils.getFullyQualifiedName(member));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
return links.createLink(
|
||||
SectionName.ANNOTATION_TYPE_FIELD_SUMMARY,
|
||||
contents.navField);
|
||||
} else {
|
||||
return contents.navField;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.ANNOTATION_TYPE_FIELD_DETAIL,
|
||||
contents.navField));
|
||||
} else {
|
||||
liNav.addContent(contents.navField);
|
||||
}
|
||||
}
|
||||
private TypeMirror getType(Element member) {
|
||||
if (utils.isConstructor(member))
|
||||
return null;
|
||||
|
||||
@ -35,7 +35,7 @@ import javax.lang.model.element.TypeElement;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeOptionalMemberWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -152,18 +152,4 @@ public class AnnotationTypeOptionalMemberWriterImpl extends
|
||||
memberTree.addContent(links.createAnchor(
|
||||
SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
return links.createLink(
|
||||
SectionName.ANNOTATION_TYPE_OPTIONAL_ELEMENT_SUMMARY,
|
||||
contents.navAnnotationTypeOptionalMember);
|
||||
} else {
|
||||
return contents.navAnnotationTypeOptionalMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeRequiredMemberWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -300,32 +300,6 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
|
||||
return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, member, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
return links.createLink(
|
||||
SectionName.ANNOTATION_TYPE_REQUIRED_ELEMENT_SUMMARY,
|
||||
contents.navAnnotationTypeRequiredMember);
|
||||
} else {
|
||||
return contents.navAnnotationTypeRequiredMember;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.ANNOTATION_TYPE_ELEMENT_DETAIL,
|
||||
contents.navAnnotationTypeMember));
|
||||
} else {
|
||||
liNav.addContent(contents.navAnnotationTypeMember);
|
||||
}
|
||||
}
|
||||
|
||||
private TypeMirror getType(Element member) {
|
||||
return utils.isExecutableElement(member)
|
||||
? utils.getReturnType((ExecutableElement) member)
|
||||
|
||||
@ -30,21 +30,20 @@ import java.util.List;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.builders.MemberSummaryBuilder;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap;
|
||||
|
||||
/**
|
||||
@ -69,6 +68,8 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||
|
||||
protected TypeElement annotationType;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* @param configuration the configuration
|
||||
* @param annotationType the annotation type being documented.
|
||||
@ -78,55 +79,7 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||
super(configuration, configuration.docPaths.forClass(annotationType));
|
||||
this.annotationType = annotationType;
|
||||
configuration.currentTypeElement = annotationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(annotationType),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this package link.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent = links.createLink(DocPaths.PACKAGE_SUMMARY,
|
||||
contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class link.
|
||||
*
|
||||
* @return a content tree for the class link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClass() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.classLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class use link.
|
||||
*
|
||||
* @return a content tree for the class use link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content linkContent = links.createLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
this.navBar = new Navigation(annotationType, configuration, fixedNavDiv, PageMode.CLASS, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +92,12 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(annotationType),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(linkContent);
|
||||
navBar.setMemberSummaryBuilder(configuration.getBuilderFactory().getMemberSummaryBuilder(this));
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -195,7 +153,8 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: contentTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
contentTree.addContent(htmlTree);
|
||||
@ -295,123 +254,6 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkTree() {
|
||||
Content treeLinkContent = links.createLink(DocPaths.PACKAGE_TREE,
|
||||
contents.treeLabel, "", "");
|
||||
Content li = HtmlTree.LI(treeLinkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add summary details to the navigation bar.
|
||||
*
|
||||
* @param subDiv the content tree to which the summary detail links will be added
|
||||
*/
|
||||
@Override
|
||||
protected void addSummaryDetailLinks(Content subDiv) {
|
||||
Content div = HtmlTree.DIV(getNavSummaryLinks());
|
||||
div.addContent(getNavDetailLinks());
|
||||
subDiv.addContent(div);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary links for navigation bar.
|
||||
*
|
||||
* @return the content tree for the navigation summary links
|
||||
*/
|
||||
protected Content getNavSummaryLinks() {
|
||||
Content li = HtmlTree.LI(contents.summaryLabel);
|
||||
li.addContent(Contents.SPACE);
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
|
||||
MemberSummaryBuilder memberSummaryBuilder =
|
||||
configuration.getBuilderFactory().getMemberSummaryBuilder(this);
|
||||
Content liNavField = new HtmlTree(HtmlTag.LI);
|
||||
addNavSummaryLink(memberSummaryBuilder,
|
||||
"doclet.navField",
|
||||
VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS, liNavField);
|
||||
addNavGap(liNavField);
|
||||
ulNav.addContent(liNavField);
|
||||
Content liNavReq = new HtmlTree(HtmlTag.LI);
|
||||
addNavSummaryLink(memberSummaryBuilder,
|
||||
"doclet.navAnnotationTypeRequiredMember",
|
||||
VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED, liNavReq);
|
||||
addNavGap(liNavReq);
|
||||
ulNav.addContent(liNavReq);
|
||||
Content liNavOpt = new HtmlTree(HtmlTag.LI);
|
||||
addNavSummaryLink(memberSummaryBuilder,
|
||||
"doclet.navAnnotationTypeOptionalMember",
|
||||
VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL, liNavOpt);
|
||||
ulNav.addContent(liNavOpt);
|
||||
return ulNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the navigation summary link.
|
||||
*
|
||||
* @param builder builder for the member to be documented
|
||||
* @param label the label for the navigation
|
||||
* @param type type to be documented
|
||||
* @param liNav the content tree to which the navigation summary link will be added
|
||||
*/
|
||||
protected void addNavSummaryLink(MemberSummaryBuilder builder,
|
||||
String label, VisibleMemberMap.Kind type, Content liNav) {
|
||||
AbstractMemberWriter writer = ((AbstractMemberWriter) builder.
|
||||
getMemberSummaryWriter(type));
|
||||
if (writer == null) {
|
||||
liNav.addContent(contents.getContent(label));
|
||||
} else {
|
||||
liNav.addContent(writer.getNavSummaryLink(null,
|
||||
! builder.getVisibleMemberMap(type).noVisibleMembers()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detail links for the navigation bar.
|
||||
*
|
||||
* @return the content tree for the detail links
|
||||
*/
|
||||
protected Content getNavDetailLinks() {
|
||||
Content li = HtmlTree.LI(contents.detailLabel);
|
||||
li.addContent(Contents.SPACE);
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
|
||||
MemberSummaryBuilder memberSummaryBuilder =
|
||||
configuration.getBuilderFactory().getMemberSummaryBuilder(this);
|
||||
AbstractMemberWriter writerField =
|
||||
((AbstractMemberWriter) memberSummaryBuilder.
|
||||
getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS));
|
||||
AbstractMemberWriter writerOptional =
|
||||
((AbstractMemberWriter) memberSummaryBuilder.
|
||||
getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL));
|
||||
AbstractMemberWriter writerRequired =
|
||||
((AbstractMemberWriter) memberSummaryBuilder.
|
||||
getMemberSummaryWriter(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED));
|
||||
Content liNavField = new HtmlTree(HtmlTag.LI);
|
||||
if (writerField != null) {
|
||||
writerField.addNavDetailLink(!utils.getAnnotationFields(annotationType).isEmpty(), liNavField);
|
||||
} else {
|
||||
liNavField.addContent(contents.navField);
|
||||
}
|
||||
addNavGap(liNavField);
|
||||
ulNav.addContent(liNavField);
|
||||
if (writerOptional != null){
|
||||
Content liNavOpt = new HtmlTree(HtmlTag.LI);
|
||||
writerOptional.addNavDetailLink(!annotationType.getAnnotationMirrors().isEmpty(), liNavOpt);
|
||||
ulNav.addContent(liNavOpt);
|
||||
} else if (writerRequired != null){
|
||||
Content liNavReq = new HtmlTree(HtmlTag.LI);
|
||||
writerRequired.addNavDetailLink(!annotationType.getAnnotationMirrors().isEmpty(), liNavReq);
|
||||
ulNav.addContent(liNavReq);
|
||||
} else {
|
||||
Content liNav = HtmlTree.LI(contents.navAnnotationTypeMember);
|
||||
ulNav.addContent(liNav);
|
||||
}
|
||||
return ulNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@ -47,7 +47,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
@ -106,6 +107,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
final String methodUseTableSummary;
|
||||
final String constructorUseTableSummary;
|
||||
final String packageUseTableSummary;
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* The HTML tree for main tag.
|
||||
@ -178,6 +180,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
resources.getText("doclet.constructors"));
|
||||
packageUseTableSummary = MessageFormat.format(useTableSummary,
|
||||
resources.getText("doclet.packages"));
|
||||
this.navBar = new Navigation(typeElement, configuration, fixedNavDiv, PageMode.USE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +267,8 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
HtmlTree htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
@ -476,7 +480,15 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(mdleLinkContent);
|
||||
Content classLinkContent = getLink(new LinkInfoImpl(
|
||||
configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement)
|
||||
.label(configuration.getText("doclet.Class")));
|
||||
navBar.setNavLinkClass(classLinkContent);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -494,65 +506,4 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
}
|
||||
return bodyTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this package link.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent =
|
||||
links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_SUMMARY), contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get class page link.
|
||||
*
|
||||
* @return a content tree for the class page link
|
||||
*/
|
||||
protected Content getNavLinkClass() {
|
||||
Content linkContent = getLink(new LinkInfoImpl(
|
||||
configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement)
|
||||
.label(configuration.getText("doclet.Class")));
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the use link.
|
||||
*
|
||||
* @return a content tree for the use link
|
||||
*/
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.useLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree link.
|
||||
*
|
||||
* @return a content tree for the tree link
|
||||
*/
|
||||
protected Content getNavLinkTree() {
|
||||
Content linkContent = utils.isEnclosingPackageIncluded(typeElement)
|
||||
? links.createLink(DocPath.parent.resolve(DocPaths.PACKAGE_TREE), contents.treeLabel)
|
||||
: links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), contents.treeLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -48,11 +50,9 @@ import jdk.javadoc.internal.doclets.toolkit.taglets.ParamTaglet;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap.Kind;
|
||||
|
||||
/**
|
||||
* Generate the Class Information Page.
|
||||
@ -78,6 +78,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
|
||||
protected final ClassTree classtree;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* @param configuration the configuration data for the doclet
|
||||
* @param typeElement the class being documented.
|
||||
@ -89,55 +91,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
this.typeElement = typeElement;
|
||||
configuration.currentTypeElement = typeElement;
|
||||
this.classtree = classTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this package link.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent = links.createLink(DocPaths.PACKAGE_SUMMARY,
|
||||
contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class link.
|
||||
*
|
||||
* @return a content tree for the class link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClass() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.classLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class use link.
|
||||
*
|
||||
* @return a content tree for the class use link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content linkContent = links.createLink(DocPaths.CLASS_USE.resolve(filename), contents.useLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
this.navBar = new Navigation(typeElement, configuration, fixedNavDiv, PageMode.CLASS, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +104,12 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(linkContent);
|
||||
navBar.setMemberSummaryBuilder(configuration.getBuilderFactory().getMemberSummaryBuilder(this));
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -210,7 +169,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: contentTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
contentTree.addContent(htmlTree);
|
||||
@ -608,100 +568,6 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
return dd;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkTree() {
|
||||
Content treeLinkContent = links.createLink(DocPaths.PACKAGE_TREE,
|
||||
contents.treeLabel, "", "");
|
||||
Content li = HtmlTree.LI(treeLinkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add summary details to the navigation bar.
|
||||
*
|
||||
* @param subDiv the content tree to which the summary detail links will be added
|
||||
*/
|
||||
@Override
|
||||
protected void addSummaryDetailLinks(Content subDiv) {
|
||||
Content div = HtmlTree.DIV(getNavSummaryLinks());
|
||||
div.addContent(getNavDetailLinks());
|
||||
subDiv.addContent(div);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary links for navigation bar.
|
||||
*
|
||||
* @return the content tree for the navigation summary links
|
||||
*/
|
||||
protected Content getNavSummaryLinks() {
|
||||
Content li = HtmlTree.LI(contents.summaryLabel);
|
||||
li.addContent(Contents.SPACE);
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
|
||||
MemberSummaryBuilder memberSummaryBuilder =
|
||||
configuration.getBuilderFactory().getMemberSummaryBuilder(this);
|
||||
for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.summarySet) {
|
||||
Content liNav = new HtmlTree(HtmlTag.LI);
|
||||
if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) {
|
||||
continue;
|
||||
}
|
||||
if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) {
|
||||
continue;
|
||||
}
|
||||
AbstractMemberWriter writer =
|
||||
((AbstractMemberWriter) memberSummaryBuilder.getMemberSummaryWriter(kind));
|
||||
if (writer == null) {
|
||||
liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind)));
|
||||
} else {
|
||||
writer.addNavSummaryLink(
|
||||
memberSummaryBuilder.members(kind),
|
||||
memberSummaryBuilder.getVisibleMemberMap(kind), liNav);
|
||||
}
|
||||
if (kind != Kind.METHODS) {
|
||||
addNavGap(liNav);
|
||||
}
|
||||
ulNav.addContent(liNav);
|
||||
}
|
||||
return ulNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detail links for the navigation bar.
|
||||
*
|
||||
* @return the content tree for the detail links
|
||||
*/
|
||||
protected Content getNavDetailLinks() {
|
||||
Content li = HtmlTree.LI(contents.detailLabel);
|
||||
li.addContent(Contents.SPACE);
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
|
||||
MemberSummaryBuilder memberSummaryBuilder =
|
||||
configuration.getBuilderFactory().getMemberSummaryBuilder(this);
|
||||
for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.detailSet) {
|
||||
Content liNav = new HtmlTree(HtmlTag.LI);
|
||||
AbstractMemberWriter writer =
|
||||
((AbstractMemberWriter) memberSummaryBuilder.
|
||||
getMemberSummaryWriter(kind));
|
||||
if (kind == VisibleMemberMap.Kind.ENUM_CONSTANTS && !utils.isEnum(typeElement)) {
|
||||
continue;
|
||||
}
|
||||
if (kind == VisibleMemberMap.Kind.CONSTRUCTORS && utils.isEnum(typeElement)) {
|
||||
continue;
|
||||
}
|
||||
if (writer == null) {
|
||||
liNav.addContent(contents.getContent(VisibleMemberMap.Kind.getNavLinkLabels(kind)));
|
||||
} else {
|
||||
writer.addNavDetailLink(memberSummaryBuilder.members(kind), liNav);
|
||||
}
|
||||
if (kind != Kind.METHODS) {
|
||||
addNavGap(liNav);
|
||||
}
|
||||
ulNav.addContent(liNav);
|
||||
}
|
||||
return ulNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the TypeElement being documented.
|
||||
*
|
||||
|
||||
@ -40,7 +40,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.ConstantsSummaryWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -86,6 +87,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
|
||||
*/
|
||||
private HtmlTree summaryTree;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Construct a ConstantsSummaryWriter.
|
||||
* @param configuration the configuration used in this run
|
||||
@ -98,6 +101,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
|
||||
configuration.getText("doclet.Constants_Summary"));
|
||||
constantsTableHeader = new TableHeader(
|
||||
contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel);
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.CONSTANTVALUES, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +115,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -341,7 +346,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: contentTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
contentTree.addContent(htmlTree);
|
||||
|
||||
@ -38,7 +38,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.ConstructorWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -294,33 +294,6 @@ public class ConstructorWriterImpl extends AbstractExecutableMemberWriter
|
||||
public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
return links.createLink(SectionName.CONSTRUCTOR_SUMMARY,
|
||||
contents.navConstructor);
|
||||
} else {
|
||||
return contents.navConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.CONSTRUCTOR_DETAIL,
|
||||
contents.navConstructor));
|
||||
} else {
|
||||
liNav.addContent(contents.navConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@ -42,6 +42,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DeprecatedAPIListBuilder;
|
||||
@ -209,6 +211,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||
|
||||
private HtmlConfiguration configuration;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@ -219,6 +223,7 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||
public DeprecatedListWriter(HtmlConfiguration configuration, DocPath filename) {
|
||||
super(configuration, filename);
|
||||
this.configuration = configuration;
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.DEPRECATED, path);
|
||||
NestedClassWriterImpl classW = new NestedClassWriterImpl(this);
|
||||
writerMap = new EnumMap<>(DeprElementKind.class);
|
||||
for (DeprElementKind kind : DeprElementKind.values()) {
|
||||
@ -307,7 +312,8 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||
htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
@ -378,24 +384,14 @@ public class DeprecatedListWriter extends SubWriterHolderWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
return bodyTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the deprecated label.
|
||||
*
|
||||
* @return a content tree for the deprecated label
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkDeprecated() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.deprecatedLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add deprecated information to the documentation tree
|
||||
*
|
||||
|
||||
@ -27,16 +27,15 @@ package jdk.javadoc.internal.doclets.formats.html;
|
||||
|
||||
import com.sun.source.doctree.AttributeTree;
|
||||
import com.sun.source.doctree.AttributeTree.ValueKind;
|
||||
import com.sun.source.doctree.DocRootTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.EndElementTree;
|
||||
import com.sun.source.doctree.LinkTree;
|
||||
import com.sun.source.doctree.StartElementTree;
|
||||
import com.sun.source.doctree.TextTree;
|
||||
import com.sun.source.util.SimpleDocTreeVisitor;
|
||||
import com.sun.tools.doclint.HtmlTag;
|
||||
import com.sun.tools.doclint.HtmlTag.Attr;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocFileElement;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
|
||||
@ -51,15 +50,19 @@ import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
|
||||
public class DocFilesHandlerImpl implements DocFilesHandler {
|
||||
|
||||
public final Element element;
|
||||
public final Location location;
|
||||
public final DocPath source;
|
||||
public final HtmlConfiguration configuration;
|
||||
private Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor to construct the DocFilesWriter object.
|
||||
@ -171,14 +174,24 @@ public class DocFilesHandlerImpl implements DocFilesHandler {
|
||||
String title = getWindowTitle(docletWriter, dfElement).trim();
|
||||
HtmlTree htmlContent = docletWriter.getBody(true, title);
|
||||
docletWriter.addTop(htmlContent);
|
||||
docletWriter.addNavLinks(true, htmlContent);
|
||||
PackageElement pkg = (PackageElement) element;
|
||||
this.navBar = new Navigation(pkg, configuration, docletWriter.fixedNavDiv,
|
||||
PageMode.DOCFILE, docletWriter.path);
|
||||
Content mdleLinkContent = docletWriter.getModuleLink(utils.elementUtils.getModuleOf(pkg),
|
||||
docletWriter.contents.moduleLabel);
|
||||
navBar.setNavLinkModule(mdleLinkContent);
|
||||
Content pkgLinkContent = docletWriter.getPackageLink(pkg, docletWriter.contents.packageLabel);
|
||||
navBar.setNavLinkPackage(pkgLinkContent);
|
||||
navBar.setUserHeader(docletWriter.getUserHeaderFooter(true));
|
||||
htmlContent.addContent(navBar.getContent(true));
|
||||
List<? extends DocTree> fullBody = utils.getFullBody(dfElement);
|
||||
Content bodyContent = docletWriter.commentTagsToContent(null, dfElement, fullBody, false);
|
||||
|
||||
docletWriter.addTagsInfo(dfElement, bodyContent);
|
||||
htmlContent.addContent(bodyContent);
|
||||
|
||||
docletWriter.addNavLinks(false, htmlContent);
|
||||
navBar.setUserFooter(docletWriter.getUserHeaderFooter(false));
|
||||
htmlContent.addContent(navBar.getContent(false));
|
||||
docletWriter.addBottom(htmlContent);
|
||||
docletWriter.printHtmlDocument(Collections.emptyList(), false, htmlContent);
|
||||
return true;
|
||||
@ -301,31 +314,5 @@ public class DocFilesHandlerImpl implements DocFilesHandler {
|
||||
throw new AssertionError("unsupported element: " + e.getKind());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(pkg),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this package link.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent = getPackageLink(pkg,
|
||||
contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.EnumConstantWriter;
|
||||
@ -273,37 +273,4 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter
|
||||
String name = utils.getFullyQualifiedName(member) + "." + member.getSimpleName();
|
||||
return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, member, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
if (typeElement == null) {
|
||||
return links.createLink(SectionName.ENUM_CONSTANT_SUMMARY,
|
||||
contents.navEnum);
|
||||
} else {
|
||||
return links.createLink(
|
||||
SectionName.ENUM_CONSTANTS_INHERITANCE,
|
||||
configuration.getClassName(typeElement), contents.navEnum);
|
||||
}
|
||||
} else {
|
||||
return contents.navEnum;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.ENUM_CONSTANT_DETAIL,
|
||||
contents.navEnum));
|
||||
} else {
|
||||
liNav.addContent(contents.navEnum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.FieldWriter;
|
||||
@ -302,38 +302,4 @@ public class FieldWriterImpl extends AbstractMemberWriter
|
||||
String name = utils.getFullyQualifiedName(member) + "." + member.getSimpleName();
|
||||
return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, member, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
if (typeElement == null) {
|
||||
return links.createLink(
|
||||
SectionName.FIELD_SUMMARY,
|
||||
contents.navField);
|
||||
} else {
|
||||
return links.createLink(
|
||||
SectionName.FIELDS_INHERITANCE,
|
||||
configuration.getClassName(typeElement), contents.navField);
|
||||
}
|
||||
} else {
|
||||
return contents.navField;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.FIELD_DETAIL,
|
||||
contents.navField));
|
||||
} else {
|
||||
liNav.addContent(contents.navField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
@ -51,6 +53,8 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
|
||||
HtmlTree mainTree = HtmlTree.MAIN();
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor to construct HelpWriter object.
|
||||
* @param configuration the configuration
|
||||
@ -59,6 +63,7 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
public HelpWriter(HtmlConfiguration configuration,
|
||||
DocPath filename) {
|
||||
super(configuration, filename);
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.HELP, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +93,8 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: body;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
body.addContent(htmlTree);
|
||||
}
|
||||
@ -96,7 +102,8 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
htmlTree = HtmlTree.FOOTER();
|
||||
}
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
@ -428,15 +435,4 @@ public class HelpWriter extends HtmlDocletWriter {
|
||||
contentTree.addContent(divContent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the help label.
|
||||
*
|
||||
* @return a content tree for the help label
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkHelp() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.helpLabel);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,11 +247,11 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
|
||||
protected Set<Character> tagSearchIndexKeys;
|
||||
|
||||
protected final Contents contents;
|
||||
public final Contents contents;
|
||||
|
||||
protected final Messages messages;
|
||||
|
||||
protected DocPaths docPaths;
|
||||
public DocPaths docPaths;
|
||||
|
||||
/**
|
||||
* Creates an object to hold the configuration for a doclet.
|
||||
|
||||
@ -69,13 +69,13 @@ import com.sun.source.util.SimpleDocTreeVisitor;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.DocType;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Script;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
@ -490,261 +490,6 @@ public class HtmlDocletWriter {
|
||||
htmlTree.addContent(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the navigation bar for the Html page at the top and and the bottom.
|
||||
*
|
||||
* @param header If true print navigation bar at the top of the page else
|
||||
* @param htmlTree the HtmlTree to which the nav links will be added
|
||||
*/
|
||||
protected void addNavLinks(boolean header, Content htmlTree) {
|
||||
if (!configuration.nonavbar) {
|
||||
Content tree = (configuration.allowTag(HtmlTag.NAV))
|
||||
? HtmlTree.NAV()
|
||||
: htmlTree;
|
||||
String allClassesId = "allclasses_";
|
||||
HtmlTree navDiv = new HtmlTree(HtmlTag.DIV);
|
||||
fixedNavDiv.setStyle(HtmlStyle.fixedNav);
|
||||
Content skipNavLinks = configuration.getContent("doclet.Skip_navigation_links");
|
||||
if (header) {
|
||||
fixedNavDiv.addContent(HtmlConstants.START_OF_TOP_NAVBAR);
|
||||
navDiv.setStyle(HtmlStyle.topNav);
|
||||
allClassesId += "navbar_top";
|
||||
Content a = links.createAnchor(SectionName.NAVBAR_TOP);
|
||||
//WCAG - Hyperlinks should contain text or an image with alt text - for AT tools
|
||||
navDiv.addContent(a);
|
||||
Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav,
|
||||
links.createLink(SectionName.SKIP_NAVBAR_TOP, skipNavLinks,
|
||||
skipNavLinks.toString(), ""));
|
||||
navDiv.addContent(skipLinkContent);
|
||||
} else {
|
||||
tree.addContent(HtmlConstants.START_OF_BOTTOM_NAVBAR);
|
||||
navDiv.setStyle(HtmlStyle.bottomNav);
|
||||
allClassesId += "navbar_bottom";
|
||||
Content a = links.createAnchor(SectionName.NAVBAR_BOTTOM);
|
||||
navDiv.addContent(a);
|
||||
Content skipLinkContent = HtmlTree.DIV(HtmlStyle.skipNav,
|
||||
links.createLink(SectionName.SKIP_NAVBAR_BOTTOM, skipNavLinks,
|
||||
skipNavLinks.toString(), ""));
|
||||
navDiv.addContent(skipLinkContent);
|
||||
}
|
||||
if (header) {
|
||||
navDiv.addContent(links.createAnchor(SectionName.NAVBAR_TOP_FIRSTROW));
|
||||
} else {
|
||||
navDiv.addContent(links.createAnchor(SectionName.NAVBAR_BOTTOM_FIRSTROW));
|
||||
}
|
||||
HtmlTree navList = new HtmlTree(HtmlTag.UL);
|
||||
navList.setStyle(HtmlStyle.navList);
|
||||
navList.addAttr(HtmlAttr.TITLE,
|
||||
configuration.getText("doclet.Navigation"));
|
||||
if (configuration.createoverview) {
|
||||
navList.addContent(getNavLinkContents());
|
||||
}
|
||||
if (configuration.showModules) {
|
||||
if (configuration.modules.size() == 1) {
|
||||
navList.addContent(getNavLinkModule(configuration.modules.first()));
|
||||
} else if (!configuration.modules.isEmpty()) {
|
||||
navList.addContent(getNavLinkModule());
|
||||
}
|
||||
}
|
||||
if (configuration.packages.size() == 1) {
|
||||
navList.addContent(getNavLinkPackage(configuration.packages.first()));
|
||||
} else if (!configuration.packages.isEmpty()) {
|
||||
navList.addContent(getNavLinkPackage());
|
||||
}
|
||||
navList.addContent(getNavLinkClass());
|
||||
if(configuration.classuse) {
|
||||
navList.addContent(getNavLinkClassUse());
|
||||
}
|
||||
if(configuration.createtree) {
|
||||
navList.addContent(getNavLinkTree());
|
||||
}
|
||||
if(!(configuration.nodeprecated ||
|
||||
configuration.nodeprecatedlist)) {
|
||||
navList.addContent(getNavLinkDeprecated());
|
||||
}
|
||||
if(configuration.createindex) {
|
||||
navList.addContent(getNavLinkIndex());
|
||||
}
|
||||
if (!configuration.nohelp) {
|
||||
navList.addContent(getNavLinkHelp());
|
||||
}
|
||||
navDiv.addContent(navList);
|
||||
Content aboutDiv = HtmlTree.DIV(HtmlStyle.aboutLanguage, getUserHeaderFooter(header));
|
||||
navDiv.addContent(aboutDiv);
|
||||
if (header) {
|
||||
fixedNavDiv.addContent(navDiv);
|
||||
} else {
|
||||
tree.addContent(navDiv);
|
||||
}
|
||||
HtmlTree subDiv = new HtmlTree(HtmlTag.DIV);
|
||||
subDiv.setStyle(HtmlStyle.subNav);
|
||||
if (configuration.frames) {
|
||||
Content ulFrames = HtmlTree.UL(HtmlStyle.navList,
|
||||
getNavShowLists(), getNavHideLists(filename));
|
||||
subDiv.addContent(ulFrames);
|
||||
}
|
||||
HtmlTree ulAllClasses = HtmlTree.UL(HtmlStyle.navList, getNavLinkClassIndex());
|
||||
ulAllClasses.addAttr(HtmlAttr.ID, allClassesId);
|
||||
subDiv.addContent(ulAllClasses);
|
||||
if (header && configuration.createindex) {
|
||||
String searchValueId = "search";
|
||||
String reset = "reset";
|
||||
HtmlTree inputText = HtmlTree.INPUT("text", searchValueId, searchValueId);
|
||||
HtmlTree inputReset = HtmlTree.INPUT(reset, reset, reset);
|
||||
Content searchTxt = configuration.getContent("doclet.search");
|
||||
HtmlTree liInput = HtmlTree.LI(HtmlTree.LABEL(searchValueId, searchTxt));
|
||||
liInput.addContent(inputText);
|
||||
liInput.addContent(inputReset);
|
||||
HtmlTree ulSearch = HtmlTree.UL(HtmlStyle.navListSearch, liInput);
|
||||
subDiv.addContent(ulSearch);
|
||||
}
|
||||
subDiv.addContent(getAllClassesLinkScript(allClassesId));
|
||||
addSummaryDetailLinks(subDiv);
|
||||
if (header) {
|
||||
subDiv.addContent(links.createAnchor(SectionName.SKIP_NAVBAR_TOP));
|
||||
fixedNavDiv.addContent(subDiv);
|
||||
fixedNavDiv.addContent(HtmlConstants.END_OF_TOP_NAVBAR);
|
||||
tree.addContent(fixedNavDiv);
|
||||
HtmlTree paddingDiv = HtmlTree.DIV(HtmlStyle.navPadding, Contents.SPACE);
|
||||
tree.addContent(paddingDiv);
|
||||
Script script = new Script(
|
||||
"<!--\n"
|
||||
+ "$('.navPadding').css('padding-top', $('.fixedNav').css(\"height\"));\n"
|
||||
+ "//-->\n");
|
||||
tree.addContent(script.asContent());
|
||||
} else {
|
||||
subDiv.addContent(links.createAnchor(SectionName.SKIP_NAVBAR_BOTTOM));
|
||||
tree.addContent(subDiv);
|
||||
tree.addContent(HtmlConstants.END_OF_BOTTOM_NAVBAR);
|
||||
}
|
||||
if (configuration.allowTag(HtmlTag.NAV)) {
|
||||
htmlTree.addContent(tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do nothing. This is the default method.
|
||||
*/
|
||||
protected void addSummaryDetailLinks(Content navDiv) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to the "overview-summary.html" page.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkContents() {
|
||||
Content linkContent = links.createLink(pathToRoot.resolve(DocPaths.overviewSummary(configuration.frames)),
|
||||
contents.overviewLabel, "", "");
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to the module summary page for the module passed.
|
||||
*
|
||||
* @param mdle Module to which link will be generated
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkModule(ModuleElement mdle) {
|
||||
Content linkContent = getModuleLink(mdle, contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the word "Module", to indicate that link is not available here.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkModule() {
|
||||
Content li = HtmlTree.LI(contents.moduleLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to the "package-summary.html" page for the package passed.
|
||||
*
|
||||
* @param pkg Package to which link will be generated
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkPackage(PackageElement pkg) {
|
||||
Content linkContent = getPackageLink(pkg, contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the word "Package" , to indicate that link is not available here.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkPackage() {
|
||||
Content li = HtmlTree.LI(contents.packageLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the word "Use", to indicate that link is not available.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content li = HtmlTree.LI(contents.useLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "FRAMES" link, to switch to the frame version of the output.
|
||||
*
|
||||
* @param link File to be linked, "index.html"
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavShowLists(DocPath link) {
|
||||
DocLink dl = new DocLink(link, path.getPath(), null);
|
||||
Content framesContent = links.createLink(dl, contents.framesLabel, "", "_top");
|
||||
Content li = HtmlTree.LI(framesContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "FRAMES" link, to switch to the frame version of the output.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavShowLists() {
|
||||
return getNavShowLists(pathToRoot.resolve(DocPaths.INDEX));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "NO FRAMES" link, to switch to the non-frame version of the output.
|
||||
*
|
||||
* @param link File to be linked
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavHideLists(DocPath link) {
|
||||
Content noFramesContent = links.createLink(link, contents.noFramesLabel, "", "_top");
|
||||
Content li = HtmlTree.LI(noFramesContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "Tree" link in the navigation bar. If there is only one package
|
||||
* specified on the command line, then the "Tree" link will be to the
|
||||
* only "package-tree.html" file otherwise it will be to the
|
||||
* "overview-tree.html" file.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkTree() {
|
||||
List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackageElements());
|
||||
DocPath docPath = packages.size() == 1 && configuration.getSpecifiedTypeElements().isEmpty()
|
||||
? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
|
||||
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
|
||||
return HtmlTree.LI(links.createLink(docPath, contents.treeLabel, "", ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the overview tree link for the main tree.
|
||||
*
|
||||
@ -758,91 +503,6 @@ public class HtmlDocletWriter {
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the word "Class", to indicate that class link is not available.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkClass() {
|
||||
Content li = HtmlTree.LI(contents.classLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "Deprecated" API link in the navigation bar.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkDeprecated() {
|
||||
Content linkContent = links.createLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST),
|
||||
contents.deprecatedLabel, "", "");
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link for generated index. If the user has used "-splitindex"
|
||||
* command line option, then link to file "index-files/index-1.html" is
|
||||
* generated otherwise link to file "index-all.html" is generated.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkClassIndex() {
|
||||
Content allClassesContent = links.createLink(pathToRoot.resolve(
|
||||
DocPaths.AllClasses(configuration.frames)),
|
||||
contents.allClassesLabel, "", "");
|
||||
Content li = HtmlTree.LI(allClassesContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link for generated class index.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkIndex() {
|
||||
Content linkContent = links.createLink(pathToRoot.resolve(
|
||||
(configuration.splitindex
|
||||
? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1))
|
||||
: DocPaths.INDEX_ALL)),
|
||||
contents.indexLabel, "", "");
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get help file link. If user has provided a help file, then generate a
|
||||
* link to the user given file, which is already copied to current or
|
||||
* destination directory.
|
||||
*
|
||||
* @return a content tree for the link
|
||||
*/
|
||||
protected Content getNavLinkHelp() {
|
||||
String helpfile = configuration.helpfile;
|
||||
DocPath helpfilenm;
|
||||
if (helpfile.isEmpty()) {
|
||||
helpfilenm = DocPaths.HELP_DOC;
|
||||
} else {
|
||||
DocFile file = DocFile.createFileForInput(configuration, helpfile);
|
||||
helpfilenm = DocPath.create(file.getName());
|
||||
}
|
||||
Content linkContent = links.createLink(pathToRoot.resolve(helpfilenm),
|
||||
contents.helpLabel, "", "");
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add gap between navigation bar elements.
|
||||
*
|
||||
* @param liNav the content tree to which the gap will be added
|
||||
*/
|
||||
protected void addNavGap(Content liNav) {
|
||||
liNav.addContent(Contents.SPACE);
|
||||
liNav.addContent("|");
|
||||
liNav.addContent(Contents.SPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get table caption.
|
||||
*
|
||||
|
||||
@ -40,7 +40,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
|
||||
@ -424,37 +424,4 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
|
||||
htmltree.addContent(Contents.SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
if (typeElement == null) {
|
||||
return links.createLink(
|
||||
SectionName.METHOD_SUMMARY,
|
||||
contents.navMethod);
|
||||
} else {
|
||||
return links.createLink(
|
||||
SectionName.METHODS_INHERITANCE,
|
||||
configuration.getClassName(typeElement), contents.navMethod);
|
||||
}
|
||||
} else {
|
||||
return contents.navMethod;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.METHOD_DETAIL, contents.navMethod));
|
||||
} else {
|
||||
liNav.addContent(contents.navMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +227,8 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: body;
|
||||
addTop(tree);
|
||||
addNavLinks(true, tree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
tree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
body.addContent(tree);
|
||||
}
|
||||
@ -244,7 +245,8 @@ public class ModuleIndexWriter extends AbstractModuleIndexWriter {
|
||||
Content htmltree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, htmltree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmltree.addContent(navBar.getContent(false));
|
||||
addBottom(htmltree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmltree);
|
||||
|
||||
@ -50,13 +50,14 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.ModuleSummaryWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
|
||||
/**
|
||||
* Class to generate file for each module contents in the right-hand frame. This will list all the
|
||||
@ -171,6 +172,8 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
*/
|
||||
protected HtmlTree sectionTree = HtmlTree.SECTION();
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor to construct ModuleWriter object and to generate "moduleName-summary.html" file.
|
||||
*
|
||||
@ -181,6 +184,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
super(configuration, configuration.docPaths.moduleSummary(mdle));
|
||||
this.mdle = mdle;
|
||||
this.moduleMode = configuration.docEnv.getModuleMode();
|
||||
this.navBar = new Navigation(mdle, configuration, fixedNavDiv, PageMode.MODULE, path);
|
||||
computeModulesData();
|
||||
}
|
||||
|
||||
@ -196,7 +200,13 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setDisplaySummaryModuleDescLink(!utils.getFullBody(mdle).isEmpty() && !configuration.nocomment);
|
||||
navBar.setDisplaySummaryModulesLink(display(requires) || display(indirectModules));
|
||||
navBar.setDisplaySummaryPackagesLink(display(packages) || display(indirectPackages)
|
||||
|| display(indirectOpenPackages));
|
||||
navBar.setDisplaySummaryServicesLink(displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees));
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -913,47 +923,6 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add summary details to the navigation bar.
|
||||
*
|
||||
* @param subDiv the content tree to which the summary detail links will be added
|
||||
*/
|
||||
@Override
|
||||
protected void addSummaryDetailLinks(Content subDiv) {
|
||||
Content div = HtmlTree.DIV(getNavSummaryLinks());
|
||||
subDiv.addContent(div);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary links for navigation bar.
|
||||
*
|
||||
* @return the content tree for the navigation summary links
|
||||
*/
|
||||
protected Content getNavSummaryLinks() {
|
||||
Content li = HtmlTree.LI(contents.moduleSubNavLabel);
|
||||
li.addContent(Contents.SPACE);
|
||||
Content ulNav = HtmlTree.UL(HtmlStyle.subNavList, li);
|
||||
Content liNav = new HtmlTree(HtmlTag.LI);
|
||||
liNav.addContent(!utils.getFullBody(mdle).isEmpty() && !configuration.nocomment
|
||||
? links.createLink(SectionName.MODULE_DESCRIPTION, contents.navModuleDescription)
|
||||
: contents.navModuleDescription);
|
||||
addNavGap(liNav);
|
||||
liNav.addContent((display(requires) || display(indirectModules))
|
||||
? links.createLink(SectionName.MODULES, contents.navModules)
|
||||
: contents.navModules);
|
||||
addNavGap(liNav);
|
||||
liNav.addContent((display(packages)
|
||||
|| display(indirectPackages) || display(indirectOpenPackages))
|
||||
? links.createLink(SectionName.PACKAGES, contents.navPackages)
|
||||
: contents.navPackages);
|
||||
addNavGap(liNav);
|
||||
liNav.addContent((displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees))
|
||||
? links.createLink(SectionName.SERVICES, contents.navServices)
|
||||
: contents.navServices);
|
||||
ulNav.addContent(liNav);
|
||||
return ulNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -975,7 +944,8 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: contentTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
contentTree.addContent(htmlTree);
|
||||
@ -1017,15 +987,4 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
li.addContent(deprDiv);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.moduleLabel);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import javax.lang.model.element.TypeElement;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
|
||||
@ -205,31 +205,4 @@ public class NestedClassWriterImpl extends AbstractMemberWriter
|
||||
protected Content getDeprecatedLink(Element member) {
|
||||
return writer.getQualifiedClassLink(LinkInfoImpl.Kind.MEMBER, member);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
if (typeElement == null) {
|
||||
return links.createLink(
|
||||
SectionName.NESTED_CLASS_SUMMARY,
|
||||
contents.navNested);
|
||||
} else {
|
||||
return links.createLink(
|
||||
SectionName.NESTED_CLASSES_INHERITANCE,
|
||||
utils.getFullyQualifiedName(typeElement), contents.navNested);
|
||||
}
|
||||
} else {
|
||||
return contents.navNested;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,7 +209,8 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: body;
|
||||
addTop(tree);
|
||||
addNavLinks(true, tree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
tree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
body.addContent(tree);
|
||||
}
|
||||
@ -226,7 +227,8 @@ public class PackageIndexWriter extends AbstractPackageIndexWriter {
|
||||
Content tree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, tree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
tree.addContent(navBar.getContent(false));
|
||||
addBottom(tree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(tree);
|
||||
|
||||
@ -31,6 +31,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
@ -57,6 +59,8 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
*/
|
||||
protected PackageElement packageElement;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param configuration the configuration
|
||||
@ -67,6 +71,7 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
super(configuration, path,
|
||||
new ClassTree(configuration.typeElementCatalog.allClasses(packageElement), configuration));
|
||||
this.packageElement = packageElement;
|
||||
this.navBar = new Navigation(packageElement, configuration, fixedNavDiv, PageMode.TREE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,7 +123,8 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
HtmlTree tree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, tree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
tree.addContent(navBar.getContent(false));
|
||||
addBottom(tree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(tree);
|
||||
@ -139,7 +145,11 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(linkContent);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -160,30 +170,4 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
ul.addContent(getNavLinkMainTree(configuration.getText("doclet.All_Packages")));
|
||||
div.addContent(ul);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link to the package summary page for the package of this tree.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent = links.createLink(DocPaths.PACKAGE_SUMMARY,
|
||||
contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassUseMapper;
|
||||
@ -63,6 +64,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
|
||||
final SortedMap<String, Set<TypeElement>> usingPackageToUsedClasses = new TreeMap<>();
|
||||
protected HtmlTree mainTree = HtmlTree.MAIN();
|
||||
final String packageUseTableSummary;
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -100,6 +102,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
|
||||
|
||||
packageUseTableSummary = resources.getText("doclet.Use_Table_Summary",
|
||||
resources.getText("doclet.packages"));
|
||||
this.navBar = new Navigation(packageElement, configuration, fixedNavDiv, PageMode.USE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,7 +143,8 @@ public class PackageUseWriter extends SubWriterHolderWriter {
|
||||
HtmlTree tree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: body;
|
||||
addNavLinks(false, tree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
tree.addContent(navBar.getContent(false));
|
||||
addBottom(tree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(tree);
|
||||
@ -249,7 +253,11 @@ public class PackageUseWriter extends SubWriterHolderWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(linkContent);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -267,54 +275,4 @@ public class PackageUseWriter extends SubWriterHolderWriter {
|
||||
}
|
||||
return bodyTree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this package link.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content linkContent = links.createLink(DocPaths.PACKAGE_SUMMARY,
|
||||
contents.packageLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the use link.
|
||||
*
|
||||
* @return a content tree for the use link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.useLabel);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree link.
|
||||
*
|
||||
* @return a content tree for the tree link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkTree() {
|
||||
Content linkContent = links.createLink(DocPaths.PACKAGE_TREE,
|
||||
contents.treeLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,12 +40,13 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
|
||||
/**
|
||||
@ -79,6 +80,8 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||
*/
|
||||
protected HtmlTree sectionTree = HtmlTree.SECTION();
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor to construct PackageWriter object and to generate
|
||||
* "package-summary.html" file in the respective package directory.
|
||||
@ -95,6 +98,7 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||
configuration.docPaths.forPackage(packageElement)
|
||||
.resolve(DocPaths.PACKAGE_SUMMARY));
|
||||
this.packageElement = packageElement;
|
||||
this.navBar = new Navigation(packageElement, configuration, fixedNavDiv, PageMode.PACKAGE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +111,11 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
navBar.setNavLinkModule(linkContent);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -346,7 +354,8 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: contentTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
contentTree.addContent(htmlTree);
|
||||
@ -361,55 +370,4 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
||||
printHtmlDocument(configuration.metakeywords.getMetaKeywords(packageElement),
|
||||
true, contentTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "Use" link for this pacakge in the navigation bar.
|
||||
*
|
||||
* @return a content tree for the class use link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkClassUse() {
|
||||
Content useLink = links.createLink(DocPaths.PACKAGE_USE,
|
||||
contents.useLabel, "", "");
|
||||
Content li = HtmlTree.LI(useLink);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "Tree" link in the navigation bar. This will be link to the package
|
||||
* tree file.
|
||||
*
|
||||
* @return a content tree for the tree link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkTree() {
|
||||
Content useLink = links.createLink(DocPaths.PACKAGE_TREE,
|
||||
contents.treeLabel, "", "");
|
||||
Content li = HtmlTree.LI(useLink);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the module link.
|
||||
*
|
||||
* @return a content tree for the module link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkModule() {
|
||||
Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement),
|
||||
contents.moduleLabel);
|
||||
Content li = HtmlTree.LI(linkContent);
|
||||
return li;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight "Package" in the navigation bar, as this is the package page.
|
||||
*
|
||||
* @return a content tree for the package link
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavLinkPackage() {
|
||||
Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, contents.packageLabel);
|
||||
return li;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
|
||||
@ -324,38 +324,4 @@ public class PropertyWriterImpl extends AbstractMemberWriter
|
||||
return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, member,
|
||||
utils.getFullyQualifiedName(member));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Content getNavSummaryLink(TypeElement typeElement, boolean link) {
|
||||
if (link) {
|
||||
if (typeElement == null) {
|
||||
return links.createLink(
|
||||
SectionName.PROPERTY_SUMMARY,
|
||||
contents.navProperty);
|
||||
} else {
|
||||
return links.createLink(
|
||||
SectionName.PROPERTIES_INHERITANCE,
|
||||
configuration.getClassName(typeElement), contents.navProperty);
|
||||
}
|
||||
} else {
|
||||
return contents.navProperty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void addNavDetailLink(boolean link, Content liNav) {
|
||||
if (link) {
|
||||
liNav.addContent(links.createLink(
|
||||
SectionName.PROPERTY_DETAIL,
|
||||
contents.navProperty));
|
||||
} else {
|
||||
liNav.addContent(contents.navProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.SerializedFormWriter;
|
||||
@ -59,12 +61,15 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
|
||||
*/
|
||||
private HtmlTree mainTree = HtmlTree.MAIN();
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* @param configuration the configuration data for the doclet
|
||||
*/
|
||||
public SerializedFormWriterImpl(HtmlConfiguration configuration) {
|
||||
super(configuration, DocPaths.SERIALIZED_FORM);
|
||||
visibleClasses = configuration.getIncludedTypeElements();
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.SERIALIZEDFORM, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +84,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
@ -261,7 +267,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
|
||||
Content htmlTree = (configuration.allowTag(HtmlTag.FOOTER))
|
||||
? HtmlTree.FOOTER()
|
||||
: serializedTree;
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
serializedTree.addContent(htmlTree);
|
||||
|
||||
@ -97,7 +97,8 @@ public class SingleIndexWriter extends AbstractIndexWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: body;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
body.addContent(htmlTree);
|
||||
}
|
||||
@ -123,7 +124,8 @@ public class SingleIndexWriter extends AbstractIndexWriter {
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
htmlTree = HtmlTree.FOOTER();
|
||||
}
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
|
||||
@ -125,7 +125,8 @@ public class SplitIndexWriter extends AbstractIndexWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: body;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
body.addContent(htmlTree);
|
||||
}
|
||||
@ -145,7 +146,8 @@ public class SplitIndexWriter extends AbstractIndexWriter {
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
htmlTree = HtmlTree.FOOTER();
|
||||
}
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
|
||||
@ -33,7 +33,8 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Links;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.StringContent;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
@ -68,6 +69,8 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
*/
|
||||
private final boolean classesOnly;
|
||||
|
||||
private final Navigation navBar;
|
||||
|
||||
/**
|
||||
* Constructor to construct TreeWriter object.
|
||||
*
|
||||
@ -79,6 +82,7 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
super(configuration, filename, classtree);
|
||||
packages = configuration.packages;
|
||||
classesOnly = packages.isEmpty();
|
||||
this.navBar = new Navigation(null, configuration, fixedNavDiv, PageMode.TREE, path);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +131,8 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
} else {
|
||||
htmlTree = body;
|
||||
}
|
||||
addNavLinks(false, htmlTree);
|
||||
navBar.setUserFooter(getUserHeaderFooter(false));
|
||||
htmlTree.addContent(navBar.getContent(false));
|
||||
addBottom(htmlTree);
|
||||
if (configuration.allowTag(HtmlTag.FOOTER)) {
|
||||
body.addContent(htmlTree);
|
||||
@ -186,7 +191,8 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
? HtmlTree.HEADER()
|
||||
: bodyTree;
|
||||
addTop(htmlTree);
|
||||
addNavLinks(true, htmlTree);
|
||||
navBar.setUserHeader(getUserHeaderFooter(true));
|
||||
htmlTree.addContent(navBar.getContent(true));
|
||||
if (configuration.allowTag(HtmlTag.HEADER)) {
|
||||
bodyTree.addContent(htmlTree);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -446,7 +446,7 @@ JTREG_BASIC_OPTIONS += -e:JIB_DATA_DIR
|
||||
JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
|
||||
# Give aot tests access to Visual Studio installation
|
||||
ifneq ($(VS120COMNTOOLS), )
|
||||
JTREG_BASIC_OPTIONS += -e:VS120COMNTOOLS=$(shell $(GETMIXEDPATH) "$(VS120COMNTOOLS)")
|
||||
JTREG_BASIC_OPTIONS += -e:VS120COMNTOOLS="$(shell $(GETMIXEDPATH) "$(patsubst %\,%,$(VS120COMNTOOLS))")"
|
||||
endif
|
||||
# Set other vm and test options
|
||||
JTREG_TEST_OPTIONS += $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%)
|
||||
|
||||
@ -36,6 +36,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -55,6 +56,7 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -75,6 +77,13 @@ public class IteratorMicroBenchmark {
|
||||
public Job(String name) { this.name = name; }
|
||||
public String name() { return name; }
|
||||
public abstract void work() throws Throwable;
|
||||
public void run() {
|
||||
try { work(); }
|
||||
catch (Throwable ex) {
|
||||
// current job cannot always be deduced from stacktrace.
|
||||
throw new RuntimeException("Job failed: " + name(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int iterations;
|
||||
@ -102,6 +111,7 @@ public class IteratorMicroBenchmark {
|
||||
static void forceFullGc() {
|
||||
CountDownLatch finalizeDone = new CountDownLatch(1);
|
||||
WeakReference<?> ref = new WeakReference<Object>(new Object() {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() { finalizeDone.countDown(); }});
|
||||
try {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@ -123,7 +133,7 @@ public class IteratorMicroBenchmark {
|
||||
* compiling everything worth compiling.
|
||||
* Returns array of average times per job per run.
|
||||
*/
|
||||
long[] time0(List<Job> jobs) throws Throwable {
|
||||
long[] time0(List<Job> jobs) {
|
||||
final int size = jobs.size();
|
||||
long[] nanoss = new long[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -132,7 +142,7 @@ public class IteratorMicroBenchmark {
|
||||
long totalTime;
|
||||
int runs = 0;
|
||||
long startTime = System.nanoTime();
|
||||
do { job.work(); runs++; }
|
||||
do { job.run(); runs++; }
|
||||
while ((totalTime = System.nanoTime() - startTime) < warmupNanos);
|
||||
nanoss[i] = totalTime/runs;
|
||||
}
|
||||
@ -211,10 +221,6 @@ public class IteratorMicroBenchmark {
|
||||
System.out.println("the answer");
|
||||
}
|
||||
|
||||
private static <T> List<T> asSubList(List<T> list) {
|
||||
return list.subList(0, list.size());
|
||||
}
|
||||
|
||||
private static <T> Iterable<T> backwards(final List<T> list) {
|
||||
return new Iterable<T>() {
|
||||
public Iterator<T> iterator() {
|
||||
@ -241,11 +247,32 @@ public class IteratorMicroBenchmark {
|
||||
new IteratorMicroBenchmark(args).run();
|
||||
}
|
||||
|
||||
void run() throws Throwable {
|
||||
// System.out.printf(
|
||||
// "iterations=%d size=%d, warmup=%1g, filter=\"%s\"%n",
|
||||
// iterations, size, warmupSeconds, nameFilter);
|
||||
HashMap<Class<?>, String> goodClassName = new HashMap<>();
|
||||
|
||||
String goodClassName(Class<?> klazz) {
|
||||
return goodClassName.computeIfAbsent(
|
||||
klazz,
|
||||
k -> {
|
||||
String simple = k.getSimpleName();
|
||||
return (simple.equals("SubList")) // too simple!
|
||||
? k.getName().replaceFirst(".*\\.", "")
|
||||
: simple;
|
||||
});
|
||||
}
|
||||
|
||||
static List<Integer> makeSubList(List<Integer> list) {
|
||||
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
int size = list.size();
|
||||
if (size <= 2) return list.subList(0, size);
|
||||
List<Integer> subList = list.subList(rnd.nextInt(0, 2),
|
||||
size - rnd.nextInt(0, 2));
|
||||
List<Integer> copy = new ArrayList<>(list);
|
||||
subList.clear();
|
||||
subList.addAll(copy);
|
||||
return subList;
|
||||
}
|
||||
|
||||
void run() throws Throwable {
|
||||
final ArrayList<Integer> al = new ArrayList<>(size);
|
||||
|
||||
// Populate collections with random data
|
||||
@ -265,10 +292,14 @@ public class IteratorMicroBenchmark {
|
||||
|
||||
ArrayList<Job> jobs = Stream.<Collection<Integer>>of(
|
||||
al, ad, abq,
|
||||
makeSubList(new ArrayList<>(al)),
|
||||
new LinkedList<>(al),
|
||||
makeSubList(new LinkedList<>(al)),
|
||||
new PriorityQueue<>(al),
|
||||
new Vector<>(al),
|
||||
makeSubList(new Vector<>(al)),
|
||||
new CopyOnWriteArrayList<>(al),
|
||||
makeSubList(new CopyOnWriteArrayList<>(al)),
|
||||
new ConcurrentLinkedQueue<>(al),
|
||||
new ConcurrentLinkedDeque<>(al),
|
||||
new LinkedBlockingQueue<>(al),
|
||||
@ -294,16 +325,25 @@ public class IteratorMicroBenchmark {
|
||||
Stream<Job> jobs(Collection<Integer> x) {
|
||||
return concatStreams(
|
||||
collectionJobs(x),
|
||||
|
||||
(x instanceof Deque)
|
||||
? dequeJobs((Deque<Integer>)x)
|
||||
: Stream.empty(),
|
||||
|
||||
(x instanceof List)
|
||||
? listJobs((List<Integer>)x)
|
||||
: Stream.empty());
|
||||
}
|
||||
|
||||
Object sneakyAdder(int[] sneakySum) {
|
||||
return new Object() {
|
||||
public int hashCode() { throw new AssertionError(); }
|
||||
public boolean equals(Object z) {
|
||||
sneakySum[0] += (int) z; return false; }};
|
||||
}
|
||||
|
||||
Stream<Job> collectionJobs(Collection<Integer> x) {
|
||||
String klazz = x.getClass().getSimpleName();
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " iterate for loop") {
|
||||
public void work() throws Throwable {
|
||||
@ -345,22 +385,28 @@ public class IteratorMicroBenchmark {
|
||||
new Job(klazz + " contains") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
Object y = new Object() {
|
||||
public boolean equals(Object z) {
|
||||
sum[0] += (int) z; return false; }};
|
||||
Object sneakyAdder = sneakyAdder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
if (x.contains(y)) throw new AssertionError();
|
||||
if (x.contains(sneakyAdder)) throw new AssertionError();
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(klazz + " containsAll") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
Collection<Object> sneakyAdderCollection =
|
||||
Collections.singleton(sneakyAdder(sum));
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
if (x.containsAll(sneakyAdderCollection))
|
||||
throw new AssertionError();
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(klazz + " remove(Object)") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
Object y = new Object() {
|
||||
public boolean equals(Object z) {
|
||||
sum[0] += (int) z; return false; }};
|
||||
Object sneakyAdder = sneakyAdder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
if (x.remove(y)) throw new AssertionError();
|
||||
if (x.remove(sneakyAdder)) throw new AssertionError();
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(klazz + " forEach") {
|
||||
public void work() throws Throwable {
|
||||
@ -446,7 +492,7 @@ public class IteratorMicroBenchmark {
|
||||
}
|
||||
|
||||
Stream<Job> dequeJobs(Deque<Integer> x) {
|
||||
String klazz = x.getClass().getSimpleName();
|
||||
String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " descendingIterator() loop") {
|
||||
public void work() throws Throwable {
|
||||
@ -466,48 +512,50 @@ public class IteratorMicroBenchmark {
|
||||
}
|
||||
|
||||
Stream<Job> listJobs(List<Integer> x) {
|
||||
String klazz = x.getClass().getSimpleName();
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " subList toArray()") {
|
||||
new Job(klazz + " listIterator forward loop") {
|
||||
public void work() throws Throwable {
|
||||
int size = x.size();
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
int total = Stream.of(x.subList(0, size / 2),
|
||||
x.subList(size / 2, size))
|
||||
.mapToInt(subList -> {
|
||||
int sum = 0;
|
||||
for (Object o : subList.toArray())
|
||||
sum += (Integer) o;
|
||||
return sum; })
|
||||
.sum();
|
||||
check.sum(total);}}},
|
||||
new Job(klazz + " subList toArray(a)") {
|
||||
int sum = 0;
|
||||
ListIterator<Integer> it = x.listIterator();
|
||||
while (it.hasNext())
|
||||
sum += it.next();
|
||||
check.sum(sum);}}},
|
||||
new Job(klazz + " listIterator backward loop") {
|
||||
public void work() throws Throwable {
|
||||
int size = x.size();
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
int total = Stream.of(x.subList(0, size / 2),
|
||||
x.subList(size / 2, size))
|
||||
.mapToInt(subList -> {
|
||||
int sum = 0;
|
||||
Integer[] a = new Integer[subList.size()];
|
||||
for (Object o : subList.toArray(a))
|
||||
sum += (Integer) o;
|
||||
return sum; })
|
||||
.sum();
|
||||
check.sum(total);}}},
|
||||
new Job(klazz + " subList toArray(empty)") {
|
||||
int sum = 0;
|
||||
ListIterator<Integer> it = x.listIterator(x.size());
|
||||
while (it.hasPrevious())
|
||||
sum += it.previous();
|
||||
check.sum(sum);}}},
|
||||
new Job(klazz + " indexOf") {
|
||||
public void work() throws Throwable {
|
||||
int size = x.size();
|
||||
Integer[] empty = new Integer[0];
|
||||
int[] sum = new int[1];
|
||||
Object sneakyAdder = sneakyAdder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
int total = Stream.of(x.subList(0, size / 2),
|
||||
x.subList(size / 2, size))
|
||||
.mapToInt(subList -> {
|
||||
int sum = 0;
|
||||
for (Object o : subList.toArray(empty))
|
||||
sum += (Integer) o;
|
||||
return sum; })
|
||||
.sum();
|
||||
check.sum(total);}}});
|
||||
sum[0] = 0;
|
||||
if (x.indexOf(sneakyAdder) != -1)
|
||||
throw new AssertionError();
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(klazz + " lastIndexOf") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
Object sneakyAdder = sneakyAdder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
if (x.lastIndexOf(sneakyAdder) != -1)
|
||||
throw new AssertionError();
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(klazz + " replaceAll") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
UnaryOperator<Integer> sneakyAdder =
|
||||
x -> { sum[0] += x; return x; };
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.replaceAll(sneakyAdder);
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
* @run main RemoveMicroBenchmark iterations=1 size=8 warmup=0
|
||||
*/
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static java.util.stream.Collectors.toCollection;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayDeque;
|
||||
@ -35,6 +35,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -47,6 +48,7 @@ import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@ -55,7 +57,7 @@ import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Usage: [iterations=N] [size=N] [filter=REGEXP] [warmup=SECONDS]
|
||||
@ -72,25 +74,38 @@ public class RemoveMicroBenchmark {
|
||||
public Job(String name) { this.name = name; }
|
||||
public String name() { return name; }
|
||||
public abstract void work() throws Throwable;
|
||||
public void run() {
|
||||
try { work(); }
|
||||
catch (Throwable ex) {
|
||||
// current job cannot always be deduced from stacktrace.
|
||||
throw new RuntimeException("Job failed: " + name(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int iterations;
|
||||
final int size; // number of elements in collections
|
||||
final double warmupSeconds;
|
||||
final long warmupNanos;
|
||||
final Pattern filter; // select subset of Jobs to run
|
||||
final Pattern nameFilter; // select subset of Jobs to run
|
||||
final boolean reverse; // reverse order of Jobs
|
||||
final boolean shuffle; // randomize order of Jobs
|
||||
|
||||
final ArrayList<Integer> elements; // contains size random Integers
|
||||
|
||||
RemoveMicroBenchmark(String[] args) {
|
||||
iterations = intArg(args, "iterations", 10_000);
|
||||
size = intArg(args, "size", 1000);
|
||||
warmupSeconds = doubleArg(args, "warmup", 7.0);
|
||||
filter = patternArg(args, "filter");
|
||||
nameFilter = patternArg(args, "filter");
|
||||
reverse = booleanArg(args, "reverse");
|
||||
shuffle = booleanArg(args, "shuffle");
|
||||
|
||||
warmupNanos = (long) (warmupSeconds * (1000L * 1000L * 1000L));
|
||||
|
||||
elements = ThreadLocalRandom.current().ints(size)
|
||||
.mapToObj(x -> x)
|
||||
.collect(toCollection(ArrayList::new));
|
||||
}
|
||||
|
||||
// --------------- GC finalization infrastructure ---------------
|
||||
@ -99,6 +114,7 @@ public class RemoveMicroBenchmark {
|
||||
static void forceFullGc() {
|
||||
CountDownLatch finalizeDone = new CountDownLatch(1);
|
||||
WeakReference<?> ref = new WeakReference<Object>(new Object() {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void finalize() { finalizeDone.countDown(); }});
|
||||
try {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@ -120,7 +136,7 @@ public class RemoveMicroBenchmark {
|
||||
* compiling everything worth compiling.
|
||||
* Returns array of average times per job per run.
|
||||
*/
|
||||
long[] time0(List<Job> jobs) throws Throwable {
|
||||
long[] time0(List<Job> jobs) {
|
||||
final int size = jobs.size();
|
||||
long[] nanoss = new long[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
@ -129,7 +145,7 @@ public class RemoveMicroBenchmark {
|
||||
long totalTime;
|
||||
int runs = 0;
|
||||
long startTime = System.nanoTime();
|
||||
do { job.work(); runs++; }
|
||||
do { job.run(); runs++; }
|
||||
while ((totalTime = System.nanoTime() - startTime) < warmupNanos);
|
||||
nanoss[i] = totalTime/runs;
|
||||
}
|
||||
@ -203,22 +219,11 @@ public class RemoveMicroBenchmark {
|
||||
throw new IllegalArgumentException(val);
|
||||
}
|
||||
|
||||
private static List<Job> filter(Pattern filter, List<Job> jobs) {
|
||||
return (filter == null) ? jobs
|
||||
: jobs.stream()
|
||||
.filter(job -> filter.matcher(job.name()).find())
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
private static void deoptimize(int sum) {
|
||||
if (sum == 42)
|
||||
System.out.println("the answer");
|
||||
}
|
||||
|
||||
private static <T> List<T> asSubList(List<T> list) {
|
||||
return list.subList(0, list.size());
|
||||
}
|
||||
|
||||
private static <T> Iterable<T> backwards(final List<T> list) {
|
||||
return new Iterable<T>() {
|
||||
public Iterator<T> iterator() {
|
||||
@ -245,66 +250,99 @@ public class RemoveMicroBenchmark {
|
||||
new RemoveMicroBenchmark(args).run();
|
||||
}
|
||||
|
||||
void run() throws Throwable {
|
||||
// System.out.printf(
|
||||
// "iterations=%d size=%d, warmup=%1g, filter=\"%s\"%n",
|
||||
// iterations, size, warmupSeconds, filter);
|
||||
HashMap<Class<?>, String> goodClassName = new HashMap<>();
|
||||
|
||||
final ArrayList<Integer> al = new ArrayList<>(size);
|
||||
String goodClassName(Class<?> klazz) {
|
||||
return goodClassName.computeIfAbsent(
|
||||
klazz,
|
||||
k -> {
|
||||
String simple = k.getSimpleName();
|
||||
return (simple.equals("SubList")) // too simple!
|
||||
? k.getName().replaceFirst(".*\\.", "")
|
||||
: simple;
|
||||
});
|
||||
}
|
||||
|
||||
// Populate collections with random data
|
||||
static List<Integer> makeSubList(List<Integer> list) {
|
||||
final ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
for (int i = 0; i < size; i++)
|
||||
al.add(rnd.nextInt(size));
|
||||
int size = rnd.nextInt(4);
|
||||
for (int i = size; i--> 0; )
|
||||
list.add(rnd.nextInt());
|
||||
int index = rnd.nextInt(size + 1);
|
||||
return list.subList(index, index);
|
||||
}
|
||||
|
||||
ArrayList<Job> jobs = new ArrayList<>();
|
||||
private static <T> List<T> asSubList(List<T> list) {
|
||||
return list.subList(0, list.size());
|
||||
}
|
||||
|
||||
List.<Collection<Integer>>of(
|
||||
new ArrayList<>(),
|
||||
new LinkedList<>(),
|
||||
new Vector<>(),
|
||||
new ArrayDeque<>(),
|
||||
new PriorityQueue<>(),
|
||||
new ArrayBlockingQueue<>(al.size()),
|
||||
new ConcurrentLinkedQueue<>(),
|
||||
new ConcurrentLinkedDeque<>(),
|
||||
new LinkedBlockingQueue<>(),
|
||||
new LinkedBlockingDeque<>(),
|
||||
new LinkedTransferQueue<>(),
|
||||
new PriorityBlockingQueue<>()).forEach(
|
||||
x -> {
|
||||
String klazz = x.getClass().getSimpleName();
|
||||
jobs.addAll(collectionJobs(klazz, () -> x, al));
|
||||
if (x instanceof Queue) {
|
||||
Queue<Integer> queue = (Queue<Integer>) x;
|
||||
jobs.addAll(queueJobs(klazz, () -> queue, al));
|
||||
}
|
||||
if (x instanceof Deque) {
|
||||
Deque<Integer> deque = (Deque<Integer>) x;
|
||||
jobs.addAll(dequeJobs(klazz, () -> deque, al));
|
||||
}
|
||||
if (x instanceof BlockingQueue) {
|
||||
BlockingQueue<Integer> q = (BlockingQueue<Integer>) x;
|
||||
jobs.addAll(blockingQueueJobs(klazz, () -> q, al));
|
||||
}
|
||||
if (x instanceof BlockingDeque) {
|
||||
BlockingDeque<Integer> q = (BlockingDeque<Integer>) x;
|
||||
jobs.addAll(blockingDequeJobs(klazz, () -> q, al));
|
||||
}
|
||||
if (x instanceof List) {
|
||||
List<Integer> list = (List<Integer>) x;
|
||||
jobs.addAll(
|
||||
collectionJobs(
|
||||
klazz + " subList",
|
||||
() -> list.subList(0, x.size()),
|
||||
al));
|
||||
}
|
||||
});
|
||||
@SafeVarargs @SuppressWarnings("varargs")
|
||||
private <T> Stream<T> concatStreams(Stream<T> ... streams) {
|
||||
return Stream.of(streams).flatMap(s -> s);
|
||||
}
|
||||
|
||||
Class<?> topLevelClass(Object x) {
|
||||
for (Class<?> k = x.getClass();; ) {
|
||||
Class<?> enclosing = k.getEnclosingClass();
|
||||
if (enclosing == null)
|
||||
return k;
|
||||
k = enclosing;
|
||||
}
|
||||
}
|
||||
|
||||
void run() throws Throwable {
|
||||
ArrayList<Job> jobs = Stream.<Collection<Integer>>of(
|
||||
new ArrayList<>(),
|
||||
makeSubList(new ArrayList<>()),
|
||||
new LinkedList<>(),
|
||||
makeSubList(new LinkedList<>()),
|
||||
new Vector<>(),
|
||||
makeSubList(new Vector<>()),
|
||||
new CopyOnWriteArrayList<>(),
|
||||
makeSubList(new CopyOnWriteArrayList<>()),
|
||||
new ArrayDeque<>(),
|
||||
new PriorityQueue<>(),
|
||||
new ArrayBlockingQueue<>(elements.size()),
|
||||
new ConcurrentLinkedQueue<>(),
|
||||
new ConcurrentLinkedDeque<>(),
|
||||
new LinkedBlockingQueue<>(),
|
||||
new LinkedBlockingDeque<>(),
|
||||
new LinkedTransferQueue<>(),
|
||||
new PriorityBlockingQueue<>())
|
||||
.flatMap(x -> jobs(x))
|
||||
.filter(job ->
|
||||
nameFilter == null || nameFilter.matcher(job.name()).find())
|
||||
.collect(toCollection(ArrayList::new));
|
||||
|
||||
if (reverse) Collections.reverse(jobs);
|
||||
if (shuffle) Collections.shuffle(jobs);
|
||||
|
||||
time(filter(filter, jobs));
|
||||
time(jobs);
|
||||
}
|
||||
|
||||
Stream<Job> jobs(Collection<Integer> x) {
|
||||
return concatStreams(
|
||||
collectionJobs(x),
|
||||
|
||||
(CopyOnWriteArrayList.class.isAssignableFrom(topLevelClass(x)))
|
||||
? Stream.empty()
|
||||
: iteratorRemoveJobs(x),
|
||||
|
||||
(x instanceof Queue)
|
||||
? queueJobs((Queue<Integer>)x)
|
||||
: Stream.empty(),
|
||||
|
||||
(x instanceof Deque)
|
||||
? dequeJobs((Deque<Integer>)x)
|
||||
: Stream.empty(),
|
||||
|
||||
(x instanceof BlockingQueue)
|
||||
? blockingQueueJobs((BlockingQueue<Integer>)x)
|
||||
: Stream.empty(),
|
||||
|
||||
(x instanceof BlockingDeque)
|
||||
? blockingDequeJobs((BlockingDeque<Integer>)x)
|
||||
: Stream.empty());
|
||||
}
|
||||
|
||||
Collection<Integer> universeRecorder(int[] sum) {
|
||||
@ -323,75 +361,81 @@ public class RemoveMicroBenchmark {
|
||||
}};
|
||||
}
|
||||
|
||||
List<Job> collectionJobs(
|
||||
String description,
|
||||
Supplier<Collection<Integer>> supplier,
|
||||
ArrayList<Integer> al) {
|
||||
return List.of(
|
||||
new Job(description + " removeIf") {
|
||||
Stream<Job> collectionJobs(Collection<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " removeIf") {
|
||||
public void work() throws Throwable {
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.removeIf(n -> { sum[0] += n; return true; });
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " removeIf rnd-two-pass") {
|
||||
new Job(klazz + " removeIf rnd-two-pass") {
|
||||
public void work() throws Throwable {
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.removeIf(n -> {
|
||||
boolean b = rnd.nextBoolean();
|
||||
if (b) sum[0] += n;
|
||||
return b; });
|
||||
x.removeIf(n -> { sum[0] += n; return true; });
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " removeAll") {
|
||||
new Job(klazz + " removeAll") {
|
||||
public void work() throws Throwable {
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
Collection<Integer> universe = universeRecorder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.removeAll(universe);
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " retainAll") {
|
||||
new Job(klazz + " retainAll") {
|
||||
public void work() throws Throwable {
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
Collection<Integer> empty = emptyRecorder(sum);
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.retainAll(empty);
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " Iterator.remove") {
|
||||
new Job(klazz + " clear") {
|
||||
public void work() throws Throwable {
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.forEach(e -> sum[0] += e);
|
||||
x.clear();
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
|
||||
Stream<Job> iteratorRemoveJobs(Collection<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " Iterator.remove") {
|
||||
public void work() throws Throwable {
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(elements);
|
||||
Iterator<Integer> it = x.iterator();
|
||||
while (it.hasNext()) {
|
||||
sum[0] += it.next();
|
||||
it.remove();
|
||||
}
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " Iterator.remove-rnd-two-pass") {
|
||||
new Job(klazz + " Iterator.remove-rnd-two-pass") {
|
||||
public void work() throws Throwable {
|
||||
ThreadLocalRandom rnd = ThreadLocalRandom.current();
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Iterator<Integer> it = x.iterator();
|
||||
it.hasNext(); ) {
|
||||
Integer e = it.next();
|
||||
@ -405,129 +449,103 @@ public class RemoveMicroBenchmark {
|
||||
sum[0] += it.next();
|
||||
it.remove();
|
||||
}
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " clear") {
|
||||
public void work() throws Throwable {
|
||||
Collection<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.forEach(e -> sum[0] += e);
|
||||
x.clear();
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
|
||||
List<Job> queueJobs(
|
||||
String description,
|
||||
Supplier<Queue<Integer>> supplier,
|
||||
ArrayList<Integer> al) {
|
||||
return List.of(
|
||||
new Job(description + " poll()") {
|
||||
Stream<Job> queueJobs(Queue<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " poll()") {
|
||||
public void work() throws Throwable {
|
||||
Queue<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Integer e; (e = x.poll()) != null; )
|
||||
sum[0] += e;
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
|
||||
List<Job> dequeJobs(
|
||||
String description,
|
||||
Supplier<Deque<Integer>> supplier,
|
||||
ArrayList<Integer> al) {
|
||||
return List.of(
|
||||
new Job(description + " descendingIterator().remove") {
|
||||
Stream<Job> dequeJobs(Deque<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " descendingIterator().remove") {
|
||||
public void work() throws Throwable {
|
||||
Deque<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
Iterator<Integer> it = x.descendingIterator();
|
||||
while (it.hasNext()) {
|
||||
sum[0] += it.next();
|
||||
it.remove();
|
||||
}
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " pollFirst()") {
|
||||
new Job(klazz + " pollFirst()") {
|
||||
public void work() throws Throwable {
|
||||
Deque<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Integer e; (e = x.pollFirst()) != null; )
|
||||
sum[0] += e;
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " pollLast()") {
|
||||
new Job(klazz + " pollLast()") {
|
||||
public void work() throws Throwable {
|
||||
Deque<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Integer e; (e = x.pollLast()) != null; )
|
||||
sum[0] += e;
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
|
||||
List<Job> blockingQueueJobs(
|
||||
String description,
|
||||
Supplier<BlockingQueue<Integer>> supplier,
|
||||
ArrayList<Integer> al) {
|
||||
return List.of(
|
||||
new Job(description + " drainTo(sink)") {
|
||||
Stream<Job> blockingQueueJobs(BlockingQueue<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " drainTo(sink)") {
|
||||
public void work() throws Throwable {
|
||||
BlockingQueue<Integer> x = supplier.get();
|
||||
ArrayList<Integer> sink = new ArrayList<>();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
sink.clear();
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
x.drainTo(sink);
|
||||
sink.forEach(e -> sum[0] += e);
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " drainTo(sink, n)") {
|
||||
new Job(klazz + " drainTo(sink, n)") {
|
||||
public void work() throws Throwable {
|
||||
BlockingQueue<Integer> x = supplier.get();
|
||||
ArrayList<Integer> sink = new ArrayList<>();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
sink.clear();
|
||||
x.addAll(al);
|
||||
x.drainTo(sink, al.size());
|
||||
x.addAll(elements);
|
||||
x.drainTo(sink, elements.size());
|
||||
sink.forEach(e -> sum[0] += e);
|
||||
check.sum(sum[0]);}}});
|
||||
}
|
||||
|
||||
List<Job> blockingDequeJobs(
|
||||
String description,
|
||||
Supplier<BlockingDeque<Integer>> supplier,
|
||||
ArrayList<Integer> al) {
|
||||
return List.of(
|
||||
new Job(description + " timed pollFirst()") {
|
||||
Stream<Job> blockingDequeJobs(BlockingDeque<Integer> x) {
|
||||
final String klazz = goodClassName(x.getClass());
|
||||
return Stream.of(
|
||||
new Job(klazz + " timed pollFirst()") {
|
||||
public void work() throws Throwable {
|
||||
BlockingDeque<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Integer e; (e = x.pollFirst(0L, TimeUnit.DAYS)) != null; )
|
||||
sum[0] += e;
|
||||
check.sum(sum[0]);}}},
|
||||
new Job(description + " timed pollLast()") {
|
||||
new Job(klazz + " timed pollLast()") {
|
||||
public void work() throws Throwable {
|
||||
BlockingDeque<Integer> x = supplier.get();
|
||||
int[] sum = new int[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
sum[0] = 0;
|
||||
x.addAll(al);
|
||||
x.addAll(elements);
|
||||
for (Integer e; (e = x.pollLast(0L, TimeUnit.DAYS)) != null; )
|
||||
sum[0] += e;
|
||||
check.sum(sum[0]);}}});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user