This commit is contained in:
Phil Race 2016-10-10 14:35:20 -07:00
commit e4ed1ab3d7
317 changed files with 11443 additions and 3416 deletions

View File

@ -380,3 +380,4 @@ a71210c0d9800eb6925b61ecd6198abd554f90ee jdk-9+134
e384420383a5b79fa0012ebcb25d8f83cff7f777 jdk-9+135
1b4b5d01aa11edf24b6fadbe3d2f3e411e3b02cd jdk-9+136
9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137
d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138

View File

@ -380,3 +380,4 @@ be1218f792a450dfb5d4b1f82616b9d95a6a732e jdk-9+133
82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135
3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136
d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138

View File

@ -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@

View File

@ -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

View File

@ -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

View File

@ -380,3 +380,4 @@ f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131
094d0db606db976045f594dba47d4593b715cc81 jdk-9+135
aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136
258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138

View File

@ -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
################################################################################

View File

@ -540,3 +540,4 @@ b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134
3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135
a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136
dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138

View File

@ -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), \

View File

@ -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), \

View File

@ -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); }

View File

@ -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);
}
}

View File

@ -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 =

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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();
}

View File

@ -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);

View File

@ -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,

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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

View File

@ -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); }

View File

@ -34,7 +34,6 @@ class G1RemSet;
class G1ConcurrentMark;
class DirtyCardToOopClosure;
class G1CMBitMap;
class G1CMMarkStack;
class G1ParScanThreadState;
class G1CMTask;
class ReferenceProcessor;

View File

@ -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;
}

View File

@ -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.

View File

@ -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) {

View File

@ -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.

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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());

View File

@ -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.

View File

@ -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);
};

View File

@ -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);

View File

@ -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");

View File

@ -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.

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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; };

View File

@ -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));

View File

@ -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;

View File

@ -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());
}

View File

@ -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 {

View File

@ -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

View File

@ -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") \

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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",

View File

@ -271,7 +271,8 @@ enum SharedSpaceType {
SharedReadOnly,
SharedReadWrite,
SharedMiscData,
SharedMiscCode
SharedMiscCode,
SharedOptional
};
void report_out_of_shared_space(SharedSpaceType space_type);

View File

@ -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);

View File

@ -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

View 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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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();
}
}

View 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;
}
}

View 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;
}
}

View File

@ -0,0 +1,5 @@
Manifest-Version: 1.0
Premain-Class: TransformerAgent
Agent-Class: TransformerAgent
Can-Retransform-Classes: true
Can-Redefine-Classes: false

View File

@ -380,3 +380,4 @@ e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135
f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136
a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138

View File

@ -383,3 +383,4 @@ ab1d78d395d4cb8be426ff181211da1a4085cf01 jdk-9+134
22631824f55128a7ab6605493b3001a37af6a168 jdk-9+135
09ec13a99f50a4a346180d1e3b0fd8bc1ee399ce jdk-9+136
297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137
7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138

View File

@ -381,3 +381,4 @@ d5c70818cd8a82e76632c8c815bdb4f75f53aeaf jdk-9+132
54c5931849a33a363e03fdffa141503f5cc4779d jdk-9+136
e72df94364e3686e7d62059ce0d6b187b82da713 jdk-9+137
665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139

View File

@ -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.

View File

@ -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)

View 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 \
))

View File

@ -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

View File

@ -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

View File

@ -21,4 +21,4 @@
# or visit www.oracle.com if you need additional information or have any
# questions.
#
tzdata2016f
tzdata2016g

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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), \

View File

@ -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