Merge
This commit is contained in:
commit
e4ed1ab3d7
1
.hgtags
1
.hgtags
@ -380,3 +380,4 @@ a71210c0d9800eb6925b61ecd6198abd554f90ee jdk-9+134
|
||||
e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135
|
||||
1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136
|
||||
9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137
|
||||
d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138
|
||||
|
@ -380,3 +380,4 @@ be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
|
||||
82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
|
||||
3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136
|
||||
d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137
|
||||
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
|
||||
|
@ -33,6 +33,7 @@ include @SPEC@
|
||||
CC := @BUILD_CC@
|
||||
CXX := @BUILD_CXX@
|
||||
LD := @BUILD_LD@
|
||||
LDCXX := @BUILD_LDCXX@
|
||||
AS := @BUILD_AS@
|
||||
NM := @BUILD_NM@
|
||||
AR := @BUILD_AR@
|
||||
|
@ -687,7 +687,6 @@ XMKMF
|
||||
MSVCP_DLL
|
||||
MSVCR_DLL
|
||||
LIBCXX
|
||||
STATIC_CXX_SETTING
|
||||
FIXPATH_DETACH_FLAG
|
||||
FIXPATH
|
||||
BUILD_GTEST
|
||||
@ -5092,7 +5091,7 @@ VS_SDK_PLATFORM_NAME_2013=
|
||||
#CUSTOM_AUTOCONF_INCLUDE
|
||||
|
||||
# Do not change or remove the following line, it is needed for consistency checks:
|
||||
DATE_WHEN_GENERATED=1474894604
|
||||
DATE_WHEN_GENERATED=1475218974
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
@ -53087,49 +53086,10 @@ fi
|
||||
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
# Test if -lstdc++ works.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if dynamic link of stdc++ is possible" >&5
|
||||
$as_echo_n "checking if dynamic link of stdc++ is possible... " >&6; }
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
OLD_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS -lstdc++"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
has_dynamic_libstdcxx=yes
|
||||
else
|
||||
has_dynamic_libstdcxx=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
CXXFLAGS="$OLD_CXXFLAGS"
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_dynamic_libstdcxx" >&5
|
||||
$as_echo "$has_dynamic_libstdcxx" >&6; }
|
||||
|
||||
# Test if stdc++ can be linked statically.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if static link of stdc++ is possible" >&5
|
||||
$as_echo_n "checking if static link of stdc++ is possible... " >&6; }
|
||||
STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic"
|
||||
STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc"
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
@ -53137,9 +53097,7 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
|
||||
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
|
||||
OLD_LIBS="$LIBS"
|
||||
OLD_CXX="$CXX"
|
||||
LIBS="$STATIC_STDCXX_FLAGS"
|
||||
CXX="$CC"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
@ -53159,7 +53117,6 @@ fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS="$OLD_LIBS"
|
||||
CXX="$OLD_CXX"
|
||||
ac_ext=cpp
|
||||
ac_cpp='$CXXCPP $CPPFLAGS'
|
||||
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
@ -53169,59 +53126,34 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_static_libstdcxx" >&5
|
||||
$as_echo "$has_static_libstdcxx" >&6; }
|
||||
|
||||
if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
|
||||
as_fn_error $? "Cannot link to stdc++, neither dynamically nor statically!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
|
||||
as_fn_error $? "Static linking of libstdc++ was not possible!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
|
||||
as_fn_error $? "Dynamic linking of libstdc++ was not possible!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
# If dynamic was requested, it's available since it would fail above otherwise.
|
||||
# If dynamic wasn't requested, go with static unless it isn't available.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libstdc++" >&5
|
||||
$as_echo_n "checking how to link with libstdc++... " >&6; }
|
||||
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
|
||||
LIBCXX="$LIBCXX -lstdc++"
|
||||
# To help comparisons with old build, put stdc++ first in JVM_LIBS
|
||||
JVM_LIBS="-lstdc++ $JVM_LIBS"
|
||||
# Ideally, we should test stdc++ for the BUILD toolchain separately. For now
|
||||
# just use the same setting as for the TARGET toolchain.
|
||||
OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
|
||||
LDCXX="$CXX"
|
||||
STATIC_CXX_SETTING="STATIC_CXX=false"
|
||||
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
|
||||
|| [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: dynamic" >&5
|
||||
$as_echo "dynamic" >&6; }
|
||||
else
|
||||
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
|
||||
JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
|
||||
# To help comparisons with old build, put stdc++ first in JVM_LIBS
|
||||
JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
|
||||
JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
# Ideally, we should test stdc++ for the BUILD toolchain separately. For now
|
||||
# just use the same setting as for the TARGET toolchain.
|
||||
OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
|
||||
OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
|
||||
LDCXX="$CC"
|
||||
STATIC_CXX_SETTING="STATIC_CXX=true"
|
||||
OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
|
||||
$as_echo "static" >&6; }
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so)
|
||||
if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then
|
||||
LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
|
||||
fi
|
||||
|
||||
# TODO better (platform agnostic) test
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
LIBCXX="-lstdc++"
|
||||
fi
|
||||
|
||||
|
||||
# Setup Windows runtime dlls
|
||||
|
@ -45,84 +45,44 @@ AC_DEFUN_ONCE([LIB_SETUP_STD_LIBS],
|
||||
)
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
# Test if -lstdc++ works.
|
||||
AC_MSG_CHECKING([if dynamic link of stdc++ is possible])
|
||||
AC_LANG_PUSH(C++)
|
||||
OLD_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS -lstdc++"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
|
||||
[has_dynamic_libstdcxx=yes],
|
||||
[has_dynamic_libstdcxx=no])
|
||||
CXXFLAGS="$OLD_CXXFLAGS"
|
||||
AC_LANG_POP(C++)
|
||||
AC_MSG_RESULT([$has_dynamic_libstdcxx])
|
||||
|
||||
# Test if stdc++ can be linked statically.
|
||||
AC_MSG_CHECKING([if static link of stdc++ is possible])
|
||||
STATIC_STDCXX_FLAGS="-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic"
|
||||
STATIC_STDCXX_FLAGS="-static-libstdc++ -static-libgcc"
|
||||
AC_LANG_PUSH(C++)
|
||||
OLD_LIBS="$LIBS"
|
||||
OLD_CXX="$CXX"
|
||||
LIBS="$STATIC_STDCXX_FLAGS"
|
||||
CXX="$CC"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
|
||||
[has_static_libstdcxx=yes],
|
||||
[has_static_libstdcxx=no])
|
||||
LIBS="$OLD_LIBS"
|
||||
CXX="$OLD_CXX"
|
||||
AC_LANG_POP(C++)
|
||||
AC_MSG_RESULT([$has_static_libstdcxx])
|
||||
|
||||
if test "x$has_static_libstdcxx" = xno && test "x$has_dynamic_libstdcxx" = xno; then
|
||||
AC_MSG_ERROR([Cannot link to stdc++, neither dynamically nor statically!])
|
||||
fi
|
||||
|
||||
if test "x$with_stdc__lib" = xstatic && test "x$has_static_libstdcxx" = xno; then
|
||||
AC_MSG_ERROR([Static linking of libstdc++ was not possible!])
|
||||
fi
|
||||
|
||||
if test "x$with_stdc__lib" = xdynamic && test "x$has_dynamic_libstdcxx" = xno; then
|
||||
AC_MSG_ERROR([Dynamic linking of libstdc++ was not possible!])
|
||||
fi
|
||||
|
||||
# If dynamic was requested, it's available since it would fail above otherwise.
|
||||
# If dynamic wasn't requested, go with static unless it isn't available.
|
||||
AC_MSG_CHECKING([how to link with libstdc++])
|
||||
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
|
||||
LIBCXX="$LIBCXX -lstdc++"
|
||||
# To help comparisons with old build, put stdc++ first in JVM_LIBS
|
||||
JVM_LIBS="-lstdc++ $JVM_LIBS"
|
||||
# Ideally, we should test stdc++ for the BUILD toolchain separately. For now
|
||||
# just use the same setting as for the TARGET toolchain.
|
||||
OPENJDK_BUILD_JVM_LIBS="-lstdc++ $OPENJDK_BUILD_JVM_LIBS"
|
||||
LDCXX="$CXX"
|
||||
STATIC_CXX_SETTING="STATIC_CXX=false"
|
||||
if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
|
||||
|| HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
|
||||
AC_MSG_RESULT([dynamic])
|
||||
else
|
||||
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
|
||||
JVM_LDFLAGS="$JVM_LDFLAGS -static-libgcc"
|
||||
# To help comparisons with old build, put stdc++ first in JVM_LIBS
|
||||
JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $JVM_LIBS"
|
||||
JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
# Ideally, we should test stdc++ for the BUILD toolchain separately. For now
|
||||
# just use the same setting as for the TARGET toolchain.
|
||||
OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS -static-libgcc"
|
||||
OPENJDK_BUILD_JVM_LIBS="-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic $OPENJDK_BUILD_JVM_LIBS"
|
||||
LDCXX="$CC"
|
||||
STATIC_CXX_SETTING="STATIC_CXX=true"
|
||||
OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
AC_MSG_RESULT([static])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(STATIC_CXX_SETTING)
|
||||
|
||||
# libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so)
|
||||
if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then
|
||||
LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
|
||||
fi
|
||||
|
||||
# TODO better (platform agnostic) test
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx && test "x$LIBCXX" = x && test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
LIBCXX="-lstdc++"
|
||||
fi
|
||||
AC_SUBST(LIBCXX)
|
||||
|
||||
# Setup Windows runtime dlls
|
||||
|
@ -380,3 +380,4 @@ f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
|
||||
094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
|
||||
aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136
|
||||
258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137
|
||||
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
|
||||
|
@ -38,7 +38,7 @@ $(eval $(call SetupJavaCompilation,BUILD_TOOLS_CORBA, \
|
||||
SRC := $(CORBA_TOPDIR)/make/src/classes, \
|
||||
BIN := $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes))
|
||||
|
||||
TOOL_LOGUTIL_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes \
|
||||
TOOL_LOGUTIL_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/corba_tools_classes \
|
||||
build.tools.logutil.MC
|
||||
|
||||
$(eval $(call SetupJavaCompilation,BUILD_IDLJ, \
|
||||
@ -50,7 +50,7 @@ $(eval $(call SetupJavaCompilation,BUILD_IDLJ, \
|
||||
EXCLUDE_FILES := ResourceBundleUtil.java module-info.java))
|
||||
|
||||
# Force the language to english for predictable source code generation.
|
||||
TOOL_IDLJ_CMD := $(JAVA) -cp $(BUILDTOOLS_OUTPUTDIR)/idlj_classes \
|
||||
TOOL_IDLJ_CMD := $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/idlj_classes \
|
||||
-Duser.language=en com.sun.tools.corba.se.idl.toJavaPortable.Compile
|
||||
|
||||
################################################################################
|
||||
|
@ -540,3 +540,4 @@ b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
|
||||
3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
|
||||
a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
|
||||
dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
|
||||
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
|
||||
|
@ -55,7 +55,7 @@ endif
|
||||
# Disabling switch warning for clang because of test source.
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
||||
TOOLCHAIN := $(JVM_TOOLCHAIN), \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
LIBRARY := jvm, \
|
||||
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
|
||||
OBJECT_DIR := $(JVM_OUTPUTDIR)/gtest/objs, \
|
||||
@ -95,7 +95,7 @@ TARGETS += $(BUILD_GTEST_LIBJVM)
|
||||
################################################################################
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \
|
||||
TOOLCHAIN := $(JVM_TOOLCHAIN), \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
PROGRAM := gtestLauncher, \
|
||||
OUTPUT_DIR := $(JVM_OUTPUTDIR)/gtest, \
|
||||
EXTRA_FILES := $(GTEST_LAUNCHER_SRC), \
|
||||
|
@ -143,13 +143,6 @@ ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), )
|
||||
JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
endif
|
||||
|
||||
ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), )
|
||||
# On macosx, aix and solaris we have to link with the C++ compiler
|
||||
JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX
|
||||
else
|
||||
JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT
|
||||
endif
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_CPU), x86)
|
||||
JVM_EXCLUDE_PATTERNS += x86_64
|
||||
else ifeq ($(OPENJDK_TARGET_CPU), x86_64)
|
||||
@ -194,7 +187,7 @@ JVM_OPTIMIZATION ?= HIGHEST_JVM
|
||||
# Now set up the actual compilation of the main hotspot native library
|
||||
|
||||
$(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
|
||||
TOOLCHAIN := $(JVM_TOOLCHAIN), \
|
||||
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
|
||||
LIBRARY := jvm, \
|
||||
OUTPUT_DIR := $(JVM_OUTPUTDIR), \
|
||||
SRC := $(JVM_SRC_DIRS), \
|
||||
|
@ -68,6 +68,7 @@ public class InstanceKlass extends Klass {
|
||||
Type type = db.lookupType("InstanceKlass");
|
||||
arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
|
||||
methods = type.getAddressField("_methods");
|
||||
defaultMethods = type.getAddressField("_default_methods");
|
||||
methodOrdering = type.getAddressField("_method_ordering");
|
||||
localInterfaces = type.getAddressField("_local_interfaces");
|
||||
transitiveInterfaces = type.getAddressField("_transitive_interfaces");
|
||||
@ -128,6 +129,7 @@ public class InstanceKlass extends Klass {
|
||||
|
||||
private static MetadataField arrayKlasses;
|
||||
private static AddressField methods;
|
||||
private static AddressField defaultMethods;
|
||||
private static AddressField methodOrdering;
|
||||
private static AddressField localInterfaces;
|
||||
private static AddressField transitiveInterfaces;
|
||||
@ -335,6 +337,20 @@ public class InstanceKlass extends Klass {
|
||||
// Accessors for declared fields
|
||||
public Klass getArrayKlasses() { return (Klass) arrayKlasses.getValue(this); }
|
||||
public MethodArray getMethods() { return new MethodArray(methods.getValue(getAddress())); }
|
||||
|
||||
public MethodArray getDefaultMethods() {
|
||||
if (defaultMethods != null) {
|
||||
Address addr = defaultMethods.getValue(getAddress());
|
||||
if ((addr != null) && (addr.getAddressAt(0) != null)) {
|
||||
return new MethodArray(addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public KlassArray getLocalInterfaces() { return new KlassArray(localInterfaces.getValue(getAddress())); }
|
||||
public KlassArray getTransitiveInterfaces() { return new KlassArray(transitiveInterfaces.getValue(getAddress())); }
|
||||
public int getJavaFieldsCount() { return (int) javaFieldsCount.getValue(this); }
|
||||
|
@ -1358,7 +1358,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
|
||||
if (!Universe::is_module_initialized() &&
|
||||
!ModuleEntryTable::javabase_defined() &&
|
||||
mod_entry == NULL) {
|
||||
mod_entry = ModuleEntryTable::javabase_module();
|
||||
mod_entry = ModuleEntryTable::javabase_moduleEntry();
|
||||
}
|
||||
|
||||
// The module must be a named module
|
||||
@ -1708,7 +1708,7 @@ void ClassLoader::create_javabase() {
|
||||
if (jb_module == NULL) {
|
||||
vm_exit_during_initialization("Unable to create ModuleEntry for java.base");
|
||||
}
|
||||
ModuleEntryTable::set_javabase_module(jb_module);
|
||||
ModuleEntryTable::set_javabase_moduleEntry(jb_module);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,6 +773,41 @@ void java_lang_Class::initialize_mirror_fields(KlassHandle k,
|
||||
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK);
|
||||
}
|
||||
|
||||
// Set the java.lang.reflect.Module module field in the java_lang_Class mirror
|
||||
void java_lang_Class::set_mirror_module_field(KlassHandle k, Handle mirror, Handle module, TRAPS) {
|
||||
if (module.is_null()) {
|
||||
// During startup, the module may be NULL only if java.base has not been defined yet.
|
||||
// Put the class on the fixup_module_list to patch later when the java.lang.reflect.Module
|
||||
// for java.base is known.
|
||||
assert(!Universe::is_module_initialized(), "Incorrect java.lang.reflect.Module pre module system initialization");
|
||||
MutexLocker m1(Module_lock, THREAD);
|
||||
// Keep list of classes needing java.base module fixup
|
||||
if (!ModuleEntryTable::javabase_defined()) {
|
||||
if (fixup_module_field_list() == NULL) {
|
||||
GrowableArray<Klass*>* list =
|
||||
new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
|
||||
set_fixup_module_field_list(list);
|
||||
}
|
||||
k->class_loader_data()->inc_keep_alive();
|
||||
fixup_module_field_list()->push(k());
|
||||
} else {
|
||||
// java.base was defined at some point between calling create_mirror()
|
||||
// and obtaining the Module_lock, patch this particular class with java.base.
|
||||
ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
|
||||
assert(javabase_entry != NULL && javabase_entry->module() != NULL,
|
||||
"Setting class module field, java.base should be defined");
|
||||
Handle javabase_handle(THREAD, JNIHandles::resolve(javabase_entry->module()));
|
||||
set_module(mirror(), javabase_handle());
|
||||
}
|
||||
} else {
|
||||
assert(Universe::is_module_initialized() ||
|
||||
(ModuleEntryTable::javabase_defined() &&
|
||||
(module() == JNIHandles::resolve(ModuleEntryTable::javabase_moduleEntry()->module()))),
|
||||
"Incorrect java.lang.reflect.Module specification while creating mirror");
|
||||
set_module(mirror(), module());
|
||||
}
|
||||
}
|
||||
|
||||
void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
Handle module, Handle protection_domain, TRAPS) {
|
||||
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
||||
@ -835,25 +870,13 @@ void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader,
|
||||
set_class_loader(mirror(), class_loader());
|
||||
|
||||
// set the module field in the java_lang_Class instance
|
||||
// This may be null during bootstrap but will get fixed up later on.
|
||||
set_module(mirror(), module());
|
||||
set_mirror_module_field(k, mirror, module, THREAD);
|
||||
|
||||
// Setup indirection from klass->mirror last
|
||||
// after any exceptions can happen during allocations.
|
||||
if (!k.is_null()) {
|
||||
k->set_java_mirror(mirror());
|
||||
}
|
||||
|
||||
// Keep list of classes needing java.base module fixup.
|
||||
if (!ModuleEntryTable::javabase_defined()) {
|
||||
if (fixup_module_field_list() == NULL) {
|
||||
GrowableArray<Klass*>* list =
|
||||
new (ResourceObj::C_HEAP, mtModule) GrowableArray<Klass*>(500, true);
|
||||
set_fixup_module_field_list(list);
|
||||
}
|
||||
k->class_loader_data()->inc_keep_alive();
|
||||
fixup_module_field_list()->push(k());
|
||||
}
|
||||
} else {
|
||||
if (fixup_mirror_list() == NULL) {
|
||||
GrowableArray<Klass*>* list =
|
||||
|
@ -219,6 +219,7 @@ class java_lang_Class : AllStatic {
|
||||
static void set_class_loader(oop java_class, oop class_loader);
|
||||
static void set_component_mirror(oop java_class, oop comp_mirror);
|
||||
static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
|
||||
static void set_mirror_module_field(KlassHandle K, Handle mirror, Handle module, TRAPS);
|
||||
public:
|
||||
static void compute_offsets();
|
||||
|
||||
|
@ -25,12 +25,85 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classFileParser.hpp"
|
||||
#include "classfile/classFileStream.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/klassFactory.hpp"
|
||||
#include "classfile/sharedClassUtil.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "prims/jvmtiEnvBase.hpp"
|
||||
#include "prims/jvmtiRedefineClasses.hpp"
|
||||
#include "trace/traceMacros.hpp"
|
||||
|
||||
// called during initial loading of a shared class
|
||||
instanceKlassHandle KlassFactory::check_shared_class_file_load_hook(
|
||||
instanceKlassHandle ik,
|
||||
Symbol* class_name,
|
||||
Handle class_loader,
|
||||
Handle protection_domain, TRAPS) {
|
||||
#if INCLUDE_CDS && INCLUDE_JVMTI
|
||||
assert(ik.not_null(), "sanity");
|
||||
assert(ik()->is_shared(), "expecting a shared class");
|
||||
|
||||
if (JvmtiExport::should_post_class_file_load_hook()) {
|
||||
assert(THREAD->is_Java_thread(), "must be JavaThread");
|
||||
|
||||
// Post the CFLH
|
||||
JvmtiCachedClassFileData* cached_class_file = NULL;
|
||||
JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data();
|
||||
assert(archived_class_data != NULL, "shared class has no archived class data");
|
||||
unsigned char* ptr =
|
||||
VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data);
|
||||
unsigned char* end_ptr =
|
||||
ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data);
|
||||
unsigned char* old_ptr = ptr;
|
||||
JvmtiExport::post_class_file_load_hook(class_name,
|
||||
class_loader,
|
||||
protection_domain,
|
||||
&ptr,
|
||||
&end_ptr,
|
||||
&cached_class_file);
|
||||
if (old_ptr != ptr) {
|
||||
// JVMTI agent has modified class file data.
|
||||
// Set new class file stream using JVMTI agent modified class file data.
|
||||
ClassLoaderData* loader_data =
|
||||
ClassLoaderData::class_loader_data(class_loader());
|
||||
int path_index = ik->shared_classpath_index();
|
||||
SharedClassPathEntry* ent =
|
||||
(SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index);
|
||||
ClassFileStream* stream = new ClassFileStream(ptr,
|
||||
end_ptr - ptr,
|
||||
ent->_name,
|
||||
ClassFileStream::verify);
|
||||
ClassFileParser parser(stream,
|
||||
class_name,
|
||||
loader_data,
|
||||
protection_domain,
|
||||
NULL,
|
||||
NULL,
|
||||
ClassFileParser::BROADCAST, // publicity level
|
||||
CHECK_NULL);
|
||||
instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
|
||||
CHECK_NULL);
|
||||
if (cached_class_file != NULL) {
|
||||
new_ik->set_cached_class_file(cached_class_file);
|
||||
}
|
||||
|
||||
if (class_loader.is_null()) {
|
||||
ResourceMark rm;
|
||||
ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD);
|
||||
}
|
||||
|
||||
return new_ik;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
|
||||
Symbol* name,
|
||||
ClassLoaderData* loader_data,
|
||||
@ -97,7 +170,6 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||
const InstanceKlass* host_klass,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS) {
|
||||
|
||||
assert(stream != NULL, "invariant");
|
||||
assert(loader_data != NULL, "invariant");
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
@ -142,5 +214,27 @@ instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream,
|
||||
|
||||
TRACE_KLASS_CREATION(result, parser, THREAD);
|
||||
|
||||
#if INCLUDE_CDS && INCLUDE_JVMTI
|
||||
if (DumpSharedSpaces) {
|
||||
assert(cached_class_file == NULL, "Sanity");
|
||||
// Archive the class stream data into the optional data section
|
||||
JvmtiCachedClassFileData *p;
|
||||
int len;
|
||||
const unsigned char *bytes;
|
||||
// event based tracing might set cached_class_file
|
||||
if ((bytes = result->get_cached_class_file_bytes()) != NULL) {
|
||||
len = result->get_cached_class_file_len();
|
||||
} else {
|
||||
len = stream->length();
|
||||
bytes = stream->buffer();
|
||||
}
|
||||
p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc(
|
||||
offset_of(JvmtiCachedClassFileData, data) + len);
|
||||
p->length = len;
|
||||
memcpy(p->data, bytes, len);
|
||||
result->set_archived_class_data(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ class KlassFactory : AllStatic {
|
||||
const InstanceKlass* host_klass,
|
||||
GrowableArray<Handle>* cp_patches,
|
||||
TRAPS);
|
||||
public:
|
||||
static instanceKlassHandle check_shared_class_file_load_hook(
|
||||
instanceKlassHandle ik,
|
||||
Symbol* class_name,
|
||||
Handle class_loader,
|
||||
Handle protection_domain, TRAPS);
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_CLASSFILE_KLASSFACTORY_HPP
|
||||
|
@ -92,7 +92,7 @@ bool ModuleEntry::can_read(ModuleEntry* m) const {
|
||||
// read java.base. If either of these conditions
|
||||
// hold, readability has been established.
|
||||
if (!this->is_named() ||
|
||||
(m == ModuleEntryTable::javabase_module())) {
|
||||
(m == ModuleEntryTable::javabase_moduleEntry())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -358,16 +358,27 @@ void ModuleEntryTable::finalize_javabase(Handle module_handle, Symbol* version,
|
||||
}
|
||||
|
||||
// Set java.lang.reflect.Module, version and location for java.base
|
||||
ModuleEntry* jb_module = javabase_module();
|
||||
ModuleEntry* jb_module = javabase_moduleEntry();
|
||||
assert(jb_module != NULL, "java.base ModuleEntry not defined");
|
||||
jb_module->set_module(boot_loader_data->add_handle(module_handle));
|
||||
jb_module->set_version(version);
|
||||
jb_module->set_location(location);
|
||||
// Once java.base's ModuleEntry _module field is set with the known
|
||||
// java.lang.reflect.Module, java.base is considered "defined" to the VM.
|
||||
jb_module->set_module(boot_loader_data->add_handle(module_handle));
|
||||
|
||||
// Store pointer to the ModuleEntry for java.base in the java.lang.reflect.Module object.
|
||||
java_lang_reflect_Module::set_module_entry(module_handle(), jb_module);
|
||||
|
||||
// Patch any previously loaded classes' module field with java.base's java.lang.reflect.Module.
|
||||
patch_javabase_entries(module_handle);
|
||||
}
|
||||
|
||||
// Within java.lang.Class instances there is a java.lang.reflect.Module field
|
||||
// that must be set with the defining module. During startup, prior to java.base's
|
||||
// definition, classes needing their module field set are added to the fixup_module_list.
|
||||
// Their module field is set once java.base's java.lang.reflect.Module is known to the VM.
|
||||
void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
|
||||
assert(Module_lock->owned_by_self(), "should have the Module_lock");
|
||||
if (module_handle.is_null()) {
|
||||
fatal("Unable to patch the module field of classes loaded prior to java.base's definition, invalid java.lang.reflect.Module");
|
||||
}
|
||||
@ -389,9 +400,7 @@ void ModuleEntryTable::patch_javabase_entries(Handle module_handle) {
|
||||
for (int i = 0; i < list_length; i++) {
|
||||
Klass* k = list->at(i);
|
||||
assert(k->is_klass(), "List should only hold classes");
|
||||
Thread* THREAD = Thread::current();
|
||||
KlassHandle kh(THREAD, k);
|
||||
java_lang_Class::fixup_module_field(kh, module_handle);
|
||||
java_lang_Class::fixup_module_field(KlassHandle(k), module_handle);
|
||||
k->class_loader_data()->dec_keep_alive();
|
||||
}
|
||||
|
||||
|
@ -78,11 +78,11 @@ public:
|
||||
_must_walk_reads = false;
|
||||
}
|
||||
|
||||
Symbol* name() const { return literal(); }
|
||||
void set_name(Symbol* n) { set_literal(n); }
|
||||
Symbol* name() const { return literal(); }
|
||||
void set_name(Symbol* n) { set_literal(n); }
|
||||
|
||||
jobject module() const { return _module; }
|
||||
void set_module(jobject j) { _module = j; }
|
||||
jobject module() const { return _module; }
|
||||
void set_module(jobject j) { _module = j; }
|
||||
|
||||
// The shared ProtectionDomain reference is set once the VM loads a shared class
|
||||
// originated from the current Module. The referenced ProtectionDomain object is
|
||||
@ -217,13 +217,13 @@ public:
|
||||
|
||||
// Special handling for unnamed module, one per class loader's ModuleEntryTable
|
||||
void create_unnamed_module(ClassLoaderData* loader_data);
|
||||
ModuleEntry* unnamed_module() { return _unnamed_module; }
|
||||
ModuleEntry* unnamed_module() { return _unnamed_module; }
|
||||
|
||||
// Special handling for java.base
|
||||
static ModuleEntry* javabase_module() { return _javabase_module; }
|
||||
static void set_javabase_module(ModuleEntry* java_base) { _javabase_module = java_base; }
|
||||
static bool javabase_defined() { return ((_javabase_module != NULL) &&
|
||||
(_javabase_module->module() != NULL)); }
|
||||
static ModuleEntry* javabase_moduleEntry() { return _javabase_module; }
|
||||
static void set_javabase_moduleEntry(ModuleEntry* java_base) { _javabase_module = java_base; }
|
||||
static bool javabase_defined() { return ((_javabase_module != NULL) &&
|
||||
(_javabase_module->module() != NULL)); }
|
||||
static void finalize_javabase(Handle module_handle, Symbol* version, Symbol* location);
|
||||
static void patch_javabase_entries(Handle module_handle);
|
||||
|
||||
|
@ -206,7 +206,7 @@ static void define_javabase_module(jobject module, jstring version,
|
||||
assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table");
|
||||
|
||||
// Ensure java.base's ModuleEntry has been created
|
||||
assert(ModuleEntryTable::javabase_module() != NULL, "No ModuleEntry for java.base");
|
||||
assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for java.base");
|
||||
|
||||
bool duplicate_javabase = false;
|
||||
{
|
||||
@ -226,7 +226,7 @@ static void define_javabase_module(jobject module, jstring version,
|
||||
for (int x = 0; x < pkg_list->length(); x++) {
|
||||
// Some of java.base's packages were added early in bootstrapping, ignore duplicates.
|
||||
if (package_table->lookup_only(pkg_list->at(x)) == NULL) {
|
||||
pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_module());
|
||||
pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry());
|
||||
assert(pkg != NULL, "Unable to create a java.base package entry");
|
||||
}
|
||||
// Unable to have a GrowableArray of TempNewSymbol. Must decrement the refcount of
|
||||
@ -255,9 +255,6 @@ static void define_javabase_module(jobject module, jstring version,
|
||||
log_trace(modules)("define_javabase_module(): creation of package %s for module java.base",
|
||||
(pkg_list->at(x))->as_C_string());
|
||||
}
|
||||
|
||||
// Patch any previously loaded classes' module field with java.base's jlr.Module.
|
||||
ModuleEntryTable::patch_javabase_entries(module_handle);
|
||||
}
|
||||
|
||||
void Modules::define_module(jobject module, jstring version,
|
||||
|
@ -1210,16 +1210,12 @@ Klass* SystemDictionary::find_shared_class(Symbol* class_name) {
|
||||
|
||||
instanceKlassHandle SystemDictionary::load_shared_class(
|
||||
Symbol* class_name, Handle class_loader, TRAPS) {
|
||||
// Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
|
||||
// is enabled since posting CFLH is not supported when loading shared class.
|
||||
if (!JvmtiExport::should_post_class_file_load_hook()) {
|
||||
instanceKlassHandle ik (THREAD, find_shared_class(class_name));
|
||||
// Make sure we only return the boot class for the NULL classloader.
|
||||
if (ik.not_null() &&
|
||||
ik->is_shared_boot_class() && class_loader.is_null()) {
|
||||
Handle protection_domain;
|
||||
return load_shared_class(ik, class_loader, protection_domain, THREAD);
|
||||
}
|
||||
instanceKlassHandle ik (THREAD, find_shared_class(class_name));
|
||||
// Make sure we only return the boot class for the NULL classloader.
|
||||
if (ik.not_null() &&
|
||||
ik->is_shared_boot_class() && class_loader.is_null()) {
|
||||
Handle protection_domain;
|
||||
return load_shared_class(ik, class_loader, protection_domain, THREAD);
|
||||
}
|
||||
return instanceKlassHandle();
|
||||
}
|
||||
@ -1303,11 +1299,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
|
||||
Handle class_loader,
|
||||
Handle protection_domain, TRAPS) {
|
||||
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
|
||||
if (JvmtiExport::should_post_class_file_load_hook()) {
|
||||
// Don't load shared class when JvmtiExport::should_post_class_file_load_hook()
|
||||
// is enabled since posting CFLH is not supported when loading shared class.
|
||||
return nh;
|
||||
}
|
||||
|
||||
if (ik.not_null()) {
|
||||
Symbol* class_name = ik->name();
|
||||
@ -1358,6 +1349,14 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
|
||||
}
|
||||
}
|
||||
|
||||
instanceKlassHandle new_ik = KlassFactory::check_shared_class_file_load_hook(
|
||||
ik, class_name, class_loader, protection_domain, CHECK_(nh));
|
||||
if (new_ik.not_null()) {
|
||||
// The class is changed by CFLH. Return the new class. The shared class is
|
||||
// not used.
|
||||
return new_ik;
|
||||
}
|
||||
|
||||
// Adjust methods to recover missing data. They need addresses for
|
||||
// interpreter entry points and their default native method address
|
||||
// must be reset.
|
||||
|
@ -1366,22 +1366,25 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
|
||||
return false;
|
||||
}
|
||||
assert(prefix != NULL && prefix != BUSY, "Error");
|
||||
size_t i = 1;
|
||||
oop cur = prefix;
|
||||
while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
|
||||
i++; cur = cur->list_ptr_from_klass();
|
||||
for (size_t i = 1; i < objsFromOverflow; ++i) {
|
||||
oop next = cur->list_ptr_from_klass();
|
||||
if (next == NULL) break;
|
||||
cur = next;
|
||||
}
|
||||
assert(cur != NULL, "Loop postcondition");
|
||||
|
||||
// Reattach remaining (suffix) to overflow list
|
||||
if (cur->klass_or_null() == NULL) {
|
||||
oop suffix = cur->list_ptr_from_klass();
|
||||
if (suffix == NULL) {
|
||||
// Write back the NULL in lieu of the BUSY we wrote
|
||||
// above and it is still the same value.
|
||||
if (_overflow_list == BUSY) {
|
||||
(void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
|
||||
}
|
||||
} else {
|
||||
assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error");
|
||||
oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list
|
||||
assert(suffix != BUSY, "Error");
|
||||
// suffix will be put back on global list
|
||||
cur->set_klass_to_list_ptr(NULL); // break off suffix
|
||||
// It's possible that the list is still in the empty(busy) state
|
||||
// we left it in a short while ago; in that case we may be
|
||||
@ -1401,8 +1404,10 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
|
||||
// Too bad, someone else got in in between; we'll need to do a splice.
|
||||
// Find the last item of suffix list
|
||||
oop last = suffix;
|
||||
while (last->klass_or_null() != NULL) {
|
||||
last = last->list_ptr_from_klass();
|
||||
while (true) {
|
||||
oop next = last->list_ptr_from_klass();
|
||||
if (next == NULL) break;
|
||||
last = next;
|
||||
}
|
||||
// Atomically prepend suffix to current overflow list
|
||||
observed_overflow_list = _overflow_list;
|
||||
|
@ -1479,7 +1479,7 @@ void G1CollectedHeap::resize_if_necessary_after_full_collection() {
|
||||
"Capacity: " SIZE_FORMAT "B occupancy: " SIZE_FORMAT "B min_desired_capacity: " SIZE_FORMAT "B (" UINTX_FORMAT " %%)",
|
||||
capacity_after_gc, used_after_gc, minimum_desired_capacity, MinHeapFreeRatio);
|
||||
|
||||
expand(expand_bytes);
|
||||
expand(expand_bytes, _workers);
|
||||
|
||||
// No expansion, now see if we want to shrink
|
||||
} else if (capacity_after_gc > maximum_desired_capacity) {
|
||||
@ -1599,7 +1599,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationConte
|
||||
word_size * HeapWordSize);
|
||||
|
||||
|
||||
if (expand(expand_bytes)) {
|
||||
if (expand(expand_bytes, _workers)) {
|
||||
_hrm.verify_optional();
|
||||
_verifier->verify_region_sets_optional();
|
||||
return attempt_allocation_at_safepoint(word_size,
|
||||
@ -1609,7 +1609,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size, AllocationConte
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) {
|
||||
bool G1CollectedHeap::expand(size_t expand_bytes, WorkGang* pretouch_workers, double* expand_time_ms) {
|
||||
size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
|
||||
aligned_expand_bytes = align_size_up(aligned_expand_bytes,
|
||||
HeapRegion::GrainBytes);
|
||||
@ -1626,7 +1626,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) {
|
||||
uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
|
||||
assert(regions_to_expand > 0, "Must expand by at least one region");
|
||||
|
||||
uint expanded_by = _hrm.expand_by(regions_to_expand);
|
||||
uint expanded_by = _hrm.expand_by(regions_to_expand, pretouch_workers);
|
||||
if (expand_time_ms != NULL) {
|
||||
*expand_time_ms = (os::elapsedTime() - expand_heap_start_time_sec) * MILLIUNITS;
|
||||
}
|
||||
@ -1927,7 +1927,7 @@ jint G1CollectedHeap::initialize() {
|
||||
_cmThread = _cm->cmThread();
|
||||
|
||||
// Now expand into the initial heap size.
|
||||
if (!expand(init_byte_size)) {
|
||||
if (!expand(init_byte_size, _workers)) {
|
||||
vm_shutdown_during_initialization("Failed to allocate initial heap.");
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
@ -3165,7 +3165,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
|
||||
assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table.");
|
||||
|
||||
_cm->note_start_of_gc();
|
||||
// We call this after finalize_cset() to
|
||||
// ensure that the CSet has been finalized.
|
||||
_cm->verify_no_cset_oops();
|
||||
@ -3241,7 +3240,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
// No need for an ergo logging here,
|
||||
// expansion_amount() does this when it returns a value > 0.
|
||||
double expand_ms;
|
||||
if (!expand(expand_bytes, &expand_ms)) {
|
||||
if (!expand(expand_bytes, _workers, &expand_ms)) {
|
||||
// We failed to expand the heap. Cannot do anything about it.
|
||||
}
|
||||
g1_policy()->phase_times()->record_expand_heap_time(expand_ms);
|
||||
@ -3251,7 +3250,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
// We redo the verification but now wrt to the new CSet which
|
||||
// has just got initialized after the previous CSet was freed.
|
||||
_cm->verify_no_cset_oops();
|
||||
_cm->note_end_of_gc();
|
||||
|
||||
// This timing is only used by the ergonomics to handle our pause target.
|
||||
// It is unclear why this should not include the full pause. We will
|
||||
|
@ -557,7 +557,7 @@ public:
|
||||
// Returns true if the heap was expanded by the requested amount;
|
||||
// false otherwise.
|
||||
// (Rounds up to a HeapRegion boundary.)
|
||||
bool expand(size_t expand_bytes, double* expand_time_ms = NULL);
|
||||
bool expand(size_t expand_bytes, WorkGang* pretouch_workers = NULL, double* expand_time_ms = NULL);
|
||||
|
||||
// Returns the PLAB statistics for a given destination.
|
||||
inline G1EvacStats* alloc_buffer_stats(InCSetState dest);
|
||||
|
@ -133,129 +133,184 @@ void G1CMBitMap::clear_range(MemRegion mr) {
|
||||
}
|
||||
|
||||
G1CMMarkStack::G1CMMarkStack() :
|
||||
_reserved_space(),
|
||||
_max_chunk_capacity(0),
|
||||
_base(NULL),
|
||||
_capacity(0),
|
||||
_saved_index((size_t)AllBits),
|
||||
_chunk_capacity(0),
|
||||
_out_of_memory(false),
|
||||
_should_expand(false) {
|
||||
set_empty();
|
||||
}
|
||||
|
||||
bool G1CMMarkStack::resize(size_t new_capacity) {
|
||||
assert(is_empty(), "Only resize when stack is empty.");
|
||||
assert(new_capacity <= MarkStackSizeMax,
|
||||
"Trying to resize stack to " SIZE_FORMAT " elements when the maximum is " SIZE_FORMAT, new_capacity, MarkStackSizeMax);
|
||||
assert(new_capacity <= _max_chunk_capacity,
|
||||
"Trying to resize stack to " SIZE_FORMAT " chunks when the maximum is " SIZE_FORMAT, new_capacity, _max_chunk_capacity);
|
||||
|
||||
size_t reservation_size = ReservedSpace::allocation_align_size_up(new_capacity * sizeof(oop));
|
||||
OopChunk* new_base = MmapArrayAllocator<OopChunk, mtGC>::allocate_or_null(new_capacity);
|
||||
|
||||
ReservedSpace rs(reservation_size);
|
||||
if (!rs.is_reserved()) {
|
||||
log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " elements and size " SIZE_FORMAT "B.", new_capacity, reservation_size);
|
||||
if (new_base == NULL) {
|
||||
log_warning(gc)("Failed to reserve memory for new overflow mark stack with " SIZE_FORMAT " chunks and size " SIZE_FORMAT "B.", new_capacity, new_capacity * sizeof(OopChunk));
|
||||
return false;
|
||||
}
|
||||
|
||||
VirtualSpace vs;
|
||||
|
||||
if (!vs.initialize(rs, rs.size())) {
|
||||
rs.release();
|
||||
log_warning(gc)("Failed to commit memory for new overflow mark stack of size " SIZE_FORMAT "B.", rs.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(vs.committed_size() == rs.size(), "Failed to commit all of the mark stack.");
|
||||
|
||||
// Release old mapping.
|
||||
_reserved_space.release();
|
||||
if (_base != NULL) {
|
||||
MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
|
||||
}
|
||||
|
||||
// Save new mapping for future unmapping.
|
||||
_reserved_space = rs;
|
||||
|
||||
MemTracker::record_virtual_memory_type((address)_reserved_space.base(), mtGC);
|
||||
|
||||
_base = (oop*) vs.low();
|
||||
_capacity = new_capacity;
|
||||
_base = new_base;
|
||||
_chunk_capacity = new_capacity;
|
||||
set_empty();
|
||||
_should_expand = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G1CMMarkStack::allocate(size_t capacity) {
|
||||
return resize(capacity);
|
||||
size_t G1CMMarkStack::capacity_alignment() {
|
||||
return (size_t)lcm(os::vm_allocation_granularity(), sizeof(OopChunk)) / sizeof(void*);
|
||||
}
|
||||
|
||||
bool G1CMMarkStack::initialize(size_t initial_capacity, size_t max_capacity) {
|
||||
guarantee(_max_chunk_capacity == 0, "G1CMMarkStack already initialized.");
|
||||
|
||||
size_t const OopChunkSizeInVoidStar = sizeof(OopChunk) / sizeof(void*);
|
||||
|
||||
_max_chunk_capacity = (size_t)align_size_up(max_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
|
||||
size_t initial_chunk_capacity = (size_t)align_size_up(initial_capacity, capacity_alignment()) / OopChunkSizeInVoidStar;
|
||||
|
||||
guarantee(initial_chunk_capacity <= _max_chunk_capacity,
|
||||
"Maximum chunk capacity " SIZE_FORMAT " smaller than initial capacity " SIZE_FORMAT,
|
||||
_max_chunk_capacity,
|
||||
initial_chunk_capacity);
|
||||
|
||||
log_debug(gc)("Initialize mark stack with " SIZE_FORMAT " chunks, maximum " SIZE_FORMAT,
|
||||
initial_chunk_capacity, _max_chunk_capacity);
|
||||
|
||||
return resize(initial_chunk_capacity);
|
||||
}
|
||||
|
||||
void G1CMMarkStack::expand() {
|
||||
// Clear expansion flag
|
||||
_should_expand = false;
|
||||
|
||||
if (_capacity == MarkStackSizeMax) {
|
||||
log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " elements.", _capacity);
|
||||
if (_chunk_capacity == _max_chunk_capacity) {
|
||||
log_debug(gc)("Can not expand overflow mark stack further, already at maximum capacity of " SIZE_FORMAT " chunks.", _chunk_capacity);
|
||||
return;
|
||||
}
|
||||
size_t old_capacity = _capacity;
|
||||
size_t old_capacity = _chunk_capacity;
|
||||
// Double capacity if possible
|
||||
size_t new_capacity = MIN2(old_capacity * 2, MarkStackSizeMax);
|
||||
size_t new_capacity = MIN2(old_capacity * 2, _max_chunk_capacity);
|
||||
|
||||
if (resize(new_capacity)) {
|
||||
log_debug(gc)("Expanded marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
|
||||
log_debug(gc)("Expanded mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
|
||||
old_capacity, new_capacity);
|
||||
} else {
|
||||
log_warning(gc)("Failed to expand marking stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " elements",
|
||||
log_warning(gc)("Failed to expand mark stack capacity from " SIZE_FORMAT " to " SIZE_FORMAT " chunks",
|
||||
old_capacity, new_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
G1CMMarkStack::~G1CMMarkStack() {
|
||||
if (_base != NULL) {
|
||||
_base = NULL;
|
||||
_reserved_space.release();
|
||||
MmapArrayAllocator<OopChunk, mtGC>::free(_base, _chunk_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
void G1CMMarkStack::par_push_arr(oop* buffer, size_t n) {
|
||||
MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
|
||||
size_t start = _index;
|
||||
size_t next_index = start + n;
|
||||
if (next_index > _capacity) {
|
||||
_overflow = true;
|
||||
return;
|
||||
}
|
||||
// Otherwise.
|
||||
_index = next_index;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
size_t ind = start + i;
|
||||
assert(ind < _capacity, "By overflow test above.");
|
||||
_base[ind] = buffer[i];
|
||||
}
|
||||
void G1CMMarkStack::add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem) {
|
||||
elem->next = *list;
|
||||
*list = elem;
|
||||
}
|
||||
|
||||
bool G1CMMarkStack::par_pop_arr(oop* buffer, size_t max, size_t* n) {
|
||||
MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
|
||||
size_t index = _index;
|
||||
if (index == 0) {
|
||||
*n = 0;
|
||||
void G1CMMarkStack::add_chunk_to_chunk_list(OopChunk* elem) {
|
||||
MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
|
||||
add_chunk_to_list(&_chunk_list, elem);
|
||||
_chunks_in_chunk_list++;
|
||||
}
|
||||
|
||||
void G1CMMarkStack::add_chunk_to_free_list(OopChunk* elem) {
|
||||
MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
|
||||
add_chunk_to_list(&_free_list, elem);
|
||||
}
|
||||
|
||||
G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_list(OopChunk* volatile* list) {
|
||||
OopChunk* result = *list;
|
||||
if (result != NULL) {
|
||||
*list = (*list)->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_chunk_list() {
|
||||
MutexLockerEx x(MarkStackChunkList_lock, Mutex::_no_safepoint_check_flag);
|
||||
OopChunk* result = remove_chunk_from_list(&_chunk_list);
|
||||
if (result != NULL) {
|
||||
_chunks_in_chunk_list--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
G1CMMarkStack::OopChunk* G1CMMarkStack::remove_chunk_from_free_list() {
|
||||
MutexLockerEx x(MarkStackFreeList_lock, Mutex::_no_safepoint_check_flag);
|
||||
return remove_chunk_from_list(&_free_list);
|
||||
}
|
||||
|
||||
G1CMMarkStack::OopChunk* G1CMMarkStack::allocate_new_chunk() {
|
||||
// This dirty read of _hwm is okay because we only ever increase the _hwm in parallel code.
|
||||
// Further this limits _hwm to a value of _chunk_capacity + #threads, avoiding
|
||||
// wraparound of _hwm.
|
||||
if (_hwm >= _chunk_capacity) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t cur_idx = Atomic::add(1, &_hwm) - 1;
|
||||
if (cur_idx >= _chunk_capacity) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OopChunk* result = ::new (&_base[cur_idx]) OopChunk;
|
||||
result->next = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool G1CMMarkStack::par_push_chunk(oop* ptr_arr) {
|
||||
// Get a new chunk.
|
||||
OopChunk* new_chunk = remove_chunk_from_free_list();
|
||||
|
||||
if (new_chunk == NULL) {
|
||||
// Did not get a chunk from the free list. Allocate from backing memory.
|
||||
new_chunk = allocate_new_chunk();
|
||||
}
|
||||
|
||||
if (new_chunk == NULL) {
|
||||
_out_of_memory = true;
|
||||
return false;
|
||||
} else {
|
||||
size_t k = MIN2(max, index);
|
||||
size_t new_ind = index - k;
|
||||
for (size_t j = 0; j < k; j++) {
|
||||
buffer[j] = _base[new_ind + j];
|
||||
}
|
||||
_index = new_ind;
|
||||
*n = k;
|
||||
return true;
|
||||
}
|
||||
|
||||
Copy::conjoint_memory_atomic(ptr_arr, new_chunk->data, OopsPerChunk * sizeof(oop));
|
||||
|
||||
add_chunk_to_chunk_list(new_chunk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void G1CMMarkStack::note_start_of_gc() {
|
||||
assert(_saved_index == (size_t)AllBits, "note_start_of_gc()/end_of_gc() calls bracketed incorrectly");
|
||||
_saved_index = _index;
|
||||
bool G1CMMarkStack::par_pop_chunk(oop* ptr_arr) {
|
||||
OopChunk* cur = remove_chunk_from_chunk_list();
|
||||
|
||||
if (cur == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Copy::conjoint_memory_atomic(cur->data, ptr_arr, OopsPerChunk * sizeof(oop));
|
||||
|
||||
add_chunk_to_free_list(cur);
|
||||
return true;
|
||||
}
|
||||
|
||||
void G1CMMarkStack::note_end_of_gc() {
|
||||
guarantee(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
|
||||
|
||||
_saved_index = (size_t)AllBits;
|
||||
void G1CMMarkStack::set_empty() {
|
||||
_chunks_in_chunk_list = 0;
|
||||
_hwm = 0;
|
||||
clear_out_of_memory();
|
||||
_chunk_list = NULL;
|
||||
_free_list = NULL;
|
||||
}
|
||||
|
||||
G1CMRootRegions::G1CMRootRegions() :
|
||||
@ -483,9 +538,8 @@ G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper*
|
||||
}
|
||||
}
|
||||
|
||||
if (!_global_mark_stack.allocate(MarkStackSize)) {
|
||||
if (!_global_mark_stack.initialize(MarkStackSize, MarkStackSizeMax)) {
|
||||
vm_exit_during_initialization("Failed to allocate initial concurrent mark overflow mark stack.");
|
||||
return;
|
||||
}
|
||||
|
||||
_tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC);
|
||||
@ -1695,10 +1749,10 @@ void G1ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
||||
// oop closures will set the has_overflown flag if we overflow the
|
||||
// global marking stack.
|
||||
|
||||
assert(_global_mark_stack.overflow() || _global_mark_stack.is_empty(),
|
||||
"mark stack should be empty (unless it overflowed)");
|
||||
assert(_global_mark_stack.is_out_of_memory() || _global_mark_stack.is_empty(),
|
||||
"Mark stack should be empty (unless it is out of memory)");
|
||||
|
||||
if (_global_mark_stack.overflow()) {
|
||||
if (_global_mark_stack.is_out_of_memory()) {
|
||||
// This should have been done already when we tried to push an
|
||||
// entry on to the global mark stack. But let's do it again.
|
||||
set_has_overflown();
|
||||
@ -2343,49 +2397,54 @@ void G1CMTask::decrease_limits() {
|
||||
}
|
||||
|
||||
void G1CMTask::move_entries_to_global_stack() {
|
||||
// local array where we'll store the entries that will be popped
|
||||
// from the local queue
|
||||
oop buffer[global_stack_transfer_size];
|
||||
// Local array where we'll store the entries that will be popped
|
||||
// from the local queue.
|
||||
oop buffer[G1CMMarkStack::OopsPerChunk];
|
||||
|
||||
int n = 0;
|
||||
size_t n = 0;
|
||||
oop obj;
|
||||
while (n < global_stack_transfer_size && _task_queue->pop_local(obj)) {
|
||||
while (n < G1CMMarkStack::OopsPerChunk && _task_queue->pop_local(obj)) {
|
||||
buffer[n] = obj;
|
||||
++n;
|
||||
}
|
||||
if (n < G1CMMarkStack::OopsPerChunk) {
|
||||
buffer[n] = NULL;
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
// we popped at least one entry from the local queue
|
||||
|
||||
if (!_cm->mark_stack_push(buffer, n)) {
|
||||
if (!_cm->mark_stack_push(buffer)) {
|
||||
set_has_aborted();
|
||||
}
|
||||
}
|
||||
|
||||
// this operation was quite expensive, so decrease the limits
|
||||
// This operation was quite expensive, so decrease the limits.
|
||||
decrease_limits();
|
||||
}
|
||||
|
||||
void G1CMTask::get_entries_from_global_stack() {
|
||||
// local array where we'll store the entries that will be popped
|
||||
bool G1CMTask::get_entries_from_global_stack() {
|
||||
// Local array where we'll store the entries that will be popped
|
||||
// from the global stack.
|
||||
oop buffer[global_stack_transfer_size];
|
||||
size_t n;
|
||||
_cm->mark_stack_pop(buffer, global_stack_transfer_size, &n);
|
||||
assert(n <= global_stack_transfer_size,
|
||||
"we should not pop more than the given limit");
|
||||
if (n > 0) {
|
||||
// yes, we did actually pop at least one entry
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
bool success = _task_queue->push(buffer[i]);
|
||||
// We only call this when the local queue is empty or under a
|
||||
// given target limit. So, we do not expect this push to fail.
|
||||
assert(success, "invariant");
|
||||
}
|
||||
oop buffer[G1CMMarkStack::OopsPerChunk];
|
||||
|
||||
if (!_cm->mark_stack_pop(buffer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// this operation was quite expensive, so decrease the limits
|
||||
// We did actually pop at least one entry.
|
||||
for (size_t i = 0; i < G1CMMarkStack::OopsPerChunk; ++i) {
|
||||
oop elem = buffer[i];
|
||||
if (elem == NULL) {
|
||||
break;
|
||||
}
|
||||
bool success = _task_queue->push(elem);
|
||||
// We only call this when the local queue is empty or under a
|
||||
// given target limit. So, we do not expect this push to fail.
|
||||
assert(success, "invariant");
|
||||
}
|
||||
|
||||
// This operation was quite expensive, so decrease the limits
|
||||
decrease_limits();
|
||||
return true;
|
||||
}
|
||||
|
||||
void G1CMTask::drain_local_queue(bool partially) {
|
||||
@ -2429,20 +2488,21 @@ void G1CMTask::drain_global_stack(bool partially) {
|
||||
|
||||
// Decide what the target size is, depending whether we're going to
|
||||
// drain it partially (so that other tasks can steal if they run out
|
||||
// of things to do) or totally (at the very end). Notice that,
|
||||
// because we move entries from the global stack in chunks or
|
||||
// because another task might be doing the same, we might in fact
|
||||
// drop below the target. But, this is not a problem.
|
||||
size_t target_size;
|
||||
// of things to do) or totally (at the very end).
|
||||
// Notice that when draining the global mark stack partially, due to the racyness
|
||||
// of the mark stack size update we might in fact drop below the target. But,
|
||||
// this is not a problem.
|
||||
// In case of total draining, we simply process until the global mark stack is
|
||||
// totally empty, disregarding the size counter.
|
||||
if (partially) {
|
||||
target_size = _cm->partial_mark_stack_size_target();
|
||||
} else {
|
||||
target_size = 0;
|
||||
}
|
||||
|
||||
if (_cm->mark_stack_size() > target_size) {
|
||||
size_t const target_size = _cm->partial_mark_stack_size_target();
|
||||
while (!has_aborted() && _cm->mark_stack_size() > target_size) {
|
||||
get_entries_from_global_stack();
|
||||
if (get_entries_from_global_stack()) {
|
||||
drain_local_queue(partially);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (!has_aborted() && get_entries_from_global_stack()) {
|
||||
drain_local_queue(partially);
|
||||
}
|
||||
}
|
||||
|
@ -149,42 +149,98 @@ class G1CMBitMap : public G1CMBitMapRO {
|
||||
//
|
||||
// Stores oops in a huge buffer in virtual memory that is always fully committed.
|
||||
// Resizing may only happen during a STW pause when the stack is empty.
|
||||
//
|
||||
// Memory is allocated on a "chunk" basis, i.e. a set of oops. For this, the mark
|
||||
// stack memory is split into evenly sized chunks of oops. Users can only
|
||||
// add or remove entries on that basis.
|
||||
// Chunks are filled in increasing address order. Not completely filled chunks
|
||||
// have a NULL element as a terminating element.
|
||||
//
|
||||
// Every chunk has a header containing a single pointer element used for memory
|
||||
// management. This wastes some space, but is negligible (< .1% with current sizing).
|
||||
//
|
||||
// Memory management is done using a mix of tracking a high water-mark indicating
|
||||
// that all chunks at a lower address are valid chunks, and a singly linked free
|
||||
// list connecting all empty chunks.
|
||||
class G1CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
ReservedSpace _reserved_space; // Space currently reserved for the mark stack.
|
||||
public:
|
||||
// Number of oops that can fit in a single chunk.
|
||||
static const size_t OopsPerChunk = 1024 - 1 /* One reference for the next pointer */;
|
||||
private:
|
||||
struct OopChunk {
|
||||
OopChunk* next;
|
||||
oop data[OopsPerChunk];
|
||||
};
|
||||
|
||||
oop* _base; // Bottom address of allocated memory area.
|
||||
size_t _capacity; // Maximum number of elements.
|
||||
size_t _index; // One more than last occupied index.
|
||||
size_t _max_chunk_capacity; // Maximum number of OopChunk elements on the stack.
|
||||
|
||||
size_t _saved_index; // Value of _index saved at start of GC to detect mark stack modifications during that time.
|
||||
OopChunk* _base; // Bottom address of allocated memory area.
|
||||
size_t _chunk_capacity; // Current maximum number of OopChunk elements.
|
||||
|
||||
char _pad0[DEFAULT_CACHE_LINE_SIZE];
|
||||
OopChunk* volatile _free_list; // Linked list of free chunks that can be allocated by users.
|
||||
char _pad1[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*)];
|
||||
OopChunk* volatile _chunk_list; // List of chunks currently containing data.
|
||||
volatile size_t _chunks_in_chunk_list;
|
||||
char _pad2[DEFAULT_CACHE_LINE_SIZE - sizeof(OopChunk*) - sizeof(size_t)];
|
||||
|
||||
volatile size_t _hwm; // High water mark within the reserved space.
|
||||
char _pad4[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)];
|
||||
|
||||
// Allocate a new chunk from the reserved memory, using the high water mark. Returns
|
||||
// NULL if out of memory.
|
||||
OopChunk* allocate_new_chunk();
|
||||
|
||||
volatile bool _out_of_memory;
|
||||
|
||||
// Atomically add the given chunk to the list.
|
||||
void add_chunk_to_list(OopChunk* volatile* list, OopChunk* elem);
|
||||
// Atomically remove and return a chunk from the given list. Returns NULL if the
|
||||
// list is empty.
|
||||
OopChunk* remove_chunk_from_list(OopChunk* volatile* list);
|
||||
|
||||
void add_chunk_to_chunk_list(OopChunk* elem);
|
||||
void add_chunk_to_free_list(OopChunk* elem);
|
||||
|
||||
OopChunk* remove_chunk_from_chunk_list();
|
||||
OopChunk* remove_chunk_from_free_list();
|
||||
|
||||
bool _overflow;
|
||||
bool _should_expand;
|
||||
|
||||
// Resizes the mark stack to the given new capacity. Releases any previous
|
||||
// memory if successful.
|
||||
bool resize(size_t new_capacity);
|
||||
|
||||
bool stack_modified() const { return _index != _saved_index; }
|
||||
public:
|
||||
G1CMMarkStack();
|
||||
~G1CMMarkStack();
|
||||
|
||||
bool allocate(size_t capacity);
|
||||
// Alignment and minimum capacity of this mark stack in number of oops.
|
||||
static size_t capacity_alignment();
|
||||
|
||||
// Pushes the first "n" elements of the given buffer on the stack.
|
||||
void par_push_arr(oop* buffer, size_t n);
|
||||
// Allocate and initialize the mark stack with the given number of oops.
|
||||
bool initialize(size_t initial_capacity, size_t max_capacity);
|
||||
|
||||
// Moves up to max elements from the stack into the given buffer. Returns
|
||||
// the number of elements pushed, and false if the array has been empty.
|
||||
// Returns true if the buffer contains at least one element.
|
||||
bool par_pop_arr(oop* buffer, size_t max, size_t* n);
|
||||
// Pushes the given buffer containing at most OopsPerChunk elements on the mark
|
||||
// stack. If less than OopsPerChunk elements are to be pushed, the array must
|
||||
// be terminated with a NULL.
|
||||
// Returns whether the buffer contents were successfully pushed to the global mark
|
||||
// stack.
|
||||
bool par_push_chunk(oop* buffer);
|
||||
|
||||
bool is_empty() const { return _index == 0; }
|
||||
size_t capacity() const { return _capacity; }
|
||||
// Pops a chunk from this mark stack, copying them into the given buffer. This
|
||||
// chunk may contain up to OopsPerChunk elements. If there are less, the last
|
||||
// element in the array is a NULL pointer.
|
||||
bool par_pop_chunk(oop* buffer);
|
||||
|
||||
bool overflow() const { return _overflow; }
|
||||
void clear_overflow() { _overflow = false; }
|
||||
// Return whether the chunk list is empty. Racy due to unsynchronized access to
|
||||
// _chunk_list.
|
||||
bool is_empty() const { return _chunk_list == NULL; }
|
||||
|
||||
size_t capacity() const { return _chunk_capacity; }
|
||||
|
||||
bool is_out_of_memory() const { return _out_of_memory; }
|
||||
void clear_out_of_memory() { _out_of_memory = false; }
|
||||
|
||||
bool should_expand() const { return _should_expand; }
|
||||
void set_should_expand(bool value) { _should_expand = value; }
|
||||
@ -192,20 +248,15 @@ class G1CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
// Expand the stack, typically in response to an overflow condition
|
||||
void expand();
|
||||
|
||||
size_t size() const { return _index; }
|
||||
// Return the approximate number of oops on this mark stack. Racy due to
|
||||
// unsynchronized access to _chunks_in_chunk_list.
|
||||
size_t size() const { return _chunks_in_chunk_list * OopsPerChunk; }
|
||||
|
||||
void set_empty() { _index = 0; clear_overflow(); }
|
||||
void set_empty();
|
||||
|
||||
// Record the current index.
|
||||
void note_start_of_gc();
|
||||
|
||||
// Make sure that we have not added any entries to the stack during GC.
|
||||
void note_end_of_gc();
|
||||
|
||||
// Apply fn to each oop in the mark stack, up to the bound recorded
|
||||
// via one of the above "note" functions. The mark stack must not
|
||||
// Apply Fn to every oop on the mark stack. The mark stack must not
|
||||
// be modified while iterating.
|
||||
template<typename Fn> void iterate(Fn fn);
|
||||
template<typename Fn> void iterate(Fn fn) const PRODUCT_RETURN;
|
||||
};
|
||||
|
||||
// Root Regions are regions that are not empty at the beginning of a
|
||||
@ -278,7 +329,6 @@ class G1ConcurrentMark: public CHeapObj<mtGC> {
|
||||
friend class G1CMDrainMarkingStackClosure;
|
||||
friend class G1CMBitMapClosure;
|
||||
friend class G1CMConcurrentMarkingTask;
|
||||
friend class G1CMMarkStack;
|
||||
friend class G1CMRemarkTask;
|
||||
friend class G1CMTask;
|
||||
|
||||
@ -479,22 +529,20 @@ protected:
|
||||
public:
|
||||
// Manipulation of the global mark stack.
|
||||
// The push and pop operations are used by tasks for transfers
|
||||
// between task-local queues and the global mark stack, and use
|
||||
// locking for concurrency safety.
|
||||
bool mark_stack_push(oop* arr, size_t n) {
|
||||
_global_mark_stack.par_push_arr(arr, n);
|
||||
if (_global_mark_stack.overflow()) {
|
||||
// between task-local queues and the global mark stack.
|
||||
bool mark_stack_push(oop* arr) {
|
||||
if (!_global_mark_stack.par_push_chunk(arr)) {
|
||||
set_has_overflown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void mark_stack_pop(oop* arr, size_t max, size_t* n) {
|
||||
_global_mark_stack.par_pop_arr(arr, max, n);
|
||||
bool mark_stack_pop(oop* arr) {
|
||||
return _global_mark_stack.par_pop_chunk(arr);
|
||||
}
|
||||
size_t mark_stack_size() { return _global_mark_stack.size(); }
|
||||
size_t partial_mark_stack_size_target() { return _global_mark_stack.capacity()/3; }
|
||||
bool mark_stack_overflow() { return _global_mark_stack.overflow(); }
|
||||
bool mark_stack_overflow() { return _global_mark_stack.is_out_of_memory(); }
|
||||
bool mark_stack_empty() { return _global_mark_stack.is_empty(); }
|
||||
|
||||
G1CMRootRegions* root_regions() { return &_root_regions; }
|
||||
@ -599,16 +647,6 @@ public:
|
||||
// read-only, so use this carefully!
|
||||
void clearRangePrevBitmap(MemRegion mr);
|
||||
|
||||
// Notify data structures that a GC has started.
|
||||
void note_start_of_gc() {
|
||||
_global_mark_stack.note_start_of_gc();
|
||||
}
|
||||
|
||||
// Notify data structures that a GC is finished.
|
||||
void note_end_of_gc() {
|
||||
_global_mark_stack.note_end_of_gc();
|
||||
}
|
||||
|
||||
// Verify that there are no CSet oops on the stacks (taskqueues /
|
||||
// global mark stack) and fingers (global / per-task).
|
||||
// If marking is not in progress, it's a no-op.
|
||||
@ -670,10 +708,7 @@ private:
|
||||
// references reaches this limit
|
||||
refs_reached_period = 384,
|
||||
// Initial value for the hash seed, used in the work stealing code
|
||||
init_hash_seed = 17,
|
||||
// How many entries will be transferred between global stack and
|
||||
// local queues at once.
|
||||
global_stack_transfer_size = 1024
|
||||
init_hash_seed = 17
|
||||
};
|
||||
|
||||
uint _worker_id;
|
||||
@ -858,9 +893,10 @@ public:
|
||||
// It pushes an object on the local queue.
|
||||
inline void push(oop obj);
|
||||
|
||||
// These two move entries to/from the global stack.
|
||||
// Move entries to the global stack.
|
||||
void move_entries_to_global_stack();
|
||||
void get_entries_from_global_stack();
|
||||
// Move entries from the global stack, return true if we were successful to do so.
|
||||
bool get_entries_from_global_stack();
|
||||
|
||||
// It pops and scans objects from the local queue. If partially is
|
||||
// true, then it stops when the queue size is of a given limit. If
|
||||
|
@ -89,14 +89,28 @@ inline bool G1CMBitMap::parMark(HeapWord* addr) {
|
||||
|
||||
#undef check_mark
|
||||
|
||||
#ifndef PRODUCT
|
||||
template<typename Fn>
|
||||
inline void G1CMMarkStack::iterate(Fn fn) {
|
||||
inline void G1CMMarkStack::iterate(Fn fn) const {
|
||||
assert_at_safepoint(true);
|
||||
assert(!stack_modified(), "Saved index " SIZE_FORMAT " must be the same as " SIZE_FORMAT, _saved_index, _index);
|
||||
for (size_t i = 0; i < _index; ++i) {
|
||||
fn(_base[i]);
|
||||
|
||||
size_t num_chunks = 0;
|
||||
|
||||
OopChunk* cur = _chunk_list;
|
||||
while (cur != NULL) {
|
||||
guarantee(num_chunks <= _chunks_in_chunk_list, "Found " SIZE_FORMAT " oop chunks which is more than there should be", num_chunks);
|
||||
|
||||
for (size_t i = 0; i < OopsPerChunk; ++i) {
|
||||
if (cur->data[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
fn(cur->data[i]);
|
||||
}
|
||||
cur = cur->next;
|
||||
num_chunks++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// It scans an object and visits its children.
|
||||
inline void G1CMTask::scan_object(oop obj) { process_grey_object<true>(obj); }
|
||||
|
@ -34,7 +34,6 @@ class G1RemSet;
|
||||
class G1ConcurrentMark;
|
||||
class DirtyCardToOopClosure;
|
||||
class G1CMBitMap;
|
||||
class G1CMMarkStack;
|
||||
class G1ParScanThreadState;
|
||||
class G1CMTask;
|
||||
class ReferenceProcessor;
|
||||
|
@ -24,8 +24,10 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/g1/g1PageBasedVirtualSpace.hpp"
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "oops/markOop.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/os.inline.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
@ -177,7 +179,7 @@ void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_pa
|
||||
guarantee(start_page < end_page,
|
||||
"Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page);
|
||||
|
||||
os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page));
|
||||
os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size);
|
||||
}
|
||||
|
||||
bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) {
|
||||
@ -198,9 +200,6 @@ bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) {
|
||||
}
|
||||
_committed.set_range(start_page, end_page);
|
||||
|
||||
if (AlwaysPreTouch) {
|
||||
pretouch_internal(start_page, end_page);
|
||||
}
|
||||
return zero_filled;
|
||||
}
|
||||
|
||||
@ -227,6 +226,53 @@ void G1PageBasedVirtualSpace::uncommit(size_t start_page, size_t size_in_pages)
|
||||
_committed.clear_range(start_page, end_page);
|
||||
}
|
||||
|
||||
class G1PretouchTask : public AbstractGangTask {
|
||||
private:
|
||||
char* volatile _cur_addr;
|
||||
char* const _start_addr;
|
||||
char* const _end_addr;
|
||||
size_t const _page_size;
|
||||
public:
|
||||
G1PretouchTask(char* start_address, char* end_address, size_t page_size) :
|
||||
AbstractGangTask("G1 PreTouch",
|
||||
Universe::is_fully_initialized() ? GCId::current_raw() :
|
||||
// During VM initialization there is
|
||||
// no GC cycle that this task can be
|
||||
// associated with.
|
||||
GCId::undefined()),
|
||||
_cur_addr(start_address),
|
||||
_start_addr(start_address),
|
||||
_end_addr(end_address),
|
||||
_page_size(page_size) {
|
||||
}
|
||||
|
||||
virtual void work(uint worker_id) {
|
||||
size_t const actual_chunk_size = MAX2(chunk_size(), _page_size);
|
||||
while (true) {
|
||||
char* touch_addr = (char*)Atomic::add_ptr((intptr_t)actual_chunk_size, (volatile void*) &_cur_addr) - actual_chunk_size;
|
||||
if (touch_addr < _start_addr || touch_addr >= _end_addr) {
|
||||
break;
|
||||
}
|
||||
char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char)));
|
||||
os::pretouch_memory(touch_addr, end_addr, _page_size);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t chunk_size() { return PreTouchParallelChunkSize; }
|
||||
};
|
||||
|
||||
void G1PageBasedVirtualSpace::pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang) {
|
||||
guarantee(pretouch_gang != NULL, "No pretouch gang specified.");
|
||||
|
||||
size_t num_chunks = MAX2((size_t)1, size_in_pages * _page_size / MAX2(G1PretouchTask::chunk_size(), _page_size));
|
||||
|
||||
uint num_workers = MIN2((uint)num_chunks, pretouch_gang->active_workers());
|
||||
G1PretouchTask cl(page_start(start_page), bounded_end_addr(start_page + size_in_pages), _page_size);
|
||||
log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.",
|
||||
cl.name(), num_workers, num_chunks, size_in_pages * _page_size);
|
||||
pretouch_gang->run_task(&cl, num_workers);
|
||||
}
|
||||
|
||||
bool G1PageBasedVirtualSpace::contains(const void* p) const {
|
||||
return _low_boundary <= (const char*) p && (const char*) p < _high_boundary;
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "memory/virtualspace.hpp"
|
||||
#include "utilities/bitMap.hpp"
|
||||
|
||||
class WorkGang;
|
||||
|
||||
// Virtual space management helper for a virtual space with an OS page allocation
|
||||
// granularity.
|
||||
// (De-)Allocation requests are always OS page aligned by passing a page index
|
||||
@ -117,6 +119,8 @@ class G1PageBasedVirtualSpace VALUE_OBJ_CLASS_SPEC {
|
||||
// Uncommit the given area of pages starting at start being size_in_pages large.
|
||||
void uncommit(size_t start_page, size_t size_in_pages);
|
||||
|
||||
void pretouch(size_t start_page, size_t size_in_pages, WorkGang* pretouch_gang = NULL);
|
||||
|
||||
// Initialize the given reserved space with the given base address and the size
|
||||
// actually used.
|
||||
// Prefer to commit in page_size chunks.
|
||||
|
@ -66,8 +66,12 @@ class G1RegionsLargerThanCommitSizeMapper : public G1RegionToSpaceMapper {
|
||||
guarantee(alloc_granularity >= page_size, "allocation granularity smaller than commit granularity");
|
||||
}
|
||||
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions) {
|
||||
bool zero_filled = _storage.commit((size_t)start_idx * _pages_per_region, num_regions * _pages_per_region);
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
|
||||
size_t const start_page = (size_t)start_idx * _pages_per_region;
|
||||
bool zero_filled = _storage.commit(start_page, num_regions * _pages_per_region);
|
||||
if (AlwaysPreTouch) {
|
||||
_storage.pretouch(start_page, num_regions * _pages_per_region, pretouch_gang);
|
||||
}
|
||||
_commit_map.set_range(start_idx, start_idx + num_regions);
|
||||
fire_on_commit(start_idx, num_regions, zero_filled);
|
||||
}
|
||||
@ -110,19 +114,38 @@ class G1RegionsSmallerThanCommitSizeMapper : public G1RegionToSpaceMapper {
|
||||
_refcounts.initialize((HeapWord*)rs.base(), (HeapWord*)(rs.base() + align_size_up(rs.size(), page_size)), page_size);
|
||||
}
|
||||
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions) {
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions, WorkGang* pretouch_gang) {
|
||||
size_t const NoPage = ~(size_t)0;
|
||||
|
||||
size_t first_committed = NoPage;
|
||||
size_t num_committed = 0;
|
||||
|
||||
bool all_zero_filled = true;
|
||||
|
||||
for (uint i = start_idx; i < start_idx + num_regions; i++) {
|
||||
assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i);
|
||||
size_t idx = region_idx_to_page_idx(i);
|
||||
uint old_refcount = _refcounts.get_by_index(idx);
|
||||
|
||||
bool zero_filled = false;
|
||||
if (old_refcount == 0) {
|
||||
if (first_committed == NoPage) {
|
||||
first_committed = idx;
|
||||
num_committed = 1;
|
||||
} else {
|
||||
num_committed++;
|
||||
}
|
||||
zero_filled = _storage.commit(idx, 1);
|
||||
}
|
||||
all_zero_filled &= zero_filled;
|
||||
|
||||
_refcounts.set_by_index(idx, old_refcount + 1);
|
||||
_commit_map.set_bit(i);
|
||||
fire_on_commit(i, 1, zero_filled);
|
||||
}
|
||||
if (AlwaysPreTouch && num_committed > 0) {
|
||||
_storage.pretouch(first_committed, num_committed, pretouch_gang);
|
||||
}
|
||||
fire_on_commit(start_idx, num_regions, all_zero_filled);
|
||||
}
|
||||
|
||||
virtual void uncommit_regions(uint start_idx, size_t num_regions) {
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
class WorkGang;
|
||||
|
||||
class G1MappingChangedListener VALUE_OBJ_CLASS_SPEC {
|
||||
public:
|
||||
// Fired after commit of the memory, i.e. the memory this listener is registered
|
||||
@ -68,7 +70,7 @@ class G1RegionToSpaceMapper : public CHeapObj<mtGC> {
|
||||
return _commit_map.at(idx);
|
||||
}
|
||||
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions = 1) = 0;
|
||||
virtual void commit_regions(uint start_idx, size_t num_regions = 1, WorkGang* pretouch_workers = NULL) = 0;
|
||||
virtual void uncommit_regions(uint start_idx, size_t num_regions = 1) = 0;
|
||||
|
||||
// Creates an appropriate G1RegionToSpaceMapper for the given parameters.
|
||||
|
@ -352,35 +352,6 @@ void HeapRegion::note_self_forwarding_removal_end(bool during_initial_mark,
|
||||
_prev_marked_bytes = marked_bytes;
|
||||
}
|
||||
|
||||
HeapWord*
|
||||
HeapRegion::object_iterate_mem_careful(MemRegion mr,
|
||||
ObjectClosure* cl) {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
// We used to use "block_start_careful" here. But we're actually happy
|
||||
// to update the BOT while we do this...
|
||||
HeapWord* cur = block_start(mr.start());
|
||||
mr = mr.intersection(used_region());
|
||||
if (mr.is_empty()) return NULL;
|
||||
// Otherwise, find the obj that extends onto mr.start().
|
||||
|
||||
assert(cur <= mr.start()
|
||||
&& (oop(cur)->klass_or_null() == NULL ||
|
||||
cur + oop(cur)->size() > mr.start()),
|
||||
"postcondition of block_start");
|
||||
oop obj;
|
||||
while (cur < mr.end()) {
|
||||
obj = oop(cur);
|
||||
if (obj->klass_or_null() == NULL) {
|
||||
// Ran into an unparseable point.
|
||||
return cur;
|
||||
} else if (!g1h->is_obj_dead(obj)) {
|
||||
cl->do_object(obj);
|
||||
}
|
||||
cur += block_size(cur);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HeapWord*
|
||||
HeapRegion::
|
||||
oops_on_card_seq_iterate_careful(MemRegion mr,
|
||||
|
@ -653,17 +653,6 @@ class HeapRegion: public G1ContiguousSpace {
|
||||
}
|
||||
}
|
||||
|
||||
// Requires that "mr" be entirely within the region.
|
||||
// Apply "cl->do_object" to all objects that intersect with "mr".
|
||||
// If the iteration encounters an unparseable portion of the region,
|
||||
// or if "cl->abort()" is true after a closure application,
|
||||
// terminate the iteration and return the address of the start of the
|
||||
// subregion that isn't done. (The two can be distinguished by querying
|
||||
// "cl->abort()".) Return of "NULL" indicates that the iteration
|
||||
// completed.
|
||||
HeapWord*
|
||||
object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
|
||||
|
||||
// filter_young: if true and the region is a young region then we
|
||||
// skip the iteration.
|
||||
// card_ptr: if not NULL, and we decide that the card is not young
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -72,22 +72,22 @@ HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
|
||||
return g1h->new_heap_region(hrm_index, mr);
|
||||
}
|
||||
|
||||
void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
|
||||
void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
|
||||
guarantee(num_regions > 0, "Must commit more than zero regions");
|
||||
guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
|
||||
|
||||
_num_committed += (uint)num_regions;
|
||||
|
||||
_heap_mapper->commit_regions(index, num_regions);
|
||||
_heap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
|
||||
// Also commit auxiliary data
|
||||
_prev_bitmap_mapper->commit_regions(index, num_regions);
|
||||
_next_bitmap_mapper->commit_regions(index, num_regions);
|
||||
_prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
_next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
|
||||
_bot_mapper->commit_regions(index, num_regions);
|
||||
_cardtable_mapper->commit_regions(index, num_regions);
|
||||
_bot_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
_cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
|
||||
_card_counts_mapper->commit_regions(index, num_regions);
|
||||
_card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
|
||||
}
|
||||
|
||||
void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
|
||||
@ -117,9 +117,9 @@ void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
|
||||
_card_counts_mapper->uncommit_regions(start, num_regions);
|
||||
}
|
||||
|
||||
void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
|
||||
void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
|
||||
guarantee(num_regions > 0, "No point in calling this for zero regions");
|
||||
commit_regions(start, num_regions);
|
||||
commit_regions(start, num_regions, pretouch_gang);
|
||||
for (uint i = start; i < start + num_regions; i++) {
|
||||
if (_regions.get_by_index(i) == NULL) {
|
||||
HeapRegion* new_hr = new_heap_region(i);
|
||||
@ -163,11 +163,11 @@ MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
|
||||
return MemoryUsage(0, used_sz, committed_sz, committed_sz);
|
||||
}
|
||||
|
||||
uint HeapRegionManager::expand_by(uint num_regions) {
|
||||
return expand_at(0, num_regions);
|
||||
uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
|
||||
return expand_at(0, num_regions, pretouch_workers);
|
||||
}
|
||||
|
||||
uint HeapRegionManager::expand_at(uint start, uint num_regions) {
|
||||
uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
|
||||
if (num_regions == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -181,7 +181,7 @@ uint HeapRegionManager::expand_at(uint start, uint num_regions) {
|
||||
while (expanded < num_regions &&
|
||||
(num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
|
||||
uint to_expand = MIN2(num_regions - expanded, num_last_found);
|
||||
make_regions_available(idx_last_found, to_expand);
|
||||
make_regions_available(idx_last_found, to_expand, pretouch_workers);
|
||||
expanded += to_expand;
|
||||
cur = idx_last_found + num_last_found + 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,7 @@ class HeapRegion;
|
||||
class HeapRegionClosure;
|
||||
class HeapRegionClaimer;
|
||||
class FreeRegionList;
|
||||
class WorkGang;
|
||||
|
||||
class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
|
||||
protected:
|
||||
@ -94,10 +95,10 @@ class HeapRegionManager: public CHeapObj<mtGC> {
|
||||
HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
|
||||
HeapWord* heap_end() const {return _regions.end_address_mapped(); }
|
||||
|
||||
void make_regions_available(uint index, uint num_regions = 1);
|
||||
void make_regions_available(uint index, uint num_regions = 1, WorkGang* pretouch_gang = NULL);
|
||||
|
||||
// Pass down commit calls to the VirtualSpace.
|
||||
void commit_regions(uint index, size_t num_regions = 1);
|
||||
void commit_regions(uint index, size_t num_regions = 1, WorkGang* pretouch_gang = NULL);
|
||||
void uncommit_regions(uint index, size_t num_regions = 1);
|
||||
|
||||
// Notify other data structures about change in the heap layout.
|
||||
@ -209,12 +210,12 @@ public:
|
||||
// HeapRegions, or re-use existing ones. Returns the number of regions the
|
||||
// sequence was expanded by. If a HeapRegion allocation fails, the resulting
|
||||
// number of regions might be smaller than what's desired.
|
||||
uint expand_by(uint num_regions);
|
||||
uint expand_by(uint num_regions, WorkGang* pretouch_workers = NULL);
|
||||
|
||||
// Makes sure that the regions from start to start+num_regions-1 are available
|
||||
// for allocation. Returns the number of regions that were committed to achieve
|
||||
// this.
|
||||
uint expand_at(uint start, uint num_regions);
|
||||
uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers = NULL);
|
||||
|
||||
// Find a contiguous set of empty regions of length num. Returns the start index of
|
||||
// that set, or G1_NO_HRM_INDEX.
|
||||
|
@ -304,9 +304,6 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
|
||||
inline static oop class_allocate(KlassHandle klass, int size, TRAPS);
|
||||
|
||||
inline static void post_allocation_install_obj_klass(KlassHandle klass,
|
||||
oop obj);
|
||||
|
||||
// Raw memory allocation facilities
|
||||
// The obj and array allocate methods are covers for these methods.
|
||||
// mem_allocate() should never be
|
||||
|
@ -41,14 +41,22 @@
|
||||
// Inline allocation implementations.
|
||||
|
||||
void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
|
||||
HeapWord* obj) {
|
||||
post_allocation_setup_no_klass_install(klass, obj);
|
||||
post_allocation_install_obj_klass(klass, oop(obj));
|
||||
HeapWord* obj_ptr) {
|
||||
post_allocation_setup_no_klass_install(klass, obj_ptr);
|
||||
oop obj = (oop)obj_ptr;
|
||||
#if ! INCLUDE_ALL_GCS
|
||||
obj->set_klass(klass());
|
||||
#else
|
||||
// Need a release store to ensure array/class length, mark word, and
|
||||
// object zeroing are visible before setting the klass non-NULL, for
|
||||
// concurrent collectors.
|
||||
obj->release_set_klass(klass());
|
||||
#endif
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
|
||||
HeapWord* objPtr) {
|
||||
oop obj = (oop)objPtr;
|
||||
HeapWord* obj_ptr) {
|
||||
oop obj = (oop)obj_ptr;
|
||||
|
||||
assert(obj != NULL, "NULL object pointer");
|
||||
if (UseBiasedLocking && (klass() != NULL)) {
|
||||
@ -59,18 +67,6 @@ void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
|
||||
}
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
|
||||
oop obj) {
|
||||
// These asserts are kind of complicated because of klassKlass
|
||||
// and the beginning of the world.
|
||||
assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
|
||||
assert(klass() == NULL || klass()->is_klass(), "not a klass");
|
||||
assert(obj != NULL, "NULL object pointer");
|
||||
obj->set_klass(klass());
|
||||
assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
|
||||
"missing klass");
|
||||
}
|
||||
|
||||
// Support for jvmti and dtrace
|
||||
inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
|
||||
// support low memory notifications (no-op if not enabled)
|
||||
@ -88,25 +84,26 @@ inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
HeapWord* obj_ptr,
|
||||
int size) {
|
||||
post_allocation_setup_common(klass, obj);
|
||||
post_allocation_setup_common(klass, obj_ptr);
|
||||
oop obj = (oop)obj_ptr;
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!((oop)obj)->is_array(), "must not be an array");
|
||||
!obj->is_array(), "must not be an array");
|
||||
// notify jvmti and dtrace
|
||||
post_allocation_notify(klass, (oop)obj, size);
|
||||
post_allocation_notify(klass, obj, size);
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
HeapWord* obj_ptr,
|
||||
int size) {
|
||||
// Set oop_size field before setting the _klass field
|
||||
// in post_allocation_setup_common() because the klass field
|
||||
// indicates that the object is parsable by concurrent GC.
|
||||
oop new_cls = (oop)obj;
|
||||
// Set oop_size field before setting the _klass field because a
|
||||
// non-NULL _klass field indicates that the object is parsable by
|
||||
// concurrent GC.
|
||||
oop new_cls = (oop)obj_ptr;
|
||||
assert(size > 0, "oop_size must be positive.");
|
||||
java_lang_Class::set_oop_size(new_cls, size);
|
||||
post_allocation_setup_common(klass, obj);
|
||||
post_allocation_setup_common(klass, obj_ptr);
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!new_cls->is_array(), "must not be an array");
|
||||
// notify jvmti and dtrace
|
||||
@ -114,15 +111,15 @@ void CollectedHeap::post_allocation_setup_class(KlassHandle klass,
|
||||
}
|
||||
|
||||
void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
|
||||
HeapWord* obj,
|
||||
HeapWord* obj_ptr,
|
||||
int length) {
|
||||
// Set array length before setting the _klass field
|
||||
// in post_allocation_setup_common() because the klass field
|
||||
// indicates that the object is parsable by concurrent GC.
|
||||
// Set array length before setting the _klass field because a
|
||||
// non-NULL klass field indicates that the object is parsable by
|
||||
// concurrent GC.
|
||||
assert(length >= 0, "length should be non-negative");
|
||||
((arrayOop)obj)->set_length(length);
|
||||
post_allocation_setup_common(klass, obj);
|
||||
oop new_obj = (oop)obj;
|
||||
((arrayOop)obj_ptr)->set_length(length);
|
||||
post_allocation_setup_common(klass, obj_ptr);
|
||||
oop new_obj = (oop)obj_ptr;
|
||||
assert(new_obj->is_array(), "must be an array");
|
||||
// notify jvmti and dtrace (must be after length is set for dtrace)
|
||||
post_allocation_notify(klass, new_obj, new_obj->size());
|
||||
|
@ -62,7 +62,12 @@ class AbstractGangTask VALUE_OBJ_CLASS_SPEC {
|
||||
AbstractGangTask(const char* name) :
|
||||
_name(name),
|
||||
_gc_id(GCId::current_raw())
|
||||
{}
|
||||
{}
|
||||
|
||||
AbstractGangTask(const char* name, const uint gc_id) :
|
||||
_name(name),
|
||||
_gc_id(gc_id)
|
||||
{}
|
||||
|
||||
// The abstract work method.
|
||||
// The argument tells you which member of the gang you are.
|
||||
|
@ -738,6 +738,7 @@ class MmapArrayAllocator : public AllStatic {
|
||||
static size_t size_for(size_t length);
|
||||
|
||||
public:
|
||||
static E* allocate_or_null(size_t length);
|
||||
static E* allocate(size_t length);
|
||||
static void free(E* addr, size_t length);
|
||||
};
|
||||
|
@ -152,6 +152,24 @@ size_t MmapArrayAllocator<E, F>::size_for(size_t length) {
|
||||
return align_size_up(size, alignment);
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* MmapArrayAllocator<E, F>::allocate_or_null(size_t length) {
|
||||
size_t size = size_for(length);
|
||||
int alignment = os::vm_allocation_granularity();
|
||||
|
||||
char* addr = os::reserve_memory(size, NULL, alignment, F);
|
||||
if (addr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (os::commit_memory(addr, size, !ExecMem, "Allocator (commit)")) {
|
||||
return (E*)addr;
|
||||
} else {
|
||||
os::release_memory(addr, size);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template <class E, MEMFLAGS F>
|
||||
E* MmapArrayAllocator<E, F>::allocate(size_t length) {
|
||||
size_t size = size_for(length);
|
||||
|
@ -649,7 +649,7 @@ ReservedSpace FileMapInfo::reserve_shared_memory() {
|
||||
|
||||
// Memory map a region in the address space.
|
||||
static const char* shared_region_name[] = { "ReadOnly", "ReadWrite", "MiscData", "MiscCode",
|
||||
"String1", "String2" };
|
||||
"String1", "String2", "OptionalData" };
|
||||
|
||||
char* FileMapInfo::map_region(int i) {
|
||||
assert(!MetaspaceShared::is_string_region(i), "sanity");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -252,10 +252,27 @@ public:
|
||||
bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
|
||||
void print_shared_spaces() NOT_CDS_RETURN;
|
||||
|
||||
// The ro+rw+md+mc spaces size
|
||||
static size_t core_spaces_size() {
|
||||
return align_size_up((SharedReadOnlySize + SharedReadWriteSize +
|
||||
SharedMiscDataSize + SharedMiscCodeSize),
|
||||
os::vm_allocation_granularity());
|
||||
}
|
||||
|
||||
// The estimated optional space size.
|
||||
//
|
||||
// Currently the optional space only has archived class bytes.
|
||||
// The core_spaces_size is the size of all class metadata, which is a good
|
||||
// estimate of the total class bytes to be archived. Only the portion
|
||||
// containing data is written out to the archive and mapped at runtime.
|
||||
// There is no memory waste due to unused portion in optional space.
|
||||
static size_t optional_space_size() {
|
||||
return core_spaces_size();
|
||||
}
|
||||
|
||||
// Total shared_spaces size includes the ro, rw, md, mc and od spaces
|
||||
static size_t shared_spaces_size() {
|
||||
return align_size_up(SharedReadOnlySize + SharedReadWriteSize +
|
||||
SharedMiscDataSize + SharedMiscCodeSize,
|
||||
os::vm_allocation_granularity());
|
||||
return core_spaces_size() + optional_space_size();
|
||||
}
|
||||
|
||||
// Stop CDS sharing and unmap CDS regions.
|
||||
|
@ -3172,36 +3172,28 @@ void Metaspace::global_initialize() {
|
||||
address cds_address = NULL;
|
||||
FileMapInfo* mapinfo = new FileMapInfo();
|
||||
|
||||
if (JvmtiExport::should_post_class_file_load_hook()) {
|
||||
// Currently CDS does not support JVMTI CFLH when loading shared class.
|
||||
// If JvmtiExport::should_post_class_file_load_hook is already enabled,
|
||||
// just disable UseSharedSpaces.
|
||||
FileMapInfo::fail_continue("Tool agent requires sharing to be disabled.");
|
||||
delete mapinfo;
|
||||
} else {
|
||||
// Open the shared archive file, read and validate the header. If
|
||||
// initialization fails, shared spaces [UseSharedSpaces] are
|
||||
// disabled and the file is closed.
|
||||
// Map in spaces now also
|
||||
if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
|
||||
cds_total = FileMapInfo::shared_spaces_size();
|
||||
cds_address = (address)mapinfo->header()->region_addr(0);
|
||||
// Open the shared archive file, read and validate the header. If
|
||||
// initialization fails, shared spaces [UseSharedSpaces] are
|
||||
// disabled and the file is closed.
|
||||
// Map in spaces now also
|
||||
if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
|
||||
cds_total = FileMapInfo::shared_spaces_size();
|
||||
cds_address = (address)mapinfo->header()->region_addr(0);
|
||||
#ifdef _LP64
|
||||
if (using_class_space()) {
|
||||
char* cds_end = (char*)(cds_address + cds_total);
|
||||
cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
|
||||
// If UseCompressedClassPointers is set then allocate the metaspace area
|
||||
// above the heap and above the CDS area (if it exists).
|
||||
allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
|
||||
// Map the shared string space after compressed pointers
|
||||
// because it relies on compressed class pointers setting to work
|
||||
mapinfo->map_string_regions();
|
||||
}
|
||||
#endif // _LP64
|
||||
} else {
|
||||
assert(!mapinfo->is_open() && !UseSharedSpaces,
|
||||
"archive file not closed or shared spaces not disabled.");
|
||||
if (using_class_space()) {
|
||||
char* cds_end = (char*)(cds_address + cds_total);
|
||||
cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
|
||||
// If UseCompressedClassPointers is set then allocate the metaspace area
|
||||
// above the heap and above the CDS area (if it exists).
|
||||
allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
|
||||
// Map the shared string space after compressed pointers
|
||||
// because it relies on compressed class pointers setting to work
|
||||
mapinfo->map_string_regions();
|
||||
}
|
||||
#endif // _LP64
|
||||
} else {
|
||||
assert(!mapinfo->is_open() && !UseSharedSpaces,
|
||||
"archive file not closed or shared spaces not disabled.");
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
|
@ -65,6 +65,7 @@ address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
|
||||
size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
|
||||
SharedMiscRegion MetaspaceShared::_mc;
|
||||
SharedMiscRegion MetaspaceShared::_md;
|
||||
SharedMiscRegion MetaspaceShared::_od;
|
||||
|
||||
void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size, SharedSpaceType space_type) {
|
||||
_vs.initialize(rs, committed_byte_size);
|
||||
@ -93,16 +94,24 @@ void MetaspaceShared::initialize_shared_rs(ReservedSpace* rs) {
|
||||
assert(DumpSharedSpaces, "dump time only");
|
||||
_shared_rs = rs;
|
||||
|
||||
// Split up and initialize the misc code and data spaces
|
||||
size_t core_spaces_size = FileMapInfo::core_spaces_size();
|
||||
size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
|
||||
ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size);
|
||||
ReservedSpace misc_section = _shared_rs->last_part(metadata_size);
|
||||
|
||||
// Now split into misc sections.
|
||||
// Split into the core and optional sections
|
||||
ReservedSpace core_data = _shared_rs->first_part(core_spaces_size);
|
||||
ReservedSpace optional_data = _shared_rs->last_part(core_spaces_size);
|
||||
|
||||
// The RO/RW and the misc sections
|
||||
ReservedSpace shared_ro_rw = core_data.first_part(metadata_size);
|
||||
ReservedSpace misc_section = core_data.last_part(metadata_size);
|
||||
|
||||
// Now split the misc code and misc data sections.
|
||||
ReservedSpace md_rs = misc_section.first_part(SharedMiscDataSize);
|
||||
ReservedSpace mc_rs = misc_section.last_part(SharedMiscDataSize);
|
||||
|
||||
_md.initialize(md_rs, SharedMiscDataSize, SharedMiscData);
|
||||
_mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData);
|
||||
_mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscCode);
|
||||
_od.initialize(optional_data, metadata_size, SharedOptional);
|
||||
}
|
||||
|
||||
// Read/write a data stream for restoring/preserving metadata pointers and
|
||||
@ -521,6 +530,7 @@ private:
|
||||
GrowableArray<Klass*> *_class_promote_order;
|
||||
VirtualSpace _md_vs;
|
||||
VirtualSpace _mc_vs;
|
||||
VirtualSpace _od_vs;
|
||||
GrowableArray<MemRegion> *_string_regions;
|
||||
|
||||
public:
|
||||
@ -598,15 +608,19 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||
remove_unshareable_in_classes();
|
||||
tty->print_cr("done. ");
|
||||
|
||||
// Set up the share data and shared code segments.
|
||||
// Set up the misc data, misc code and optional data segments.
|
||||
_md_vs = *MetaspaceShared::misc_data_region()->virtual_space();
|
||||
_mc_vs = *MetaspaceShared::misc_code_region()->virtual_space();
|
||||
_od_vs = *MetaspaceShared::optional_data_region()->virtual_space();
|
||||
char* md_low = _md_vs.low();
|
||||
char* md_top = MetaspaceShared::misc_data_region()->alloc_top();
|
||||
char* md_end = _md_vs.high();
|
||||
char* mc_low = _mc_vs.low();
|
||||
char* mc_top = MetaspaceShared::misc_code_region()->alloc_top();
|
||||
char* mc_end = _mc_vs.high();
|
||||
char* od_low = _od_vs.low();
|
||||
char* od_top = MetaspaceShared::optional_data_region()->alloc_top();
|
||||
char* od_end = _od_vs.high();
|
||||
|
||||
// Reserve space for the list of Klass*s whose vtables are used
|
||||
// for patching others as needed.
|
||||
@ -661,28 +675,32 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||
const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
|
||||
const size_t md_alloced = md_end-md_low;
|
||||
const size_t mc_alloced = mc_end-mc_low;
|
||||
const size_t od_alloced = od_end-od_low;
|
||||
const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced
|
||||
+ ss_bytes;
|
||||
+ ss_bytes + od_alloced;
|
||||
|
||||
// Occupied size of each space.
|
||||
const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
|
||||
const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
|
||||
const size_t md_bytes = size_t(md_top - md_low);
|
||||
const size_t mc_bytes = size_t(mc_top - mc_low);
|
||||
const size_t od_bytes = size_t(od_top - od_low);
|
||||
|
||||
// Percent of total size
|
||||
const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes;
|
||||
const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes + od_bytes;
|
||||
const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
|
||||
const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
|
||||
const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
|
||||
const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
|
||||
const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0;
|
||||
const double od_t_perc = od_bytes / double(total_bytes) * 100.0;
|
||||
|
||||
// Percent of fullness of each space
|
||||
const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
|
||||
const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
|
||||
const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
|
||||
const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
|
||||
const double od_u_perc = od_bytes / double(od_alloced) * 100.0;
|
||||
const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
|
||||
|
||||
#define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT
|
||||
@ -691,6 +709,7 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||
tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low));
|
||||
tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low));
|
||||
tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes, 100.0, p2i(ss_low));
|
||||
tty->print_cr(fmt_space, "od", od_bytes, od_t_perc, od_alloced, od_u_perc, p2i(od_low));
|
||||
tty->print_cr("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
|
||||
total_bytes, total_alloced, total_u_perc);
|
||||
|
||||
@ -734,6 +753,10 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||
SharedMiscCodeSize,
|
||||
true, true);
|
||||
mapinfo->write_string_regions(_string_regions);
|
||||
mapinfo->write_region(MetaspaceShared::od, _od_vs.low(),
|
||||
pointer_delta(od_top, _od_vs.low(), sizeof(char)),
|
||||
pointer_delta(od_end, _od_vs.low(), sizeof(char)),
|
||||
true, false);
|
||||
}
|
||||
|
||||
mapinfo->close();
|
||||
@ -1049,8 +1072,6 @@ void MetaspaceShared::print_shared_spaces() {
|
||||
|
||||
|
||||
// Map shared spaces at requested addresses and return if succeeded.
|
||||
// Need to keep the bounds of the ro and rw space for the Metaspace::contains
|
||||
// call, or is_in_shared_space.
|
||||
bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||
size_t image_alignment = mapinfo->alignment();
|
||||
|
||||
@ -1068,6 +1089,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||
char* _rw_base = NULL;
|
||||
char* _md_base = NULL;
|
||||
char* _mc_base = NULL;
|
||||
char* _od_base = NULL;
|
||||
|
||||
// Map each shared region
|
||||
if ((_ro_base = mapinfo->map_region(ro)) != NULL &&
|
||||
@ -1078,6 +1100,8 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||
mapinfo->verify_region_checksum(md) &&
|
||||
(_mc_base = mapinfo->map_region(mc)) != NULL &&
|
||||
mapinfo->verify_region_checksum(mc) &&
|
||||
(_od_base = mapinfo->map_region(od)) != NULL &&
|
||||
mapinfo->verify_region_checksum(od) &&
|
||||
(image_alignment == (size_t)max_alignment()) &&
|
||||
mapinfo->validate_classpath_entry_table()) {
|
||||
// Success (no need to do anything)
|
||||
@ -1089,6 +1113,7 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) {
|
||||
if (_rw_base != NULL) mapinfo->unmap_region(rw);
|
||||
if (_md_base != NULL) mapinfo->unmap_region(md);
|
||||
if (_mc_base != NULL) mapinfo->unmap_region(mc);
|
||||
if (_od_base != NULL) mapinfo->unmap_region(od);
|
||||
#ifndef _WINDOWS
|
||||
// Release the entire mapped region
|
||||
shared_rs.release();
|
||||
|
@ -132,6 +132,7 @@ class MetaspaceShared : AllStatic {
|
||||
// Used only during dumping.
|
||||
static SharedMiscRegion _md;
|
||||
static SharedMiscRegion _mc;
|
||||
static SharedMiscRegion _od;
|
||||
public:
|
||||
enum {
|
||||
vtbl_list_size = DEFAULT_VTBL_LIST_SIZE,
|
||||
@ -148,7 +149,10 @@ class MetaspaceShared : AllStatic {
|
||||
max_strings = 2, // max number of string regions in string space
|
||||
num_non_strings = 4, // number of non-string regions
|
||||
first_string = num_non_strings, // index of first string region
|
||||
n_regions = max_strings + num_non_strings // total number of regions
|
||||
// The optional data region is the last region.
|
||||
// Currently it only contains class file data.
|
||||
od = max_strings + num_non_strings,
|
||||
n_regions = od + 1 // total number of regions
|
||||
};
|
||||
|
||||
// Accessor functions to save shared space created for metadata, which has
|
||||
@ -222,9 +226,10 @@ class MetaspaceShared : AllStatic {
|
||||
static int count_class(const char* classlist_file);
|
||||
static void estimate_regions_size() NOT_CDS_RETURN;
|
||||
|
||||
// Allocate a block of memory from the "mc" or "md" regions.
|
||||
// Allocate a block of memory from the "mc", "md", or "od" regions.
|
||||
static char* misc_code_space_alloc(size_t num_bytes) { return _mc.alloc(num_bytes); }
|
||||
static char* misc_data_space_alloc(size_t num_bytes) { return _md.alloc(num_bytes); }
|
||||
static char* optional_data_space_alloc(size_t num_bytes) { return _od.alloc(num_bytes); }
|
||||
|
||||
static address cds_i2i_entry_code_buffers(size_t total_size);
|
||||
|
||||
@ -243,5 +248,9 @@ class MetaspaceShared : AllStatic {
|
||||
assert(DumpSharedSpaces, "used during dumping only");
|
||||
return &_md;
|
||||
}
|
||||
static SharedMiscRegion* optional_data_region() {
|
||||
assert(DumpSharedSpaces, "used during dumping only");
|
||||
return &_od;
|
||||
}
|
||||
};
|
||||
#endif // SHARE_VM_MEMORY_METASPACESHARED_HPP
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "memory/heapInspection.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/metaspaceShared.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
@ -1972,11 +1973,6 @@ void InstanceKlass::remove_unshareable_info() {
|
||||
m->remove_unshareable_info();
|
||||
}
|
||||
|
||||
// cached_class_file might be pointing to a malloc'ed buffer allocated by
|
||||
// event-based tracing code at CDS dump time. It's not usable at runtime
|
||||
// so let's clear it.
|
||||
set_cached_class_file(NULL);
|
||||
|
||||
// do array classes also.
|
||||
array_klasses_do(remove_unshareable_in_class);
|
||||
}
|
||||
@ -2070,6 +2066,7 @@ void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) {
|
||||
}
|
||||
|
||||
void InstanceKlass::release_C_heap_structures() {
|
||||
assert(!this->is_shared(), "should not be called for a shared class");
|
||||
|
||||
// Can't release the constant pool here because the constant pool can be
|
||||
// deallocated separately from the InstanceKlass for default methods and
|
||||
@ -2250,8 +2247,8 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, TRAPS) {
|
||||
// the java.base module. If a non-java.base package is erroneously placed
|
||||
// in the java.base module it will be caught later when java.base
|
||||
// is defined by ModuleEntryTable::verify_javabase_packages check.
|
||||
assert(ModuleEntryTable::javabase_module() != NULL, "java.base module is NULL");
|
||||
_package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_module());
|
||||
assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "java.base module is NULL");
|
||||
_package_entry = loader_data->packages()->lookup(pkg_name, ModuleEntryTable::javabase_moduleEntry());
|
||||
} else {
|
||||
assert(loader_data->modules()->unnamed_module() != NULL, "unnamed module is NULL");
|
||||
_package_entry = loader_data->packages()->lookup(pkg_name,
|
||||
@ -3653,6 +3650,15 @@ Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) {
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
JvmtiCachedClassFileData* InstanceKlass::get_cached_class_file() {
|
||||
if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
|
||||
// Ignore the archived class stream data
|
||||
return NULL;
|
||||
} else {
|
||||
return _cached_class_file;
|
||||
}
|
||||
}
|
||||
|
||||
jint InstanceKlass::get_cached_class_file_len() {
|
||||
return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
|
||||
}
|
||||
@ -3660,4 +3666,15 @@ jint InstanceKlass::get_cached_class_file_len() {
|
||||
unsigned char * InstanceKlass::get_cached_class_file_bytes() {
|
||||
return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
JvmtiCachedClassFileData* InstanceKlass::get_archived_class_data() {
|
||||
assert(this->is_shared(), "class should be shared");
|
||||
if (MetaspaceShared::is_in_shared_space(_cached_class_file)) {
|
||||
return _cached_class_file;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -783,7 +783,7 @@ public:
|
||||
void set_cached_class_file(JvmtiCachedClassFileData *data) {
|
||||
_cached_class_file = data;
|
||||
}
|
||||
JvmtiCachedClassFileData * get_cached_class_file() { return _cached_class_file; }
|
||||
JvmtiCachedClassFileData * get_cached_class_file();
|
||||
jint get_cached_class_file_len();
|
||||
unsigned char * get_cached_class_file_bytes();
|
||||
|
||||
@ -795,6 +795,13 @@ public:
|
||||
return _jvmti_cached_class_field_map;
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void set_archived_class_data(JvmtiCachedClassFileData* data) {
|
||||
_cached_class_file = data;
|
||||
}
|
||||
|
||||
JvmtiCachedClassFileData * get_archived_class_data();
|
||||
#endif // INCLUDE_CDS
|
||||
#else // INCLUDE_JVMTI
|
||||
|
||||
static void purge_previous_versions(InstanceKlass* ik) { return; };
|
||||
|
@ -530,7 +530,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
|
||||
InstanceKlass* ik = (InstanceKlass*) k;
|
||||
module_entry = ik->module();
|
||||
} else {
|
||||
module_entry = ModuleEntryTable::javabase_module();
|
||||
module_entry = ModuleEntryTable::javabase_moduleEntry();
|
||||
}
|
||||
// Obtain java.lang.reflect.Module, if available
|
||||
Handle module_handle(THREAD, ((module_entry != NULL) ? JNIHandles::resolve(module_entry->module()) : (oop)NULL));
|
||||
|
@ -87,6 +87,7 @@ class oopDesc {
|
||||
inline narrowKlass* compressed_klass_addr();
|
||||
|
||||
inline void set_klass(Klass* k);
|
||||
inline void release_set_klass(Klass* k);
|
||||
|
||||
// For klass field compression
|
||||
inline int klass_gap() const;
|
||||
|
@ -129,10 +129,14 @@ narrowKlass* oopDesc::compressed_klass_addr() {
|
||||
return &_metadata._compressed_klass;
|
||||
}
|
||||
|
||||
#define CHECK_SET_KLASS(k) \
|
||||
do { \
|
||||
assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass"); \
|
||||
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \
|
||||
} while (0)
|
||||
|
||||
void oopDesc::set_klass(Klass* k) {
|
||||
// since klasses are promoted no store check is needed
|
||||
assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
|
||||
assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
|
||||
CHECK_SET_KLASS(k);
|
||||
if (UseCompressedClassPointers) {
|
||||
*compressed_klass_addr() = Klass::encode_klass_not_null(k);
|
||||
} else {
|
||||
@ -140,6 +144,18 @@ void oopDesc::set_klass(Klass* k) {
|
||||
}
|
||||
}
|
||||
|
||||
void oopDesc::release_set_klass(Klass* k) {
|
||||
CHECK_SET_KLASS(k);
|
||||
if (UseCompressedClassPointers) {
|
||||
OrderAccess::release_store(compressed_klass_addr(),
|
||||
Klass::encode_klass_not_null(k));
|
||||
} else {
|
||||
OrderAccess::release_store_ptr(klass_addr(), k);
|
||||
}
|
||||
}
|
||||
|
||||
#undef CHECK_SET_KLASS
|
||||
|
||||
int oopDesc::klass_gap() const {
|
||||
return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ TypeArrayKlass* TypeArrayKlass::create_klass(BasicType type,
|
||||
null_loader_data->add_class(ak);
|
||||
|
||||
// Call complete_create_array_klass after all instance variables have been initialized.
|
||||
complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_module(), CHECK_NULL);
|
||||
complete_create_array_klass(ak, ak->super(), ModuleEntryTable::javabase_moduleEntry(), CHECK_NULL);
|
||||
|
||||
return ak;
|
||||
}
|
||||
@ -347,7 +347,7 @@ const char* TypeArrayKlass::internal_name() const {
|
||||
|
||||
// A TypeArrayKlass is an array of a primitive type, its defining module is java.base
|
||||
ModuleEntry* TypeArrayKlass::module() const {
|
||||
return ModuleEntryTable::javabase_module();
|
||||
return ModuleEntryTable::javabase_moduleEntry();
|
||||
}
|
||||
|
||||
PackageEntry* TypeArrayKlass::package() const {
|
||||
|
@ -272,6 +272,31 @@ public:
|
||||
|
||||
// Get/PutObject must be special-cased, since it works with handles.
|
||||
|
||||
// We could be accessing the referent field in a reference
|
||||
// object. If G1 is enabled then we need to register non-null
|
||||
// referent with the SATB barrier.
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
static bool is_java_lang_ref_Reference_access(oop o, jlong offset) {
|
||||
if (offset == java_lang_ref_Reference::referent_offset && o != NULL) {
|
||||
Klass* k = o->klass();
|
||||
if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
|
||||
assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ensure_satb_referent_alive(oop o, jlong offset, oop v) {
|
||||
#if INCLUDE_ALL_GCS
|
||||
if (UseG1GC && v != NULL && is_java_lang_ref_Reference_access(o, offset)) {
|
||||
G1SATBCardTableModRefBS::enqueue(v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// These functions allow a null base pointer with an arbitrary address.
|
||||
// But if the base pointer is non-null, the offset should make some sense.
|
||||
// That is, it should be in the range [0, MAX_OBJECT_SIZE].
|
||||
@ -286,34 +311,9 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObject(JNIEnv *env, jobject unsafe, jobject obj,
|
||||
v = *(oop*)index_oop_from_field_offset_long(p, offset);
|
||||
}
|
||||
|
||||
jobject ret = JNIHandles::make_local(env, v);
|
||||
ensure_satb_referent_alive(p, offset, v);
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
// We could be accessing the referent field in a reference
|
||||
// object. If G1 is enabled then we need to register non-null
|
||||
// referent with the SATB barrier.
|
||||
if (UseG1GC) {
|
||||
bool needs_barrier = false;
|
||||
|
||||
if (ret != NULL) {
|
||||
if (offset == java_lang_ref_Reference::referent_offset && obj != NULL) {
|
||||
oop o = JNIHandles::resolve(obj);
|
||||
Klass* k = o->klass();
|
||||
if (InstanceKlass::cast(k)->reference_type() != REF_NONE) {
|
||||
assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
|
||||
needs_barrier = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_barrier) {
|
||||
oop referent = JNIHandles::resolve(ret);
|
||||
G1SATBCardTableModRefBS::enqueue(referent);
|
||||
}
|
||||
}
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
return ret;
|
||||
return JNIHandles::make_local(env, v);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_PutObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
|
||||
@ -344,6 +344,8 @@ UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobj
|
||||
(void)const_cast<oop&>(v = *(volatile oop*) addr);
|
||||
}
|
||||
|
||||
ensure_satb_referent_alive(p, offset, v);
|
||||
|
||||
OrderAccess::acquire();
|
||||
return JNIHandles::make_local(env, v);
|
||||
} UNSAFE_END
|
||||
|
@ -1596,6 +1596,10 @@ public:
|
||||
product(bool, AlwaysPreTouch, false, \
|
||||
"Force all freshly committed pages to be pre-touched") \
|
||||
\
|
||||
product(size_t, PreTouchParallelChunkSize, 1 * G, \
|
||||
"Per-thread chunk size for parallel memory pre-touch.") \
|
||||
range(1, SIZE_MAX / 2) \
|
||||
\
|
||||
product_pd(size_t, CMSYoungGenPerWorker, \
|
||||
"The maximum size of young gen chosen by default per GC worker " \
|
||||
"thread available") \
|
||||
|
@ -77,6 +77,8 @@ Mutex* Shared_SATB_Q_lock = NULL;
|
||||
Mutex* DirtyCardQ_FL_lock = NULL;
|
||||
Monitor* DirtyCardQ_CBL_mon = NULL;
|
||||
Mutex* Shared_DirtyCardQ_lock = NULL;
|
||||
Mutex* MarkStackFreeList_lock = NULL;
|
||||
Mutex* MarkStackChunkList_lock = NULL;
|
||||
Mutex* ParGCRareEvent_lock = NULL;
|
||||
Mutex* DerivedPointerTableGC_lock = NULL;
|
||||
Mutex* Compile_lock = NULL;
|
||||
@ -194,6 +196,9 @@ void mutex_init() {
|
||||
|
||||
def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);
|
||||
def(StringDedupTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_never);
|
||||
|
||||
def(MarkStackFreeList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
|
||||
def(MarkStackChunkList_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
|
||||
}
|
||||
def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes);
|
||||
def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never);
|
||||
|
@ -81,7 +81,8 @@ extern Monitor* DirtyCardQ_CBL_mon; // Protects dirty card Q
|
||||
extern Mutex* Shared_DirtyCardQ_lock; // Lock protecting dirty card
|
||||
// queue shared by
|
||||
// non-Java threads.
|
||||
// (see option ExplicitGCInvokesConcurrent)
|
||||
extern Mutex* MarkStackFreeList_lock; // Protects access to the global mark stack free list.
|
||||
extern Mutex* MarkStackChunkList_lock; // Protects access to the global mark stack chunk list.
|
||||
extern Mutex* ParGCRareEvent_lock; // Synchronizes various (rare) parallel GC ops.
|
||||
extern Mutex* Compile_lock; // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
|
||||
extern Monitor* MethodCompileQueue_lock; // a lock held when method compilations are enqueued, dequeued
|
||||
|
@ -1705,8 +1705,8 @@ bool os::release_memory(char* addr, size_t bytes) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void os::pretouch_memory(void* start, void* end) {
|
||||
for (volatile char *p = (char*)start; p < (char*)end; p += os::vm_page_size()) {
|
||||
void os::pretouch_memory(void* start, void* end, size_t page_size) {
|
||||
for (volatile char *p = (char*)start; p < (char*)end; p += page_size) {
|
||||
*p = 0;
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ class os: AllStatic {
|
||||
// to make the OS back the memory range with actual memory.
|
||||
// Current implementation may not touch the last page if unaligned addresses
|
||||
// are passed.
|
||||
static void pretouch_memory(void* start, void* end);
|
||||
static void pretouch_memory(void* start, void* end, size_t page_size = vm_page_size());
|
||||
|
||||
enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
|
||||
static bool protect_memory(char* addr, size_t bytes, ProtType prot,
|
||||
|
@ -282,6 +282,12 @@ void report_untested(const char* file, int line, const char* message) {
|
||||
}
|
||||
|
||||
void report_out_of_shared_space(SharedSpaceType shared_space) {
|
||||
if (shared_space == SharedOptional) {
|
||||
// The estimated shared_optional_space size is large enough
|
||||
// for all class bytes. It should not run out of space.
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
static const char* name[] = {
|
||||
"shared read only space",
|
||||
"shared read write space",
|
||||
|
@ -271,7 +271,8 @@ enum SharedSpaceType {
|
||||
SharedReadOnly,
|
||||
SharedReadWrite,
|
||||
SharedMiscData,
|
||||
SharedMiscCode
|
||||
SharedMiscCode,
|
||||
SharedOptional
|
||||
};
|
||||
|
||||
void report_out_of_shared_space(SharedSpaceType space_type);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -79,8 +79,8 @@ template <MEMFLAGS F> inline BasicHashtableEntry<F>* BasicHashtable<F>::bucket(i
|
||||
|
||||
|
||||
template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEntry<F>* l) {
|
||||
// Warning: Preserve store ordering. The SystemDictionary is read
|
||||
// without locks. The new SystemDictionaryEntry must be
|
||||
// Warning: Preserve store ordering. The PackageEntryTable, ModuleEntryTable and
|
||||
// SystemDictionary are read without locks. The new entry must be
|
||||
// complete before other threads can be allowed to see it
|
||||
// via a store to _buckets[index].
|
||||
OrderAccess::release_store_ptr(&_entry, l);
|
||||
@ -88,8 +88,8 @@ template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEn
|
||||
|
||||
|
||||
template <MEMFLAGS F> inline BasicHashtableEntry<F>* HashtableBucket<F>::get_entry() const {
|
||||
// Warning: Preserve load ordering. The SystemDictionary is read
|
||||
// without locks. The new SystemDictionaryEntry must be
|
||||
// Warning: Preserve load ordering. The PackageEntryTable, ModuleEntryTable and
|
||||
// SystemDictionary are read without locks. The new entry must be
|
||||
// complete before other threads can be allowed to see it
|
||||
// via a store to _buckets[index].
|
||||
return (BasicHashtableEntry<F>*) OrderAccess::load_ptr_acquire(&_entry);
|
||||
|
@ -110,10 +110,6 @@ public class TestOptionsWithRanges {
|
||||
excludeTestMaxRange("OldSize");
|
||||
excludeTestMaxRange("ParallelGCThreads");
|
||||
|
||||
excludeTestMaxRange("CompilerThreadStackSize");
|
||||
excludeTestMaxRange("ThreadStackSize");
|
||||
excludeTestMaxRange("VMThreadStackSize");
|
||||
|
||||
/*
|
||||
* Remove parameters controlling the code cache. As these
|
||||
* parameters have implications on the physical memory
|
||||
|
115
hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java
Normal file
115
hotspot/test/runtime/SharedArchiveFile/CDSTestUtils.java
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
|
||||
// This class contains common test utilities for CDS testing
|
||||
public class CDSTestUtils {
|
||||
|
||||
// check result of 'dump' operation
|
||||
public static void checkDump(OutputAnalyzer output, String... extraMatches)
|
||||
throws Exception {
|
||||
|
||||
output.shouldContain("Loading classes to share");
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
for (String match : extraMatches) {
|
||||
output.shouldContain(match);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check the output for indication that mapping of the archive failed
|
||||
public static boolean isUnableToMap(OutputAnalyzer output) {
|
||||
String outStr = output.getOutput();
|
||||
if ((output.getExitValue() == 1) && (
|
||||
outStr.contains("Unable to reserve shared space at required address") ||
|
||||
outStr.contains("Unable to map ReadOnly shared space at required address") ||
|
||||
outStr.contains("Unable to map ReadWrite shared space at required address") ||
|
||||
outStr.contains("Unable to map MiscData shared space at required address") ||
|
||||
outStr.contains("Unable to map MiscCode shared space at required address") ||
|
||||
outStr.contains("Unable to map shared string space at required address") ||
|
||||
outStr.contains("Could not allocate metaspace at a compatible address") ||
|
||||
outStr.contains("Unable to allocate shared string space: range is not within java heap") ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check result of 'exec' operation, that is when JVM is run using the archive
|
||||
public static void checkExec(OutputAnalyzer output, String... extraMatches) throws Exception {
|
||||
if (isUnableToMap(output)) {
|
||||
System.out.println("Unable to map shared archive: test did not complete; assumed PASS");
|
||||
return;
|
||||
}
|
||||
output.shouldContain("sharing");
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
for (String match : extraMatches) {
|
||||
output.shouldContain(match);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get the file object for the test artifact
|
||||
private static File getTestArtifactFile(String prefix, String name) {
|
||||
File dir = new File(System.getProperty("test.classes", "."));
|
||||
return new File(dir, prefix + name);
|
||||
}
|
||||
|
||||
|
||||
// create file containing the specified class list
|
||||
public static File makeClassList(String testCaseName, String classes[])
|
||||
throws Exception {
|
||||
|
||||
File classList = getTestArtifactFile(testCaseName, "test.classlist");
|
||||
FileOutputStream fos = new FileOutputStream(classList);
|
||||
PrintStream ps = new PrintStream(fos);
|
||||
|
||||
addToClassList(ps, classes);
|
||||
|
||||
ps.close();
|
||||
fos.close();
|
||||
|
||||
return classList;
|
||||
}
|
||||
|
||||
|
||||
private static void addToClassList(PrintStream ps, String classes[])
|
||||
throws IOException
|
||||
{
|
||||
if (classes != null) {
|
||||
for (String s : classes) {
|
||||
ps.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Implementor implements Interface {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Implementor: entering main()");
|
||||
test();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
// from interface
|
||||
(new Implementor()).printString();
|
||||
// from implementor
|
||||
System.out.println(TransformUtil.ChildCheckPattern +
|
||||
TransformUtil.BeforePattern);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public interface Interface {
|
||||
public static final String stringToBeTransformed =
|
||||
TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern;
|
||||
|
||||
default void printString() {
|
||||
System.out.println(stringToBeTransformed);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class SubClass extends SuperClazz {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("SubClass: entering main()");
|
||||
test();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
// The line below will be used to check for successful class transformation
|
||||
System.out.println(TransformUtil.ChildCheckPattern +
|
||||
TransformUtil.BeforePattern);
|
||||
(new SubClass()).callParent();
|
||||
}
|
||||
|
||||
private void callParent() {
|
||||
super.testParent();
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
public class SuperClazz {
|
||||
public static void testParent() {
|
||||
System.out.println("SuperClazz: entering testParent()");
|
||||
|
||||
// The line below will be used to check for successful class transformation
|
||||
System.out.println(TransformUtil.ParentCheckPattern + TransformUtil.BeforePattern);
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
// Test Entry - a single entry in a test table
|
||||
// that defines a test case
|
||||
// See TransformRelatedClasses.java for more details
|
||||
public class TestEntry {
|
||||
int testCaseId;
|
||||
boolean transformParent;
|
||||
boolean transformChild;
|
||||
boolean isParentExpectedShared;
|
||||
boolean isChildExpectedShared;
|
||||
|
||||
public TestEntry(int testCaseId,
|
||||
boolean transformParent, boolean transformChild,
|
||||
boolean isParentExpectedShared, boolean isChildExpectedShared) {
|
||||
this.testCaseId = testCaseId;
|
||||
this.transformParent = transformParent;
|
||||
this.transformChild = transformChild;
|
||||
this.isParentExpectedShared = isParentExpectedShared;
|
||||
this.isChildExpectedShared = isChildExpectedShared;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Exercise initial transformation (ClassFileLoadHook)
|
||||
* with CDS with Interface/Implementor pair
|
||||
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
|
||||
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
|
||||
* @requires vm.flavor != "minimal"
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* jdk.jartool/sun.tools.jar
|
||||
* java.management
|
||||
* java.instrument
|
||||
* @build TransformUtil TransformerAgent Interface Implementor
|
||||
* @run main/othervm TransformRelatedClasses Interface Implementor
|
||||
*/
|
||||
|
||||
// Clarification on @requires declarations:
|
||||
// CDS is not supported w/o the use of Compressed OOPs
|
||||
// JVMTI's ClassFileLoadHook is not supported under minimal VM
|
||||
|
||||
// This test class uses TransformRelatedClasses to do its work.
|
||||
// The goal of this test is to exercise transformation of related interface
|
||||
// and its implementor in combination with CDS.
|
||||
// The transformation is done via ClassFileLoadHook mechanism.
|
||||
// Both superclass and subclass reside in the shared archive.
|
||||
// The test consists of 4 test cases where transformation is applied
|
||||
// to an interface and an implementor in a combinatorial manner.
|
||||
// Please see TransformRelatedClasses.java for details.
|
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
// This is the main test class for testing transformation of related classes
|
||||
// in combination with CDS, to ensure these features work well together.
|
||||
// The relationships that can be tested using this test class are:
|
||||
// superclass/subclass, and interface/implementor relationships.
|
||||
//
|
||||
// The test uses combinatorial approach.
|
||||
// For details on test table and test cases see main() method in this class.
|
||||
//
|
||||
// This test consists of multiple classes for better flexibility and reuse,
|
||||
// and also relies on certain common utility code.
|
||||
// Here are the details on the structure of the test
|
||||
//
|
||||
// Structure of the test:
|
||||
// TransformRelatedClasses -- common main test driver
|
||||
// The TransformRelatedClasses is invoked from test driver classes:
|
||||
// TransformInterfaceAndImplementor, TransformSuperAndSubClasses
|
||||
// It is responsible for preparing test artifacts (test jar, agent jar
|
||||
// and the shared archive), running test cases and checking the results.
|
||||
// The following test classes below are launched in a sub-process with use
|
||||
// of shared archive:
|
||||
// SuperClazz, SubClass -- super/sub class pair under test
|
||||
// Interface, Implementor -- classes under test
|
||||
// This test will transform these classes, based on the test case data,
|
||||
// by changing a predefined unique string in each class.
|
||||
// For more details, see the test classes' code and comments.
|
||||
//
|
||||
// Other related classes:
|
||||
// TestEntry - a class representing a single test case, as test entry in the table
|
||||
// TransformTestCommon - common methods for transformation test cases
|
||||
//
|
||||
// Other utility/helper classes and files used in this test:
|
||||
// TransformerAgent - an agent that is used when JVM-under-test is executed
|
||||
// to transform specific strings inside specified classes
|
||||
// TransformerAgent.mf - accompanies transformer agent
|
||||
// CDSTestUtils - Test Utilities common to all CDS tests
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
|
||||
public class TransformRelatedClasses {
|
||||
static final String archiveName = "./TransformRelatedClasses.jsa";
|
||||
static String agentClasses[] = {
|
||||
"TransformerAgent",
|
||||
"TransformerAgent$SimpleTransformer",
|
||||
"TransformUtil"
|
||||
};
|
||||
|
||||
String parent;
|
||||
String child;
|
||||
String[] testClasses = new String[2];
|
||||
String[] testNames = new String[2];
|
||||
String testJar;
|
||||
String agentJar;
|
||||
|
||||
|
||||
private static void log(String msg) {
|
||||
System.out.println("TransformRelatedClasses: " + msg);
|
||||
}
|
||||
|
||||
|
||||
// This class is intended to test 2 parent-child relationships:
|
||||
// 1. Base Class (parent) and Derived Class (child)
|
||||
// 2. Interface (parent) and Implementor (child)
|
||||
// Parameters to main(): parent, child
|
||||
public static void main(String args[]) throws Exception {
|
||||
TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]);
|
||||
test.prepare();
|
||||
|
||||
// Test Table
|
||||
// TestEntry: (testCaseId, transformParent, tranformChild,
|
||||
// isParentExpectedShared, isChildExpectedShared)
|
||||
ArrayList<TestEntry> testTable = new ArrayList<>();
|
||||
|
||||
// base case - no tranformation - all expected to be shared
|
||||
testTable.add(new TestEntry(0, false, false, true, true));
|
||||
|
||||
// transform parent only - both parent and child should not be shared
|
||||
testTable.add(new TestEntry(1, true, false, false, false));
|
||||
|
||||
// transform parent and child - both parent and child should not be shared
|
||||
testTable.add(new TestEntry(2, true, true, false, false));
|
||||
|
||||
// transform child only - parent should still be shared, but not child
|
||||
testTable.add(new TestEntry(3, false, true, true, false));
|
||||
|
||||
// run the tests
|
||||
for (TestEntry entry : testTable) {
|
||||
test.runTest(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public TransformRelatedClasses(String parent, String child) {
|
||||
log("Constructor: parent = " + parent + ", child = " + child);
|
||||
this.parent = parent;
|
||||
this.child = child;
|
||||
testClasses[0] = parent;
|
||||
testClasses[1] = child;
|
||||
testNames[0] = parent.replace('.', '/');
|
||||
testNames[1] = child.replace('.', '/');
|
||||
}
|
||||
|
||||
|
||||
// same test jar and archive can be used for all test cases
|
||||
private void prepare() throws Exception {
|
||||
// create agent jar
|
||||
// Agent is the same for all test cases
|
||||
String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
|
||||
agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
|
||||
ClassFileInstaller.Manifest.fromSourceFile(pathToManifest),
|
||||
agentClasses);
|
||||
|
||||
// create a test jar
|
||||
testJar =
|
||||
ClassFileInstaller.writeJar(parent + "-" + child + ".jar",
|
||||
testClasses);
|
||||
|
||||
// create an archive
|
||||
File classList = CDSTestUtils.makeClassList("transform-" + parent,
|
||||
testNames);
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
|
||||
"-Xbootclasspath/a:" + testJar,
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:ExtraSharedClassListFile=" +
|
||||
classList.getPath(),
|
||||
"-XX:SharedArchiveFile=" + archiveName,
|
||||
"-XX:+PrintSharedSpaces",
|
||||
"-Xshare:dump");
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
CDSTestUtils.checkDump(out);
|
||||
}
|
||||
|
||||
|
||||
private void runTest(TestEntry entry) throws Exception {
|
||||
log("runTest(): testCaseId = " + entry.testCaseId);
|
||||
|
||||
// execute with archive
|
||||
String agentParam = "-javaagent:" + agentJar + "=" +
|
||||
TransformTestCommon.getAgentParams(entry, parent, child);
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true,
|
||||
"-Xbootclasspath/a:" + testJar,
|
||||
"-XX:+UnlockDiagnosticVMOptions",
|
||||
"-XX:SharedArchiveFile=" + archiveName,
|
||||
"-Xlog:class+load=info",
|
||||
"-Xshare:on", "-showversion",
|
||||
agentParam, child);
|
||||
OutputAnalyzer out = new OutputAnalyzer(pb.start());
|
||||
|
||||
TransformTestCommon.checkResults(entry, out, parent, child);
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Exercise initial transformation (ClassFileLoadHook)
|
||||
* with CDS with SubClass and SuperClass
|
||||
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
|
||||
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
|
||||
* @requires vm.flavor != "minimal"
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* jdk.jartool/sun.tools.jar
|
||||
* java.management
|
||||
* java.instrument
|
||||
* @build TransformUtil TransformerAgent SubClass SuperClazz
|
||||
* @run main/othervm TransformRelatedClasses SuperClazz SubClass
|
||||
*/
|
||||
|
||||
// Clarification on @requires declarations:
|
||||
// CDS is not supported w/o the use of Compressed OOPs
|
||||
// JVMTI's ClassFileLoadHook is not supported under minimal VM
|
||||
|
||||
// This test class uses TransformRelatedClasses to do its work.
|
||||
// The goal of this test is to exercise transformation of related superclass
|
||||
// and subclass in combination with CDS.
|
||||
// The transformation is done via ClassFileLoadHook mechanism.
|
||||
// Both superclass and subclass reside in the shared archive.
|
||||
// The test consists of 4 test cases where transformation is applied
|
||||
// to a parent and child in combinatorial manner.
|
||||
// Please see TransformRelatedClasses.java for details.
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Exercise initial transformation (ClassFileLoadHook)
|
||||
* with CDS with SubClass and SuperClass, each lives in own separate package
|
||||
* @library /test/lib /runtime/SharedArchiveFile /testlibrary/jvmti
|
||||
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
|
||||
* @requires vm.flavor != "minimal"
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* jdk.jartool/sun.tools.jar
|
||||
* java.management
|
||||
* java.instrument
|
||||
* @build TransformUtil TransformerAgent SubClass SuperClazz
|
||||
* @compile myPkg2/SubClass.java myPkg1/SuperClazz.java
|
||||
* @run main/othervm TransformRelatedClasses myPkg1.SuperClazz myPkg2.SubClass
|
||||
*/
|
||||
|
||||
// Clarification on @requires declarations:
|
||||
// CDS is not supported w/o the use of Compressed OOPs
|
||||
// JVMTI's ClassFileLoadHook is not supported under minimal VM
|
||||
|
||||
// This test class uses TransformRelatedClasses to do its work.
|
||||
// The goal of this test is to exercise transformation of related superclass
|
||||
// and subclass in combination with CDS; each class lives in its own package.
|
||||
// The transformation is done via ClassFileLoadHook mechanism.
|
||||
// Both superclass and subclass reside in the shared archive.
|
||||
// The test consists of 4 test cases where transformation is applied
|
||||
// to a parent and child in combinatorial manner.
|
||||
// Please see TransformRelatedClasses.java for details.
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
|
||||
// This class contains methods common to all transformation test cases
|
||||
public class TransformTestCommon {
|
||||
|
||||
// get parameters to an agent depending on the test case
|
||||
// these parameters will instruct the agent which classes should be
|
||||
// transformed
|
||||
public static String getAgentParams(TestEntry entry,
|
||||
String parent, String child) {
|
||||
|
||||
if (entry.transformParent && entry.transformChild)
|
||||
return parent + "," + child;
|
||||
if (entry.transformParent)
|
||||
return parent;
|
||||
if (entry.transformChild)
|
||||
return child;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
private static void checkTransformationResults(TestEntry entry,
|
||||
OutputAnalyzer out)
|
||||
throws Exception {
|
||||
|
||||
if (entry.transformParent)
|
||||
out.shouldContain(TransformUtil.ParentCheckPattern +
|
||||
TransformUtil.AfterPattern);
|
||||
|
||||
if (entry.transformChild)
|
||||
out.shouldContain(TransformUtil.ChildCheckPattern +
|
||||
TransformUtil.AfterPattern);
|
||||
}
|
||||
|
||||
|
||||
private static void checkSharingByClass(TestEntry entry, OutputAnalyzer out,
|
||||
String parent, String child)
|
||||
throws Exception {
|
||||
|
||||
String parentSharedMatch = parent + " source: shared objects file";
|
||||
String childSharedMatch = child + " source: shared objects file";
|
||||
|
||||
if (entry.isParentExpectedShared)
|
||||
out.shouldContain(parentSharedMatch);
|
||||
else
|
||||
out.shouldNotContain(parentSharedMatch);
|
||||
|
||||
if (entry.isChildExpectedShared)
|
||||
out.shouldContain(childSharedMatch);
|
||||
else
|
||||
out.shouldNotContain(childSharedMatch);
|
||||
}
|
||||
|
||||
|
||||
// Both parent and child classes should be passed to ClassFileTransformer.transform()
|
||||
// exactly once.
|
||||
private static void checkTransformationCounts(TestEntry entry, OutputAnalyzer out,
|
||||
String parent, String child)
|
||||
throws Exception {
|
||||
|
||||
String patternBase = "TransformerAgent: SimpleTransformer called for: ";
|
||||
|
||||
out.shouldContain(patternBase + child + "@1");
|
||||
out.shouldContain(patternBase + parent + "@1");
|
||||
|
||||
out.shouldNotContain(patternBase + child + "@2");
|
||||
out.shouldNotContain(patternBase + parent + "@2");
|
||||
}
|
||||
|
||||
|
||||
public static void checkResults(TestEntry entry, OutputAnalyzer out,
|
||||
String parent, String child)
|
||||
throws Exception {
|
||||
|
||||
// If we were not able to map an archive,
|
||||
// then do not perform other checks, since
|
||||
// there was no sharing at all
|
||||
if (CDSTestUtils.isUnableToMap(out))
|
||||
return;
|
||||
|
||||
String childVmName = child.replace('.', '/');
|
||||
String parentVmName = parent.replace('.', '/');
|
||||
|
||||
CDSTestUtils.checkExec(out);
|
||||
checkTransformationCounts(entry, out, parentVmName, childVmName);
|
||||
checkTransformationResults(entry, out);
|
||||
checkSharingByClass(entry, out, parent, child);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package myPkg1;
|
||||
|
||||
public class SuperClazz {
|
||||
public static void testParent() {
|
||||
System.out.println("SuperClazz: entering testParent()");
|
||||
|
||||
// The line below will be used to check for successful class transformation
|
||||
System.out.println("parent-transform-check: this-should-be-transformed");
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package myPkg2;
|
||||
|
||||
import myPkg1.SuperClazz;
|
||||
|
||||
public class SubClass extends SuperClazz {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("SubClass: entering main()");
|
||||
test();
|
||||
}
|
||||
|
||||
public static void test() {
|
||||
// The line below will be used to check for successful class transformation
|
||||
System.out.println("child-transform-check: this-should-be-transformed");
|
||||
(new SubClass()).callParent();
|
||||
|
||||
// Get the system packages, which should contain myPkg1 and myPkag2
|
||||
Package[] pkgs = Package.getPackages();
|
||||
for (int i = 0; i < pkgs.length; i++) {
|
||||
if (pkgs[i].getName().equals("myPkg1")) {
|
||||
for (int j = 0; j < pkgs.length; j++) {
|
||||
if (pkgs[j].getName().equals("myPkg2")) {
|
||||
return; // found myPkg1 & myPkg1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Missing system package");
|
||||
}
|
||||
|
||||
private void callParent() {
|
||||
super.testParent();
|
||||
}
|
||||
}
|
75
hotspot/test/testlibrary/jvmti/TransformUtil.java
Normal file
75
hotspot/test/testlibrary/jvmti/TransformUtil.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
public class TransformUtil {
|
||||
public static final String BeforePattern = "this-should-be-transformed";
|
||||
public static final String AfterPattern = "this-has-been--transformed";
|
||||
public static final String ParentCheckPattern = "parent-transform-check: ";
|
||||
public static final String ChildCheckPattern = "child-transform-check: ";
|
||||
|
||||
/**
|
||||
* @return the number of occurrences of the <code>from</code> string that
|
||||
* have been replaced.
|
||||
*/
|
||||
public static int replace(byte buff[], String from, String to) {
|
||||
if (to.length() != from.length()) {
|
||||
throw new RuntimeException("bad strings");
|
||||
}
|
||||
byte f[] = asciibytes(from);
|
||||
byte t[] = asciibytes(to);
|
||||
byte f0 = f[0];
|
||||
|
||||
int numReplaced = 0;
|
||||
int max = buff.length - f.length;
|
||||
for (int i = 0; i < max; ) {
|
||||
if (buff[i] == f0 && replace(buff, f, t, i)) {
|
||||
i += f.length;
|
||||
numReplaced++;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return numReplaced;
|
||||
}
|
||||
|
||||
public static boolean replace(byte buff[], byte f[], byte t[], int i) {
|
||||
for (int x = 0; x < f.length; x++) {
|
||||
if (buff[x+i] != f[x]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < f.length; x++) {
|
||||
buff[x+i] = t[x];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static byte[] asciibytes(String s) {
|
||||
byte b[] = new byte[s.length()];
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
b[i] = (byte)s.charAt(i);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
100
hotspot/test/testlibrary/jvmti/TransformerAgent.java
Normal file
100
hotspot/test/testlibrary/jvmti/TransformerAgent.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.HashMap;
|
||||
|
||||
// This is a test utility class used to transform
|
||||
// specified classes via initial transformation (ClassFileLoadHook).
|
||||
// Names of classes to be transformed are supplied as arguments,
|
||||
// the phrase to be transformed is a hard-coded predefined
|
||||
// fairly unique phrase.
|
||||
|
||||
public class TransformerAgent {
|
||||
private static String[] classesToTransform;
|
||||
|
||||
|
||||
private static void log(String msg) {
|
||||
System.out.println("TransformerAgent: " + msg);
|
||||
}
|
||||
|
||||
|
||||
// arguments are comma-separated list of classes to transform
|
||||
public static void premain(String agentArguments, Instrumentation instrumentation) {
|
||||
log("premain() is called, arguments = " + agentArguments);
|
||||
classesToTransform = agentArguments.split(",");
|
||||
instrumentation.addTransformer(new SimpleTransformer(), /*canRetransform=*/true);
|
||||
}
|
||||
|
||||
|
||||
public static void agentmain(String args, Instrumentation inst) throws Exception {
|
||||
log("agentmain() is called");
|
||||
premain(args, inst);
|
||||
}
|
||||
|
||||
|
||||
static class SimpleTransformer implements ClassFileTransformer {
|
||||
public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
|
||||
ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
|
||||
|
||||
log("SimpleTransformer called for: " + name + "@" + incrCounter(name));
|
||||
if (!shouldTransform(name))
|
||||
return null;
|
||||
|
||||
log("transforming: class name = " + name);
|
||||
int nrOfReplacements = TransformUtil.replace(buffer, TransformUtil.BeforePattern,
|
||||
TransformUtil.AfterPattern);
|
||||
log("replaced the string, nrOfReplacements = " + nrOfReplacements);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Check class name pattern, since test should only transform certain classes
|
||||
private static boolean shouldTransform(String name) {
|
||||
for (String match : classesToTransform) {
|
||||
if (name.matches(match)) {
|
||||
log("shouldTransform: match-found, match = " + match);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static HashMap<String, Integer> counterMap = new HashMap<>();
|
||||
|
||||
static Integer incrCounter(String className) {
|
||||
Integer i = counterMap.get(className);
|
||||
if (i == null) {
|
||||
i = new Integer(1);
|
||||
} else {
|
||||
i = new Integer(i.intValue() + 1);
|
||||
}
|
||||
counterMap.put(className, i);
|
||||
return i;
|
||||
}
|
||||
}
|
5
hotspot/test/testlibrary/jvmti/TransformerAgent.mf
Normal file
5
hotspot/test/testlibrary/jvmti/TransformerAgent.mf
Normal file
@ -0,0 +1,5 @@
|
||||
Manifest-Version: 1.0
|
||||
Premain-Class: TransformerAgent
|
||||
Agent-Class: TransformerAgent
|
||||
Can-Retransform-Classes: true
|
||||
Can-Redefine-Classes: false
|
@ -380,3 +380,4 @@ e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
|
||||
f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135
|
||||
f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136
|
||||
a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137
|
||||
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
|
||||
|
@ -383,3 +383,4 @@ ab1d78d395d4cb8be426ff181211da1a4085cf01 jdk-9+134
|
||||
22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135
|
||||
09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136
|
||||
297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137
|
||||
7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138
|
||||
|
@ -381,3 +381,4 @@ d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
|
||||
54c5931849a33a363e03fdffa141503f5cc4779d jdk-9+136
|
||||
e72df94364e3686e7d62059ce0d6b187b82da713 jdk-9+137
|
||||
665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
|
||||
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
|
||||
|
@ -1,27 +1,27 @@
|
||||
|
||||
OPENJDK ASSEMBLY EXCEPTION
|
||||
|
||||
The OpenJDK source code made available by Sun at openjdk.java.net and
|
||||
openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the
|
||||
GNU General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
|
||||
The OpenJDK source code made available by Oracle America, Inc. (Oracle) at
|
||||
openjdk.java.net ("OpenJDK Code") is distributed under the terms of the GNU
|
||||
General Public License <http://www.gnu.org/copyleft/gpl.html> version 2
|
||||
only ("GPL2"), with the following clarification and special exception.
|
||||
|
||||
Linking this OpenJDK Code statically or dynamically with other code
|
||||
is making a combined work based on this library. Thus, the terms
|
||||
and conditions of GPL2 cover the whole combination.
|
||||
|
||||
As a special exception, Sun gives you permission to link this
|
||||
OpenJDK Code with certain code licensed by Sun as indicated at
|
||||
As a special exception, Oracle gives you permission to link this
|
||||
OpenJDK Code with certain code licensed by Oracle as indicated at
|
||||
http://openjdk.java.net/legal/exception-modules-2007-05-08.html
|
||||
("Designated Exception Modules") to produce an executable,
|
||||
regardless of the license terms of the Designated Exception Modules,
|
||||
and to copy and distribute the resulting executable under GPL2,
|
||||
provided that the Designated Exception Modules continue to be
|
||||
governed by the licenses under which they were offered by Sun.
|
||||
governed by the licenses under which they were offered by Oracle.
|
||||
|
||||
As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to
|
||||
build an executable that includes those portions of necessary code that Sun
|
||||
could not provide under GPL2 (or that Sun has provided under GPL2 with the
|
||||
Classpath exception). If you modify or add to the OpenJDK code, that new
|
||||
GPL2 code may still be combined with Designated Exception Modules if the
|
||||
new code is made subject to this exception by its copyright holder.
|
||||
As such, it allows licensees and sublicensees of Oracle's GPL2 OpenJDK Code
|
||||
to build an executable that includes those portions of necessary code that
|
||||
Oracle could not provide under GPL2 (or that Oracle has provided under GPL2
|
||||
with the Classpath exception). If you modify or add to the OpenJDK code,
|
||||
that new GPL2 code may still be combined with Designated Exception Modules
|
||||
if the new code is made subject to this exception by its copyright holder.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -338,6 +338,7 @@ define SetupBuildJvmtiDemoBody
|
||||
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jvmti/$1, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/image/jvmti/$1/lib, \
|
||||
LIBRARY := $1, \
|
||||
STRIP_SYMBOLS := false, \
|
||||
))
|
||||
|
||||
$1 += $$(BUILD_DEMO_JVMTI_NATIVE_$1)
|
||||
@ -453,6 +454,7 @@ ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native/jni/Poller, \
|
||||
OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/demos/native, \
|
||||
LIBRARY := Poller, \
|
||||
STRIP_SYMBOLS := false, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_DEMO_NATIVE_Poller)
|
||||
|
42
jdk/make/CompileModuleTools.gmk
Normal file
42
jdk/make/CompileModuleTools.gmk
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
include JavaCompilation.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
|
||||
TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
|
||||
|
||||
$(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
|
||||
SETUP := GENERATE_USINGJDKBYTECODE, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/classes, \
|
||||
INCLUDES := build/tools/deps \
|
||||
build/tools/jigsaw, \
|
||||
BIN := $(TOOLS_CLASSES_DIR), \
|
||||
ADD_JAVAC_FLAGS := \
|
||||
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
|
||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||
))
|
@ -1,225 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
default: all
|
||||
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
|
||||
################################################################################
|
||||
|
||||
# Put the libraries here. Different locations for different target OS types.
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||
HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
|
||||
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
|
||||
else
|
||||
HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin
|
||||
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Import hotspot
|
||||
#
|
||||
|
||||
# Don't import jsig library for static builds
|
||||
ifneq ($(STATIC_BUILD), true)
|
||||
JSIG_IMPORT = jsig.*
|
||||
else
|
||||
JSIG_IMPORT =
|
||||
endif
|
||||
|
||||
HOTSPOT_BASE_IMPORT_FILES := \
|
||||
$(addprefix $(LIBRARY_PREFIX), jvm.* $(JSIG_IMPORT) jvm_db.* jvm_dtrace.*) \
|
||||
Xusage.txt \
|
||||
#
|
||||
|
||||
$(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE, \
|
||||
SRC := $(HOTSPOT_LIB_DIR), \
|
||||
DEST := $(BASE_INSTALL_LIBRARIES_HERE), \
|
||||
FILES := $(shell $(FIND) $(HOTSPOT_LIB_DIR) -type f \
|
||||
-a \( -name DUMMY $(addprefix -o$(SPACE)-name$(SPACE), $(HOTSPOT_BASE_IMPORT_FILES)) \) )))
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
$(eval $(call SetupCopyFiles,COPY_HOTSPOT_BASE_JVMLIB, \
|
||||
SRC := $(HOTSPOT_DIST)/lib, \
|
||||
DEST := $(BASE_INSTALL_LIBRARIES_HERE), \
|
||||
FILES := $(wildcard $(HOTSPOT_DIST)/lib/*.lib)))
|
||||
endif
|
||||
|
||||
BASE_TARGETS := $(COPY_HOTSPOT_BASE) $(COPY_HOTSPOT_BASE_JVMLIB)
|
||||
|
||||
################################################################################
|
||||
|
||||
ifneq ($(STATIC_BUILD), true)
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
|
||||
$(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
|
||||
else
|
||||
JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
|
||||
$(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
|
||||
endif
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), windows)
|
||||
ifeq ($(call check-jvm-variant, server), true)
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
|
||||
ifneq (, $(JSIG_DEBUGINFO))
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
|
||||
endif
|
||||
endif
|
||||
ifeq ($(call check-jvm-variant, client), true)
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
|
||||
ifneq (, $(JSIG_DEBUGINFO))
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
|
||||
endif
|
||||
endif
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
ifeq ($(call check-jvm-variant, minimal), true)
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
|
||||
ifneq (,$(JSIG_DEBUGINFO))
|
||||
BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/server/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/server/%.dSYM:
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/server/%.diz : $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(RM) $@.tmp $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(LN) -s ../$(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(RM) $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(MV) $@.tmp $@
|
||||
else
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/server/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/server/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(RM) $@.tmp $(basename $@).debuginfo
|
||||
$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
|
||||
$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
|
||||
$(RM) $(basename $@).debuginfo
|
||||
$(MV) $@.tmp $@
|
||||
endif
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/client/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/client/%.dSYM : $(BASE_INSTALL_LIBRARIES_HERE)/%.dSYM
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/client/%.diz : $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(RM) $@.tmp $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(LN) -s ../$(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F))$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(RM) $(basename $@)$(SHARED_LIBRARY_SUFFIX).dSYM
|
||||
$(MV) $@.tmp $@
|
||||
else
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/client/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/client/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(RM) $@.tmp $(basename $@).debuginfo
|
||||
$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
|
||||
$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
|
||||
$(RM) $(basename $@).debuginfo
|
||||
$(MV) $@.tmp $@
|
||||
endif
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/minimal/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_LIBRARIES_HERE)/%$(SHARED_LIBRARY_SUFFIX)
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
ifneq ($(OPENJDK_TARGET_OS), macosx)
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/minimal/%.debuginfo: $(BASE_INSTALL_LIBRARIES_HERE)/%.debuginfo
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(LN) -s ../$(@F) $@
|
||||
|
||||
$(BASE_INSTALL_LIBRARIES_HERE)/minimal/%.diz: $(BASE_INSTALL_LIBRARIES_HERE)/%.diz
|
||||
$(MKDIR) -p $(@D)
|
||||
$(RM) $@
|
||||
$(RM) $@.tmp $(basename $@).debuginfo
|
||||
$(LN) -s ../$(basename $(@F)).debuginfo $(basename $@).debuginfo
|
||||
$(CD) $(@D) && $(ZIP) -q -y $@.tmp $(basename $(@F)).debuginfo
|
||||
$(RM) $(basename $@).debuginfo
|
||||
$(MV) $@.tmp $@
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
||||
ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
$(eval $(call SetupCopyFiles,BASE_COPY_LIBS_BIN, \
|
||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
|
||||
DEST := $(JDK_OUTPUTDIR)/bin, \
|
||||
FILES := $(filter-out %.lib, $(BASE_TARGETS))))
|
||||
|
||||
$(eval $(call SetupCopyFiles,BASE_COPY_LIBS_LIB, \
|
||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
|
||||
DEST := $(JDK_OUTPUTDIR)/lib, \
|
||||
FILES := $(filter %.lib, $(BASE_TARGETS))))
|
||||
|
||||
else
|
||||
$(eval $(call SetupCopyFiles,BASE_COPY_LIBS, \
|
||||
SRC := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base, \
|
||||
DEST := $(JDK_OUTPUTDIR)/lib, \
|
||||
FILES := $(BASE_TARGETS)))
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
|
||||
all: $(BASE_TARGETS) $(BASE_COPY_LIBS_BIN) $(BASE_COPY_LIBS_LIB) \
|
||||
$(BASE_COPY_LIBS)
|
||||
|
||||
.PHONY: default all
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,18 +26,14 @@
|
||||
include $(SPEC)
|
||||
include MakeBase.gmk
|
||||
include JavaCompilation.gmk
|
||||
include SetupJavaCompilers.gmk
|
||||
|
||||
TOOLS_CLASSES_DIR := $(BUILDTOOLS_OUTPUTDIR)/tools_jigsaw_classes
|
||||
|
||||
$(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
|
||||
SETUP := GENERATE_USINGJDKBYTECODE, \
|
||||
SRC := $(JDK_TOPDIR)/make/src/classes, \
|
||||
INCLUDES := build/tools/deps \
|
||||
build/tools/jigsaw, \
|
||||
BIN := $(TOOLS_CLASSES_DIR), \
|
||||
ADD_JAVAC_FLAGS := --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
|
||||
|
||||
# To avoid reevaluating the compilation setup for the tools each time this file
|
||||
# is included, the actual compilation is handled by CompileModuleTools.gmk. The
|
||||
# following trick is used to be able to declare a dependency on the built tools.
|
||||
BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
|
||||
BUILD_JIGSAW_TOOLS, $(TOOLS_CLASSES_DIR))
|
||||
|
||||
TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
|
||||
build.tools.jigsaw.GenGraphs
|
||||
@ -45,3 +41,8 @@ TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
|
||||
TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
|
||||
--add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
|
||||
build.tools.jigsaw.ModuleSummary
|
||||
|
||||
TOOL_ADD_PACKAGES_ATTRIBUTE := $(BUILD_JAVA) $(JAVA_FLAGS_SMALL) \
|
||||
-cp $(TOOLS_CLASSES_DIR) \
|
||||
--add-exports java.base/jdk.internal.module=ALL-UNNAMED \
|
||||
build.tools.jigsaw.AddPackagesAttribute
|
||||
|
@ -21,4 +21,4 @@
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
tzdata2016f
|
||||
tzdata2016g
|
||||
|
@ -487,7 +487,7 @@ Zone Africa/Monrovia -0:43:08 - LMT 1882
|
||||
# http://www.libyaherald.com/2013/10/24/correction-no-time-change-tomorrow/
|
||||
#
|
||||
# From Paul Eggert (2013-10-25):
|
||||
# For now, assume they're reverting to the pre-2012 rules of permanent UTC+2.
|
||||
# For now, assume they're reverting to the pre-2012 rules of permanent UT +02.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Libya 1951 only - Oct 14 2:00 1:00 S
|
||||
|
@ -33,9 +33,7 @@
|
||||
# http://www.spri.cam.ac.uk/bob/periant.htm
|
||||
# for information.
|
||||
# Unless otherwise specified, we have no time zone information.
|
||||
#
|
||||
# Except for the French entries,
|
||||
# I made up all time zone abbreviations mentioned here; corrections welcome!
|
||||
|
||||
# FORMAT is '-00' and GMTOFF is 0 for locations while uninhabited.
|
||||
|
||||
# Argentina - year-round bases
|
||||
@ -52,7 +50,7 @@
|
||||
# previously sealers and scientific personnel wintered
|
||||
# Margaret Turner reports
|
||||
# http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html
|
||||
# (1999-09-30) that they're UTC+5, with no DST;
|
||||
# (1999-09-30) that they're UT +05, with no DST;
|
||||
# presumably this is when they have visitors.
|
||||
#
|
||||
# year-round bases
|
||||
@ -91,23 +89,22 @@
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Antarctica/Casey 0 - -00 1969
|
||||
8:00 - AWST 2009 Oct 18 2:00
|
||||
# Australian Western Std Time
|
||||
11:00 - CAST 2010 Mar 5 2:00 # Casey Time
|
||||
8:00 - AWST 2011 Oct 28 2:00
|
||||
11:00 - CAST 2012 Feb 21 17:00u
|
||||
8:00 - AWST
|
||||
8:00 - +08 2009 Oct 18 2:00
|
||||
11:00 - +11 2010 Mar 5 2:00
|
||||
8:00 - +08 2011 Oct 28 2:00
|
||||
11:00 - +11 2012 Feb 21 17:00u
|
||||
8:00 - +08
|
||||
Zone Antarctica/Davis 0 - -00 1957 Jan 13
|
||||
7:00 - DAVT 1964 Nov # Davis Time
|
||||
7:00 - +07 1964 Nov
|
||||
0 - -00 1969 Feb
|
||||
7:00 - DAVT 2009 Oct 18 2:00
|
||||
5:00 - DAVT 2010 Mar 10 20:00u
|
||||
7:00 - DAVT 2011 Oct 28 2:00
|
||||
5:00 - DAVT 2012 Feb 21 20:00u
|
||||
7:00 - DAVT
|
||||
7:00 - +07 2009 Oct 18 2:00
|
||||
5:00 - +05 2010 Mar 10 20:00u
|
||||
7:00 - +07 2011 Oct 28 2:00
|
||||
5:00 - +05 2012 Feb 21 20:00u
|
||||
7:00 - +07
|
||||
Zone Antarctica/Mawson 0 - -00 1954 Feb 13
|
||||
6:00 - MAWT 2009 Oct 18 2:00 # Mawson Time
|
||||
5:00 - MAWT
|
||||
6:00 - +06 2009 Oct 18 2:00
|
||||
5:00 - +05
|
||||
# References:
|
||||
# Casey Weather (1998-02-26)
|
||||
# http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html
|
||||
@ -161,7 +158,7 @@ Zone Antarctica/Mawson 0 - -00 1954 Feb 13
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
|
||||
5:00 - TFT # ISO code TF Time
|
||||
5:00 - +05
|
||||
#
|
||||
# year-round base in the main continent
|
||||
# Dumont d'Urville, Île des Pétrels, -6640+14001, since 1956-11
|
||||
@ -172,9 +169,9 @@ Zone Indian/Kerguelen 0 - -00 1950 # Port-aux-Français
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Antarctica/DumontDUrville 0 - -00 1947
|
||||
10:00 - PMT 1952 Jan 14 # Port-Martin Time
|
||||
10:00 - +10 1952 Jan 14
|
||||
0 - -00 1956 Nov
|
||||
10:00 - DDUT # Dumont-d'Urville Time
|
||||
10:00 - +10
|
||||
|
||||
# France & Italy - year-round base
|
||||
# Concordia, -750600+1232000, since 2005
|
||||
@ -200,7 +197,7 @@ Zone Antarctica/DumontDUrville 0 - -00 1947
|
||||
# station of Japan, it's appropriate for the principal location.
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Antarctica/Syowa 0 - -00 1957 Jan 29
|
||||
3:00 - SYOT # Syowa Time
|
||||
3:00 - +03
|
||||
# See:
|
||||
# NIPR Antarctic Research Activities (1999-08-17)
|
||||
# http://www.nipr.ac.jp/english/ara01.html
|
||||
@ -237,17 +234,17 @@ Zone Antarctica/Syowa 0 - -00 1957 Jan 29
|
||||
# correct, but they should be quite close to the actual dates.
|
||||
#
|
||||
# From Paul Eggert (2014-03-21):
|
||||
# The CET-switching Troll rules require zic from tzcode 2014b or later, so as
|
||||
# The CET-switching Troll rules require zic from tz 2014b or later, so as
|
||||
# suggested by Bengt-Inge Larsson comment them out for now, and approximate
|
||||
# with only UTC and CEST. Uncomment them when 2014b is more prevalent.
|
||||
#
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
#Rule Troll 2005 max - Mar 1 1:00u 1:00 CET
|
||||
Rule Troll 2005 max - Mar lastSun 1:00u 2:00 CEST
|
||||
#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 CET
|
||||
#Rule Troll 2004 max - Nov 7 1:00u 0:00 UTC
|
||||
#Rule Troll 2005 max - Mar 1 1:00u 1:00 +01
|
||||
Rule Troll 2005 max - Mar lastSun 1:00u 2:00 +02
|
||||
#Rule Troll 2005 max - Oct lastSun 1:00u 1:00 +01
|
||||
#Rule Troll 2004 max - Nov 7 1:00u 0:00 +00
|
||||
# Remove the following line when uncommenting the above '#Rule' lines.
|
||||
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 UTC
|
||||
Rule Troll 2004 max - Oct lastSun 1:00u 0:00 +00
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Antarctica/Troll 0 - -00 2005 Feb 12
|
||||
0:00 Troll %s
|
||||
@ -288,10 +285,10 @@ Zone Antarctica/Troll 0 - -00 2005 Feb 12
|
||||
# changes during the year and does not necessarily correspond to mean
|
||||
# solar noon. So the Vostok time might have been whatever the clocks
|
||||
# happened to be during their visit. So we still don't really know what time
|
||||
# it is at Vostok. But we'll guess UTC+6.
|
||||
# it is at Vostok. But we'll guess +06.
|
||||
#
|
||||
Zone Antarctica/Vostok 0 - -00 1957 Dec 16
|
||||
6:00 - VOST # Vostok time
|
||||
6:00 - +06
|
||||
|
||||
# S Africa - year-round bases
|
||||
# Marion Island, -4653+03752
|
||||
@ -324,7 +321,7 @@ Zone Antarctica/Vostok 0 - -00 1957 Dec 16
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Antarctica/Rothera 0 - -00 1976 Dec 1
|
||||
-3:00 - ROTT # Rothera time
|
||||
-3:00 - -03
|
||||
|
||||
# Uruguay - year round base
|
||||
# Artigas, King George Island, -621104-0585107
|
||||
|
@ -139,13 +139,11 @@ Zone Asia/Kabul 4:36:48 - LMT 1890
|
||||
# http://www.worldtimezone.com/dst_news/dst_news_armenia03.html
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Yerevan 2:58:00 - LMT 1924 May 2
|
||||
3:00 - YERT 1957 Mar # Yerevan Time
|
||||
4:00 RussiaAsia YER%sT 1991 Mar 31 2:00s
|
||||
3:00 1:00 YERST 1991 Sep 23 # independence
|
||||
3:00 RussiaAsia AM%sT 1995 Sep 24 2:00s
|
||||
4:00 - AMT 1997
|
||||
4:00 RussiaAsia AM%sT 2012 Feb 9
|
||||
4:00 - AMT
|
||||
3:00 - +03 1957 Mar
|
||||
4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
|
||||
3:00 RussiaAsia +03/+04 1995 Sep 24 2:00s
|
||||
4:00 - +04 1997
|
||||
4:00 RussiaAsia +04/+05
|
||||
|
||||
# Azerbaijan
|
||||
|
||||
@ -166,13 +164,12 @@ Rule Azer 1997 2015 - Mar lastSun 4:00 1:00 S
|
||||
Rule Azer 1997 2015 - Oct lastSun 5:00 0 -
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Baku 3:19:24 - LMT 1924 May 2
|
||||
3:00 - BAKT 1957 Mar # Baku Time
|
||||
4:00 RussiaAsia BAK%sT 1991 Mar 31 2:00s
|
||||
3:00 1:00 BAKST 1991 Aug 30 # independence
|
||||
3:00 RussiaAsia AZ%sT 1992 Sep lastSun 2:00s
|
||||
4:00 - AZT 1996 # Azerbaijan Time
|
||||
4:00 EUAsia AZ%sT 1997
|
||||
4:00 Azer AZ%sT
|
||||
3:00 - +03 1957 Mar
|
||||
4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
|
||||
3:00 RussiaAsia +03/+04 1992 Sep lastSun 2:00s
|
||||
4:00 - +04 1996
|
||||
4:00 EUAsia +04/+05 1997
|
||||
4:00 Azer +04/+05
|
||||
|
||||
# Bahrain
|
||||
# See Asia/Qatar.
|
||||
@ -291,7 +288,7 @@ Zone Asia/Brunei 7:39:40 - LMT 1926 Mar # Bandar Seri Begawan
|
||||
# Milne says 6:24:40 was the meridian of the time ball observatory at Rangoon.
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Rangoon 6:24:40 - LMT 1880 # or Yangon
|
||||
Zone Asia/Yangon 6:24:40 - LMT 1880 # or Rangoon
|
||||
6:24:40 - RMT 1920 # Rangoon Mean Time?
|
||||
6:30 - BURT 1942 May # Burma Time
|
||||
9:00 - JST 1945 May 3
|
||||
@ -406,7 +403,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
# Lewiston (ME) Daily Sun (1939-05-29), p 17, said "Even the time is
|
||||
# different - the occupied districts going by Tokyo time, an hour
|
||||
# ahead of that prevailing in the rest of Shanghai." Guess that the
|
||||
# Xujiahui Observatory was under French control and stuck with UT+8.
|
||||
# Xujiahui Observatory was under French control and stuck with UT +08.
|
||||
#
|
||||
# In earlier versions of this file, China had many separate Zone entries, but
|
||||
# this was based on what were apparently incorrect data in Shanks & Pottenger.
|
||||
@ -415,26 +412,26 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
# Proposed in 1918 and theoretically in effect until 1949 (although in practice
|
||||
# mainly observed in coastal areas), the five zones were:
|
||||
#
|
||||
# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT+8.5
|
||||
# Changbai Time ("Long-white Time", Long-white = Heilongjiang area) UT +08:30
|
||||
# Asia/Harbin (currently a link to Asia/Shanghai)
|
||||
# Heilongjiang (except Mohe county), Jilin
|
||||
#
|
||||
# Zhongyuan Time ("Central plain Time") UT+8
|
||||
# Zhongyuan Time ("Central plain Time") UT +08
|
||||
# Asia/Shanghai
|
||||
# most of China
|
||||
# This currently represents most other zones as well,
|
||||
# as apparently these regions have been the same since 1970.
|
||||
# Milne gives 8:05:43.2 for Xujiahui Observatory time; round to nearest.
|
||||
# Guo says Shanghai switched to UT+8 "from the end of the 19th century".
|
||||
# Guo says Shanghai switched to UT +08 "from the end of the 19th century".
|
||||
#
|
||||
# Long-shu Time (probably due to Long and Shu being two names of that area) UT+7
|
||||
# Long-shu Time (probably due to Long and Shu being two names of the area) UT +07
|
||||
# Asia/Chongqing (currently a link to Asia/Shanghai)
|
||||
# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
|
||||
# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
|
||||
# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
|
||||
# Yangchun, Yangjiang, Yu'nan, and Yunfu.
|
||||
#
|
||||
# Xin-zang Time ("Xinjiang-Tibet Time") UT+6
|
||||
# Xin-zang Time ("Xinjiang-Tibet Time") UT +06
|
||||
# Asia/Urumqi
|
||||
# This currently represents Kunlun Time as well,
|
||||
# as apparently the two regions have been the same since 1970.
|
||||
@ -447,7 +444,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
|
||||
# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
|
||||
#
|
||||
# Kunlun Time UT+5.5
|
||||
# Kunlun Time UT +05:30
|
||||
# Asia/Kashgar (currently a link to Asia/Urumqi)
|
||||
# West Tibet, including Pulan, Aheqi, Shufu, Shule;
|
||||
# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
|
||||
@ -463,7 +460,7 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
#
|
||||
# On the other hand, ethnic Uyghurs, who make up about half the
|
||||
# population of Xinjiang, typically use "Xinjiang time" which is two
|
||||
# hours behind Beijing time, or UTC +0600. The government of the Xinjiang
|
||||
# hours behind Beijing time, or UT +06. The government of the Xinjiang
|
||||
# Uyghur Autonomous Region, (XAUR, or just Xinjiang for short) as well as
|
||||
# local governments such as the Ürümqi city government use both times in
|
||||
# publications, referring to what is popularly called Xinjiang time as
|
||||
@ -519,8 +516,8 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
# having the same time as Beijing.
|
||||
|
||||
# From Paul Eggert (2014-06-30):
|
||||
# In the early days of the PRC, Tibet was given its own time zone (UT+6) but
|
||||
# this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
|
||||
# In the early days of the PRC, Tibet was given its own time zone (UT +06)
|
||||
# but this was withdrawn in 1959 and never reinstated; see Tubten Khétsun,
|
||||
# Memories of life in Lhasa under Chinese Rule, Columbia U Press, ISBN
|
||||
# 978-0231142861 (2008), translator's introduction by Matthew Akester, p x.
|
||||
# As this is before our 1970 cutoff, Tibet doesn't need a separate zone.
|
||||
@ -534,12 +531,12 @@ Rule PRC 1987 1991 - Apr Sun>=10 0:00 1:00 D
|
||||
# Republics, the Soviet Union, the Kuomintang, and the People's Republic of
|
||||
# China, and tracking down all these organizations' timekeeping rules would be
|
||||
# quite a trick. Approximate this lost history by a transition from LMT to
|
||||
# XJT at the start of 1928, the year of accession of the warlord Jin Shuren,
|
||||
# UT +06 at the start of 1928, the year of accession of the warlord Jin Shuren,
|
||||
# which happens to be the date given by Shanks & Pottenger (no doubt as a
|
||||
# guess) as the transition from LMT. Ignore the usage of UT+8 before
|
||||
# 1986-02-01 under the theory that the transition date to UT+8 is unknown and
|
||||
# guess) as the transition from LMT. Ignore the usage of +08 before
|
||||
# 1986-02-01 under the theory that the transition date to +08 is unknown and
|
||||
# that the sort of users who prefer Asia/Urumqi now typically ignored the
|
||||
# UT+8 mandate back then.
|
||||
# +08 mandate back then.
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
# Beijing time, used throughout China; represented by Shanghai.
|
||||
@ -744,7 +741,7 @@ Zone Asia/Hong_Kong 7:36:42 - LMT 1904 Oct 30
|
||||
# be found from historical government announcement database.
|
||||
|
||||
# From Paul Eggert (2014-07-03):
|
||||
# As per Yu-Cheng Chuang, say that Taiwan was at UT+9 from 1937-10-01
|
||||
# As per Yu-Cheng Chuang, say that Taiwan was at UT +09 from 1937-10-01
|
||||
# until 1945-09-21 at 01:00, overriding Shanks & Pottenger.
|
||||
# Likewise, use Yu-Cheng Chuang's data for DST in Taiwan.
|
||||
|
||||
@ -858,16 +855,15 @@ Link Asia/Nicosia Europe/Nicosia
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Tbilisi 2:59:11 - LMT 1880
|
||||
2:59:11 - TBMT 1924 May 2 # Tbilisi Mean Time
|
||||
3:00 - TBIT 1957 Mar # Tbilisi Time
|
||||
4:00 RussiaAsia TBI%sT 1991 Mar 31 2:00s
|
||||
3:00 1:00 TBIST 1991 Apr 9 # independence
|
||||
3:00 RussiaAsia GE%sT 1992 # Georgia Time
|
||||
3:00 E-EurAsia GE%sT 1994 Sep lastSun
|
||||
4:00 E-EurAsia GE%sT 1996 Oct lastSun
|
||||
4:00 1:00 GEST 1997 Mar lastSun
|
||||
4:00 E-EurAsia GE%sT 2004 Jun 27
|
||||
3:00 RussiaAsia GE%sT 2005 Mar lastSun 2:00
|
||||
4:00 - GET
|
||||
3:00 - +03 1957 Mar
|
||||
4:00 RussiaAsia +04/+05 1991 Mar 31 2:00s
|
||||
3:00 RussiaAsia +03/+04 1992
|
||||
3:00 E-EurAsia +03/+04 1994 Sep lastSun
|
||||
4:00 E-EurAsia +04/+05 1996 Oct lastSun
|
||||
4:00 1:00 +05 1997 Mar lastSun
|
||||
4:00 E-EurAsia +04/+05 2004 Jun 27
|
||||
3:00 RussiaAsia +03/+04 2005 Mar lastSun 2:00
|
||||
4:00 - +04
|
||||
|
||||
# East Timor
|
||||
|
||||
@ -944,7 +940,7 @@ Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata
|
||||
# These would be the earliest possible times for a change.
|
||||
# Régimes horaires pour le monde entier, by Henri Le Corre, (Éditions
|
||||
# Traditionnelles, 1987, Paris) says that Java and Madura switched
|
||||
# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
|
||||
# from UT +09 to +07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
|
||||
# (Hollandia). For now, assume all Indonesian locations other than Jayapura
|
||||
# switched on 1945-09-23.
|
||||
#
|
||||
@ -955,11 +951,11 @@ Zone Asia/Kolkata 5:53:28 - LMT 1880 # Kolkata
|
||||
# summary published by the Time and Frequency Laboratory of the
|
||||
# Research Center for Calibration, Instrumentation and Metrology,
|
||||
# Indonesia, <http://time.kim.lipi.go.id/time-eng.php> (2006-09-29).
|
||||
# The abbreviations are:
|
||||
# The time zone abbreviations and UT offsets are:
|
||||
#
|
||||
# WIB - UTC+7 - Waktu Indonesia Barat (Indonesia western time)
|
||||
# WITA - UTC+8 - Waktu Indonesia Tengah (Indonesia central time)
|
||||
# WIT - UTC+9 - Waktu Indonesia Timur (Indonesia eastern time)
|
||||
# WIB - +07 - Waktu Indonesia Barat (Indonesia western time)
|
||||
# WITA - +08 - Waktu Indonesia Tengah (Indonesia central time)
|
||||
# WIT - +09 - Waktu Indonesia Timur (Indonesia eastern time)
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
# Java, Sumatra
|
||||
@ -1848,11 +1844,11 @@ Rule Kyrgyz 1997 2005 - Mar lastSun 2:30 1:00 S
|
||||
Rule Kyrgyz 1997 2004 - Oct lastSun 2:30 0 -
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2
|
||||
5:00 - FRUT 1930 Jun 21 # Frunze Time
|
||||
6:00 RussiaAsia FRU%sT 1991 Mar 31 2:00s
|
||||
5:00 1:00 FRUST 1991 Aug 31 2:00 # independence
|
||||
5:00 Kyrgyz KG%sT 2005 Aug 12 # Kyrgyzstan Time
|
||||
6:00 - KGT
|
||||
5:00 - +05 1930 Jun 21
|
||||
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
|
||||
5:00 RussiaAsia +05/+06 1991 Aug 31 2:00
|
||||
5:00 Kyrgyz +05/+06 2005 Aug 12
|
||||
6:00 - +06
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -1891,25 +1887,24 @@ Rule ROK 1957 1960 - Sep Sun>=18 0:00 0 S
|
||||
Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D
|
||||
Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
|
||||
|
||||
# From Paul Eggert (2014-10-30):
|
||||
# From Paul Eggert (2016-08-23):
|
||||
# The Korean Wikipedia entry gives the following sources for UT offsets:
|
||||
#
|
||||
# 1908: Official Journal Article No. 3994 (Edict No. 5)
|
||||
# 1908: Official Journal Article No. 3994 (decree No. 5)
|
||||
# 1912: Governor-General of Korea Official Gazette Issue No. 367
|
||||
# (Announcement No. 338)
|
||||
# 1954: Presidential Decree No. 876 (1954-03-17)
|
||||
# 1961: Law No. 676 (1961-08-07)
|
||||
# 1987: Law No. 3919 (1986-12-31)
|
||||
#
|
||||
# The Wikipedia entry also has confusing information about a change
|
||||
# to UT+9 in April 1910, but then what would be the point of the later change
|
||||
# to UT+9 on 1912-01-01? Omit the 1910 change for now.
|
||||
# (Another source "1987: Law No. 3919 (1986-12-31)" was in the 2014-10-30
|
||||
# edition of the Korean Wikipedia entry.)
|
||||
#
|
||||
# I guessed that time zone abbreviations through 1945 followed the same
|
||||
# rules as discussed under Taiwan, with nominal switches from JST to KST
|
||||
# when the respective cities were taken over by the Allies after WWII.
|
||||
#
|
||||
# For Pyongyang we have no information; guess no changes since World War II.
|
||||
# For Pyongyang, guess no changes from World War II until 2015, as we
|
||||
# have no information otherwise.
|
||||
|
||||
# From Steffen Thorsen (2015-08-07):
|
||||
# According to many news sources, North Korea is going to change to
|
||||
@ -2069,7 +2064,7 @@ Zone Indian/Maldives 4:54:00 - LMT 1880 # Male
|
||||
# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
|
||||
# there is only one time zone and that DST is observed, citing Microsoft
|
||||
# Windows XP as the source. Risto Nykänen (2005-05-16) reports that
|
||||
# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
|
||||
# travelmongolia.org says there are two time zones (UT +07, +08) with no DST.
|
||||
# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
|
||||
# Washington, DC says there are two time zones, with DST observed.
|
||||
# He also found
|
||||
@ -2705,7 +2700,7 @@ Link Asia/Qatar Asia/Bahrain
|
||||
# earlier date.
|
||||
#
|
||||
# Shanks & Pottenger also state that until 1968-05-01 Saudi Arabia had two
|
||||
# time zones; the other zone, at UTC+4, was in the far eastern part of
|
||||
# time zones; the other zone, at UT +04, was in the far eastern part of
|
||||
# the country. Ignore this, as it's before our 1970 cutoff.
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
@ -2974,10 +2969,10 @@ Zone Asia/Damascus 2:25:12 - LMT 1920 # Dimashq
|
||||
# From Shanks & Pottenger.
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Dushanbe 4:35:12 - LMT 1924 May 2
|
||||
5:00 - DUST 1930 Jun 21 # Dushanbe Time
|
||||
6:00 RussiaAsia DUS%sT 1991 Mar 31 2:00s
|
||||
5:00 1:00 DUSST 1991 Sep 9 2:00s
|
||||
5:00 - TJT # Tajikistan Time
|
||||
5:00 - +05 1930 Jun 21
|
||||
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00s
|
||||
5:00 1:00 +05/+06 1991 Sep 9 2:00s
|
||||
5:00 - +05
|
||||
|
||||
# Thailand
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
@ -2991,11 +2986,10 @@ Link Asia/Bangkok Asia/Vientiane # Laos
|
||||
# From Shanks & Pottenger.
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Ashgabat 3:53:32 - LMT 1924 May 2 # or Ashkhabad
|
||||
4:00 - ASHT 1930 Jun 21 # Ashkhabad Time
|
||||
5:00 RussiaAsia ASH%sT 1991 Mar 31 2:00
|
||||
4:00 RussiaAsia ASH%sT 1991 Oct 27 # independence
|
||||
4:00 RussiaAsia TM%sT 1992 Jan 19 2:00
|
||||
5:00 - TMT
|
||||
4:00 - +04 1930 Jun 21
|
||||
5:00 RussiaAsia +05/+06 1991 Mar 31 2:00
|
||||
4:00 RussiaAsia +04/+05 1992 Jan 19 2:00
|
||||
5:00 - +05
|
||||
|
||||
# United Arab Emirates
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
@ -3007,20 +3001,18 @@ Link Asia/Dubai Asia/Muscat # Oman
|
||||
# Byalokoz 1919 says Uzbekistan was 4:27:53.
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Asia/Samarkand 4:27:53 - LMT 1924 May 2
|
||||
4:00 - SAMT 1930 Jun 21 # Samarkand Time
|
||||
5:00 - SAMT 1981 Apr 1
|
||||
5:00 1:00 SAMST 1981 Oct 1
|
||||
6:00 - TAST 1982 Apr 1 # Tashkent Time
|
||||
5:00 RussiaAsia SAM%sT 1991 Sep 1 # independence
|
||||
5:00 RussiaAsia UZ%sT 1992
|
||||
5:00 - UZT
|
||||
4:00 - +04 1930 Jun 21
|
||||
5:00 - +05 1981 Apr 1
|
||||
5:00 1:00 +06 1981 Oct 1
|
||||
6:00 - +06 1982 Apr 1
|
||||
5:00 RussiaAsia +05/+06 1992
|
||||
5:00 - +05
|
||||
# Milne says Tashkent was 4:37:10.8; round to nearest.
|
||||
Zone Asia/Tashkent 4:37:11 - LMT 1924 May 2
|
||||
5:00 - TAST 1930 Jun 21 # Tashkent Time
|
||||
6:00 RussiaAsia TAS%sT 1991 Mar 31 2:00
|
||||
5:00 RussiaAsia TAS%sT 1991 Sep 1 # independence
|
||||
5:00 RussiaAsia UZ%sT 1992
|
||||
5:00 - UZT
|
||||
5:00 - +05 1930 Jun 21
|
||||
6:00 RussiaAsia +06/+07 1991 Mar 31 2:00
|
||||
5:00 RussiaAsia +05/+06 1992
|
||||
5:00 - +05
|
||||
|
||||
# Vietnam
|
||||
|
||||
|
@ -568,7 +568,7 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880
|
||||
# Base the Bougainville entry on the Arawa-Kieta region, which appears to have
|
||||
# the most people even though it was devastated in the Bougainville Civil War.
|
||||
#
|
||||
# Although Shanks gives 1942-03-15 / 1943-11-01 for JST, these dates
|
||||
# Although Shanks gives 1942-03-15 / 1943-11-01 for UT +09, these dates
|
||||
# are apparently rough guesswork from the starts of military campaigns.
|
||||
# The World War II entries below are instead based on Arawa-Kieta.
|
||||
# The Japanese occupied Kieta in July 1942,
|
||||
@ -576,8 +576,8 @@ Zone Pacific/Port_Moresby 9:48:40 - LMT 1880
|
||||
# http://pwencycl.kgbudge.com/B/o/Bougainville.htm
|
||||
# and seem to have controlled it until their 1945-08-21 surrender.
|
||||
#
|
||||
# The Autonomous Region of Bougainville plans to switch from UTC+10 to UTC+11
|
||||
# on 2014-12-28 at 02:00. They call UTC+11 "Bougainville Standard Time";
|
||||
# The Autonomous Region of Bougainville switched from UT +10 to +11
|
||||
# on 2014-12-28 at 02:00. They call +11 "Bougainville Standard Time";
|
||||
# abbreviate this as BST. See:
|
||||
# http://www.bougainville24.com/bougainville-issues/bougainville-gets-own-timezone/
|
||||
#
|
||||
@ -643,7 +643,7 @@ Link Pacific/Pago_Pago Pacific/Midway # in US minor outlying islands
|
||||
# From Paul Eggert (2014-06-27):
|
||||
# The International Date Line Act 2011
|
||||
# http://www.parliament.gov.ws/images/ACTS/International_Date_Line_Act__2011_-_Eng.pdf
|
||||
# changed Samoa from UTC-11 to UTC+13, effective "12 o'clock midnight, on
|
||||
# changed Samoa from UT -11 to +13, effective "12 o'clock midnight, on
|
||||
# Thursday 29th December 2011". The International Date Line was adjusted
|
||||
# accordingly.
|
||||
|
||||
@ -738,7 +738,7 @@ Zone Pacific/Funafuti 11:56:52 - LMT 1901
|
||||
# 1886-1891; Baker was similar but exact dates are not known.
|
||||
# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
|
||||
# uninhabited thereafter.
|
||||
# Howland observed Hawaii Standard Time (UT-10:30) in 1937;
|
||||
# Howland observed Hawaii Standard Time (UT -10:30) in 1937;
|
||||
# see page 206 of Elgen M. Long and Marie K. Long,
|
||||
# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
|
||||
# So most likely Howland and Baker observed Hawaii Time from 1935
|
||||
@ -1496,7 +1496,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
|
||||
# Zealand time. I understand that is the time they keep locally, anyhow."
|
||||
# For now, assume this practice goes back to the introduction of standard time
|
||||
# in New Zealand, as this would make Chatham Islands time almost exactly match
|
||||
# LMT back when New Zealand was at UTC+11:30; also, assume Chatham Islands did
|
||||
# LMT back when New Zealand was at UT +11:30; also, assume Chatham Islands did
|
||||
# not observe New Zealand's prewar DST.
|
||||
|
||||
###############################################################################
|
||||
@ -1552,7 +1552,7 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
|
||||
# For now, we assume the Ladrones switched at the same time as the Philippines;
|
||||
# see Asia/Manila.
|
||||
|
||||
# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
|
||||
# US Public Law 106-564 (2000-12-23) made UT +10 the official standard time,
|
||||
# under the name "Chamorro Standard Time". There is no official abbreviation,
|
||||
# but Congressman Robert A. Underwood, author of the bill that became law,
|
||||
# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
|
||||
@ -1564,15 +1564,15 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
|
||||
# "I am certain, having lived there for the past decade, that 'Truk'
|
||||
# (now properly known as Chuuk) ... is in the time zone GMT+10."
|
||||
#
|
||||
# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
|
||||
# Shanks & Pottenger write that Truk switched from UT +10 to +11
|
||||
# on 1978-10-01; ignore this for now.
|
||||
|
||||
# From Paul Eggert (1999-10-29):
|
||||
# The Federated States of Micronesia Visitors Board writes in
|
||||
# The Federated States of Micronesia - Visitor Information (1999-01-26)
|
||||
# http://www.fsmgov.org/info/clocks.html
|
||||
# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
|
||||
# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
|
||||
# that Truk and Yap are UT +10, and Ponape and Kosrae are +11.
|
||||
# We don't know when Kosrae switched from +12; assume January 1 for now.
|
||||
|
||||
|
||||
# Midway
|
||||
@ -1638,11 +1638,11 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901
|
||||
# ordaining - by a masterpiece of diplomatic flattery - that
|
||||
# the Fourth of July should be celebrated twice in that year."
|
||||
|
||||
# Although Shanks & Pottenger says they both switched to UTC-11:30
|
||||
# in 1911, and to UTC-11 in 1950. many earlier sources give UTC-11
|
||||
# Although Shanks & Pottenger says they both switched to UT -11:30
|
||||
# in 1911, and to -11 in 1950. many earlier sources give -11
|
||||
# for American Samoa, e.g., the US National Bureau of Standards
|
||||
# circular "Standard Time Throughout the World", 1932.
|
||||
# Assume American Samoa switched to UTC-11 in 1911, not 1950,
|
||||
# Assume American Samoa switched to -11 in 1911, not 1950,
|
||||
# and that after 1950 they agreed until (western) Samoa skipped a
|
||||
# day in 2011. Assume also that the Samoas follow the US and New
|
||||
# Zealand's "ST"/"DT" style of daylight-saving abbreviations.
|
||||
|
@ -59,6 +59,7 @@ Link Asia/Shanghai Asia/Harbin
|
||||
Link Asia/Urumqi Asia/Kashgar
|
||||
Link Asia/Kathmandu Asia/Katmandu
|
||||
Link Asia/Macau Asia/Macao
|
||||
Link Asia/Yangon Asia/Rangoon
|
||||
Link Asia/Ho_Chi_Minh Asia/Saigon
|
||||
Link Asia/Jerusalem Asia/Tel_Aviv
|
||||
Link Asia/Thimphu Asia/Thimbu
|
||||
|
@ -31,6 +31,13 @@
|
||||
# need now for the entries that are not on UTC are for ships at sea
|
||||
# that cannot use POSIX TZ settings.
|
||||
|
||||
# Starting with POSIX 1003.1-2001, the entries below are all
|
||||
# unnecessary as settings for the TZ environment variable. E.g.,
|
||||
# instead of TZ='Etc/GMT+4' one can use the POSIX setting TZ='<-04>+4'.
|
||||
#
|
||||
# Do not use a POSIX TZ setting like TZ='GMT+4', which is four hours
|
||||
# behind GMT but uses the completely misleading abbreviation "GMT".
|
||||
|
||||
Zone Etc/GMT 0 - GMT
|
||||
Zone Etc/UTC 0 - UTC
|
||||
Zone Etc/UCT 0 - UCT
|
||||
@ -49,23 +56,13 @@ Link Etc/GMT Etc/GMT-0
|
||||
Link Etc/GMT Etc/GMT+0
|
||||
Link Etc/GMT Etc/GMT0
|
||||
|
||||
# We use POSIX-style signs in the Zone names and the output abbreviations,
|
||||
# Be consistent with POSIX TZ settings in the Zone names,
|
||||
# even though this is the opposite of what many people expect.
|
||||
# POSIX has positive signs west of Greenwich, but many people expect
|
||||
# positive signs east of Greenwich. For example, TZ='Etc/GMT+4' uses
|
||||
# the abbreviation "GMT+4" and corresponds to 4 hours behind UT
|
||||
# the abbreviation "-04" and corresponds to 4 hours behind UT
|
||||
# (i.e. west of Greenwich) even though many people would expect it to
|
||||
# mean 4 hours ahead of UT (i.e. east of Greenwich).
|
||||
#
|
||||
# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation allows for
|
||||
# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
|
||||
# ISO 8601 you can use TZ='<-0400>+4'. Thus the commonly-expected
|
||||
# offset is kept within the angle bracket (and is used for display)
|
||||
# while the POSIX sign is kept outside the angle bracket (and is used
|
||||
# for calculation).
|
||||
#
|
||||
# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
|
||||
# GMT but uses the completely misleading abbreviation "GMT".
|
||||
|
||||
# Earlier incarnations of this package were not POSIX-compliant,
|
||||
# and had lines such as
|
||||
@ -74,30 +71,31 @@ Link Etc/GMT Etc/GMT0
|
||||
# way does a
|
||||
# zic -l GMT-12
|
||||
# so we moved the names into the Etc subdirectory.
|
||||
# Also, the time zone abbreviations are now compatible with %z.
|
||||
|
||||
Zone Etc/GMT-14 14 - GMT-14 # 14 hours ahead of GMT
|
||||
Zone Etc/GMT-13 13 - GMT-13
|
||||
Zone Etc/GMT-12 12 - GMT-12
|
||||
Zone Etc/GMT-11 11 - GMT-11
|
||||
Zone Etc/GMT-10 10 - GMT-10
|
||||
Zone Etc/GMT-9 9 - GMT-9
|
||||
Zone Etc/GMT-8 8 - GMT-8
|
||||
Zone Etc/GMT-7 7 - GMT-7
|
||||
Zone Etc/GMT-6 6 - GMT-6
|
||||
Zone Etc/GMT-5 5 - GMT-5
|
||||
Zone Etc/GMT-4 4 - GMT-4
|
||||
Zone Etc/GMT-3 3 - GMT-3
|
||||
Zone Etc/GMT-2 2 - GMT-2
|
||||
Zone Etc/GMT-1 1 - GMT-1
|
||||
Zone Etc/GMT+1 -1 - GMT+1
|
||||
Zone Etc/GMT+2 -2 - GMT+2
|
||||
Zone Etc/GMT+3 -3 - GMT+3
|
||||
Zone Etc/GMT+4 -4 - GMT+4
|
||||
Zone Etc/GMT+5 -5 - GMT+5
|
||||
Zone Etc/GMT+6 -6 - GMT+6
|
||||
Zone Etc/GMT+7 -7 - GMT+7
|
||||
Zone Etc/GMT+8 -8 - GMT+8
|
||||
Zone Etc/GMT+9 -9 - GMT+9
|
||||
Zone Etc/GMT+10 -10 - GMT+10
|
||||
Zone Etc/GMT+11 -11 - GMT+11
|
||||
Zone Etc/GMT+12 -12 - GMT+12
|
||||
Zone Etc/GMT-14 14 - +14
|
||||
Zone Etc/GMT-13 13 - +13
|
||||
Zone Etc/GMT-12 12 - +12
|
||||
Zone Etc/GMT-11 11 - +11
|
||||
Zone Etc/GMT-10 10 - +10
|
||||
Zone Etc/GMT-9 9 - +09
|
||||
Zone Etc/GMT-8 8 - +08
|
||||
Zone Etc/GMT-7 7 - +07
|
||||
Zone Etc/GMT-6 6 - +06
|
||||
Zone Etc/GMT-5 5 - +05
|
||||
Zone Etc/GMT-4 4 - +04
|
||||
Zone Etc/GMT-3 3 - +03
|
||||
Zone Etc/GMT-2 2 - +02
|
||||
Zone Etc/GMT-1 1 - +01
|
||||
Zone Etc/GMT+1 -1 - -01
|
||||
Zone Etc/GMT+2 -2 - -02
|
||||
Zone Etc/GMT+3 -3 - -03
|
||||
Zone Etc/GMT+4 -4 - -04
|
||||
Zone Etc/GMT+5 -5 - -05
|
||||
Zone Etc/GMT+6 -6 - -06
|
||||
Zone Etc/GMT+7 -7 - -07
|
||||
Zone Etc/GMT+8 -8 - -08
|
||||
Zone Etc/GMT+9 -9 - -09
|
||||
Zone Etc/GMT+10 -10 - -10
|
||||
Zone Etc/GMT+11 -11 - -11
|
||||
Zone Etc/GMT+12 -12 - -12
|
||||
|
@ -98,8 +98,7 @@
|
||||
# 1:00 CET CEST CEMT Central Europe
|
||||
# 1:00:14 SET Swedish (1879-1899)*
|
||||
# 2:00 EET EEST Eastern Europe
|
||||
# 3:00 FET Further-eastern Europe (2011-2014)*
|
||||
# 3:00 MSK MSD MSM* Minsk, Moscow
|
||||
# 3:00 MSK MSD Moscow
|
||||
|
||||
# From Peter Ilieve (1994-12-04),
|
||||
# The original six [EU members]: Belgium, France, (West) Germany, Italy,
|
||||
@ -606,16 +605,33 @@ Rule E-Eur 1979 1995 - Sep lastSun 0:00 0 -
|
||||
Rule E-Eur 1981 max - Mar lastSun 0:00 1:00 S
|
||||
Rule E-Eur 1996 max - Oct lastSun 0:00 0 -
|
||||
|
||||
|
||||
# Daylight saving time for Russia and the Soviet Union
|
||||
#
|
||||
# The 1917-1921 decree URLs are from Alexander Belopolsky (2016-08-23).
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Russia 1917 only - Jul 1 23:00 1:00 MST # Moscow Summer Time
|
||||
#
|
||||
# Decree No. 142 (1917-12-22) http://istmat.info/node/28137
|
||||
Rule Russia 1917 only - Dec 28 0:00 0 MMT # Moscow Mean Time
|
||||
#
|
||||
# Decree No. 497 (1918-05-30) http://istmat.info/node/30001
|
||||
Rule Russia 1918 only - May 31 22:00 2:00 MDST # Moscow Double Summer Time
|
||||
Rule Russia 1918 only - Sep 16 1:00 1:00 MST
|
||||
#
|
||||
# Decree No. 258 (1919-05-29) http://istmat.info/node/37949
|
||||
Rule Russia 1919 only - May 31 23:00 2:00 MDST
|
||||
Rule Russia 1919 only - Jul 1 2:00 1:00 MSD
|
||||
#
|
||||
Rule Russia 1919 only - Jul 1 0:00u 1:00 MSD
|
||||
Rule Russia 1919 only - Aug 16 0:00 0 MSK
|
||||
#
|
||||
# Decree No. 63 (1921-02-03) http://istmat.info/node/45840
|
||||
Rule Russia 1921 only - Feb 14 23:00 1:00 MSD
|
||||
Rule Russia 1921 only - Mar 20 23:00 2:00 MSM # Midsummer
|
||||
#
|
||||
# Decree No. 121 (1921-03-07) http://istmat.info/node/45949
|
||||
Rule Russia 1921 only - Mar 20 23:00 2:00 +05
|
||||
#
|
||||
Rule Russia 1921 only - Sep 1 0:00 1:00 MSD
|
||||
Rule Russia 1921 only - Oct 1 0:00 0 -
|
||||
# Act No. 925 of the Council of Ministers of the USSR (1980-10-24):
|
||||
@ -798,8 +814,6 @@ Zone Europe/Vienna 1:05:21 - LMT 1893 Apr
|
||||
# From Alexander Bokovoy (2014-10-09):
|
||||
# Belarussian government decided against changing to winter time....
|
||||
# http://eng.belta.by/all_news/society/Belarus-decides-against-adjusting-time-in-Russias-wake_i_76335.html
|
||||
# From Paul Eggert (2014-10-08):
|
||||
# Hence Belarus can share time zone abbreviations with Moscow again.
|
||||
#
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
Zone Europe/Minsk 1:50:16 - LMT 1880
|
||||
@ -810,8 +824,7 @@ Zone Europe/Minsk 1:50:16 - LMT 1880
|
||||
3:00 Russia MSK/MSD 1990
|
||||
3:00 - MSK 1991 Mar 31 2:00s
|
||||
2:00 Russia EE%sT 2011 Mar 27 2:00s
|
||||
3:00 - FET 2014 Oct 26 1:00s
|
||||
3:00 - MSK
|
||||
3:00 - +03
|
||||
|
||||
# Belgium
|
||||
#
|
||||
@ -1319,7 +1332,7 @@ Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15 0:01
|
||||
# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
|
||||
# says that Bersarin issued an order to use Moscow time on May 20.
|
||||
# However, Moscow did not observe daylight saving in 1945, so
|
||||
# this was equivalent to CEMT (GMT+3), not GMT+4.
|
||||
# this was equivalent to UT +03, not +04.
|
||||
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
@ -2283,7 +2296,6 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
|
||||
# http://www.worldtimezone.com/dst_news/dst_news_russia-map-2014-07.html
|
||||
|
||||
# From Paul Eggert (2006-03-22):
|
||||
# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
|
||||
# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
|
||||
# are from Andrey A. Chernov. The rest is from Shanks & Pottenger,
|
||||
# except we follow Chernov's report that 1992 DST transitions were Sat
|
||||
@ -2359,7 +2371,7 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
2:00 Poland CE%sT 1946
|
||||
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
|
||||
2:00 Russia EE%sT 2011 Mar 27 2:00s
|
||||
3:00 - FET 2014 Oct 26 2:00s
|
||||
3:00 - +03 2014 Oct 26 2:00s
|
||||
2:00 - EET
|
||||
|
||||
|
||||
@ -2412,6 +2424,16 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
# 78 RU-SPE Saint Petersburg
|
||||
# 83 RU-NEN Nenets Autonomous Okrug
|
||||
|
||||
# From Paul Eggert (2016-08-23):
|
||||
# The Soviets switched to UT-based time in 1919. Decree No. 59
|
||||
# (1919-02-08) http://istmat.info/node/35567 established UT-based time
|
||||
# zones, and Decree No. 147 (1919-03-29) http://istmat.info/node/35854
|
||||
# specified a transition date of 1919-07-01, apparently at 00:00 UT.
|
||||
# No doubt only the Soviet-controlled regions switched on that date;
|
||||
# later transitions to UT-based time in other parts of Russia are
|
||||
# taken from what appear to be guesses by Shanks.
|
||||
# (Thanks to Alexander Belopolsky for pointers to the decrees.)
|
||||
|
||||
# From Stepan Golosunov (2016-03-07):
|
||||
# 11. Regions-violators, 1981-1982.
|
||||
# Wikipedia refers to
|
||||
@ -2453,7 +2475,7 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
# attributes the 1982 changes to the Act of the Council of Ministers
|
||||
# of the USSR No. 126 from 18.02.1982. 1980-925.txt also adds
|
||||
# Udmurtia to the list of affected territories and lists Khatangsky
|
||||
# district separately from Taymyr Autonomous Okurg. Probably erroneously.
|
||||
# district separately from Taymyr Autonomous Okrug. Probably erroneously.
|
||||
#
|
||||
# The affected territories are currently listed under Europe/Moscow,
|
||||
# Asia/Yekaterinburg and Asia/Krasnoyarsk.
|
||||
@ -2513,7 +2535,7 @@ Zone Europe/Kaliningrad 1:22:00 - LMT 1893 Apr
|
||||
|
||||
Zone Europe/Moscow 2:30:17 - LMT 1880
|
||||
2:30:17 - MMT 1916 Jul 3 # Moscow Mean Time
|
||||
2:31:19 Russia %s 1919 Jul 1 2:00
|
||||
2:31:19 Russia %s 1919 Jul 1 0:00u
|
||||
3:00 Russia %s 1921 Oct
|
||||
3:00 Russia MSK/MSD 1922 Oct
|
||||
2:00 - EET 1930 Jun 21
|
||||
@ -2596,22 +2618,21 @@ Zone Europe/Astrakhan 3:12:12 - LMT 1924 May
|
||||
# The 1988 transition is from USSR act No. 5 (1988-01-04).
|
||||
|
||||
Zone Europe/Volgograd 2:57:40 - LMT 1920 Jan 3
|
||||
3:00 - TSAT 1925 Apr 6 # Tsaritsyn Time
|
||||
3:00 - STAT 1930 Jun 21 # Stalingrad Time
|
||||
4:00 - STAT 1961 Nov 11
|
||||
4:00 Russia VOL%sT 1988 Mar 27 2:00s # Volgograd T
|
||||
3:00 Russia VOL%sT 1991 Mar 31 2:00s
|
||||
4:00 - VOLT 1992 Mar 29 2:00s
|
||||
3:00 Russia MSK/MSD 2011 Mar 27 2:00s
|
||||
4:00 - MSK 2014 Oct 26 2:00s
|
||||
3:00 - MSK
|
||||
3:00 - +03 1930 Jun 21
|
||||
4:00 - +04 1961 Nov 11
|
||||
4:00 Russia +04/+05 1988 Mar 27 2:00s
|
||||
3:00 Russia +03/+04 1991 Mar 31 2:00s
|
||||
4:00 - +04 1992 Mar 29 2:00s
|
||||
3:00 Russia +03/+04 2011 Mar 27 2:00s
|
||||
4:00 - +04 2014 Oct 26 2:00s
|
||||
3:00 - +03
|
||||
|
||||
# From Paul Eggert (2016-03-18):
|
||||
# Europe/Kirov covers:
|
||||
# 43 RU-KIR Kirov Oblast
|
||||
# The 1989 transition is from USSR act No. 227 (1989-03-14).
|
||||
#
|
||||
Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 2:00
|
||||
Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0:00u
|
||||
3:00 - +03 1930 Jun 21
|
||||
4:00 Russia +04/+05 1989 Mar 26 2:00s
|
||||
3:00 Russia +03/+04 1991 Mar 31 2:00s
|
||||
@ -2629,16 +2650,16 @@ Zone Europe/Kirov 3:18:48 - LMT 1919 Jul 1 2:00
|
||||
# Byalokoz 1919 says Samara was 3:20:20.
|
||||
# The 1989 transition is from USSR act No. 227 (1989-03-14).
|
||||
|
||||
Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 2:00
|
||||
3:00 - SAMT 1930 Jun 21 # Samara Time
|
||||
4:00 - SAMT 1935 Jan 27
|
||||
4:00 Russia KUY%sT 1989 Mar 26 2:00s # Kuybyshev
|
||||
3:00 Russia MSK/MSD 1991 Mar 31 2:00s
|
||||
2:00 Russia EE%sT 1991 Sep 29 2:00s
|
||||
3:00 - SAMT 1991 Oct 20 3:00
|
||||
4:00 Russia SAM%sT 2010 Mar 28 2:00s
|
||||
3:00 Russia SAM%sT 2011 Mar 27 2:00s
|
||||
4:00 - SAMT
|
||||
Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 0:00u
|
||||
3:00 - +03 1930 Jun 21
|
||||
4:00 - +04 1935 Jan 27
|
||||
4:00 Russia +04/+05 1989 Mar 26 2:00s
|
||||
3:00 Russia +03/+04 1991 Mar 31 2:00s
|
||||
2:00 Russia +02/+03 1991 Sep 29 2:00s
|
||||
3:00 - +03 1991 Oct 20 3:00
|
||||
4:00 Russia +04/+05 2010 Mar 28 2:00s
|
||||
3:00 Russia +03/+04 2011 Mar 27 2:00s
|
||||
4:00 - +04
|
||||
|
||||
# From Paul Eggert (2016-03-18):
|
||||
# Europe/Ulyanovsk covers:
|
||||
@ -2653,7 +2674,7 @@ Zone Europe/Samara 3:20:20 - LMT 1919 Jul 1 2:00
|
||||
# From Matt Johnson (2016-03-09):
|
||||
# http://publication.pravo.gov.ru/Document/View/0001201603090051
|
||||
|
||||
Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 2:00
|
||||
Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0:00u
|
||||
3:00 - +03 1930 Jun 21
|
||||
4:00 Russia +04/+05 1989 Mar 26 2:00s
|
||||
3:00 Russia +03/+04 1991 Mar 31 2:00s
|
||||
@ -2685,12 +2706,12 @@ Zone Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 2:00
|
||||
|
||||
Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3
|
||||
3:45:05 - PMT 1919 Jul 15 4:00
|
||||
4:00 - SVET 1930 Jun 21 # Sverdlovsk Time
|
||||
5:00 Russia SVE%sT 1991 Mar 31 2:00s
|
||||
4:00 Russia SVE%sT 1992 Jan 19 2:00s
|
||||
5:00 Russia YEK%sT 2011 Mar 27 2:00s
|
||||
6:00 - YEKT 2014 Oct 26 2:00s
|
||||
5:00 - YEKT
|
||||
4:00 - +04 1930 Jun 21
|
||||
5:00 Russia +05/+06 1991 Mar 31 2:00s
|
||||
4:00 Russia +04/+05 1992 Jan 19 2:00s
|
||||
5:00 Russia +05/+06 2011 Mar 27 2:00s
|
||||
6:00 - +06 2014 Oct 26 2:00s
|
||||
5:00 - +05
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
|
||||
@ -2700,12 +2721,12 @@ Zone Asia/Yekaterinburg 4:02:33 - LMT 1916 Jul 3
|
||||
# Byalokoz 1919 says Omsk was 4:53:30.
|
||||
|
||||
Zone Asia/Omsk 4:53:30 - LMT 1919 Nov 14
|
||||
5:00 - OMST 1930 Jun 21 # Omsk Time
|
||||
6:00 Russia OMS%sT 1991 Mar 31 2:00s
|
||||
5:00 Russia OMS%sT 1992 Jan 19 2:00s
|
||||
6:00 Russia OMS%sT 2011 Mar 27 2:00s
|
||||
7:00 - OMST 2014 Oct 26 2:00s
|
||||
6:00 - OMST
|
||||
5:00 - +05 1930 Jun 21
|
||||
6:00 Russia +06/+07 1991 Mar 31 2:00s
|
||||
5:00 Russia +05/+06 1992 Jan 19 2:00s
|
||||
6:00 Russia +06/+07 2011 Mar 27 2:00s
|
||||
7:00 - +07 2014 Oct 26 2:00s
|
||||
6:00 - +06
|
||||
|
||||
# From Paul Eggert (2016-02-22):
|
||||
# Asia/Barnaul covers:
|
||||
@ -2785,7 +2806,7 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
|
||||
# Note that time belts (numbered from 2 (Moscow) to 12 according to their
|
||||
# GMT/UTC offset and having too many exceptions like regions formally
|
||||
# belonging to one belt but using time from another) were replaced
|
||||
# with time zones in 2011 with different numberings (there was a
|
||||
# with time zones in 2011 with different numbering (there was a
|
||||
# 2-hour gap between second and third zones in 2011-2014).
|
||||
|
||||
# From Stepan Golosunov (2016-04-12):
|
||||
@ -2868,12 +2889,12 @@ Zone Asia/Novokuznetsk 5:48:48 - LMT 1924 May 1
|
||||
# Byalokoz 1919 says Krasnoyarsk was 6:11:26.
|
||||
|
||||
Zone Asia/Krasnoyarsk 6:11:26 - LMT 1920 Jan 6
|
||||
6:00 - KRAT 1930 Jun 21 # Krasnoyarsk Time
|
||||
7:00 Russia KRA%sT 1991 Mar 31 2:00s
|
||||
6:00 Russia KRA%sT 1992 Jan 19 2:00s
|
||||
7:00 Russia KRA%sT 2011 Mar 27 2:00s
|
||||
8:00 - KRAT 2014 Oct 26 2:00s
|
||||
7:00 - KRAT
|
||||
6:00 - +06 1930 Jun 21
|
||||
7:00 Russia +07/+08 1991 Mar 31 2:00s
|
||||
6:00 Russia +06/+07 1992 Jan 19 2:00s
|
||||
7:00 Russia +07/+08 2011 Mar 27 2:00s
|
||||
8:00 - +08 2014 Oct 26 2:00s
|
||||
7:00 - +07
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
|
||||
@ -2890,12 +2911,12 @@ Zone Asia/Krasnoyarsk 6:11:26 - LMT 1920 Jan 6
|
||||
|
||||
Zone Asia/Irkutsk 6:57:05 - LMT 1880
|
||||
6:57:05 - IMT 1920 Jan 25 # Irkutsk Mean Time
|
||||
7:00 - IRKT 1930 Jun 21 # Irkutsk Time
|
||||
8:00 Russia IRK%sT 1991 Mar 31 2:00s
|
||||
7:00 Russia IRK%sT 1992 Jan 19 2:00s
|
||||
8:00 Russia IRK%sT 2011 Mar 27 2:00s
|
||||
9:00 - IRKT 2014 Oct 26 2:00s
|
||||
8:00 - IRKT
|
||||
7:00 - +07 1930 Jun 21
|
||||
8:00 Russia +08/+09 1991 Mar 31 2:00s
|
||||
7:00 Russia +07/+08 1992 Jan 19 2:00s
|
||||
8:00 Russia +08/+09 2011 Mar 27 2:00s
|
||||
9:00 - +09 2014 Oct 26 2:00s
|
||||
8:00 - +08
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-06):
|
||||
@ -2912,13 +2933,13 @@ Zone Asia/Irkutsk 6:57:05 - LMT 1880
|
||||
# http://publication.pravo.gov.ru/Document/View/0001201512300107
|
||||
|
||||
Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15
|
||||
8:00 - YAKT 1930 Jun 21 # Yakutsk Time
|
||||
9:00 Russia YAK%sT 1991 Mar 31 2:00s
|
||||
8:00 Russia YAK%sT 1992 Jan 19 2:00s
|
||||
9:00 Russia YAK%sT 2011 Mar 27 2:00s
|
||||
10:00 - YAKT 2014 Oct 26 2:00s
|
||||
8:00 - IRKT 2016 Mar 27 2:00
|
||||
9:00 - YAKT
|
||||
8:00 - +08 1930 Jun 21
|
||||
9:00 Russia +09/+10 1991 Mar 31 2:00s
|
||||
8:00 Russia +08/+09 1992 Jan 19 2:00s
|
||||
9:00 Russia +09/+10 2011 Mar 27 2:00s
|
||||
10:00 - +10 2014 Oct 26 2:00s
|
||||
8:00 - +08 2016 Mar 27 2:00
|
||||
9:00 - +09
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
|
||||
@ -2958,12 +2979,12 @@ Zone Asia/Chita 7:33:52 - LMT 1919 Dec 15
|
||||
# Byalokoz 1919 says Yakutsk was 8:38:58.
|
||||
|
||||
Zone Asia/Yakutsk 8:38:58 - LMT 1919 Dec 15
|
||||
8:00 - YAKT 1930 Jun 21 # Yakutsk Time
|
||||
9:00 Russia YAK%sT 1991 Mar 31 2:00s
|
||||
8:00 Russia YAK%sT 1992 Jan 19 2:00s
|
||||
9:00 Russia YAK%sT 2011 Mar 27 2:00s
|
||||
10:00 - YAKT 2014 Oct 26 2:00s
|
||||
9:00 - YAKT
|
||||
8:00 - +08 1930 Jun 21
|
||||
9:00 Russia +09/+10 1991 Mar 31 2:00s
|
||||
8:00 Russia +08/+09 1992 Jan 19 2:00s
|
||||
9:00 Russia +09/+10 2011 Mar 27 2:00s
|
||||
10:00 - +10 2014 Oct 26 2:00s
|
||||
9:00 - +09
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
|
||||
@ -2981,12 +3002,12 @@ Zone Asia/Yakutsk 8:38:58 - LMT 1919 Dec 15
|
||||
# Go with Byalokoz.
|
||||
|
||||
Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15
|
||||
9:00 - VLAT 1930 Jun 21 # Vladivostok Time
|
||||
10:00 Russia VLA%sT 1991 Mar 31 2:00s
|
||||
9:00 Russia VLA%sT 1992 Jan 19 2:00s
|
||||
10:00 Russia VLA%sT 2011 Mar 27 2:00s
|
||||
11:00 - VLAT 2014 Oct 26 2:00s
|
||||
10:00 - VLAT
|
||||
9:00 - +09 1930 Jun 21
|
||||
10:00 Russia +10/+11 1991 Mar 31 2:00s
|
||||
9:00 Russia +09/+10 1992 Jan 19 2:00s
|
||||
10:00 Russia +10/+11 2011 Mar 27 2:00s
|
||||
11:00 - +11 2014 Oct 26 2:00s
|
||||
10:00 - +10
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03):
|
||||
@ -3004,14 +3025,14 @@ Zone Asia/Vladivostok 8:47:31 - LMT 1922 Nov 15
|
||||
# This transition is no doubt wrong, but we have no better info.
|
||||
|
||||
Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15
|
||||
8:00 - YAKT 1930 Jun 21 # Yakutsk Time
|
||||
9:00 Russia YAK%sT 1991 Mar 31 2:00s
|
||||
8:00 Russia YAK%sT 1992 Jan 19 2:00s
|
||||
9:00 Russia YAK%sT 2004
|
||||
10:00 Russia VLA%sT 2011 Mar 27 2:00s
|
||||
11:00 - VLAT 2011 Sep 13 0:00s # Decree 725?
|
||||
10:00 - YAKT 2014 Oct 26 2:00s
|
||||
9:00 - YAKT
|
||||
8:00 - +08 1930 Jun 21
|
||||
9:00 Russia +09/+10 1991 Mar 31 2:00s
|
||||
8:00 Russia +08/+09 1992 Jan 19 2:00s
|
||||
9:00 Russia +09/+10 2004
|
||||
10:00 Russia +10/+11 2011 Mar 27 2:00s
|
||||
11:00 - +11 2011 Sep 13 0:00s # Decree 725?
|
||||
10:00 - +10 2014 Oct 26 2:00s
|
||||
9:00 - +09
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03):
|
||||
@ -3027,15 +3048,14 @@ Zone Asia/Khandyga 9:02:13 - LMT 1919 Dec 15
|
||||
|
||||
# The Zone name should be Asia/Yuzhno-Sakhalinsk, but that's too long.
|
||||
Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23
|
||||
9:00 - JCST 1937 Oct 1
|
||||
9:00 - JST 1945 Aug 25
|
||||
11:00 Russia SAK%sT 1991 Mar 31 2:00s # Sakhalin T
|
||||
10:00 Russia SAK%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia SAK%sT 1997 Mar lastSun 2:00s
|
||||
10:00 Russia SAK%sT 2011 Mar 27 2:00s
|
||||
11:00 - SAKT 2014 Oct 26 2:00s
|
||||
10:00 - SAKT 2016 Mar 27 2:00s
|
||||
11:00 - SAKT
|
||||
9:00 - +09 1945 Aug 25
|
||||
11:00 Russia +11/+12 1991 Mar 31 2:00s # Sakhalin T
|
||||
10:00 Russia +10/+11 1992 Jan 19 2:00s
|
||||
11:00 Russia +11/+12 1997 Mar lastSun 2:00s
|
||||
10:00 Russia +10/+11 2011 Mar 27 2:00s
|
||||
11:00 - +11 2014 Oct 26 2:00s
|
||||
10:00 - +10 2016 Mar 27 2:00s
|
||||
11:00 - +11
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2009-11-29):
|
||||
@ -3058,13 +3078,13 @@ Zone Asia/Sakhalin 9:30:48 - LMT 1905 Aug 23
|
||||
# http://publication.pravo.gov.ru/Document/View/0001201604050038
|
||||
|
||||
Zone Asia/Magadan 10:03:12 - LMT 1924 May 2
|
||||
10:00 - MAGT 1930 Jun 21 # Magadan Time
|
||||
11:00 Russia MAG%sT 1991 Mar 31 2:00s
|
||||
10:00 Russia MAG%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia MAG%sT 2011 Mar 27 2:00s
|
||||
12:00 - MAGT 2014 Oct 26 2:00s
|
||||
10:00 - MAGT 2016 Apr 24 2:00s
|
||||
11:00 - MAGT
|
||||
10:00 - +10 1930 Jun 21 # Magadan Time
|
||||
11:00 Russia +11/+12 1991 Mar 31 2:00s
|
||||
10:00 Russia +10/+11 1992 Jan 19 2:00s
|
||||
11:00 Russia +11/+12 2011 Mar 27 2:00s
|
||||
12:00 - +12 2014 Oct 26 2:00s
|
||||
10:00 - +10 2016 Apr 24 2:00s
|
||||
11:00 - +11
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-06):
|
||||
@ -3107,17 +3127,14 @@ Zone Asia/Magadan 10:03:12 - LMT 1924 May 2
|
||||
# in Russian.) In addition, Srednekolymsk appears to be a much older
|
||||
# settlement and the population of Zyryanka seems to be declining.
|
||||
# Go with Srednekolymsk.
|
||||
#
|
||||
# Since Magadan Oblast moves to UTC+10 on 2014-10-26, we cannot keep using MAGT
|
||||
# as the abbreviation. Use SRET instead.
|
||||
|
||||
Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2
|
||||
10:00 - MAGT 1930 Jun 21 # Magadan Time
|
||||
11:00 Russia MAG%sT 1991 Mar 31 2:00s
|
||||
10:00 Russia MAG%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia MAG%sT 2011 Mar 27 2:00s
|
||||
12:00 - MAGT 2014 Oct 26 2:00s
|
||||
11:00 - SRET # Srednekolymsk Time
|
||||
10:00 - +10 1930 Jun 21
|
||||
11:00 Russia +11/+12 1991 Mar 31 2:00s
|
||||
10:00 Russia +10/+11 1992 Jan 19 2:00s
|
||||
11:00 Russia +11/+12 2011 Mar 27 2:00s
|
||||
12:00 - +12 2014 Oct 26 2:00s
|
||||
11:00 - +11
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03):
|
||||
@ -3135,14 +3152,14 @@ Zone Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2
|
||||
# UTC+12 since at least then, too.
|
||||
|
||||
Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15
|
||||
8:00 - YAKT 1930 Jun 21 # Yakutsk Time
|
||||
9:00 Russia YAKT 1981 Apr 1
|
||||
11:00 Russia MAG%sT 1991 Mar 31 2:00s
|
||||
10:00 Russia MAG%sT 1992 Jan 19 2:00s
|
||||
11:00 Russia MAG%sT 2011 Mar 27 2:00s
|
||||
12:00 - MAGT 2011 Sep 13 0:00s # Decree 725?
|
||||
11:00 - VLAT 2014 Oct 26 2:00s
|
||||
10:00 - VLAT
|
||||
8:00 - +08 1930 Jun 21
|
||||
9:00 Russia +09/+10 1981 Apr 1
|
||||
11:00 Russia +11/+12 1991 Mar 31 2:00s
|
||||
10:00 Russia +10/+11 1992 Jan 19 2:00s
|
||||
11:00 Russia +11/+12 2011 Mar 27 2:00s
|
||||
12:00 - +12 2011 Sep 13 0:00s # Decree 725?
|
||||
11:00 - +11 2014 Oct 26 2:00s
|
||||
10:00 - +10
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03), per Oscar van Vlijmen (2001-08-25):
|
||||
@ -3155,12 +3172,12 @@ Zone Asia/Ust-Nera 9:32:54 - LMT 1919 Dec 15
|
||||
# The Zone name should be Asia/Petropavlovsk-Kamchatski or perhaps
|
||||
# Asia/Petropavlovsk-Kamchatsky, but these are too long.
|
||||
Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10
|
||||
11:00 - PETT 1930 Jun 21 # P-K Time
|
||||
12:00 Russia PET%sT 1991 Mar 31 2:00s
|
||||
11:00 Russia PET%sT 1992 Jan 19 2:00s
|
||||
12:00 Russia PET%sT 2010 Mar 28 2:00s
|
||||
11:00 Russia PET%sT 2011 Mar 27 2:00s
|
||||
12:00 - PETT
|
||||
11:00 - +11 1930 Jun 21
|
||||
12:00 Russia +12/+13 1991 Mar 31 2:00s
|
||||
11:00 Russia +11/+12 1992 Jan 19 2:00s
|
||||
12:00 Russia +12/+13 2010 Mar 28 2:00s
|
||||
11:00 Russia +11/+12 2011 Mar 27 2:00s
|
||||
12:00 - +12
|
||||
|
||||
|
||||
# From Tim Parenti (2014-07-03):
|
||||
@ -3168,13 +3185,13 @@ Zone Asia/Kamchatka 10:34:36 - LMT 1922 Nov 10
|
||||
# 87 RU-CHU Chukotka Autonomous Okrug
|
||||
|
||||
Zone Asia/Anadyr 11:49:56 - LMT 1924 May 2
|
||||
12:00 - ANAT 1930 Jun 21 # Anadyr Time
|
||||
13:00 Russia ANA%sT 1982 Apr 1 0:00s
|
||||
12:00 Russia ANA%sT 1991 Mar 31 2:00s
|
||||
11:00 Russia ANA%sT 1992 Jan 19 2:00s
|
||||
12:00 Russia ANA%sT 2010 Mar 28 2:00s
|
||||
11:00 Russia ANA%sT 2011 Mar 27 2:00s
|
||||
12:00 - ANAT
|
||||
12:00 - +12 1930 Jun 21
|
||||
13:00 Russia +13/+14 1982 Apr 1 0:00s
|
||||
12:00 Russia +12/+13 1991 Mar 31 2:00s
|
||||
11:00 Russia +11/+12 1992 Jan 19 2:00s
|
||||
12:00 Russia +12/+13 2010 Mar 28 2:00s
|
||||
11:00 Russia +11/+12 2011 Mar 27 2:00s
|
||||
12:00 - +12
|
||||
|
||||
|
||||
# San Marino
|
||||
@ -3495,6 +3512,14 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment.
|
||||
# Engineered Standard Time," said Twitter user @aysekarahasan.
|
||||
# http://www.bbc.com/news/world-europe-34631326
|
||||
|
||||
# From Burak AYDIN (2016-09-08):
|
||||
# Turkey will stay in Daylight Saving Time even in winter....
|
||||
# http://www.resmigazete.gov.tr/eskiler/2016/09/20160908-2.pdf
|
||||
#
|
||||
# From Paul Eggert (2016-09-07):
|
||||
# The change is permanent, so this is the new standard time in Turkey.
|
||||
# It takes effect today, which is not much notice.
|
||||
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
||||
Rule Turkey 1916 only - May 1 0:00 1:00 S
|
||||
Rule Turkey 1916 only - Oct 1 0:00 0 -
|
||||
@ -3558,7 +3583,7 @@ Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 -
|
||||
Zone Europe/Istanbul 1:55:52 - LMT 1880
|
||||
1:56:56 - IMT 1910 Oct # Istanbul Mean Time?
|
||||
2:00 Turkey EE%sT 1978 Oct 15
|
||||
3:00 Turkey TR%sT 1985 Apr 20 # Turkey Time
|
||||
3:00 Turkey +03/+04 1985 Apr 20
|
||||
2:00 Turkey EE%sT 2007
|
||||
2:00 EU EE%sT 2011 Mar 27 1:00u
|
||||
2:00 - EET 2011 Mar 28 1:00u
|
||||
@ -3566,7 +3591,8 @@ Zone Europe/Istanbul 1:55:52 - LMT 1880
|
||||
2:00 - EET 2014 Mar 31 1:00u
|
||||
2:00 EU EE%sT 2015 Oct 25 1:00u
|
||||
2:00 1:00 EEST 2015 Nov 8 1:00u
|
||||
2:00 EU EE%sT
|
||||
2:00 EU EE%sT 2016 Sep 7
|
||||
3:00 - +03
|
||||
Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
|
||||
|
||||
# Ukraine
|
||||
|
@ -24,9 +24,10 @@
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
|
||||
# For companies who don't want to put time zone specification in
|
||||
# their installation procedures. When users run date, they'll get the message.
|
||||
# Also useful for the "comp.sources" version.
|
||||
# For distributors who don't want to put time zone specification in
|
||||
# their installation procedures. Users that run 'date' will get the
|
||||
# time zone abbreviation "-00", indicating that the actual time zone
|
||||
# is unknown.
|
||||
|
||||
# Zone NAME GMTOFF RULES FORMAT
|
||||
Zone Factory 0 - "Local time zone must be set--see zic manual page"
|
||||
Zone Factory 0 - -00
|
||||
|
@ -79,6 +79,7 @@ Leap 2005 Dec 31 23:59:60 + S
|
||||
Leap 2008 Dec 31 23:59:60 + S
|
||||
Leap 2012 Jun 30 23:59:60 + S
|
||||
Leap 2015 Jun 30 23:59:60 + S
|
||||
Leap 2016 Dec 31 23:59:60 + S
|
||||
|
||||
# Updated through IERS Bulletin C51
|
||||
# File expires on: 28 December 2016
|
||||
# Updated through IERS Bulletin C52
|
||||
# File expires on: 28 June 2017
|
||||
|
@ -436,11 +436,42 @@ Zone America/Denver -6:59:56 - LMT 1883 Nov 18 12:00:04
|
||||
# north of the Salmon River, and the towns of Burgdorf and Warren),
|
||||
# Nevada (except West Wendover), Oregon (except the northern 3/4 of
|
||||
# Malheur county), and Washington
|
||||
|
||||
# From Paul Eggert (2016-08-20):
|
||||
# In early February 1948, in response to California's electricity shortage,
|
||||
# PG&E changed power frequency from 60 to 59.5 Hz during daylight hours,
|
||||
# causing electric clocks to lose six minutes per day. (This did not change
|
||||
# legal time, and is not part of the data here.) See:
|
||||
# Ross SA. An energy crisis from the past: Northern California in 1948.
|
||||
# Working Paper No. 8, Institute of Governmental Studies, UC Berkeley,
|
||||
# 1973-11. http://escholarship.org/uc/item/8x22k30c
|
||||
#
|
||||
# In another measure to save electricity, DST was instituted from 1948-03-14
|
||||
# at 02:01 to 1949-01-16 at 02:00, with the governor having the option to move
|
||||
# the fallback transition earlier. See pages 3-4 of:
|
||||
# http://clerk.assembly.ca.gov/sites/clerk.assembly.ca.gov/files/archive/Statutes/1948/48Vol1_Chapters.pdf
|
||||
#
|
||||
# In response:
|
||||
#
|
||||
# Governor Warren received a torrent of objecting mail, and it is not too much
|
||||
# to speculate that the objections to Daylight Saving Time were one important
|
||||
# factor in the defeat of the Dewey-Warren Presidential ticket in California.
|
||||
# -- Ross, p 25
|
||||
#
|
||||
# On December 8 the governor exercised the option, setting the date to January 1
|
||||
# (LA Times 1948-12-09). The transition time was 02:00 (LA Times 1949-01-01).
|
||||
#
|
||||
# Despite the controversy, in 1949 California voters approved Proposition 12,
|
||||
# which established DST from April's last Sunday at 01:00 until September's
|
||||
# last Sunday at 02:00. This was amended by 1962's Proposition 6, which changed
|
||||
# the fall-back date to October's last Sunday. See:
|
||||
# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1501&context=ca_ballot_props
|
||||
# http://repository.uchastings.edu/cgi/viewcontent.cgi?article=1636&context=ca_ballot_props
|
||||
#
|
||||
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER
|
||||
Rule CA 1948 only - Mar 14 2:00 1:00 D
|
||||
Rule CA 1948 only - Mar 14 2:01 1:00 D
|
||||
Rule CA 1949 only - Jan 1 2:00 0 S
|
||||
Rule CA 1950 1966 - Apr lastSun 2:00 1:00 D
|
||||
Rule CA 1950 1966 - Apr lastSun 1:00 1:00 D
|
||||
Rule CA 1950 1961 - Sep lastSun 2:00 0 S
|
||||
Rule CA 1962 1966 - Oct lastSun 2:00 0 S
|
||||
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
||||
@ -3304,7 +3335,7 @@ Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre
|
||||
# indicating that the normal ET rules are followed.
|
||||
#
|
||||
# From Paul Eggert (2014-08-19):
|
||||
# The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round. See:
|
||||
# The 2014-08-13 Cabinet meeting decided to stay on UT -04 year-round. See:
|
||||
# http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm
|
||||
# Model this as a switch from EST/EDT to AST ...
|
||||
# From Chris Walton (2014-11-04):
|
||||
|
@ -433,9 +433,9 @@ Rule Arg 2008 only - Oct Sun>=15 0:00 1:00 S
|
||||
# stuck on Summer daylight savings time even though the summer is over.
|
||||
|
||||
# From Paul Eggert (2013-09-05):
|
||||
# Perhaps San Luis operates on the legal fiction that it is at UTC-4
|
||||
# Perhaps San Luis operates on the legal fiction that it is at -04
|
||||
# with perpetual summer time, but ordinary usage typically seems to
|
||||
# just say it's at UTC-3; see, for example,
|
||||
# just say it's at -03; see, for example,
|
||||
# http://es.wikipedia.org/wiki/Hora_oficial_argentina
|
||||
# We've documented similar situations as being plain changes to
|
||||
# standard time, so let's do that here too. This does not change UTC
|
||||
|
@ -284,7 +284,7 @@ MH +0709+17112 Pacific/Majuro Marshall Islands (most areas)
|
||||
MH +0905+16720 Pacific/Kwajalein Kwajalein
|
||||
MK +4159+02126 Europe/Skopje
|
||||
ML +1239-00800 Africa/Bamako
|
||||
MM +1647+09610 Asia/Rangoon
|
||||
MM +1647+09610 Asia/Yangon
|
||||
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
|
||||
MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
|
||||
MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar
|
||||
|
@ -218,7 +218,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBZIP, \
|
||||
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
||||
LDFLAGS_windows := -export:ZIP_Open -export:ZIP_Close -export:ZIP_FindEntry \
|
||||
-export:ZIP_ReadEntry -export:ZIP_GetNextEntry \
|
||||
-export:ZIP_InflateFully -export:ZIP_CRC32, \
|
||||
-export:ZIP_InflateFully -export:ZIP_CRC32 -export:ZIP_FreeEntry, \
|
||||
LIBS_unix := -ljvm -ljava $(LIBZ), \
|
||||
LIBS_solaris := -lc, \
|
||||
LIBS_windows := jvm.lib $(WIN_JAVA_LIB), \
|
||||
|
@ -98,7 +98,6 @@ SUNWprivate_1.1 {
|
||||
Java_sun_net_sdp_SdpSupport_create0;
|
||||
Java_sun_net_spi_DefaultProxySelector_init;
|
||||
Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
|
||||
NET_AllocSockaddr;
|
||||
NET_SockaddrToInetAddress;
|
||||
NET_SockaddrEqualsInetAddress;
|
||||
NET_InetAddressToSockaddr;
|
||||
|
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