--- a/make/common/NativeCompilation.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/common/NativeCompilation.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -237,7 +237,7 @@
$1_SRC_FILE := $$($1_FILE)
ifneq ($$($1_DISABLE_THIS_FILE_DEFINE), true)
- $1_THIS_FILE = -DTHIS_FILE='"$$(<F)"'
+ $1_THIS_FILE = -DTHIS_FILE='"$$($1_FILENAME)"'
endif
ifeq ($$($1_OPTIMIZATION), )
--- a/make/gensrc/GensrcMisc.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/gensrc/GensrcMisc.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -42,6 +42,7 @@
@@VERSION_DATE@@ => $(VERSION_DATE) ; \
@@VERSION_CLASSFILE_MAJOR@@ => $(VERSION_CLASSFILE_MAJOR) ; \
@@VERSION_CLASSFILE_MINOR@@ => $(VERSION_CLASSFILE_MINOR) ; \
+ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \
@@VENDOR_VERSION_STRING@@ => $(VENDOR_VERSION_STRING) ; \
@@VENDOR@@ => $(COMPANY_NAME) ; \
@@VENDOR_URL@@ => $(VENDOR_URL) ; \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/launcher/Launcher-jdk.jfr.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LauncherCommon.gmk
+
+$(eval $(call SetupBuildLauncher, jfr, \
+ MAIN_CLASS := jdk.jfr.internal.tool.Main, \
+ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
+))
--- a/make/launcher/Launcher-jdk.pack.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/launcher/Launcher-jdk.pack.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -39,7 +39,7 @@
# On Mac, we have always exported all symbols, probably due to oversight
# and/or misunderstanding. To emulate this, don't hide any symbols
# by default.
-# On AIX/xlc we need at least xlc 13.1 for the symbol hiding
+# On AIX/xlc we need at least xlc 13.1 for the symbol hiding (see JDK-8214063)
# Also provide an override for non-conformant libraries.
ifeq ($(TOOLCHAIN_TYPE), gcc)
CXXFLAGS_JDKEXE += -fvisibility=hidden
@@ -50,10 +50,6 @@
endif
else ifeq ($(TOOLCHAIN_TYPE), solstudio)
CXXFLAGS_JDKEXE += -xldscope=hidden
-else ifeq ($(TOOLCHAIN_TYPE), xlc)
- ifneq ($(CC_VERSION_NUMBER), 12.1)
- CXXFLAGS_JDKEXE += -qvisibility=hidden
- endif
endif
UNPACKEXE_SRC := $(TOPDIR)/src/jdk.pack/share/native/common-unpack \
--- a/make/launcher/LauncherCommon.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/launcher/LauncherCommon.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -33,7 +33,7 @@
# On Mac, we have always exported all symbols, probably due to oversight
# and/or misunderstanding. To emulate this, don't hide any symbols
# by default.
-# On AIX/xlc we need at least xlc 13.1 for the symbol hiding
+# On AIX/xlc we need at least xlc 13.1 for the symbol hiding (see JDK-8214063)
# Also provide an override for non-conformant libraries.
ifeq ($(TOOLCHAIN_TYPE), gcc)
LAUNCHER_CFLAGS += -fvisibility=hidden
@@ -42,10 +42,6 @@
LAUNCHER_CFLAGS += -fvisibility=hidden
else ifeq ($(TOOLCHAIN_TYPE), solstudio)
LAUNCHER_CFLAGS += -xldscope=hidden
-else ifeq ($(TOOLCHAIN_TYPE), xlc)
- ifneq ($(CC_VERSION_NUMBER), 12.1)
- CXXFLAGS_JDKEXE += -qvisibility=hidden
- endif
endif
LAUNCHER_SRC := $(TOPDIR)/src/java.base/share/native/launcher
--- a/make/lib/Awt2dLibraries.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/lib/Awt2dLibraries.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -776,17 +776,6 @@
ifeq ($(USE_EXTERNAL_LIBPNG), false)
LIBSPLASHSCREEN_HEADER_DIRS += libsplashscreen/libpng
-
- ifeq ($(OPENJDK_TARGET_OS), macosx)
- ifeq ($(USE_EXTERNAL_LIBZ), true)
- # When building our own libpng and using an external libz, we need to
- # inject our own libz.h to tweak the exported ZLIB_VERNUM macro. See
- # $(TOPDIR)/src/java.desktop/macosx/native/libsplashscreen/libpng/zlibwrapper/zlib.h
- # for details. This must be specified with -iquote, not -I to avoid a
- # circular include.
- LIBSPLASHSCREEN_CFLAGS += -iquote $(TOPDIR)/src/$(MODULE)/macosx/native/libsplashscreen/libpng/zlibwrapper
- endif
- endif
else
LIBSPLASHSCREEN_EXCLUDES += libpng
endif
--- a/make/lib/LibCommon.gmk Wed Dec 05 17:03:58 2018 -0500
+++ b/make/lib/LibCommon.gmk Wed Dec 05 17:05:42 2018 -0500
@@ -38,7 +38,7 @@
# On Mac, we have always exported all symbols, probably due to oversight
# and/or misunderstanding. To emulate this, don't hide any symbols
# by default.
-# On AIX/xlc we need at least xlc 13.1 for the symbol hiding
+# On AIX/xlc we need at least xlc 13.1 for the symbol hiding (see JDK-8214063)
# Also provide an override for non-conformant libraries.
ifeq ($(TOOLCHAIN_TYPE), gcc)
CFLAGS_JDKLIB += -fvisibility=hidden
@@ -53,12 +53,6 @@
CFLAGS_JDKLIB += -xldscope=hidden
CXXFLAGS_JDKLIB += -xldscope=hidden
EXPORT_ALL_SYMBOLS := -xldscope=global
-else ifeq ($(TOOLCHAIN_TYPE), xlc)
- ifneq ($(CC_VERSION_NUMBER), 12.1)
- CFLAGS_JDKLIB += -qvisibility=hidden
- CXXFLAGS_JDKLIB += -qvisibility=hidden
- EXPORT_ALL_SYMBOLS := -qvisibility=default
- endif
endif
# Put the libraries here.
--- a/src/hotspot/cpu/zero/stack_zero.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/cpu/zero/stack_zero.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -26,7 +26,7 @@
#include "precompiled.hpp"
#include "interpreter/bytecodeInterpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/thread.inline.hpp"
#include "stack_zero.hpp"
#include "stack_zero.inline.hpp"
#include "runtime/frame.inline.hpp"
--- a/src/hotspot/share/classfile/classLoaderData.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -192,7 +192,7 @@
OrderAccess::release_store(&_head, next);
}
oop* handle = &_head->_data[_head->_size];
- *handle = o;
+ NativeAccess<IS_DEST_UNINITIALIZED>::oop_store(handle, o);
OrderAccess::release_store(&_head->_size, _head->_size + 1);
return handle;
}
@@ -234,7 +234,7 @@
VerifyContainsOopClosure(oop target) : _target(target), _found(false) {}
void do_oop(oop* p) {
- if (p != NULL && oopDesc::equals(RawAccess<>::oop_load(p), _target)) {
+ if (p != NULL && oopDesc::equals(NativeAccess<AS_NO_KEEPALIVE>::oop_load(p), _target)) {
_found = true;
}
}
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -583,7 +583,6 @@
}
void ClassLoaderDataGraph::purge() {
- assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
ClassLoaderData* list = _unloading;
_unloading = NULL;
ClassLoaderData* next = list;
--- a/src/hotspot/share/classfile/compactHashtable.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/compactHashtable.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -375,6 +375,9 @@
inline int remain() {
return (int)(_end - _p);
}
+ int last_line_no() {
+ return _line_no - 1;
+ }
void corrupted(const char *p, const char *msg);
--- a/src/hotspot/share/classfile/dictionary.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/dictionary.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -235,7 +235,7 @@
void Dictionary::do_unloading() {
- assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
+ assert_locked_or_safepoint(SystemDictionary_lock);
// The NULL class loader doesn't initiate loading classes from other class loaders
if (loader_data() == ClassLoaderData::the_null_class_loader_data()) {
--- a/src/hotspot/share/classfile/dictionary.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/dictionary.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -173,7 +173,7 @@
for (ProtectionDomainEntry* current = pd_set(); // accessed at a safepoint
current != NULL;
current = current->_next) {
- oopDesc::verify(current->_pd_cache->object_no_keepalive());
+ guarantee(oopDesc::is_oop(current->_pd_cache->object_no_keepalive()), "Invalid oop");
}
}
--- a/src/hotspot/share/classfile/verifier.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/classfile/verifier.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -2017,8 +2017,7 @@
if (kls != NULL) {
current_class()->class_loader_data()->record_dependency(kls);
if (log_is_enabled(Debug, class, resolve)) {
- InstanceKlass* cur_class = InstanceKlass::cast(current_class());
- Verifier::trace_class_resolution(kls, cur_class);
+ Verifier::trace_class_resolution(kls, current_class());
}
}
return kls;
--- a/src/hotspot/share/code/codeBehaviours.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/codeBehaviours.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -30,10 +30,10 @@
CompiledICProtectionBehaviour* CompiledICProtectionBehaviour::_current = NULL;
bool DefaultICProtectionBehaviour::lock(CompiledMethod* method) {
- if (CompiledIC_lock->owned_by_self()) {
+ if (is_safe(method)) {
return false;
}
- CompiledIC_lock->lock();
+ CompiledIC_lock->lock_without_safepoint_check();
return true;
}
--- a/src/hotspot/share/code/codeCache.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/codeCache.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -1411,8 +1411,7 @@
}
if (heap->full_count() == 0) {
- LogTarget(Debug, codecache) lt;
- if (lt.is_enabled()) {
+ if (PrintCodeHeapAnalytics) {
CompileBroker::print_heapinfo(tty, "all", "4096"); // details, may be a lot!
}
}
--- a/src/hotspot/share/code/codeHeapState.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/codeHeapState.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -38,7 +38,7 @@
// Aggregation condenses the information of a piece of the CodeHeap
// (4096 bytes by default) into an analysis granule. These granules
// contain enough detail to gain initial insight while keeping the
-// internal sttructure sizes in check.
+// internal structure sizes in check.
//
// The CodeHeap is a living thing. Therefore, the aggregate is collected
// under the CodeCache_lock. The subsequent print steps are only locked
@@ -63,15 +63,12 @@
//
// If you are (only) interested in how the CodeHeap looks like after running
// a sample workload, you can use the command line option
-// -Xlog:codecache=Trace
+// -XX:+PrintCodeHeapAnalytics
+// It will cause a full analysis to be written to tty. In addition, a full
+// analysis will be written the first time a "CodeCache full" condition is
+// detected.
//
-// To see the CodeHeap state in case of a "CodeCache full" condition, start the
-// VM with the
-// -Xlog:codecache=Debug
-// command line option. It will produce output only for the first time the
-// condition is recognized.
-//
-// Both command line option variants produce output identical to the jcmd function
+// The command line option produces output identical to the jcmd function
// jcmd <pid> Compiler.CodeHeap_Analytics all 4096
// ---------------------------------------------------------------------------------
--- a/src/hotspot/share/code/compiledIC.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/compiledIC.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -126,7 +126,6 @@
{
CodeBlob* cb = CodeCache::find_blob_unsafe(_call->instruction_address());
- MutexLockerEx pl(CompiledICLocker::is_safe(cb->as_compiled_method()) ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
assert(cb != NULL && cb->is_compiled(), "must be compiled");
_call->set_destination_mt_safe(entry_point);
}
@@ -237,7 +236,13 @@
initialize_from_iter(iter);
}
-bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS) {
+// This function may fail for two reasons: either due to running out of vtable
+// stubs, or due to running out of IC stubs in an attempted transition to a
+// transitional state. The needs_ic_stub_refill value will be set if the failure
+// was due to running out of IC stubs, in which case the caller will refill IC
+// stubs and retry.
+bool CompiledIC::set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode,
+ bool& needs_ic_stub_refill, TRAPS) {
assert(CompiledICLocker::is_safe(_method), "mt unsafe call");
assert(!is_optimized(), "cannot set an optimized virtual call to megamorphic");
assert(is_call_to_compiled() || is_call_to_interpreted(), "going directly to megamorphic?");
@@ -259,7 +264,11 @@
CompiledICHolder* holder = new CompiledICHolder(call_info->resolved_method()->method_holder(),
call_info->resolved_klass(), false);
holder->claim();
- InlineCacheBuffer::create_transition_stub(this, holder, entry);
+ if (!InlineCacheBuffer::create_transition_stub(this, holder, entry)) {
+ delete holder;
+ needs_ic_stub_refill = true;
+ return false;
+ }
} else {
assert(call_info->call_kind() == CallInfo::vtable_call, "either itable or vtable");
// Can be different than selected_method->vtable_index(), due to package-private etc.
@@ -269,7 +278,10 @@
if (entry == NULL) {
return false;
}
- InlineCacheBuffer::create_transition_stub(this, NULL, entry);
+ if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) {
+ needs_ic_stub_refill = true;
+ return false;
+ }
}
if (TraceICs) {
@@ -350,7 +362,7 @@
return is_call_to_interpreted;
}
-void CompiledIC::set_to_clean(bool in_use) {
+bool CompiledIC::set_to_clean(bool in_use) {
assert(CompiledICLocker::is_safe(_method), "mt unsafe call");
if (TraceInlineCacheClearing || TraceICs) {
tty->print_cr("IC@" INTPTR_FORMAT ": set to clean", p2i(instruction_address()));
@@ -361,7 +373,7 @@
// A zombie transition will always be safe, since the metadata has already been set to NULL, so
// we only need to patch the destination
- bool safe_transition = _call->is_safe_for_patching() || !in_use || is_optimized() || CompiledICLocker::is_safe(_method);
+ bool safe_transition = _call->is_safe_for_patching() || !in_use || is_optimized() || SafepointSynchronize::is_at_safepoint();
if (safe_transition) {
// Kill any leftover stub we might have too
@@ -373,7 +385,9 @@
}
} else {
// Unsafe transition - create stub.
- InlineCacheBuffer::create_transition_stub(this, NULL, entry);
+ if (!InlineCacheBuffer::create_transition_stub(this, NULL, entry)) {
+ return false;
+ }
}
// We can't check this anymore. With lazy deopt we could have already
// cleaned this IC entry before we even return. This is possible if
@@ -382,6 +396,7 @@
// race because the IC entry was complete when we safepointed so
// cleaning it immediately is harmless.
// assert(is_clean(), "sanity check");
+ return true;
}
bool CompiledIC::is_clean() const {
@@ -393,7 +408,7 @@
return is_clean;
}
-void CompiledIC::set_to_monomorphic(CompiledICInfo& info) {
+bool CompiledIC::set_to_monomorphic(CompiledICInfo& info) {
assert(CompiledICLocker::is_safe(_method), "mt unsafe call");
// Updating a cache to the wrong entry can cause bugs that are very hard
// to track down - if cache entry gets invalid - we just clean it. In
@@ -411,8 +426,7 @@
if (info.to_interpreter() || info.to_aot()) {
// Call to interpreter
if (info.is_optimized() && is_optimized()) {
- assert(is_clean(), "unsafe IC path");
- MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
+ assert(is_clean(), "unsafe IC path");
// the call analysis (callee structure) specifies that the call is optimized
// (either because of CHA or the static target is final)
// At code generation time, this call has been emitted as static call
@@ -430,7 +444,11 @@
}
} else {
// Call via method-klass-holder
- InlineCacheBuffer::create_transition_stub(this, info.claim_cached_icholder(), info.entry());
+ CompiledICHolder* holder = info.claim_cached_icholder();
+ if (!InlineCacheBuffer::create_transition_stub(this, holder, info.entry())) {
+ delete holder;
+ return false;
+ }
if (TraceICs) {
ResourceMark rm(thread);
tty->print_cr ("IC@" INTPTR_FORMAT ": monomorphic to interpreter via icholder ", p2i(instruction_address()));
@@ -450,7 +468,9 @@
(!is_in_transition_state() && (info.is_optimized() || static_bound || is_clean()));
if (!safe) {
- InlineCacheBuffer::create_transition_stub(this, info.cached_metadata(), info.entry());
+ if (!InlineCacheBuffer::create_transition_stub(this, info.cached_metadata(), info.entry())) {
+ return false;
+ }
} else {
if (is_optimized()) {
set_ic_destination(info.entry());
@@ -475,6 +495,7 @@
// race because the IC entry was complete when we safepointed so
// cleaning it immediately is harmless.
// assert(is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
+ return true;
}
@@ -575,16 +596,16 @@
// ----------------------------------------------------------------------------
-void CompiledStaticCall::set_to_clean(bool in_use) {
+bool CompiledStaticCall::set_to_clean(bool in_use) {
// in_use is unused but needed to match template function in CompiledMethod
assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call");
// Reset call site
- MutexLockerEx pl(SafepointSynchronize::is_at_safepoint() ? NULL : Patching_lock, Mutex::_no_safepoint_check_flag);
set_destination_mt_safe(resolve_call_stub());
// Do not reset stub here: It is too expensive to call find_stub.
// Instead, rely on caller (nmethod::clear_inline_caches) to clear
// both the call and its stub.
+ return true;
}
bool CompiledStaticCall::is_clean() const {
@@ -624,7 +645,6 @@
void CompiledStaticCall::set(const StaticCallInfo& info) {
assert(CompiledICLocker::is_safe(instruction_address()), "mt unsafe call");
- MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
// Updating a cache to the wrong entry can cause bugs that are very hard
// to track down - if cache entry gets invalid - we just clean it. In
// this way it is always the same code path that is responsible for
--- a/src/hotspot/share/code/compiledIC.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/compiledIC.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -28,6 +28,7 @@
#include "code/nativeInst.hpp"
#include "interpreter/linkResolver.hpp"
#include "oops/compiledICHolder.hpp"
+#include "runtime/safepointVerifiers.hpp"
//-----------------------------------------------------------------------------
// The CompiledIC represents a compiled inline cache.
@@ -67,6 +68,7 @@
CompiledMethod* _method;
CompiledICProtectionBehaviour* _behaviour;
bool _locked;
+ NoSafepointVerifier _nsv;
public:
CompiledICLocker(CompiledMethod* method);
@@ -272,13 +274,13 @@
//
// They all takes a TRAP argument, since they can cause a GC if the inline-cache buffer is full.
//
- void set_to_clean(bool in_use = true);
- void set_to_monomorphic(CompiledICInfo& info);
+ bool set_to_clean(bool in_use = true);
+ bool set_to_monomorphic(CompiledICInfo& info);
void clear_ic_stub();
// Returns true if successful and false otherwise. The call can fail if memory
- // allocation in the code cache fails.
- bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS);
+ // allocation in the code cache fails, or ic stub refill is required.
+ bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, bool& needs_ic_stub_refill, TRAPS);
static void compute_monomorphic_entry(const methodHandle& method, Klass* receiver_klass,
bool is_optimized, bool static_bound, bool caller_is_nmethod,
@@ -372,7 +374,7 @@
virtual address destination() const = 0;
// Clean static call (will force resolving on next use)
- void set_to_clean(bool in_use = true);
+ bool set_to_clean(bool in_use = true);
// Set state. The entry must be the same, as computed by compute_entry.
// Computation and setting is split up, since the actions are separate during
--- a/src/hotspot/share/code/compiledMethod.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/compiledMethod.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -27,6 +27,7 @@
#include "code/compiledMethod.inline.hpp"
#include "code/scopeDesc.hpp"
#include "code/codeCache.hpp"
+#include "code/icBuffer.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/gcBehaviours.hpp"
#include "interpreter/bytecode.inline.hpp"
@@ -430,27 +431,30 @@
#endif // ASSERT
-void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) {
+bool CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) {
+ if (ic->is_clean()) {
+ return true;
+ }
if (ic->is_icholder_call()) {
// The only exception is compiledICHolder metdata which may
// yet be marked below. (We check this further below).
CompiledICHolder* cichk_metdata = ic->cached_icholder();
if (cichk_metdata->is_loader_alive()) {
- return;
+ return true;
}
} else {
Metadata* ic_metdata = ic->cached_metadata();
if (ic_metdata != NULL) {
if (ic_metdata->is_klass()) {
if (((Klass*)ic_metdata)->is_loader_alive()) {
- return;
+ return true;
}
} else if (ic_metdata->is_method()) {
Method* method = (Method*)ic_metdata;
assert(!method->is_old(), "old method should have been cleaned");
if (method->method_holder()->is_loader_alive()) {
- return;
+ return true;
}
} else {
ShouldNotReachHere();
@@ -458,7 +462,7 @@
}
}
- ic->set_to_clean();
+ return ic->set_to_clean();
}
// static_stub_Relocations may have dangling references to
@@ -496,7 +500,7 @@
// Clean references to unloaded nmethods at addr from this one, which is not unloaded.
template <class CompiledICorStaticCall>
-static void clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
+static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
bool clean_all) {
// Ok, to lookup references to zombies here
CodeBlob *cb = CodeCache::find_blob_unsafe(addr);
@@ -504,20 +508,23 @@
if (nm != NULL) {
// Clean inline caches pointing to both zombie and not_entrant methods
if (clean_all || !nm->is_in_use() || nm->is_unloading() || (nm->method()->code() != nm)) {
- ic->set_to_clean(from->is_alive());
+ if (!ic->set_to_clean(from->is_alive())) {
+ return false;
+ }
assert(ic->is_clean(), "nmethod " PTR_FORMAT "not clean %s", p2i(from), from->method()->name_and_sig_as_C_string());
}
}
+ return true;
}
-static void clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from,
+static bool clean_if_nmethod_is_unloaded(CompiledIC *ic, CompiledMethod* from,
bool clean_all) {
- clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from, clean_all);
+ return clean_if_nmethod_is_unloaded(ic, ic->ic_destination(), from, clean_all);
}
-static void clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from,
+static bool clean_if_nmethod_is_unloaded(CompiledStaticCall *csc, CompiledMethod* from,
bool clean_all) {
- clean_if_nmethod_is_unloaded(csc, csc->destination(), from, clean_all);
+ return clean_if_nmethod_is_unloaded(csc, csc->destination(), from, clean_all);
}
// Cleans caches in nmethods that point to either classes that are unloaded
@@ -527,7 +534,7 @@
// nmethods are unloaded. Return postponed=true in the parallel case for
// inline caches found that point to nmethods that are not yet visited during
// the do_unloading walk.
-void CompiledMethod::unload_nmethod_caches(bool unloading_occurred) {
+bool CompiledMethod::unload_nmethod_caches(bool unloading_occurred) {
ResourceMark rm;
// Exception cache only needs to be called if unloading occurred
@@ -535,18 +542,32 @@
clean_exception_cache();
}
- cleanup_inline_caches_impl(unloading_occurred, false);
+ if (!cleanup_inline_caches_impl(unloading_occurred, false)) {
+ return false;
+ }
// All static stubs need to be cleaned.
clean_ic_stubs();
// Check that the metadata embedded in the nmethod is alive
DEBUG_ONLY(metadata_do(check_class));
+ return true;
+}
+
+void CompiledMethod::cleanup_inline_caches(bool clean_all) {
+ for (;;) {
+ { CompiledICLocker ic_locker(this);
+ if (cleanup_inline_caches_impl(false, clean_all)) {
+ return;
+ }
+ }
+ InlineCacheBuffer::refill_ic_stubs();
+ }
}
// Called to clean up after class unloading for live nmethods and from the sweeper
// for all methods.
-void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
+bool CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) {
assert(CompiledICLocker::is_safe(this), "mt unsafe call");
ResourceMark rm;
@@ -561,30 +582,34 @@
if (unloading_occurred) {
// If class unloading occurred we first clear ICs where the cached metadata
// is referring to an unloaded klass or method.
- clean_ic_if_metadata_is_dead(CompiledIC_at(&iter));
+ if (!clean_ic_if_metadata_is_dead(CompiledIC_at(&iter))) {
+ return false;
+ }
}
- clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all);
+ if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) {
+ return false;
+ }
break;
case relocInfo::opt_virtual_call_type:
- clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all);
+ if (!clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), this, clean_all)) {
+ return false;
+ }
break;
case relocInfo::static_call_type:
- clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all);
+ if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) {
+ return false;
+ }
break;
- case relocInfo::oop_type:
- break;
-
- case relocInfo::metadata_type:
- break; // nothing to do.
-
default:
break;
}
}
+
+ return true;
}
// Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found
--- a/src/hotspot/share/code/compiledMethod.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/compiledMethod.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -352,12 +352,11 @@
// Inline cache support for class unloading and nmethod unloading
private:
- void cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all);
+ bool cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all);
+
public:
- void cleanup_inline_caches(bool clean_all) {
- // Serial version used by sweeper and whitebox test
- cleanup_inline_caches_impl(false, clean_all);
- }
+ // Serial version used by sweeper and whitebox test
+ void cleanup_inline_caches(bool clean_all);
virtual void clear_inline_caches();
void clear_ic_stubs();
@@ -390,7 +389,7 @@
address oops_reloc_begin() const;
private:
- void static clean_ic_if_metadata_is_dead(CompiledIC *ic);
+ bool static clean_ic_if_metadata_is_dead(CompiledIC *ic);
void clean_ic_stubs();
@@ -400,7 +399,7 @@
virtual bool is_unloading() = 0;
- void unload_nmethod_caches(bool class_unloading_occurred);
+ bool unload_nmethod_caches(bool class_unloading_occurred);
virtual void do_unloading(bool unloading_occurred) { }
private:
--- a/src/hotspot/share/code/dependencyContext.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/dependencyContext.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -35,8 +35,9 @@
PerfCounter* DependencyContext::_perf_total_buckets_deallocated_count = NULL;
PerfCounter* DependencyContext::_perf_total_buckets_stale_count = NULL;
PerfCounter* DependencyContext::_perf_total_buckets_stale_acc_count = NULL;
-nmethodBucket* volatile DependencyContext::_purge_list = NULL;
-volatile uint64_t DependencyContext::_cleaning_epoch = 0;
+nmethodBucket* volatile DependencyContext::_purge_list = NULL;
+volatile uint64_t DependencyContext::_cleaning_epoch = 0;
+uint64_t DependencyContext::_cleaning_epoch_monotonic = 0;
void dependencyContext_init() {
DependencyContext::init();
@@ -262,7 +263,7 @@
return Atomic::sub(1, &_count);
}
-// We use a safepoint counter to track the safepoint counter the last time a given
+// We use a monotonically increasing epoch counter to track the last epoch a given
// dependency context was cleaned. GC threads claim cleanup tasks by performing
// a CAS on this value.
bool DependencyContext::claim_cleanup() {
@@ -311,13 +312,15 @@
// a purge list to be deleted later.
void DependencyContext::cleaning_start() {
assert(SafepointSynchronize::is_at_safepoint(), "must be");
- uint64_t epoch = SafepointSynchronize::safepoint_counter();
+ uint64_t epoch = ++_cleaning_epoch_monotonic;
Atomic::store(epoch, &_cleaning_epoch);
}
// The epilogue marks the end of dependency context cleanup by the GC,
-// and also makes subsequent releases of nmethodBuckets case immediate
-// deletion. It is admitted to end the cleanup in a concurrent phase.
+// and also makes subsequent releases of nmethodBuckets cause immediate
+// deletion. It is okay to delay calling of cleaning_end() to a concurrent
+// phase, subsequent to the safepoint operation in which cleaning_start()
+// was called. That allows dependency contexts to be cleaned concurrently.
void DependencyContext::cleaning_end() {
uint64_t epoch = 0;
Atomic::store(epoch, &_cleaning_epoch);
--- a/src/hotspot/share/code/dependencyContext.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/dependencyContext.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -86,11 +86,12 @@
nmethodBucket* dependencies();
nmethodBucket* dependencies_not_unloading();
- static PerfCounter* _perf_total_buckets_allocated_count;
- static PerfCounter* _perf_total_buckets_deallocated_count;
- static PerfCounter* _perf_total_buckets_stale_count;
- static PerfCounter* _perf_total_buckets_stale_acc_count;
+ static PerfCounter* _perf_total_buckets_allocated_count;
+ static PerfCounter* _perf_total_buckets_deallocated_count;
+ static PerfCounter* _perf_total_buckets_stale_count;
+ static PerfCounter* _perf_total_buckets_stale_acc_count;
static nmethodBucket* volatile _purge_list;
+ static uint64_t _cleaning_epoch_monotonic;
static volatile uint64_t _cleaning_epoch;
public:
--- a/src/hotspot/share/code/icBuffer.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/icBuffer.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -42,10 +42,10 @@
DEF_STUB_INTERFACE(ICStub);
StubQueue* InlineCacheBuffer::_buffer = NULL;
-ICStub* InlineCacheBuffer::_next_stub = NULL;
CompiledICHolder* InlineCacheBuffer::_pending_released = NULL;
int InlineCacheBuffer::_pending_count = 0;
+DEBUG_ONLY(volatile int InlineCacheBuffer::_needs_refill = 0;)
void ICStub::finalize() {
if (!is_empty()) {
@@ -103,52 +103,45 @@
//-----------------------------------------------------------------------------------------------
// Implementation of InlineCacheBuffer
-void InlineCacheBuffer::init_next_stub() {
- ICStub* ic_stub = (ICStub*)buffer()->request_committed (ic_stub_code_size());
- assert (ic_stub != NULL, "no room for a single stub");
- set_next_stub(ic_stub);
-}
void InlineCacheBuffer::initialize() {
if (_buffer != NULL) return; // already initialized
_buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer");
assert (_buffer != NULL, "cannot allocate InlineCacheBuffer");
- init_next_stub();
}
ICStub* InlineCacheBuffer::new_ic_stub() {
- while (true) {
- ICStub* ic_stub = (ICStub*)buffer()->request_committed(ic_stub_code_size());
- if (ic_stub != NULL) {
- return ic_stub;
- }
- // we ran out of inline cache buffer space; must enter safepoint.
- // We do this by forcing a safepoint
- EXCEPTION_MARK;
+ return (ICStub*)buffer()->request_committed(ic_stub_code_size());
+}
+
+
+void InlineCacheBuffer::refill_ic_stubs() {
+ DEBUG_ONLY(Atomic::store(0, &_needs_refill));
+ // we ran out of inline cache buffer space; must enter safepoint.
+ // We do this by forcing a safepoint
+ EXCEPTION_MARK;
- VM_ICBufferFull ibf;
- VMThread::execute(&ibf);
- // We could potential get an async. exception at this point.
- // In that case we will rethrow it to ourselvs.
- if (HAS_PENDING_EXCEPTION) {
- oop exception = PENDING_EXCEPTION;
- CLEAR_PENDING_EXCEPTION;
- Thread::send_async_exception(JavaThread::current()->threadObj(), exception);
- }
+ VM_ICBufferFull ibf;
+ VMThread::execute(&ibf);
+ // We could potential get an async. exception at this point.
+ // In that case we will rethrow it to ourselvs.
+ if (HAS_PENDING_EXCEPTION) {
+ oop exception = PENDING_EXCEPTION;
+ CLEAR_PENDING_EXCEPTION;
+ Thread::send_async_exception(JavaThread::current()->threadObj(), exception);
}
- ShouldNotReachHere();
- return NULL;
}
void InlineCacheBuffer::update_inline_caches() {
- if (buffer()->number_of_stubs() > 1) {
+ assert(_needs_refill == 0,
+ "Forgot to handle a failed IC transition requiring IC stubs");
+ if (buffer()->number_of_stubs() > 0) {
if (TraceICBuffer) {
tty->print_cr("[updating inline caches with %d stubs]", buffer()->number_of_stubs());
}
buffer()->remove_all();
- init_next_stub();
}
release_pending_icholders();
}
@@ -160,7 +153,7 @@
bool InlineCacheBuffer::is_empty() {
- return buffer()->number_of_stubs() == 1; // always has sentinel
+ return buffer()->number_of_stubs() == 0;
}
@@ -169,8 +162,7 @@
}
-void InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) {
- MutexLockerEx ml(CompiledIC_lock->owned_by_self() ? NULL : CompiledIC_lock);
+bool InlineCacheBuffer::create_transition_stub(CompiledIC *ic, void* cached_value, address entry) {
assert(!SafepointSynchronize::is_at_safepoint(), "should not be called during a safepoint");
assert(CompiledICLocker::is_safe(ic->instruction_address()), "mt unsafe call");
if (TraceICBuffer) {
@@ -178,20 +170,24 @@
p2i(ic->instruction_address()), p2i(entry), p2i(cached_value));
}
+ // allocate and initialize new "out-of-line" inline-cache
+ ICStub* ic_stub = new_ic_stub();
+ if (ic_stub == NULL) {
+ DEBUG_ONLY(Atomic::inc(&_needs_refill));
+ return false;
+ }
+
// If an transition stub is already associate with the inline cache, then we remove the association.
if (ic->is_in_transition_state()) {
ICStub* old_stub = ICStub_from_destination_address(ic->stub_address());
old_stub->clear();
}
- // allocate and initialize new "out-of-line" inline-cache
- ICStub* ic_stub = get_next_stub();
ic_stub->set_stub(ic, cached_value, entry);
// Update inline cache in nmethod to point to new "out-of-line" allocated inline cache
ic->set_ic_destination(ic_stub);
-
- set_next_stub(new_ic_stub()); // can cause safepoint synchronization
+ return true;
}
@@ -225,9 +221,7 @@
// not safe to free them until them since they might be visible to
// another thread.
void InlineCacheBuffer::queue_for_release(CompiledICHolder* icholder) {
- MutexLockerEx mex1((CompiledIC_lock->owned_by_self() ||
- SafepointSynchronize::is_at_safepoint()) ? NULL : CompiledIC_lock);
- MutexLockerEx mex2(InlineCacheBuffer_lock);
+ MutexLockerEx mex(InlineCacheBuffer_lock, Mutex::_no_safepoint_check_flag);
icholder->set_next(_pending_released);
_pending_released = icholder;
_pending_count++;
--- a/src/hotspot/share/code/icBuffer.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/icBuffer.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -30,6 +30,7 @@
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.hpp"
#include "utilities/align.hpp"
+#include "utilities/macros.hpp"
//
// For CompiledIC's:
@@ -100,20 +101,16 @@
static int ic_stub_code_size();
static StubQueue* _buffer;
- static ICStub* _next_stub;
static CompiledICHolder* _pending_released;
static int _pending_count;
+ DEBUG_ONLY(static volatile int _needs_refill;)
+
static StubQueue* buffer() { return _buffer; }
- static void set_next_stub(ICStub* next_stub) { _next_stub = next_stub; }
- static ICStub* get_next_stub() { return _next_stub; }
-
- static void init_next_stub();
static ICStub* new_ic_stub();
-
// Machine-dependent implementation of ICBuffer
static void assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point);
static address ic_buffer_entry_point (address code_begin);
@@ -129,6 +126,7 @@
// removes the ICStubs after backpatching
static void update_inline_caches();
+ static void refill_ic_stubs();
// for debugging
static bool is_empty();
@@ -138,7 +136,7 @@
static int pending_icholder_count() { return _pending_count; }
// New interface
- static void create_transition_stub(CompiledIC *ic, void* cached_value, address entry);
+ static bool create_transition_stub(CompiledIC *ic, void* cached_value, address entry);
static address ic_destination_for(CompiledIC *ic);
static void* cached_value_for(CompiledIC *ic);
};
--- a/src/hotspot/share/code/nmethod.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/nmethod.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -1575,14 +1575,44 @@
if (state_is_unloading) {
return true;
}
- if (state_unloading_cycle == CodeCache::unloading_cycle()) {
+ uint8_t current_cycle = CodeCache::unloading_cycle();
+ if (state_unloading_cycle == current_cycle) {
return false;
}
// The IsUnloadingBehaviour is responsible for checking if there are any dead
// oops in the CompiledMethod, by calling oops_do on it.
- state_unloading_cycle = CodeCache::unloading_cycle();
- state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
+ state_unloading_cycle = current_cycle;
+
+ if (is_zombie()) {
+ // Zombies without calculated unloading epoch are never unloading due to GC.
+
+ // There are no races where a previously observed is_unloading() nmethod
+ // suddenly becomes not is_unloading() due to here being observed as zombie.
+
+ // With STW unloading, all is_alive() && is_unloading() nmethods are unlinked
+ // and unloaded in the safepoint. That makes races where an nmethod is first
+ // observed as is_alive() && is_unloading() and subsequently observed as
+ // is_zombie() impossible.
+
+ // With concurrent unloading, all references to is_unloading() nmethods are
+ // first unlinked (e.g. IC caches and dependency contexts). Then a global
+ // handshake operation is performed with all JavaThreads before finally
+ // unloading the nmethods. The sweeper never converts is_alive() && is_unloading()
+ // nmethods to zombies; it waits for them to become is_unloaded(). So before
+ // the global handshake, it is impossible for is_unloading() nmethods to
+ // racingly become is_zombie(). And is_unloading() is calculated for all is_alive()
+ // nmethods before taking that global handshake, meaning that it will never
+ // be recalculated after the handshake.
+
+ // After that global handshake, is_unloading() nmethods are only observable
+ // to the iterators, and they will never trigger recomputation of the cached
+ // is_unloading_state, and hence may not suffer from such races.
+
+ state_is_unloading = false;
+ } else {
+ state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this);
+ }
state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle);
@@ -1620,7 +1650,8 @@
}
#endif
- unload_nmethod_caches(unloading_occurred);
+ guarantee(unload_nmethod_caches(unloading_occurred),
+ "Should not need transition stubs");
}
}
--- a/src/hotspot/share/code/relocInfo.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/relocInfo.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -644,12 +644,12 @@
return (Method*)m;
}
-void virtual_call_Relocation::clear_inline_cache() {
+bool virtual_call_Relocation::clear_inline_cache() {
// No stubs for ICs
// Clean IC
ResourceMark rm;
CompiledIC* icache = CompiledIC_at(this);
- icache->set_to_clean();
+ return icache->set_to_clean();
}
@@ -672,15 +672,20 @@
return (Method*)m;
}
-void opt_virtual_call_Relocation::clear_inline_cache() {
+template<typename CompiledICorStaticCall>
+static bool set_to_clean_no_ic_refill(CompiledICorStaticCall* ic) {
+ guarantee(ic->set_to_clean(), "Should not need transition stubs");
+ return true;
+}
+
+bool opt_virtual_call_Relocation::clear_inline_cache() {
// No stubs for ICs
// Clean IC
ResourceMark rm;
CompiledIC* icache = CompiledIC_at(this);
- icache->set_to_clean();
+ return set_to_clean_no_ic_refill(icache);
}
-
address opt_virtual_call_Relocation::static_stub(bool is_aot) {
// search for the static stub who points back to this static call
address static_call_addr = addr();
@@ -715,10 +720,10 @@
_method_index = unpack_1_int();
}
-void static_call_Relocation::clear_inline_cache() {
+bool static_call_Relocation::clear_inline_cache() {
// Safe call site info
CompiledStaticCall* handler = this->code()->compiledStaticCall_at(this);
- handler->set_to_clean();
+ return set_to_clean_no_ic_refill(handler);
}
@@ -757,10 +762,11 @@
return NULL;
}
-void static_stub_Relocation::clear_inline_cache() {
+bool static_stub_Relocation::clear_inline_cache() {
// Call stub is only used when calling the interpreted code.
// It does not really need to be cleared, except that we want to clean out the methodoop.
CompiledDirectStaticCall::set_stub_to_clean(this);
+ return true;
}
--- a/src/hotspot/share/code/relocInfo.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/relocInfo.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -814,7 +814,7 @@
// all relocations are able to reassert their values
virtual void set_value(address x);
- virtual void clear_inline_cache() { }
+ virtual bool clear_inline_cache() { return true; }
// This method assumes that all virtual/static (inline) caches are cleared (since for static_call_type and
// ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is
@@ -1052,7 +1052,7 @@
void pack_data_to(CodeSection* dest);
void unpack_data();
- void clear_inline_cache();
+ bool clear_inline_cache();
};
@@ -1083,7 +1083,7 @@
void pack_data_to(CodeSection* dest);
void unpack_data();
- void clear_inline_cache();
+ bool clear_inline_cache();
// find the matching static_stub
address static_stub(bool is_aot);
@@ -1117,7 +1117,7 @@
void pack_data_to(CodeSection* dest);
void unpack_data();
- void clear_inline_cache();
+ bool clear_inline_cache();
// find the matching static_stub
address static_stub(bool is_aot);
@@ -1146,7 +1146,7 @@
static_stub_Relocation() { }
public:
- void clear_inline_cache();
+ bool clear_inline_cache();
address static_call() { return _static_call; }
bool is_aot() { return _is_aot; }
--- a/src/hotspot/share/code/stubs.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/stubs.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -117,7 +117,7 @@
Stub* StubQueue::request(int requested_code_size) {
assert(requested_code_size > 0, "requested_code_size must be > 0");
- if (_mutex != NULL) _mutex->lock();
+ if (_mutex != NULL) _mutex->lock_without_safepoint_check();
Stub* s = current_stub();
int requested_size = align_up(stub_code_size_to_size(requested_code_size), CodeEntryAlignment);
if (requested_size <= available_space()) {
@@ -207,7 +207,7 @@
void StubQueue::verify() {
// verify only if initialized
if (_stub_buffer == NULL) return;
- MutexLockerEx lock(_mutex);
+ MutexLockerEx lock(_mutex, Mutex::_no_safepoint_check_flag);
// verify index boundaries
guarantee(0 <= _buffer_size, "buffer size must be positive");
guarantee(0 <= _buffer_limit && _buffer_limit <= _buffer_size , "_buffer_limit out of bounds");
@@ -234,9 +234,8 @@
void StubQueue::print() {
- MutexLockerEx lock(_mutex);
+ MutexLockerEx lock(_mutex, Mutex::_no_safepoint_check_flag);
for (Stub* s = first(); s != NULL; s = next(s)) {
stub_print(s);
}
}
-
--- a/src/hotspot/share/code/vtableStubs.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/code/vtableStubs.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -124,7 +124,7 @@
void VtableStubs::initialize() {
VtableStub::_receiver_location = SharedRuntime::name_for_receiver();
{
- MutexLocker ml(VtableStubs_lock);
+ MutexLockerEx ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag);
assert(_number_of_vtable_stubs == 0, "potential performance bug: VtableStubs initialized more than once");
assert(is_power_of_2(N), "N must be a power of 2");
for (int i = 0; i < N; i++) {
@@ -247,7 +247,7 @@
VtableStub* VtableStubs::lookup(bool is_vtable_stub, int vtable_index) {
- MutexLocker ml(VtableStubs_lock);
+ MutexLockerEx ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag);
unsigned hash = VtableStubs::hash(is_vtable_stub, vtable_index);
VtableStub* s = _table[hash];
while( s && !s->matches(is_vtable_stub, vtable_index)) s = s->next();
@@ -256,7 +256,7 @@
void VtableStubs::enter(bool is_vtable_stub, int vtable_index, VtableStub* s) {
- MutexLocker ml(VtableStubs_lock);
+ MutexLockerEx ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag);
assert(s->matches(is_vtable_stub, vtable_index), "bad vtable stub");
unsigned int h = VtableStubs::hash(is_vtable_stub, vtable_index);
// enter s at the beginning of the corresponding list
@@ -266,7 +266,7 @@
}
VtableStub* VtableStubs::entry_point(address pc) {
- MutexLocker ml(VtableStubs_lock);
+ MutexLockerEx ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag);
VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset());
uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index());
VtableStub* s;
--- a/src/hotspot/share/gc/g1/g1Arguments.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1Arguments.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -81,6 +81,13 @@
vm_exit_during_initialization("The flag -XX:+UseG1GC can not be combined with -XX:ParallelGCThreads=0", NULL);
}
+ // When dumping the CDS archive we want to reduce fragmentation by
+ // triggering a full collection. To get as low fragmentation as
+ // possible we only use one worker thread.
+ if (DumpSharedSpaces) {
+ FLAG_SET_ERGO(uint, ParallelGCThreads, 1);
+ }
+
if (FLAG_IS_DEFAULT(G1ConcRefinementThreads)) {
FLAG_SET_ERGO(uint, G1ConcRefinementThreads, ParallelGCThreads);
}
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -273,6 +273,69 @@
};
// Should be only used at CDS dump time
+class VerifyReadyForArchivingRegionClosure : public HeapRegionClosure {
+ bool _seen_free;
+ bool _has_holes;
+ bool _has_unexpected_holes;
+ bool _has_humongous;
+public:
+ bool has_holes() {return _has_holes;}
+ bool has_unexpected_holes() {return _has_unexpected_holes;}
+ bool has_humongous() {return _has_humongous;}
+
+ VerifyReadyForArchivingRegionClosure() : HeapRegionClosure() {
+ _seen_free = false;
+ _has_holes = false;
+ _has_unexpected_holes = false;
+ _has_humongous = false;
+ }
+ virtual bool do_heap_region(HeapRegion* hr) {
+ const char* hole = "";
+
+ if (hr->is_free()) {
+ _seen_free = true;
+ } else {
+ if (_seen_free) {
+ _has_holes = true;
+ if (hr->is_humongous()) {
+ hole = " hole";
+ } else {
+ _has_unexpected_holes = true;
+ hole = " hole **** unexpected ****";
+ }
+ }
+ }
+ if (hr->is_humongous()) {
+ _has_humongous = true;
+ }
+ log_info(gc, region, cds)("HeapRegion " INTPTR_FORMAT " %s%s", p2i(hr->bottom()), hr->get_type_str(), hole);
+ return false;
+ }
+};
+
+// We want all used regions to be moved to the bottom-end of the heap, so we have
+// a contiguous range of free regions at the top end of the heap. This way, we can
+// avoid fragmentation while allocating the archive regions.
+//
+// Before calling this, a full GC should have been executed with a single worker thread,
+// so that no old regions would be moved to the middle of the heap.
+void G1HeapVerifier::verify_ready_for_archiving() {
+ VerifyReadyForArchivingRegionClosure cl;
+ G1CollectedHeap::heap()->heap_region_iterate(&cl);
+ if (cl.has_holes()) {
+ log_warning(gc, verify)("All free regions should be at the top end of the heap, but"
+ " we found holes. This is probably caused by (unmovable) humongous"
+ " allocations, and may lead to fragmentation while"
+ " writing archive heap memory regions.");
+ }
+ if (cl.has_humongous()) {
+ log_warning(gc, verify)("(Unmovable) humongous regions have been found and"
+ " may lead to fragmentation while"
+ " writing archive heap memory regions.");
+ }
+ assert(!cl.has_unexpected_holes(), "all holes should have been caused by humongous regions");
+}
+
class VerifyArchivePointerRegionClosure: public HeapRegionClosure {
private:
G1CollectedHeap* _g1h;
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -115,6 +115,7 @@
void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
void verify_dirty_young_regions() PRODUCT_RETURN;
+ static void verify_ready_for_archiving();
static void verify_archive_regions();
};
--- a/src/hotspot/share/gc/shared/gcCause.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/shared/gcCause.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,9 @@
case _wb_full_gc:
return "WhiteBox Initiated Full GC";
+ case _archive_time_gc:
+ return "Full GC for -Xshare:dump";
+
case _no_gc:
return "No GC";
--- a/src/hotspot/share/gc/shared/gcCause.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/shared/gcCause.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,7 @@
_wb_young_gc,
_wb_conc_mark,
_wb_full_gc,
+ _archive_time_gc,
/* implementation independent, but reserved for GC use */
_no_gc,
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -279,18 +279,6 @@
_fast_refill_waste * HeapWordSize);
}
-void ThreadLocalAllocBuffer::verify() {
- HeapWord* p = start();
- HeapWord* t = top();
- HeapWord* prev_p = NULL;
- while (p < t) {
- oopDesc::verify(oop(p));
- prev_p = p;
- p += oop(p)->size();
- }
- guarantee(p == top(), "end of last object must match end of space");
-}
-
void ThreadLocalAllocBuffer::set_sample_end() {
size_t heap_words_remaining = pointer_delta(_end, _top);
size_t bytes_until_sample = thread()->heap_sampler().bytes_until_sample();
--- a/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/shared/threadLocalAllocBuffer.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -188,8 +188,6 @@
static ByteSize end_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _end); }
static ByteSize top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _top); }
static ByteSize pf_top_offset() { return byte_offset_of(ThreadLocalAllocBuffer, _pf_top); }
-
- void verify();
};
class ThreadLocalAllocStats : public StackObj {
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -995,13 +995,12 @@
}
bool ZBarrierSetC2::expand_barriers(Compile* C, PhaseIterGVN& igvn) const {
- PhaseMacroExpand macro(igvn);
ZBarrierSetC2State* s = state();
if (s->load_barrier_count() > 0) {
+ PhaseMacroExpand macro(igvn);
#ifdef ASSERT
verify_gc_barriers(false);
#endif
- igvn.set_delay_transform(true);
int skipped = 0;
while (s->load_barrier_count() > skipped) {
int load_barrier_count = s->load_barrier_count();
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -728,7 +728,7 @@
// class is initialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
- InstanceKlass* klass = InstanceKlass::cast(info.field_holder());
+ InstanceKlass* klass = info.field_holder();
bool uninitialized_static = is_static && !klass->is_initialized();
bool has_initialized_final_update = info.field_holder()->major_version() >= 53 &&
info.has_initialized_final_update();
--- a/src/hotspot/share/interpreter/linkResolver.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/interpreter/linkResolver.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -1151,7 +1151,7 @@
InstanceKlass* ck = InstanceKlass::cast(current_klass);
InstanceKlass *klass_to_check = !ck->is_unsafe_anonymous() ?
ck :
- InstanceKlass::cast(ck->unsafe_anonymous_host());
+ ck->unsafe_anonymous_host();
// Disable verification for the dynamically-generated reflection bytecodes.
bool is_reflect = klass_to_check->is_subclass_of(
SystemDictionary::reflect_MagicAccessorImpl_klass());
--- a/src/hotspot/share/jfr/leakprofiler/emitEventOperation.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/jfr/leakprofiler/emitEventOperation.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -158,12 +158,14 @@
const jlong last_sweep = _emit_all ? max_jlong : _object_sampler->last_sweep().value();
int count = 0;
- for (int i = 0; i < _object_sampler->item_count(); ++i) {
- const ObjectSample* sample = _object_sampler->item_at(i);
- if (sample->is_alive_and_older_than(last_sweep)) {
- write_event(sample, edge_store);
+ const ObjectSample* current = _object_sampler->first();
+ while (current != NULL) {
+ ObjectSample* prev = current->prev();
+ if (current->is_alive_and_older_than(last_sweep)) {
+ write_event(current, edge_store);
++count;
}
+ current = prev;
}
// restore thread local stack trace and thread id
--- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -122,6 +122,10 @@
return _list->last();
}
+const ObjectSample* ObjectSampler::first() const {
+ return _list->first();
+}
+
const ObjectSample* ObjectSampler::last_resolved() const {
return _list->last_resolved();
}
--- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -69,6 +69,7 @@
const ObjectSample* item_at(int index) const;
ObjectSample* item_at(int index);
int item_count() const;
+ const ObjectSample* first() const;
const ObjectSample* last() const;
const ObjectSample* last_resolved() const;
void set_last_resolved(const ObjectSample* sample);
--- a/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -45,6 +45,10 @@
return _in_use_list.head();
}
+ObjectSample* SampleList::first() const {
+ return _in_use_list.tail();
+}
+
const ObjectSample* SampleList::last_resolved() const {
return _last_resolved;
}
--- a/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/jfr/leakprofiler/sampling/sampleList.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -53,6 +53,7 @@
void set_last_resolved(const ObjectSample* sample);
ObjectSample* get();
ObjectSample* last() const;
+ ObjectSample* first() const;
void release(ObjectSample* sample);
const ObjectSample* last_resolved() const;
ObjectSample* reuse(ObjectSample* sample);
--- a/src/hotspot/share/memory/filemap.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/memory/filemap.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -683,7 +683,7 @@
int arr_len = heap_mem == NULL ? 0 : heap_mem->length();
if(arr_len > max_num_regions) {
fail_stop("Unable to write archive heap memory regions: "
- "number of memory regions exceeds maximum due to fragmentation."
+ "number of memory regions exceeds maximum due to fragmentation. "
"Please increase java heap size "
"(current MaxHeapSize is " SIZE_FORMAT ", InitialHeapSize is " SIZE_FORMAT ").",
MaxHeapSize, InitialHeapSize);
--- a/src/hotspot/share/memory/heapShared.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/memory/heapShared.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -193,6 +193,8 @@
return;
}
+ G1HeapVerifier::verify_ready_for_archiving();
+
{
NoSafepointVerifier nsv;
@@ -581,7 +583,7 @@
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
if (!fs.access_flags().is_static()) {
BasicType ft = fs.field_descriptor().field_type();
- if (!fs.access_flags().is_final() && (ft == T_ARRAY || T_OBJECT)) {
+ if (!fs.access_flags().is_final() && (ft == T_ARRAY || ft == T_OBJECT)) {
ResourceMark rm(THREAD);
log_warning(cds, heap)(
"Please check reference field in %s instance in closed archive heap region: %s %s",
--- a/src/hotspot/share/memory/metaspace.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/memory/metaspace.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -865,6 +865,7 @@
// Utils to check if a pointer or range is part of a committed metaspace region.
metaspace::VirtualSpaceNode* MetaspaceUtils::find_enclosing_virtual_space(const void* p) {
+ MutexLockerEx cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
VirtualSpaceNode* vsn = Metaspace::space_list()->find_enclosing_space(p);
if (Metaspace::using_class_space() && vsn == NULL) {
vsn = Metaspace::class_space_list()->find_enclosing_space(p);
--- a/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/memory/metaspace/virtualSpaceList.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -89,7 +89,6 @@
// nodes with a 0 container_count. Remove Metachunks in
// the node from their respective freelists.
void VirtualSpaceList::purge(ChunkManager* chunk_manager) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work");
assert_lock_strong(MetaspaceExpand_lock);
// Don't use a VirtualSpaceListIterator because this
// list is being changed and a straightforward use of an iterator is not safe.
--- a/src/hotspot/share/memory/metaspaceShared.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/memory/metaspaceShared.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,6 +29,7 @@
#include "classfile/classLoaderExt.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/loaderConstraints.hpp"
+#include "classfile/javaClasses.inline.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/stringTable.hpp"
@@ -350,7 +351,11 @@
}
}
+static GrowableArray<Handle>* _extra_interned_strings = NULL;
+
void MetaspaceShared::read_extra_data(const char* filename, TRAPS) {
+ _extra_interned_strings = new (ResourceObj::C_HEAP, mtInternal)GrowableArray<Handle>(10000, true);
+
HashtableTextDump reader(filename);
reader.check_version("VERSION: 1.0");
@@ -358,15 +363,45 @@
int utf8_length;
int prefix_type = reader.scan_prefix(&utf8_length);
ResourceMark rm(THREAD);
- char* utf8_buffer = NEW_RESOURCE_ARRAY(char, utf8_length);
+ if (utf8_length == 0x7fffffff) {
+ // buf_len will overflown 32-bit value.
+ vm_exit_during_initialization(err_msg("string length too large: %d", utf8_length));
+ }
+ int buf_len = utf8_length+1;
+ char* utf8_buffer = NEW_RESOURCE_ARRAY(char, buf_len);
reader.get_utf8(utf8_buffer, utf8_length);
+ utf8_buffer[utf8_length] = '\0';
if (prefix_type == HashtableTextDump::SymbolPrefix) {
- SymbolTable::new_symbol(utf8_buffer, utf8_length, THREAD);
+ SymbolTable::new_permanent_symbol(utf8_buffer, THREAD);
} else{
assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
- utf8_buffer[utf8_length] = '\0';
oop s = StringTable::intern(utf8_buffer, THREAD);
+
+ if (HAS_PENDING_EXCEPTION) {
+ log_warning(cds, heap)("[line %d] extra interned string allocation failed; size too large: %d",
+ reader.last_line_no(), utf8_length);
+ CLEAR_PENDING_EXCEPTION;
+ } else {
+#if INCLUDE_G1GC
+ if (UseG1GC) {
+ typeArrayOop body = java_lang_String::value(s);
+ const HeapRegion* hr = G1CollectedHeap::heap()->heap_region_containing(body);
+ if (hr->is_humongous()) {
+ // Don't keep it alive, so it will be GC'ed before we dump the strings, in order
+ // to maximize free heap space and minimize fragmentation.
+ log_warning(cds, heap)("[line %d] extra interned string ignored; size too large: %d",
+ reader.last_line_no(), utf8_length);
+ continue;
+ }
+ }
+#endif
+ // Interned strings are GC'ed if there are no references to it, so let's
+ // add a reference to keep this string alive.
+ assert(s != NULL, "must succeed");
+ Handle h(THREAD, s);
+ _extra_interned_strings->append(h);
+ }
}
}
}
@@ -451,8 +486,6 @@
return _cds_i2i_entry_code_buffers;
}
-// CDS code for dumping shared archive.
-
// Global object for holding classes that have been loaded. Since this
// is run at a safepoint just before exit, this is the entire set of classes.
static GrowableArray<Klass*>* _global_klass_objects;
@@ -1686,6 +1719,13 @@
link_and_cleanup_shared_classes(CATCH);
tty->print_cr("Rewriting and linking classes: done");
+ if (HeapShared::is_heap_object_archiving_allowed()) {
+ // Avoid fragmentation while archiving heap objects.
+ Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
+ Universe::heap()->collect(GCCause::_archive_time_gc);
+ Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
+ }
+
VM_PopulateDumpSharedSpace op;
VMThread::execute(&op);
}
--- a/src/hotspot/share/oops/weakHandle.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/oops/weakHandle.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -39,7 +39,7 @@
// This is the vm version of jweak but has different GC lifetimes and policies,
// depending on the type.
-enum WeakHandleType { vm_class_loader_data, vm_string, vm_string_table_data };
+enum WeakHandleType { vm_class_loader_data, vm_string_table_data };
template <WeakHandleType T>
class WeakHandle {
--- a/src/hotspot/share/prims/methodHandles.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/prims/methodHandles.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -1086,8 +1086,6 @@
}
void MethodHandles::clean_dependency_context(oop call_site) {
- assert_locked_or_safepoint(CodeCache_lock);
-
oop context = java_lang_invoke_CallSite::context_no_keepalive(call_site);
DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context);
deps.clean_unloading_dependents();
--- a/src/hotspot/share/runtime/globals.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/globals.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -723,6 +723,9 @@
"Print the code cache memory usage each time a method is " \
"compiled") \
\
+ diagnostic(bool, PrintCodeHeapAnalytics, false, \
+ "Print code heap usage statistics on exit and on full condition") \
+ \
diagnostic(bool, PrintStubCode, false, \
"Print generated stub code") \
\
--- a/src/hotspot/share/runtime/java.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/java.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -318,8 +318,7 @@
// CodeHeap State Analytics.
// Does also call NMethodSweeper::print(tty)
- LogTarget(Trace, codecache) lt;
- if (lt.is_enabled()) {
+ if (PrintCodeHeapAnalytics) {
CompileBroker::print_heapinfo(NULL, "all", "4096"); // details
} else if (PrintMethodFlushingStatistics) {
NMethodSweeper::print(tty);
@@ -387,8 +386,7 @@
// CodeHeap State Analytics.
// Does also call NMethodSweeper::print(tty)
- LogTarget(Trace, codecache) lt;
- if (lt.is_enabled()) {
+ if (PrintCodeHeapAnalytics) {
CompileBroker::print_heapinfo(NULL, "all", "4096"); // details
} else if (PrintMethodFlushingStatistics) {
NMethodSweeper::print(tty);
--- a/src/hotspot/share/runtime/jniHandles.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/jniHandles.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -318,7 +318,7 @@
class VerifyJNIHandles: public OopClosure {
public:
virtual void do_oop(oop* root) {
- oopDesc::verify(*root);
+ guarantee(oopDesc::is_oop(RawAccess<>::oop_load(root)), "Invalid oop");
}
virtual void do_oop(narrowOop* root) { ShouldNotReachHere(); }
};
@@ -327,11 +327,7 @@
VerifyJNIHandles verify_handle;
oops_do(&verify_handle);
-
- // JNI weaks are handled concurrently in ZGC, so they can't be verified here
- if (!UseZGC) {
- weak_oops_do(&verify_handle);
- }
+ weak_oops_do(&verify_handle);
}
// This method is implemented here to avoid circular includes between
--- a/src/hotspot/share/runtime/mutexLocker.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/mutexLocker.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -251,7 +251,7 @@
def(SystemDictionary_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread
def(SharedDictionary_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread
def(Module_lock , PaddedMutex , leaf+2, true, Monitor::_safepoint_check_always);
- def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always);
+ def(InlineCacheBuffer_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_never);
def(VMStatistic_lock , PaddedMutex , leaf, false, Monitor::_safepoint_check_always);
def(ExpandHeap_lock , PaddedMutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread
def(JNIHandleBlockFreeList_lock , PaddedMutex , leaf-1, true, Monitor::_safepoint_check_never); // handles are used by VM thread
@@ -281,7 +281,7 @@
def(VMOperationRequest_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes);
def(RetData_lock , PaddedMutex , nonleaf, false, Monitor::_safepoint_check_always);
def(Terminator_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_sometimes);
- def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_always);
+ def(VtableStubs_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
def(Notify_lock , PaddedMonitor, nonleaf, true, Monitor::_safepoint_check_always);
def(JNIGlobalAlloc_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
def(JNIGlobalActive_lock , PaddedMutex , nonleaf-1, true, Monitor::_safepoint_check_never);
@@ -294,7 +294,7 @@
def(JfieldIdCreation_lock , PaddedMutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation
def(ResolvedMethodTable_lock , PaddedMutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect ResolvedMethodTable
- def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks VtableStubs_lock, InlineCacheBuffer_lock
+ def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_never); // locks VtableStubs_lock, InlineCacheBuffer_lock
def(CompileTaskAlloc_lock , PaddedMutex , nonleaf+2, true, Monitor::_safepoint_check_always);
def(CompileStatistics_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_always);
def(DirectivesStack_lock , PaddedMutex , special, true, Monitor::_safepoint_check_never);
--- a/src/hotspot/share/runtime/safepoint.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/safepoint.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -732,6 +732,7 @@
// Finish monitor deflation.
ObjectSynchronizer::finish_deflate_idle_monitors(&deflate_counters);
+ assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
}
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -25,12 +25,13 @@
#include "precompiled.hpp"
#include "jvm.h"
#include "aot/aotLoader.hpp"
-#include "code/compiledMethod.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/compiledIC.hpp"
+#include "code/icBuffer.hpp"
+#include "code/compiledMethod.inline.hpp"
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/abstractCompiler.hpp"
@@ -1058,7 +1059,7 @@
address pc = vfst.frame_pc();
{ // Get call instruction under lock because another thread may be busy patching it.
- MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
+ CompiledICLocker ic_locker(caller);
return caller->attached_method_before_pc(pc);
}
return NULL;
@@ -1245,11 +1246,87 @@
return callee_method;
}
+// This fails if resolution required refilling of IC stubs
+bool SharedRuntime::resolve_sub_helper_internal(methodHandle callee_method, const frame& caller_frame,
+ CompiledMethod* caller_nm, bool is_virtual, bool is_optimized,
+ Handle receiver, CallInfo& call_info, Bytecodes::Code invoke_code, TRAPS) {
+ StaticCallInfo static_call_info;
+ CompiledICInfo virtual_call_info;
+
+ // Make sure the callee nmethod does not get deoptimized and removed before
+ // we are done patching the code.
+ CompiledMethod* callee = callee_method->code();
+
+ if (callee != NULL) {
+ assert(callee->is_compiled(), "must be nmethod for patching");
+ }
+
+ if (callee != NULL && !callee->is_in_use()) {
+ // Patch call site to C2I adapter if callee nmethod is deoptimized or unloaded.
+ callee = NULL;
+ }
+ nmethodLocker nl_callee(callee);
+#ifdef ASSERT
+ address dest_entry_point = callee == NULL ? 0 : callee->entry_point(); // used below
+#endif
+
+ bool is_nmethod = caller_nm->is_nmethod();
+
+ if (is_virtual) {
+ assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check");
+ bool static_bound = call_info.resolved_method()->can_be_statically_bound();
+ Klass* klass = invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass();
+ CompiledIC::compute_monomorphic_entry(callee_method, klass,
+ is_optimized, static_bound, is_nmethod, virtual_call_info,
+ CHECK_false);
+ } else {
+ // static call
+ CompiledStaticCall::compute_entry(callee_method, is_nmethod, static_call_info);
+ }
+
+ // grab lock, check for deoptimization and potentially patch caller
+ {
+ CompiledICLocker ml(caller_nm);
+
+ // Lock blocks for safepoint during which both nmethods can change state.
+
+ // Now that we are ready to patch if the Method* was redefined then
+ // don't update call site and let the caller retry.
+ // Don't update call site if callee nmethod was unloaded or deoptimized.
+ // Don't update call site if callee nmethod was replaced by an other nmethod
+ // which may happen when multiply alive nmethod (tiered compilation)
+ // will be supported.
+ if (!callee_method->is_old() &&
+ (callee == NULL || (callee->is_in_use() && callee_method->code() == callee))) {
+#ifdef ASSERT
+ // We must not try to patch to jump to an already unloaded method.
+ if (dest_entry_point != 0) {
+ CodeBlob* cb = CodeCache::find_blob(dest_entry_point);
+ assert((cb != NULL) && cb->is_compiled() && (((CompiledMethod*)cb) == callee),
+ "should not call unloaded nmethod");
+ }
+#endif
+ if (is_virtual) {
+ CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc());
+ if (inline_cache->is_clean()) {
+ if (!inline_cache->set_to_monomorphic(virtual_call_info)) {
+ return false;
+ }
+ }
+ } else {
+ CompiledStaticCall* ssc = caller_nm->compiledStaticCall_before(caller_frame.pc());
+ if (ssc->is_clean()) ssc->set(static_call_info);
+ }
+ }
+ } // unlock CompiledICLocker
+ return true;
+}
+
// Resolves a call. The compilers generate code for calls that go here
// and are patched with the real destination of the call.
methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
- bool is_virtual,
- bool is_optimized, TRAPS) {
+ bool is_virtual,
+ bool is_optimized, TRAPS) {
ResourceMark rm(thread);
RegisterMap cbl_map(thread, false);
@@ -1315,76 +1392,19 @@
// (cached_oop, destination address) pair. For a static call/optimized
// virtual this is just a destination address.
- StaticCallInfo static_call_info;
- CompiledICInfo virtual_call_info;
-
- // Make sure the callee nmethod does not get deoptimized and removed before
- // we are done patching the code.
- CompiledMethod* callee = callee_method->code();
-
- if (callee != NULL) {
- assert(callee->is_compiled(), "must be nmethod for patching");
- }
-
- if (callee != NULL && !callee->is_in_use()) {
- // Patch call site to C2I adapter if callee nmethod is deoptimized or unloaded.
- callee = NULL;
- }
- nmethodLocker nl_callee(callee);
-#ifdef ASSERT
- address dest_entry_point = callee == NULL ? 0 : callee->entry_point(); // used below
-#endif
-
- bool is_nmethod = caller_nm->is_nmethod();
-
- if (is_virtual) {
- assert(receiver.not_null() || invoke_code == Bytecodes::_invokehandle, "sanity check");
- bool static_bound = call_info.resolved_method()->can_be_statically_bound();
- Klass* klass = invoke_code == Bytecodes::_invokehandle ? NULL : receiver->klass();
- CompiledIC::compute_monomorphic_entry(callee_method, klass,
- is_optimized, static_bound, is_nmethod, virtual_call_info,
- CHECK_(methodHandle()));
- } else {
- // static call
- CompiledStaticCall::compute_entry(callee_method, is_nmethod, static_call_info);
+ // Patching IC caches may fail if we run out if transition stubs.
+ // We refill the ic stubs then and try again.
+ for (;;) {
+ bool successful = resolve_sub_helper_internal(callee_method, caller_frame, caller_nm,
+ is_virtual, is_optimized, receiver,
+ call_info, invoke_code, CHECK_(methodHandle()));
+ if (successful) {
+ return callee_method;
+ } else {
+ InlineCacheBuffer::refill_ic_stubs();
+ }
}
- // grab lock, check for deoptimization and potentially patch caller
- {
- CompiledICLocker ml(caller_nm);
-
- // Lock blocks for safepoint during which both nmethods can change state.
-
- // Now that we are ready to patch if the Method* was redefined then
- // don't update call site and let the caller retry.
- // Don't update call site if callee nmethod was unloaded or deoptimized.
- // Don't update call site if callee nmethod was replaced by an other nmethod
- // which may happen when multiply alive nmethod (tiered compilation)
- // will be supported.
- if (!callee_method->is_old() &&
- (callee == NULL || (callee->is_in_use() && callee_method->code() == callee))) {
-#ifdef ASSERT
- // We must not try to patch to jump to an already unloaded method.
- if (dest_entry_point != 0) {
- CodeBlob* cb = CodeCache::find_blob(dest_entry_point);
- assert((cb != NULL) && cb->is_compiled() && (((CompiledMethod*)cb) == callee),
- "should not call unloaded nmethod");
- }
-#endif
- if (is_virtual) {
- CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc());
- if (inline_cache->is_clean()) {
- inline_cache->set_to_monomorphic(virtual_call_info);
- }
- } else {
- CompiledStaticCall* ssc = caller_nm->compiledStaticCall_before(caller_frame.pc());
- if (ssc->is_clean()) ssc->set(static_call_info);
- }
- }
-
- } // unlock CompiledICLocker
-
- return callee_method;
}
@@ -1518,7 +1538,85 @@
return callee_method->verified_code_entry();
JRT_END
-
+// The handle_ic_miss_helper_internal function returns false if it failed due
+// to either running out of vtable stubs or ic stubs due to IC transitions
+// to transitional states. The needs_ic_stub_refill value will be set if
+// the failure was due to running out of IC stubs, in which case handle_ic_miss_helper
+// refills the IC stubs and tries again.
+bool SharedRuntime::handle_ic_miss_helper_internal(Handle receiver, CompiledMethod* caller_nm,
+ const frame& caller_frame, methodHandle callee_method,
+ Bytecodes::Code bc, CallInfo& call_info,
+ bool& needs_ic_stub_refill, TRAPS) {
+ CompiledICLocker ml(caller_nm);
+ CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc());
+ bool should_be_mono = false;
+ if (inline_cache->is_optimized()) {
+ if (TraceCallFixup) {
+ ResourceMark rm(THREAD);
+ tty->print("OPTIMIZED IC miss (%s) call to", Bytecodes::name(bc));
+ callee_method->print_short_name(tty);
+ tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
+ }
+ should_be_mono = true;
+ } else if (inline_cache->is_icholder_call()) {
+ CompiledICHolder* ic_oop = inline_cache->cached_icholder();
+ if (ic_oop != NULL) {
+ if (!ic_oop->is_loader_alive()) {
+ // Deferred IC cleaning due to concurrent class unloading
+ if (!inline_cache->set_to_clean()) {
+ needs_ic_stub_refill = true;
+ return false;
+ }
+ } else if (receiver()->klass() == ic_oop->holder_klass()) {
+ // This isn't a real miss. We must have seen that compiled code
+ // is now available and we want the call site converted to a
+ // monomorphic compiled call site.
+ // We can't assert for callee_method->code() != NULL because it
+ // could have been deoptimized in the meantime
+ if (TraceCallFixup) {
+ ResourceMark rm(THREAD);
+ tty->print("FALSE IC miss (%s) converting to compiled call to", Bytecodes::name(bc));
+ callee_method->print_short_name(tty);
+ tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
+ }
+ should_be_mono = true;
+ }
+ }
+ }
+
+ if (should_be_mono) {
+ // We have a path that was monomorphic but was going interpreted
+ // and now we have (or had) a compiled entry. We correct the IC
+ // by using a new icBuffer.
+ CompiledICInfo info;
+ Klass* receiver_klass = receiver()->klass();
+ inline_cache->compute_monomorphic_entry(callee_method,
+ receiver_klass,
+ inline_cache->is_optimized(),
+ false, caller_nm->is_nmethod(),
+ info, CHECK_false);
+ if (!inline_cache->set_to_monomorphic(info)) {
+ needs_ic_stub_refill = true;
+ return false;
+ }
+ } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) {
+ // Potential change to megamorphic
+
+ bool successful = inline_cache->set_to_megamorphic(&call_info, bc, needs_ic_stub_refill, CHECK_false);
+ if (!successful) {
+ if (!needs_ic_stub_refill) {
+ return false;
+ }
+ if (!inline_cache->set_to_clean()) {
+ needs_ic_stub_refill = true;
+ return false;
+ }
+ }
+ } else {
+ // Either clean or megamorphic
+ }
+ return true;
+}
methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) {
ResourceMark rm(thread);
@@ -1555,8 +1653,6 @@
methodHandle callee_method = call_info.selected_method();
- bool should_be_mono = false;
-
#ifndef PRODUCT
Atomic::inc(&_ic_miss_ctr);
@@ -1585,75 +1681,41 @@
JvmtiDynamicCodeEventCollector event_collector;
// Update inline cache to megamorphic. Skip update if we are called from interpreted.
- {
- RegisterMap reg_map(thread, false);
- frame caller_frame = thread->last_frame().sender(®_map);
- CodeBlob* cb = caller_frame.cb();
- CompiledMethod* caller_nm = cb->as_compiled_method_or_null();
- CompiledICLocker ml(caller_nm);
-
- if (cb->is_compiled()) {
- CompiledIC* inline_cache = CompiledIC_before(((CompiledMethod*)cb), caller_frame.pc());
- bool should_be_mono = false;
- if (inline_cache->is_optimized()) {
- if (TraceCallFixup) {
- ResourceMark rm(thread);
- tty->print("OPTIMIZED IC miss (%s) call to", Bytecodes::name(bc));
- callee_method->print_short_name(tty);
- tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
- }
- should_be_mono = true;
- } else if (inline_cache->is_icholder_call()) {
- CompiledICHolder* ic_oop = inline_cache->cached_icholder();
- if (ic_oop != NULL) {
- if (!ic_oop->is_loader_alive()) {
- // Deferred IC cleaning due to concurrent class unloading
- inline_cache->set_to_clean();
- } else if (receiver()->klass() == ic_oop->holder_klass()) {
- // This isn't a real miss. We must have seen that compiled code
- // is now available and we want the call site converted to a
- // monomorphic compiled call site.
- // We can't assert for callee_method->code() != NULL because it
- // could have been deoptimized in the meantime
- if (TraceCallFixup) {
- ResourceMark rm(thread);
- tty->print("FALSE IC miss (%s) converting to compiled call to", Bytecodes::name(bc));
- callee_method->print_short_name(tty);
- tty->print_cr(" code: " INTPTR_FORMAT, p2i(callee_method->code()));
- }
- should_be_mono = true;
- }
- }
- }
-
- if (should_be_mono) {
-
- // We have a path that was monomorphic but was going interpreted
- // and now we have (or had) a compiled entry. We correct the IC
- // by using a new icBuffer.
- CompiledICInfo info;
- Klass* receiver_klass = receiver()->klass();
- inline_cache->compute_monomorphic_entry(callee_method,
- receiver_klass,
- inline_cache->is_optimized(),
- false, caller_nm->is_nmethod(),
- info, CHECK_(methodHandle()));
- inline_cache->set_to_monomorphic(info);
- } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) {
- // Potential change to megamorphic
- bool successful = inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle()));
- if (!successful) {
- inline_cache->set_to_clean();
- }
- } else {
- // Either clean or megamorphic
- }
+ // Transitioning IC caches may require transition stubs. If we run out
+ // of transition stubs, we have to drop locks and perform a safepoint
+ // that refills them.
+ RegisterMap reg_map(thread, false);
+ frame caller_frame = thread->last_frame().sender(®_map);
+ CodeBlob* cb = caller_frame.cb();
+ CompiledMethod* caller_nm = cb->as_compiled_method();
+
+ for (;;) {
+ bool needs_ic_stub_refill = false;
+ bool successful = handle_ic_miss_helper_internal(receiver, caller_nm, caller_frame, callee_method,
+ bc, call_info, needs_ic_stub_refill, CHECK_(methodHandle()));
+ if (successful || !needs_ic_stub_refill) {
+ return callee_method;
} else {
- fatal("Unimplemented");
+ InlineCacheBuffer::refill_ic_stubs();
}
- } // Release CompiledICLocker
-
- return callee_method;
+ }
+}
+
+static bool clear_ic_at_addr(CompiledMethod* caller_nm, address call_addr, bool is_static_call) {
+ CompiledICLocker ml(caller_nm);
+ if (is_static_call) {
+ CompiledStaticCall* ssc = caller_nm->compiledStaticCall_at(call_addr);
+ if (!ssc->is_clean()) {
+ return ssc->set_to_clean();
+ }
+ } else {
+ // compiled, dispatched call (which used to call an interpreted method)
+ CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr);
+ if (!inline_cache->is_clean()) {
+ return inline_cache->set_to_clean();
+ }
+ }
+ return true;
}
//
@@ -1703,7 +1765,7 @@
{
// Get call instruction under lock because another thread may be
// busy patching it.
- MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
+ CompiledICLocker ml(caller_nm);
// Location of call instruction
call_addr = caller_nm->call_instruction_address(pc);
}
@@ -1735,14 +1797,12 @@
// to a wrong method). It should not be performance critical, since the
// resolve is only done once.
- CompiledICLocker ml(caller_nm);
- if (is_static_call) {
- CompiledStaticCall* ssc = caller_nm->compiledStaticCall_at(call_addr);
- ssc->set_to_clean();
- } else {
- // compiled, dispatched call (which used to call an interpreted method)
- CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr);
- inline_cache->set_to_clean();
+ for (;;) {
+ if (!clear_ic_at_addr(caller_nm, call_addr, is_static_call)) {
+ InlineCacheBuffer::refill_ic_stubs();
+ } else {
+ break;
+ }
}
}
}
@@ -1880,9 +1940,8 @@
if (moop->code() == NULL) return;
if (nm->is_in_use()) {
-
// Expect to find a native call there (unless it was no-inline cache vtable dispatch)
- MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
+ CompiledICLocker ic_locker(nm);
if (NativeCall::is_call_before(return_pc)) {
ResourceMark mark;
NativeCallWrapper* call = nm->call_wrapper_before(return_pc);
--- a/src/hotspot/share/runtime/sharedRuntime.hpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/sharedRuntime.hpp Wed Dec 05 17:05:42 2018 -0500
@@ -48,6 +48,9 @@
friend class VMStructs;
private:
+ static bool resolve_sub_helper_internal(methodHandle callee_method, const frame& caller_frame,
+ CompiledMethod* caller_nm, bool is_virtual, bool is_optimized,
+ Handle receiver, CallInfo& call_info, Bytecodes::Code invoke_code, TRAPS);
static methodHandle resolve_sub_helper(JavaThread *thread,
bool is_virtual,
bool is_optimized, TRAPS);
@@ -324,6 +327,10 @@
// deopt blob
static void generate_deopt_blob(void);
+ static bool handle_ic_miss_helper_internal(Handle receiver, CompiledMethod* caller_nm, const frame& caller_frame,
+ methodHandle callee_method, Bytecodes::Code bc, CallInfo& call_info,
+ bool& needs_ic_stub_refill, TRAPS);
+
public:
static DeoptimizationBlob* deopt_blob(void) { return _deopt_blob; }
--- a/src/hotspot/share/runtime/sweeper.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/sweeper.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -699,7 +699,6 @@
// But still remember to clean-up inline caches for alive nmethods
if (cm->is_alive() && !cm->is_unloading()) {
// Clean inline caches that point to zombie/non-entrant/unloaded nmethods
- CompiledICLocker ml(cm);
cm->cleanup_inline_caches(false);
SWEEP(cm);
}
@@ -745,19 +744,16 @@
}
} else {
// Still alive, clean up its inline caches
- CompiledICLocker ml(cm);
cm->cleanup_inline_caches(false);
SWEEP(cm);
}
} else if (cm->is_unloaded()) {
// Code is unloaded, so there are no activations on the stack.
// Convert the nmethod to zombie or flush it directly in the OSR case.
- {
- // Clean ICs of unloaded nmethods as well because they may reference other
- // unloaded nmethods that may be flushed earlier in the sweeper cycle.
- CompiledICLocker ml(cm);
- cm->cleanup_inline_caches(false);
- }
+
+ // Clean ICs of unloaded nmethods as well because they may reference other
+ // unloaded nmethods that may be flushed earlier in the sweeper cycle.
+ cm->cleanup_inline_caches(false);
if (cm->is_osr_method()) {
SWEEP(cm);
// No inline caches will ever point to osr methods, so we can just remove it
@@ -776,7 +772,6 @@
possibly_flush((nmethod*)cm);
}
// Clean inline caches that point to zombie/non-entrant/unloaded nmethods
- CompiledICLocker ml(cm);
cm->cleanup_inline_caches(false);
SWEEP(cm);
}
--- a/src/hotspot/share/runtime/thread.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/hotspot/share/runtime/thread.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -3902,6 +3902,9 @@
// may be attached late and JVMTI must track phases of VM execution
JvmtiExport::enter_live_phase();
+ // Make perfmemory accessible
+ PerfMemory::set_accessible(true);
+
// Notify JVMTI agents that VM initialization is complete - nop if no agents.
JvmtiExport::post_vm_initialized();
--- a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
package com.sun.crypto.provider;
import java.io.*;
-import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.AlgorithmParametersSpi;
import java.security.spec.AlgorithmParameterSpec;
@@ -264,7 +263,20 @@
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
- kdfAlgo = parseKDF(pBES2_params.data.getDerValue());
+ DerValue kdf = pBES2_params.data.getDerValue();
+
+ // Before JDK-8202837, PBES2-params was mistakenly encoded like
+ // an AlgorithmId which is a sequence of its own OID and the real
+ // PBES2-params. If the first DerValue is an OID instead of a
+ // PBES2-KDFs (which should be a SEQUENCE), we are likely to be
+ // dealing with this buggy encoding. Skip the OID and treat the
+ // next DerValue as the real PBES2-params.
+ if (kdf.getTag() == DerValue.tag_ObjectId) {
+ pBES2_params = pBES2_params.data.getDerValue();
+ kdf = pBES2_params.data.getDerValue();
+ }
+
+ kdfAlgo = parseKDF(kdf);
if (pBES2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
--- a/src/java.base/share/classes/java/lang/VersionProps.java.template Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/java/lang/VersionProps.java.template Wed Dec 05 17:05:42 2018 -0500
@@ -51,6 +51,9 @@
private static final String VERSION_NUMBER =
"@@VERSION_NUMBER@@";
+ private static final String VERSION_SPECIFICATION =
+ "@@VERSION_SPECIFICATION@@";
+
private static final String VERSION_BUILD =
"@@VERSION_BUILD@@";
@@ -97,7 +100,7 @@
props.setProperty("java.class.version", CLASSFILE_MAJOR_MINOR);
- props.setProperty("java.specification.version", VERSION_NUMBER);
+ props.setProperty("java.specification.version", VERSION_SPECIFICATION);
props.setProperty("java.specification.name", "Java Platform API Specification");
props.setProperty("java.specification.vendor", "Oracle Corporation");
--- a/src/java.base/share/classes/java/util/doc-files/coll-reference.html Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/java/util/doc-files/coll-reference.html Wed Dec 05 17:05:42 2018 -0500
@@ -431,7 +431,7 @@
fill(List, Object)</a></strong> - Overwrites every element in a
list with the specified value.</li>
<li><strong><a href=
-"../Collections.html#copy-java.util.List(java.util.List)">
+"../Collections.html#copy(java.util.List,java.util.List)">
copy(List dest, List src)</a></strong> - Copies the source list
into the destination list.</li>
<li><strong><a href=
--- a/src/java.base/share/classes/java/util/zip/Deflater.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/java/util/zip/Deflater.java Wed Dec 05 17:05:42 2018 -0500
@@ -224,7 +224,6 @@
* One of the {@code setInput()} methods should be called whenever
* {@code needsInput()} returns true indicating that more input data
* is required.
- * <p>
* @param input the input data bytes
* @param off the start offset of the data
* @param len the length of the data
@@ -248,7 +247,6 @@
* One of the {@code setInput()} methods should be called whenever
* {@code needsInput()} returns true indicating that more input data
* is required.
- * <p>
* @param input the input data bytes
* @see Deflater#needsInput
*/
--- a/src/java.base/share/classes/jdk/internal/org/xml/sax/DTDHandler.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/org/xml/sax/DTDHandler.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,6 @@
*/
public interface DTDHandler {
-
/**
* Receive notification of a notation declaration event.
*
@@ -136,6 +135,39 @@
String notationName)
throws SAXException;
+ // from SAX2 extension DeclHandler
+ /**
+ * Receive notification of the start of DTD declarations.
+ *
+ * The start/endDTD events appear within the start/endDocument events
+ * from ContentHandler.
+ *
+ * @param name The document type name.
+ * @param publicId The declared public identifier for the
+ * external DTD subset, or null if none was declared.
+ * @param systemId The declared system identifier for the
+ * external DTD subset, or null if none was declared.
+ * (Note that this is not resolved against the document
+ * base URI.)
+ * @throws SAXException the event receiver may throw an exception during processing
+ */
+ default public void startDTD (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ // no op
+ }
+
+ // Custom API for the Properties
+
+ /**
+ * Receive notification of the start of DTD internal subset.
+ *
+ * @throws SAXException the event receiver may throw an exception during processing
+ */
+ default public void startInternalSub () throws SAXException
+ {
+ // no op
+ }
}
// end of DTDHandler.java
--- a/src/java.base/share/classes/jdk/internal/util/SystemProps.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/util/SystemProps.java Wed Dec 05 17:05:42 2018 -0500
@@ -90,7 +90,6 @@
putIfAbsent(props, "socksNonProxyHosts", raw.propDefault(Raw._socksNonProxyHosts_NDX));
putIfAbsent(props, "awt.toolkit", raw.propDefault(Raw._awt_toolkit_NDX));
putIfAbsent(props, "java.awt.headless", raw.propDefault(Raw._java_awt_headless_NDX));
- putIfAbsent(props, "java.awt.printerjob", raw.propDefault(Raw._java_awt_printerjob_NDX));
putIfAbsent(props, "java.awt.graphicsenv", raw.propDefault(Raw._java_awt_graphicsenv_NDX));
putIfAbsent(props, "sun.desktop", raw.propDefault(Raw._sun_desktop_NDX));
putIfAbsent(props, "sun.java2d.fontpath", raw.propDefault(Raw._sun_java2d_fontpath_NDX));
@@ -204,8 +203,7 @@
@Native private static final int _https_proxyHost_NDX = 1 + _http_proxyPort_NDX;
@Native private static final int _https_proxyPort_NDX = 1 + _https_proxyHost_NDX;
@Native private static final int _java_awt_graphicsenv_NDX = 1 + _https_proxyPort_NDX;
- @Native private static final int _java_awt_printerjob_NDX = 1 + _java_awt_graphicsenv_NDX;
- @Native private static final int _java_awt_headless_NDX = 1 + _java_awt_printerjob_NDX;
+ @Native private static final int _java_awt_headless_NDX = 1 + _java_awt_graphicsenv_NDX;
@Native private static final int _java_io_tmpdir_NDX = 1 + _java_awt_headless_NDX;
@Native private static final int _line_separator_NDX = 1 + _java_io_tmpdir_NDX;
@Native private static final int _os_arch_NDX = 1 + _line_separator_NDX;
--- a/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/util/xml/PropertiesDefaultHandler.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,11 +54,11 @@
private static final String ATTR_KEY = "key";
// The required DTD URI for exported properties
private static final String PROPS_DTD_DECL =
- "<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">";
+ "<!DOCTYPE properties SYSTEM \"http://java.sun.com/dtd/properties.dtd\">";
private static final String PROPS_DTD_URI =
- "http://java.sun.com/dtd/properties.dtd";
+ "http://java.sun.com/dtd/properties.dtd";
private static final String PROPS_DTD =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<!-- DTD for properties -->"
+ "<!ELEMENT properties ( comment?, entry* ) >"
+ "<!ATTLIST properties"
@@ -136,15 +136,15 @@
////////////////////////////////////////////////////////////////////
// Validate while parsing
////////////////////////////////////////////////////////////////////
- static final String ALLOWED_ELEMENTS = "properties, comment, entry";
+ static final String ALLOWED_ELEMENTS = "comment, entry";
static final String ALLOWED_COMMENT = "comment";
////////////////////////////////////////////////////////////////////
// Handler methods
////////////////////////////////////////////////////////////////////
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
+ boolean sawRoot = false; // whether a valid root element exists
boolean sawComment = false;
boolean validEntry = false;
- int rootElem = 0;
String key;
String rootElm;
@@ -152,32 +152,38 @@
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException
{
- if (rootElem < 2) {
- rootElem++;
+ if (sawRoot) {
+ if (!ALLOWED_ELEMENTS.contains(qName)) {
+ fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
+ }
+ } else {
+ // check whether the root has been declared in the DTD
+ if (rootElm == null) {
+ fatalError(new SAXParseException("An XML properties document must contain"
+ + " the DOCTYPE declaration as defined by java.util.Properties.", null));
+ }
+
+ // check whether the element name matches the declaration
+ if (!rootElm.equals(qName)) {
+ fatalError(new SAXParseException("Document root element \"" + qName
+ + "\", must match DOCTYPE root \"" + rootElm + "\"", null));
+ }
+
+ // this is a valid root element
+ sawRoot = true;
}
- if (rootElm == null) {
- fatalError(new SAXParseException("An XML properties document must contain"
- + " the DOCTYPE declaration as defined by java.util.Properties.", null));
- }
-
- if (rootElem == 1 && !rootElm.equals(qName)) {
- fatalError(new SAXParseException("Document root element \"" + qName
- + "\", must match DOCTYPE root \"" + rootElm + "\"", null));
- }
- if (!ALLOWED_ELEMENTS.contains(qName)) {
- fatalError(new SAXParseException("Element type \"" + qName + "\" must be declared.", null));
- }
if (qName.equals(ELEMENT_ENTRY)) {
validEntry = true;
key = attributes.getValue(ATTR_KEY);
if (key == null) {
- fatalError(new SAXParseException("Attribute \"key\" is required and must be specified for element type \"entry\"", null));
+ fatalError(new SAXParseException("Attribute \"key\" is required and " +
+ "must be specified for element type \"entry\"", null));
}
} else if (qName.equals(ALLOWED_COMMENT)) {
if (sawComment) {
fatalError(new SAXParseException("Only one comment element may be allowed. "
- + "The content of element type \"properties\" must match \"(comment?,entry*)\"", null));
+ + "The content of element type \"properties\" must match \"(comment?,entry*)\"", null));
}
sawComment = true;
}
@@ -192,8 +198,9 @@
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
- if (!ALLOWED_ELEMENTS.contains(qName)) {
- fatalError(new SAXParseException("Element: " + qName + " is invalid, must match \"(comment?,entry*)\".", null));
+ if (!ALLOWED_ELEMENTS.contains(qName) && !ELEMENT_ROOT.equals(qName)) {
+ fatalError(new SAXParseException("Element: " + qName +
+ " is invalid, must match \"(comment?,entry*)\".", null));
}
if (validEntry) {
@@ -204,19 +211,12 @@
}
@Override
- public void notationDecl(String name, String publicId, String systemId) throws SAXException {
- rootElm = name;
- }
-
- @Override
public InputSource resolveEntity(String pubid, String sysid)
- throws SAXException, IOException {
+ throws SAXException, IOException {
{
if (sysid.equals(PROPS_DTD_URI)) {
- InputSource is;
- is = new InputSource(new StringReader(PROPS_DTD));
- is.setSystemId(PROPS_DTD_URI);
- return is;
+ // The properties DTD is known to the handler, no need to parse it
+ return null;
}
throw new SAXException("Invalid system identifier: " + sysid);
}
@@ -236,4 +236,24 @@
public void warning(SAXParseException x) throws SAXException {
throw x;
}
+
+ // SAX2 extension from DTDHandler
+
+ @Override
+ public void startDTD (String name, String publicId, String systemId) throws SAXException
+ {
+ if (!ELEMENT_ROOT.equals(name) || !PROPS_DTD_URI.equals(systemId)) {
+ fatalError(new SAXParseException("An XML properties document must contain"
+ + " the DOCTYPE declaration as defined by java.util.Properties.", null));
+ }
+ rootElm = name;
+ }
+
+ @Override
+ public void startInternalSub () throws SAXException
+ {
+ fatalError(new SAXParseException("Internal DTD subset is not allowed. " +
+ "The Properties XML document must have the following DOCTYPE declaration: \n" +
+ PROPS_DTD_DECL, null));
+ }
}
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/Parser.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -650,6 +650,8 @@
* @exception IOException
*/
private void dtdsub() throws Exception {
+ startInternalSub(); // reports the event before parsing the subset
+
char ch;
for (short st = 0; st >= 0;) {
ch = getch();
@@ -2231,6 +2233,13 @@
throws SAXException;
/**
+ * Reports the start of DTD internal subset.
+ *
+ * @throws SAXException if the receiver throws SAXException
+ */
+ public abstract void startInternalSub () throws SAXException;
+
+ /**
* Reports a comment.
*
* @param text The comment text starting from first charcater.
--- a/src/java.base/share/classes/jdk/internal/util/xml/impl/ParserSAX.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/jdk/internal/util/xml/impl/ParserSAX.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -551,7 +551,16 @@
* @param sysid The system identifier of the entity or <code>null</code>.
*/
protected void docType(String name, String pubid, String sysid) throws SAXException {
- mHandDtd.notationDecl(name, pubid, sysid);
+ mHandDtd.startDTD(name, pubid, sysid);
+ }
+
+ /**
+ * Reports the start of DTD internal subset.
+ *
+ * @throws SAXException if the receiver throws SAXException
+ */
+ public void startInternalSub () throws SAXException {
+ mHandDtd.startInternalSub();
}
/**
--- a/src/java.base/share/classes/sun/security/x509/DNSName.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/sun/security/x509/DNSName.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,16 +34,17 @@
* This class implements the DNSName as required by the GeneralNames
* ASN.1 object.
* <p>
- * [RFC2459] When the subjectAltName extension contains a domain name service
+ * [RFC5280] When the subjectAltName extension contains a domain name system
* label, the domain name MUST be stored in the dNSName (an IA5String).
- * The name MUST be in the "preferred name syntax," as specified by RFC
- * 1034 [RFC 1034]. Note that while upper and lower case letters are
- * allowed in domain names, no signifigance is attached to the case. In
+ * The name MUST be in the "preferred name syntax", as specified by
+ * Section 3.5 of [RFC1034] and as modified by Section 2.1 of
+ * [RFC1123]. Note that while uppercase and lowercase letters are
+ * allowed in domain names, no significance is attached to the case. In
* addition, while the string " " is a legal domain name, subjectAltName
- * extensions with a dNSName " " are not permitted. Finally, the use of
- * the DNS representation for Internet mail addresses (wpolk.nist.gov
- * instead of wpolk@nist.gov) is not permitted; such identities are to
- * be encoded as rfc822Name.
+ * extensions with a dNSName of " " MUST NOT be used. Finally, the use
+ * of the DNS representation for Internet mail addresses
+ * (subscriber.example.com instead of subscriber@example.com) MUST NOT
+ * be used; such identities are to be encoded as rfc822Name.
*
* @author Amit Kapoor
* @author Hemma Prafullchandra
@@ -51,9 +52,8 @@
public class DNSName implements GeneralNameInterface {
private String name;
- private static final String alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- private static final String digitsAndHyphen = "0123456789-";
- private static final String alphaDigitsAndHyphen = alpha + digitsAndHyphen;
+ private static final String alphaDigits =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
/**
* Create the DNSName object from the passed encoded Der value.
@@ -73,35 +73,38 @@
*/
public DNSName(String name) throws IOException {
if (name == null || name.length() == 0)
- throw new IOException("DNS name must not be null");
- if (name.indexOf(' ') != -1)
- throw new IOException("DNS names or NameConstraints with blank components are not permitted");
- if (name.charAt(0) == '.' || name.charAt(name.length() -1) == '.')
- throw new IOException("DNS names or NameConstraints may not begin or end with a .");
- //Name will consist of label components separated by "."
- //startIndex is the index of the first character of a component
- //endIndex is the index of the last character of a component plus 1
- for (int endIndex,startIndex=0; startIndex < name.length(); startIndex = endIndex+1) {
+ throw new IOException("DNSName must not be null or empty");
+ if (name.contains(" "))
+ throw new IOException("DNSName with blank components is not permitted");
+ if (name.startsWith(".") || name.endsWith("."))
+ throw new IOException("DNSName may not begin or end with a .");
+ /*
+ * Name will consist of label components separated by "."
+ * startIndex is the index of the first character of a component
+ * endIndex is the index of the last character of a component plus 1
+ */
+ for (int endIndex,startIndex = 0; startIndex < name.length(); startIndex = endIndex+1) {
endIndex = name.indexOf('.', startIndex);
if (endIndex < 0) {
endIndex = name.length();
}
- if ((endIndex-startIndex) < 1)
- throw new IOException("DNSName SubjectAltNames with empty components are not permitted");
+ if (endIndex - startIndex < 1)
+ throw new IOException("DNSName with empty components are not permitted");
- //DNSName components must begin with a letter A-Z or a-z
- if (alpha.indexOf(name.charAt(startIndex)) < 0)
- throw new IOException("DNSName components must begin with a letter");
+ // RFC 1123: DNSName components must begin with a letter or digit
+ if (alphaDigits.indexOf(name.charAt(startIndex)) < 0)
+ throw new IOException("DNSName components must begin with a letter or digit");
//nonStartIndex: index for characters in the component beyond the first one
for (int nonStartIndex=startIndex+1; nonStartIndex < endIndex; nonStartIndex++) {
char x = name.charAt(nonStartIndex);
- if ((alphaDigitsAndHyphen).indexOf(x) < 0)
+ if ((alphaDigits).indexOf(x) < 0 && x != '-')
throw new IOException("DNSName components must consist of letters, digits, and hyphens");
}
}
this.name = name;
}
+
/**
* Return the type of the GeneralName.
*/
@@ -117,7 +120,7 @@
}
/**
- * Encode the DNS name into the DerOutputStream.
+ * Encode the DNSName into the DerOutputStream.
*
* @param out the DER stream to encode the DNSName to.
* @exception IOException on encoding errors.
@@ -137,7 +140,7 @@
* Compares this name with another, for equality.
*
* @return true iff the names are equivalent
- * according to RFC2459.
+ * according to RFC5280.
*/
public boolean equals(Object obj) {
if (this == obj)
@@ -148,7 +151,7 @@
DNSName other = (DNSName)obj;
- // RFC2459 mandates that these names are
+ // RFC5280 mandates that these names are
// not case-sensitive
return name.equalsIgnoreCase(other.name);
}
@@ -172,12 +175,14 @@
* </ul>. These results are used in checking NameConstraints during
* certification path verification.
* <p>
- * RFC2459: DNS name restrictions are expressed as foo.bar.com. Any subdomain
- * satisfies the name constraint. For example, www.foo.bar.com would
- * satisfy the constraint but bigfoo.bar.com would not.
+ * RFC5280: DNS name restrictions are expressed as host.example.com.
+ * Any DNS name that can be constructed by simply adding zero or more
+ * labels to the left-hand side of the name satisfies the name constraint.
+ * For example, www.host.example.com would satisfy the constraint but
+ * host1.example.com would not.
* <p>
- * draft-ietf-pkix-new-part1-00.txt: DNS name restrictions are expressed as foo.bar.com.
- * Any DNS name that
+ * draft-ietf-pkix-new-part1-00.txt: DNSName restrictions are expressed as foo.bar.com.
+ * Any DNSName that
* can be constructed by simply adding to the left hand side of the name
* satisfies the name constraint. For example, www.foo.bar.com would
* satisfy the constraint but foo1.bar.com would not.
--- a/src/java.base/share/classes/sun/security/x509/GeneralName.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/sun/security/x509/GeneralName.java Wed Dec 05 17:05:42 2018 -0500
@@ -112,7 +112,7 @@
encName.resetTag(DerValue.tag_IA5String);
name = new DNSName(encName);
} else {
- throw new IOException("Invalid encoding of DNS name");
+ throw new IOException("Invalid encoding of DNSName");
}
break;
--- a/src/java.base/share/classes/sun/security/x509/RFC822Name.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/sun/security/x509/RFC822Name.java Wed Dec 05 17:05:42 2018 -0500
@@ -246,7 +246,7 @@
subtree=subtree.substring(atNdx+1);
}
- /* count dots in dnsname, adding one if dnsname preceded by @ */
+ /* count dots in DNSName, adding one if DNSName preceded by @ */
for (; subtree.lastIndexOf('.') >= 0; i++) {
subtree=subtree.substring(0,subtree.lastIndexOf('.'));
}
--- a/src/java.base/share/classes/sun/security/x509/URIName.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/sun/security/x509/URIName.java Wed Dec 05 17:05:42 2018 -0500
@@ -131,13 +131,13 @@
try {
hostDNS = new DNSName(host);
} catch (IOException ioe) {
- // Not a valid DNS Name; see if it is a valid IPv4
+ // Not a valid DNSName; see if it is a valid IPv4
// IPAddressName
try {
hostIP = new IPAddressName(host);
} catch (Exception ioe2) {
throw new IOException("invalid URI name (host " +
- "portion is not a valid DNS name, IPv4 address," +
+ "portion is not a valid DNSName, IPv4 address," +
" or IPv6 address):" + name);
}
}
@@ -339,7 +339,7 @@
// If one (or both) is an IP address, only same type
constraintType = NAME_SAME_TYPE;
} else {
- // Both host portions are DNS names. Are they domains?
+ // Both host portions are DNSNames. Are they domains?
boolean thisDomain = (host.charAt(0) == '.');
boolean otherDomain = (otherHost.charAt(0) == '.');
DNSName otherDNS = (DNSName) otherHostObject;
--- a/src/java.base/share/classes/sun/security/x509/X500Name.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/classes/sun/security/x509/X500Name.java Wed Dec 05 17:05:42 2018 -0500
@@ -1213,7 +1213,7 @@
*/
/*
- * OID for "DC=" domain component attributes, used with DNS names in DN
+ * OID for "DC=" domain component attributes, used with DNSNames in DN
* format
*/
DOMAIN_COMPONENT_OID =
--- a/src/java.base/share/native/libjava/System.c Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/native/libjava/System.c Wed Dec 05 17:05:42 2018 -0500
@@ -206,19 +206,6 @@
/* patch level */
PUTPROP(propArray, _sun_os_patch_level_NDX, sprops->patch_level);
- /* Printing properties */
- /* Note: java.awt.printerjob is an implementation private property which
- * just happens to have a java.* name because it is referenced in
- * a java.awt class. It is the mechanism by which the implementation
- * finds the appropriate class in the JRE for the platform.
- * It is explicitly not designed to be overridden by clients as
- * a way of replacing the implementation class, and in any case
- * the mechanism by which the class is loaded is constrained to only
- * find and load classes that are part of the JRE.
- * This property may be removed if that mechanism is redesigned
- */
- PUTPROP(propArray, _java_awt_printerjob_NDX, sprops->printerJob);
-
PUTPROP(propArray, _awt_toolkit_NDX, sprops->awt_toolkit);
/* Java2D properties */
--- a/src/java.base/share/native/libjava/java_props.h Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/share/native/libjava/java_props.h Wed Dec 05 17:05:42 2018 -0500
@@ -69,7 +69,6 @@
char *sun_stdout_encoding;
char *sun_stderr_encoding;
- char *printerJob;
char *graphics_env;
char *awt_toolkit;
--- a/src/java.base/unix/native/libjava/java_props_md.c Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/unix/native/libjava/java_props_md.c Wed Dec 05 17:05:42 2018 -0500
@@ -391,13 +391,6 @@
}
#endif /* MACOSX */
- /* Printing properties */
-#ifdef MACOSX
- sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";
-#else
- sprops.printerJob = "sun.print.PSPrinterJob";
-#endif
-
/* patches/service packs installed */
sprops.patch_level = NULL; // leave it undefined
--- a/src/java.base/windows/native/libjava/java_props_md.c Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.base/windows/native/libjava/java_props_md.c Wed Dec 05 17:05:42 2018 -0500
@@ -376,9 +376,6 @@
sprops.tmp_dir = _wcsdup(tmpdir);
}
- /* Printing properties */
- sprops.printerJob = "sun.awt.windows.WPrinterJob";
-
/* Java2D properties */
sprops.graphics_env = "sun.awt.Win32GraphicsEnvironment";
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Wed Dec 05 17:05:42 2018 -0500
@@ -32,6 +32,7 @@
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.swing.JProgressBar;
+import javax.swing.JTabbedPane;
import javax.swing.JSlider;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
@@ -42,6 +43,8 @@
import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY;
import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY;
+import static javax.accessibility.AccessibleContext.ACCESSIBLE_NAME_PROPERTY;
+
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleState;
import sun.awt.AWTAccessor;
@@ -67,6 +70,7 @@
private static native void valueChanged(long ptr);
private static native void selectedTextChanged(long ptr);
private static native void selectionChanged(long ptr);
+ private static native void titleChanged(long ptr);
private static native void menuOpened(long ptr);
private static native void menuClosed(long ptr);
private static native void menuItemSelected(long ptr);
@@ -121,9 +125,9 @@
Object oldValue = e.getOldValue();
if (name.compareTo(ACCESSIBLE_CARET_PROPERTY) == 0) {
selectedTextChanged(ptr);
- } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0 ) {
+ } else if (name.compareTo(ACCESSIBLE_TEXT_PROPERTY) == 0) {
valueChanged(ptr);
- } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0 ) {
+ } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0) {
selectionChanged(ptr);
} else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) {
if (newValue instanceof AccessibleContext) {
@@ -162,6 +166,11 @@
if (thisRole == AccessibleRole.CHECK_BOX) {
valueChanged(ptr);
}
+ } else if (name.compareTo(ACCESSIBLE_NAME_PROPERTY) == 0) {
+ //for now trigger only for JTabbedPane.
+ if (e.getSource() instanceof JTabbedPane) {
+ titleChanged(ptr);
+ }
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/macosx/classes/sun/print/PlatformPrinterJobProxy.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.awt.print.PrinterJob;
+
+public class PlatformPrinterJobProxy {
+
+ public static PrinterJob getPrinterJob() {
+ return new sun.lwawt.macosx.CPrinterJob();
+ }
+}
+
+
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.h Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.h Wed Dec 05 17:05:42 2018 -0500
@@ -52,6 +52,7 @@
- (void)postValueChanged;
- (void)postSelectedTextChanged;
- (void)postSelectionChanged;
+- (void)postTitleChanged;
- (BOOL)isEqual:(id)anObject;
- (BOOL)isAccessibleWithEnv:(JNIEnv *)env forAccessible:(jobject)accessible;
--- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Wed Dec 05 17:05:42 2018 -0500
@@ -221,6 +221,12 @@
NSAccessibilityPostNotification(self, NSAccessibilitySelectedChildrenChangedNotification);
}
+-(void)postTitleChanged
+{
+ AWT_ASSERT_APPKIT_THREAD;
+ NSAccessibilityPostNotification(self, NSAccessibilityTitleChangedNotification);
+}
+
- (void)postMenuOpened
{
AWT_ASSERT_APPKIT_THREAD;
@@ -497,7 +503,8 @@
if (attributeStatesArray[6]) {
[attributeNames addObject:NSAccessibilityChildrenAttribute];
if ([javaRole isEqualToString:@"list"]
- || [javaRole isEqualToString:@"table"]) {
+ || [javaRole isEqualToString:@"table"]
+ || [javaRole isEqualToString:@"pagetablist"]) {
[attributeNames addObject:NSAccessibilitySelectedChildrenAttribute];
[attributeNames addObject:NSAccessibilityVisibleChildrenAttribute];
}
@@ -1443,6 +1450,19 @@
/*
* Class: sun_lwawt_macosx_CAccessible
+ * Method: titleChanged
+ * Signature: (I)V
+ */
+ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CAccessible_titleChanged
+ (JNIEnv *env, jclass jklass, jlong element)
+ {
+JNF_COCOA_ENTER(env);
+ [ThreadUtilities performOnMainThread:@selector(postTitleChanged) on:(JavaComponentAccessibility*)jlong_to_ptr(element) withObject:nil waitUntilDone:NO];
+JNF_COCOA_EXIT(env);
+ }
+
+/*
+ * Class: sun_lwawt_macosx_CAccessible
* Method: menuOpened
* Signature: (I)V
*/
--- a/src/java.desktop/macosx/native/libsplashscreen/libpng/zlibwrapper/zlib.h Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This header file is used to hijack the include of "zlib.h" from libpng on
- * Macos. We do that to be able to build on macos 10.13 or later, but still
- * keep binary compatibility with older versions (as specified to configure).
- *
- * The problem is that in 10.13, Macos shipped with a newer version of zlib,
- * which exports the function inflateValidate. There is a call to this
- * function in pngrutil.c, guarded by a preprocessor check of ZLIB_VERNUM being
- * high enough. If we compile this call in and link to the newer version of
- * zlib, we will get link errors if the code is executed on an older Mac with
- * an older version of zlib.
- *
- * The zlib.h header in Macos has been annotated with Macos specific macros that
- * guard these kinds of version specific APIs, but libpng is not using those
- * checks in its conditionals, just ZLIB_VERNUM. To fix this, we check for the
- * MAC_OS_X_VERSION_MIN_REQUIRED macro here and adjust the ZLIB_VERNUM to the
- # known version bundled with that release. This solution is certainly a hack,
- * but it seems the affected versions of zlib.h are compatible enough for this
- * to work.
- */
-
-#include <zlib.h>
-#include <AvailabilityMacros.h>
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
-# undef ZLIB_VERNUM
-# define ZLIB_VERNUM 0x1250
-#elif MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_13
-# undef ZLIB_VERNUM
-# define ZLIB_VERNUM 0x1280
-#endif
--- a/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,17 @@
package com.sun.beans.introspect;
-import com.sun.beans.TypeResolver;
-import com.sun.beans.finder.MethodFinder;
-
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import com.sun.beans.TypeResolver;
+import com.sun.beans.finder.MethodFinder;
+
final class MethodInfo {
final Method method;
final Class<?> type;
@@ -141,7 +140,10 @@
if (aret.isAssignableFrom(bret)) {
return 1;
}
- return -1;
+ if (bret.isAssignableFrom(aret)) {
+ return -1;
+ }
+ return aret.getName().compareTo(bret.getName());
}
static final MethodOrder instance = new MethodOrder();
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriteParam.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriteParam.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,12 +56,11 @@
* <tr>
* <td>JPEG</td>
* <td>"New" JPEG-in-TIFF compression</td>
- * <td><a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">TIFF
- * Technical Note #2</a></td>
- * </tr>
+ * <td>TIFF Technical Note #2</td></tr>
* <tr>
* <td>ZLib</td>
* <td>"Deflate/Inflate" compression (see note following this table)</td>
+ * <td>Adobe Photoshop® TIFF Technical Notes</td>
* </tr>
* <tr>
* <td>PackBits</td>
--- a/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html Wed Dec 05 17:05:42 2018 -0500
@@ -57,22 +57,21 @@
The following table summarizes the desktop properties documented
here, and their value types.
<br><br>
-<table align="center" border="0" cellspacing="0" cellpadding="2"
- summary="Standard AWT Desktop Properties">
+<table>
<tr bgcolor="#ccccff">
-<th valign="TOP" align="LEFT">Property Name</th>
-<th valign="TOP" align="LEFT">Value Type</th>
-<th valign="TOP" align="LEFT">Summary Description</th>
+<th>Property Name</th>
+<th>Value Type</th>
+<th>Summary Description</th>
</tr>
<tr>
-<td valign="TOP"><A href="#awt.font.desktophints">awt.font.desktophints</A></td>
-<td valign="TOP"><a href="../../util/Map.html">java.util.Map</a></td>
-<td valign="TOP">Font smoothing (text antialiasing) settings.</td>
+<td><A href="#awt.font.desktophints">awt.font.desktophints</A></td>
+<td><a href="../../util/Map.html">java.util.Map</a></td>
+<td>Font smoothing (text antialiasing) settings.</td>
</tr>
<tr>
-<td valign="TOP"><A href="#sun.awt.enableExtraMouseButtons">sun.awt.enableExtraMouseButtons</A></td>
-<td valign="TOP"><a href="../../lang/Boolean.html">java.lang.Boolean</a></td>
-<td valign="TOP">Controls if mouse events from extra buttons are to be generated or not</td>
+<td><A href="#sun.awt.enableExtraMouseButtons">sun.awt.enableExtraMouseButtons</A></td>
+<td><a href="../../lang/Boolean.html">java.lang.Boolean</a></td>
+<td>Controls if mouse events from extra buttons are to be generated or not</td>
</tr>
</table>
--- a/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/java/awt/doc-files/Modality.html Wed Dec 05 17:05:42 2018 -0500
@@ -3,6 +3,10 @@
<head>
<meta charset="utf-8"/>
<title>The AWT Modality</title>
+ <style>
+ td {text-align: center;}
+ tr {text-align: center;}
+ </style>
</head>
<!--
Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
@@ -202,48 +206,46 @@
</p><p>
<u>Showing the toolkit-modal dialog: "M"</u><br>
M remains unblocked.
- </p><p>
-<!-- <center> -->
- </p>
+
<table border="1">
<caption>The Standard Blocking Matrix</caption>
- <tbody><tr align="center">
- <td align="center">current/shown</td>
- <td align="center">frame & modeless</td>
- <td align="center">document</td>
- <td align="center">application</td>
- <td align="center">toolkit</td>
+ <tbody><tr>
+ <td>current/shown</td>
+ <td>frame & modeless</td>
+ <td>document</td>
+ <td>application</td>
+ <td>toolkit</td>
</tr>
- <tr align="center">
- <td align="center">-</td>
- <td align="center">-</td>
- <td align="center">-</td>
- <td align="center">-</td>
- <td align="center">-</td>
+ <tr>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
</tr>
- <tr align="center">
- <td align="center">document</td>
- <td align="center">blocked</td>
- <td align="center">-</td>
- <td align="center">-</td>
- <td align="center">-</td>
+ <tr>
+ <td>document</td>
+ <td>blocked</td>
+ <td>-</td>
+ <td>-</td>
+ <td>-</td>
</tr>
- <tr align="center">
- <td align="center">application</td>
- <td align="center">blocked</td>
- <td align="center">blocked</td>
- <td align="center">-</td>
- <td align="center">-</td>
+ <tr>
+ <td>application</td>
+ <td>blocked</td>
+ <td>blocked</td>
+ <td>-</td>
+ <td>-</td>
</tr>
- <tr align="center">
- <td align="center">toolkit</td>
- <td align="center">blocked</td>
- <td align="center">blocked</td>
- <td align="center">blocked</td>
- <td align="center">-</td>
+ <tr>
+ <td>toolkit</td>
+ <td>blocked</td>
+ <td>blocked</td>
+ <td>blocked</td>
+ <td>-</td>
</tr>
- </tbody></table>
-<!-- </center> -->
+ </tbody>
+ </table>
<p>
After the modal dialog is shown, all the windows from its SB are blocked,
except those that block this modal dialog.
@@ -378,43 +380,43 @@
<table border="0">
<tbody><tr>
- <td align="left" >
+ <td style="text-align:left" >
<ol>
<li>Frame "F" is shown<br>
<li>Document-modal dialog "D<sub>i</sub>" is shown<br>
<li>F becomes blocked by D<sub>i</sub> — it's in the same document<br>
<li>Document-modal dialog "D<sub>ii</sub>" is shown<br>
<li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> — it's in the
- same document<br>
+ same document<br>
</ol>
<br>
</td>
- <td align="center">
+ <td>
<img src="modal-example1.gif" alt="Example 1">
<br>
</td>
</tr>
<tr>
- <td align="left">
+ <td style="text-align:left">
<ol>
<li>Frame "F" is shown<br>
<li>Document-modal dialog "D<sub>i</sub>" is shown<br>
<li>F becomes blocked by D<sub>i</sub> — it's in the same document<br>
<li>Document-modal dialog "D<sub>ii</sub>" is shown<br>
<li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> —
- it's in the same document<br>
+ it's in the same document<br>
<li>D<sub>i</sub> is hidden<br>
<li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br>
</ol>
<br>
</td>
- <td align="center">
+ <td>
<img src="modal-example2.gif" alt="Example 2">
<br>
</td>
</tr>
<tr>
- <td align="left">
+ <td style="text-align:left">
<ol>
<li>Frame "F" is shown<br>
<li>Toolkit-modal dialog "D<sub>i</sub>" is created, but not shown<br>
@@ -422,37 +424,37 @@
<li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br>
<li>Application-modal dialog "D<sub>iii</sub>" is shown<br>
<li>D<sub>ii</sub> becomes blocked by D<sub>iii</sub> —
- it's in the same application<br>
+ it's in the same application<br>
<li>D<sub>i</sub> is shown<br>
<li>D<sub>i</sub> becomes blocked by D<sub>ii</sub> — it's its owner<br>
<li>D<sub>iii</sub> remains unblocked — it blocks D<sub>ii</sub> and
- D<sub>ii</sub> blocks D<sub>i</sub><br>
+ D<sub>ii</sub> blocks D<sub>i</sub><br>
</ol>
<br>
</td>
- <td align="center">
+ <td>
<img src="modal-example3.gif" alt="Example 3">
<br>
</td>
</tr>
<tr>
- <td align="left">
- <ol>
+ <td style="text-align:left">
+ <ol>
<li>Frame "F" is shown<br>
<li>Toolkit-modal dialog "D<sub>i</sub>" is created, but not shown<br>
<li>Document-modal dialog "D<sub>ii</sub>" is shown<br>
<li>F becomes blocked by D<sub>ii</sub> — it's in the same document<br>
<li>Application-modal dialog "D<sub>iii</sub>" is shown<br>
<li>D<sub>ii</sub> becomes blocked by D<sub>iii</sub> — it's in the
- same application<br>
+ same application<br>
<li>D<sub>i</sub> is shown<br>
<li>D<sub>iii</sub> becomes blocked by D<sub>i</sub> — D<sub>i</sub>
- is not blocked<br>
+ is not blocked<br>
<li>D<sub>i</sub> remains unblocked<br>
</ol>
<br>
</td>
- <td align="center">
+ <td>
<img src="modal-example4.gif" alt="Example 4">
<br>
</td>
--- a/src/java.desktop/share/classes/java/awt/print/PrinterJob.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/java/awt/print/PrinterJob.java Wed Dec 05 17:05:42 2018 -0500
@@ -72,20 +72,7 @@
if (security != null) {
security.checkPrintJobAccess();
}
- return java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<PrinterJob>() {
- public PrinterJob run() {
- String nm = System.getProperty("java.awt.printerjob", null);
- try {
- return (PrinterJob)Class.forName(nm).
- getConstructor().newInstance();
- } catch (ClassNotFoundException e) {
- throw new AWTError("PrinterJob not found: " + nm);
- } catch (ReflectiveOperationException e) {
- throw new AWTError("Could not instantiate PrinterJob: " + nm);
- }
- }
- });
+ return sun.print.PlatformPrinterJobProxy.getPrinterJob();
}
/**
--- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html Wed Dec 05 17:05:42 2018 -0500
@@ -512,12 +512,11 @@
<tr>
<td>JPEG</td>
<td>"New" JPEG-in-TIFF compression</td>
-<td><a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">TIFF
-Technical Note #2</a></td>
-</tr>
+<td>TIFF Technical Note #2</td></tr>
<tr>
<td>ZLib</td>
<td>"Deflate/Inflate" compression (see note following this table)</td>
+<td>Adobe Photoshop® TIFF Technical Notes</td>
</tr>
<tr>
<td>PackBits</td>
--- a/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/javax/imageio/plugins/tiff/BaselineTIFFTagSet.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -892,9 +892,8 @@
public static final int TAG_TRANSFER_RANGE = 342;
/**
- * Constant specifying the "JPEGTables" tag.
- *
- * @see <a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">JPEG-in-TIFF compression</a>
+ * Constant specifying the "JPEGTables" tag for
+ * "New style" JPEG-in-TIFF compression.
*/
public static final int TAG_JPEG_TABLES = 347;
--- a/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/classes/javax/print/attribute/standard/package-info.java Wed Dec 05 17:05:42 2018 -0500
@@ -162,96 +162,96 @@
* <th scope="col">Print<br>Service<br>Attribute
* <th scope="col">SupportedValuesAttribute
* </thead>
- * <tbody>
+ * <tbody style="text-align: center">
* <tr>
* <th scope="row"><a href="Compression.html">Compression</a>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <td>
* <td>
* <tr>
* <th scope="row"><a href="DocumentName.html">DocumentName</a>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <td>
* <td>
* <tr>
* <th scope="row"><a href="Chromaticity.html">Chromaticity</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="Copies.html">Copies</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="CopiesSupported.html">CopiesSupported</a>
* <tr>
* <th scope="row"><a href="Finishings.html">Finishings</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="JobHoldUntil.html">JobHoldUntil</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="JobImpressions.html">JobImpressions</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="JobImpressionsSupported.html">JobImpressionsSupported</a>
* <tr>
* <th scope="row"><a href="JobKOctets.html">JobKOctets</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="JobKOctetsSupported.html">JobKOctetsSupported</a>
* <tr>
* <th scope="row"><a href="JobMediaSheets.html">JobMediaSheets</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="JobMediaSheetsSupported.html">JobMediaSheetsSupported</a>
* <tr>
* <th scope="row"><a href="JobName.html">JobName</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="JobPriority.html">JobPriority</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="JobPrioritySupported.html">JobPrioritySupported</a>
* <tr>
* <th scope="row"><a href="JobSheets.html">JobSheets</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="Media.html">Media</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -265,73 +265,73 @@
* <th scope="row"><a href="MultipleDocumentHandling.html">
* MultipleDocumentHandling</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="NumberUp.html">NumberUp</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td><a href="NumberUpSupported.html">NumberUpSupported</a>
* <tr>
* <th scope="row"><a href="OrientationRequested.html">
* OrientationRequested</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="PageRanges.html">PageRanges</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="PresentationDirection.html">
* PresentationDirection</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="PrinterResolution.html">PrinterResolution</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="PrintQuality.html">PrintQuality</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="RequestingUserName.html">RequestingUserName</a>
* <td>
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="SheetCollate.html">SheetCollate</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="Sides.html">Sides</a>
- * <td align="center">X
- * <td align="center">X
- * <td align="center">X
+ * <td>X
+ * <td>X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -339,14 +339,14 @@
* DateTimeAtCompleted</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="DateTimeAtCreation.html">DateTimeAtCreation</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -354,7 +354,7 @@
* DateTimeAtProcessing</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -362,7 +362,7 @@
* JobImpressionsCompleted</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -370,7 +370,7 @@
* JobKOctetsProcessed</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -378,7 +378,7 @@
* JobMediaSheetsCompleted</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -386,7 +386,7 @@
* JobMessageFromOperator</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -394,14 +394,14 @@
* JobOriginatingUserName</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
* <th scope="row"><a href="JobState.html">JobState</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -410,7 +410,7 @@
* Contains zero or more --
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -424,7 +424,7 @@
* <th scope="row"><a href="NumberOfDocuments.html">NumberOfDocuments</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -432,7 +432,7 @@
* NumberOfInterveningJobs</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -440,7 +440,7 @@
* OutputDeviceAssigned</a>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <td>
* <tr>
@@ -448,14 +448,14 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PagesPerMinute.html">PagesPerMinute</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PagesPerMinuteColor.html">
@@ -463,7 +463,7 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PDLOverrideSupported.html">
@@ -471,7 +471,7 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterIsAcceptingJobs.html">
@@ -479,21 +479,21 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterInfo.html">PrinterInfo</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterLocation.html">PrinterLocation</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterMessageFromOperator.html">
@@ -501,7 +501,7 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterMakeAndModel.html">
@@ -509,14 +509,14 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterMoreInfo.html">PrinterMoreInfo</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterMoreInfoManufacturer.html">
@@ -524,21 +524,21 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterName.html">PrinterName</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterState.html">PrinterState</a>
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="PrinterStateReasons.html">
@@ -548,7 +548,7 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row">-- <a href="PrinterStateReason.html">
@@ -570,7 +570,7 @@
* <td>
* <td>
* <td>
- * <td align="center">X
+ * <td>X
* <td>
* <tr>
* <th scope="row"><a href="ReferenceUriSchemesSupported.html">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/print/PlatformPrinterJobProxy.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.awt.print.PrinterJob;
+
+public class PlatformPrinterJobProxy {
+
+ public static PrinterJob getPrinterJob() {
+ return new sun.print.PSPrinterJob();
+ }
+}
+
+
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c Wed Dec 05 17:05:42 2018 -0500
@@ -461,6 +461,14 @@
/* See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=657854 */
#define FT_MulFixFloatShift6(a, b) (((float) (a)) * ((float) (b)) / 65536.0 / 64.0)
+#define contextAwareMetricsX(x, y) \
+ (FTFixedToFloat(context->transform.xx) * (x) - \
+ FTFixedToFloat(context->transform.xy) * (y))
+
+#define contextAwareMetricsY(x, y) \
+ (-FTFixedToFloat(context->transform.yx) * (x) + \
+ FTFixedToFloat(context->transform.yy) * (y))
+
/*
* See FreeType source code: src/base/ftobjs.c ft_recompute_scaled_metrics()
* http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1659
@@ -491,9 +499,13 @@
my = 0;
metrics = (*env)->NewObject(env,
- sunFontIDs.strikeMetricsClass,
- sunFontIDs.strikeMetricsCtr,
- ax, ay, dx, dy, bx, by, lx, ly, mx, my);
+ sunFontIDs.strikeMetricsClass,
+ sunFontIDs.strikeMetricsCtr,
+ contextAwareMetricsX(ax, ay), contextAwareMetricsY(ax, ay),
+ contextAwareMetricsX(dx, dy), contextAwareMetricsY(dx, dy),
+ bx, by,
+ contextAwareMetricsX(lx, ly), contextAwareMetricsY(lx, ly),
+ contextAwareMetricsX(mx, my), contextAwareMetricsY(mx, my));
return metrics;
}
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h Wed Dec 05 17:05:42 2018 -0500
@@ -137,7 +137,7 @@
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SEQUENTIAL_READ_SUPPORTED
#define PNG_SETJMP_SUPPORTED
-#define PNG_SET_OPTION_SUPPORTED
+/*#undef PNG_SET_OPTION_SUPPORTED*/
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
#define PNG_SET_USER_LIMITS_SUPPORTED
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/windows/classes/sun/print/PlatformPrinterJobProxy.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.print;
+
+import java.awt.print.PrinterJob;
+
+public class PlatformPrinterJobProxy {
+
+ public static PrinterJob getPrinterJob() {
+ return new sun.awt.windows.WPrinterJob();
+ }
+}
+
+
--- a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -745,7 +745,7 @@
hres = ppf->Load(wstr, STGM_READ);
if (SUCCEEDED(hres)) {
if (resolve) {
- hres = psl->Resolve(NULL, 0);
+ hres = psl->Resolve(NULL, SLR_NO_UI);
// Ignore failure
}
pidl = (LPITEMIDLIST)NULL;
--- a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:05:42 2018 -0500
@@ -268,6 +268,7 @@
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
try {
+ f = f.getCanonicalFile();
f.createNewFile();
} catch (IOException x) {
f = new File(tmpdir, fn);
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:05:42 2018 -0500
@@ -283,6 +283,7 @@
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
try {
+ f = f.getCanonicalFile();
f.createNewFile();
} catch (IOException x) {
String root;
@@ -295,6 +296,7 @@
root = tmpdir;
}
f = new File(root, fn);
+ f = f.getCanonicalFile();
f.createNewFile();
}
return f;
--- a/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java Wed Dec 05 17:05:42 2018 -0500
@@ -234,6 +234,7 @@
String path = "/proc/" + pid + "/cwd/" + fn;
File f = new File(path);
try {
+ f = f.getCanonicalFile();
f.createNewFile();
} catch (IOException x) {
f = new File(tmpdir, fn);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Dec 05 17:05:42 2018 -0500
@@ -2363,16 +2363,19 @@
List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
for (; tl.nonEmpty(); tl = tl.tail) {
Type pt = tl.head;
- switch (pt.getKind()) {
- case INTERSECTION:
- case UNION:
- return true;
- case TYPEVAR:
- TypeVar tv = (TypeVar) pt;
- if (tv.bound.getKind() == TypeKind.INTERSECTION) {
- return true;
- }
- }
+ return isIntersectionOrUnionType(pt);
+ }
+ return false;
+ }
+
+ boolean isIntersectionOrUnionType(Type t) {
+ switch (t.getKind()) {
+ case INTERSECTION:
+ case UNION:
+ return true;
+ case TYPEVAR:
+ TypeVar tv = (TypeVar) t;
+ return isIntersectionOrUnionType(tv.bound);
}
return false;
}
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AccessibleMembersLookup.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/AccessibleMembersLookup.java Wed Dec 05 17:05:42 2018 -0500
@@ -216,7 +216,10 @@
// were not yet loaded, they'll only get loaded in a non-resolved state; no static initializers for
// them will trigger just by doing this.
// Don't overwrite an inner class with an inherited inner class with the same name.
- innerClasses.putIfAbsent(innerClass.getSimpleName(), innerClass);
+ Class<?> previousClass = innerClasses.get(innerClass.getSimpleName());
+ if (previousClass == null || previousClass.getDeclaringClass().isAssignableFrom(innerClass.getDeclaringClass())) {
+ innerClasses.put(innerClass.getSimpleName(), innerClass);
+ }
}
} else {
searchSuperTypes = true;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/JMap.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -182,7 +182,7 @@
hgw.write(fileName);
System.out.println("heap written to " + fileName);
return true;
- } catch (IOException exp) {
+ } catch (IOException | RuntimeException exp) {
System.err.println(exp.getMessage());
return false;
}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -32,6 +32,7 @@
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.classfile.*;
+import sun.jvm.hotspot.gc.z.ZCollectedHeap;
/*
* This class writes Java heap in hprof binary format. This format is
@@ -388,11 +389,15 @@
}
public synchronized void write(String fileName) throws IOException {
+ VM vm = VM.getVM();
+ if (vm.getUniverse().heap() instanceof ZCollectedHeap) {
+ throw new RuntimeException("This operation is not supported with ZGC.");
+ }
+
// open file stream and create buffered data output stream
fos = new FileOutputStream(fileName);
out = new DataOutputStream(new BufferedOutputStream(fos));
- VM vm = VM.getVM();
dbg = vm.getDebugger();
objectHeap = vm.getObjectHeap();
--- a/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -647,7 +647,7 @@
(void)snprintf(buf, sizeof(buf), "JDWP %s, jvmtiError=%s(%d)",
msg, jvmtiErrorText(error), error);
} else {
- (void)snprintf(buf, sizeof(buf), "JDWP %s", buf);
+ (void)snprintf(buf, sizeof(buf), "JDWP %s", msg);
}
if (env != NULL) {
(*((*env)->FatalError))(env, buf);
--- a/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/ValueDescriptor.java Wed Dec 05 17:05:42 2018 -0500
@@ -291,7 +291,7 @@
if (type.isSimpleType()) {
return Collections.emptyList();
}
- return Collections.unmodifiableList(type.getFields());
+ return type.getFields();
}
// package private
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/ChunkParser.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/ChunkParser.java Wed Dec 05 17:05:42 2018 -0500
@@ -53,7 +53,7 @@
private final TimeConverter timeConverter;
public ChunkParser(RecordingInput input) throws IOException {
- this(new ChunkHeader(input));
+ this(new ChunkHeader(input));
}
private ChunkParser(ChunkHeader header) throws IOException {
@@ -61,7 +61,7 @@
this.chunkHeader = header;
this.metadata = header.readMetadata();
this.absoluteChunkEnd = header.getEnd();
- this.timeConverter = new TimeConverter(chunkHeader);
+ this.timeConverter = new TimeConverter(chunkHeader, metadata.getGMTOffset());
ParserFactory factory = new ParserFactory(metadata, timeConverter);
LongMap<ConstantMap> constantPools = factory.getConstantPools();
@@ -114,9 +114,7 @@
boolean flush = input.readBoolean();
int poolCount = input.readInt();
Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.TRACE, () -> {
- return "New constant pool: startPosition=" + position +
- ", size=" + size + ", deltaToNext=" + delta +
- ", flush=" + flush + ", poolCount=" + poolCount;
+ return "New constant pool: startPosition=" + position + ", size=" + size + ", deltaToNext=" + delta + ", flush=" + flush + ", poolCount=" + poolCount;
});
for (int i = 0; i < poolCount; i++) {
@@ -155,7 +153,7 @@
private String getName(long id) {
Type type = typeMap.get(id);
- return type == null ? ("unknown(" + id +")") : type.getName();
+ return type == null ? ("unknown(" + id + ")") : type.getName();
}
public Collection<Type> getTypes() {
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedEvent.java Wed Dec 05 17:05:42 2018 -0500
@@ -41,7 +41,8 @@
public final class RecordedEvent extends RecordedObject {
private final EventType eventType;
private final long startTime;
- private final long endTime;
+ // package private needed for efficient sorting
+ final long endTime;
// package private
RecordedEvent(EventType type, List<ValueDescriptor> vds, Object[] values, long startTime, long endTime, TimeConverter timeConverter) {
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java Wed Dec 05 17:05:42 2018 -0500
@@ -25,11 +25,11 @@
package jdk.jfr.consumer;
-import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.Duration;
import java.time.Instant;
+import java.time.OffsetDateTime;
import java.util.List;
import java.util.Objects;
@@ -37,7 +37,7 @@
import jdk.jfr.Timestamp;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.internal.PrivateAccess;
-import jdk.jfr.internal.cmd.PrettyWriter;
+import jdk.jfr.internal.tool.PrettyWriter;
/**
* A complex data type that consists of one or more fields.
@@ -872,18 +872,19 @@
final public String toString() {
StringWriter s = new StringWriter();
PrettyWriter p = new PrettyWriter(new PrintWriter(s));
- try {
- if (this instanceof RecordedEvent) {
- p.print((RecordedEvent) this);
- } else {
- p.print(this, "");
- }
+ p.setStackDepth(5);
+ if (this instanceof RecordedEvent) {
+ p.print((RecordedEvent) this);
+ } else {
+ p.print(this, "");
+ }
+ p.flush(true);
+ return s.toString();
+ }
- } catch (IOException e) {
- // Ignore, should not happen with StringWriter
- }
- p.flush();
- return s.toString();
+ // package private for now. Used by EventWriter
+ OffsetDateTime getOffsetDateTime(String name) {
+ return OffsetDateTime.ofInstant(getInstant(name), timeConverter.getZoneOffset());
}
private static IllegalArgumentException newIllegalArgumentException(String name, String typeName) {
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java Wed Dec 05 17:05:42 2018 -0500
@@ -32,13 +32,16 @@
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import jdk.jfr.EventType;
import jdk.jfr.internal.MetadataDescriptor;
+import jdk.jfr.internal.Type;
import jdk.jfr.internal.consumer.ChunkHeader;
import jdk.jfr.internal.consumer.RecordingInput;
+import jdk.jfr.internal.consumer.RecordingInternals;
/**
* A recording file.
@@ -59,7 +62,29 @@
* @since 9
*/
public final class RecordingFile implements Closeable {
+ static{
+ RecordingInternals.INSTANCE = new RecordingInternals() {
+ public List<Type> readTypes(RecordingFile file) throws IOException {
+ return file.readTypes();
+ }
+ public boolean isLastEventInChunk(RecordingFile file) {
+ return file.isLastEventInChunk;
+ }
+
+ @Override
+ public Object getOffsetDataTime(RecordedObject event, String name) {
+ return event.getOffsetDateTime(name);
+ }
+
+ @Override
+ public void sort(List<RecordedEvent> events) {
+ Collections.sort(events, (e1, e2) -> Long.compare(e1.endTime, e2.endTime));
+ }
+ };
+ }
+
+ private boolean isLastEventInChunk;
private final File file;
private RecordingInput input;
private ChunkParser chunkParser;
@@ -98,9 +123,11 @@
ensureOpen();
throw new EOFException();
}
+ isLastEventInChunk = false;
RecordedEvent event = nextEvent;
nextEvent = chunkParser.readEvent();
if (nextEvent == null) {
+ isLastEventInChunk = true;
findNext();
}
return event;
@@ -131,6 +158,21 @@
HashSet<Long> foundIds = new HashSet<>();
try (RecordingInput ri = new RecordingInput(file)) {
ChunkHeader ch = new ChunkHeader(ri);
+ aggregateEventTypeForChunk(ch, types, foundIds);
+ while (!ch.isLastChunk()) {
+ ch = ch.nextHeader();
+ aggregateEventTypeForChunk(ch, types, foundIds);
+ }
+ }
+ return types;
+ }
+
+ List<Type> readTypes() throws IOException {
+ ensureOpen();
+ List<Type> types = new ArrayList<>();
+ HashSet<Long> foundIds = new HashSet<>();
+ try (RecordingInput ri = new RecordingInput(file)) {
+ ChunkHeader ch = new ChunkHeader(ri);
aggregateTypeForChunk(ch, types, foundIds);
while (!ch.isLastChunk()) {
ch = ch.nextHeader();
@@ -140,7 +182,17 @@
return types;
}
- private static void aggregateTypeForChunk(ChunkHeader ch, List<EventType> types, HashSet<Long> foundIds) throws IOException {
+ private void aggregateTypeForChunk(ChunkHeader ch, List<Type> types, HashSet<Long> foundIds) throws IOException {
+ MetadataDescriptor m = ch.readMetadata();
+ for (Type t : m.getTypes()) {
+ if (!foundIds.contains(t.getId())) {
+ types.add(t);
+ foundIds.add(t.getId());
+ }
+ }
+ }
+
+ private static void aggregateEventTypeForChunk(ChunkHeader ch, List<EventType> types, HashSet<Long> foundIds) throws IOException {
MetadataDescriptor m = ch.readMetadata();
for (EventType t : m.getEventTypes()) {
if (!foundIds.contains(t.getId())) {
--- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/TimeConverter.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/TimeConverter.java Wed Dec 05 17:05:42 2018 -0500
@@ -25,6 +25,12 @@
package jdk.jfr.consumer;
+import java.time.DateTimeException;
+import java.time.ZoneOffset;
+
+import jdk.jfr.internal.LogLevel;
+import jdk.jfr.internal.LogTag;
+import jdk.jfr.internal.Logger;
import jdk.jfr.internal.consumer.ChunkHeader;
/**
@@ -34,11 +40,22 @@
private final long startTicks;
private final long startNanos;
private final double divisor;
+ private final ZoneOffset zoneOffet;
- TimeConverter(ChunkHeader chunkHeader) {
+ TimeConverter(ChunkHeader chunkHeader, int rawOffset) {
this.startTicks = chunkHeader.getStartTicks();
this.startNanos = chunkHeader.getStartNanos();
this.divisor = chunkHeader.getTicksPerSecond() / 1000_000_000L;
+ this.zoneOffet = zoneOfSet(rawOffset);
+ }
+
+ private ZoneOffset zoneOfSet(int rawOffset) {
+ try {
+ return ZoneOffset.ofTotalSeconds(rawOffset / 1000);
+ } catch (DateTimeException dte) {
+ Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Could not create ZoneOffset from raw offset " + rawOffset);
+ }
+ return ZoneOffset.UTC;
}
public long convertTimestamp(long ticks) {
@@ -48,4 +65,8 @@
public long convertTimespan(long ticks) {
return (long) (ticks / divisor);
}
+
+ public ZoneOffset getZoneOffset() {
+ return zoneOffet;
+ }
}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java Wed Dec 05 17:05:42 2018 -0500
@@ -49,7 +49,7 @@
private static final String OLD_OBJECT_CUTOFF = EVENT_NAME + "#" + Cutoff.NAME;
private static final String OLD_OBJECT_ENABLED = EVENT_NAME + "#" + Enabled.NAME;
- // Emit if old object is enabled in recoding with cutoff for that recording
+ // Emit if old object is enabled in recording with cutoff for that recording
public static void emit(PlatformRecording recording) {
if (isEnabled(recording)) {
long nanos = CutoffSetting.parseValueSafe(recording.getSettings().get(OLD_OBJECT_CUTOFF));
@@ -59,7 +59,7 @@
}
// Emit if old object is enabled for at least one recording, and use the largest
- // cutoff for an enabled recoding
+ // cutoff for an enabled recording
public static void emit(List<PlatformRecording> recordings, Boolean pathToGcRoots) {
boolean enabled = false;
long cutoffNanos = Boolean.TRUE.equals(pathToGcRoots) ? Long.MAX_VALUE : 0L;
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Type.java Wed Dec 05 17:05:42 2018 -0500
@@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -71,7 +72,7 @@
private final String name;
private final String superType;
private final boolean constantPool;
- private final ArrayList<ValueDescriptor> fields = new ArrayList<>();
+ private List<ValueDescriptor> fields = new ArrayList<>();
private Boolean simpleType; // calculated lazy
private boolean remove = true;
private long id;
@@ -183,6 +184,10 @@
}
public List<ValueDescriptor> getFields() {
+ if (fields instanceof ArrayList) {
+ ((ArrayList<ValueDescriptor>) fields).trimToSize();
+ fields = Collections.unmodifiableList(fields);
+ }
return fields;
}
@@ -216,7 +221,7 @@
}
void trimFields() {
- fields.trimToSize();
+ getFields();
}
void setAnnotations(List<AnnotationElement> annotations) {
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Utils.java Wed Dec 05 17:05:42 2018 -0500
@@ -102,6 +102,9 @@
}
public static String formatBytes(long bytes, String separation) {
+ if (bytes == 1) {
+ return "1 byte";
+ }
if (bytes < 1024) {
return bytes + " bytes";
}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Command.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-
-abstract class Command {
-
- private final static Command HELP = new HelpCommand();
- private final static List<Command> COMMANDS = createCommands();
-
- static void displayHelp() {
- System.out.println("Usage: java " + Execute.class.getName() + " <command> [<options>]");
- System.out.println();
- displayAvailableCommands();
- }
-
- static void displayAvailableCommands() {
- System.out.println("Available commands are:");
- System.out.println();
- boolean first = true;
- for (Command c : Command.COMMANDS) {
- if (!first) {
- System.out.println();
- }
- System.out.println(" " + c.getName() + " " + c.getOptionSyntax());
- System.out.println(" " + c.getDescription());
- first = false;
- }
- }
-
- public static List<Command> getCommands() {
- return COMMANDS;
- }
-
- public static Command valueOf(String commandName) {
- for (Command command : COMMANDS) {
- if (command.getName().equals(commandName)) {
- return command;
- }
- }
- return null;
- }
-
- abstract public String getOptionSyntax();
-
- abstract public String getName();
-
- abstract public String getDescription();
-
- abstract public void displayOptionUsage();
-
- abstract public void execute(Deque<String> options);
-
- final protected void userFailed(String message) {
- println();
- println(message);
- displayUsage();
- throw new IllegalArgumentException(message);
- }
-
- final protected void ensureMaxArgumentCount(Deque<String> options, int maxCount) {
- if (options.size() > maxCount) {
- userFailed("Too many arguments");
- }
- }
-
- final protected void ensureMinArgumentCount(Deque<String> options, int minCount) {
- if (options.size() < minCount) {
- userFailed("Too few arguments");
- }
- }
-
- final protected void ensureFileExist(Path file) {
- if (!Files.exists(file)) {
- userFailed("Could not find file " + file);
- }
- }
-
- final protected Path ensureFileDoesNotExist(Path file) {
- if (Files.exists(file)) {
- userFailed("File " + file + " already exists");
- }
- return file;
- }
-
- final protected void ensureJFRFile(Path path) {
- if (!path.toString().endsWith(".jfr")) {
- userFailed("Filename must end with .jfr");
- }
- }
-
- final protected void displayUsage() {
- String javaText = "java " + Execute.class.getName();
- println();
- println("Usage: " + javaText + " " + getName() + " " + getOptionSyntax());
- println();
- displayOptionUsage();
- }
-
- final protected void println() {
- System.out.println();
- }
-
- final protected void print(String text) {
- System.out.print(text);
- }
-
- final protected void println(String text) {
- System.out.println(text);
- }
-
- private static List<Command> createCommands() {
- List<Command> commands = new ArrayList<>();
- commands.add(new PrintCommand());
- commands.add(new SummaryCommand());
- commands.add(new ReconstructCommand());
- commands.add(new SplitCommand());
- commands.add(HELP);
- return Collections.unmodifiableList(commands);
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Execute.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.LinkedList;
-
-/**
- * Launcher class for JFR tools
- *
- */
-public final class Execute {
-
- public static void main(String... args) {
- Deque<String> argList = new LinkedList<>(Arrays.asList(args));
- if (argList.isEmpty()) {
- System.out.println();
- Command.displayHelp();
- return;
- }
- String command = argList.remove();
- for (Command c : Command.getCommands()) {
- if (c.getName().equals(command)) {
- try {
- c.execute(argList);
- } catch (IllegalArgumentException iae) {
- return; // already handled by command
- } catch (Throwable e) {
- System.out.println();
- System.out.println(e.getMessage());
- System.out.println();
- }
- return;
- }
- }
- System.out.println();
- System.out.println("Unknown command " + command + ".");
- System.out.println();
- Command.displayHelp();
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/HelpCommand.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.util.Deque;
-
-final class HelpCommand extends Command {
-
- @Override
- public String getOptionSyntax() {
- return "[<command>]";
- }
-
- @Override
- public void displayOptionUsage() {
- println(" <command> The name of the command to get help for");
- println();
- Command.displayAvailableCommands();
- }
-
- @Override
- public String getName() {
- return "help";
- }
-
- @Override
- public String getDescription() {
- return "Display help about a command";
- }
-
- @Override
- public void execute(Deque<String> options) {
- if (options.isEmpty()) {
- displayUsage();
- } else {
- ensureMaxArgumentCount(options, 1);
- String commandName = options.remove();
- Command c = Command.valueOf(commandName);
- if (c == null) {
- userFailed("Unknown command " + commandName);
- }
- c.displayUsage();
- }
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/JSONWriter.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-
-final class JSONWriter extends StructuredWriter {
-
- public JSONWriter(PrintWriter writer) {
- super(writer);
- }
-
- public void print(Path source) throws IOException {
- try (RecordingFile es = new RecordingFile(source)) {
- printObjectBegin();
- printRecording(es);
- printObjectEnd();
- flush();
- }
- }
-
- private void printRecording(RecordingFile es) throws IOException {
- printDataStructureName("recording");
- printObjectBegin();
- printEvents(es);
- printObjectEnd();
- }
-
- private void printEvents(RecordingFile es) throws IOException {
- printDataStructureName("events");
- printArrayBegin();
- boolean first = true;
- while (es.hasMoreEvents()) {
- RecordedEvent e = es.readEvent();
- printNewDataStructure(first, true, null);
- printEvent(e);
- flush();
- first = false;
- }
- printArrayEnd();
- }
-
- private void printEvent(RecordedEvent e) {
- printObjectBegin();
- EventType type = e.getEventType();
- printValue(true, false, "name", type.getName());
- printValue(false, false, "typeId", type.getId());
- printValue(false, false, "startTime", e.getStartTime());
- printValue(false, false, "duration", e.getDuration());
- printNewDataStructure(false, false, "values");
- printObject(e);
- printObjectEnd();
- }
-
- void printValue(boolean first, boolean arrayElement, String name, Object value) {
- printNewDataStructure(first, arrayElement, name);
- if (!printIfNull(value)) {
- if (value instanceof Boolean) {
- printAsString(value);
- return;
- }
- if (value instanceof Double) {
- Double dValue = (Double) value;
- if (Double.isNaN(dValue) || Double.isInfinite(dValue)) {
- printNull();
- return;
- }
- printAsString(value);
- return;
- }
- if (value instanceof Float) {
- Float fValue = (Float) value;
- if (Float.isNaN(fValue) || Float.isInfinite(fValue)) {
- printNull();
- return;
- }
- printAsString(value);
- return;
- }
- if (value instanceof Number) {
- printAsString(value);
- return;
- }
- print("\"");
- printEscaped(String.valueOf(value));
- print("\"");
- }
- }
-
- public void printObject(RecordedObject object) {
- printObjectBegin();
- boolean first = true;
- for (ValueDescriptor v : object.getFields()) {
- printValueDescriptor(first, false, v, object.getValue(v.getName()));
- first = false;
- }
- printObjectEnd();
- }
-
- private void printArray(ValueDescriptor v, Object[] array) {
- printArrayBegin();
- boolean first = true;
- for (Object arrayElement : array) {
- printValueDescriptor(first, true, v, arrayElement);
- first = false;
- }
- printArrayEnd();
- }
-
- private void printValueDescriptor(boolean first, boolean arrayElement, ValueDescriptor vd, Object value) {
- if (vd.isArray() && !arrayElement) {
- printNewDataStructure(first, arrayElement, vd.getName());
- if (!printIfNull(value)) {
- printArray(vd, (Object[]) value);
- }
- return;
- }
- if (!vd.getFields().isEmpty()) {
- printNewDataStructure(first, arrayElement, vd.getName());
- if (!printIfNull(value)) {
- printObject((RecordedObject) value);
- }
- return;
- }
- printValue(first, arrayElement, vd.getName(), value);
- }
-
- private void printNewDataStructure(boolean first, boolean arrayElement, String name) {
- if (!first) {
- print(", ");
- if (!arrayElement) {
- println();
- }
- }
- if (!arrayElement) {
- printDataStructureName(name);
- }
- }
-
- private boolean printIfNull(Object value) {
- if (value == null) {
- printNull();
- return true;
- }
- return false;
- }
-
- private void printNull() {
- print("null");
- }
-
- private void printDataStructureName(String text) {
- printIndent();
- print("\"");
- print(text);
- print("\": ");
- }
-
- private void printObjectEnd() {
- retract();
- println();
- printIndent();
- print("}");
- }
-
- private void printObjectBegin() {
- println("{");
- indent();
- }
-
- private void printArrayEnd() {
- print("]");
- }
-
- private void printArrayBegin() {
- print("[");
- }
-
- private void printEscaped(String text) {
- for (int i = 0; i < text.length(); i++) {
- printEscaped(text.charAt(i));
- }
- }
-
- private void printEscaped(char c) {
- if (c == '\b') {
- print("\\b");
- return;
- }
- if (c == '\n') {
- print("\\n");
- return;
- }
- if (c == '\t') {
- print("\\t");
- return;
- }
- if (c == '\f') {
- print("\\f");
- return;
- }
- if (c == '\r') {
- print("\\r");
- return;
- }
- if (c == '\"') {
- print("\\\"");
- return;
- }
- if (c == '\\') {
- print("\\\\");
- return;
- }
- if (c == '/') {
- print("\\/");
- return;
- }
- if (c > 0x7F || c < 32) {
- print("\\u");
- // 0x10000 will pad with zeros.
- print(Integer.toHexString(0x10000 + (int) c).substring(1));
- return;
- }
- print(c);
- }
-
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrettyWriter.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.StringJoiner;
-
-import jdk.jfr.AnnotationElement;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.jfr.internal.PrivateAccess;
-import jdk.jfr.internal.Type;
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-public final class PrettyWriter extends StructuredWriter {
-
- public PrettyWriter(PrintWriter destination) {
- super(destination);
- }
-
- void print(Path source) throws FileNotFoundException, IOException {
- try (RecordingInput input = new RecordingInput(source.toFile())) {
- HashSet<Type> typeSet = new HashSet<>();
- for (ChunkHeader ch = new ChunkHeader(input); !ch.isLastChunk(); ch = ch.nextHeader()) {
- typeSet.addAll(ch.readMetadata().getTypes());
- }
- List<Type> types = new ArrayList<>(typeSet);
- Collections.sort(types, (c1, c2) -> Long.compare(c1.getId(), c2.getId()));
- for (Type t : types) {
- printType(t);
- }
- flush();
- }
-
- try (RecordingFile es = new RecordingFile(source)) {
- while (es.hasMoreEvents()) {
- print(es.readEvent());
- flush();
- }
- }
- flush();
- }
-
- public void printType(Type t) throws IOException {
- print("// id: ");
- println(String.valueOf(t.getId()));
- int commentIndex = t.getName().length() + 10;
- String typeName = t.getName();
- int index = typeName.lastIndexOf(".");
- if (index != -1) {
- println("package " + typeName.substring(0, index) + ";");
- }
- printAnnotations(commentIndex, t.getAnnotationElements());
- print("class " + typeName.substring(index + 1));
- String superType = t.getSuperType();
- if (superType != null) {
- print(" extends " + superType);
- }
- println(" {");
- indent();
- for (ValueDescriptor v : t.getFields()) {
- printField(commentIndex, v);
- }
- retract();
- println("}");
- println();
- }
-
- private void printField(int commentIndex, ValueDescriptor v) throws IOException {
- println();
- printAnnotations(commentIndex, v.getAnnotationElements());
- printIndent();
- Type vType = PrivateAccess.getInstance().getType(v);
- if (Type.SUPER_TYPE_SETTING.equals(vType.getSuperType())) {
- print("static ");
- }
- print(makeSimpleType(v.getTypeName()));
- if (v.isArray()) {
- print("[]");
- }
- print(" ");
- print(v.getName());
- print(";");
- printCommentRef(commentIndex, v.getTypeId());
- }
-
- private void printCommentRef(int commentIndex, long typeId) throws IOException {
- int column = getColumn();
- if (column > commentIndex) {
- print(" ");
- } else {
- while (column < commentIndex) {
- print(" ");
- column++;
- }
- }
- println(" // id=" + typeId);
- }
-
- private void printAnnotations(int commentIndex, List<AnnotationElement> annotations) throws IOException {
- for (AnnotationElement a : annotations) {
- printIndent();
- print("@");
- print(makeSimpleType(a.getTypeName()));
- List<ValueDescriptor> vs = a.getValueDescriptors();
- if (!vs.isEmpty()) {
- printAnnotation(a);
- printCommentRef(commentIndex, a.getTypeId());
- } else {
- println();
- }
- }
- }
-
- private void printAnnotation(AnnotationElement a) throws IOException {
- StringJoiner sj = new StringJoiner(", ", "(", ")");
- List<ValueDescriptor> vs = a.getValueDescriptors();
- for (ValueDescriptor v : vs) {
- Object o = a.getValue(v.getName());
- if (vs.size() == 1 && v.getName().equals("value")) {
- sj.add(textify(o));
- } else {
- sj.add(v.getName() + "=" + textify(o));
- }
- }
- print(sj.toString());
- }
-
- private String textify(Object o) {
- if (o.getClass().isArray()) {
- Object[] array = (Object[]) o;
- if (array.length == 1) {
- return quoteIfNeeded(array[0]);
- }
- StringJoiner s = new StringJoiner(", ", "{", "}") ;
- for (Object ob : array) {
- s.add(quoteIfNeeded(ob));
- }
- return s.toString();
- } else {
- return quoteIfNeeded(o);
- }
- }
-
- private String quoteIfNeeded(Object o) {
- if (o instanceof String) {
- return "\"" + o + "\"";
- } else {
- return String.valueOf(o);
- }
- }
-
- private String makeSimpleType(String typeName) {
- int index = typeName.lastIndexOf(".");
- return typeName.substring(index + 1);
- }
-
- public void print(RecordedEvent event) throws IOException {
- print(makeSimpleType(event.getEventType().getName()), " ");
- print((RecordedObject) event, "");
- }
-
- public void print(RecordedObject struct, String postFix) throws IOException {
- println("{");
- indent();
- for (ValueDescriptor v : struct.getFields()) {
- printIndent();
- print(v.getName(), " = ");
- printValue(struct.getValue(v.getName()), "");
- }
- retract();
- printIndent();
- println("}" + postFix);
- }
-
- private void printArray(Object[] array) throws IOException {
- println("[");
- indent();
- for (int i = 0; i < array.length; i++) {
- printIndent();
- printValue(array[i], i + 1 < array.length ? ", " : "");
- }
- retract();
- printIndent();
- println("]");
- }
-
- private void printValue(Object value, String postFix) throws IOException {
- if (value == null) {
- println("null" + postFix);
- } else if (value instanceof RecordedObject) {
- print((RecordedObject) value, postFix);
- } else if (value.getClass().isArray()) {
- printArray((Object[]) value);
- } else {
- String text = String.valueOf(value);
- if (value instanceof String) {
- text = "\"" + text + "\"";
- }
- println(text);
- }
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrintCommand.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Deque;
-
-final class PrintCommand extends Command {
- @Override
- public String getName() {
- return "print";
- }
-
- @Override
- public String getOptionSyntax() {
- return "[--xml|--json] <file>";
- }
-
- @Override
- public String getDescription() {
- return "Print contents of a recording file (.jfr)";
- }
-
- @Override
- public void displayOptionUsage() {
- println(" --xml Print a recording in XML format");
- println();
- println(" --json Print a recording in JSON format");
- println();
- println(" <file> Location of the recording file (.jfr) to print");
- }
-
- @Override
- public void execute(Deque<String> options) {
- if (options.isEmpty()) {
- userFailed("Missing file");
- }
- ensureMaxArgumentCount(options, 2);
-
- Path file = Paths.get(options.removeLast());
-
- ensureFileExist(file);
- ensureJFRFile(file);
- ensureMaxArgumentCount(options, 1);
-
- String format = "--pretty";
- if (!options.isEmpty()) {
- format = options.remove();
- }
- try (PrintWriter pw = new PrintWriter(System.out)) {
- try {
- switch (format) {
- case "--pretty":
- PrettyWriter prettyWriter = new PrettyWriter(pw);
- prettyWriter.print(file);
- break;
- case "--xml":
- XMLWriter xmlPrinter = new XMLWriter(pw);
- xmlPrinter.print(file);
- break;
- case "--json":
- JSONWriter jsonWriter = new JSONWriter(pw);
- jsonWriter.print(file);
- break;
- default:
- userFailed("Unknown option " + format);
- break;
- }
- } catch (IOException ioe) {
- userFailed("Could not read recording at " + file.toAbsolutePath() + ". " + ioe.getMessage());
- }
- }
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/ReconstructCommand.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-
-final class ReconstructCommand extends Command {
-
- @Override
- public String getOptionSyntax() {
- return "<repository> <file>";
- }
-
- @Override
- public String getName() {
- return "reconstruct";
- }
-
- @Override
- public String getDescription() {
- return "Assemble leftover chunks, from a disk repository, into a recording file (.jfr)";
- }
-
- @Override
- public void displayOptionUsage() {
- println(" <repository> Directory where the repository is located");
- println();
- println(" <file> Name of the recording file (.jfr) to create");
- }
-
- @Override
- public void execute(Deque<String> options) {
- ensureMinArgumentCount(options, 2);
- ensureMaxArgumentCount(options, 2);
-
- Path repository = Paths.get(options.pop()).toAbsolutePath();
- if (!Files.exists(repository)) {
- userFailed("Could not find disk repository at " + repository);
- }
- if (!Files.isDirectory(repository)) {
- userFailed("Must specify a directory as disk repository");
- }
- Path output = Paths.get(options.pop());
- ensureFileDoesNotExist(output);
- ensureJFRFile(output);
-
- try (FileOutputStream fos = new FileOutputStream(output.toFile())) {
- List<Path> files = listJFRFiles(repository);
- if (files.isEmpty()) {
- throw new IllegalStateException("No *.jfr files found at " + repository);
- }
- println();
- println("Combining files... ");
- println();
- transferTo(files, output, fos.getChannel());
- println();
- println("Reconstruction complete.");
- } catch (IOException e) {
- userFailed("Could not open destination file " + output + ". " + e.getMessage());
- }
- }
-
- private List<Path> listJFRFiles(Path path) throws IOException {
- try {
- List<Path> files = new ArrayList<>();
- if (Files.isDirectory(path)) {
- try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.jfr")) {
- for (Path p : stream) {
- if (!Files.isDirectory(p) && Files.isReadable(p)) {
- files.add(p);
- }
- }
- }
- }
- files.sort((u, v) -> u.getFileName().compareTo(v.getFileName()));
- return files;
- } catch (IOException ioe) {
- throw new IllegalStateException("Could not list *.jfr for directory " + path + ". " + ioe.getMessage());
- }
- }
-
- private void transferTo(List<Path> sourceFiles, Path output, FileChannel out) {
- long pos = 0;
- for (Path p : sourceFiles) {
- println(" " + p.toString());
- try (FileChannel sourceChannel = FileChannel.open(p)) {
- long rem = Files.size(p);
- while (rem > 0) {
- long n = Math.min(rem, 1024 * 1024);
- long w = out.transferFrom(sourceChannel, pos, n);
- pos += w;
- rem -= w;
- }
- } catch (IOException ioe) {
- throw new IllegalStateException("Could not copy recording chunk " + p + " to new file. " + ioe.getMessage());
- }
- }
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SplitCommand.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-final class SplitCommand extends Command {
-
- @Override
- public String getOptionSyntax() {
- return "[--maxchunks <chunks>] <file>";
- }
-
- @Override
- public void displayOptionUsage() {
- println(" --maxchunks <chunks> Maximum number of chunks per splitted file (default 5).");
- println(" The chunk size varies, but is typically around 15 MB.");
- println();
- println(" <file> Location of recording file (.jfr) to split");
- }
-
- @Override
- public String getName() {
- return "split";
- }
-
- @Override
- public String getDescription() {
- return "Splits a recording file into smaller files";
- }
-
- @Override
- public void execute(Deque<String> options) {
- if (options.isEmpty()) {
- userFailed("Missing file");
- }
- ensureMaxArgumentCount(options, 3);
- Path file = Paths.get(options.removeLast());
- ensureFileExist(file);
- ensureJFRFile(file);
- int maxchunks = 5;
- if (!options.isEmpty()) {
- String option = options.pop();
- if (!"--maxchunks".equals(option)) {
- userFailed("Unknown option " + option);
- }
- if (options.isEmpty()) {
- userFailed("Missing value for --maxChunks");
- }
- String value = options.pop();
- try {
- maxchunks = Integer.parseInt(value);
- if (maxchunks < 1) {
- userFailed("Must be at least one chunk per file.");
- }
- } catch (NumberFormatException nfe) {
- userFailed("Not a valid value for --maxchunks.");
- }
- }
- ensureMaxArgumentCount(options, 0);
- println();
- println("Examining recording " + file + " ...");
- List<Long> sizes;
-
- try {
- sizes = findChunkSizes(file);
- } catch (IOException e) {
- throw new IllegalStateException("Unexpected error. " + e.getMessage());
- }
- if (sizes.size() <= maxchunks) {
- throw new IllegalStateException("Number of chunks in recording (" + sizes.size() + ") doesn't exceed max chunks (" + maxchunks + ")");
- }
- println();
-
- println();
- if (sizes.size() > 0) {
- print("File consists of " + sizes.size() + " chunks. The recording will be split into ");
- sizes = combineChunkSizes(sizes, maxchunks);
- println(sizes.size() + " files with at most " + maxchunks + " chunks per file.");
- println();
-
- try {
- splitFile(file, sizes);
- } catch (IOException e) {
- throw new IllegalStateException("Unexpected error. " + e.getMessage());
- }
- } else {
- println("No JFR chunks found in file. ");
- }
- }
-
- private List<Long> findChunkSizes(Path p) throws IOException {
- try (RecordingInput input = new RecordingInput(p.toFile())) {
- List<Long> sizes = new ArrayList<>();
- ChunkHeader ch = new ChunkHeader(input);
- sizes.add(ch.getSize());
- while (!ch.isLastChunk()) {
- ch = ch.nextHeader();
- sizes.add(ch.getSize());
- }
- return sizes;
- }
- }
-
- private List<Long> combineChunkSizes(List<Long> sizes, int chunksPerFile) {
- List<Long> reduced = new ArrayList<Long>();
- long size = sizes.get(0);
- for (int n = 1; n < sizes.size(); n++) {
- if (n % chunksPerFile == 0) {
- reduced.add(size);
- size = 0;
- }
- size += sizes.get(n);
- }
- reduced.add(size);
- return reduced;
- }
-
- private void splitFile(Path file, List<Long> splitPositions) throws IOException {
-
- int padAmountZeros = String.valueOf(splitPositions.size() - 1).length();
- String fileName = file.toString();
- String fileFormatter = fileName.subSequence(0, fileName.length() - 4) + "_%0" + padAmountZeros + "d.jfr";
- for (int i = 0; i < splitPositions.size(); i++) {
- Path p = Paths.get(String.format(fileFormatter, i));
- if (Files.exists(p)) {
- throw new IllegalStateException("Can't create split file " + p + ", a file with that name already exist");
- }
- }
- DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file.toFile())));
-
- for (int i = 0; i < splitPositions.size(); i++) {
- Long l = splitPositions.get(i);
- byte[] bytes = readBytes(stream, l.intValue());
- Path p = Paths.get(String.format(fileFormatter, i));
- File splittedFile = p.toFile();
- println("Writing " + splittedFile + " ...");
- FileOutputStream fos = new FileOutputStream(splittedFile);
- fos.write(bytes);
- fos.close();
- }
- stream.close();
- }
-
- private byte[] readBytes(InputStream stream, int count) throws IOException {
- byte[] data = new byte[count];
- int totalRead = 0;
- while (totalRead < data.length) {
- int read = stream.read(data, totalRead, data.length - totalRead);
- if (read == -1) {
- throw new IOException("Unexpected end of data.");
- }
- totalRead += read;
- }
- return data;
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/StructuredWriter.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.PrintWriter;
-
-abstract class StructuredWriter {
- private final static String LINE_SEPARATOR = String.format("%n");
-
- private final PrintWriter out;
- private final StringBuilder builder = new StringBuilder(4000);
-
- private char[] indentionArray = new char[0];
- private int indent = 0;
- private int column;
-
- StructuredWriter(PrintWriter p) {
- out = p;
- }
-
- final protected int getColumn() {
- return column;
- }
-
- // Flush to print writer
- public final void flush() {
- out.print(builder.toString());
- builder.setLength(0);
- }
-
- final public void printIndent() {
- builder.append(indentionArray, 0, indent);
- column += indent;
- }
-
- final public void println() {
- builder.append(LINE_SEPARATOR);
- column = 0;
- }
-
- final public void print(String... texts) {
- for (String text : texts) {
- print(text);
- }
- }
-
- final public void printAsString(Object o) {
- print(String.valueOf(o));
- }
-
- final public void print(String text) {
- builder.append(text);
- column += text.length();
- }
-
- final public void print(char c) {
- builder.append(c);
- column++;
- }
-
- final public void print(int value) {
- print(String.valueOf(value));
- }
-
- final public void indent() {
- indent += 2;
- updateIndent();
- }
-
- final public void retract() {
- indent -= 2;
- updateIndent();
- }
-
- final public void println(String text) {
- print(text);
- println();
- }
-
- private void updateIndent() {
- if (indent > indentionArray.length) {
- indentionArray = new char[indent];
- for (int i = 0; i < indentionArray.length; i++) {
- indentionArray[i] = ' ';
- }
- }
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SummaryCommand.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-
-import jdk.jfr.EventType;
-import jdk.jfr.internal.MetadataDescriptor;
-import jdk.jfr.internal.Type;
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-final class SummaryCommand extends Command {
-
- private static class Statistics {
- Statistics(String name) {
- this.name = name;
- }
-
- String name;
- long count;
- long size;
- }
-
- @Override
- public String getOptionSyntax() {
- return "<file>";
- }
-
- @Override
- public void displayOptionUsage() {
- println(" <file> Location of the recording file (.jfr) to display information about");
- }
-
- @Override
- public String getName() {
- return "summary";
- }
-
- @Override
- public String getDescription() {
- return "Display general information about a recording file (.jfr)";
- }
-
- @Override
- public void execute(Deque<String> options) {
- if (options.isEmpty()) {
- userFailed("Missing file");
- }
- ensureMaxArgumentCount(options, 1);
- Path p = Paths.get(options.remove());
- ensureFileExist(p);
- ensureJFRFile(p);
- try {
- printInformation(p);
- } catch (IOException e) {
- throw new IllegalStateException("Unexpected error. " + e.getMessage());
- }
- }
-
- private void printInformation(Path p) throws IOException {
- long totalSize = 0;
- long totalDuration = 0;
- long chunks = 0;
-
- try (RecordingInput input = new RecordingInput(p.toFile())) {
- ChunkHeader first = new ChunkHeader(input);
- ChunkHeader ch = first;
- String eventPrefix = Type.EVENT_NAME_PREFIX;
- if (first.getMajor() == 1) {
- eventPrefix = "com.oracle.jdk.";
- }
- HashMap<Long, Statistics> stats = new HashMap<>();
- stats.put(0L, new Statistics(eventPrefix + "Metadata"));
- stats.put(1L, new Statistics(eventPrefix + "CheckPoint"));
- int minWidth = 0;
- while (true) {
- long chunkEnd = ch.getEnd();
- MetadataDescriptor md = ch.readMetadata();
-
- for (EventType eventType : md.getEventTypes()) {
- stats.computeIfAbsent(eventType.getId(), (e) -> new Statistics(eventType.getName()));
- minWidth = Math.max(minWidth, eventType.getName().length());
- }
-
- totalSize += ch.getSize();
- totalDuration += ch.getDuration();
- chunks++;
- input.position(ch.getEventStart());
- while (input.position() < chunkEnd) {
-
- long pos = input.position();
- int size = input.readInt();
- long eventTypeId = input.readLong();
- Statistics s = stats.get(eventTypeId);
-
- if (s != null) {
- s.count++;
- s.size += size;
- }
- input.position(pos + size);
- }
- if (ch.isLastChunk()) {
- break;
- }
- ch = ch.nextHeader();
- }
- println();
- long epochSeconds = first.getStartNanos() / 1_000_000_000L;
- long adjustNanos = first.getStartNanos() - epochSeconds * 1_000_000_000L;
- println(" Version: " + first.getMajor() + "." + first.getMinor());
- println(" Chunks: " + chunks);
- println(" Size: " + totalSize + " bytes");
- println(" Start: " + Instant.ofEpochSecond(epochSeconds, adjustNanos));
- println(" Duration: " + Duration.ofNanos(totalDuration));
- println();
- println(" Start Ticks: " + first.getStartTicks());
- println(" Ticks / Second: " + first.getTicksPerSecond());
-
- List<Statistics> statsList = new ArrayList<>(stats.values());
- Collections.sort(statsList, (u, v) -> Long.compare(v.count, u.count));
- println();
- String header = " Count Size (bytes) ";
- String typeHeader = " Event Type";
- minWidth = Math.max(minWidth, typeHeader.length());
- println(typeHeader + pad(minWidth - typeHeader.length(), ' ') + header);
- println(pad(minWidth + header.length(), '='));
- for (Statistics s : statsList) {
- System.out.printf(" %-" + minWidth + "s%10d %12d\n", s.name, s.count, s.size);
- }
- }
- }
-
- private String pad(int count, char c) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < count; i++) {
- sb.append(c);
- }
- return sb.toString();
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/XMLWriter.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-
-final class XMLWriter extends StructuredWriter {
-
- public XMLWriter(PrintWriter destination) {
- super(destination);
- }
-
- public void print(Path source) throws IOException {
- try (RecordingFile es = new RecordingFile(source)) {
- println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- println("<recording>");
- indent();
- printIndent();
- println("<events>");
- indent();
- while (es.hasMoreEvents()) {
- printEvent(es.readEvent());
- flush();
- }
- retract();
- printIndent();
- println("</events>");
- retract();
- println("</recording>");
- flush();
- }
- }
-
- private void printEvent(RecordedEvent e) throws IOException {
- EventType type = e.getEventType();
- printIndent();
- print("<event");
- printAttribute("typeId", String.valueOf(type.getId()));
- printAttribute("name", type.getName());
- printAttribute("startTime",e.getStartTime().toString());
- printAttribute("duration", e.getDuration().toString());
- print(">");
- printObject(e);
- printIndent();
- println("</event>");
- println();
- }
-
- private void printAttribute(String name, String value) {
- print(" ", name, "=\"", value, "\"");
- }
-
- public void printObject(RecordedObject struct) {
- println();
- indent();
- for (ValueDescriptor v : struct.getFields()) {
- printValueDescriptor(v, struct.getValue(v.getName()), -1);
- }
- retract();
- }
-
- private void printArray(ValueDescriptor v, Object[] array) {
- println();
- indent();
- for (int index = 0; index < array.length; index++) {
- printValueDescriptor(v, array[index], index);
- }
- retract();
- }
-
- private void printValueDescriptor(ValueDescriptor vd, Object value, int index) {
- boolean arrayElement = index != -1;
- String name = arrayElement ? null : vd.getName();
- if (vd.isArray() && !arrayElement) {
- if (printBeginElement("array", name, value, index)) {
- printArray(vd, (Object[]) value);
- printIndent();
- printEndElement("array");
- }
- return;
- }
- if (!vd.getFields().isEmpty()) {
- if (printBeginElement("struct", name, value, index)) {
- printObject((RecordedObject) value);
- printIndent();
- printEndElement("struct");
- }
- return;
- }
- if (printBeginElement("value", name, value, index)) {
- printEscaped(String.valueOf(value));
- printEndElement("value");
- }
- }
-
- private boolean printBeginElement(String elementName, String name, Object value, int index) {
- printIndent();
- print("<", elementName);
- if (name != null) {
- printAttribute("name", name);
- }
- if (index != -1) {
- printAttribute("index", Integer.toString(index));
- }
- if (value == null) {
- print("><null/></");
- print(elementName);
- println(">");
- return false;
- }
- if (value.getClass().isArray()) {
- Object[] array = (Object[]) value;
- printAttribute("size", Integer.toString(array.length));
- }
- print(">");
- return true;
- }
-
- private void printEndElement(String elementName) {
- print("</");
- print(elementName);
- println(">");
- }
-
- private void printEscaped(String text) {
- for (int i = 0; i < text.length(); i++) {
- printEscaped(text.charAt(i));
- }
- }
-
- private void printEscaped(char c) {
- if (c == 34) {
- print(""");
- return;
- }
- if (c == 38) {
- print("&");
- return;
- }
- if (c == 39) {
- print("'");
- return;
- }
- if (c == 60) {
- print("<");
- return;
- }
- if (c == 62) {
- print(">");
- return;
- }
- if (c > 0x7F) {
- print("&#");
- print((int) c);
- print(';');
- return;
- }
- print(c);
- }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/ChunkHeader.java Wed Dec 05 17:05:42 2018 -0500
@@ -161,7 +161,7 @@
return chunkSize;
}
- public long getDuration() {
+ public long getDurationNanos() {
return durationNanos;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInternals.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jfr.internal.consumer;
+
+import java.io.IOException;
+import java.util.List;
+
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.jfr.internal.Type;
+
+public abstract class RecordingInternals {
+
+ public static RecordingInternals INSTANCE;
+
+ public abstract boolean isLastEventInChunk(RecordingFile file);
+
+ public abstract Object getOffsetDataTime(RecordedObject event, String name);
+
+ public abstract List<Type> readTypes(RecordingFile file) throws IOException;
+
+ public abstract void sort(List<RecordedEvent> events);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Assemble.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.channels.FileChannel;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+
+final class Assemble extends Command {
+
+ @Override
+ public String getName() {
+ return "assemble";
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ return Collections.singletonList("<repository> <file>");
+ }
+
+ @Override
+ public String getDescription() {
+ return "Assemble leftover chunks from a disk repository into a recording file";
+ }
+
+ @Override
+ public void displayOptionUsage(PrintStream stream) {
+ stream.println(" <repository> Directory where the repository is located");
+ stream.println();
+ stream.println(" <file> Name of the recording file (.jfr) to create");
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ ensureMinArgumentCount(options, 2);
+ ensureMaxArgumentCount(options, 2);
+ Path repository = getDirectory(options.pop());
+
+ Path file = Paths.get(options.pop());
+ ensureFileDoesNotExist(file);
+ ensureJFRFile(file);
+
+ try (FileOutputStream fos = new FileOutputStream(file.toFile())) {
+ List<Path> files = listJFRFiles(repository);
+ if (files.isEmpty()) {
+ throw new UserDataException("no *.jfr files found at " + repository);
+ }
+ println();
+ println("Assembling files... ");
+ println();
+ transferTo(files, file, fos.getChannel());
+ println();
+ println("Finished.");
+ } catch (IOException e) {
+ throw new UserDataException("could not open destination file " + file + ". " + e.getMessage());
+ }
+ }
+
+ private List<Path> listJFRFiles(Path path) throws UserDataException {
+ try {
+ List<Path> files = new ArrayList<>();
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.jfr")) {
+ for (Path p : stream) {
+ if (!Files.isDirectory(p) && Files.isReadable(p)) {
+ files.add(p);
+ }
+ }
+ }
+ }
+ files.sort((u, v) -> u.getFileName().compareTo(v.getFileName()));
+ return files;
+ } catch (IOException ioe) {
+ throw new UserDataException("could not list *.jfr for directory " + path + ". " + ioe.getMessage());
+ }
+ }
+
+ private void transferTo(List<Path> sourceFiles, Path output, FileChannel out) throws UserDataException {
+ long pos = 0;
+ for (Path p : sourceFiles) {
+ println(" " + p.toString());
+ try (FileChannel sourceChannel = FileChannel.open(p)) {
+ long rem = Files.size(p);
+ while (rem > 0) {
+ long n = Math.min(rem, 1024 * 1024);
+ long w = out.transferFrom(sourceChannel, pos, n);
+ pos += w;
+ rem -= w;
+ }
+ } catch (IOException ioe) {
+ throw new UserDataException("could not copy recording chunk " + p + " to new file. " + ioe.getMessage());
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Command.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOError;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+
+abstract class Command {
+ public final static String title = "Tool for working with Flight Recorder files (.jfr)";
+ private final static Command HELP = new Help();
+ private final static List<Command> COMMANDS = createCommands();
+
+ private static List<Command> createCommands() {
+ List<Command> commands = new ArrayList<>();
+ commands.add(new Print());
+ commands.add(new Metadata());
+ commands.add(new Summary());
+ commands.add(new Assemble());
+ commands.add(new Disassemble());
+ commands.add(new Version());
+ commands.add(HELP);
+ return Collections.unmodifiableList(commands);
+ }
+
+ static void displayHelp() {
+ System.out.println(title);
+ System.out.println();
+ displayAvailableCommands(System.out);
+ }
+
+ abstract public String getName();
+
+ abstract public String getDescription();
+
+ abstract public void execute(Deque<String> argList) throws UserSyntaxException, UserDataException;
+
+ protected String getTitle() {
+ return getDescription();
+ }
+
+ static void displayAvailableCommands(PrintStream stream) {
+ boolean first = true;
+ for (Command c : Command.COMMANDS) {
+ if (!first) {
+ System.out.println();
+ }
+ displayCommand(stream, c);
+ stream.println(" " + c.getDescription());
+ first = false;
+ }
+ }
+
+ protected static void displayCommand(PrintStream stream, Command c) {
+ boolean firstSyntax = true;
+ String alias = buildAlias(c);
+ String initial = " jfr " + c.getName();
+ for (String syntaxLine : c.getOptionSyntax()) {
+ if (firstSyntax) {
+ if (syntaxLine.length() != 0) {
+ stream.println(initial + " " + syntaxLine + alias);
+ } else {
+ stream.println(initial + alias);
+ }
+ } else {
+ for (int i = 0; i < initial.length(); i++) {
+ stream.print(" ");
+ }
+ stream.println(" " + syntaxLine);
+ }
+ firstSyntax = false;
+ }
+ }
+
+ private static String buildAlias(Command c) {
+ List<String> aliases = c.getAliases();
+ if (aliases.isEmpty()) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ if (aliases.size() == 1) {
+ sb.append(" (alias ");
+ sb.append(aliases.get(0));
+ sb.append(")");
+ return sb.toString();
+ }
+ sb.append(" (aliases ");
+ for (int i = 0; i< aliases.size(); i ++ ) {
+ sb.append(aliases.get(i));
+ if (i < aliases.size() -1) {
+ sb.append(", ");
+ }
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public static List<Command> getCommands() {
+ return COMMANDS;
+ }
+
+ public static Command valueOf(String commandName) {
+ for (Command command : COMMANDS) {
+ if (command.getName().equals(commandName)) {
+ return command;
+ }
+ }
+ return null;
+ }
+
+ public List<String> getOptionSyntax() {
+ return Collections.singletonList("");
+ }
+
+ public void displayOptionUsage(PrintStream stream) {
+ }
+
+ protected boolean acceptOption(Deque<String> options, String expected) throws UserSyntaxException {
+ if (expected.equals(options.peek())) {
+ if (options.size() < 2) {
+ throw new UserSyntaxException("missing value for " + options.peek());
+ }
+ options.remove();
+ return true;
+ }
+ return false;
+ }
+
+ protected void warnForWildcardExpansion(String option, String filter) throws UserDataException {
+ // Users should quote their wildcards to avoid expansion by the shell
+ try {
+ if (!filter.contains(File.pathSeparator)) {
+ Path p = Path.of(".", filter);
+ if (!Files.exists(p)) {
+ return;
+ }
+ }
+ throw new UserDataException("wildcards should be quoted, for example " + option + " \"Foo*\"");
+ } catch (InvalidPathException ipe) {
+ // ignore
+ }
+ }
+
+ protected boolean acceptFilterOption(Deque<String> options, String expected) throws UserSyntaxException {
+ if (!acceptOption(options, expected)) {
+ return false;
+ }
+ if (options.isEmpty()) {
+ throw new UserSyntaxException("missing filter after " + expected);
+ }
+ String filter = options.peek();
+ if (filter.startsWith("--")) {
+ throw new UserSyntaxException("missing filter after " + expected);
+ }
+ return true;
+ }
+
+ final protected void ensureMaxArgumentCount(Deque<String> options, int maxCount) throws UserSyntaxException {
+ if (options.size() > maxCount) {
+ throw new UserSyntaxException("too many arguments");
+ }
+ }
+
+ final protected void ensureMinArgumentCount(Deque<String> options, int minCount) throws UserSyntaxException {
+ if (options.size() < minCount) {
+ throw new UserSyntaxException("too few arguments");
+ }
+ }
+
+ final protected Path getDirectory(String pathText) throws UserDataException {
+ try {
+ Path path = Paths.get(pathText).toAbsolutePath();
+ if (!Files.exists((path))) {
+ throw new UserDataException("directory does not exist, " + pathText);
+ }
+ if (!Files.isDirectory(path)) {
+ throw new UserDataException("path must be directory, " + pathText);
+ }
+ return path;
+ } catch (InvalidPathException ipe) {
+ throw new UserDataException("invalid path '" + pathText + "'");
+ }
+ }
+
+ final protected Path getJFRInputFile(Deque<String> options) throws UserSyntaxException, UserDataException {
+ if (options.isEmpty()) {
+ throw new UserSyntaxException("missing file");
+ }
+ String file = options.removeLast();
+ if (file.startsWith("--")) {
+ throw new UserSyntaxException("missing file");
+ }
+ try {
+ Path path = Paths.get(file).toAbsolutePath();
+ ensureAccess(path);
+ ensureJFRFile(path);
+ return path;
+ } catch (IOError ioe) {
+ throw new UserDataException("i/o error reading file '" + file + "', " + ioe.getMessage());
+ } catch (InvalidPathException ipe) {
+ throw new UserDataException("invalid path '" + file + "'");
+ }
+ }
+
+ private void ensureAccess(Path path) throws UserDataException {
+ try (RandomAccessFile rad = new RandomAccessFile(path.toFile(), "r")) {
+ if (rad.length() == 0) {
+ throw new UserDataException("file is empty '" + path + "'");
+ }
+ rad.read(); // try to read 1 byte
+ } catch (FileNotFoundException e) {
+ throw new UserDataException("could not find file '" + path + "'");
+ } catch (IOException e) {
+ throw new UserDataException("i/o error reading file '" + path + "', " + e.getMessage());
+ }
+ }
+
+ final protected void couldNotReadError(Path p, IOException e) throws UserDataException {
+ throw new UserDataException("could not read recording at " + p.toAbsolutePath() + ". " + e.getMessage());
+ }
+
+ final protected Path ensureFileDoesNotExist(Path file) throws UserDataException {
+ if (Files.exists(file)) {
+ throw new UserDataException("file '" + file + "' already exists");
+ }
+ return file;
+ }
+
+ final protected void ensureJFRFile(Path path) throws UserDataException {
+ if (!path.toString().endsWith(".jfr")) {
+ throw new UserDataException("filename must end with '.jfr'");
+ }
+ }
+
+ protected void displayUsage(PrintStream stream) {
+ displayCommand(stream, this);
+ stream.println();
+ displayOptionUsage(stream);
+ }
+
+ final protected void println() {
+ System.out.println();
+ }
+
+ final protected void print(String text) {
+ System.out.print(text);
+ }
+
+ final protected void println(String text) {
+ System.out.println(text);
+ }
+
+ final protected boolean matches(String command) {
+ for (String s : getNames()) {
+ if (s.equals(command)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected List<String> getAliases() {
+ return Collections.emptyList();
+ }
+
+ public List<String> getNames() {
+ List<String> names = new ArrayList<>();
+ names.add(getName());
+ names.addAll(getAliases());
+ return names;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.List;
+
+import jdk.jfr.internal.consumer.ChunkHeader;
+import jdk.jfr.internal.consumer.RecordingInput;
+
+final class Disassemble extends Command {
+
+ @Override
+ public String getName() {
+ return "disassemble";
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ List<String> list = new ArrayList<>();
+ list.add("[--output <directory>]");
+ list.add("[--max-chunks <chunks>]");
+ list.add("[--max-size <size>]");
+ list.add("<file>");
+ return list;
+ }
+
+ @Override
+ public void displayOptionUsage(PrintStream stream) {
+ stream.println(" --output <directory> The location to write the disassembled file,");
+ stream.println(" by default the current directory");
+ stream.println("");
+ stream.println(" --max-chunks <chunks> Maximum number of chunks per disassembled file,");
+ stream.println(" by default 5. The chunk size varies, but is ");
+ stream.println(" typically around 15 MB.");
+ stream.println("");
+ stream.println(" --max-size <size> Maximum number of bytes per file.");
+ stream.println("");
+ stream.println(" <file> Location of the recording file (.jfr)");
+ }
+
+ @Override
+ public String getDescription() {
+ return "Disassamble a recording file into smaller files/chunks";
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ if (options.isEmpty()) {
+ throw new UserSyntaxException("missing file");
+ }
+ Path file = getJFRInputFile(options);
+ int maxChunks = Integer.MAX_VALUE;
+ int maxsize = Integer.MAX_VALUE;
+ String output = System.getProperty("user.dir");
+ int optionCount = options.size();
+ while (optionCount > 0) {
+ if (acceptOption(options, "--output")) {
+ output = options.pop();
+ }
+ if (acceptOption(options, "--max-size")) {
+ String value = options.pop();
+ try {
+ maxsize = Integer.parseInt(value);
+ if (maxsize < 1) {
+ throw new UserDataException("max size must be at least 1");
+ }
+ } catch (NumberFormatException nfe) {
+ throw new UserDataException("not a valid value for --max-size.");
+ }
+ }
+ if (acceptOption(options, "--max-chunks")) {
+ String value = options.pop();
+ try {
+ maxChunks = Integer.parseInt(value);
+ if (maxChunks < 1) {
+ throw new UserDataException("max chunks must be at least 1.");
+ }
+ } catch (NumberFormatException nfe) {
+ throw new UserDataException("not a valid value for --max-size.");
+ }
+ }
+ if (optionCount == options.size()) {
+ // No progress made
+ throw new UserSyntaxException("unknown option " + options.peek());
+ }
+ optionCount = options.size();
+ }
+ Path outputPath = getDirectory(output);
+
+ println();
+ println("Examining recording " + file + " ...");
+ List<Long> sizes;
+ if (maxsize != Integer.MAX_VALUE && maxChunks == Integer.MAX_VALUE) {
+ try {
+ long fileSize = Files.size(file);
+ if (maxsize >=fileSize) {
+ println();
+ println("File size (" + fileSize +") does not exceed max size (" + maxsize + ")");
+ return;
+ }
+ } catch (IOException e) {
+ throw new UserDataException("unexpected i/o error when determining file size" + e.getMessage());
+ }
+ }
+ if (maxsize == Integer.MAX_VALUE && maxChunks == Integer.MAX_VALUE) {
+ maxChunks = 5;
+ }
+
+ try {
+ sizes = findChunkSizes(file);
+ } catch (IOException e) {
+ throw new UserDataException("unexpected i/o error. " + e.getMessage());
+ }
+ if (maxsize == Integer.MAX_VALUE == sizes.size() <= maxChunks) {
+ throw new UserDataException("number of chunks in recording (" + sizes.size() + ") doesn't exceed max chunks (" + maxChunks + ")");
+ }
+ println();
+ if (sizes.size() > 0) {
+ List<Long> combinedSizes = combineChunkSizes(sizes, maxChunks, maxsize);
+ print("File consists of " + sizes.size() + " chunks. The recording will be split into ");
+ println(combinedSizes.size() + " files");
+ println();
+ splitFile(outputPath, file, combinedSizes);
+ } else {
+ throw new UserDataException("no JFR chunks found in file.");
+ }
+ }
+
+ private List<Long> findChunkSizes(Path p) throws IOException {
+ try (RecordingInput input = new RecordingInput(p.toFile())) {
+ List<Long> sizes = new ArrayList<>();
+ ChunkHeader ch = new ChunkHeader(input);
+ sizes.add(ch.getSize());
+ while (!ch.isLastChunk()) {
+ ch = ch.nextHeader();
+ sizes.add(ch.getSize());
+ }
+ return sizes;
+ }
+ }
+
+ private List<Long> combineChunkSizes(List<Long> sizes, int maxChunks, long maxSize) {
+ List<Long> reduced = new ArrayList<Long>();
+ int chunks = 1;
+ long fileSize = sizes.get(0);
+ for (int i = 1; i < sizes.size(); i++) {
+ long size = sizes.get(i);
+ if (fileSize + size > maxSize) {
+ reduced.add(fileSize);
+ chunks = 1;
+ fileSize = size;
+ continue;
+ }
+ fileSize += size;
+ if (chunks == maxChunks) {
+ reduced.add(fileSize);
+ fileSize = 0;
+ chunks = 1;
+ continue;
+ }
+ chunks++;
+ }
+ if (fileSize != 0) {
+ reduced.add(fileSize);
+ }
+ return reduced;
+ }
+
+ private void splitFile(Path directory, Path file, List<Long> splitPositions) throws UserDataException {
+ int padAmountZeros = String.valueOf(splitPositions.size() - 1).length();
+ String fileName = file.getFileName().toString();
+ String fileFormatter = fileName.subSequence(0, fileName.length() - 4) + "_%0" + padAmountZeros + "d.jfr";
+ for (int i = 0; i < splitPositions.size(); i++) {
+ String formattedFilename = String.format(fileFormatter, i);
+ try {
+ Path p = directory.resolve(formattedFilename);
+ if (Files.exists(p)) {
+ throw new UserDataException("can't create disassembled file " + p + ", a file with that name already exist");
+ }
+ } catch (InvalidPathException ipe) {
+ throw new UserDataException("can't construct path with filename" + formattedFilename);
+ }
+ }
+
+ try (DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file.toFile())))) {
+ for (int i = 0; i < splitPositions.size(); i++) {
+ Long l = splitPositions.get(i);
+ byte[] bytes = readBytes(stream, l.intValue());
+ String formattedFilename = String.format(fileFormatter, i);
+ Path p = directory.resolve(formattedFilename);
+ File splittedFile = p.toFile();
+ println("Writing " + splittedFile + " ... " + bytes.length);
+ FileOutputStream fos = new FileOutputStream(splittedFile);
+ fos.write(bytes);
+ fos.close();
+ }
+ } catch (IOException ioe) {
+ throw new UserDataException("i/o error writing file " + file);
+ }
+ }
+
+ private byte[] readBytes(InputStream stream, int count) throws UserDataException, IOException {
+ byte[] data = new byte[count];
+ int totalRead = 0;
+ while (totalRead < data.length) {
+ int read = stream.read(data, totalRead, data.length - totalRead);
+ if (read == -1) {
+ throw new UserDataException("unexpected end of data");
+ }
+ totalRead += read;
+ }
+ return data;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/EventPrintWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+import jdk.jfr.EventType;
+import jdk.jfr.Timespan;
+import jdk.jfr.Timestamp;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.jfr.internal.consumer.RecordingInternals;
+
+abstract class EventPrintWriter extends StructuredWriter {
+
+ enum ValueType {
+ TIMESPAN, TIMESTAMP, OTHER
+ }
+
+ protected static final String STACK_TRACE_FIELD = "stackTrace";
+ protected static final String EVENT_THREAD_FIELD = "eventThread";
+
+ private Predicate<EventType> eventFilter = x -> true;
+ private int stackDepth;
+
+ // cach that will speed up annotation lookup
+ private Map<ValueDescriptor, ValueType> typeOfValues = new HashMap<>();
+
+ EventPrintWriter(PrintWriter p) {
+ super(p);
+ }
+
+ abstract protected void print(List<RecordedEvent> events);
+
+ void print(Path source) throws FileNotFoundException, IOException {
+ List<RecordedEvent> events = new ArrayList<>(500_000);
+ printBegin();
+ try (RecordingFile file = new RecordingFile(source)) {
+ while (file.hasMoreEvents()) {
+ RecordedEvent event = file.readEvent();
+ if (acceptEvent(event)) {
+ events.add(event);
+ }
+ if (RecordingInternals.INSTANCE.isLastEventInChunk(file)) {
+ RecordingInternals.INSTANCE.sort(events);
+ print(events);
+ events.clear();
+ }
+ }
+ }
+ printEnd();
+ flush(true);
+ }
+
+ protected void printEnd() {
+ }
+
+ protected void printBegin() {
+ }
+
+ public final void setEventFilter(Predicate<EventType> eventFilter) {
+ this.eventFilter = eventFilter;
+ }
+
+ protected final boolean acceptEvent(RecordedEvent event) {
+ return eventFilter.test(event.getEventType());
+ }
+
+ protected final int getStackDepth() {
+ return stackDepth;
+ }
+
+ protected final boolean isLateField(String name) {
+ return name.equals(EVENT_THREAD_FIELD) || name.equals(STACK_TRACE_FIELD);
+ }
+
+ public void setStackDepth(int stackDepth) {
+ this.stackDepth = stackDepth;
+ }
+
+ protected Object getValue(RecordedObject object, ValueDescriptor v) {
+ ValueType valueType = typeOfValues.get(v);
+ if (valueType == null) {
+ valueType = determineValueType(v);
+ typeOfValues.put(v, valueType);
+ }
+ switch (valueType) {
+ case TIMESPAN:
+ return object.getDuration(v.getName());
+ case TIMESTAMP:
+ return RecordingInternals.INSTANCE.getOffsetDataTime(object, v.getName());
+ default:
+ return object.getValue(v.getName());
+ }
+ }
+ // It's expensive t check
+ private ValueType determineValueType(ValueDescriptor v) {
+ if (v.getAnnotation(Timespan.class) != null) {
+ return ValueType.TIMESPAN;
+ }
+ if (v.getAnnotation(Timestamp.class) != null) {
+ return ValueType.TIMESTAMP;
+ }
+ return ValueType.OTHER;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Help.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.List;
+
+final class Help extends Command {
+
+ @Override
+ public String getName() {
+ return "help";
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ return Collections.singletonList("[<command>]");
+ }
+
+ protected List<String> getAliases() {
+ return List.of("--help", "-h", "-?");
+ }
+
+ @Override
+ public void displayOptionUsage(PrintStream stream) {
+ println(" <command> The name of the command to get help for");
+ }
+
+ @Override
+ public String getDescription() {
+ return "Display all available commands, or help about a specific command";
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ if (options.isEmpty()) {
+ Command.displayHelp();
+ return;
+ }
+ ensureMaxArgumentCount(options, 1);
+ String commandName = options.remove();
+ Command c = Command.valueOf(commandName);
+ if (c == null) {
+ throw new UserDataException("unknown command '" + commandName + "'");
+ }
+ println(c.getTitle());
+ println();
+ c.displayUsage(System.out);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/JSONWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+import jdk.jfr.EventType;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedFrame;
+import jdk.jfr.consumer.RecordedObject;
+
+final class JSONWriter extends EventPrintWriter {
+
+ private boolean first = true;
+
+ public JSONWriter(PrintWriter writer) {
+ super(writer);
+ }
+
+ @Override
+ protected void printBegin() {
+ printObjectBegin();
+ printDataStructureName("recording");
+ printObjectBegin();
+ printDataStructureName("events");
+ printArrayBegin();
+ }
+
+ @Override
+ protected void print(List<RecordedEvent> events) {
+ for (RecordedEvent event : events) {
+ printNewDataStructure(first, true, null);
+ printEvent(event);
+ flush(false);
+ first = false;
+ }
+ }
+
+ @Override
+ protected void printEnd() {
+ printArrayEnd();;
+ printObjectEnd();
+ printObjectEnd();
+ }
+
+ private void printEvent(RecordedEvent event) {
+ printObjectBegin();
+ EventType type = event.getEventType();
+ printValue(true, false, "type", type.getName());
+ printNewDataStructure(false, false, "values");
+ printObjectBegin();
+ boolean first = true;
+ for (ValueDescriptor v : event.getFields()) {
+ printValueDescriptor(first, false, v, getValue(event, v));
+ first = false;
+ }
+ printObjectEnd();
+ printObjectEnd();
+ }
+
+ void printValue(boolean first, boolean arrayElement, String name, Object value) {
+ printNewDataStructure(first, arrayElement, name);
+ if (!printIfNull(value)) {
+ if (value instanceof Boolean) {
+ printAsString(value);
+ return;
+ }
+ if (value instanceof Double) {
+ Double dValue = (Double) value;
+ if (Double.isNaN(dValue) || Double.isInfinite(dValue)) {
+ printNull();
+ return;
+ }
+ printAsString(value);
+ return;
+ }
+ if (value instanceof Float) {
+ Float fValue = (Float) value;
+ if (Float.isNaN(fValue) || Float.isInfinite(fValue)) {
+ printNull();
+ return;
+ }
+ printAsString(value);
+ return;
+ }
+ if (value instanceof Number) {
+ printAsString(value);
+ return;
+ }
+ print("\"");
+ printEscaped(String.valueOf(value));
+ print("\"");
+ }
+ }
+
+ public void printObject(RecordedObject object) {
+ printObjectBegin();
+ boolean first = true;
+ for (ValueDescriptor v : object.getFields()) {
+ printValueDescriptor(first, false, v, getValue(object, v));
+ first = false;
+ }
+ printObjectEnd();
+ }
+
+ private void printArray(ValueDescriptor v, Object[] array) {
+ printArrayBegin();
+ boolean first = true;
+ int depth = 0;
+ for (Object arrayElement : array) {
+ if (!(arrayElement instanceof RecordedFrame) || depth < getStackDepth()) {
+ printValueDescriptor(first, true, v, arrayElement);
+ }
+ depth++;
+ first = false;
+ }
+ printArrayEnd();
+ }
+
+ private void printValueDescriptor(boolean first, boolean arrayElement, ValueDescriptor vd, Object value) {
+ if (vd.isArray() && !arrayElement) {
+ printNewDataStructure(first, arrayElement, vd.getName());
+ if (!printIfNull(value)) {
+ printArray(vd, (Object[]) value);
+ }
+ return;
+ }
+ if (!vd.getFields().isEmpty()) {
+ printNewDataStructure(first, arrayElement, vd.getName());
+ if (!printIfNull(value)) {
+ printObject((RecordedObject) value);
+ }
+ return;
+ }
+ printValue(first, arrayElement, vd.getName(), value);
+ }
+
+ private void printNewDataStructure(boolean first, boolean arrayElement, String name) {
+ if (!first) {
+ print(", ");
+ if (!arrayElement) {
+ println();
+ }
+ }
+ if (!arrayElement) {
+ printDataStructureName(name);
+ }
+ }
+
+ private boolean printIfNull(Object value) {
+ if (value == null) {
+ printNull();
+ return true;
+ }
+ return false;
+ }
+
+ private void printNull() {
+ print("null");
+ }
+
+ private void printDataStructureName(String text) {
+ printIndent();
+ print("\"");
+ print(text);
+ print("\": ");
+ }
+
+ private void printObjectEnd() {
+ retract();
+ println();
+ printIndent();
+ print("}");
+ }
+
+ private void printObjectBegin() {
+ println("{");
+ indent();
+ }
+
+ private void printArrayEnd() {
+ print("]");
+ }
+
+ private void printArrayBegin() {
+ print("[");
+ }
+
+ private void printEscaped(String text) {
+ for (int i = 0; i < text.length(); i++) {
+ printEscaped(text.charAt(i));
+ }
+ }
+
+ private void printEscaped(char c) {
+ if (c == '\b') {
+ print("\\b");
+ return;
+ }
+ if (c == '\n') {
+ print("\\n");
+ return;
+ }
+ if (c == '\t') {
+ print("\\t");
+ return;
+ }
+ if (c == '\f') {
+ print("\\f");
+ return;
+ }
+ if (c == '\r') {
+ print("\\r");
+ return;
+ }
+ if (c == '\"') {
+ print("\\\"");
+ return;
+ }
+ if (c == '\\') {
+ print("\\\\");
+ return;
+ }
+ if (c == '/') {
+ print("\\/");
+ return;
+ }
+ if (c > 0x7F || c < 32) {
+ print("\\u");
+ // 0x10000 will pad with zeros.
+ print(Integer.toHexString(0x10000 + (int) c).substring(1));
+ return;
+ }
+ print(c);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Main.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * Launcher class for the JDK_HOME\bin\jfr tool
+ *
+ */
+public final class Main {
+
+ private static final int EXIT_OK = 0;
+ private static final int EXIT_FAILED = 1;
+ private static final int EXIT_WRONG_ARGUMENTS = 2;
+
+ public static void main(String... args) {
+ Deque<String> argList = new LinkedList<>(Arrays.asList(args));
+ if (argList.isEmpty()) {
+ System.out.println(Command.title);
+ System.out.println();
+ System.out.println("Before using this tool, you must have a recording file.");
+ System.out.println("A file can be created by starting a recording from command line:");
+ System.out.println();
+ System.out.println(" java -XX:StartFlightRecording:filename=recording.jfr,duration=30s ... ");
+ System.out.println();
+ System.out.println("A recording can also be started on already running Java Virtual Machine:");
+ System.out.println();
+ System.out.println(" jcmd (to list available pids)");
+ System.out.println(" jcmd <pid> JFR.start");
+ System.out.println();
+ System.out.println("Recording data can be dumped to file using the JFR.dump command:");
+ System.out.println();
+ System.out.println(" jcmd <pid> JFR.dump filename=recording.jfr");
+ System.out.println();
+ System.out.println("The contents of the recording can then be printed, for example:");
+ System.out.println();
+ System.out.println(" jfr print recording.jfr");
+ System.out.println();
+ System.out.println(" jfr print --events CPULoad,GarbageCollection recording.jfr");
+ System.out.println();
+ System.out.println(" jfr print --json --events CPULoad recording.jfr");
+ System.out.println();
+ System.out.println(" jfr print --categories \"GC,JVM,Java*\" recording.jfr");
+ System.out.println();
+ System.out.println(" jfr print --events \"jdk.*\" --stack-depth 64 recording.jfr");
+ System.out.println();
+ System.out.println(" jfr summary recording.jfr");
+ System.out.println();
+ System.out.println(" jfr metadata recoding.jfr");
+ System.out.println();
+ System.out.println("For more information about available commands, use 'jfr help'");
+ System.exit(EXIT_OK);
+ }
+ String command = argList.remove();
+ for (Command c : Command.getCommands()) {
+ if (c.matches(command)) {
+ try {
+ c.execute(argList);
+ System.exit(EXIT_OK);
+ } catch (UserDataException ude) {
+ System.err.println("jfr " + c.getName() + ": " + ude.getMessage());
+ System.exit(EXIT_FAILED);
+ } catch (UserSyntaxException use) {
+ System.err.println("jfr " + c.getName() + ": " + use.getMessage());
+ System.err.println();
+ System.err.println("Usage:");
+ System.err.println();
+ c.displayUsage(System.err);
+ System.exit(EXIT_WRONG_ARGUMENTS);
+ } catch (Throwable e) {
+ System.err.println("jfr " + c.getName() + ": unexpected internal error, " + e.getMessage());
+ e.printStackTrace();
+ System.exit(EXIT_FAILED);
+ }
+ }
+ }
+ System.err.println("jfr: unknown command '" + command + "'");
+ System.err.println();
+ System.err.println("List of available commands:");
+ System.err.println();
+ Command.displayAvailableCommands(System.err);
+ System.exit(EXIT_WRONG_ARGUMENTS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Metadata.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.List;
+
+import jdk.jfr.consumer.RecordingFile;
+import jdk.jfr.internal.Type;
+import jdk.jfr.internal.consumer.RecordingInternals;
+
+final class Metadata extends Command {
+
+ private static class TypeComparator implements Comparator<Type> {
+
+ @Override
+ public int compare(Type t1, Type t2) {
+ int g1 = groupValue(t1);
+ int g2 = groupValue(t2);
+ if (g1 == g2) {
+ String n1 = t1.getName();
+ String n2 = t2.getName();
+ String package1 = n1.substring(0, n1.lastIndexOf('.') + 1);
+ String package2 = n2.substring(0, n2.lastIndexOf('.') + 1);
+
+ if (package1.equals(package2)) {
+ return n1.compareTo(n2);
+ } else {
+ // Ensure that jdk.* are printed first
+ // This makes it easier to find user defined events at the end.
+ if (Type.SUPER_TYPE_EVENT.equals(t1.getSuperType()) && !package1.equals(package2)) {
+ if (package1.equals("jdk.jfr")) {
+ return -1;
+ }
+ if (package2.equals("jdk.jfr")) {
+ return 1;
+ }
+ }
+ return package1.compareTo(package2);
+ }
+ } else {
+ return Integer.compare(groupValue(t1), groupValue(t2));
+ }
+ }
+
+ int groupValue(Type t) {
+ String superType = t.getSuperType();
+ if (superType == null) {
+ return 1;
+ }
+ if (Type.SUPER_TYPE_ANNOTATION.equals(superType)) {
+ return 3;
+ }
+ if (Type.SUPER_TYPE_SETTING.equals(superType)) {
+ return 4;
+ }
+ if (Type.SUPER_TYPE_EVENT.equals(superType)) {
+ return 5;
+ }
+ return 2; // reserved for enums in the future
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "metadata";
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ return Collections.singletonList("<file>");
+ }
+
+ @Override
+ public String getDescription() {
+ return "Display event metadata, such as labels, descriptions and field layout";
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ Path file = getJFRInputFile(options);
+
+ boolean showIds = false;
+ int optionCount = options.size();
+ while (optionCount > 0) {
+ if (acceptOption(options, "--ids")) {
+ showIds = true;
+ }
+ if (optionCount == options.size()) {
+ // No progress made
+ throw new UserSyntaxException("unknown option " + options.peek());
+ }
+ optionCount = options.size();
+ }
+
+ try (PrintWriter pw = new PrintWriter(System.out)) {
+ PrettyWriter prettyWriter = new PrettyWriter(pw);
+ prettyWriter.setShowIds(showIds);
+ try (RecordingFile rf = new RecordingFile(file)) {
+ List<Type> types = RecordingInternals.INSTANCE.readTypes(rf);
+ Collections.sort(types, new TypeComparator());
+ for (Type type : types) {
+ prettyWriter.printType(type);
+ }
+ prettyWriter.flush(true);
+ } catch (IOException ioe) {
+ couldNotReadError(file, ioe);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,501 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringJoiner;
+
+import jdk.jfr.AnnotationElement;
+import jdk.jfr.DataAmount;
+import jdk.jfr.Frequency;
+import jdk.jfr.MemoryAddress;
+import jdk.jfr.Percentage;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedClass;
+import jdk.jfr.consumer.RecordedClassLoader;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedFrame;
+import jdk.jfr.consumer.RecordedMethod;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordedStackTrace;
+import jdk.jfr.consumer.RecordedThread;
+import jdk.jfr.internal.PrivateAccess;
+import jdk.jfr.internal.Type;
+import jdk.jfr.internal.Utils;
+
+/**
+ * Print events in a human-readable format.
+ *
+ * This class is also used by {@link RecordedObject#toString()}
+ */
+public final class PrettyWriter extends EventPrintWriter {
+ private final static DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
+ private final static Long ZERO = 0L;
+ private boolean showIds;
+
+ public PrettyWriter(PrintWriter destination) {
+ super(destination);
+ }
+
+ @Override
+ protected void print(List<RecordedEvent> events) {
+ for (RecordedEvent e : events) {
+ print(e);
+ flush(false);
+ }
+ }
+
+ public void printType(Type t) {
+ if (showIds) {
+ print("// id: ");
+ println(String.valueOf(t.getId()));
+ }
+ int commentIndex = t.getName().length() + 10;
+ String typeName = t.getName();
+ int index = typeName.lastIndexOf(".");
+ if (index != -1) {
+ println("@Name(\"" + typeName + "\")");
+ }
+ printAnnotations(commentIndex, t.getAnnotationElements());
+ print("class " + typeName.substring(index + 1));
+ String superType = t.getSuperType();
+ if (superType != null) {
+ print(" extends " + superType);
+ }
+ println(" {");
+ indent();
+ boolean first = true;
+ for (ValueDescriptor v : t.getFields()) {
+ printField(commentIndex, v, first);
+ first = false;
+ }
+ retract();
+ println("}");
+ println();
+ }
+
+ private void printField(int commentIndex, ValueDescriptor v, boolean first) {
+ if (!first) {
+ println();
+ }
+ printAnnotations(commentIndex, v.getAnnotationElements());
+ printIndent();
+ Type vType = PrivateAccess.getInstance().getType(v);
+ if (Type.SUPER_TYPE_SETTING.equals(vType.getSuperType())) {
+ print("static ");
+ }
+ print(makeSimpleType(v.getTypeName()));
+ if (v.isArray()) {
+ print("[]");
+ }
+ print(" ");
+ print(v.getName());
+ print(";");
+ printCommentRef(commentIndex, v.getTypeId());
+ }
+
+ private void printCommentRef(int commentIndex, long typeId) {
+ if (showIds) {
+ int column = getColumn();
+ if (column > commentIndex) {
+ print(" ");
+ } else {
+ while (column < commentIndex) {
+ print(" ");
+ column++;
+ }
+ }
+ println(" // id=" + typeId);
+ } else {
+ println();
+ }
+ }
+
+ private void printAnnotations(int commentIndex, List<AnnotationElement> annotations) {
+ for (AnnotationElement a : annotations) {
+ printIndent();
+ print("@");
+ print(makeSimpleType(a.getTypeName()));
+ List<ValueDescriptor> vs = a.getValueDescriptors();
+ if (!vs.isEmpty()) {
+ printAnnotation(a);
+ printCommentRef(commentIndex, a.getTypeId());
+ } else {
+ println();
+ }
+ }
+ }
+
+ private void printAnnotation(AnnotationElement a) {
+ StringJoiner sj = new StringJoiner(", ", "(", ")");
+ List<ValueDescriptor> vs = a.getValueDescriptors();
+ for (ValueDescriptor v : vs) {
+ Object o = a.getValue(v.getName());
+ if (vs.size() == 1 && v.getName().equals("value")) {
+ sj.add(textify(o));
+ } else {
+ sj.add(v.getName() + "=" + textify(o));
+ }
+ }
+ print(sj.toString());
+ }
+
+ private String textify(Object o) {
+ if (o.getClass().isArray()) {
+ Object[] array = (Object[]) o;
+ if (array.length == 1) {
+ return quoteIfNeeded(array[0]);
+ }
+ StringJoiner s = new StringJoiner(", ", "{", "}");
+ for (Object ob : array) {
+ s.add(quoteIfNeeded(ob));
+ }
+ return s.toString();
+ } else {
+ return quoteIfNeeded(o);
+ }
+ }
+
+ private String quoteIfNeeded(Object o) {
+ if (o instanceof String) {
+ return "\"" + o + "\"";
+ } else {
+ return String.valueOf(o);
+ }
+ }
+
+ private String makeSimpleType(String typeName) {
+ int index = typeName.lastIndexOf(".");
+ return typeName.substring(index + 1);
+ }
+
+ public void print(RecordedEvent event) {
+ print(event.getEventType().getName(), " ");
+ println("{");
+ indent();
+ for (ValueDescriptor v : event.getFields()) {
+ String name = v.getName();
+ if (!isZeroDuration(event, name) && !isLateField(name)) {
+ printFieldValue(event, v);
+ }
+ }
+ if (event.getThread() != null) {
+ printIndent();
+ print(EVENT_THREAD_FIELD + " = ");
+ printThread(event.getThread(), "");
+ }
+ if (event.getStackTrace() != null) {
+ printIndent();
+ print(STACK_TRACE_FIELD + " = ");
+ printStackTrace(event.getStackTrace());
+ }
+ retract();
+ printIndent();
+ println("}");
+ println();
+ }
+
+ private boolean isZeroDuration(RecordedEvent event, String name) {
+ return name.equals("duration") && ZERO.equals(event.getValue("duration"));
+ }
+
+ private void printStackTrace(RecordedStackTrace stackTrace) {
+ println("[");
+ List<RecordedFrame> frames = stackTrace.getFrames();
+ indent();
+ int i = 0;
+ while (i < frames.size() && i < getStackDepth()) {
+ RecordedFrame frame = frames.get(i);
+ if (frame.isJavaFrame()) {
+ printIndent();
+ printValue(frame, null, "");
+ println();
+ i++;
+ }
+ }
+ if (stackTrace.isTruncated() || i == getStackDepth()) {
+ printIndent();
+ println("...");
+ }
+ retract();
+ printIndent();
+ println("]");
+ }
+
+ public void print(RecordedObject struct, String postFix) {
+ println("{");
+ indent();
+ for (ValueDescriptor v : struct.getFields()) {
+ printFieldValue(struct, v);
+ }
+ retract();
+ printIndent();
+ println("}" + postFix);
+ }
+
+ private void printFieldValue(RecordedObject struct, ValueDescriptor v) {
+ printIndent();
+ print(v.getName(), " = ");
+ printValue(getValue(struct, v), v, "");
+ }
+
+ private void printArray(Object[] array) {
+ println("[");
+ indent();
+ for (int i = 0; i < array.length; i++) {
+ printIndent();
+ printValue(array[i], null, i + 1 < array.length ? ", " : "");
+ }
+ retract();
+ printIndent();
+ println("]");
+ }
+
+ private void printValue(Object value, ValueDescriptor field, String postFix) {
+ if (value == null) {
+ println("null" + postFix);
+ return;
+ }
+ if (value instanceof RecordedObject) {
+ if (value instanceof RecordedThread) {
+ printThread((RecordedThread) value, postFix);
+ return;
+ }
+ if (value instanceof RecordedClass) {
+ printClass((RecordedClass) value, postFix);
+ return;
+ }
+ if (value instanceof RecordedClassLoader) {
+ printClassLoader((RecordedClassLoader) value, postFix);
+ return;
+ }
+ if (value instanceof RecordedFrame) {
+ RecordedFrame frame = (RecordedFrame) value;
+ if (frame.isJavaFrame()) {
+ printJavaFrame((RecordedFrame) value, postFix);
+ return;
+ }
+ }
+ if (value instanceof RecordedMethod) {
+ println(formatMethod((RecordedMethod) value));
+ return;
+ }
+ print((RecordedObject) value, postFix);
+ return;
+ }
+ if (value.getClass().isArray()) {
+ printArray((Object[]) value);
+ return;
+ }
+ if (field.getContentType() != null) {
+ if (printFormatted(field, value)) {
+ return;
+ }
+ }
+ String text = String.valueOf(value);
+ if (value instanceof String) {
+ text = "\"" + text + "\"";
+ }
+ println(text);
+ }
+
+ private void printClassLoader(RecordedClassLoader cl, String postFix) {
+ // Purposely not printing class loader name to avoid cluttered output
+ RecordedClass clazz = cl.getType();
+ print(clazz == null ? "null" : clazz.getName());
+ if (clazz != null) {
+ print(" (");
+ print("id = ");
+ print(String.valueOf(cl.getId()));
+ println(")");
+ }
+ }
+
+ private void printJavaFrame(RecordedFrame f, String postFix) {
+ print(formatMethod(f.getMethod()));
+ int line = f.getLineNumber();
+ if (line >= 0) {
+ print(" line: " + line);
+ }
+ print(postFix);
+ }
+
+ private String formatMethod(RecordedMethod m) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(m.getType().getName());
+ sb.append(".");
+ sb.append(m.getName());
+ sb.append("(");
+ StringJoiner sj = new StringJoiner(", ");
+ String md = m.getDescriptor().replace("/", ".");
+ String parameter = md.substring(1, md.lastIndexOf(")"));
+ for (String qualifiedName : decodeDescriptors(parameter)) {
+ String typeName = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
+ sj.add(typeName);
+ }
+ sb.append(sj);
+ sb.append(")");
+ return sb.toString();
+ }
+
+ private void printClass(RecordedClass clazz, String postFix) {
+ RecordedClassLoader classLoader = clazz.getClassLoader();
+ String classLoaderName = "null";
+ if (classLoader != null) {
+ if (classLoader.getName() != null) {
+ classLoaderName = classLoader.getName();
+ } else {
+ classLoaderName = classLoader.getType().getName();
+ }
+ }
+ String className = clazz.getName();
+ if (className.startsWith("[")) {
+ className = decodeDescriptors(className).get(0);
+ }
+ println(className + " (classLoader = " + classLoaderName + ")" + postFix);
+ }
+
+ List<String> decodeDescriptors(String descriptor) {
+ List<String> descriptors = new ArrayList<>();
+ for (int index = 0; index < descriptor.length(); index++) {
+ String arrayBrackets = "";
+ while (descriptor.charAt(index) == '[') {
+ arrayBrackets += "[]";
+ index++;
+ }
+ char c = descriptor.charAt(index);
+ String type;
+ switch (c) {
+ case 'L':
+ int endIndex = descriptor.indexOf(';', index);
+ type = descriptor.substring(index + 1, endIndex);
+ index = endIndex;
+ break;
+ case 'I':
+ type = "int";
+ break;
+ case 'J':
+ type = "long";
+ break;
+ case 'Z':
+ type = "boolean";
+ break;
+ case 'D':
+ type = "double";
+ break;
+ case 'F':
+ type = "float";
+ break;
+ case 'S':
+ type = "short";
+ break;
+ case 'C':
+ type = "char";
+ break;
+ case 'B':
+ type = "byte";
+ break;
+ default:
+ type = "<unknown-descriptor-type>";
+ }
+ descriptors.add(type + arrayBrackets);
+ }
+ return descriptors;
+ }
+
+ private void printThread(RecordedThread thread, String postFix) {
+ long javaThreadId = thread.getJavaThreadId();
+ if (javaThreadId > 0) {
+ println("\"" + thread.getJavaName() + "\" (javaThreadId = " + thread.getJavaThreadId() + ")" + postFix);
+ } else {
+ println("\"" + thread.getOSName() + "\" (osThreadId = " + thread.getOSThreadId() + ")" + postFix);
+ }
+ }
+
+ private boolean printFormatted(ValueDescriptor field, Object value) {
+ if (value instanceof Duration) {
+ Duration d = (Duration) value;
+ double s = d.toNanosPart() / 1000_000_000.0 + d.toSecondsPart();
+ if (s < 1.0) {
+ if (s < 0.001) {
+ println(String.format("%.3f", s * 1_000_000) + " us");
+ } else {
+ println(String.format("%.3f", s * 1_000) + " ms");
+ }
+ } else {
+ if (s < 1000.0) {
+ println(String.format("%.3f", s) + " s");
+ } else {
+ println(String.format("%.0f", s) + " s");
+ }
+ }
+ return true;
+ }
+ if (value instanceof OffsetDateTime) {
+ OffsetDateTime zdt = (OffsetDateTime) value;
+ println(TIME_FORMAT.format(zdt));
+ return true;
+ }
+ Percentage percentage = field.getAnnotation(Percentage.class);
+ if (percentage != null) {
+ if (value instanceof Number) {
+ double d = ((Number) value).doubleValue();
+ println(String.format("%.2f", d * 100) + "%");
+ return true;
+ }
+ }
+ DataAmount dataAmount = field.getAnnotation(DataAmount.class);
+ if (dataAmount != null) {
+ if (value instanceof Number) {
+ Number n = (Number) value;
+ String bytes = Utils.formatBytes(n.longValue(), " ");
+ if (field.getAnnotation(Frequency.class) != null) {
+ bytes += "/s";
+ }
+ println(bytes);
+ return true;
+ }
+ }
+ MemoryAddress memoryAddress = field.getAnnotation(MemoryAddress.class);
+ if (memoryAddress != null) {
+ if (value instanceof Number) {
+ long d = ((Number) value).longValue();
+ println(String.format("0x%08X", d));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void setShowIds(boolean showIds) {
+ this.showIds = showIds;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Print.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import jdk.jfr.EventType;
+
+final class Print extends Command {
+ @Override
+ public String getName() {
+ return "print";
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ List<String> list = new ArrayList<>();
+ list.add("[--xml|--json]");
+ list.add("[--categories <filter>]");
+ list.add("[--events <filter>]");
+ list.add("[--stack-depth <depth>]");
+ list.add("<file>");
+ return list;
+ }
+
+ @Override
+ protected String getTitle() {
+ return "Print contents of a recording file";
+ }
+
+ @Override
+ public String getDescription() {
+ return getTitle() + ". See 'jfr help print' for details.";
+ }
+
+ @Override
+ public void displayOptionUsage(PrintStream stream) {
+ stream.println(" --xml Print recording in XML format");
+ stream.println();
+ stream.println(" --json Print recording in JSON format");
+ stream.println();
+ stream.println(" --categories <filter> Select events matching a category name.");
+ stream.println(" The filter is a comma-separated list of names,");
+ stream.println(" simple and/or qualified, and/or quoted glob patterns");
+ stream.println();
+ stream.println(" --events <filter> Select events matching an event name.");
+ stream.println(" The filter is a comma-separated list of names,");
+ stream.println(" simple and/or qualified, and/or quoted glob patterns");
+ stream.println();
+ stream.println(" --stack-depth <depth> Number of frames in stack traces, by default 5");
+ stream.println();
+ stream.println(" <file> Location of the recording file (.jfr)");
+ stream.println();
+ stream.println();
+ stream.println("Example usage:");
+ stream.println();
+ stream.println(" jfr print --events OldObjectSample recording.jfr");
+ stream.println();
+ stream.println(" jfr print --events CPULoad,GarbageCollection recording.jfr");
+ stream.println();
+ stream.println(" jfr print --categories \"GC,JVM,Java*\" recording.jfr");
+ stream.println();
+ stream.println(" jfr print --events \"jdk.*\" --stack-depth 64 recording.jfr");
+ stream.println();
+ stream.println(" jfr print --json --events CPULoad recording.jfr");
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ Path file = getJFRInputFile(options);
+ PrintWriter pw = new PrintWriter(System.out, false, Charset.forName("UTF-8"));
+ Predicate<EventType> eventFilter = null;
+ int stackDepth = 5;
+ EventPrintWriter eventWriter = null;
+ int optionCount = options.size();
+ while (optionCount > 0) {
+ if (acceptFilterOption(options, "--events")) {
+ String filter = options.remove();
+ warnForWildcardExpansion("--events", filter);
+ eventFilter = addEventFilter(filter, eventFilter);
+ }
+ if (acceptFilterOption(options, "--categories")) {
+ String filter = options.remove();
+ warnForWildcardExpansion("--categories", filter);
+ eventFilter = addCategoryFilter(filter, eventFilter);
+ }
+ if (acceptOption(options, "--stack-depth")) {
+ String value = options.pop();
+ try {
+ stackDepth = Integer.parseInt(value);
+ if (stackDepth < 0) {
+ throw new UserSyntaxException("stack depth must be zero or a positive integer.");
+ }
+ } catch (NumberFormatException nfe) {
+ throw new UserSyntaxException("not a valid value for --stack-depth");
+ }
+ }
+ if (acceptFormatterOption(options, eventWriter, "--json")) {
+ eventWriter = new JSONWriter(pw);
+ }
+ if (acceptFormatterOption(options, eventWriter, "--xml")) {
+ eventWriter = new XMLWriter(pw);
+ }
+ if (optionCount == options.size()) {
+ // No progress made
+ throw new UserSyntaxException("unknown option " + options.peek());
+ }
+ optionCount = options.size();
+ }
+ if (eventWriter == null) {
+ eventWriter = new PrettyWriter(pw); // default to pretty printer
+ }
+ eventWriter.setStackDepth(stackDepth);
+ if (eventFilter != null) {
+ eventFilter = addCache(eventFilter, eventType -> eventType.getId());
+ eventWriter.setEventFilter(eventFilter);
+ }
+ try {
+ eventWriter.print(file);
+ } catch (IOException ioe) {
+ couldNotReadError(file, ioe);
+ }
+ pw.flush();
+ }
+
+ private static boolean acceptFormatterOption(Deque<String> options, EventPrintWriter eventWriter, String expected) throws UserSyntaxException {
+ if (expected.equals(options.peek())) {
+ if (eventWriter != null) {
+ throw new UserSyntaxException("only one format can be specified at a time");
+ }
+ options.remove();
+ return true;
+ }
+ return false;
+ }
+
+ private static <T, X> Predicate<T> addCache(final Predicate<T> filter, Function<T, X> cacheFunction) {
+ Map<X, Boolean> cache = new HashMap<>();
+ return t -> cache.computeIfAbsent(cacheFunction.apply(t), x -> filter.test(t));
+ }
+
+ private static <T> Predicate<T> recurseIfPossible(Predicate<T> filter) {
+ return x -> filter != null && filter.test(x);
+ }
+
+ private static Predicate<EventType> addCategoryFilter(String filterText, Predicate<EventType> eventFilter) throws UserSyntaxException {
+ List<String> filters = explodeFilter(filterText);
+ return recurseIfPossible(eventType -> {
+ for (String category : eventType.getCategoryNames()) {
+ for (String filter : filters) {
+ if (match(category, filter)) {
+ return true;
+ }
+ if (category.contains(" ") && acronomify(category).equals(filter)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ });
+ }
+
+ private static String acronomify(String multipleWords) {
+ boolean newWord = true;
+ String acronym = "";
+ for (char c : multipleWords.toCharArray()) {
+ if (newWord) {
+ if (Character.isAlphabetic(c) && Character.isUpperCase(c)) {
+ acronym += c;
+ }
+ }
+ newWord = Character.isWhitespace(c);
+ }
+ return acronym;
+ }
+
+ private static Predicate<EventType> addEventFilter(String filterText, final Predicate<EventType> eventFilter) throws UserSyntaxException {
+ List<String> filters = explodeFilter(filterText);
+ return recurseIfPossible(eventType -> {
+ for (String filter : filters) {
+ String fullEventName = eventType.getName();
+ if (match(fullEventName, filter)) {
+ return true;
+ }
+ String eventName = fullEventName.substring(fullEventName.lastIndexOf(".") + 1);
+ if (match(eventName, filter)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ private static boolean match(String text, String filter) {
+ if (filter.length() == 0) {
+ // empty filter string matches if string is empty
+ return text.length() == 0;
+ }
+ if (filter.charAt(0) == '*') { // recursive check
+ filter = filter.substring(1);
+ for (int n = 0; n <= text.length(); n++) {
+ if (match(text.substring(n), filter))
+ return true;
+ }
+ } else if (text.length() == 0) {
+ // empty string and non-empty filter does not match
+ return false;
+ } else if (filter.charAt(0) == '?') {
+ // eat any char and move on
+ return match(text.substring(1), filter.substring(1));
+ } else if (filter.charAt(0) == text.charAt(0)) {
+ // eat chars and move on
+ return match(text.substring(1), filter.substring(1));
+ }
+ return false;
+ }
+
+ private static List<String> explodeFilter(String filter) throws UserSyntaxException {
+ List<String> list = new ArrayList<>();
+ for (String s : filter.split(",")) {
+ s = s.trim();
+ if (!s.isEmpty()) {
+ list.add(s);
+ }
+ }
+ return list;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/StructuredWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.PrintWriter;
+
+abstract class StructuredWriter {
+ private final static String LINE_SEPARATOR = String.format("%n");
+
+ private final PrintWriter out;
+ private final StringBuilder builder = new StringBuilder(4000);
+
+ private char[] indentionArray = new char[0];
+ private int indent = 0;
+ private int column;
+ // print first event immediately so tool feels responsive
+ private boolean first = true;
+
+ StructuredWriter(PrintWriter p) {
+ out = p;
+ }
+
+ final protected int getColumn() {
+ return column;
+ }
+
+ // Flush to print writer
+ public final void flush(boolean hard) {
+ if (hard) {
+ out.print(builder.toString());
+ builder.setLength(0);
+ return;
+ }
+ if (first || builder.length() > 100_000) {
+ out.print(builder.toString());
+ builder.setLength(0);
+ first = false;
+ }
+ }
+
+ final public void printIndent() {
+ builder.append(indentionArray, 0, indent);
+ column += indent;
+ }
+
+ final public void println() {
+ builder.append(LINE_SEPARATOR);
+ column = 0;
+ }
+
+ final public void print(String... texts) {
+ for (String text : texts) {
+ print(text);
+ }
+ }
+
+ final public void printAsString(Object o) {
+ print(String.valueOf(o));
+ }
+
+ final public void print(String text) {
+ builder.append(text);
+ column += text.length();
+ }
+
+ final public void print(char c) {
+ builder.append(c);
+ column++;
+ }
+
+ final public void print(int value) {
+ print(String.valueOf(value));
+ }
+
+ final public void indent() {
+ indent += 2;
+ updateIndent();
+ }
+
+ final public void retract() {
+ indent -= 2;
+ updateIndent();
+ }
+
+ final public void println(String text) {
+ print(text);
+ println();
+ }
+
+ private void updateIndent() {
+ if (indent > indentionArray.length) {
+ indentionArray = new char[indent];
+ for (int i = 0; i < indentionArray.length; i++) {
+ indentionArray[i] = ' ';
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Summary.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.Path;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import jdk.jfr.EventType;
+import jdk.jfr.internal.MetadataDescriptor;
+import jdk.jfr.internal.Type;
+import jdk.jfr.internal.consumer.ChunkHeader;
+import jdk.jfr.internal.consumer.RecordingInput;
+
+final class Summary extends Command {
+ private final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withLocale(Locale.UK).withZone(ZoneOffset.UTC);
+
+ @Override
+ public String getName() {
+ return "summary";
+ }
+
+ private static class Statistics {
+ Statistics(String name) {
+ this.name = name;
+ }
+ String name;
+ long count;
+ long size;
+ }
+
+ @Override
+ public List<String> getOptionSyntax() {
+ return Collections.singletonList("<file>");
+ }
+
+ @Override
+ public void displayOptionUsage(PrintStream stream) {
+ stream.println(" <file> Location of the recording file (.jfr) to display information about");
+ }
+
+ @Override
+ public String getDescription() {
+ return "Display general information about a recording file (.jfr)";
+ }
+
+ @Override
+ public void execute(Deque<String> options) throws UserSyntaxException, UserDataException {
+ ensureMaxArgumentCount(options, 1);
+ Path p = getJFRInputFile(options);
+ try {
+ printInformation(p);
+ } catch (IOException e) {
+ couldNotReadError(p, e);
+ }
+ }
+
+ private void printInformation(Path p) throws IOException {
+ long totalDuration = 0;
+ long chunks = 0;
+
+ try (RecordingInput input = new RecordingInput(p.toFile())) {
+ ChunkHeader first = new ChunkHeader(input);
+ ChunkHeader ch = first;
+ String eventPrefix = Type.EVENT_NAME_PREFIX;
+ if (first.getMajor() == 1) {
+ eventPrefix = "com.oracle.jdk.";
+ }
+ HashMap<Long, Statistics> stats = new HashMap<>();
+ stats.put(0L, new Statistics(eventPrefix + "Metadata"));
+ stats.put(1L, new Statistics(eventPrefix + "CheckPoint"));
+ int minWidth = 0;
+ while (true) {
+ long chunkEnd = ch.getEnd();
+ MetadataDescriptor md = ch.readMetadata();
+
+ for (EventType eventType : md.getEventTypes()) {
+ stats.computeIfAbsent(eventType.getId(), (e) -> new Statistics(eventType.getName()));
+ minWidth = Math.max(minWidth, eventType.getName().length());
+ }
+
+ totalDuration += ch.getDurationNanos();
+ chunks++;
+ input.position(ch.getEventStart());
+ while (input.position() < chunkEnd) {
+ long pos = input.position();
+ int size = input.readInt();
+ long eventTypeId = input.readLong();
+ Statistics s = stats.get(eventTypeId);
+ if (s != null) {
+ s.count++;
+ s.size += size;
+ }
+ input.position(pos + size);
+ }
+ if (ch.isLastChunk()) {
+ break;
+ }
+ ch = ch.nextHeader();
+ }
+ println();
+ long epochSeconds = first.getStartNanos() / 1_000_000_000L;
+ long adjustNanos = first.getStartNanos() - epochSeconds * 1_000_000_000L;
+ println(" Version: " + first.getMajor() + "." + first.getMinor());
+ println(" Chunks: " + chunks);
+ println(" Start: " + DATE_FORMAT.format(Instant.ofEpochSecond(epochSeconds, adjustNanos)) + " (UTC)");
+ println(" Duration: " + (totalDuration + 500_000_000) / 1_000_000_000 + " s");
+
+ List<Statistics> statsList = new ArrayList<>(stats.values());
+ Collections.sort(statsList, (u, v) -> Long.compare(v.count, u.count));
+ println();
+ String header = " Count Size (bytes) ";
+ String typeHeader = " Event Type";
+ minWidth = Math.max(minWidth, typeHeader.length());
+ println(typeHeader + pad(minWidth - typeHeader.length(), ' ') + header);
+ println(pad(minWidth + header.length(), '='));
+ for (Statistics s : statsList) {
+ System.out.printf(" %-" + minWidth + "s%10d %12d\n", s.name, s.count, s.size);
+ }
+ }
+ }
+
+ private String pad(int count, char c) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < count; i++) {
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/UserDataException.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+/**
+ * Exception that is thrown if there is something wrong with the input, for instance
+ * a file that can't be read or a numerical value that is out of range.
+ * <p>
+ * When this exception is thrown, a user will typically not want to see the
+ * command line syntax, but instead information about what was wrong with the
+ * input.
+ */
+final class UserDataException extends Exception {
+ private static final long serialVersionUID = 6656457380115167810L;
+ /**
+ * The error message.
+ *
+ * The first letter should not be capitalized, so a context can be printed prior
+ * to the error message.
+ *
+ * @param errorMessage
+ */
+ public UserDataException(String errorMessage) {
+ super(errorMessage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/UserSyntaxException.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+/**
+ * Exception that is thrown if options don't follow the syntax of the command.
+ */
+final class UserSyntaxException extends Exception {
+ private static final long serialVersionUID = 3437009454344160933L;
+
+ /**
+ * The error message.
+ *
+ * The first letter should not be capitalized, so a context can be printed prior
+ * to the error message.
+ *
+ * @param errorMessage
+ */
+ public UserSyntaxException(String message) {
+ super(message);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Version.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.util.Deque;
+import java.util.List;
+
+final class Version extends Command {
+ @Override
+ public String getName() {
+ return "version";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Display version of the jfr tool";
+ }
+
+ @Override
+ public void execute(Deque<String> options) {
+ System.out.println("1.0");
+ }
+
+ protected List<String> getAliases() {
+ return List.of("--version");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/XMLWriter.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.internal.tool;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+import jdk.jfr.EventType;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedFrame;
+import jdk.jfr.consumer.RecordedObject;
+
+final class XMLWriter extends EventPrintWriter {
+ public XMLWriter(PrintWriter destination) {
+ super(destination);
+ }
+
+ @Override
+ protected void printBegin() {
+ println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ println("<recording xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
+ indent();
+ printIndent();
+ println("<events>");
+ indent();
+ }
+
+ @Override
+ protected void printEnd() {
+ retract();
+ printIndent();
+ println("</events>");
+ retract();
+ println("</recording>");
+ }
+
+ @Override
+ protected void print(List<RecordedEvent> events) {
+ for (RecordedEvent event : events) {
+ printEvent(event);
+ }
+ }
+
+ private void printEvent(RecordedEvent event) {
+ EventType type = event.getEventType();
+ printIndent();
+ print("<event");
+ printAttribute("type", type.getName());
+ print(">");
+ println();
+ indent();
+ for (ValueDescriptor v : event.getFields()) {
+ printValueDescriptor(v, getValue(event, v), -1);
+ }
+ retract();
+ printIndent();
+ println("</event>");
+ println();
+ }
+
+ private void printAttribute(String name, String value) {
+ print(" ", name, "=\"", value, "\"");
+ }
+
+ public void printObject(RecordedObject struct) {
+ println();
+ indent();
+ for (ValueDescriptor v : struct.getFields()) {
+ printValueDescriptor(v, getValue(struct, v), -1);
+ }
+ retract();
+ }
+
+ private void printArray(ValueDescriptor v, Object[] array) {
+ println();
+ indent();
+ int depth = 0;
+ for (int index = 0; index < array.length; index++) {
+ Object arrayElement = array[index];
+ if (!(arrayElement instanceof RecordedFrame) || depth < getStackDepth()) {
+ printValueDescriptor(v, array[index], index);
+ }
+ depth++;
+ }
+ retract();
+ }
+
+ private void printValueDescriptor(ValueDescriptor vd, Object value, int index) {
+ boolean arrayElement = index != -1;
+ String name = arrayElement ? null : vd.getName();
+ if (vd.isArray() && !arrayElement) {
+ if (printBeginElement("array", name, value, index)) {
+ printArray(vd, (Object[]) value);
+ printIndent();
+ printEndElement("array");
+ }
+ return;
+ }
+ if (!vd.getFields().isEmpty()) {
+ if (printBeginElement("struct", name, value, index)) {
+ printObject((RecordedObject) value);
+ printIndent();
+ printEndElement("struct");
+ }
+ return;
+ }
+ if (printBeginElement("value", name, value, index)) {
+ printEscaped(String.valueOf(value));
+ printEndElement("value");
+ }
+ }
+
+ private boolean printBeginElement(String elementName, String name, Object value, int index) {
+ printIndent();
+ print("<", elementName);
+ if (name != null) {
+ printAttribute("name", name);
+ }
+ if (index != -1) {
+ printAttribute("index", Integer.toString(index));
+ }
+ if (value == null) {
+ printAttribute("xsi:nil", "true");
+ println("/>");
+ return false;
+ }
+ if (value.getClass().isArray()) {
+ Object[] array = (Object[]) value;
+ printAttribute("size", Integer.toString(array.length));
+ }
+ print(">");
+ return true;
+ }
+
+ private void printEndElement(String elementName) {
+ print("</");
+ print(elementName);
+ println(">");
+ }
+
+ private void printEscaped(String text) {
+ for (int i = 0; i < text.length(); i++) {
+ printEscaped(text.charAt(i));
+ }
+ }
+
+ private void printEscaped(char c) {
+ if (c == 34) {
+ print(""");
+ return;
+ }
+ if (c == 38) {
+ print("&");
+ return;
+ }
+ if (c == 39) {
+ print("'");
+ return;
+ }
+ if (c == 60) {
+ print("<");
+ return;
+ }
+ if (c == 62) {
+ print(">");
+ return;
+ }
+ if (c > 0x7F) {
+ print("&#");
+ print((int) c);
+ print(';');
+ return;
+ }
+ print(c);
+ }
+}
--- a/src/jdk.jfr/share/classes/module-info.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jfr/share/classes/module-info.java Wed Dec 05 17:05:42 2018 -0500
@@ -25,6 +25,12 @@
/**
* Defines the API for JDK Flight Recorder.
+ * <p>
+ *
+ * <dl style="font-family:'DejaVu Sans', Arial, Helvetica, sans serif">
+ * <dt class="simpleTagLabel">Tool Guides:
+ * <dd>{@extLink jfr_tool_reference jfr}
+ * </dl>
*
* @moduleGraph
* @since 9
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java Wed Dec 05 17:05:42 2018 -0500
@@ -108,7 +108,11 @@
case "del": {
// --release-info del:keys=openjdk,java_version
- Utils.parseList(config.get(KEYS)).stream().forEach((k) -> {
+ String keys = config.get(KEYS);
+ if (keys == null || keys.isEmpty()) {
+ throw new IllegalArgumentException("No key specified for delete");
+ }
+ Utils.parseList(keys).stream().forEach((k) -> {
release.remove(k);
});
}
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Wed Dec 05 17:03:58 2018 -0500
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Wed Dec 05 17:05:42 2018 -0500
@@ -52,6 +52,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.TreeMap;
import java.util.TreeSet;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
@@ -925,7 +926,7 @@
mv.visitTypeInsn(ANEWARRAY, "java/util/Map$Entry");
int index = 0;
- for (Map.Entry<String, Set<String>> e : map.entrySet()) {
+ for (var e : new TreeMap<>(map).entrySet()) {
String name = e.getKey();
Set<String> s = e.getValue();
@@ -971,7 +972,7 @@
pushInt(mv, size);
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
int i = 0;
- for (String element : set) {
+ for (String element : sorted(set)) {
mv.visitInsn(DUP);
pushInt(mv, i);
mv.visitLdcInsn(element);
@@ -985,7 +986,7 @@
true);
} else {
StringBuilder sb = new StringBuilder("(");
- for (String element : set) {
+ for (String element : sorted(set)) {
mv.visitLdcInsn(element);
sb.append("Ljava/lang/Object;");
}
@@ -1146,7 +1147,7 @@
pushInt(mv, requires.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Requires");
int arrayIndex = 0;
- for (Requires require : requires) {
+ for (Requires require : sorted(requires)) {
String compiledVersion = null;
if (require.compiledVersion().isPresent()) {
compiledVersion = require.compiledVersion().get().toString();
@@ -1192,7 +1193,7 @@
pushInt(mv, exports.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Exports");
int arrayIndex = 0;
- for (Exports export : exports) {
+ for (Exports export : sorted(exports)) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, arrayIndex++);
newExports(export.modifiers(), export.source(), export.targets());
@@ -1245,7 +1246,7 @@
pushInt(mv, opens.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Opens");
int arrayIndex = 0;
- for (Opens open : opens) {
+ for (Opens open : sorted(opens)) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, arrayIndex++);
newOpens(open.modifiers(), open.source(), open.targets());
@@ -1310,7 +1311,7 @@
pushInt(mv, provides.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Provides");
int arrayIndex = 0;
- for (Provides provide : provides) {
+ for (Provides provide : sorted(provides)) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, arrayIndex++);
newProvides(provide.service(), provide.providers());
@@ -1420,6 +1421,8 @@
// Invoke ModuleHashes.Builder::hashForModule
recordedHashes
.names()
+ .stream()
+ .sorted()
.forEach(mn -> hashForModule(mn, recordedHashes.hashFor(mn)));
// Put ModuleHashes into the hashes array
@@ -1600,7 +1603,7 @@
* it will reuse defaultVarIndex. For a Set with multiple references,
* it will use a new local variable retrieved from the nextLocalVar
*/
- class SetBuilder<T> {
+ class SetBuilder<T extends Comparable<T>> {
private final Set<T> elements;
private final int defaultVarIndex;
private final IntSupplier nextLocalVar;
@@ -1660,7 +1663,7 @@
if (elements.size() <= 10) {
// call Set.of(e1, e2, ...)
StringBuilder sb = new StringBuilder("(");
- for (T t : elements) {
+ for (T t : sorted(elements)) {
sb.append("Ljava/lang/Object;");
visitElement(t, mv);
}
@@ -1672,7 +1675,7 @@
pushInt(mv, elements.size());
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
int arrayIndex = 0;
- for (T t : elements) {
+ for (T t : sorted(elements)) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, arrayIndex);
visitElement(t, mv); // value
@@ -1690,7 +1693,7 @@
* Generates bytecode to create one single instance of EnumSet
* for a given set of modifiers and assign to a local variable slot.
*/
- class EnumSetBuilder<T> extends SetBuilder<T> {
+ class EnumSetBuilder<T extends Comparable<T>> extends SetBuilder<T> {
private final String className;
@@ -1788,7 +1791,7 @@
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
int index = 0;
- for (String moduleName : map.keySet()) {
+ for (String moduleName : sorted(map.keySet())) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, index);
mv.visitLdcInsn(moduleName);
@@ -1811,7 +1814,7 @@
mv.visitTypeInsn(ANEWARRAY, "java/lang/String");
index = 0;
- for (String className : map.values()) {
+ for (String className : sorted(map.values())) {
mv.visitInsn(DUP); // arrayref
pushInt(mv, index);
mv.visitLdcInsn(className.replace('/', '.'));
@@ -1832,6 +1835,19 @@
}
/**
+ * Returns a sorted copy of a collection.
+ *
+ * This is useful to ensure a deterministic iteration order.
+ *
+ * @return a sorted copy of the given collection.
+ */
+ private static <T extends Comparable<T>> List<T> sorted(Collection<T> c) {
+ var l = new ArrayList<T>(c);
+ Collections.sort(l);
+ return l;
+ }
+
+ /**
* Pushes an int constant
*/
private static void pushInt(MethodVisitor mv, int value) {
--- a/test/hotspot/jtreg/runtime/appcds/LotsOfClasses.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/runtime/appcds/LotsOfClasses.java Wed Dec 05 17:05:42 2018 -0500
@@ -57,16 +57,12 @@
opts.addSuffix("--add-modules");
opts.addSuffix("ALL-SYSTEM");
opts.addSuffix("-Xlog:hashtables");
- opts.addSuffix("-Xms500m");
opts.addSuffix("-Xmx500m");
+ opts.addSuffix("-Xlog:gc+region+cds");
+ opts.addSuffix("-Xlog:gc+region=trace");
OutputAnalyzer out = CDSTestUtils.createArchive(opts);
- try {
- CDSTestUtils.checkDump(out);
- } catch (java.lang.RuntimeException re) {
- out.shouldContain(
- "number of memory regions exceeds maximum due to fragmentation");
- }
+ CDSTestUtils.checkDump(out);
}
static void findAllClasses(ArrayList<String> list) throws Throwable {
--- a/test/hotspot/jtreg/runtime/appcds/cacheObject/ArchivedIntegerCacheTest.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/runtime/appcds/cacheObject/ArchivedIntegerCacheTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -146,8 +146,11 @@
"-Xmx1g",
"-XX:NewSize=1g",
"-Xlog:cds+heap=info",
+ "-Xlog:gc+region+cds",
+ "-Xlog:gc+region=trace",
use_whitebox_jar);
TestCommon.checkDump(output,
- "Cannot archive the sub-graph referenced from [Ljava.lang.Integer; object");
+ "Cannot archive the sub-graph referenced from [Ljava.lang.Integer; object",
+ "humongous regions have been found and may lead to fragmentation");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/HumongousDuringDump.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary Test how CDS dumping handles the existence of humongous G1 regions.
+ * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
+ * @requires vm.cds.archived.java.heap
+ * @requires vm.flavor != "minimal"
+ * @modules java.base/jdk.internal.misc
+ * jdk.jartool/sun.tools.jar
+ * java.management
+ * @build HumongousDuringDumpTransformer Hello
+ * @run main/othervm/timeout=240 HumongousDuringDump
+ */
+
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class HumongousDuringDump {
+ public static String appClasses[] = {
+ "Hello",
+ };
+ public static String agentClasses[] = {
+ "HumongousDuringDumpTransformer",
+ };
+
+ public static void main(String[] args) throws Throwable {
+ String agentJar =
+ ClassFileInstaller.writeJar("HumongousDuringDumpTransformer.jar",
+ ClassFileInstaller.Manifest.fromSourceFile("HumongousDuringDumpTransformer.mf"),
+ agentClasses);
+
+ String appJar =
+ ClassFileInstaller.writeJar("HumongousDuringDumpApp.jar", appClasses);
+
+ String gcLog = Boolean.getBoolean("test.cds.verbose.gc") ?
+ "-Xlog:gc*=info,gc+region=trace,gc+alloc+region=debug" : "-showversion";
+
+ String extraArg = "-javaagent:" + agentJar;
+ String extraOption = "-XX:+AllowArchivingWithJavaAgent";
+
+ OutputAnalyzer out =
+ TestCommon.testDump(appJar, TestCommon.list("Hello"),
+ "-XX:+UnlockDiagnosticVMOptions", extraOption,
+ "-Xlog:gc+region+cds",
+ "-Xlog:gc+region=trace",
+ extraArg, "-Xmx64m", gcLog);
+ out.shouldContain("(Unmovable) humongous regions have been found and may lead to fragmentation");
+ out.shouldContain("All free regions should be at the top end of the heap, but we found holes.");
+ out.shouldMatch("gc,region,cds. HeapRegion .* HUM. hole");
+ String pattern = "gc,region,cds. HeapRegion .*hole";
+ out.shouldMatch(pattern);
+ out.shouldNotMatch(pattern + ".*unexpected");
+
+ TestCommon.run(
+ "-cp", appJar,
+ "-verbose",
+ "-Xmx64m",
+ "-XX:+PrintSharedSpaces",
+ "-XX:+UnlockDiagnosticVMOptions", extraOption,
+ gcLog,
+ "Hello")
+ .assertNormalExit();
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/HumongousDuringDumpTransformer.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.Instrumentation;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+// This test is sensitive to -Xmx. It must be run with -xmx64m.
+// Running with a different -Xmx requires changing the parameters and careful re-testing.
+public class HumongousDuringDumpTransformer implements ClassFileTransformer {
+ public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
+ ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
+ if (name.equals("Hello")) {
+ try {
+ makeHumongousRegions();
+ } catch (Throwable t) {
+ array = null;
+ humon = null;
+ System.out.println("Unexpected error: " + t);
+ t.printStackTrace();
+ }
+ }
+ array = null;
+ return null;
+ }
+
+ private static Instrumentation savedInstrumentation;
+
+ public static void premain(String agentArguments, Instrumentation instrumentation) {
+ long xmx = Runtime.getRuntime().maxMemory();
+ if (xmx < 60 * 1024 * 1024 || xmx > 80 * 1024 * 1024) {
+ System.out.println("Running with incorrect heap size: " + xmx);
+ System.exit(1);
+ }
+
+ System.out.println("ClassFileTransformer.premain() is called");
+ instrumentation.addTransformer(new HumongousDuringDumpTransformer(), /*canRetransform=*/true);
+ savedInstrumentation = instrumentation;
+ }
+
+ public static Instrumentation getInstrumentation() {
+ return savedInstrumentation;
+ }
+
+ public static void agentmain(String args, Instrumentation inst) throws Exception {
+ premain(args, inst);
+ }
+
+ Object[] array;
+
+ static final int DUMMY_SIZE = 4096 - 16 - 8;
+ static final int HUMON_SIZE = 4 * 1024 * 1024 - 16 - 8;
+ static final int SKIP = 13;
+
+ byte humon[] = null;
+ boolean first = true;
+
+ public synchronized void makeHumongousRegions() {
+ if (!first) {
+ return;
+ }
+ System.out.println("===============================================================================");
+ first = false;
+
+ int total = 0;
+ array = new Object[100000];
+ System.out.println(array);
+
+ // (1) Allocate about 8MB of old objects.
+ for (int n=0, i=0; total < 8 * 1024 * 1024; n++) {
+ // Make enough allocations to cause a GC (for 64MB heap) to create
+ // old regions.
+ //
+ // But don't completely fill up the heap. That would cause OOM and
+ // may not be handled gracefully inside class transformation!
+ Object x = new byte[DUMMY_SIZE];
+ if ((n % SKIP) == 0) {
+ array[i++] = x;
+ total += DUMMY_SIZE;
+ }
+ }
+
+ System.gc();
+
+ // (2) Now allocate a humongous array. It will sit above the 8MB of old regions.
+ humon = new byte[HUMON_SIZE];
+ array = null;
+ System.gc();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/HumongousDuringDumpTransformer.mf Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Premain-Class: HumongousDuringDumpTransformer
+Agent-Class: HumongousDuringDumpTransformer
+Can-Retransform-Classes: true
+Can-Redefine-Classes: true
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/InvalidFileFormat.java Wed Dec 05 17:05:42 2018 -0500
@@ -57,6 +57,7 @@
test("OverflowPrefix.txt", "Num overflow. Corrupted at line 4");
test("UnrecognizedPrefix.txt", "Unrecognized format. Corrupted at line 5");
test("TruncatedString.txt", "Truncated. Corrupted at line 3");
+ test("LengthOverflow.txt", "string length too large: 2147483647");
}
private static void
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsHumongous.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary Use a shared string allocated in a humongous G1 region.
+ * @comment -- the following implies that G1 is used (by command-line or by default)
+ * @requires vm.cds.archived.java.heap
+ *
+ * @library /test/hotspot/jtreg/runtime/appcds /test/lib
+ * @modules jdk.jartool/sun.tools.jar
+ * @build HelloString
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. SharedStringsHumongous
+ */
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import sun.hotspot.WhiteBox;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.Asserts;
+
+public class SharedStringsHumongous {
+ static String sharedArchiveConfigFile = System.getProperty("user.dir") + File.separator + "SharedStringsHumongous_gen.txt";
+
+ public static void main(String[] args) throws Exception {
+ WhiteBox wb = WhiteBox.getWhiteBox();
+
+ try (FileOutputStream fos = new FileOutputStream(sharedArchiveConfigFile)) {
+ PrintWriter out = new PrintWriter(new OutputStreamWriter(fos));
+ out.println("VERSION: 1.0");
+ out.println("@SECTION: String");
+ out.println("31: shared_test_string_unique_14325");
+ int region_size = wb.g1RegionSize();
+ char body[] = new char[region_size + region_size / 2];
+ for (int i = 0; i < body.length; i++) {
+ body[i] = 'x';
+ }
+ Asserts.assertTrue(wb.g1IsHumongous(body));
+ String prefix = "generated_string (followed by " + body.length + " 'x') ";
+
+ System.out.println("G1 region size: " + region_size);
+ System.out.println("Using a humongous string: " + prefix);
+
+ String s = prefix + new String(body);
+ out.println(s.length() + ": " + s);
+ out.close();
+ }
+
+ SharedStringsUtils.run(args, SharedStringsHumongous::test);
+ }
+
+ public static void test(String[] args) throws Exception {
+ String vmOptionsPrefix[] = SharedStringsUtils.getChildVMOptionsPrefix();
+ String appJar = JarBuilder.build("SharedStringsHumongous", "HelloString");
+
+ OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list("HelloString"),
+ TestCommon.concat(vmOptionsPrefix,
+ "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
+ "-Xlog:gc+region+cds",
+ "-Xlog:gc+region=trace"));
+ TestCommon.checkDump(dumpOutput, "extra interned string ignored; size too large");
+ // Extra strings that are humongous are not kelp alive, so they should be GC'ed
+ // before dumping the string table. That means the heap should contain no
+ // humongous regions.
+ dumpOutput.shouldNotMatch("gc,region,cds. HeapRegion 0x[0-9a-f]* HUM");
+
+ OutputAnalyzer execOutput = TestCommon.exec(appJar,
+ TestCommon.concat(vmOptionsPrefix, "HelloString"));
+ TestCommon.checkExec(execOutput);
+ }
+}
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsStress.java Wed Dec 05 17:05:42 2018 -0500
@@ -29,7 +29,7 @@
* @library /test/hotspot/jtreg/runtime/appcds /test/lib
* @modules jdk.jartool/sun.tools.jar
* @build HelloString
- * @run driver SharedStringsStress
+ * @run driver/timeout=500 SharedStringsStress
*/
import java.io.File;
import java.io.FileOutputStream;
@@ -39,34 +39,56 @@
import jdk.test.lib.process.ProcessTools;
public class SharedStringsStress {
- public static void main(String[] args) throws Exception {
- SharedStringsUtils.run(args, SharedStringsStress::test);
- }
+ static String sharedArchiveConfigFile = System.getProperty("user.dir") + File.separator + "SharedStringsStress_gen.txt";
- public static void test(String[] args) throws Exception {
- String vmOptionsPrefix[] = SharedStringsUtils.getChildVMOptionsPrefix();
-
- String appJar = JarBuilder.build("SharedStringsStress", "HelloString");
-
- String sharedArchiveConfigFile = System.getProperty("user.dir") + File.separator + "SharedStringsStress_gen.txt";
+ public static void main(String[] args) throws Exception {
try (FileOutputStream fos = new FileOutputStream(sharedArchiveConfigFile)) {
PrintWriter out = new PrintWriter(new OutputStreamWriter(fos));
out.println("VERSION: 1.0");
out.println("@SECTION: String");
out.println("31: shared_test_string_unique_14325");
- for (int i=0; i<100000; i++) {
+ for (int i=0; i<200000; i++) {
String s = "generated_string " + i;
out.println(s.length() + ": " + s);
}
out.close();
}
- OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list("HelloString"),
- TestCommon.concat(vmOptionsPrefix,
- "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile));
- TestCommon.checkDump(dumpOutput);
- OutputAnalyzer execOutput = TestCommon.exec(appJar,
- TestCommon.concat(vmOptionsPrefix, "HelloString"));
- TestCommon.checkExec(execOutput);
+ SharedStringsUtils.run(args, SharedStringsStress::test);
+ }
+
+ public static void test(String[] args) throws Exception {
+ String vmOptionsPrefix[] = SharedStringsUtils.getChildVMOptionsPrefix();
+ String appJar = JarBuilder.build("SharedStringsStress", "HelloString");
+
+ String test_cases[][] = {
+ // default heap size
+ {},
+
+ // Test for handling of heap fragmentation. With sharedArchiveConfigFile, we will dump about
+ // 18MB of shared objects on 64 bit VM (smaller on 32-bit).
+ //
+ // During dump time, an extra copy of these objects are allocated,
+ // so we need about 36MB, plus a few MB for other system data. So 64MB total heap
+ // should be enough.
+ //
+ // The VM should executed a full GC to maximize contiguous free space and
+ // avoid fragmentation.
+ {"-Xmx64m"},
+ };
+
+ for (String[] extra_opts: test_cases) {
+ vmOptionsPrefix = TestCommon.concat(vmOptionsPrefix, extra_opts);
+
+ OutputAnalyzer dumpOutput = TestCommon.dump(appJar, TestCommon.list("HelloString"),
+ TestCommon.concat(vmOptionsPrefix,
+ "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile,
+ "-Xlog:gc+region+cds",
+ "-Xlog:gc+region=trace"));
+ TestCommon.checkDump(dumpOutput);
+ OutputAnalyzer execOutput = TestCommon.exec(appJar,
+ TestCommon.concat(vmOptionsPrefix, "HelloString"));
+ TestCommon.checkExec(execOutput);
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/LengthOverflow.txt Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,10 @@
+VERSION: 1.0
+@SECTION: String
+2147483647: s
+5: cp819
+31: shared_test_string_intern_12345
+7: test123
+@SECTION: Symbol
+41 -1: (Ljava/util/Set<TE;>;Ljava/lang/Object;)V
+10 -1: linkMethod
+20 -1: isAlphaNumericString
--- a/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/TruncatedString.txt Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/runtime/appcds/sharedStrings/invalidFormat/TruncatedString.txt Wed Dec 05 17:05:42 2018 -0500
@@ -1,6 +1,6 @@
VERSION: 1.0
@SECTION: String
-2147483647: s
+40000: s
5: cp819
31: shared_test_string_intern_12345
7: test123
--- a/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java Wed Dec 05 17:05:42 2018 -0500
@@ -37,6 +37,7 @@
import jdk.test.lib.hprof.HprofParser;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.Utils;
import jtreg.SkippedException;
import java.io.File;
@@ -134,10 +135,24 @@
System.out.println(out.getStdout());
System.err.println(out.getStderr());
- Asserts.assertTrue(dumpFile.exists() && dumpFile.isFile(),
- "Could not find dump file " + dumpFile.getAbsolutePath());
+ if (dumpFile.exists() && dumpFile.isFile()) {
+ HprofParser.parse(dumpFile);
+ } else {
+ boolean ZGCUsed = false;
- HprofParser.parse(dumpFile);
+ for (String opt: Utils.getFilteredTestJavaOpts()) {
+ if (opt.contains("+UseZGC")) {
+ ZGCUsed = true;
+ break;
+ }
+ }
+
+ if (!ZGCUsed) {
+ throw new RuntimeException(
+ "Could not find dump file " + dumpFile.getAbsolutePath());
+ }
+ }
+
System.out.println("PASSED");
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Exception/exception001/exception001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Exception/exception001/exception001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -63,15 +63,15 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static exceptionInfo exs[] = {
- {"Lnsk/jvmti/Exception/exception001c;",
- "Lnsk/jvmti/Exception/exception001b;", "meth1", "()V", 7,
- "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 14},
- {"Ljava/lang/ArithmeticException;",
- "Lnsk/jvmti/Exception/exception001b;", "meth2", "(I)I", 3,
- "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 24},
- {"Ljava/lang/ArrayIndexOutOfBoundsException;",
- "Lnsk/jvmti/Exception/exception001b;", "meth3", "(I)I", 10,
- "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 34}
+ { "Lnsk/jvmti/Exception/exception001c;",
+ "Lnsk/jvmti/Exception/exception001b;", "meth1", "()V", 7,
+ "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 14 },
+ { "Ljava/lang/ArithmeticException;",
+ "Lnsk/jvmti/Exception/exception001b;", "meth2", "(I)I", 3,
+ "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 24 },
+ { "Ljava/lang/ArrayIndexOutOfBoundsException;",
+ "Lnsk/jvmti/Exception/exception001b;", "meth3", "(I)I", 10,
+ "Lnsk/jvmti/Exception/exception001a;", "run", "()V", 34 }
};
static int eventsCount = 0;
static int eventsExpected = 0;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ExceptionCatch/excatch001/excatch001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ExceptionCatch/excatch001/excatch001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -55,12 +55,12 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static exceptionInfo exs[] = {
- {"Lnsk/jvmti/ExceptionCatch/excatch001c;",
- "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 14},
- {"Ljava/lang/ArithmeticException;",
- "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 24},
- {"Ljava/lang/ArrayIndexOutOfBoundsException;",
- "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 34}
+ { "Lnsk/jvmti/ExceptionCatch/excatch001c;",
+ "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 14 },
+ { "Ljava/lang/ArithmeticException;",
+ "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 24 },
+ { "Ljava/lang/ArrayIndexOutOfBoundsException;",
+ "Lnsk/jvmti/ExceptionCatch/excatch001a;", "run", "()V", 34 }
};
static int eventsCount = 0;
static int eventsExpected = 0;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetFieldName/getfldnm005/getfldnm005.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetFieldName/getfldnm005/getfldnm005.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -40,47 +40,47 @@
/* expected field signatures are below */
static const char *fld_sig[][FLDS_NUM] = {
- {"_getfldnm005St", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005;", "NULL"},
+ { "_getfldnm005St", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005;", "NULL" },
- {"_getfldnm005b", "instance",
- "Lnsk/jvmti/GetFieldName/getfldnm005b;",
- "Lnsk/jvmti/GetFieldName/getfldnm005b<Ljava/lang/String;>;"},
- {"_getfldnm005bSt", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005b;",
- "Lnsk/jvmti/GetFieldName/getfldnm005b<Ljava/lang/String;>;"},
+ { "_getfldnm005b", "instance",
+ "Lnsk/jvmti/GetFieldName/getfldnm005b;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005b<Ljava/lang/String;>;" },
+ { "_getfldnm005bSt", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005b;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005b<Ljava/lang/String;>;" },
- {"_getfldnm005c", "instance",
- "Lnsk/jvmti/GetFieldName/getfldnm005c;",
- "Lnsk/jvmti/GetFieldName/getfldnm005c<Ljava/lang/Boolean;Ljava/lang/Integer;>;"},
- {"_getfldnm005cSt", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005c;",
- "Lnsk/jvmti/GetFieldName/getfldnm005c<Ljava/lang/Boolean;Ljava/lang/Integer;>;"},
+ { "_getfldnm005c", "instance",
+ "Lnsk/jvmti/GetFieldName/getfldnm005c;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005c<Ljava/lang/Boolean;Ljava/lang/Integer;>;" },
+ { "_getfldnm005cSt", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005c;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005c<Ljava/lang/Boolean;Ljava/lang/Integer;>;" },
- {"_getfldnm005e", "instance",
- "Lnsk/jvmti/GetFieldName/getfldnm005e;",
- "NULL"},
- {"_getfldnm005eSt", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005e;",
- "NULL"},
+ { "_getfldnm005e", "instance",
+ "Lnsk/jvmti/GetFieldName/getfldnm005e;",
+ "NULL" },
+ { "_getfldnm005eSt", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005e;",
+ "NULL" },
- {"_getfldnm005if", "instance",
- "Lnsk/jvmti/GetFieldName/getfldnm005if;",
- "Lnsk/jvmti/GetFieldName/getfldnm005if<Ljava/lang/Object;>;"},
- {"_getfldnm005ifSt", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005if;",
- "Lnsk/jvmti/GetFieldName/getfldnm005if<Ljava/lang/Object;>;"},
+ { "_getfldnm005if", "instance",
+ "Lnsk/jvmti/GetFieldName/getfldnm005if;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005if<Ljava/lang/Object;>;" },
+ { "_getfldnm005ifSt", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005if;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005if<Ljava/lang/Object;>;" },
- {"_getfldnm005g", "instance",
- "Lnsk/jvmti/GetFieldName/getfldnm005g;",
- "Lnsk/jvmti/GetFieldName/getfldnm005g<Lnsk/jvmti/GetFieldName/getfldnm005f;>;"},
- {"_getfldnm005gSt", "static",
- "Lnsk/jvmti/GetFieldName/getfldnm005g;",
- "Lnsk/jvmti/GetFieldName/getfldnm005g<Lnsk/jvmti/GetFieldName/getfldnm005f;>;"},
+ { "_getfldnm005g", "instance",
+ "Lnsk/jvmti/GetFieldName/getfldnm005g;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005g<Lnsk/jvmti/GetFieldName/getfldnm005f;>;" },
+ { "_getfldnm005gSt", "static",
+ "Lnsk/jvmti/GetFieldName/getfldnm005g;",
+ "Lnsk/jvmti/GetFieldName/getfldnm005g<Lnsk/jvmti/GetFieldName/getfldnm005f;>;" },
- {"_getfldnm005gArr", "instance",
- "[Lnsk/jvmti/GetFieldName/getfldnm005g;",
- "NULL"}
+ { "_getfldnm005gArr", "instance",
+ "[Lnsk/jvmti/GetFieldName/getfldnm005g;",
+ "NULL" }
};
static jvmtiEnv *jvmti = NULL;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetFrameLocation/frameloc002/frameloc002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetFrameLocation/frameloc002/frameloc002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -45,8 +45,8 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static frame_info fi =
- {"Lnsk/jvmti/GetFrameLocation/frameloc002;", "check",
- "(Ljava/lang/Thread;)I", -1};
+ { "Lnsk/jvmti/GetFrameLocation/frameloc002;", "check",
+ "(Ljava/lang/Thread;)I", -1 };
#ifdef STATIC_BUILD
JNIEXPORT jint JNICALL Agent_OnLoad_frameloc002(JavaVM *jvm, char *options, void *reserved) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetMethodDeclaringClass/declcls003/declcls003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetMethodDeclaringClass/declcls003/declcls003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -37,7 +37,7 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static const char *exp_class_sig = "Ljava/lang/Object;";
-static const char *arr_sigs[] = {"[B", "[C", "[D", "[F", "[I", "[J", "[S", "[Z",
+static const char *arr_sigs[] = { "[B", "[C", "[D", "[F", "[I", "[J", "[S", "[Z",
"[Lnsk/jvmti/GetMethodDeclaringClass/declcls003;",
"[[Lnsk/jvmti/GetMethodDeclaringClass/declcls003;"
};
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetMethodName/methname003/methname003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetMethodName/methname003/methname003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -44,40 +44,40 @@
/* expected class signatures are below */
static const char *meth_sig[][METH_NUM][TOT_NUM] = {
- {{"methname003bMeth", "instance",
+ { { "methname003bMeth", "instance",
"(Lnsk/jvmti/GetMethodName/methname003b;)Lnsk/jvmti/GetMethodName/methname003b;",
- "<L:Ljava/lang/String;>(Lnsk/jvmti/GetMethodName/methname003b<TL;>;)Lnsk/jvmti/GetMethodName/methname003b<Ljava/lang/String;>;"},
- {"methname003bMethSt", "static",
- "(Lnsk/jvmti/GetMethodName/methname003b;)Lnsk/jvmti/GetMethodName/methname003b;",
- "<T:Ljava/lang/String;>(Lnsk/jvmti/GetMethodName/methname003b<TT;>;)Lnsk/jvmti/GetMethodName/methname003b<Ljava/lang/String;>;"}},
+ "<L:Ljava/lang/String;>(Lnsk/jvmti/GetMethodName/methname003b<TL;>;)Lnsk/jvmti/GetMethodName/methname003b<Ljava/lang/String;>;" },
+ { "methname003bMethSt", "static",
+ "(Lnsk/jvmti/GetMethodName/methname003b;)Lnsk/jvmti/GetMethodName/methname003b;",
+ "<T:Ljava/lang/String;>(Lnsk/jvmti/GetMethodName/methname003b<TT;>;)Lnsk/jvmti/GetMethodName/methname003b<Ljava/lang/String;>;" } },
- {{"methname003cMeth", "instance",
+ { { "methname003cMeth", "instance",
"(Ljava/lang/Class;)Ljava/lang/Object;",
- "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"},
- {"methname003cMethSt", "static",
- "(Ljava/lang/Class;)Ljava/lang/Object;",
- "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;"}},
+ "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;" },
+ { "methname003cMethSt", "static",
+ "(Ljava/lang/Class;)Ljava/lang/Object;",
+ "<U:Ljava/lang/Object;>(Ljava/lang/Class<TU;>;)TU;" } },
- {{"methname003eMeth", "instance",
+ { { "methname003eMeth", "instance",
"(Lnsk/jvmti/GetMethodName/methname003e;)V",
- "NULL"},
- {"methname003eMethSt", "static",
- "(Lnsk/jvmti/GetMethodName/methname003e;)V",
- "NULL"}},
+ "NULL" },
+ { "methname003eMethSt", "static",
+ "(Lnsk/jvmti/GetMethodName/methname003e;)V",
+ "NULL" } },
- {{"methname003ifMeth", "instance",
+ { { "methname003ifMeth", "instance",
"()I",
- "NULL"},
- {"methname003ifMeth2", "instance",
- "(Ljava/lang/Object;)I",
- "<T:Ljava/lang/Object;>(TT;)I"}},
+ "NULL" },
+ { "methname003ifMeth2", "instance",
+ "(Ljava/lang/Object;)I",
+ "<T:Ljava/lang/Object;>(TT;)I" } },
- {{"methname003gMeth", "instance",
+ { { "methname003gMeth", "instance",
"(Ljava/lang/Byte;Ljava/lang/Double;[Ljava/lang/Class;)V",
- "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;[Ljava/lang/Class<*>;)V"},
- {"methname003gMethSt", "static",
- "(Ljava/lang/Byte;Ljava/lang/Double;)V",
- "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;)V"}}
+ "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;[Ljava/lang/Class<*>;)V" },
+ { "methname003gMethSt", "static",
+ "(Ljava/lang/Byte;Ljava/lang/Double;)V",
+ "<A:Ljava/lang/Byte;B:Ljava/lang/Double;>(TA;TB;)V" } }
};
static jvmtiEnv *jvmti = NULL;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/IterateThroughHeap/filter-tagged/HeapFilter.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/IterateThroughHeap/filter-tagged/HeapFilter.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -66,10 +66,8 @@
static jint TAGGED_INT_VALUE = 0xC0DE02 + POISON;
static jint UNTAGGED_STATIC_INT_VALUE = 0xC0DE03 + POISON;
static jint UNTAGGED_INT_VALUE = 0xC0DE04 + POISON;
-static jint TAGGED_INT_ARRAY_VALUE[] = {0xC0DE01,
- 0xC0DE01+1};
-static jint UNTAGGED_INT_ARRAY_VALUE[] = {0xC0DE03,
- 0xC0DE03+1};
+static jint TAGGED_INT_ARRAY_VALUE[] = { 0xC0DE01, 0xC0DE01 + 1 };
+static jint UNTAGGED_INT_ARRAY_VALUE[] = { 0xC0DE03, 0xC0DE03 + 1 };
static const wchar_t *TAGGED_STRING_VALUE = L"I'm a tagged string";
static const wchar_t *UNTAGGED_STRING_VALUE = L"I'm an untagged string";
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/IterateThroughHeap/non-concrete-klass-filter/NonConcreteKlassFilter.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/IterateThroughHeap/non-concrete-klass-filter/NonConcreteKlassFilter.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -52,7 +52,7 @@
//klass-filters used in this test
#define FILTER_COUNT 2
static const char *types[] = { "nsk/jvmti/IterateThroughHeap/non_concrete_klass_filter/Interface",
- "nsk/jvmti/IterateThroughHeap/non_concrete_klass_filter/AbstractClass"};
+ "nsk/jvmti/IterateThroughHeap/non_concrete_klass_filter/AbstractClass" };
jint JNICALL field_callback(jvmtiHeapReferenceKind kind,
const jvmtiHeapReferenceInfo* info,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodEntry/mentry001/mentry001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodEntry/mentry001/mentry001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -54,9 +54,9 @@
static size_t eventsExpected = 0;
static size_t eventsCount = 0;
static entry_info entries[] = {
- {"check", "()I", -1},
- {"dummy", "()V", 0},
- {"chain", "()V", -1}
+ { "check", "()I", -1 },
+ { "dummy", "()V", 0 },
+ { "chain", "()V", -1 }
};
void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodExit/mexit001/mexit001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodExit/mexit001/mexit001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -50,8 +50,8 @@
static size_t eventsExpected = 0;
static size_t eventsCount = 0;
static exit_info exits[] = {
- {"Lnsk/jvmti/MethodExit/mexit001a;", "chain", "()V", -1},
- {"Lnsk/jvmti/MethodExit/mexit001a;", "dummy", "()V", 3}
+ { "Lnsk/jvmti/MethodExit/mexit001a;", "chain", "()V", -1 },
+ { "Lnsk/jvmti/MethodExit/mexit001a;", "dummy", "()V", 3 }
};
void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodExit/mexit002/mexit002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/MethodExit/mexit002/mexit002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -50,8 +50,8 @@
static size_t eventsExpected = 0;
static size_t eventsCount = 0;
static exit_info exits[] = {
- {"Lnsk/jvmti/MethodExit/mexit002a;", "chain", "()V", -1},
- {"Lnsk/jvmti/MethodExit/mexit002a;", "dummy", "()V", 3}
+ { "Lnsk/jvmti/MethodExit/mexit002a;", "chain", "()V", -1 },
+ { "Lnsk/jvmti/MethodExit/mexit002a;", "dummy", "()V", 3 }
};
void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/NativeMethodBind/nativemethbind001/nativemethbind001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/NativeMethodBind/nativemethbind001/nativemethbind001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -39,15 +39,15 @@
/* tested methods */
#define METH_NUM 2
static const char *METHODS[][2] = {
- {"nativeMethod", "(Z)V"},
- {"anotherNativeMethod", "()V"},
+ { "nativeMethod", "(Z)V" },
+ { "anotherNativeMethod", "()V" },
};
/* event counters for the tested methods and expected numbers
of the events */
static volatile int bindEv[][2] = {
- {0, 1},
- {0, 1}
+ { 0, 1 },
+ { 0, 1 }
};
static const char *CLASS_SIG =
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/PopFrame/popframe006/popframe006.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/PopFrame/popframe006/popframe006.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -51,15 +51,15 @@
static int stepCount = 0, stepExpected = 0;
static int popCount = 0, popExpected = 0;
static check_info checks[] = {
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "run", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "C", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "C", "()V", 0},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 3},
- {"Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 3}
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "run", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "C", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "C", "()V", 0 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "B", "()V", 3 },
+ { "Lnsk/jvmti/PopFrame/popframe006$TestThread;", "A", "()V", 3 }
};
void check(jvmtiEnv *jvmti_env, jmethodID mid, jlocation loc, int i) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/PopFrame/popframe008/popframe008.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/PopFrame/popframe008/popframe008.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -50,10 +50,10 @@
static int framesExpected = 0;
static int framesCount = 0;
static frame_info frames[] = {
- {"Lnsk/jvmti/PopFrame/popframe008$TestThread;", "C", "()V", 1},
- {"Lnsk/jvmti/PopFrame/popframe008$TestThread;", "B", "()V", 1},
- {"Lnsk/jvmti/PopFrame/popframe008$TestThread;", "A", "()V", 1},
- {"Lnsk/jvmti/PopFrame/popframe008$TestThread;", "run", "()V", 1}
+ { "Lnsk/jvmti/PopFrame/popframe008$TestThread;", "C", "()V", 1 },
+ { "Lnsk/jvmti/PopFrame/popframe008$TestThread;", "B", "()V", 1 },
+ { "Lnsk/jvmti/PopFrame/popframe008$TestThread;", "A", "()V", 1 },
+ { "Lnsk/jvmti/PopFrame/popframe008$TestThread;", "run", "()V", 1 }
};
void check(jvmtiEnv *jvmti_env, jmethodID mid, jlocation loc, int i) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass008/redefclass008.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass008/redefclass008.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -45,11 +45,11 @@
/* list of breakpoints */
static breakpoint breakpoints[] = {
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 0, NULL},
- {1, (char*) "finMethod", (char*) "(JIJ)V", 5, NULL},
- {1, (char*) "finMethod", (char*) "(JIJ)V", 4, NULL},
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 1, NULL},
- {0, (char*) "statMethod", (char*) "(III)I", 1, NULL}
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 0, NULL },
+ { 1, (char*) "finMethod", (char*) "(JIJ)V", 5, NULL },
+ { 1, (char*) "finMethod", (char*) "(JIJ)V", 4, NULL },
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 1, NULL },
+ { 0, (char*) "statMethod", (char*) "(III)I", 1, NULL }
};
static jclass redefCls; /* JNI's Java class object */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass009/redefclass009.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass009/redefclass009.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -42,33 +42,33 @@
/* local variables of redefined methods */
static localVar constr_lv[] = { /* constructor's local variables */
- {(char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;"},
- {(char*) "constr_i", (char*) "I"},
- {(char*) "constr_l", (char*) "J"},
- {(char*) "constr_d", (char*) "D"},
- {(char*) "constr_f", (char*) "F"},
- {(char*) "constr_c", (char*) "C"}
+ { (char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;" },
+ { (char*) "constr_i", (char*) "I" },
+ { (char*) "constr_l", (char*) "J" },
+ { (char*) "constr_d", (char*) "D" },
+ { (char*) "constr_f", (char*) "F" },
+ { (char*) "constr_c", (char*) "C" }
};
static localVar checkIt_lv[] = { /* checkIt()'s local variables */
- {(char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;"},
- {(char*) "out", (char*) "Ljava/io/PrintStream;"},
- {(char*) "DEBUG_MODE", (char*) "Z"}
+ { (char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;" },
+ { (char*) "out", (char*) "Ljava/io/PrintStream;" },
+ { (char*) "DEBUG_MODE", (char*) "Z" }
};
static localVar finMeth_lv[] = { /* finMethod()'s local variables */
- {(char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;"},
- {(char*) "fin_c", (char*) "C"},
- {(char*) "fin_i", (char*) "J"},
- {(char*) "fin_j", (char*) "I"},
- {(char*) "fin_k", (char*) "J"},
- {(char*) "fin_l", (char*) "J"},
- {(char*) "fin_f", (char*) "F"}
+ { (char*) "this", (char*) "Lnsk/jvmti/RedefineClasses/redefclass009r;" },
+ { (char*) "fin_c", (char*) "C" },
+ { (char*) "fin_i", (char*) "J" },
+ { (char*) "fin_j", (char*) "I" },
+ { (char*) "fin_k", (char*) "J" },
+ { (char*) "fin_l", (char*) "J" },
+ { (char*) "fin_f", (char*) "F" }
};
static localVar statMeth_lv[] = { /* statMethod()'s local variables */
- {(char*) "stat_x", (char*) "I"},
- {(char*) "stat_y", (char*) "I"},
- {(char*) "stat_z", (char*) "I"},
- {(char*) "stat_j", (char*) "D"},
- {(char*) "stat_i", (char*) "I"}
+ { (char*) "stat_x", (char*) "I" },
+ { (char*) "stat_y", (char*) "I" },
+ { (char*) "stat_z", (char*) "I" },
+ { (char*) "stat_j", (char*) "D" },
+ { (char*) "stat_i", (char*) "I" }
};
typedef struct { /* local variables of a method */
@@ -82,18 +82,18 @@
/* list of original methods with NULL pointers to localVar */
static methInfo origMethInfo[] = {
- {1, (char*) "<init>", (char*) "()V", 1, NULL, NULL},
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 4, NULL, NULL},
- {1, (char*) "finMethod", (char*) "(CJIJ)V", 5, NULL, NULL},
- {0, (char*) "statMethod", (char*) "(III)D", 3, NULL, NULL}
+ { 1, (char*) "<init>", (char*) "()V", 1, NULL, NULL },
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 4, NULL, NULL },
+ { 1, (char*) "finMethod", (char*) "(CJIJ)V", 5, NULL, NULL },
+ { 0, (char*) "statMethod", (char*) "(III)D", 3, NULL, NULL }
};
/* list of redefined methods */
static methInfo redefMethInfo[] = {
- {1, (char*) "<init>", (char*) "()V", 6, constr_lv, NULL},
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, checkIt_lv, NULL},
- {1, (char*) "finMethod", (char*) "(CJIJ)V", 7, finMeth_lv, NULL},
- {0, (char*) "statMethod", (char*) "(III)D", 5, statMeth_lv, NULL}
+ { 1, (char*) "<init>", (char*) "()V", 6, constr_lv, NULL },
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, checkIt_lv, NULL },
+ { 1, (char*) "finMethod", (char*) "(CJIJ)V", 7, finMeth_lv, NULL },
+ { 0, (char*) "statMethod", (char*) "(III)D", 5, statMeth_lv, NULL }
};
static jvmtiEnv *jvmti = NULL;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass010/redefclass010.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass010/redefclass010.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -37,18 +37,18 @@
/* line number matrix of original methods */
static int orig_ln[METH_NUM][8] = {
- {34, 0, 0, 0, 0, 0, 0, 0}, /* <init> */
- {40,41,43, 0, 0, 0, 0, 0}, /* checkIt */
- {55, 0, 0, 0, 0, 0, 0, 0}, /* finMethod */
- {48,50,51,50,52, 0, 0, 0} /* statMethod */
+ { 34, 0, 0, 0, 0, 0, 0, 0 }, /* <init> */
+ { 40,41,43, 0, 0, 0, 0, 0 }, /* checkIt */
+ { 55, 0, 0, 0, 0, 0, 0, 0 }, /* finMethod */
+ { 48,50,51,50,52, 0, 0, 0 } /* statMethod */
};
/* line number matrix of redefined methods */
static int redf_ln[METH_NUM][8] = {
- {38,39,40,41,42,43,44,46}, /* <init> */
- {51,53,55, 0, 0, 0, 0, 0}, /* checkIt */
- {64,66,67,68,69,70,72, 0}, /* finMethod */
- {60, 0, 0, 0, 0, 0, 0, 0} /* statMethod */
+ { 38,39,40,41,42,43,44,46 }, /* <init> */
+ { 51,53,55, 0, 0, 0, 0, 0 }, /* checkIt */
+ { 64,66,67,68,69,70,72, 0 }, /* finMethod */
+ { 60, 0, 0, 0, 0, 0, 0, 0 } /* statMethod */
};
typedef struct { /* line numbers of a method */
@@ -61,18 +61,18 @@
/* list of original methods */
static methInfo origMethInfo[] = {
- {1, (char*) "<init>", (char*) "()V", 1, NULL},
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, NULL},
- {1, (char*) "finMethod", (char*) "(CJIJ)V", 1, NULL},
- {0, (char*) "statMethod", (char*) "(III)D", 5, NULL}
+ { 1, (char*) "<init>", (char*) "()V", 1, NULL },
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, NULL },
+ { 1, (char*) "finMethod", (char*) "(CJIJ)V", 1, NULL },
+ { 0, (char*) "statMethod", (char*) "(III)D", 5, NULL }
};
/* list of redefined methods */
static methInfo redefMethInfo[] = {
- {1, (char*) "<init>", (char*) "()V", 8, NULL},
- {1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, NULL},
- {1, (char*) "finMethod", (char*) "(CJIJ)V", 7, NULL},
- {0, (char*) "statMethod", (char*) "(III)D", 1, NULL}
+ { 1, (char*) "<init>", (char*) "()V", 8, NULL },
+ { 1, (char*) "checkIt", (char*) "(Ljava/io/PrintStream;Z)I", 3, NULL },
+ { 1, (char*) "finMethod", (char*) "(CJIJ)V", 7, NULL },
+ { 0, (char*) "statMethod", (char*) "(III)D", 1, NULL }
};
static jvmtiEnv *jvmti = NULL;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass019/redefclass019.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass019/redefclass019.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -62,33 +62,33 @@
static const char *cls_exp = "Lnsk/jvmti/RedefineClasses/redefclass019a;";
static var_info run[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0 }
};
static var_info checkPoint[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0 }
};
static var_info chain1[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0},
- {"localInt1", "I", 2},
- {"localInt2", "I", 3333}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0 },
+ { "localInt1", "I", 2 },
+ { "localInt2", "I", 3333 }
};
static var_info chain2[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0 }
};
static var_info chain3[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass019a;", 0 }
};
static frame_info frames[] = {
- {JNI_TRUE, "checkPoint", "()V", 115, 1, checkPoint},
- {JNI_FALSE, "chain3", "()V", 49, 1, chain3},
- {JNI_FALSE, "chain2", "()V", 44, 1, chain2},
- {JNI_FALSE, "chain1", "()V", 39, 3, chain1},
- {JNI_FALSE, "run", "()V", 32, 1, run},
+ { JNI_TRUE, "checkPoint", "()V", 115, 1, checkPoint },
+ { JNI_FALSE, "chain3", "()V", 49, 1, chain3 },
+ { JNI_FALSE, "chain2", "()V", 44, 1, chain2 },
+ { JNI_FALSE, "chain1", "()V", 39, 3, chain1 },
+ { JNI_FALSE, "run", "()V", 32, 1, run },
};
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass027/redefclass027.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RedefineClasses/redefclass027/redefclass027.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -80,38 +80,38 @@
static const char *cls_exp = "Lnsk/jvmti/RedefineClasses/redefclass027a;";
static var_info run[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0},
- {"localInt1", "I", 1}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0 },
+ { "localInt1", "I", 1 }
};
static var_info method1[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0},
- {"argInt1", "I", 10},
- {"localInt2", "I", 2},
- {"ex", "Ljava/lang/Exception;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0 },
+ { "argInt1", "I", 10 },
+ { "localInt2", "I", 2 },
+ { "ex", "Ljava/lang/Exception;", 0 }
};
static var_info pop[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0},
- {"argInt1", "I", 10},
- {"localInt2", "I", 2},
- {"ex", "Ljava/lang/Exception;", 0}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0 },
+ { "argInt1", "I", 10 },
+ { "localInt2", "I", 2 },
+ { "ex", "Ljava/lang/Exception;", 0 }
};
static var_info method2[] = {
- {"this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0},
- {"argInt2", "I", 20},
- {"localInt4", "I", 4}
+ { "this", "Lnsk/jvmti/RedefineClasses/redefclass027a;", 0 },
+ { "argInt2", "I", 20 },
+ { "localInt4", "I", 4 }
};
static frame_info frames[] = {
- {JNI_FALSE, "run", "()V", 97, 2, run, "bp"},
- {JNI_FALSE, "run", "()V", 97, 2, run, "step"},
- {JNI_FALSE, "run", "()V", 99, 2, run, "mod"},
- {JNI_FALSE, "method2", "(I)V", 116, 3, method2, "acc"},
- {JNI_FALSE, "method2", "(I)V", 117, 3, method2, "exc"},
- {JNI_FALSE, "method1", "(I)V", 108, 4, method1, "catch"},
- {JNI_FALSE, "method1", "(I)V", 112, 4, pop, "pop"},
+ { JNI_FALSE, "run", "()V", 97, 2, run, "bp" },
+ { JNI_FALSE, "run", "()V", 97, 2, run, "step" },
+ { JNI_FALSE, "run", "()V", 99, 2, run, "mod" },
+ { JNI_FALSE, "method2", "(I)V", 116, 3, method2, "acc" },
+ { JNI_FALSE, "method2", "(I)V", 117, 3, method2, "exc" },
+ { JNI_FALSE, "method1", "(I)V", 108, 4, method1, "catch" },
+ { JNI_FALSE, "method1", "(I)V", 112, 4, pop, "pop" },
};
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/setfldw001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/setfldw001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -48,12 +48,12 @@
static jvmtiCapabilities caps;
static jint result = PASSED;
static field fields[] = {
- {"nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld0", "I", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld1", "I", 1, NULL, NULL},
- {"nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld2",
- "Lnsk/jvmti/SetFieldAccessWatch/setfldw001a;", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldAccessWatch/setfldw001a", "fld3", "[I", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldAccessWatch/setfldw001b", "fld4", "F", 0, NULL, NULL},
+ { "nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld0", "I", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld1", "I", 1, NULL, NULL },
+ { "nsk/jvmti/SetFieldAccessWatch/setfldw001", "fld2",
+ "Lnsk/jvmti/SetFieldAccessWatch/setfldw001a;", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldAccessWatch/setfldw001a", "fld3", "[I", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldAccessWatch/setfldw001b", "fld4", "F", 0, NULL, NULL },
};
void setWatch(JNIEnv *env, jint ind) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw003/setfldw003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw003/setfldw003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -40,7 +40,7 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static jfieldID actual_fid = NULL;
-static jfieldID fids[4] = {NULL, NULL, NULL, NULL};
+static jfieldID fids[4] = { NULL, NULL, NULL, NULL };
void JNICALL FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,
jthread thr, jmethodID method,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw004/setfldw004.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw004/setfldw004.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -40,7 +40,7 @@
static jint result = PASSED;
static jboolean printdump = JNI_FALSE;
static jfieldID actual_fid = NULL;
-static jfieldID fids[4] = {NULL, NULL, NULL, NULL};
+static jfieldID fids[4] = { NULL, NULL, NULL, NULL };
void JNICALL FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,
jthread thr, jmethodID method,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw005/setfldw005.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw005/setfldw005.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -49,22 +49,22 @@
static jboolean printdump = JNI_FALSE;
static jfieldID actual_fid = NULL;
static field fields[] = {
- {"fld0", "J", JNI_TRUE, NULL, "static long"},
- {"fld1", "J", JNI_FALSE, NULL, "long"},
- {"fld2", "F", JNI_TRUE, NULL, "static float"},
- {"fld3", "F", JNI_FALSE, NULL, "float"},
- {"fld4", "D", JNI_TRUE, NULL, "static double"},
- {"fld5", "D", JNI_FALSE, NULL, "double"},
- {"fld6", "Ljava/lang/Object;", JNI_TRUE, NULL, "static Object"},
- {"fld7", "Ljava/lang/Object;", JNI_FALSE, NULL, "Object"},
- {"fld8", "Z", JNI_TRUE, NULL, "static boolean"},
- {"fld9", "Z", JNI_FALSE, NULL, "boolean"},
- {"fld10", "B", JNI_TRUE, NULL, "static byte"},
- {"fld11", "B", JNI_FALSE, NULL, "byte"},
- {"fld12", "S", JNI_TRUE, NULL, "static short"},
- {"fld13", "S", JNI_FALSE, NULL, "short"},
- {"fld14", "C", JNI_TRUE, NULL, "static char"},
- {"fld15", "C", JNI_FALSE, NULL, "char"}
+ { "fld0", "J", JNI_TRUE, NULL, "static long" },
+ { "fld1", "J", JNI_FALSE, NULL, "long" },
+ { "fld2", "F", JNI_TRUE, NULL, "static float" },
+ { "fld3", "F", JNI_FALSE, NULL, "float" },
+ { "fld4", "D", JNI_TRUE, NULL, "static double" },
+ { "fld5", "D", JNI_FALSE, NULL, "double" },
+ { "fld6", "Ljava/lang/Object;", JNI_TRUE, NULL, "static Object" },
+ { "fld7", "Ljava/lang/Object;", JNI_FALSE, NULL, "Object" },
+ { "fld8", "Z", JNI_TRUE, NULL, "static boolean" },
+ { "fld9", "Z", JNI_FALSE, NULL, "boolean" },
+ { "fld10", "B", JNI_TRUE, NULL, "static byte" },
+ { "fld11", "B", JNI_FALSE, NULL, "byte" },
+ { "fld12", "S", JNI_TRUE, NULL, "static short" },
+ { "fld13", "S", JNI_FALSE, NULL, "short" },
+ { "fld14", "C", JNI_TRUE, NULL, "static char" },
+ { "fld15", "C", JNI_FALSE, NULL, "char" }
};
void JNICALL FieldAccess(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw001/setfmodw001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw001/setfmodw001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -48,12 +48,12 @@
static jvmtiCapabilities caps;
static jint result = PASSED;
static field fields[] = {
- {"nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld0", "I", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld1", "I", 1, NULL, NULL},
- {"nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld2",
- "Lnsk/jvmti/SetFieldModificationWatch/setfmodw001a;", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldModificationWatch/setfmodw001a", "fld3", "[I", 0, NULL, NULL},
- {"nsk/jvmti/SetFieldModificationWatch/setfmodw001b", "fld4", "F", 0, NULL, NULL},
+ { "nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld0", "I", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld1", "I", 1, NULL, NULL },
+ { "nsk/jvmti/SetFieldModificationWatch/setfmodw001", "fld2",
+ "Lnsk/jvmti/SetFieldModificationWatch/setfmodw001a;", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldModificationWatch/setfmodw001a", "fld3", "[I", 0, NULL, NULL },
+ { "nsk/jvmti/SetFieldModificationWatch/setfmodw001b", "fld4", "F", 0, NULL, NULL },
};
void setWatch(JNIEnv *env, jint ind) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw003/setfmodw003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw003/setfmodw003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -51,10 +51,10 @@
static char actual_sig = '\0';
static jint actual_val = 0;
static field flds[] = {
- {"fld0", 'I', JNI_TRUE, 42, NULL},
- {"fld1", 'I', JNI_TRUE, 43, NULL},
- {"fld2", 'I', JNI_FALSE, 44, NULL},
- {"fld3", 'I', JNI_FALSE, 45, NULL}
+ { "fld0", 'I', JNI_TRUE, 42, NULL },
+ { "fld1", 'I', JNI_TRUE, 43, NULL },
+ { "fld2", 'I', JNI_FALSE, 44, NULL },
+ { "fld3", 'I', JNI_FALSE, 45, NULL }
};
void JNICALL FieldModification(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw004/setfmodw004.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw004/setfmodw004.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -51,10 +51,10 @@
static char actual_sig = '\0';
static jint actual_val = 0;
static field flds[] = {
- {"fld0", 'I', JNI_TRUE, 96, NULL},
- {"fld1", 'I', JNI_TRUE, 97, NULL},
- {"fld2", 'I', JNI_FALSE, 98, NULL},
- {"fld3", 'I', JNI_FALSE, 99, NULL}
+ { "fld0", 'I', JNI_TRUE, 96, NULL },
+ { "fld1", 'I', JNI_TRUE, 97, NULL },
+ { "fld2", 'I', JNI_FALSE, 98, NULL },
+ { "fld3", 'I', JNI_FALSE, 99, NULL }
};
void JNICALL FieldModification(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw005/setfmodw005.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetFieldModificationWatch/setfmodw005/setfmodw005.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -52,22 +52,22 @@
static char actual_sig = '\0';
static jvalue actual_val = {};
static field flds[] = {
- {"fld0", "J", JNI_TRUE, "static long", NULL, {} },
- {"fld1", "J", JNI_FALSE, "long", NULL, {} },
- {"fld2", "F", JNI_TRUE, "static float", NULL, {} },
- {"fld3", "F", JNI_FALSE, "float", NULL, {} },
- {"fld4", "D", JNI_TRUE, "static double", NULL, {} },
- {"fld5", "D", JNI_FALSE, "double", NULL, {} },
- {"fld6", "Ljava/lang/Object;", JNI_TRUE, "static Object", NULL, {} },
- {"fld7", "Ljava/lang/Object;", JNI_FALSE, "Object", NULL, {} },
- {"fld8", "Z", JNI_TRUE, "static boolean", NULL, {} },
- {"fld9", "Z", JNI_FALSE, "boolean", NULL, {} },
- {"fld10", "B", JNI_TRUE, "static byte", NULL, {} },
- {"fld11", "B", JNI_FALSE, "byte", NULL, {} },
- {"fld12", "S", JNI_TRUE, "static short", NULL, {} },
- {"fld13", "S", JNI_FALSE, "short", NULL, {} },
- {"fld14", "C", JNI_TRUE, "static char", NULL, {} },
- {"fld15", "C", JNI_FALSE, "char", NULL, {} }
+ { "fld0", "J", JNI_TRUE, "static long", NULL, {} },
+ { "fld1", "J", JNI_FALSE, "long", NULL, {} },
+ { "fld2", "F", JNI_TRUE, "static float", NULL, {} },
+ { "fld3", "F", JNI_FALSE, "float", NULL, {} },
+ { "fld4", "D", JNI_TRUE, "static double", NULL, {} },
+ { "fld5", "D", JNI_FALSE, "double", NULL, {} },
+ { "fld6", "Ljava/lang/Object;", JNI_TRUE, "static Object", NULL, {} },
+ { "fld7", "Ljava/lang/Object;", JNI_FALSE, "Object", NULL, {} },
+ { "fld8", "Z", JNI_TRUE, "static boolean", NULL, {} },
+ { "fld9", "Z", JNI_FALSE, "boolean", NULL, {} },
+ { "fld10", "B", JNI_TRUE, "static byte", NULL, {} },
+ { "fld11", "B", JNI_FALSE, "byte", NULL, {} },
+ { "fld12", "S", JNI_TRUE, "static short", NULL, {} },
+ { "fld13", "S", JNI_FALSE, "short", NULL, {} },
+ { "fld14", "C", JNI_TRUE, "static char", NULL, {} },
+ { "fld15", "C", JNI_FALSE, "char", NULL, {} }
};
void JNICALL FieldModification(jvmtiEnv *jvmti_env, JNIEnv *env,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetSystemProperty/setsysprop003/setsysprop003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetSystemProperty/setsysprop003/setsysprop003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -41,9 +41,9 @@
} PropertyDesc;
static PropertyDesc propDescList[PROPERTIES_COUNT] = {
- {"nsk.jvmti.test.property", "new value of nsk.jvmti.test.property"},
- {"nsk.jvmti.test.property.empty.old", "new value of nsk.jvmti.test.property.emply.old"},
- {"nsk.jvmti.test.property.empty.new", ""}
+ { "nsk.jvmti.test.property", "new value of nsk.jvmti.test.property" },
+ { "nsk.jvmti.test.property.empty.old", "new value of nsk.jvmti.test.property.emply.old" },
+ { "nsk.jvmti.test.property.empty.new", "" }
};
/* ============================================================================= */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep001/singlestep001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep001/singlestep001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -48,7 +48,7 @@
"([Ljava/lang/String;Ljava/io/PrintStream;)I"
};
-static volatile long stepEv[] = {0, 0};
+static volatile long stepEv[] = { 0, 0 };
static const char *CLASS_SIG =
"Lnsk/jvmti/SingleStep/singlestep001;";
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -39,19 +39,19 @@
/* tested methods */
#define METH_NUM 4
static const char *METHODS[][2] = {
- {"bpMethod", "()V"},
- {"nativeMethod", "()V"},
- {"anotherNativeMethod", "(I)V"},
- {"runThis", "([Ljava/lang/String;Ljava/io/PrintStream;)I"}
+ { "bpMethod", "()V" },
+ { "nativeMethod", "()V" },
+ { "anotherNativeMethod", "(I)V" },
+ { "runThis", "([Ljava/lang/String;Ljava/io/PrintStream;)I" }
};
/* event counters for the tested methods and expected numbers
of the events */
static volatile long stepEv[][2] = {
- {0, 1},
- {0, 0},
- {0, 0},
- {0, 1}
+ { 0, 1 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 1 }
};
static const char *CLASS_SIG =
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM05/em05t001/em05t001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM05/em05t001/em05t001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -65,8 +65,8 @@
/* descriptions of tested methods */
static MethodDesc methodsDesc[METHODS_COUNT] = {
- {"javaMethod", "(I)I", NULL, 0, 0, 0},
- {"nativeMethod", "(I)I", NULL, 0, 0, 0}
+ { "javaMethod", "(I)I", NULL, 0, 0, 0 },
+ { "nativeMethod", "(I)I", NULL, 0, 0, 0 }
};
/* ============================================================================= */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM05/em05t002/em05t002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM05/em05t002/em05t002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -71,8 +71,8 @@
/* descriptions of tested methods */
static MethodDesc methodsDesc[METHODS_COUNT] = {
- {"javaMethod", "(I)I", NULL, 0, {}, {} },
- {"nativeMethod", "(I)I", NULL, 0, {}, {} }
+ { "javaMethod", "(I)I", NULL, 0, {}, {} },
+ { "nativeMethod", "(I)I", NULL, 0, {}, {} }
};
/* current compilation moment */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/jni_interception/JI03/ji03t002/ji03t002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/jni_interception/JI03/ji03t002/ji03t002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -53,8 +53,8 @@
} methInfo;
static methInfo meth_info[] = {
- {0, "statMeth", "(I)D", NULL, "statMeth_calls", NULL, 0, 0},
- {1, "voidMeth", "()V", NULL, "voidMeth_calls", NULL, 0, 0}
+ { 0, "statMeth", "(I)D", NULL, "statMeth_calls", NULL, 0, 0 },
+ { 1, "voidMeth", "()V", NULL, "voidMeth_calls", NULL, 0, 0 }
};
/* the original JNI function table */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t001/sp02t001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t001/sp02t001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -50,12 +50,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", 2, NULL},
- {"threadEntering", 2, NULL},
- {"threadWaiting", 2, NULL},
- {"threadSleeping", 2, NULL},
- {"threadRunningInterrupted", 2, NULL},
- {"threadRunningNative", 2, NULL}
+ { "threadRunning", 2, NULL },
+ { "threadEntering", 2, NULL },
+ { "threadWaiting", 2, NULL },
+ { "threadSleeping", 2, NULL },
+ { "threadRunningInterrupted", 2, NULL },
+ { "threadRunningNative", 2, NULL }
};
/* ============================================================================= */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t002/sp02t002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t002/sp02t002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -54,12 +54,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadEntering", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadWaiting", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadSleeping", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadRunningInterrupted", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadRunningNative", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}
+ { "threadRunning", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadEntering", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadWaiting", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadSleeping", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadRunningInterrupted", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadRunningNative", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION }
};
/* indexes of known threads */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t003/sp02t003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP02/sp02t003/sp02t003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -54,12 +54,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadEntering", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadWaiting", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadSleeping", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadRunningInterrupted", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION},
- {"threadRunningNative", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION}
+ { "threadRunning", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadEntering", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadWaiting", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadSleeping", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadRunningInterrupted", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION },
+ { "threadRunningNative", "testedMethod", "()V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION }
};
/* indexes of known threads */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t001/sp06t001.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t001/sp06t001.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -62,12 +62,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE},
- {"threadEntering", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE},
- {"threadWaiting", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE},
- {"threadSleeping", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE},
- {"threadRunningInterrupted", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE},
- {"threadRunningNative", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE}
+ { "threadRunning", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE },
+ { "threadEntering", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE },
+ { "threadWaiting", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE },
+ { "threadSleeping", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE },
+ { "threadRunningInterrupted", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE },
+ { "threadRunningNative", "testedMethod", "(ZI)V", 2, NULL, NULL, NULL, NSK_FALSE }
};
/* indexes of known threads */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t002/sp06t002.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t002/sp06t002.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -62,12 +62,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadEntering", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadWaiting", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadSleeping", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadRunningInterrupted", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadRunningNative", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE}
+ { "threadRunning", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadEntering", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadWaiting", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadSleeping", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadRunningInterrupted", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadRunningNative", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE }
};
/* indexes of known threads */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t003/sp06t003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/sampling/SP06/sp06t003/sp06t003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -62,12 +62,12 @@
/* descriptions of tested threads */
static ThreadDesc threadsDesc[THREADS_COUNT] = {
- {"threadRunning", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadEntering", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadWaiting", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadSleeping", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadRunningInterrupted", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE},
- {"threadRunningNative", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE}
+ { "threadRunning", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadEntering", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadWaiting", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadSleeping", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadRunningInterrupted", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE },
+ { "threadRunningNative", "testedMethod", "(ZI)V", NULL, NULL, NULL, NSK_JVMTI_INVALID_JLOCATION, NSK_FALSE }
};
/* indexes of known threads */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase.java Wed Dec 05 17:05:42 2018 -0500
@@ -54,8 +54,7 @@
}
}
- native static int doForceEarlyReturn(Class targCls,
- Thread earlyretThr, long valToRet);
+ native static int doForceEarlyReturn(Thread earlyretThr, long valToRet);
native static int suspThread(earlyretThread earlyretThr);
native static int resThread(earlyretThread earlyretThr);
native static int check();
@@ -96,8 +95,7 @@
out.println("Forcing early return...");
// force return from a top frame of the child thread
- retCode = doForceEarlyReturn(earlyretThread.class,
- earlyretThr, JAVA_BIRTH_YEAR);
+ retCode = doForceEarlyReturn(earlyretThr, JAVA_BIRTH_YEAR);
earlyretDone = true;
earlyretThr.letItGo();
if (retCode != Consts.TEST_PASSED) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -78,22 +78,29 @@
JNIEXPORT jint JNICALL
Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_suspThread(JNIEnv *env,
jclass cls, jobject earlyretThr) {
- jvmtiError err;
if (!caps.can_force_early_return || !caps.can_suspend) {
return PASSED;
}
- printf(">>>>>>>> Invoke SuspendThread()\n");
- err = jvmti->SuspendThread(earlyretThr);
- if (err != JVMTI_ERROR_NONE) {
- printf("%s: Failed to call SuspendThread(): error=%d: %s\n",
- __FILE__, err, TranslateError(err));
- return JNI_ERR;
+ jclass clazz = env->GetObjectClass(earlyretThr);
+ if (clazz == NULL) {
+ printf("Cannot get class of thread object\n");
+ RETURN_FAILED;
}
- printf("<<<<<<<< SuspendThread() is successfully done\n");
- fflush(0);
- return PASSED;
+
+ midActiveMethod = env->GetMethodID(clazz, name_exp, sig_exp);
+ if (midActiveMethod == NULL) {
+ printf("Cannot find Method ID for method %s\n", name_exp);
+ RETURN_FAILED;
+ }
+
+ int result = suspendThreadAtMethod(jvmti, cls, earlyretThr, midActiveMethod);
+ if( result == NSK_TRUE) {
+ return PASSED;
+ } else {
+ RETURN_FAILED;
+ }
}
JNIEXPORT jint JNICALL
@@ -119,7 +126,7 @@
JNIEXPORT jint JNICALL
Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_doForceEarlyReturn(JNIEnv *env,
- jclass cls, jclass targCls, jthread earlyretThr, jlong valToRet) {
+ jclass cls, jthread earlyretThr, jlong valToRet) {
jvmtiError err;
if (!caps.can_force_early_return || !caps.can_suspend) {
@@ -160,14 +167,6 @@
}
printf(">>>>>>>> Invoke ForceEarlyReturn()\n");
- printf("Before call to GetMethodID(%s, %s)\n", name_exp, sig_exp);
- midActiveMethod = env->GetMethodID(targCls, name_exp, sig_exp);
- if (midActiveMethod == NULL) {
- printf("Cannot find Method ID for method %s\n", name_exp);
- RETURN_FAILED;
- }
- printf("After call to GetMethodID(%s, %s)\n", name_exp, sig_exp);
-
err = jvmti->ForceEarlyReturnLong(earlyretThr, valToRet);
if (err != JVMTI_ERROR_NONE) {
printf("TEST FAILED: the function ForceEarlyReturn()"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/MethodBind/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/MethodBind/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,8 +29,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/StackTrace/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/StackTrace/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -32,8 +32,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/AddToBootstrapClassLoaderSearch/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/AddToBootstrapClassLoaderSearch/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,8 +29,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/Dispose/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/Dispose/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,8 +29,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/ForceGarbageCollection/gc/gc.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/ForceGarbageCollection/gc/gc.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,7 +29,7 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
#define THREADS_LIMIT 8
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/environment/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/environment/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,8 +29,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/nosuspendMonitorInfo/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/nosuspendMonitorInfo/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -29,8 +29,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/nosuspendStackTrace/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/nosuspendStackTrace/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -28,8 +28,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -51,8 +51,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf(" unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf(" unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf(" %d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/setNullVMInit/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/setNullVMInit/JvmtiTest/JvmtiTest.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -38,8 +38,8 @@
extern "C" {
-#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res;}
-#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res;}
+#define JVMTI_ERROR_CHECK(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); return res; }
+#define JVMTI_ERROR_CHECK_EXPECTED_ERROR(str,res,err) if (res != err) { printf(str); printf("unexpected error %d\n",res); return res; }
#define JVMTI_ERROR_CHECK_VOID(str,res) if (res != JVMTI_ERROR_NONE) { printf(str); printf("%d\n",res); iGlobalStatus = 2; }
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/AddToBootstrapClassLoaderSearch/bootclssearch_agent.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/AddToBootstrapClassLoaderSearch/bootclssearch_agent.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -37,7 +37,7 @@
static char segment1[3000] = "";
static char segment2[3000] = "";
-static const char* const illegal_segments[] = {"", "tmp/"};
+static const char* const illegal_segments[] = { "", "tmp/" };
jboolean use_segment2 = JNI_FALSE;
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/AddToSystemClassLoaderSearch/systemclssearch_agent.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/AddToSystemClassLoaderSearch/systemclssearch_agent.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -37,7 +37,7 @@
static char segment1[3000] = "";
static char segment2[3000] = "";
-static const char* const illegal_segments[] = {"", "tmp/"};
+static const char* const illegal_segments[] = { "", "tmp/" };
jboolean use_segment2 = JNI_FALSE;
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/Injector.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -494,7 +494,7 @@
// verification_type_info locals[number_of_locals];
// u2 number_of_stack_items;
// verification_type_info stack[number_of_stack_items];
- //}
+ // }
put_u1(FULL_FRAME);
frameOffsetDelta = get_u2();
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/agent_tools.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/agent_tools.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -42,7 +42,7 @@
static void* agentThreadArg = NULL;
-typedef enum {NEW, RUNNABLE, WAITING, SUSPENDED, TERMINATED} thread_state_t;
+typedef enum { NEW, RUNNABLE, WAITING, SUSPENDED, TERMINATED } thread_state_t;
typedef struct agent_data_t {
volatile thread_state_t thread_state;
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -633,6 +633,69 @@
return 1;
}
+#define SLEEP_DELAY 10L
+
+int suspendThreadAtMethod(jvmtiEnv *jvmti, jclass cls, jobject thread, jmethodID testMethod) {
+ printf(">>>>>>>> Invoke SuspendThread()\n");
+
+ jvmtiError err = jvmti->SuspendThread(thread);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("%s: Failed to call SuspendThread(): error=%d: %s\n",
+ __FILE__, err, TranslateError(err));
+ return NSK_FALSE;
+ }
+
+ int result = NSK_TRUE;
+ jmethodID method = NULL;
+ jlocation loc;
+
+ // We need to ensure that the thread is suspended at the right place when the top
+ // frame belongs to the test rather than to incidental Java code (classloading,
+ // JVMCI, etc). Below we do resume/suspend in the loop until the target method
+ // is executed in the top frame or the loop counter exceeds the limit.
+ for (int i = 0; i < 10; i++) {
+ err = jvmti->GetFrameLocation(thread, 0, &method, &loc);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(GetFrameLocation) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = NSK_FALSE;
+ break;
+ }
+
+ char *name, *sig, *generic;
+ jvmti->GetMethodName(method, &name, &sig, &generic);
+ printf(">>> Attempt %d to suspend the thread. Top frame: \"%s%s\"\n",
+ i, name, sig);
+ if (method == testMethod) break;
+
+ err = jvmti->ResumeThread(thread);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(ResumeThread) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = NSK_FALSE;
+ }
+
+ mssleep(SLEEP_DELAY);
+
+ err = jvmti->SuspendThread(thread);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("(SuspendThread) unexpected error: %s (%d)\n",
+ TranslateError(err), err);
+ result = NSK_FALSE;
+ }
+ }
+ if(method == testMethod) {
+ printf("<<<<<<<< SuspendThread() is successfully done\n");
+ } else {
+ char *name, *sig, *generic;
+ jvmti->GetMethodName(testMethod, &name, &sig, &generic);
+ printf("Failed in the suspendThread: was not able to suspend thread "
+ "with required method \"%s%s\" on the top\n", name, sig);
+ result = NSK_FALSE;
+ }
+ return result;
+}
+
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor) {
jvmtiError error = env->CreateRawMonitor(name, monitor);
if (!NSK_JVMTI_VERIFY(error)) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h Wed Dec 05 17:05:42 2018 -0500
@@ -371,6 +371,12 @@
int isThreadExpected(jvmtiEnv *jvmti, jthread thread);
+/**
+* This method makes the thread to be suspended at the right place when the top frame
+* belongs to the test rather than to incidental Java code (classloading, JVMCI, etc).
+*/
+int suspendThreadAtMethod(jvmtiEnv *jvmti, jclass cls, jobject thread, jmethodID method);
+
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor);
void exitOnError(jvmtiError error);
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/native/nsk_tools.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/native/nsk_tools.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -43,7 +43,7 @@
int verbose;
int tracing;
int nComplains;
-} nsk_context = {NSK_FALSE, NSK_TRACE_NONE, 0};
+} nsk_context = { NSK_FALSE, NSK_TRACE_NONE, 0 };
void nsk_setVerboseMode(int verbose) {
nsk_context.verbose = verbose;
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp Wed Dec 05 17:03:58 2018 -0500
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/libjnistress003.cpp Wed Dec 05 17:05:42 2018 -0500
@@ -68,7 +68,7 @@
arrayArray[DOUBLE]=env->NewDoubleArray(SIZE); CE
for (i=0;i<8;i++)
- {env->SetObjectArrayElement(objectsArray,i,arrayArray[i]); CE }
+ { env->SetObjectArrayElement(objectsArray,i,arrayArray[i]); CE }
boolBuf=(jboolean *)malloc(SIZE*sizeof(jboolean));
byteBuf=(jbyte *)malloc(SIZE*sizeof(jbyte));
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/CR6551600Test.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/CR6551600Test.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,11 @@
package transform;
-import static jaxp.library.JAXPTestUtilities.getSystemProperty;
-
import java.io.File;
import java.io.FilePermission;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -35,17 +36,18 @@
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import jaxp.library.JAXPTestUtilities;
-
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import jaxp.library.JAXPTestUtilities;
+
/*
* @test
* @bug 6551600
+ * @requires os.family == "windows"
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true transform.CR6551600Test
* @run testng/othervm transform.CR6551600Test
@@ -56,17 +58,22 @@
@Test
public final void testUNCPath() {
- boolean isWindows = getSystemProperty("os.name").contains("Windows");
+ var hostName = "";
+ try {
+ hostName = java.net.InetAddress.getLocalHost().getHostName();
+ } catch (java.net.UnknownHostException e) {
+ // falls through
+ }
+
+ var uncPath = "\\\\" + hostName + "\\C$\\temp\\";
+
+ if (!checkAccess(uncPath)) {
+ System.out.println("Cannot access UNC path. Test exits.");
+ return;
+ }
+
+ var uncFilePath = uncPath + "xslt_unc_test.xml";
JAXPTestUtilities.runWithTmpPermission(() -> {
- String hostName = "";
- try {
- hostName = java.net.InetAddress.getLocalHost().getHostName();
- } catch (java.net.UnknownHostException e) {
- // falls through
- }
-
- String path = isWindows ? "\\\\" + hostName + "\\C$\\xslt_unc_test.xml" : "///tmp/test.xml";
-
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
@@ -75,7 +82,7 @@
doc.appendChild(root);
// create an identity transform
Transformer t = TransformerFactory.newInstance().newTransformer();
- File f = new File(path);
+ File f = new File(uncFilePath);
StreamResult result = new StreamResult(f);
DOMSource source = new DOMSource(doc);
System.out.println("Writing to " + f);
@@ -86,11 +93,24 @@
Assert.fail(e.toString());
}
- File file = new File(path);
+ File file = new File(uncFilePath);
if (file.exists()) {
file.deleteOnExit();
}
- }, isWindows ? new FilePermission("//localhost/C$/xslt_unc_test.xml", "read,write,delete")
- : new FilePermission("///tmp/test.xml", "read,write,delete"));
+ }, new FilePermission(uncFilePath, "read,write,delete"));
+ }
+
+ private boolean checkAccess(String path) {
+ return JAXPTestUtilities.runWithTmpPermission(() -> {
+ try {
+ Path tmepFile = Files.createTempFile(Paths.get(path), "test", "6551600");
+ Files.deleteIfExists(tmepFile);
+ return true;
+ } catch (Exception e) {
+ System.out.println("Access check failed.");
+ e.printStackTrace();
+ return false;
+ }
+ }, new FilePermission(path + "*", "read,write,delete"));
}
}
--- a/test/jdk/ProblemList.txt Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/ProblemList.txt Wed Dec 05 17:05:42 2018 -0500
@@ -715,7 +715,6 @@
com/sun/java/swing/plaf/windows/Test8173145.java 8198334 windows-all
-javax/swing/border/Test6981576.java 8198339 generic-all
javax/swing/border/TestTitledBorderLeak.java 8213531 linux-all
javax/swing/JComponent/7154030/bug7154030.java 7190978 generic-all
javax/swing/JComboBox/ConsumedKeyTest/ConsumedKeyTest.java 8067986 generic-all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/font/Rotate/RotatedFontMetricsTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test RotatedFontMetricsTest
+ * @bug 8139178
+ * @summary This test verifies that rotation does not affect font metrics.
+ * @run main RotatedFontMetricsTest
+ */
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+public class RotatedFontMetricsTest {
+ static final int FONT_SIZE = Integer.getInteger("font.size", 20);
+
+ public static void main(String ... args) {
+ Font font = new Font(Font.DIALOG, Font.PLAIN, FONT_SIZE);
+ Graphics2D g2d = createGraphics();
+
+ FontMetrics ref = null;
+ RuntimeException failure = null;
+ for (int a = 0; a < 360; a += 15) {
+ Graphics2D g = (Graphics2D)g2d.create();
+ g.rotate(Math.toRadians(a));
+ FontMetrics m = g.getFontMetrics(font);
+ g.dispose();
+
+ boolean status = true;
+ if (ref == null) {
+ ref = m;
+ } else {
+ status = ref.getAscent() == m.getAscent() &&
+ ref.getDescent() == m.getDescent() &&
+ ref.getLeading() == m.getLeading() &&
+ ref.getMaxAdvance() == m.getMaxAdvance();
+ }
+
+ System.out.printf("Metrics a%d, d%d, l%d, m%d (%d) %s\n",
+ m.getAscent(), m.getDescent(), m.getLeading(), m.getMaxAdvance(),
+ (int)a, status ? "OK" : "FAIL");
+
+ if (!status && failure == null) {
+ failure = new RuntimeException("Font metrics differ for angle " + a);
+ }
+ }
+ if (failure != null) {
+ throw failure;
+ }
+ System.out.println("done");
+ }
+
+ private static Graphics2D createGraphics() {
+ BufferedImage dst = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
+ return dst.createGraphics();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/print/PrinterJob/CheckPrinterJobSystemProperty.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8130264 8214552 8214558
+ * @summary verify the PrinterJob implementation class name is not
+ * polluting system properties
+ */
+
+public class CheckPrinterJobSystemProperty {
+
+ public static void main(String[] args) {
+ String pjProp = System.getProperty("java.awt.printerjob");
+ if (pjProp != null) {
+ throw new RuntimeException("pjProp = " + pjProp);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/beans/Introspector/MethodOrderException.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.beans.Introspector;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.RandomAccess;
+
+/**
+ * @test
+ * @bug 8211147
+ * @modules java.desktop/com.sun.beans.introspect:open
+ */
+public final class MethodOrderException {
+
+ public static void main(final String[] args) throws Exception {
+ // Public API, fails rarely
+ testPublicAPI();
+ // Test using internal API, fails always
+ testPrivateAPI();
+ }
+
+ private static void testPublicAPI() throws Exception {
+ Introspector.getBeanInfo(X.class);
+ }
+
+ private static void testPrivateAPI() throws Exception {
+ Class<?> name = Class.forName(
+ "com.sun.beans.introspect.MethodInfo$MethodOrder");
+ Field instance = name.getDeclaredField("instance");
+ instance.setAccessible(true);
+ Comparator<Method> o = (Comparator) instance.get(name);
+ List<Method> methods = List.of(X.class.getDeclaredMethods());
+ methods.forEach(m1 -> {
+ methods.forEach(m2 -> {
+ if (o.compare(m1, m2) != -o.compare(m2, m1)) {
+ System.err.println("Method1 = "+ m1);
+ System.err.println("Method2 = "+ m2);
+ throw new RuntimeException("Broken contract!");
+ }
+ });
+ });
+ }
+
+ interface X_1 {
+
+ AbstractList x_8();
+ }
+ interface X_2 {
+
+ Cloneable x_0();
+ }
+ interface X_3 {
+
+ Serializable x_1();
+ }
+ interface X_4 {
+
+ Object x_7();
+ }
+ interface X_5 {
+
+ RandomAccess x_6();
+ }
+ interface X_6 {
+
+ RandomAccess x_0();
+ }
+ interface X_7 {
+
+ Serializable x_5();
+ }
+ interface X_8 {
+
+ Object x_4();
+ }
+ interface X_9 {
+
+ RandomAccess x_5();
+ }
+ interface X_10 {
+
+ Cloneable x_5();
+ }
+ interface X_11 {
+
+ RandomAccess x_9();
+ }
+ interface X_12 {
+
+ Cloneable x_9();
+ }
+ interface X_13 {
+
+ Iterable x_2();
+ }
+ interface X_14 {
+
+ Collection x_7();
+ }
+ interface X_15 {
+
+ Serializable x_4();
+ }
+ interface X_16 {
+
+ Cloneable x_7();
+ }
+ interface X_17 {
+
+ Object x_1();
+ }
+ interface X_18 {
+
+ ArrayList x_6();
+ }
+ interface X_19 {
+
+ List x_5();
+ }
+ interface X_20 {
+
+ Collection x_2();
+ }
+ interface X_21 {
+
+ List x_1();
+ }
+ interface X_22 {
+
+ List x_3();
+ }
+ interface X_23 {
+
+ RandomAccess x_3();
+ }
+ interface X_24 {
+
+ RandomAccess x_1();
+ }
+ interface X_25 {
+
+ Object x_6();
+ }
+ interface X_26 {
+
+ Cloneable x_7();
+ }
+ interface X_27 {
+
+ Iterable x_0();
+ }
+ interface X_28 {
+
+ Iterable x_1();
+ }
+ interface X_29 {
+
+ AbstractList x_7();
+ }
+ interface X_30 {
+
+ AbstractList x_1();
+ }
+ interface X_31 {
+
+ Cloneable x_9();
+ }
+ interface X_32 {
+
+ ArrayList x_6();
+ }
+ interface X_33 {
+
+ Cloneable x_2();
+ }
+ interface X_34 {
+
+ Iterable x_6();
+ }
+ interface X_35 {
+
+ Iterable x_9();
+ }
+ interface X_36 {
+
+ AbstractList x_9();
+ }
+ interface X_37 {
+
+ Iterable x_7();
+ }
+ interface X_38 {
+
+ Iterable x_3();
+ }
+ interface X_39 {
+
+ Iterable x_9();
+ }
+ interface X_40 {
+
+ AbstractList x_3();
+ }
+ interface X_41 {
+
+ List x_0();
+ }
+ interface X_42 {
+
+ Iterable x_0();
+ }
+ interface X_43 {
+
+ Iterable x_2();
+ }
+ interface X_44 {
+
+ ArrayList x_4();
+ }
+ interface X_45 {
+
+ AbstractList x_4();
+ }
+ interface X_46 {
+
+ Collection x_4();
+ }
+ interface X_47 {
+
+ ArrayList x_2();
+ }
+ interface X_48 {
+
+ ArrayList x_6();
+ }
+ interface X_49 {
+
+ Serializable x_1();
+ }
+ interface X_50 {
+
+ Cloneable x_7();
+ }
+ interface X_51 {
+
+ Collection x_5();
+ }
+ interface X_52 {
+
+ RandomAccess x_5();
+ }
+ interface X_53 {
+
+ Collection x_5();
+ }
+ interface X_54 {
+
+ RandomAccess x_4();
+ }
+ interface X_55 {
+
+ Collection x_0();
+ }
+ interface X_56 {
+
+ Collection x_7();
+ }
+ interface X_57 {
+
+ Iterable x_9();
+ }
+ interface X_58 {
+
+ List x_3();
+ }
+ interface X_59 {
+
+ Serializable x_7();
+ }
+ interface X_60 {
+
+ AbstractCollection x_6();
+ }
+ interface X_61 {
+
+ AbstractList x_9();
+ }
+ interface X_62 {
+
+ List x_7();
+ }
+ interface X_63 {
+
+ AbstractCollection x_3();
+ }
+ interface X_64 {
+
+ RandomAccess x_4();
+ }
+ interface X_65 {
+
+ Object x_3();
+ }
+ interface X_66 {
+
+ RandomAccess x_6();
+ }
+ interface X_67 {
+
+ Cloneable x_6();
+ }
+ interface X_68 {
+
+ Cloneable x_3();
+ }
+ interface X_69 {
+
+ Collection x_5();
+ }
+ interface X_70 {
+
+ AbstractCollection x_0();
+ }
+ interface X_71 {
+
+ Object x_8();
+ }
+ interface X_72 {
+
+ AbstractCollection x_3();
+ }
+ interface X_73 {
+
+ Serializable x_4();
+ }
+ interface X_74 {
+
+ AbstractList x_8();
+ }
+ interface X_75 {
+
+ ArrayList x_1();
+ }
+ interface X_76 {
+
+ List x_5();
+ }
+ interface X_77 {
+
+ Object x_0();
+ }
+ interface X_78 {
+
+ Collection x_0();
+ }
+ interface X_79 {
+
+ ArrayList x_2();
+ }
+ interface X_80 {
+
+ ArrayList x_8();
+ }
+ interface X_81 {
+
+ Cloneable x_3();
+ }
+ interface X_82 {
+
+ Serializable x_1();
+ }
+ interface X_83 {
+
+ List x_1();
+ }
+ interface X_84 {
+
+ Collection x_5();
+ }
+ interface X_85 {
+
+ RandomAccess x_9();
+ }
+ interface X_86 {
+
+ AbstractList x_3();
+ }
+ interface X_87 {
+
+ Cloneable x_6();
+ }
+ interface X_88 {
+
+ Object x_2();
+ }
+ interface X_89 {
+
+ ArrayList x_5();
+ }
+ interface X_90 {
+
+ Iterable x_1();
+ }
+ interface X_91 {
+
+ ArrayList x_4();
+ }
+ interface X_92 {
+
+ Iterable x_6();
+ }
+ interface X_93 {
+
+ Collection x_7();
+ }
+ interface X_94 {
+
+ Iterable x_2();
+ }
+ interface X_95 {
+
+ AbstractList x_7();
+ }
+ interface X_96 {
+
+ RandomAccess x_2();
+ }
+ interface X_97 {
+
+ RandomAccess x_2();
+ }
+ interface X_98 {
+
+ List x_6();
+ }
+ interface X_99 {
+
+ Object x_4();
+ }
+ interface X_100 {
+
+ Collection x_7();
+ }
+ static class X
+ implements X_1, X_2, X_3, X_4, X_5, X_6, X_7, X_8, X_9, X_10, X_11,
+ X_12, X_13, X_14, X_15, X_16, X_17, X_18, X_19, X_20,
+ X_21, X_22, X_23, X_24, X_25, X_26, X_27, X_28, X_29,
+ X_30, X_31, X_32, X_33, X_34, X_35, X_36, X_37, X_38,
+ X_39, X_40, X_41, X_42, X_43, X_44, X_45, X_46, X_47,
+ X_48, X_49, X_50, X_51, X_52, X_53, X_54, X_55, X_56,
+ X_57, X_58, X_59, X_60, X_61, X_62, X_63, X_64, X_65,
+ X_66, X_67, X_68, X_69, X_70, X_71, X_72, X_73, X_74,
+ X_75, X_76, X_77, X_78, X_79, X_80, X_81, X_82, X_83,
+ X_84, X_85, X_86, X_87, X_88, X_89, X_90, X_91, X_92,
+ X_93, X_94, X_95, X_96, X_97, X_98, X_99, X_100 {
+
+ public ArrayList x_0() {
+ return null;
+ }
+
+ public ArrayList x_1() {
+ return null;
+ }
+
+ public ArrayList x_2() {
+ return null;
+ }
+
+ public ArrayList x_3() {
+ return null;
+ }
+
+ public ArrayList x_4() {
+ return null;
+ }
+
+ public ArrayList x_5() {
+ return null;
+ }
+
+ public ArrayList x_6() {
+ return null;
+ }
+
+ public ArrayList x_7() {
+ return null;
+ }
+
+ public ArrayList x_8() {
+ return null;
+ }
+
+ public ArrayList x_9() {
+ return null;
+ }
+ }
+}
--- a/test/jdk/java/lang/ProcessBuilder/Basic.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/lang/ProcessBuilder/Basic.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -2084,7 +2084,7 @@
//----------------------------------------------------------------
// Check that reads which are pending when Process.destroy is
- // called, get EOF, not IOException("Stream closed").
+ // called, get EOF, or IOException("Stream closed").
//----------------------------------------------------------------
try {
final int cases = 4;
@@ -2112,6 +2112,11 @@
default: throw new Error();
}
equal(-1, r);
+ } catch (IOException ioe) {
+ if (!ioe.getMessage().equals("Stream closed")) {
+ // BufferedInputStream may throw IOE("Stream closed").
+ unexpected(ioe);
+ }
} catch (Throwable t) { unexpected(t); }}};
thread.start();
--- a/test/jdk/java/lang/ref/ReachabilityFenceTest.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/lang/ref/ReachabilityFenceTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -25,6 +25,8 @@
* @bug 8133348
* @summary Tests if reachabilityFence is working
*
+ * @requires vm.opt.DeoptimizeALot != true
+ *
* @run main/othervm -Xint -Dpremature=false ReachabilityFenceTest
* @run main/othervm -XX:TieredStopAtLevel=1 -Dpremature=true ReachabilityFenceTest
* @run main/othervm -XX:TieredStopAtLevel=2 -Dpremature=true ReachabilityFenceTest
@@ -142,4 +144,4 @@
finalized.set(true);
}
}
-}
\ No newline at end of file
+}
--- a/test/jdk/java/time/test/java/time/format/TestNonIsoFormatter.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/time/test/java/time/format/TestNonIsoFormatter.java Wed Dec 05 17:05:42 2018 -0500
@@ -191,7 +191,7 @@
String mdStr = "-01-01";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("GGGG y-M-d")
- .toFormatter()
+ .toFormatter(Locale.ROOT)
.withChronology(chrono);
DateTimeFormatter dtfLenient = dtf.withResolverStyle(ResolverStyle.LENIENT);
assertEquals(LocalDate.parse(lenient+mdStr, dtfLenient), LocalDate.parse(strict+mdStr, dtf));
--- a/test/jdk/java/util/Properties/Compatibility.xml Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"
- [<!ENTITY intEnt 'value3'> ]>
-<?PITarget PIContent?>
-<properties>
-<comment>Property With Other Encoding</comment>
-<entry key="Key1">value1</entry>
-<entry key="Key2"><![CDATA[<value2>]]></entry>
-<entry key="Key3">&intEnt;</entry>
-</properties>
--- a/test/jdk/java/util/Properties/CompatibilityTest.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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
- * @bug 8005280 8004371
- * @summary Compatibility test
- */
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-/**
- * This is a behavior compatibility test.
- * Although not defined by the properties.dtd, the constructs
- * in Compatibility.xml are supported by the regular JDK XML
- * Provider.
- *
- * @author: Joe Wang
- */
-public class CompatibilityTest {
-
- public static void main(String[] args) {
- testInternalDTD();
- }
-
- /*
- * Not in the spec, but the constructs work with the current JDK
- */
- static void testInternalDTD() {
- String src = System.getProperty("test.src");
- if (src == null) {
- src = ".";
- }
- loadPropertyFile(src + "/Compatibility.xml");
- }
-
- /*
- * 'Store' the populated 'Property' with the specified 'Encoding Type' as an
- * XML file. Retrieve the same XML file and 'load' onto a new 'Property' object.
- */
- static void loadPropertyFile(String filename) {
- try (InputStream in = new FileInputStream(filename)) {
- Properties prop = new Properties();
- prop.loadFromXML(in);
- verifyProperites(prop);
- } catch (IOException ex) {
- fail(ex.getMessage());
- }
- }
-
- /*
- * This method verifies the first key-value with the original string.
- */
- static void verifyProperites(Properties prop) {
- try {
- for (String key : prop.stringPropertyNames()) {
- String val = prop.getProperty(key);
- if (key.equals("Key1")) {
- if (!val.equals("value1")) {
- fail("Key:" + key + "'s value: \nExpected: value1\nFound: " + val);
- }
- } else if (key.equals("Key2")) {
- if (!val.equals("<value2>")) {
- fail("Key:" + key + "'s value: \nExpected: <value2>\nFound: " + val);
- }
- } else if (key.equals("Key3")) {
- if (!val.equals("value3")) {
- fail("Key:" + key + "'s value: \nExpected: value3\nFound: " + val);
- }
- }
- }
- } catch (Exception e) {
- fail(e.getMessage());
- }
-
- }
-
- static void fail(String err) {
- throw new RuntimeException(err);
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Properties/invalidxml/IllegalElement.xml Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf8" standalone="no"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+
+<!-- The dtd requires a properties root, but not element -->
+
+<properties>
+<comment>comment</comment>
+ <properties>
+ <entry key="firstKey">value of the first key</entry>
+ </properties>
+</properties>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/Properties/invalidxml/invalidDTD.xml Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"
+ [<!ENTITY intEnt 'value3'> ]>
+<?PITarget PIContent?>
+<properties>
+<comment>Property With Other Encoding</comment>
+<entry key="Key1">value1</entry>
+<entry key="Key2"><![CDATA[<value2>]]></entry>
+<entry key="Key3">&intEnt;</entry>
+</properties>
--- a/test/jdk/java/util/ResourceBundle/Control/XmlRB.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/Control/XmlRB.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for XMLResourceBundleTest.java</comment>
<entry key="type">XML</entry>
--- a/test/jdk/java/util/ResourceBundle/Control/XmlRB_ja.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/Control/XmlRB_ja.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for XMLResourceBundleTest.java</comment>
<entry key="type">Xï¼ï¼¬</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle</comment>
<entry key="key">root: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_de.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_de.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle</comment>
<entry key="key">de: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_en.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_en.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle</comment>
<entry key="key">en: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_fr.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_fr.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle</comment>
<entry key="key">fr: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_ja.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_ja.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle in named modules.</comment>
<entry key="key">ja: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_zh.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_zh.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle in named modules.</comment>
<entry key="key">zh: message</entry>
--- a/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_zh_TW.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/ResourceBundle/modules/basic/srcXml/bundles/jdk/test/resources/MyResources_zh_TW.xml Wed Dec 05 17:05:42 2018 -0500
@@ -2,15 +2,7 @@
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for ResourceBundle in named modules.</comment>
<entry key="key">zh-TW: message</entry>
--- a/test/jdk/java/util/spi/ResourceBundleControlProvider/com/foo/XmlRB.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/spi/ResourceBundleControlProvider/com/foo/XmlRB.xml Wed Dec 05 17:05:42 2018 -0500
@@ -23,15 +23,7 @@
-->
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for UserDefaultControlTest.java</comment>
<entry key="type">XML</entry>
--- a/test/jdk/java/util/spi/ResourceBundleControlProvider/com/foo/XmlRB_ja.xml Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/java/util/spi/ResourceBundleControlProvider/com/foo/XmlRB_ja.xml Wed Dec 05 17:05:42 2018 -0500
@@ -23,15 +23,7 @@
-->
<!---->
-<!-- DTD for properties -->
-<!DOCTYPE properties [
-<!ELEMENT properties ( comment?, entry* ) >
-<!ATTLIST properties version CDATA #FIXED "1.0">
-<!ELEMENT comment (#PCDATA) >
-<!ELEMENT entry (#PCDATA) >
-<!ATTLIST entry key CDATA #REQUIRED>
-]>
-
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>Test data for UserDefaultControlTest.java</comment>
<entry key="type">Xï¼ï¼¬</entry>
--- a/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java Wed Dec 05 17:05:42 2018 -0500
@@ -28,7 +28,7 @@
* @requires (os.family == "mac")
* @summary JPopupMenu is overlapped by a Dock on Mac OS X
* @library /test/lib
- * /test/jdk/lib/testlibrary/
+ * /lib/client
* @build ExtendedRobot jdk.test.lib.Platform
* @run main bug7154841
*/
--- a/test/jdk/javax/swing/border/Test6981576.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/javax/swing/border/Test6981576.java Wed Dec 05 17:05:42 2018 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,28 +23,59 @@
/*
* @test
+ * @key headful
* @bug 6981576
* @summary Tests that default border for the titled border is not null
- * @author Sergey Malenkov
*/
import java.awt.Component;
+import java.awt.EventQueue;
import java.awt.Graphics;
+
import javax.swing.JFrame;
import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
import javax.swing.UIManager;
-import javax.swing.UIManager.LookAndFeelInfo;
+import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;
-public class Test6981576 extends TitledBorder implements Runnable, Thread.UncaughtExceptionHandler {
- public static void main(String[] args) {
- SwingUtilities.invokeLater(new Test6981576());
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+public class Test6981576 extends TitledBorder {
+
+ private static volatile Throwable failed;
+
+ public static void main(String[] args) throws Throwable {
+ Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
+ e.printStackTrace();
+ failed = e;
+ });
+
+ for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) {
+ EventQueue.invokeAndWait(() -> setLookAndFeel(laf));
+ EventQueue.invokeAndWait(() -> {
+ JPanel panel = new JPanel();
+ panel.setBorder(new Test6981576());
+ frame = new JFrame("Test6981576");
+ frame.add(panel);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ frame.setSize(300, 300);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ });
+ EventQueue.invokeAndWait(() -> {
+ frame.repaint();
+ });
+ EventQueue.invokeAndWait(() -> {
+ frame.dispose();
+ });
+ }
+ if (failed != null) {
+ throw failed;
+ }
}
- private int index;
- private LookAndFeelInfo[] infos;
- private JFrame frame;
+ private static JFrame frame;
private Test6981576() {
super("");
@@ -55,37 +86,15 @@
getBorder().paintBorder(c, g, x, y, width, height);
}
- public void run() {
- if (this.infos == null) {
- this.infos = UIManager.getInstalledLookAndFeels();
- Thread.currentThread().setUncaughtExceptionHandler(this);
- JPanel panel = new JPanel();
- panel.setBorder(this);
- this.frame = new JFrame(getClass().getSimpleName());
- this.frame.add(panel);
- this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- this.frame.setVisible(true);
- }
- if (this.index == this.infos.length) {
- this.frame.dispose();
- }
- else {
- LookAndFeelInfo info = this.infos[this.index % this.infos.length];
- try {
- UIManager.setLookAndFeel(info.getClassName());
- }
- catch (Exception exception) {
- System.err.println("could not change look and feel");
- }
- SwingUtilities.updateComponentTreeUI(this.frame);
- this.frame.pack();
- this.frame.setLocationRelativeTo(null);
- this.index++;
- SwingUtilities.invokeLater(this);
+ private static void setLookAndFeel(final UIManager.LookAndFeelInfo laf) {
+ try {
+ UIManager.setLookAndFeel(laf.getClassName());
+ System.out.println("LookAndFeel: " + laf.getClassName());
+ } catch (final UnsupportedLookAndFeelException ignored){
+ System.out.println("Unsupported LookAndFeel: " + laf.getClassName());
+ } catch (ClassNotFoundException | InstantiationException |
+ IllegalAccessException e) {
+ throw new RuntimeException(e);
}
}
-
- public void uncaughtException(Thread thread, Throwable throwable) {
- System.exit(1);
- }
}
--- a/test/jdk/jdk/jfr/cmd/ExecuteHelper.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import jdk.jfr.Configuration;
-import jdk.jfr.Event;
-import jdk.jfr.Recording;
-import jdk.test.lib.Utils;
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;;
-
-final class ExecuteHelper {
-
- public static Object[] array;
-
- static class CustomEvent extends Event {
- int intValue;
- long longValue;
- double doubliValue;
- float floatValue;
- String stringValue;
- Short shortValue;
- boolean booleanValue;
- char charValue;
- double trickyDouble;
- }
-
- public static OutputAnalyzer run(String... args) {
- String[] array = new String[args.length + 1];
- System.arraycopy(args, 0, array, 1, args.length);
- array[0] = "jdk.jfr.internal.cmd.Execute";
- try {
- return ProcessTools.executeTestJava(array);
- } catch (Exception e) {
- String message = String.format("Caught exception while executing '%s'", Arrays.asList(array));
- throw new RuntimeException(message, e);
- }
- }
-
- public static void emitCustomEvents() {
- // Custom events with potentially tricky values
- CustomEvent event1 = new CustomEvent();
- event1.trickyDouble = Double.NaN;
- event1.intValue = Integer.MIN_VALUE;
- event1.longValue = Long.MIN_VALUE;
- event1.doubliValue = Double.MIN_VALUE;
- event1.floatValue = Float.MIN_VALUE;
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < 512; i++) {
- sb.append((char) i);
- }
- sb.append("\u2324");
- event1.stringValue = sb.toString();
- event1.shortValue = Short.MIN_VALUE;
- event1.booleanValue = true;
- event1.booleanValue = false;
- event1.charValue = '\b';
- event1.commit();
-
- CustomEvent event2 = new CustomEvent();
- event2.trickyDouble = Double.NEGATIVE_INFINITY;
- event2.intValue = Integer.MAX_VALUE;
- event2.longValue = Long.MAX_VALUE;
- event2.doubliValue = Double.MAX_VALUE;
- event2.floatValue = Float.MAX_VALUE;
- event2.stringValue = null;
- event2.shortValue = Short.MAX_VALUE;
- event2.booleanValue = false;
- event2.charValue = 0;
- event2.commit();
- }
-
- public static Path createProfilingRecording() throws Exception {
- Path file = Utils.createTempFile("profiling-recording", ".jfr");
- // Create a recording with some data
- try (Recording r = new Recording(Configuration.getConfiguration("profile"))) {
- r.start();
-
- // Allocation event
- array = new Object[1000000];
- array = null;
-
- // Class loading event etc
- provokeClassLoading();
-
- // GC events
- System.gc();
-
- // ExecutionSample
- long t = System.currentTimeMillis();
- while (System.currentTimeMillis() - t < 50) {
- // do nothing
- }
-
- // Other periodic events, i.e CPU load
- Thread.sleep(1000);
-
- r.stop();
- r.dump(file);
- }
-
- return file;
- }
-
- private static void provokeClassLoading() {
- // Matching a string with regexp
- // is expected to load some classes and generate some VM events
- Pattern p = Pattern.compile("a*b");
- Matcher m = p.matcher("aaaaab");
- m.matches();
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestHelp.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test help
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestHelp
- */
-public class TestHelp {
-
- public static void main(String[] args) throws Exception {
- OutputAnalyzer output = ExecuteHelper.run("help");
- output.shouldContain("Available commands are:");
- output.shouldContain("print");
- output.shouldContain("reconstruct");
- output.shouldContain("summary");
- output.shouldContain("help");
-
- output = ExecuteHelper.run("help", "help");
- output.shouldContain("Available commands are:");
-
- output = ExecuteHelper.run("help", "wrongcommand");
- output.shouldContain("Unknown command");
-
- output = ExecuteHelper.run("help", "wrongcommand", "wrongarguments");
- output.shouldContain("Too many arguments");
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrint.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.io.FileWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import jdk.test.lib.Utils;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr print
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestPrint
- */
-public class TestPrint {
-
- public static void main(String[] args) throws Exception {
-
- OutputAnalyzer output = ExecuteHelper.run("print");
- output.shouldContain("Missing file");
-
- output = ExecuteHelper.run("print", "missing.jfr");
- output.shouldContain("Could not find file ");
-
- output = ExecuteHelper.run("print", "missing.jfr", "option1", "option2");
- output.shouldContain("Too many arguments");
-
- Path file = Utils.createTempFile("faked-print-file", ".jfr");
- FileWriter fw = new FileWriter(file.toFile());
- fw.write('d');
- fw.close();
- output = ExecuteHelper.run("print", "--wrongOption", file.toAbsolutePath().toString());
- output.shouldContain("Unknown option");
- Files.delete(file);
-
- // Also see TestPrintJSON, TestPrintXML and TestPrintDefault.
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintDefault.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --json
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules java.scripting
- * jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintDefault
- */
-public class TestPrintDefault {
-
- public static void main(String... args) throws Exception {
-
- Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
- OutputAnalyzer output = ExecuteHelper.run("print", recordingFile.toString());
- output.shouldContain("JVMInformation");
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintJSON.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.nashorn.api.scripting.JSObject;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --json
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules jdk.scripting.nashorn
- * jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintJSON
- */
-public class TestPrintJSON {
-
- public static void main(String... args) throws Exception {
-
- Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
- OutputAnalyzer output = ExecuteHelper.run("print", "--json", recordingFile.toString());
- String json = output.getStdout();
-
- // Parse JSON using Nashorn
- String statement = "var jsonObject = " + json;
- ScriptEngineManager factory = new ScriptEngineManager();
- ScriptEngine engine = factory.getEngineByName("nashorn");
- engine.eval(statement);
- JSObject o = (JSObject) engine.get("jsonObject");
- JSObject recording = (JSObject) o.getMember("recording");
- JSObject events = (JSObject) recording.getMember("events");
-
- // Verify events are equal
- try (RecordingFile rf = new RecordingFile(recordingFile)) {
- for (Object jsonEvent : events.values()) {
- RecordedEvent recordedEvent = rf.readEvent();
- double typeId = recordedEvent.getEventType().getId();
- String startTime = recordedEvent.getStartTime().toString();
- String duration = recordedEvent.getDuration().toString();
- Asserts.assertEquals(typeId, ((Number) ((JSObject) jsonEvent).getMember("typeId")).doubleValue());
- Asserts.assertEquals(startTime, ((JSObject) jsonEvent).getMember("startTime"));
- Asserts.assertEquals(duration, ((JSObject) jsonEvent).getMember("duration"));
- assertEquals(jsonEvent, recordedEvent);
- }
- Asserts.assertFalse(rf.hasMoreEvents(), "Incorrect number of events");
- }
- }
-
- private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception {
- // Check object
- if (jfrObject instanceof RecordedObject) {
- JSObject values = (JSObject) ((JSObject) jsonObject).getMember("values");
- RecordedObject recObject = (RecordedObject) jfrObject;
- Asserts.assertEquals(values.values().size(), recObject.getFields().size());
- for (ValueDescriptor v : recObject.getFields()) {
- String name = v.getName();
- assertEquals(values.getMember(name), recObject.getValue(name));
- return;
- }
- }
- // Check array
- if (jfrObject != null && jfrObject.getClass().isArray()) {
- Object[] jfrArray = (Object[]) jfrObject;
- JSObject jsArray = (JSObject) jsonObject;
- for (int i = 0; i < jfrArray.length; i++) {
- assertEquals(jsArray.getSlot(i), jfrArray[i]);
- }
- return;
- }
- String jsonText = String.valueOf(jsonObject);
- // Double.NaN / Double.Inifinity is not supported by JSON format,
- // use null
- if (jfrObject instanceof Double) {
- double expected = ((Double) jfrObject);
- if (Double.isInfinite(expected) || Double.isNaN(expected)) {
- Asserts.assertEquals("null", jsonText);
- return;
- }
- double value = Double.parseDouble(jsonText);
- Asserts.assertEquals(expected, value);
- return;
- }
- // Float.NaN / Float.Inifinity is not supported by JSON format,
- // use null
- if (jfrObject instanceof Float) {
- float expected = ((Float) jfrObject);
- if (Float.isInfinite(expected) || Float.isNaN(expected)) {
- Asserts.assertEquals("null", jsonText);
- return;
- }
- float value = Float.parseFloat(jsonText);
- Asserts.assertEquals(expected, value);
- return;
- }
- if (jfrObject instanceof Integer) {
- Integer expected = ((Integer) jfrObject);
- double value = Double.parseDouble(jsonText);
- Asserts.assertEquals(expected.doubleValue(), value);
- return;
- }
- if (jfrObject instanceof Long) {
- Long expected = ((Long) jfrObject);
- double value = Double.parseDouble(jsonText);
- Asserts.assertEquals(expected.doubleValue(), value);
- return;
- }
-
- String jfrText = String.valueOf(jfrObject);
- Asserts.assertEquals(jfrText, jsonText, "Primitive values don't match. JSON = " + jsonText);
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintXML.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.io.StringReader;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --xml
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules java.scripting
- * java.xml
- * jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintXML
- */
-public class TestPrintXML {
-
- public static void main(String... args) throws Exception {
-
- Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
- OutputAnalyzer output = ExecuteHelper.run("print", "--xml", recordingFile.toString());
- String xml = output.getStdout();
- System.out.println(xml);
- // Parse XML string
- SAXParserFactory factory = SAXParserFactory.newInstance();
- SAXParser sp = factory.newSAXParser();
- XMLReader xr = sp.getXMLReader();
- RecordingHandler handler = new RecordingHandler();
- xr.setContentHandler(handler);
- xr.parse(new InputSource(new StringReader(xml)));
-
- // Verify that all data was written correctly
- Iterator<RecordedEvent> it = RecordingFile.readAllEvents(recordingFile).iterator();
- for (XMLEvent xmlEvent : handler.events) {
- RecordedEvent re = it.next();
- if (!compare(re, xmlEvent.values)) {
- System.out.println(re);
- System.out.println(xmlEvent.values.toString());
- throw new Exception("Event doesn't match");
- }
- }
-
- }
-
- @SuppressWarnings("unchecked")
- static boolean compare(Object eventObject, Object xmlObject) {
- if (eventObject == null) {
- return xmlObject == null;
- }
- if (eventObject instanceof RecordedObject) {
- RecordedObject re = (RecordedObject) eventObject;
- Map<String, Object> xmlMap = (Map<String, Object>) xmlObject;
- List<ValueDescriptor> fields = re.getFields();
- if (fields.size() != xmlMap.size()) {
- return false;
- }
- for (ValueDescriptor v : fields) {
- String name = v.getName();
- if (!compare(re.getValue(name), xmlMap.get(name))) {
- return false;
- }
- }
- return true;
- }
- if (eventObject.getClass().isArray()) {
- Object[] array = (Object[]) eventObject;
- Object[] xmlArray = (Object[]) xmlObject;
- if (array.length != xmlArray.length) {
- return false;
- }
- for (int i = 0; i < array.length; i++) {
- if (!compare(array[i], xmlArray[i])) {
- return false;
- }
- }
- return true;
- }
- String s1 = String.valueOf(eventObject);
- String s2 = (String) xmlObject;
- return s1.equals(s2);
- }
-
- static class XMLEvent {
- String name;
- Instant startTime;
- Duration duration;
- Map<String, Object> values = new HashMap<>();
-
- XMLEvent(String name, Instant startTime, Duration duration) {
- this.name = name;
- this.startTime = startTime;
- this.duration = duration;
- }
- }
-
- public static final class RecordingHandler extends DefaultHandler {
-
- private Stack<Object> objects = new Stack<>();
- private Stack<SimpleEntry<String, String>> elements = new Stack<>();
- private List<XMLEvent> events = new ArrayList<>();
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
- elements.push(new SimpleEntry<>(attrs.getValue("name"), attrs.getValue("index")));
- switch (qName) {
- case "null":
- objects.pop();
- objects.push(null);
- break;
- case "event":
- Instant startTime = Instant.parse(attrs.getValue("startTime"));
- Duration duration = Duration.parse(attrs.getValue("duration"));
- objects.push(new XMLEvent(attrs.getValue("name"), startTime, duration));
- break;
- case "struct":
- objects.push(new HashMap<String, Object>());
- break;
- case "array":
- objects.push(new Object[Integer.parseInt(attrs.getValue("size"))]);
- break;
- case "value":
- objects.push(new StringBuilder());
- break;
- }
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- if (!objects.isEmpty()) {
- Object o = objects.peek();
- if (o instanceof StringBuilder) {
- ((StringBuilder) o).append(ch, start, length);
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void endElement(String uri, String localName, String qName) {
- SimpleEntry<String, String> element = elements.pop();
- switch (qName) {
- case "event":
- case "struct":
- case "array":
- case "value":
- String name = element.getKey();
- Object value = objects.pop();
- if (objects.isEmpty()) {
- events.add((XMLEvent) value);
- return;
- }
- if (value instanceof StringBuilder) {
- value = ((StringBuilder) value).toString();
- }
- Object parent = objects.peek();
- if (parent instanceof XMLEvent) {
- ((XMLEvent) parent).values.put(name, value);
- }
- if (parent instanceof Map) {
- ((Map<String, Object>) parent).put(name, value);
- }
- if (parent != null && parent.getClass().isArray()) {
- int index = Integer.parseInt(element.getValue());
- ((Object[]) parent)[index] = value;
- }
- }
- }
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestReconstruct.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import jdk.jfr.Event;
-import jdk.jfr.Name;
-import jdk.jfr.Recording;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.jfr.internal.Repository;
-import jdk.jfr.internal.SecuritySupport.SafePath;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr reconstruct
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @modules jdk.jfr/jdk.jfr.internal
- * @run main/othervm jdk.jfr.cmd.TestReconstruct
- */
-public class TestReconstruct {
-
- @Name("Correlation")
- static class CorrelationEvent extends Event {
- int id;
- }
- private static int RECORDING_COUNT = 5;
-
- @SuppressWarnings("resource")
- public static void main(String[] args) throws Exception {
- // Create some disk recordings
- Recording[] recordings = new Recording[5];
- for (int i = 0; i < RECORDING_COUNT; i++) {
- Recording r = new Recording();
- r.setToDisk(true);
- r.start();
- CorrelationEvent ce = new CorrelationEvent();
- ce.id = i;
- ce.commit();
- r.stop();
- recordings[i] = r;
- }
- Path dir = Paths.get("reconstruction-parts");
- Files.createDirectories(dir);
-
- long expectedCount = 0;
- for (int i = 0; i < RECORDING_COUNT; i++) {
- Path tmp = dir.resolve("chunk-part-" + i + ".jfr");
- recordings[i].dump(tmp);
- expectedCount += countEventInRecording(tmp);
- }
-
- SafePath repository = Repository.getRepository().getRepositoryPath();
- Path destinationPath = Paths.get("reconstructed.jfr");
-
- String directory = repository.toString();
- String destination = destinationPath.toAbsolutePath().toString();
-
- // Test failure
- OutputAnalyzer output = ExecuteHelper.run("reconstruct");
-
- output.shouldContain("Too few arguments");
-
- output = ExecuteHelper.run("reconstruct", directory);
- output.shouldContain("Too few arguments");
-
- output = ExecuteHelper.run("reconstruct", "not-a-directory", destination);
- output.shouldContain("Could not find disk repository at");
-
- output = ExecuteHelper.run("reconstruct", directory, "not-a-destination");
- output.shouldContain("Filename must end with .jfr");
-
- output = ExecuteHelper.run("reconstruct", "--wrongOption", directory, destination);
- output.shouldContain("Too many arguments");
-
- FileWriter fw = new FileWriter(destination);
- fw.write('d');
- fw.close();
- output = ExecuteHelper.run("reconstruct", directory, destination);
- output.shouldContain("already exists");
- Files.delete(destinationPath);
-
- // test success
- output = ExecuteHelper.run("reconstruct", directory, destination);
- System.out.println(output.getOutput());
- output.shouldContain("Reconstruction complete");
-
- long reconstructedCount = countEventInRecording(destinationPath);
- Asserts.assertEquals(expectedCount, reconstructedCount);
- // Cleanup
- for (int i = 0; i < RECORDING_COUNT; i++) {
- recordings[i].close();
- }
- }
-
- private static long countEventInRecording(Path file) throws IOException {
- Integer lastId = -1;
- try (RecordingFile rf = new RecordingFile(file)) {
- long count = 0;
- while (rf.hasMoreEvents()) {
- RecordedEvent re = rf.readEvent();
- if (re.getEventType().getName().equals("Correlation")) {
- Integer id = re.getValue("id");
- if (id < lastId) {
- Asserts.fail("Expected chunk number to increase");
- }
- lastId = id;
- }
- count++;
- }
- return count;
- }
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestSplit.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import jdk.jfr.Configuration;
-import jdk.jfr.Recording;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr split
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestSplit
- */
-public class TestSplit {
-
- public static void main(String[] args) throws Exception {
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
- String dateText = formatter.format(new Date());
-
- Path recordingFileA = Paths.get("many-chunks-A-" + dateText + ".jfr");
- Path recordingFileB = Paths.get("many-chunks-B-" + dateText + ".jfr");
- makeRecordingWithChunks(6, recordingFileA);
- Files.copy(recordingFileA, recordingFileB);
-
- String fileAText = recordingFileA.toAbsolutePath().toString();
- String fileBText = recordingFileB.toAbsolutePath().toString();
-
- OutputAnalyzer output = ExecuteHelper.run("split");
- output.shouldContain("Missing file");
-
- output = ExecuteHelper.run("split", "--wrongOption1", "..wrongOption2", "..wrongOption3", fileAText);
- output.shouldContain("Too many arguments");
-
- output = ExecuteHelper.run("split", "--wrongOption", fileAText);
- output.shouldContain("Unknown option");
-
- output = ExecuteHelper.run("split", "--wrongOption", "1", fileAText);
- output.shouldContain("Unknown option");
-
- output = ExecuteHelper.run("split", "--maxchunks", "-3", fileAText);
- output.shouldContain("Must be at least one chunk per file");
-
- output = ExecuteHelper.run("split", "--maxchunks", "1000", fileAText);
- output.shouldContain("Number of chunks in recording");
- output.shouldContain("doesn't exceed max chunks");
- output = ExecuteHelper.run("split", fileAText); // maxchunks is 5 by
- // default
- System.out.println(output.getOutput());
- System.out.println(fileAText);
- verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_1.jfr");
- verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_2.jfr");
-
- output = ExecuteHelper.run("split", "--maxchunks", "2", fileBText);
-
- verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_1.jfr");
- verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_2.jfr");
- verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_3.jfr");
-
- output = ExecuteHelper.run("split", "--maxchunks", "2", fileBText);
- output.shouldContain("file with that name already exist");
- }
-
- private static void verifyRecording(String name) throws IOException {
- System.out.println("split name " + name);
- try (RecordingFile rf = new RecordingFile(Paths.get(name))) {
- rf.readEvent();
- }
- }
-
- // Will create at least 2 * count + 1 chunks.
- private static void makeRecordingWithChunks(int count, Path file) throws IOException, ParseException {
- Recording main = new Recording(Configuration.getConfiguration("default"));
- main.setToDisk(true);
- main.start();
- for (int i = 0; i < count; i++) {
- Recording r = new Recording();
- r.setToDisk(true);
- r.start();
- r.stop();
- r.close();
- }
- main.stop();
- main.dump(file);
- main.close();
- }
-}
--- a/test/jdk/jdk/jfr/cmd/TestSummary.java Wed Dec 05 17:03:58 2018 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr info
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestSummary
- */
-public class TestSummary {
-
- public static void main(String[] args) throws Exception {
- Path f = ExecuteHelper.createProfilingRecording().toAbsolutePath();
- String file = f.toAbsolutePath().toString();
-
- OutputAnalyzer output = ExecuteHelper.run("summary");
- output.shouldContain("Missing file");
-
- output = ExecuteHelper.run("summary", "--wrongOption", file);
- output.shouldContain("Too many arguments");
-
- output = ExecuteHelper.run("summary", file);
- try (RecordingFile rf = new RecordingFile(f)) {
- for (EventType t : rf.readEventTypes()) {
- output.shouldContain(t.getName());
- }
- }
- output.shouldContain("Version");
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/ExecuteHelper.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.nio.file.Path;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jdk.jfr.Configuration;
+import jdk.jfr.Event;
+import jdk.jfr.Recording;
+import jdk.test.lib.Utils;;
+
+final class ExecuteHelper {
+
+ public static Object[] array;
+
+ static class CustomEvent extends Event {
+ int intValue;
+ long longValue;
+ double doubliValue;
+ float floatValue;
+ String stringValue;
+ Short shortValue;
+ boolean booleanValue;
+ char charValue;
+ double trickyDouble;
+ }
+
+ public static void emitCustomEvents() {
+ // Custom events with potentially tricky values
+ CustomEvent event1 = new CustomEvent();
+ event1.trickyDouble = Double.NaN;
+ event1.intValue = Integer.MIN_VALUE;
+ event1.longValue = Long.MIN_VALUE;
+ event1.doubliValue = Double.MIN_VALUE;
+ event1.floatValue = Float.MIN_VALUE;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < 512; i++) {
+ sb.append((char) i);
+ }
+ sb.append("\u2324");
+ event1.stringValue = sb.toString();
+ event1.shortValue = Short.MIN_VALUE;
+ event1.booleanValue = true;
+ event1.booleanValue = false;
+ event1.charValue = '\b';
+ event1.commit();
+
+ CustomEvent event2 = new CustomEvent();
+ event2.trickyDouble = Double.NEGATIVE_INFINITY;
+ event2.intValue = Integer.MAX_VALUE;
+ event2.longValue = Long.MAX_VALUE;
+ event2.doubliValue = Double.MAX_VALUE;
+ event2.floatValue = Float.MAX_VALUE;
+ event2.stringValue = null;
+ event2.shortValue = Short.MAX_VALUE;
+ event2.booleanValue = false;
+ event2.charValue = 0;
+ event2.commit();
+ }
+
+ public static Path createProfilingRecording() throws Exception {
+ Path file = Utils.createTempFile("profiling-recording", ".jfr");
+ // Create a recording with some data
+ try (Recording r = new Recording(Configuration.getConfiguration("profile"))) {
+ r.start();
+
+ // Allocation event
+ array = new Object[1000000];
+ array = null;
+
+ // Class loading event etc
+ provokeClassLoading();
+
+ // GC events
+ System.gc();
+
+ // ExecutionSample
+ long t = System.currentTimeMillis();
+ while (System.currentTimeMillis() - t < 50) {
+ // do nothing
+ }
+
+ // Other periodic events, i.e CPU load
+ Thread.sleep(1000);
+
+ r.stop();
+ r.dump(file);
+ }
+
+ return file;
+ }
+
+ private static void provokeClassLoading() {
+ // Matching a string with regexp
+ // is expected to load some classes and generate some VM events
+ Pattern p = Pattern.compile("a*b");
+ Matcher m = p.matcher("aaaaab");
+ m.matches();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestAssemble.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.jfr.Event;
+import jdk.jfr.Name;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.jfr.internal.Repository;
+import jdk.jfr.internal.SecuritySupport.SafePath;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test jfr reconstruct
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @modules jdk.jfr/jdk.jfr.internal
+ * @run main/othervm jdk.jfr.tool.TestAssemble
+ */
+public class TestAssemble {
+
+ @Name("Correlation")
+ static class CorrelationEvent extends Event {
+ int id;
+ }
+ private static int RECORDING_COUNT = 5;
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) throws Throwable {
+ // Create some disk recordings
+ Recording[] recordings = new Recording[5];
+ for (int i = 0; i < RECORDING_COUNT; i++) {
+ Recording r = new Recording();
+ r.setToDisk(true);
+ r.start();
+ CorrelationEvent ce = new CorrelationEvent();
+ ce.id = i;
+ ce.commit();
+ r.stop();
+ recordings[i] = r;
+ }
+ Path dir = Paths.get("reconstruction-parts");
+ Files.createDirectories(dir);
+
+ long expectedCount = 0;
+ for (int i = 0; i < RECORDING_COUNT; i++) {
+ Path tmp = dir.resolve("chunk-part-" + i + ".jfr");
+ recordings[i].dump(tmp);
+ expectedCount += countEventInRecording(tmp);
+ }
+
+ SafePath repository = Repository.getRepository().getRepositoryPath();
+ Path destinationPath = Paths.get("reconstructed.jfr");
+
+ String directory = repository.toString();
+ String destination = destinationPath.toAbsolutePath().toString();
+
+ // Test failure
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "assemble");
+ output.shouldContain("too few arguments");
+
+ output = ProcessTools.executeProcess("jfr", "assemble", directory);
+ output.shouldContain("too few arguments");
+
+ output = ProcessTools.executeProcess("jfr", "assemble", "not-a-directory", destination);
+ output.shouldContain("directory does not exist, not-a-directory");
+
+ output = ProcessTools.executeProcess("jfr", "assemble", directory, "not-a-destination");
+ output.shouldContain("filename must end with '.jfr'");
+
+ output = ProcessTools.executeProcess("jfr","assemble", "--wrongOption", directory, destination);
+ output.shouldContain("too many arguments");
+
+ FileWriter fw = new FileWriter(destination);
+ fw.write('d');
+ fw.close();
+ output = ProcessTools.executeProcess("jfr", "assemble", directory, destination);
+ output.shouldContain("already exists");
+ Files.delete(destinationPath);
+
+ // test success
+ output = ProcessTools.executeProcess("jfr", "assemble", directory, destination);
+ System.out.println(output.getOutput());
+ output.shouldContain("Finished.");
+
+ long reconstructedCount = countEventInRecording(destinationPath);
+ Asserts.assertEquals(expectedCount, reconstructedCount);
+ // Cleanup
+ for (int i = 0; i < RECORDING_COUNT; i++) {
+ recordings[i].close();
+ }
+ }
+
+ private static long countEventInRecording(Path file) throws IOException {
+ Integer lastId = -1;
+ try (RecordingFile rf = new RecordingFile(file)) {
+ long count = 0;
+ while (rf.hasMoreEvents()) {
+ RecordedEvent re = rf.readEvent();
+ if (re.getEventType().getName().equals("Correlation")) {
+ Integer id = re.getValue("id");
+ if (id < lastId) {
+ Asserts.fail("Expected chunk number to increase");
+ }
+ lastId = id;
+ }
+ count++;
+ }
+ return count;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestDisassemble.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import jdk.jfr.Configuration;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test jfr split
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.tool.TestDisassemble
+ */
+public class TestDisassemble {
+
+ public static void main(String[] args) throws Throwable {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
+ String dateText = formatter.format(new Date());
+
+ Path recordingFileA = Paths.get("many-chunks-A-" + dateText + ".jfr");
+ Path recordingFileB = Paths.get("many-chunks-B-" + dateText + ".jfr");
+ Path recordingFileC = Paths.get("many-chunks-C-" + dateText + ".jfr");
+ makeRecordingWithChunks(6, recordingFileA);
+ Files.copy(recordingFileA, recordingFileB);
+ Files.copy(recordingFileA, recordingFileC);
+
+ String fileAText = recordingFileA.toAbsolutePath().toString();
+ String fileBText = recordingFileB.toAbsolutePath().toString();
+ String fileCText = recordingFileC.toAbsolutePath().toString();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "disassemble");
+ output.shouldContain("missing file");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--wrongOption", fileAText);
+ output.shouldContain("unknown option");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--wrongOption", "1", fileAText);
+ output.shouldContain("unknown option");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--max-chunks", "-3", fileAText);
+ output.shouldContain("max chunks must be at least 1");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--max-chunks", "1000", fileAText);
+ output.shouldContain("number of chunks in recording");
+ output.shouldContain("doesn't exceed max chunks");
+ output = ProcessTools.executeProcess("jfr", "disassemble", fileAText); // maxchunks is 5 by
+ // default
+ System.out.println(output.getOutput());
+ System.out.println(fileAText);
+ verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_1.jfr");
+ verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_2.jfr");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--max-chunks", "2", fileBText);
+
+ verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_1.jfr");
+ verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_2.jfr");
+ verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_3.jfr");
+
+ output = ProcessTools.executeProcess("jfr","disassemble", "--max-chunks", "2", fileBText);
+ output.shouldContain("file with that name already exist");
+
+ // sanity check
+ output = ProcessTools.executeProcess("jfr","disassemble", "--max-size", "500000", fileCText);
+ verifyRecording(fileCText.substring(0, fileCText.length() - 4) + "_1.jfr");
+ }
+
+ private static void verifyRecording(String name) throws IOException {
+ System.out.println("Disassembling: " + name);
+ try (RecordingFile rf = new RecordingFile(Paths.get(name))) {
+ rf.readEvent();
+ }
+ }
+
+ // Will create at least 2 * count + 1 chunks.
+ private static void makeRecordingWithChunks(int count, Path file) throws IOException, ParseException {
+ Recording main = new Recording(Configuration.getConfiguration("default"));
+ main.setToDisk(true);
+ main.start();
+ for (int i = 0; i < count; i++) {
+ Recording r = new Recording();
+ r.setToDisk(true);
+ r.start();
+ r.stop();
+ r.close();
+ }
+ main.stop();
+ main.dump(file);
+ main.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestHelp.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test help
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.tool.TestHelp
+ */
+public class TestHelp {
+
+ public static void main(String[] args) throws Throwable {
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "help");
+ output.shouldContain("print");
+ output.shouldContain("assemble");
+ output.shouldContain("disassemble");
+ output.shouldContain("metadata");
+ output.shouldContain("summary");
+ output.shouldContain("help");
+
+ output = ProcessTools.executeProcess("jfr", "help", "version");
+ output.shouldContain("Display version of the jfr tool");
+ output.shouldContain("jfr version");
+
+ output = ProcessTools.executeProcess("jfr", "help", "wrongcommand");
+ output.shouldContain("unknown command 'wrongcommand'");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestMetadata.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.nio.file.Path;
+
+import jdk.jfr.EventType;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test jfr info
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.tool.TestMetadata
+ */
+public class TestMetadata {
+
+ public static void main(String[] args) throws Throwable {
+ Path f = ExecuteHelper.createProfilingRecording().toAbsolutePath();
+ String file = f.toAbsolutePath().toString();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "metadata");
+ output.shouldContain("missing file");
+
+ output = ProcessTools.executeProcess("jfr", "metadata", "--wrongOption", file);
+ output.shouldContain("unknown option --wrongOption");
+
+ output = ProcessTools.executeProcess("jfr", "metadata", file);
+ try (RecordingFile rf = new RecordingFile(f)) {
+ for (EventType t : rf.readEventTypes()) {
+ String name = t.getName();
+ name = name.substring(name.lastIndexOf(".") + 1);
+ output.shouldContain(name);
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestPrint.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.io.FileWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test jfr print
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.tool.TestPrint
+ */
+public class TestPrint {
+
+ public static void main(String[] args) throws Throwable {
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "print");
+ output.shouldContain("missing file");
+
+ output = ProcessTools.executeProcess("jfr", "print", "missing.jfr");
+ output.shouldContain("could not find file ");
+
+ Path file = Utils.createTempFile("faked-print-file", ".jfr");
+ FileWriter fw = new FileWriter(file.toFile());
+ fw.write('d');
+ fw.close();
+ output = ProcessTools.executeProcess("jfr", "print", "--wrongOption", file.toAbsolutePath().toString());
+ output.shouldContain("unknown option");
+ Files.delete(file);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestPrintDefault.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.nio.file.Path;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @key jfr
+ * @summary Tests print --json
+ * @requires vm.hasJFR
+ *
+ * @library /test/lib /test/jdk
+ * @modules java.scripting
+ * jdk.jfr
+ *
+ * @run main/othervm jdk.jfr.tool.TestPrintDefault
+ */
+public class TestPrintDefault {
+
+ public static void main(String... args) throws Throwable {
+
+ Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "print", recordingFile.toString());
+ output.shouldContain("JVMInformation");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestPrintJSON.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.nio.file.Path;
+import java.time.OffsetDateTime;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+import jdk.jfr.Timespan;
+import jdk.jfr.Timestamp;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @key jfr
+ * @summary Tests print --json
+ * @requires vm.hasJFR
+ *
+ * @library /test/lib /test/jdk
+ * @modules jdk.scripting.nashorn
+ * jdk.jfr
+ *
+ * @run main/othervm jdk.jfr.tool.TestPrintJSON
+ */
+public class TestPrintJSON {
+
+ public static void main(String... args) throws Throwable {
+
+ Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "print", "--json", "--stack-depth", "999", recordingFile.toString());
+ String json = output.getStdout();
+
+ // Parse JSON using Nashorn
+ String statement = "var jsonObject = " + json;
+ ScriptEngineManager factory = new ScriptEngineManager();
+ ScriptEngine engine = factory.getEngineByName("nashorn");
+ engine.eval(statement);
+ JSObject o = (JSObject) engine.get("jsonObject");
+ JSObject recording = (JSObject) o.getMember("recording");
+ JSObject jsonEvents = (JSObject) recording.getMember("events");
+
+ List<RecordedEvent> events = RecordingFile.readAllEvents(recordingFile);
+ Collections.sort(events, (e1, e2) -> e1.getEndTime().compareTo(e2.getEndTime()));
+ // Verify events are equal
+ Iterator<RecordedEvent> it = events.iterator();
+
+ for (Object jsonEvent : jsonEvents.values()) {
+ RecordedEvent recordedEvent = it.next();
+ String typeName = recordedEvent.getEventType().getName();
+ Asserts.assertEquals(typeName, ((JSObject) jsonEvent).getMember("type").toString());
+ assertEquals(jsonEvent, recordedEvent);
+ }
+ Asserts.assertFalse(events.size() != jsonEvents.values().size(), "Incorrect number of events");
+ }
+
+ private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception {
+ // Check object
+ if (jfrObject instanceof RecordedObject) {
+ JSObject values = (JSObject) ((JSObject) jsonObject).getMember("values");
+ RecordedObject recObject = (RecordedObject) jfrObject;
+ Asserts.assertEquals(values.values().size(), recObject.getFields().size());
+ for (ValueDescriptor v : recObject.getFields()) {
+ String name = v.getName();
+ Object jsonValue = values.getMember(name);
+ Object expectedValue = recObject.getValue(name);
+ if (v.getAnnotation(Timestamp.class) != null) {
+ // Make instant of OffsetDateTime
+ jsonValue = OffsetDateTime.parse("" + jsonValue).toInstant().toString();
+ expectedValue = recObject.getInstant(name);
+ }
+ if (v.getAnnotation(Timespan.class) != null) {
+ expectedValue = recObject.getDuration(name);
+ }
+ assertEquals(jsonValue, expectedValue);
+ return;
+ }
+ }
+ // Check array
+ if (jfrObject != null && jfrObject.getClass().isArray()) {
+ Object[] jfrArray = (Object[]) jfrObject;
+ JSObject jsArray = (JSObject) jsonObject;
+ for (int i = 0; i < jfrArray.length; i++) {
+ assertEquals(jsArray.getSlot(i), jfrArray[i]);
+ }
+ return;
+ }
+ String jsonText = String.valueOf(jsonObject);
+ // Double.NaN / Double.Inifinity is not supported by JSON format,
+ // use null
+ if (jfrObject instanceof Double) {
+ double expected = ((Double) jfrObject);
+ if (Double.isInfinite(expected) || Double.isNaN(expected)) {
+ Asserts.assertEquals("null", jsonText);
+ return;
+ }
+ double value = Double.parseDouble(jsonText);
+ Asserts.assertEquals(expected, value);
+ return;
+ }
+ // Float.NaN / Float.Inifinity is not supported by JSON format,
+ // use null
+ if (jfrObject instanceof Float) {
+ float expected = ((Float) jfrObject);
+ if (Float.isInfinite(expected) || Float.isNaN(expected)) {
+ Asserts.assertEquals("null", jsonText);
+ return;
+ }
+ float value = Float.parseFloat(jsonText);
+ Asserts.assertEquals(expected, value);
+ return;
+ }
+ if (jfrObject instanceof Integer) {
+ Integer expected = ((Integer) jfrObject);
+ double value = Double.parseDouble(jsonText);
+ Asserts.assertEquals(expected.doubleValue(), value);
+ return;
+ }
+ if (jfrObject instanceof Long) {
+ Long expected = ((Long) jfrObject);
+ double value = Double.parseDouble(jsonText);
+ Asserts.assertEquals(expected.doubleValue(), value);
+ return;
+ }
+
+ String jfrText = String.valueOf(jfrObject);
+ Asserts.assertEquals(jfrText, jsonText, "Primitive values don't match. JSON = " + jsonText);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestPrintXML.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.io.File;
+import java.io.StringReader;
+import java.nio.file.Path;
+import java.time.OffsetDateTime;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+import jdk.jfr.Timespan;
+import jdk.jfr.Timestamp;
+import jdk.jfr.ValueDescriptor;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedObject;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @key jfr
+ * @summary Tests print --xml
+ * @requires vm.hasJFR
+ *
+ * @library /test/lib /test/jdk
+ * @modules java.scripting java.xml jdk.jfr
+ *
+ * @run main/othervm jdk.jfr.tool.TestPrintXML
+ */
+public class TestPrintXML {
+
+ public static void main(String... args) throws Throwable {
+
+ Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "print", "--xml", "--stack-depth", "9999", recordingFile.toString());
+ System.out.println(recordingFile);
+ String xml = output.getStdout();
+
+ SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ Schema schema = schemaFactory.newSchema(new File(System.getProperty("test.src"), "jfr.xsd"));
+
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setSchema(schema);
+ factory.setNamespaceAware(true);
+
+ SAXParser sp = factory.newSAXParser();
+ XMLReader xr = sp.getXMLReader();
+ RecordingHandler handler = new RecordingHandler();
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+ xr.parse(new InputSource(new StringReader(xml)));
+
+ // Verify that all data was written correctly
+ List<RecordedEvent> events = RecordingFile.readAllEvents(recordingFile);
+ Collections.sort(events, (e1, e2) -> e1.getEndTime().compareTo(e2.getEndTime()));
+ Iterator<RecordedEvent> it = events.iterator();
+ for (XMLEvent xmlEvent : handler.events) {
+ RecordedEvent re = it.next();
+ if (!compare(re, xmlEvent.values)) {
+ System.out.println("Expected:");
+ System.out.println("----------------------");
+ System.out.println(re);
+ System.out.println();
+ System.out.println("Was (XML)");
+ System.out.println("----------------------");
+ System.out.println(xmlEvent);
+ System.out.println();
+ throw new Exception("Event doesn't match");
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ static boolean compare(Object eventObject, Object xmlObject) {
+ if (eventObject == null) {
+ return xmlObject == null;
+ }
+ if (eventObject instanceof RecordedObject) {
+ RecordedObject re = (RecordedObject) eventObject;
+ Map<String, Object> xmlMap = (Map<String, Object>) xmlObject;
+ List<ValueDescriptor> fields = re.getFields();
+ if (fields.size() != xmlMap.size()) {
+ return false;
+ }
+ for (ValueDescriptor v : fields) {
+ String name = v.getName();
+ Object xmlValue = xmlMap.get(name);
+ Object expectedValue = re.getValue(name);
+ if (v.getAnnotation(Timestamp.class) != null) {
+ // Make instant of OffsetDateTime
+ xmlValue = OffsetDateTime.parse("" + xmlValue).toInstant().toString();
+ expectedValue = re.getInstant(name);
+ }
+ if (v.getAnnotation(Timespan.class) != null) {
+ expectedValue = re.getDuration(name);
+ }
+ if (!compare(expectedValue, xmlValue)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (eventObject.getClass().isArray()) {
+ Object[] array = (Object[]) eventObject;
+ Object[] xmlArray = (Object[]) xmlObject;
+ if (array.length != xmlArray.length) {
+ return false;
+ }
+ for (int i = 0; i < array.length; i++) {
+ if (!compare(array[i], xmlArray[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ String s1 = String.valueOf(eventObject);
+ String s2 = (String) xmlObject;
+ return s1.equals(s2);
+ }
+
+ static class XMLEvent {
+ String name;
+ private Map<String, Object> values = new HashMap<>();
+
+ XMLEvent(String name) {
+ this.name = name;
+ }
+ }
+
+ public static final class RecordingHandler extends DefaultHandler {
+
+ private Stack<Object> objects = new Stack<>();
+ private Stack<SimpleEntry<String, String>> elements = new Stack<>();
+ private List<XMLEvent> events = new ArrayList<>();
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
+ elements.push(new SimpleEntry<>(attrs.getValue("name"), attrs.getValue("index")));
+ String nil = attrs.getValue("xsi:nil");
+ if ("true".equals(nil)) {
+ objects.push(null);
+ return;
+ }
+
+ switch (qName) {
+ case "event":
+ objects.push(new XMLEvent(attrs.getValue("type")));
+ break;
+ case "struct":
+ objects.push(new HashMap<String, Object>());
+ break;
+ case "array":
+ objects.push(new Object[Integer.parseInt(attrs.getValue("size"))]);
+ break;
+ case "value":
+ objects.push(new StringBuilder());
+ break;
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (!objects.isEmpty()) {
+ Object o = objects.peek();
+ if (o instanceof StringBuilder) {
+ ((StringBuilder) o).append(ch, start, length);
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void endElement(String uri, String localName, String qName) {
+ SimpleEntry<String, String> element = elements.pop();
+ switch (qName) {
+ case "event":
+ case "struct":
+ case "array":
+ case "value":
+ String name = element.getKey();
+ Object value = objects.pop();
+ if (objects.isEmpty()) {
+ events.add((XMLEvent) value);
+ return;
+ }
+ if (value instanceof StringBuilder) {
+ value = ((StringBuilder) value).toString();
+ }
+ Object parent = objects.peek();
+ if (parent instanceof XMLEvent) {
+ ((XMLEvent) parent).values.put(name, value);
+ }
+ if (parent instanceof Map) {
+ ((Map<String, Object>) parent).put(name, value);
+ }
+ if (parent != null && parent.getClass().isArray()) {
+ int index = Integer.parseInt(element.getValue());
+ ((Object[]) parent)[index] = value;
+ }
+ }
+ }
+
+ public void warning(SAXParseException spe) throws SAXException {
+ throw new SAXException(spe);
+ }
+
+ public void error(SAXParseException spe) throws SAXException {
+ throw new SAXException(spe);
+ }
+
+ public void fatalError(SAXParseException spe) throws SAXException {
+ throw new SAXException(spe);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/TestSummary.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.tool;
+
+import java.nio.file.Path;
+
+import jdk.jfr.EventType;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @summary Test jfr info
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.tool.TestSummary
+ */
+public class TestSummary {
+
+ public static void main(String[] args) throws Throwable {
+ Path f = ExecuteHelper.createProfilingRecording().toAbsolutePath();
+ String file = f.toAbsolutePath().toString();
+
+ OutputAnalyzer output = ProcessTools.executeProcess("jfr", "summary");
+ output.shouldContain("missing file");
+
+ output = ProcessTools.executeProcess("jfr", "summary", "--wrongOption", file);
+ output.shouldContain("too many arguments");
+
+ output = ProcessTools.executeProcess("jfr", "summary", file);
+ try (RecordingFile rf = new RecordingFile(f)) {
+ for (EventType t : rf.readEventTypes()) {
+ output.shouldContain(t.getName());
+ }
+ }
+ output.shouldContain("Version");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/tool/jfr.xsd Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="1.0">
+ <xs:element name="recording">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="1">
+ <xs:element name="events">
+ <xs:complexType>
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="event" type="eventType" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="eventType">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:choice>
+ <xs:element name="struct" nillable="true" type="structType" />
+ <xs:element name="array" nillable="true" type="arrayType" />
+ <xs:element name="value" nillable="true" type="valueType" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute use="required" name="type" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="structType">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:choice>
+ <xs:element name="struct" nillable="true" type="structType" />
+ <xs:element name="array" nillable="true" type="arrayType" />
+ <xs:element name="value" nillable="true" type="valueType" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute use="required" name="name" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="arrayType">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:choice>
+ <xs:element name="struct" nillable="true" type="structElement" />
+ <xs:element name="array" nillable="true" type="arrayElement" />
+ <xs:element name="value" nillable="true" type="valueElement" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute use="required" name="size" type="xs:int" />
+ <xs:attribute use="required" name="name" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="valueType">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute use="required" name="name" type="xs:string" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ <xs:complexType name="structElement">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:choice>
+ <xs:element name="struct" nillable="true" type="structType" />
+ <xs:element name="array" nillable="true" type="arrayType" />
+ <xs:element name="value" nillable="true" type="valueType" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute use="required" name="index" type="xs:int" />
+ </xs:complexType>
+ <xs:complexType name="arrayElement">
+ <xs:sequence minOccurs="0" maxOccurs="unbounded">
+ <xs:choice>
+ <xs:element name="value" nillable="true" type="valueType" />
+ <xs:element name="array" nillable="true" type="arrayType" />
+ <xs:element name="struct" nillable="true" type="structType" />
+ </xs:choice>
+ </xs:sequence>
+ <xs:attribute use="required" name="index" type="xs:int" />
+ </xs:complexType>
+ <xs:complexType name="valueElement">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute use="required" name="index" type="xs:int" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+</xs:schema>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/pkcs12/WrongPBES2.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8214513
+ * @summary A PKCS12 keystore from Java 8 using custom PBE parameters cannot be read in Java 11
+ */
+
+import javax.crypto.spec.PBEParameterSpec;
+import java.io.*;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+
+public class WrongPBES2 {
+
+ private static final char[] PASS = "changeit".toCharArray();
+
+ // This is a PKCS 12 file using PBES2 with an incorrect encoding before
+ // JDK-8202837 is fixed. It is generated with these 2 commands:
+ //
+ // keytool -genkeypair -alias a -dname CN=A -keystore ks -storepass changeit
+ // $JDK10/bin/java WrongPBES2 reenc
+ static final String P12_FILE =
+ "308208940201033082084d06092a864886f70d010701a082083e0482083a3082" +
+ "08363082035206092a864886f70d010701a08203430482033f3082033b308203" +
+ "37060b2a864886f70d010c0a0102a08202ee308202ea307406092a864886f70d" +
+ "01050d306706092a864886f70d01050d305a303906092a864886f70d01050c30" +
+ "2c0414000000000000000000000000000000000000000002030186a002012030" +
+ "0c06082a864886f70d020b0500301d060960864801650304012a04105abc352d" +
+ "35d98fd77d8c8cf205d690c6048202703ff97bd4488a6a5569993fb6f89792e7" +
+ "33632b20fdc502bf0801c8ee80683d064c4dae5b8880ade893a87bfdb4427dfd" +
+ "01bc5656fdb50f45f1e8d60b37416d2f3b1be9e8ae145bfe035f9d947fa49a31" +
+ "baef86dec6780a0f96a7ad5d9ef850b15f56d6b6f2f0798c190b01b42d955d36" +
+ "96f1416efb0c246b56e3715c1ccef701f975f6faf7e7640b8edca79f996682d8" +
+ "5a414c8210004f247058c3362f328c12d024ea88de5ab3d6c50a7cf8f32b69de" +
+ "999930ccb29be0d278216db0959d9b142e4c46207edaf91f37708e0250e99262" +
+ "c4acba4b83c2c0affb3bfc2d5bfe210baffe56ba1f667c9e3c33e0c4164d0c16" +
+ "abc89bca2c1af7fc234163a6a17e4852ee08053bdf699c8659ea57f77427ab3b" +
+ "cea357a85ffd80589403bc73ff50490f9b0bfb37fedf495aae8ef8a00da7d1e1" +
+ "62c49dacf82503e803953f48e302d1ae1b7e7870a479c7861ffc236469807f31" +
+ "da0b15a915a62d4f0a42698a4c9779595619effa04765f91342821229752ec6d" +
+ "6e0657ad4e41979847b5903ddb6a6819b859797a2f663898694fe294cc85b9c3" +
+ "d485516659dcd6d89f631903be35367315b131f9f5ec63ee5bf25f3afcf8bc9c" +
+ "d9056a56f951746664cfa3ed0596e005fda6fb753d9c67c92fd1a9f22d06a59e" +
+ "9c7af058dddad3b9265fc29c18122f55c07a1780050251990c221ba2b3767586" +
+ "405def7a1b224135ac4a694f0e3d27666486531aad9e27a3855f54e2916a642a" +
+ "ed06fc5275b675bbf457a26978b0f4306c166119dedc3aedf366cbf34efa647e" +
+ "a65b8451c7b1d083fe1ee3a8493a0330ee7da68552614e50ca7326a25d741e40" +
+ "ccac2149d1ff5cb8778a3b08ed3d9a1774c971525454b7c20b18610b9bc847cc" +
+ "3136301106092a864886f70d01091431041e020061302106092a864886f70d01" +
+ "09153114041254696d652031353433363738383539323632308204dc06092a86" +
+ "4886f70d010706a08204cd308204c9020100308204c206092a864886f70d0107" +
+ "013029060a2a864886f70d010c0106301b0414e6d3162d3b75f103fac6ea3fbf" +
+ "96d08c0225d308020300c3508082048834d05f8953cad673f7de3b5446bcdd31" +
+ "310b376eec04c393f1077cfda8ad69fe0133cf79fbdd204eeca165e1d6e288b9" +
+ "a6625dfe34aa722f230c50da44d463753d3bbd7e762cb0f164b7fbfe4a3aff8c" +
+ "dc664ef2c6afd01232de66d81221e977738b81838cadd0fe1f87bdd7278dcdbd" +
+ "2307bda516e931691e3da46f82f72073ab6502b9f2b23788c620756eedddf21e" +
+ "705a6043d29a8e27285fea79e4a9966f5b08d5f13bc6f4d854f47879ee90e72d" +
+ "3a5cc6eccda9edf60c4d73edf3e4dd6c715c06c53e83ba461e10868e5ef5e218" +
+ "726bc6714f3071b3f17a075ff9d28d2cb48896b785d48551e8410f2bc882ad04" +
+ "88d60c85c3b966e1b484e4190267b38e3179107f3c49abd2b058fb32eab4abfc" +
+ "ee914ee4407954e1edb338042ca04b1561df364139a64a1080c79bfdfa17d15b" +
+ "6fc26b0572427b2f1b9bbea6d1a730a7dd1b08d22093658f9a5665ae8e9a04b8" +
+ "af89a60ea7994d17949b22e2fc6d5d4dd1d280283fd649e1aca6e0e4c90ae509" +
+ "afc01bd92127321798562cf5ba75fed840f8ca9082c8c58334a95593fa5b1b57" +
+ "ea86cb8452136dee7ecd63872d4848d9052e181f6bca0772a4d4dd43817b9005" +
+ "a6314cbd90474a24b6ed9c9896097bba51ca7cd48120b5f9fee3f98dd99bbcd3" +
+ "e0ab43bcbb922bcf48cf710f7a5b9d192f419f607b6ca7937d8ed6f990835b88" +
+ "7f480cc5fad2708c57c674d0e082af60d8b0108df2bf88b321df4d0431d4dfc0" +
+ "4ae21cfd5446715e4af6bcb2224a8d6dc26d71806f21c1e17e8dd2ac57632234" +
+ "1d3e72cbcce4c4e59421fc5202ec6d76c623b81a872ab6b8d53e4215234ee8d9" +
+ "61148b0f42300fc0c89ec91f528698d79a27af593e5fd56484c97763ebc4a797" +
+ "13511ec0e13c59318d1ac444f6121a81a4f505b7e3dca70d6cd74b209fc10003" +
+ "78d5f2016c63acd019a1175e41fe60b88ff5e7238b32ef25243da462cabcd6c7" +
+ "5789c6055ef4999522acb386138f085e9bc2e9b41ecaf3bbb0990ac8b9efde0e" +
+ "eedff4c636bd13ef2dc18bfe5e900d88f4649ce326bc4f8e9bfe058832a595e3" +
+ "5c65415ca9606b0d2c705519eb83995a6da302f53e57a93f2be20dc858d3d5e9" +
+ "e8fdbc10af092b47c108d2e44eed00879626389b35df014e54ea3bf067d2d800" +
+ "b74f67c3576d585e6fedf9634e1ae7941d0de0faed7c76e0296d701728792bf4" +
+ "9bf007738d9273af8981bd71ed4a6360c08a4c5ab83ee337141c37679cf5db7a" +
+ "5aff7353ed6285bab948cac12559ee6ed9f34ee20e01b538975e26c310a33790" +
+ "f8be9fbb907f2585f55d2a456c6be4e46e08edd3aa5392d1c9415a6ded826776" +
+ "b04a3804f9b5f078888320ee5b279a4bba3b5c73ae1e8444b9320b92eb6b8e16" +
+ "75f505bcf79ff0e0cc80326e9bedbc6baebce47725aef3914e4326b924984788" +
+ "1d21d59d71b08ba34283f5784deeeecb9f4a3cfbcb21e48e8a9a94972ee7366e" +
+ "04d1d9c60534fdb7bfe5ec559427b6bbe96d41f551dde0800684226920cbc4f4" +
+ "1f3a7225e0c6a15d3ebee4e87ae4c40fef4d2e5272bb5b0037030665ae1faba7" +
+ "4c41a04277bbe1851e090c8d31e48575bbc96618e3cfeea5a2f80fc1e565adc8" +
+ "ffd84b803877ff9b305a4da59e6f707b3dbe95f7c037fbec303e302130090605" +
+ "2b0e03021a05000414adb4dd32f3ce248ec62e2fd45835255c2316739e041441" +
+ "f87d07019980ef69b635f06017567e36aa3d8802030186a0";
+
+ public static void main(String[] args) throws Exception {
+ if (args.length > 0 && args[0].equals("reenc")) {
+ reEncodeWithPBES2();
+ } else {
+ test();
+ }
+ }
+
+ private static void test() throws Exception {
+ byte[] p12 = new byte[P12_FILE.length() / 2];
+ for (int i = 0; i < p12.length; i++) {
+ p12[i] = Integer.valueOf(P12_FILE.substring(2 * i, 2 * i + 2), 16)
+ .byteValue();
+ }
+ KeyStore ks = KeyStore.getInstance("pkcs12");
+ ks.load(new ByteArrayInputStream(p12), PASS);
+ System.out.println(ks.getKey("a", PASS));
+ }
+
+ private static void reEncodeWithPBES2() throws Exception {
+ KeyStore keyStore = KeyStore.getInstance(new File("ks"), PASS);
+ KeyStore.PrivateKeyEntry privateKeyEntry = new KeyStore.PrivateKeyEntry(
+ (PrivateKey)keyStore.getKey("a", PASS),
+ new Certificate[] { keyStore.getCertificate("a") });
+ keyStore.setEntry("a", privateKeyEntry, new KeyStore.PasswordProtection(
+ PASS, "PBEWithHmacSHA512AndAES_256",
+ new PBEParameterSpec(new byte[20], 100_000)));
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ keyStore.store(bout, PASS);
+ byte[] p12 = bout.toByteArray();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < p12.length; i++) {
+ if (i % 32 == 0) {
+ if (i != 0) {
+ sb.append("\" +\n");
+ }
+ sb.append("\"");
+ }
+ sb.append(String.format("%02x", p12[i] & 0xff));
+ }
+ sb.append("\";\n");
+ System.out.println(sb.toString());
+ }
+}
--- a/test/jdk/sun/security/tools/keytool/KeyToolTest.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/sun/security/tools/keytool/KeyToolTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -1436,6 +1436,7 @@
testOK("", pre+"san3 -ext san=dns:me.org");
testOK("", pre+"san4 -ext san=ip:192.168.0.1");
testOK("", pre+"san5 -ext san=oid:1.2.3.4");
+ testOK("", pre+"san6 -ext san=dns:1abc.com"); //begin with digit
testOK("", pre+"san235 -ext san=uri:http://me.org,dns:me.org,oid:1.2.3.4");
ks = loadStore("x.jks", "changeit", "JKS");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/x509/GeneralName/DNSNameTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary DNSName parsing tests
+ * @bug 8213952
+ * @modules java.base/sun.security.x509
+ * @run testng DNSNameTest
+ */
+
+import java.io.IOException;
+import sun.security.x509.DNSName;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class DNSNameTest {
+ @DataProvider(name = "goodNames")
+ public Object[][] goodNames() {
+ Object[][] data = {
+ {"abc.com"},
+ {"ABC.COM"},
+ {"a12.com"},
+ {"a1b2c3.com"},
+ {"1abc.com"},
+ {"123.com"},
+ {"abc.com-"}, // end with hyphen
+ {"a-b-c.com"}, // hyphens
+ };
+ return data;
+ }
+
+ @DataProvider(name = "badNames")
+ public Object[][] badNames() {
+ Object[][] data = {
+ {" 1abc.com"}, // begin with space
+ {"1abc.com "}, // end with space
+ {"1a bc.com "}, // no space allowed
+ {"-abc.com"}, // begin with hyphen
+ {"a..b"}, // ..
+ {".a"}, // begin with .
+ {"a."}, // end with .
+ {""}, // empty
+ {" "}, // space only
+ };
+ return data;
+ }
+
+ @Test(dataProvider = "goodNames")
+ public void testGoodDNSName(String dnsNameString) {
+ try {
+ DNSName dn = new DNSName(dnsNameString);
+ } catch (IOException e) {
+ fail("Unexpected IOException");
+ }
+ }
+
+ @Test(dataProvider = "badNames")
+ public void testBadDNSName(String dnsNameString) {
+ try {
+ DNSName dn = new DNSName(dnsNameString);
+ fail("IOException expected");
+ } catch (IOException e) {
+ if (!e.getMessage().contains("DNSName"))
+ fail("Unexpeceted message: " + e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/JLinkReproducibleTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.nio.file.*;
+import java.util.*;
+
+import static jdk.test.lib.Asserts.*;
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.ProcessTools;
+
+/*
+ * @test
+ * @bug 8214230
+ * @summary Test that jlinks generates reproducible modules files
+ * @library /test/lib
+ * @run driver JLinkReproducibleTest
+ */
+public class JLinkReproducibleTest {
+ private static void run(List<String> cmd) throws Exception {
+ var pb = new ProcessBuilder(cmd.toArray(new String[0]));
+ var res = ProcessTools.executeProcess(pb);
+ res.shouldHaveExitValue(0);
+ }
+
+ private static void jlink(Path image) throws Exception {
+ var cmd = new ArrayList<String>();
+ cmd.add(JDKToolFinder.getJDKTool("jlink"));
+ cmd.addAll(List.of(
+ "--module-path", JMODS_DIR.toString() + File.pathSeparator + CLASS_DIR.toString(),
+ "--add-modules", "main",
+ "--compress=2",
+ "--output", image.toString()
+ ));
+ run(cmd);
+ }
+
+ private static void javac(String... args) throws Exception {
+ var cmd = new ArrayList<String>();
+ cmd.add(JDKToolFinder.getJDKTool("javac"));
+ cmd.addAll(Arrays.asList(args));
+ run(cmd);
+ }
+
+ private static final List<String> MODULE_INFO = List.of(
+ "module main {",
+ " exports org.test.main;",
+ "}"
+ );
+
+ private static final List<String> MAIN_CLASS = List.of(
+ "package org.test.main;",
+ "public class Main {",
+ " public static void main(String[] args) {",
+ " System.out.println(\"Hello, world\");",
+ " }",
+ "}"
+ );
+
+ private static final Path CLASS_DIR = Path.of("classes");
+ private static final Path JMODS_DIR = Path.of(System.getProperty("java.home"), "jmods");
+
+ public static void main(String[] args) throws Exception {
+ // Write the source code
+ var srcDir = Path.of("main", "org", "test", "main");
+ Files.createDirectories(srcDir.toAbsolutePath());
+
+ var srcFile = srcDir.resolve("Main.java");
+ Files.write(srcFile, MAIN_CLASS);
+
+ var moduleFile = Path.of("main").resolve("module-info.java");
+ Files.write(moduleFile, MODULE_INFO);
+
+ // Compile the source code to class files
+ javac("--module-source-path", ".",
+ "--module", "main",
+ "-d", CLASS_DIR.toString());
+
+ // Link the first image
+ var firstImage = Path.of("image-first");
+ jlink(firstImage);
+ var firstModulesFile = firstImage.resolve("lib")
+ .resolve("modules");
+
+ // Link the second image
+ var secondImage = Path.of("image-second");
+ jlink(secondImage);
+ var secondModulesFile = secondImage.resolve("lib")
+ .resolve("modules");
+
+ // Ensure module files are identical
+ assertEquals(-1L, Files.mismatch(firstModulesFile, secondModulesFile));
+ }
+}
--- a/test/jdk/tools/jlink/JLinkTest.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/tools/jlink/JLinkTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -44,6 +44,7 @@
* @summary Test image creation
* @bug 8189777
* @bug 8194922
+ * @bug 8206962
* @author Jean-Francois Denise
* @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g)
* @library ../lib
@@ -344,6 +345,16 @@
.option("--help")
.call().assertSuccess();
}
+
+ {
+ String imageDir = "bug8206962";
+ JImageGenerator.getJLinkTask()
+ .modulePath(helper.defaultModulePath())
+ .output(helper.createNewImageDir(imageDir))
+ .addMods("java.base")
+ .option("--release-info=del")
+ .call().assertFailure("Error: No key specified for delete");
+ }
}
private static void testCompress(Helper helper, String moduleName, String... userOptions) throws IOException {
--- a/test/jdk/tools/launcher/HelpFlagsTest.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/tools/launcher/HelpFlagsTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -140,6 +140,7 @@
new ToolHelpSpec("jdb", 1, 1, 1, 0, 1, 1, 0), // -?, -h, --help -help, Documents -help
new ToolHelpSpec("jdeprscan", 1, 1, 1, 0, 0, 0, 1), // -?, -h, --help
new ToolHelpSpec("jdeps", 1, 1, 1, 0, 1, 0, 2), // -?, -h, --help, -help accepted but not documented.
+ new ToolHelpSpec("jfr", 1, 1, 1, 0, 0, 0, 2), // -?, -h, --help
new ToolHelpSpec("jhsdb", 0, 0, 0, 0, 0, 0, 0), // none, prints help message anyways.
new ToolHelpSpec("jimage", 1, 1, 1, 0, 0, 0, 2), // -?, -h, --help
new ToolHelpSpec("jinfo", 1, 1, 1, 0, 1, 1, 1), // -?, -h, --help -help, Documents -help
@@ -224,6 +225,7 @@
line.charAt(posAfter) != ',' &&
line.charAt(posAfter) != '[' && // jar
line.charAt(posAfter) != ']' && // jarsigner
+ line.charAt(posAfter) != ')' && // jfr
line.charAt(posAfter) != '|' && // jstatd
line.charAt(posAfter) != ':' && // jps
line.charAt(posAfter) != '"') { // keytool
--- a/test/jdk/tools/launcher/VersionCheck.java Wed Dec 05 17:03:58 2018 -0500
+++ b/test/jdk/tools/launcher/VersionCheck.java Wed Dec 05 17:05:42 2018 -0500
@@ -88,6 +88,7 @@
"jcontrol",
"jdeprscan",
"jdeps",
+ "jfr",
"jimage",
"jinfo",
"jlink",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/T8213703/InvalidReceiverTypeTest.java Wed Dec 05 17:05:42 2018 -0500
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8213703
+ * @summary LambdaConversionException: Invalid receiver type not a subtype of implementation type interface
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+public class InvalidReceiverTypeTest {
+
+ static abstract class A {}
+
+ interface B {
+ boolean g();
+ }
+
+ static class C extends A implements B {
+ public boolean g() {
+ return true;
+ }
+ }
+
+ static class D<R extends A & B> {
+ public long f(List<? extends R> xs) {
+ return xs.stream().filter(B::g).count();
+ }
+ }
+
+ public static void main(String[] args) {
+ long count = new D<C>().f(Arrays.asList(new C()));
+ System.err.println(count);
+ }
+}