From 455fd39d4988f452546f679c0aa78d2e6d104961 Mon Sep 17 00:00:00 2001
From: Harold Seigel
Date: Thu, 7 Mar 2013 11:49:38 -0500
Subject: [PATCH 001/136] 7158805: Better rewriting of nested subroutine calls
Reviewed-by: mschoene, coleenp
---
hotspot/src/share/vm/memory/allocation.cpp | 30 +++++++++-----------
hotspot/src/share/vm/memory/allocation.hpp | 23 +++++++++++----
hotspot/src/share/vm/oops/generateOopMap.cpp | 20 +++++++++----
3 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index f83eada8192..675d86f8cdc 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -248,7 +248,7 @@ class ChunkPool: public CHeapObj {
ChunkPool(size_t size) : _size(size) { _first = NULL; _num_chunks = _num_used = 0; }
// Allocate a new chunk from the pool (might expand the pool)
- _NOINLINE_ void* allocate(size_t bytes) {
+ _NOINLINE_ void* allocate(size_t bytes, AllocFailType alloc_failmode) {
assert(bytes == _size, "bad size");
void* p = NULL;
// No VM lock can be taken inside ThreadCritical lock, so os::malloc
@@ -258,9 +258,9 @@ class ChunkPool: public CHeapObj {
p = get_first();
}
if (p == NULL) p = os::malloc(bytes, mtChunk, CURRENT_PC);
- if (p == NULL)
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "ChunkPool::allocate");
-
+ }
return p;
}
@@ -357,7 +357,7 @@ class ChunkPoolCleaner : public PeriodicTask {
//--------------------------------------------------------------------------------------
// Chunk implementation
-void* Chunk::operator new(size_t requested_size, size_t length) {
+void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, size_t length) {
// requested_size is equal to sizeof(Chunk) but in order for the arena
// allocations to come out aligned as expected the size must be aligned
// to expected arean alignment.
@@ -365,13 +365,14 @@ void* Chunk::operator new(size_t requested_size, size_t length) {
assert(ARENA_ALIGN(requested_size) == aligned_overhead_size(), "Bad alignment");
size_t bytes = ARENA_ALIGN(requested_size) + length;
switch (length) {
- case Chunk::size: return ChunkPool::large_pool()->allocate(bytes);
- case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes);
- case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes);
+ case Chunk::size: return ChunkPool::large_pool()->allocate(bytes, alloc_failmode);
+ case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes, alloc_failmode);
+ case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes, alloc_failmode);
default: {
- void *p = os::malloc(bytes, mtChunk, CALLER_PC);
- if (p == NULL)
+ void* p = os::malloc(bytes, mtChunk, CALLER_PC);
+ if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) {
vm_exit_out_of_memory(bytes, "Chunk::new");
+ }
return p;
}
}
@@ -425,7 +426,7 @@ NOT_PRODUCT(volatile jint Arena::_instance_count = 0;)
Arena::Arena(size_t init_size) {
size_t round_size = (sizeof (char *)) - 1;
init_size = (init_size+round_size) & ~round_size;
- _first = _chunk = new (init_size) Chunk(init_size);
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, init_size) Chunk(init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(init_size);
@@ -433,7 +434,7 @@ Arena::Arena(size_t init_size) {
}
Arena::Arena() {
- _first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size);
+ _first = _chunk = new (AllocFailStrategy::EXIT_OOM, Chunk::init_size) Chunk(Chunk::init_size);
_hwm = _chunk->bottom(); // Save the cached hwm, max
_max = _chunk->top();
set_size_in_bytes(Chunk::init_size);
@@ -540,12 +541,9 @@ void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
size_t len = MAX2(x, (size_t) Chunk::size);
Chunk *k = _chunk; // Get filled-up chunk address
- _chunk = new (len) Chunk(len);
+ _chunk = new (alloc_failmode, len) Chunk(len);
if (_chunk == NULL) {
- if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
- signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
- }
return NULL;
}
if (k) k->set_next(_chunk); // Append new chunk to end of linked list
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index bc01b0135b0..a5371b7aa1b 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -274,7 +274,7 @@ class Chunk: CHeapObj {
Chunk* _next; // Next Chunk in list
const size_t _len; // Size of this Chunk
public:
- void* operator new(size_t size, size_t length);
+ void* operator new(size_t size, AllocFailType alloc_failmode, size_t length);
void operator delete(void* p);
Chunk(size_t length);
@@ -337,10 +337,15 @@ protected:
void signal_out_of_memory(size_t request, const char* whence) const;
- void check_for_overflow(size_t request, const char* whence) const {
+ bool check_for_overflow(size_t request, const char* whence,
+ AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) const {
if (UINTPTR_MAX - request < (uintptr_t)_hwm) {
+ if (alloc_failmode == AllocFailStrategy::RETURN_NULL) {
+ return false;
+ }
signal_out_of_memory(request, whence);
}
+ return true;
}
public:
@@ -364,7 +369,8 @@ protected:
assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
x = ARENA_ALIGN(x);
debug_only(if (UseMallocOnly) return malloc(x);)
- check_for_overflow(x, "Arena::Amalloc");
+ if (!check_for_overflow(x, "Arena::Amalloc", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
@@ -378,7 +384,8 @@ protected:
void *Amalloc_4(size_t x, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM) {
assert( (x&(sizeof(char*)-1)) == 0, "misaligned size" );
debug_only(if (UseMallocOnly) return malloc(x);)
- check_for_overflow(x, "Arena::Amalloc_4");
+ if (!check_for_overflow(x, "Arena::Amalloc_4", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode);
@@ -399,7 +406,8 @@ protected:
size_t delta = (((size_t)_hwm + DALIGN_M1) & ~DALIGN_M1) - (size_t)_hwm;
x += delta;
#endif
- check_for_overflow(x, "Arena::Amalloc_D");
+ if (!check_for_overflow(x, "Arena::Amalloc_D", alloc_failmode))
+ return NULL;
NOT_PRODUCT(inc_bytes_allocated(x);)
if (_hwm + x > _max) {
return grow(x, alloc_failmode); // grow() returns a result aligned >= 8 bytes.
@@ -539,6 +547,9 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
#define NEW_RESOURCE_ARRAY(type, size)\
(type*) resource_allocate_bytes((size) * sizeof(type))
+#define NEW_RESOURCE_ARRAY_RETURN_NULL(type, size)\
+ (type*) resource_allocate_bytes((size) * sizeof(type), AllocFailStrategy::RETURN_NULL)
+
#define NEW_RESOURCE_ARRAY_IN_THREAD(thread, type, size)\
(type*) resource_allocate_bytes(thread, (size) * sizeof(type))
diff --git a/hotspot/src/share/vm/oops/generateOopMap.cpp b/hotspot/src/share/vm/oops/generateOopMap.cpp
index 8c12b7ac77d..9a9dc23d4e8 100644
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp
@@ -642,11 +642,21 @@ int GenerateOopMap::next_bb_start_pc(BasicBlock *bb) {
// CellType handling methods
//
+// Allocate memory and throw LinkageError if failure.
+#define ALLOC_RESOURCE_ARRAY(var, type, count) \
+ var = NEW_RESOURCE_ARRAY_RETURN_NULL(type, count); \
+ if (var == NULL) { \
+ report_error("Cannot reserve enough memory to analyze this method"); \
+ return; \
+ }
+
+
void GenerateOopMap::init_state() {
_state_len = _max_locals + _max_stack + _max_monitors;
- _state = NEW_RESOURCE_ARRAY(CellTypeState, _state_len);
+ ALLOC_RESOURCE_ARRAY(_state, CellTypeState, _state_len);
memset(_state, 0, _state_len * sizeof(CellTypeState));
- _state_vec_buf = NEW_RESOURCE_ARRAY(char, MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */);
+ int count = MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */;
+ ALLOC_RESOURCE_ARRAY(_state_vec_buf, char, count);
}
void GenerateOopMap::make_context_uninitialized() {
@@ -905,7 +915,7 @@ void GenerateOopMap::init_basic_blocks() {
// But cumbersome since we don't know the stack heights yet. (Nor the
// monitor stack heights...)
- _basic_blocks = NEW_RESOURCE_ARRAY(BasicBlock, _bb_count);
+ ALLOC_RESOURCE_ARRAY(_basic_blocks, BasicBlock, _bb_count);
// Make a pass through the bytecodes. Count the number of monitorenters.
// This can be used an upper bound on the monitor stack depth in programs
@@ -976,8 +986,8 @@ void GenerateOopMap::init_basic_blocks() {
return;
}
- CellTypeState *basicBlockState =
- NEW_RESOURCE_ARRAY(CellTypeState, bbNo * _state_len);
+ CellTypeState *basicBlockState;
+ ALLOC_RESOURCE_ARRAY(basicBlockState, CellTypeState, bbNo * _state_len);
memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState));
// Make a pass over the basicblocks and assign their state vectors.
From 6ebc920e1e1f63f3c0b8b44c04b3cc776e522fca Mon Sep 17 00:00:00 2001
From: Sean Mullan
Date: Fri, 5 Apr 2013 10:18:36 -0400
Subject: [PATCH 002/136] 8001330: Improve on checking order
Reviewed-by: acorn, hawtin
---
.../src/share/vm/classfile/javaClasses.cpp | 26 ++++++
.../src/share/vm/classfile/javaClasses.hpp | 9 +-
hotspot/src/share/vm/classfile/vmSymbols.hpp | 2 +
hotspot/src/share/vm/memory/universe.cpp | 21 +++++
hotspot/src/share/vm/memory/universe.hpp | 4 +
hotspot/src/share/vm/prims/jvm.cpp | 83 +++++++++++++++++--
6 files changed, 137 insertions(+), 8 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index fe03d3fb132..0550adc9ebc 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -2774,6 +2774,7 @@ void java_lang_invoke_CallSite::compute_offsets() {
int java_security_AccessControlContext::_context_offset = 0;
int java_security_AccessControlContext::_privilegedContext_offset = 0;
int java_security_AccessControlContext::_isPrivileged_offset = 0;
+int java_security_AccessControlContext::_isAuthorized_offset = -1;
void java_security_AccessControlContext::compute_offsets() {
assert(_isPrivileged_offset == 0, "offsets should be initialized only once");
@@ -2794,9 +2795,20 @@ void java_security_AccessControlContext::compute_offsets() {
fatal("Invalid layout of java.security.AccessControlContext");
}
_isPrivileged_offset = fd.offset();
+
+ // The offset may not be present for bootstrapping with older JDK.
+ if (ik->find_local_field(vmSymbols::isAuthorized_name(), vmSymbols::bool_signature(), &fd)) {
+ _isAuthorized_offset = fd.offset();
+ }
}
+bool java_security_AccessControlContext::is_authorized(Handle context) {
+ assert(context.not_null() && context->klass() == SystemDictionary::AccessControlContext_klass(), "Invalid type");
+ assert(_isAuthorized_offset != -1, "should be set");
+ return context->bool_field(_isAuthorized_offset) != 0;
+}
+
oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) {
assert(_isPrivileged_offset != 0, "offsets should have been initialized");
// Ensure klass is initialized
@@ -2807,6 +2819,8 @@ oop java_security_AccessControlContext::create(objArrayHandle context, bool isPr
result->obj_field_put(_context_offset, context());
result->obj_field_put(_privilegedContext_offset, privileged_context());
result->bool_field_put(_isPrivileged_offset, isPrivileged);
+ // whitelist AccessControlContexts created by the JVM.
+ result->bool_field_put(_isAuthorized_offset, true);
return result;
}
@@ -2916,6 +2930,15 @@ int java_lang_System::err_offset_in_bytes() {
}
+bool java_lang_System::has_security_manager() {
+ InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::System_klass());
+ address addr = ik->static_field_addr(static_security_offset);
+ if (UseCompressedOops) {
+ return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL;
+ } else {
+ return oopDesc::load_decode_heap_oop((oop*)addr) != NULL;
+ }
+}
int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
@@ -2976,6 +2999,7 @@ int java_lang_ClassLoader::parent_offset;
int java_lang_System::static_in_offset;
int java_lang_System::static_out_offset;
int java_lang_System::static_err_offset;
+int java_lang_System::static_security_offset;
int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
@@ -3101,6 +3125,7 @@ void JavaClasses::compute_hard_coded_offsets() {
java_lang_System::static_in_offset = java_lang_System::hc_static_in_offset * x;
java_lang_System::static_out_offset = java_lang_System::hc_static_out_offset * x;
java_lang_System::static_err_offset = java_lang_System::hc_static_err_offset * x;
+ java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x;
// java_lang_StackTraceElement
java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header;
@@ -3300,6 +3325,7 @@ void JavaClasses::check_offsets() {
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, in, "Ljava/io/InputStream;");
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, out, "Ljava/io/PrintStream;");
CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, err, "Ljava/io/PrintStream;");
+ CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, security, "Ljava/lang/SecurityManager;");
// java.lang.StackTraceElement
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
index ac0f15e2cee..b0314a6e007 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
@@ -1149,11 +1149,14 @@ class java_security_AccessControlContext: AllStatic {
static int _context_offset;
static int _privilegedContext_offset;
static int _isPrivileged_offset;
+ static int _isAuthorized_offset;
static void compute_offsets();
public:
static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS);
+ static bool is_authorized(Handle context);
+
// Debugging/initialization
friend class JavaClasses;
};
@@ -1213,18 +1216,22 @@ class java_lang_System : AllStatic {
enum {
hc_static_in_offset = 0,
hc_static_out_offset = 1,
- hc_static_err_offset = 2
+ hc_static_err_offset = 2,
+ hc_static_security_offset = 3
};
static int static_in_offset;
static int static_out_offset;
static int static_err_offset;
+ static int static_security_offset;
public:
static int in_offset_in_bytes();
static int out_offset_in_bytes();
static int err_offset_in_bytes();
+ static bool has_security_manager();
+
// Debugging
friend class JavaClasses;
};
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 1e66346eec5..ab68f3a5ed4 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -94,6 +94,7 @@
template(java_lang_SecurityManager, "java/lang/SecurityManager") \
template(java_security_AccessControlContext, "java/security/AccessControlContext") \
template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \
+ template(impliesCreateAccessControlContext_name, "impliesCreateAccessControlContext") \
template(java_io_OutputStream, "java/io/OutputStream") \
template(java_io_Reader, "java/io/Reader") \
template(java_io_BufferedReader, "java/io/BufferedReader") \
@@ -346,6 +347,7 @@
template(contextClassLoader_name, "contextClassLoader") \
template(inheritedAccessControlContext_name, "inheritedAccessControlContext") \
template(isPrivileged_name, "isPrivileged") \
+ template(isAuthorized_name, "isAuthorized") \
template(getClassContext_name, "getClassContext") \
template(wait_name, "wait") \
template(checkPackageAccess_name, "checkPackageAccess") \
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 90a2276cb93..12d92aae49d 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -108,6 +108,7 @@ oop Universe::_the_null_string = NULL;
oop Universe::_the_min_jint_string = NULL;
LatestMethodOopCache* Universe::_finalizer_register_cache = NULL;
LatestMethodOopCache* Universe::_loader_addClass_cache = NULL;
+LatestMethodOopCache* Universe::_pd_implies_cache = NULL;
ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL;
oop Universe::_out_of_memory_error_java_heap = NULL;
oop Universe::_out_of_memory_error_perm_gen = NULL;
@@ -224,6 +225,7 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
_finalizer_register_cache->serialize(f);
_loader_addClass_cache->serialize(f);
_reflect_invoke_cache->serialize(f);
+ _pd_implies_cache->serialize(f);
}
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
@@ -648,6 +650,7 @@ jint universe_init() {
// Metaspace::initialize_shared_spaces() tries to populate them.
Universe::_finalizer_register_cache = new LatestMethodOopCache();
Universe::_loader_addClass_cache = new LatestMethodOopCache();
+ Universe::_pd_implies_cache = new LatestMethodOopCache();
Universe::_reflect_invoke_cache = new ActiveMethodOopsCache();
if (UseSharedSpaces) {
@@ -1082,6 +1085,23 @@ bool universe_post_init() {
Universe::_loader_addClass_cache->init(
SystemDictionary::ClassLoader_klass(), m, CHECK_false);
+ // Setup method for checking protection domain
+ InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false);
+ m = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->
+ find_method(vmSymbols::impliesCreateAccessControlContext_name(),
+ vmSymbols::void_boolean_signature());
+ // Allow NULL which should only happen with bootstrapping.
+ if (m != NULL) {
+ if (m->is_static()) {
+ // NoSuchMethodException doesn't actually work because it tries to run the
+ // function before java_lang_Class is linked. Print error and exit.
+ tty->print_cr("ProtectionDomain.impliesCreateAccessControlContext() has the wrong linkage");
+ return false; // initialization failed
+ }
+ Universe::_pd_implies_cache->init(
+ SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);;
+ }
+
// The folowing is initializing converter functions for serialization in
// JVM.cpp. If we clean up the StrictMath code above we may want to find
// a better solution for this as well.
@@ -1497,6 +1517,7 @@ bool ActiveMethodOopsCache::is_same_method(Method* const method) const {
Method* LatestMethodOopCache::get_Method() {
+ if (klass() == NULL) return NULL;
InstanceKlass* ik = InstanceKlass::cast(klass());
Method* m = ik->method_with_idnum(method_idnum());
assert(m != NULL, "sanity check");
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index 2bf0b653f58..6c890d6ea46 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -176,6 +176,7 @@ class Universe: AllStatic {
static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string
static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects
static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
+ static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes
static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks
static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace)
static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace)
@@ -346,7 +347,10 @@ class Universe: AllStatic {
static oop the_min_jint_string() { return _the_min_jint_string; }
static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); }
static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); }
+
+ static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); }
static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; }
+
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 5c31ea1e5ac..628888010db 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1144,6 +1144,56 @@ JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protect
}
JVM_END
+static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) {
+ // If there is a security manager and protection domain, check the access
+ // in the protection domain, otherwise it is authorized.
+ if (java_lang_System::has_security_manager()) {
+
+ // For bootstrapping, if pd implies method isn't in the JDK, allow
+ // this context to revert to older behavior.
+ // In this case the isAuthorized field in AccessControlContext is also not
+ // present.
+ if (Universe::protection_domain_implies_method() == NULL) {
+ return true;
+ }
+
+ // Whitelist certain access control contexts
+ if (java_security_AccessControlContext::is_authorized(context)) {
+ return true;
+ }
+
+ oop prot = klass->protection_domain();
+ if (prot != NULL) {
+ // Call pd.implies(new SecurityPermission("createAccessControlContext"))
+ // in the new wrapper.
+ methodHandle m(THREAD, Universe::protection_domain_implies_method());
+ Handle h_prot(THREAD, prot);
+ JavaValue result(T_BOOLEAN);
+ JavaCallArguments args(h_prot);
+ JavaCalls::call(&result, m, &args, CHECK_false);
+ return (result.get_jboolean() != 0);
+ }
+ }
+ return true;
+}
+
+// Create an AccessControlContext with a protection domain with null codesource
+// and null permissions - which gives no permissions.
+oop create_dummy_access_control_context(TRAPS) {
+ InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass());
+ // new ProtectionDomain(null,null);
+ oop null_protection_domain = pd_klass->allocate_instance(CHECK_NULL);
+ Handle null_pd(THREAD, null_protection_domain);
+
+ // new ProtectionDomain[] {pd};
+ objArrayOop context = oopFactory::new_objArray(pd_klass, 1, CHECK_NULL);
+ context->obj_at_put(0, null_pd());
+
+ // new AccessControlContext(new ProtectionDomain[] {pd})
+ objArrayHandle h_context(THREAD, context);
+ oop result = java_security_AccessControlContext::create(h_context, false, Handle(), CHECK_NULL);
+ return result;
+}
JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject context, jboolean wrapException))
JVMWrapper("JVM_DoPrivileged");
@@ -1152,8 +1202,29 @@ JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, job
THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), "Null action");
}
- // Stack allocated list of privileged stack elements
- PrivilegedElement pi;
+ // Compute the frame initiating the do privileged operation and setup the privileged stack
+ vframeStream vfst(thread);
+ vfst.security_get_caller_frame(1);
+
+ if (vfst.at_end()) {
+ THROW_MSG_0(vmSymbols::java_lang_InternalError(), "no caller?");
+ }
+
+ Method* method = vfst.method();
+ instanceKlassHandle klass (THREAD, method->method_holder());
+
+ // Check that action object understands "Object run()"
+ Handle h_context;
+ if (context != NULL) {
+ h_context = Handle(THREAD, JNIHandles::resolve(context));
+ bool authorized = is_authorized(h_context, klass, CHECK_NULL);
+ if (!authorized) {
+ // Create an unprivileged access control object and call it's run function
+ // instead.
+ oop noprivs = create_dummy_access_control_context(CHECK_NULL);
+ h_context = Handle(THREAD, noprivs);
+ }
+ }
// Check that action object understands "Object run()"
Handle object (THREAD, JNIHandles::resolve(action));
@@ -1167,12 +1238,10 @@ JVM_ENTRY(jobject, JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, job
THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
}
- // Compute the frame initiating the do privileged operation and setup the privileged stack
- vframeStream vfst(thread);
- vfst.security_get_caller_frame(1);
-
+ // Stack allocated list of privileged stack elements
+ PrivilegedElement pi;
if (!vfst.at_end()) {
- pi.initialize(&vfst, JNIHandles::resolve(context), thread->privileged_stack_top(), CHECK_NULL);
+ pi.initialize(&vfst, h_context(), thread->privileged_stack_top(), CHECK_NULL);
thread->set_privileged_stack_top(&pi);
}
From dec7bd5d024b95ea7bd1747dfa80580e12acb630 Mon Sep 17 00:00:00 2001
From: Sean Coffey
Date: Mon, 8 Apr 2013 23:12:03 +0100
Subject: [PATCH 003/136] 8001032: Restrict object access
Restrict object access; fix reviewed also by Alexander Fomin
Reviewed-by: alanb, ahgross
---
.../com_sun_corba_se_impl_orbutil.jmk | 3 +-
.../se/impl/activation/ServerManagerImpl.java | 3 +-
.../se/impl/interceptors/PIHandlerImpl.java | 3 +-
.../se/impl/interceptors/RequestInfoImpl.java | 11 +++--
.../sun/corba/se/impl/io/ValueUtility.java | 10 +++-
.../corba/se/impl/javax/rmi/CORBA/Util.java | 11 ++---
.../corba/se/impl/orb/ORBDataParserImpl.java | 3 +-
.../com/sun/corba/se/impl/orb/ORBImpl.java | 3 +-
.../sun/corba/se/impl/orb/ParserTable.java | 22 +++++----
.../corba/se/impl/orbutil/ORBClassLoader.java | 47 -------------------
.../sun/corba/se/impl/orbutil/ORBUtility.java | 8 ++--
.../LocateReplyMessage_1_2.java | 3 +-
.../protocol/giopmsgheaders/MessageBase.java | 8 ++--
.../giopmsgheaders/ReplyMessage_1_0.java | 3 +-
.../giopmsgheaders/ReplyMessage_1_1.java | 3 +-
.../classes/com/sun/corba/se/spi/orb/ORB.java | 6 +--
.../corba/se/spi/orb/OperationFactory.java | 8 ++--
.../classes/sun/corba/JavaCorbaAccess.java | 3 +-
18 files changed, 61 insertions(+), 97 deletions(-)
delete mode 100644 corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java
diff --git a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
index 465c546ec59..d007b4e374c 100644
--- a/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
+++ b/corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,6 @@ com_sun_corba_se_impl_orbutil_java = \
com/sun/corba/se/impl/orbutil/ObjectStreamClassUtil_1_3.java \
com/sun/corba/se/impl/orbutil/ORBConstants.java \
com/sun/corba/se/impl/orbutil/ORBUtility.java \
- com/sun/corba/se/impl/orbutil/ORBClassLoader.java \
com/sun/corba/se/impl/orbutil/RepIdDelegator.java \
com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java \
com/sun/corba/se/impl/orbutil/RepositoryIdStrings.java \
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
index 4fde9aad06a..745f0aafadb 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/activation/ServerManagerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,6 @@ import com.sun.corba.se.impl.logging.ActivationSystemException ;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.util.Utility;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
index e7d7ae27e76..9ad417e464e 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/PIHandlerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,6 @@ import com.sun.corba.se.impl.logging.InterceptorsSystemException;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.corba.RequestImpl;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.StackImpl;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
index a20de7a3af0..9ef904b02e1 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,13 +86,14 @@ import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
import com.sun.corba.se.impl.encoding.EncapsOutputStream;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.util.RepositoryId;
import com.sun.corba.se.impl.logging.InterceptorsSystemException;
import com.sun.corba.se.impl.logging.OMGSystemException;
+import sun.corba.SharedSecrets;
+
/**
* Implementation of the RequestInfo interface as specified in
* orbos/99-12-02 section 5.4.1.
@@ -452,7 +453,8 @@ public abstract class RequestInfoImpl
// Find the read method on the helper class:
String helperClassName = className + "Helper";
- Class helperClass = ORBClassLoader.loadClass( helperClassName );
+ Class> helperClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
Class[] readParams = new Class[1];
readParams[0] = org.omg.CORBA.portable.InputStream.class;
Method readMethod = helperClass.getMethod( "read", readParams );
@@ -512,7 +514,8 @@ public abstract class RequestInfoImpl
Class exceptionClass = userException.getClass();
String className = exceptionClass.getName();
String helperClassName = className + "Helper";
- Class helperClass = ORBClassLoader.loadClass( helperClassName );
+ Class> helperClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass( helperClassName );
// Find insert( Any, class ) method
Class[] insertMethodParams = new Class[2];
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java b/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
index 41d85a265fc..20cec8d7b30 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,14 @@ public class ValueUtility {
public ValueHandlerImpl newValueHandlerImpl() {
return ValueHandlerImpl.getInstance();
}
+ public Class> loadClass(String className) throws ClassNotFoundException {
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ return Thread.currentThread().getContextClassLoader().
+ loadClass(className);
+ } else {
+ return ClassLoader.getSystemClassLoader().loadClass(className);
+ }
+ }
});
}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
index aa2c6483804..7829d52a495 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -109,12 +109,9 @@ import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.IdentityHashtable;
import com.sun.corba.se.impl.util.JDKBridge;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.logging.UtilSystemException;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import sun.corba.SharedSecrets;
-import sun.corba.JavaCorbaAccess;
-
/**
* Provides utility methods that can be used by stubs and ties to
@@ -263,7 +260,7 @@ public class Util implements javax.rmi.CORBA.UtilDelegate
return new MarshalException(message,inner);
} else if (ex instanceof ACTIVITY_REQUIRED) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.ActivityRequiredException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
@@ -279,7 +276,7 @@ public class Util implements javax.rmi.CORBA.UtilDelegate
}
} else if (ex instanceof ACTIVITY_COMPLETED) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.ActivityCompletedException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
@@ -295,7 +292,7 @@ public class Util implements javax.rmi.CORBA.UtilDelegate
}
} else if (ex instanceof INVALID_ACTIVITY) {
try {
- Class cl = ORBClassLoader.loadClass(
+ Class> cl = SharedSecrets.getJavaCorbaAccess().loadClass(
"javax.activity.InvalidActivityException");
Class[] params = new Class[2];
params[0] = java.lang.String.class;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
index 46b0627ae35..94bb5d9ee8f 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBDataParserImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,6 @@ import com.sun.corba.se.spi.transport.ReadTimeouts;
import com.sun.corba.se.impl.encoding.CodeSetComponentInfo ;
import com.sun.corba.se.impl.legacy.connection.USLPort;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ORBConstants ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
index 5db85734a95..ee0a535205a 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,6 @@ import com.sun.corba.se.impl.oa.toa.TOAFactory;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
import com.sun.corba.se.impl.oa.poa.DelegateImpl;
import com.sun.corba.se.impl.oa.poa.POAFactory;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.StackImpl;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
index 550c4a7f304..6229de4be15 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,6 @@ import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry ;
import com.sun.corba.se.impl.legacy.connection.USLPort ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
import com.sun.corba.se.impl.oa.poa.BadServerIdHandler ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ORBConstants ;
import com.sun.corba.se.impl.protocol.giopmsgheaders.KeyAddr ;
import com.sun.corba.se.impl.protocol.giopmsgheaders.ProfileAddr ;
@@ -86,6 +85,8 @@ import com.sun.corba.se.impl.protocol.giopmsgheaders.ReferenceAddr ;
import com.sun.corba.se.impl.transport.DefaultIORToSocketInfoImpl;
import com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl;
+import sun.corba.SharedSecrets;
+
/** Initialize the parser data for the standard ORB parser. This is used both
* to implement ORBDataParserImpl and to provide the basic testing framework
* for ORBDataParserImpl.
@@ -640,8 +641,8 @@ public class ParserTable {
String param = (String)value ;
try {
- Class legacySocketFactoryClass =
- ORBClassLoader.loadClass(param);
+ Class> legacySocketFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -670,7 +671,8 @@ public class ParserTable {
String param = (String)value ;
try {
- Class socketFactoryClass = ORBClassLoader.loadClass(param);
+ Class> socketFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -699,7 +701,8 @@ public class ParserTable {
String param = (String)value ;
try {
- Class iorToSocketInfoClass = ORBClassLoader.loadClass(param);
+ Class> iorToSocketInfoClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -728,7 +731,8 @@ public class ParserTable {
String param = (String)value ;
try {
- Class iiopPrimaryToContactInfoClass = ORBClassLoader.loadClass(param);
+ Class> iiopPrimaryToContactInfoClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
@@ -757,8 +761,8 @@ public class ParserTable {
String param = (String)value ;
try {
- Class contactInfoListFactoryClass =
- ORBClassLoader.loadClass(param);
+ Class> contactInfoListFactoryClass =
+ SharedSecrets.getJavaCorbaAccess().loadClass(param);
// For security reasons avoid creating an instance if
// this socket factory class is not one that would fail
// the class cast anyway.
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java
deleted file mode 100644
index 3e3ba8dcf11..00000000000
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBClassLoader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute 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 com.sun.corba.se.impl.orbutil;
-
-/**
- * Based on feedback from bug report 4452016, all class loading
- * in the ORB is isolated here. It is acceptable to use
- * Class.forName only when one is certain that the desired class
- * should come from the core JDK.
- */
-public class ORBClassLoader
-{
- public static Class loadClass(String className)
- throws ClassNotFoundException
- {
- return ORBClassLoader.getClassLoader().loadClass(className);
- }
-
- public static ClassLoader getClassLoader() {
- if (Thread.currentThread().getContextClassLoader() != null)
- return Thread.currentThread().getContextClassLoader();
- else
- return ClassLoader.getSystemClassLoader();
- }
-}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
index 23d51f9008a..41dba4d9489 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,6 +90,8 @@ import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
+import sun.corba.SharedSecrets;
+
/**
* Handy class full of static functions that don't belong in util.Utility for pure ORB reasons.
*/
@@ -262,8 +264,8 @@ public final class ORBUtility {
{
try {
String name = classNameOf(strm.read_string());
- SystemException ex
- = (SystemException)ORBClassLoader.loadClass(name).newInstance();
+ SystemException ex = (SystemException)SharedSecrets.
+ getJavaCorbaAccess().loadClass(name).newInstance();
ex.minor = strm.read_long();
ex.completed = CompletionStatus.from_int(strm.read_long());
return ex;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
index a3af1ec2a41..8274de69f84 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/LocateReplyMessage_1_2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@ import com.sun.corba.se.impl.encoding.CDROutputStream;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
index b1eb366882a..6559be7fca4 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/MessageBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,9 +60,10 @@ import com.sun.corba.se.impl.encoding.CDRInputStream_1_0;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.impl.protocol.AddressingDispositionException;
+import sun.corba.SharedSecrets;
+
/**
* This class acts as the base class for the various GIOP message types. This
* also serves as a factory to create various message types. We currently
@@ -909,7 +910,8 @@ public abstract class MessageBase implements Message{
SystemException sysEx = null;
try {
- Class clazz = ORBClassLoader.loadClass(exClassName);
+ Class> clazz =
+ SharedSecrets.getJavaCorbaAccess().loadClass(exClassName);
if (message == null) {
sysEx = (SystemException) clazz.newInstance();
} else {
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
index 8bcc4e8aec6..4d77e3aff0b 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_0.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@ import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.impl.encoding.CDRInputStream;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
index e22e0fb64f8..65d8578f634 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/giopmsgheaders/ReplyMessage_1_1.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@ import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.servicecontext.ServiceContexts;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.impl.orbutil.ORBUtility;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.impl.encoding.CDRInputStream;
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java b/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
index 306a9f7d2bf..91a691e2b25 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -97,8 +97,8 @@ import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import sun.awt.AppContext;
+import sun.corba.SharedSecrets;
public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
implements Broker, TypeCodeFactory
@@ -201,7 +201,7 @@ public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
try {
// First try the configured class name, if any
- Class cls = ORBClassLoader.loadClass( className ) ;
+ Class> cls = SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
sff = (PresentationManager.StubFactoryFactory)cls.newInstance() ;
} catch (Exception exc) {
// Use the default. Log the error as a warning.
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java b/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
index eb81eb56be0..d84523b0fd9 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,9 +35,10 @@ import java.net.MalformedURLException ;
import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
-import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
import com.sun.corba.se.impl.orbutil.ObjectUtility ;
+import sun.corba.SharedSecrets;
+
/** This is a static factory class for commonly used operations
* for property parsing. The following operations are supported:
*
@@ -247,7 +248,8 @@ public abstract class OperationFactory {
String className = getString( value ) ;
try {
- Class result = ORBClassLoader.loadClass( className ) ;
+ Class> result =
+ SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
return result ;
} catch (Exception exc) {
ORBUtilSystemException wrapper = ORBUtilSystemException.get(
diff --git a/corba/src/share/classes/sun/corba/JavaCorbaAccess.java b/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
index 046453f2767..0d21551ef3e 100644
--- a/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
+++ b/corba/src/share/classes/sun/corba/JavaCorbaAccess.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,4 +29,5 @@ import com.sun.corba.se.impl.io.ValueHandlerImpl;
public interface JavaCorbaAccess {
public ValueHandlerImpl newValueHandlerImpl();
+ public Class> loadClass(String className) throws ClassNotFoundException;
}
From 1fc6a72e9d80436c51a762232e36b820aa3ced2a Mon Sep 17 00:00:00 2001
From: Sean Mullan
Date: Mon, 22 Apr 2013 08:33:12 -0400
Subject: [PATCH 004/136] 8011896: Add check for invalid offset for new
AccessControlContext isAuthorized field
Reviewed-by: acorn
---
hotspot/src/share/vm/classfile/javaClasses.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index 0550adc9ebc..9c09d711b95 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -2819,8 +2819,10 @@ oop java_security_AccessControlContext::create(objArrayHandle context, bool isPr
result->obj_field_put(_context_offset, context());
result->obj_field_put(_privilegedContext_offset, privileged_context());
result->bool_field_put(_isPrivileged_offset, isPrivileged);
- // whitelist AccessControlContexts created by the JVM.
- result->bool_field_put(_isAuthorized_offset, true);
+ // whitelist AccessControlContexts created by the JVM if present
+ if (_isAuthorized_offset != -1) {
+ result->bool_field_put(_isAuthorized_offset, true);
+ }
return result;
}
From b342ac9ee19b9f6f189856d179451cc8d637b78b Mon Sep 17 00:00:00 2001
From: Sean Coffey
Date: Tue, 30 Apr 2013 11:53:51 +0100
Subject: [PATCH 005/136] 8000642: Better handling of objects for
transportation
Reviewed-by: alanb, mchung, skoivu
---
.../com/sun/corba/se/impl/corba/AnyImpl.java | 12 +-
.../sun/corba/se/impl/corba/TypeCodeImpl.java | 5 +-
.../IDLJavaSerializationOutputStream.java | 4 +-
.../impl/encoding/TypeCodeOutputStream.java | 8 +-
.../se/impl/interceptors/CDREncapsCodec.java | 5 +-
.../se/impl/interceptors/RequestInfoImpl.java | 7 +-
.../sun/corba/se/impl/io/IIOPInputStream.java | 8 +-
.../corba/se/impl/io/IIOPOutputStream.java | 10 +-
.../sun/corba/se/impl/io/InputStreamHook.java | 2 +-
.../corba/se/impl/io/OutputStreamHook.java | 2 +-
.../se/impl/ior/EncapsulationUtility.java | 3 +-
.../se/impl/ior/GenericTaggedProfile.java | 5 +-
.../com/sun/corba/se/impl/ior/IORImpl.java | 8 +-
.../sun/corba/se/impl/ior/ObjectKeyImpl.java | 3 +-
.../ior/TaggedComponentFactoryFinderImpl.java | 5 +-
.../se/impl/ior/iiop/IIOPProfileImpl.java | 5 +-
.../ior/iiop/IIOPProfileTemplateImpl.java | 7 +-
.../com/sun/corba/se/impl/orb/ORBImpl.java | 2 +-
.../sun/corba/se/impl/orb/ORBSingleton.java | 4 +-
.../protocol/CorbaMessageMediatorImpl.java | 22 ++-
.../impl/transport/CorbaContactInfoBase.java | 4 +-
.../transport/SharedCDRContactInfoImpl.java | 4 +-
.../SocketOrChannelAcceptorImpl.java | 8 +-
.../SocketOrChannelConnectionImpl.java | 6 +-
.../corba/se/spi/ior/TaggedComponentBase.java | 5 +-
.../se/spi/servicecontext/ServiceContext.java | 5 +-
.../omg/CORBA_2_3/portable/OutputStream.java | 40 ++++-
.../sun/corba/OutputStreamFactory.java | 149 ++++++++++++++++++
28 files changed, 278 insertions(+), 70 deletions(-)
create mode 100644 corba/src/share/classes/sun/corba/OutputStreamFactory.java
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
index 0177bdd6407..3018cdef99e 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,8 @@ package com.sun.corba.se.impl.corba;
import java.io.Serializable;
import java.math.BigDecimal;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.List ;
import java.util.ArrayList ;
@@ -504,7 +506,13 @@ public class AnyImpl extends Any
public org.omg.CORBA.portable.OutputStream create_output_stream()
{
//debug.log ("create_output_stream");
- return new AnyOutputStream(orb);
+ final ORB finalorb = this.orb;
+ return AccessController.doPrivileged(new PrivilegedAction() {
+ @Override
+ public AnyOutputStream run() {
+ return new AnyOutputStream(finalorb);
+ }
+ });
}
/**
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/corba/TypeCodeImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/corba/TypeCodeImpl.java
index 7e926ddba63..4e90f7f2a32 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/corba/TypeCodeImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/corba/TypeCodeImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -600,7 +600,8 @@ public final class TypeCodeImpl extends TypeCode
}
public static CDROutputStream newOutputStream(ORB orb) {
- TypeCodeOutputStream tcos = new TypeCodeOutputStream((ORB)orb);
+ TypeCodeOutputStream tcos =
+ sun.corba.OutputStreamFactory.newTypeCodeOutputStream(orb);
//if (debug) System.out.println("Created TypeCodeOutputStream " + tcos +
// " with no parent");
return tcos;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/encoding/IDLJavaSerializationOutputStream.java b/corba/src/share/classes/com/sun/corba/se/impl/encoding/IDLJavaSerializationOutputStream.java
index b26d2db2214..6914e0ec87a 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/IDLJavaSerializationOutputStream.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/IDLJavaSerializationOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@ import org.omg.CORBA.CompletionStatus;
*
* @author Ram Jeyaraman
*/
-public class IDLJavaSerializationOutputStream extends CDROutputStreamBase {
+final class IDLJavaSerializationOutputStream extends CDROutputStreamBase {
private ORB orb;
private byte encodingVersion;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/encoding/TypeCodeOutputStream.java b/corba/src/share/classes/com/sun/corba/se/impl/encoding/TypeCodeOutputStream.java
index 79139f15de6..94f6466013a 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/TypeCodeOutputStream.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/TypeCodeOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -196,7 +196,8 @@ public final class TypeCodeOutputStream extends EncapsOutputStream
}
public TypeCodeOutputStream createEncapsulation(org.omg.CORBA.ORB _orb) {
- TypeCodeOutputStream encap = new TypeCodeOutputStream((ORB)_orb, isLittleEndian());
+ TypeCodeOutputStream encap =
+ sun.corba.OutputStreamFactory.newTypeCodeOutputStream((ORB)_orb, isLittleEndian());
encap.setEnclosingOutputStream(this);
encap.makeEncapsulation();
//if (TypeCodeImpl.debug) System.out.println("Created TypeCodeOutputStream " + encap + " with parent " + this);
@@ -211,7 +212,8 @@ public final class TypeCodeOutputStream extends EncapsOutputStream
public static TypeCodeOutputStream wrapOutputStream(OutputStream os) {
boolean littleEndian = ((os instanceof CDROutputStream) ? ((CDROutputStream)os).isLittleEndian() : false);
- TypeCodeOutputStream tos = new TypeCodeOutputStream((ORB)os.orb(), littleEndian);
+ TypeCodeOutputStream tos =
+ sun.corba.OutputStreamFactory.newTypeCodeOutputStream((ORB)os.orb(), littleEndian);
tos.setEnclosingOutputStream(os);
//if (TypeCodeImpl.debug) System.out.println("Created TypeCodeOutputStream " + tos + " with parent " + os);
return tos;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/CDREncapsCodec.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/CDREncapsCodec.java
index 2b3e0fae116..6f469e2dc7d 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/CDREncapsCodec.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/CDREncapsCodec.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -155,7 +155,8 @@ public final class CDREncapsCodec
// be versioned. This can be handled once this work is complete.
// Create output stream with default endianness.
- EncapsOutputStream cdrOut = new EncapsOutputStream(
+ EncapsOutputStream cdrOut =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(
(com.sun.corba.se.spi.orb.ORB)orb, giopVersion );
// This is an encapsulation, so put out the endian:
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
index 9ef904b02e1..52e457f2220 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/interceptors/RequestInfoImpl.java
@@ -659,7 +659,8 @@ public abstract class RequestInfoImpl
// Convert the "core" service context to an
// "IOP" ServiceContext by writing it to a
// CDROutputStream and reading it back.
- EncapsOutputStream out = new EncapsOutputStream(myORB);
+ EncapsOutputStream out =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(myORB);
context.write( out, GIOPVersion.V1_2 );
InputStream inputStream = out.create_input_stream();
@@ -695,8 +696,8 @@ public abstract class RequestInfoImpl
{
int id = 0 ;
// Convert IOP.service_context to core.ServiceContext:
- EncapsOutputStream outputStream = new EncapsOutputStream(
- myORB );
+ EncapsOutputStream outputStream =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(myORB);
InputStream inputStream = null;
UnknownServiceContext coreServiceContext = null;
ServiceContextHelper.write( outputStream, service_context );
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java
index 9f7008a16f8..b8afc9ce839 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java
@@ -300,11 +300,11 @@ public class IIOPInputStream
resetStream();
}
- public final void setOrbStream(org.omg.CORBA_2_3.portable.InputStream os) {
+ final void setOrbStream(org.omg.CORBA_2_3.portable.InputStream os) {
orbStream = os;
}
- public final org.omg.CORBA_2_3.portable.InputStream getOrbStream() {
+ final org.omg.CORBA_2_3.portable.InputStream getOrbStream() {
return orbStream;
}
@@ -327,11 +327,11 @@ public class IIOPInputStream
return (javax.rmi.CORBA.ValueHandler) vhandler;
}
- public final void increaseRecursionDepth(){
+ final void increaseRecursionDepth(){
recursionDepth++;
}
- public final int decreaseRecursionDepth(){
+ final int decreaseRecursionDepth(){
return --recursionDepth;
}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java
index 9cf6afd6dbb..1ca9e118cfd 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -124,19 +124,19 @@ public class IIOPOutputStream
}
}
- public final void setOrbStream(org.omg.CORBA_2_3.portable.OutputStream os) {
+ final void setOrbStream(org.omg.CORBA_2_3.portable.OutputStream os) {
orbStream = os;
}
- public final org.omg.CORBA_2_3.portable.OutputStream getOrbStream() {
+ final org.omg.CORBA_2_3.portable.OutputStream getOrbStream() {
return orbStream;
}
- public final void increaseRecursionDepth(){
+ final void increaseRecursionDepth(){
recursionDepth++;
}
- public final int decreaseRecursionDepth(){
+ final int decreaseRecursionDepth(){
return --recursionDepth;
}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/InputStreamHook.java b/corba/src/share/classes/com/sun/corba/se/impl/io/InputStreamHook.java
index a55f0020adb..f8dcbe5b6d8 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/InputStreamHook.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/InputStreamHook.java
@@ -251,7 +251,7 @@ public abstract class InputStreamHook extends ObjectInputStream
}
protected abstract byte getStreamFormatVersion();
- protected abstract org.omg.CORBA_2_3.portable.InputStream getOrbStream();
+ abstract org.omg.CORBA_2_3.portable.InputStream getOrbStream();
// Description of possible actions
protected static class ReadObjectState {
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java b/corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java
index d596accfb49..a40b007bac5 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/io/OutputStreamHook.java
@@ -179,7 +179,7 @@ public abstract class OutputStreamHook extends ObjectOutputStream
putFields.write(this);
}
- public abstract org.omg.CORBA_2_3.portable.OutputStream getOrbStream();
+ abstract org.omg.CORBA_2_3.portable.OutputStream getOrbStream();
protected abstract void beginOptionalCustomData();
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/EncapsulationUtility.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/EncapsulationUtility.java
index 9071fc0c5aa..1d0f3c457f4 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/EncapsulationUtility.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/EncapsulationUtility.java
@@ -128,7 +128,8 @@ public class EncapsulationUtility
static public void writeEncapsulation( WriteContents obj,
OutputStream os )
{
- EncapsOutputStream out = new EncapsOutputStream( (ORB)os.orb() ) ;
+ EncapsOutputStream out =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)os.orb());
out.putEndian() ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/GenericTaggedProfile.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/GenericTaggedProfile.java
index 1d43402e668..b715dce5a39 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/GenericTaggedProfile.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/GenericTaggedProfile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,7 +95,8 @@ public class GenericTaggedProfile extends GenericIdentifiable implements TaggedP
public org.omg.IOP.TaggedProfile getIOPProfile()
{
- EncapsOutputStream os = new EncapsOutputStream( orb ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(orb);
write( os ) ;
InputStream is = (InputStream)(os.create_input_stream()) ;
return org.omg.IOP.TaggedProfileHelper.read( is ) ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/IORImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/IORImpl.java
index 8cd6fa271f0..8c531d0933a 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/IORImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/IORImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -213,7 +213,8 @@ public class IORImpl extends IdentifiableContainerBase implements IOR
{
StringWriter bs;
- MarshalOutputStream s = new EncapsOutputStream(factory);
+ MarshalOutputStream s =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(factory);
s.putEndian();
write( (OutputStream)s );
bs = new StringWriter();
@@ -237,7 +238,8 @@ public class IORImpl extends IdentifiableContainerBase implements IOR
}
public org.omg.IOP.IOR getIOPIOR() {
- EncapsOutputStream os = new EncapsOutputStream(factory);
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(factory);
write(os);
InputStream is = (InputStream) (os.create_input_stream());
return org.omg.IOP.IORHelper.read(is);
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/ObjectKeyImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/ObjectKeyImpl.java
index df2a1f5644e..614e035828d 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/ObjectKeyImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/ObjectKeyImpl.java
@@ -87,7 +87,8 @@ public class ObjectKeyImpl implements ObjectKey
public byte[] getBytes( org.omg.CORBA.ORB orb )
{
- EncapsOutputStream os = new EncapsOutputStream( (ORB)orb ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)orb);
write( os ) ;
return os.toByteArray() ;
}
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/TaggedComponentFactoryFinderImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/TaggedComponentFactoryFinderImpl.java
index bc1dbda9f4e..db334e75c79 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/TaggedComponentFactoryFinderImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/TaggedComponentFactoryFinderImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,8 @@ public class TaggedComponentFactoryFinderImpl extends
public TaggedComponent create( org.omg.CORBA.ORB orb,
org.omg.IOP.TaggedComponent comp )
{
- EncapsOutputStream os = new EncapsOutputStream( (ORB)orb ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)orb);
org.omg.IOP.TaggedComponentHelper.write( os, comp ) ;
InputStream is = (InputStream)(os.create_input_stream() ) ;
// Skip the component ID: we just wrote it out above
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileImpl.java
index be59b3f7959..4a7b0b921de 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -247,7 +247,8 @@ public class IIOPProfileImpl extends IdentifiableBase implements IIOPProfile
public org.omg.IOP.TaggedProfile getIOPProfile()
{
- EncapsOutputStream os = new EncapsOutputStream( orb ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(orb);
os.write_long( getId() ) ;
write( os ) ;
InputStream is = (InputStream)(os.create_input_stream()) ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileTemplateImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileTemplateImpl.java
index 26ac601daac..32a7d66d665 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileTemplateImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/ior/iiop/IIOPProfileTemplateImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -132,8 +132,9 @@ public class IIOPProfileTemplateImpl extends TaggedProfileTemplateBase
// Note that this cannot be accomplished with a codec!
// Use the byte order of the given stream
- OutputStream encapsulatedOS = new EncapsOutputStream( (ORB)os.orb(),
- ((CDROutputStream)os).isLittleEndian() ) ;
+ OutputStream encapsulatedOS =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream(
+ (ORB)os.orb(), ((CDROutputStream)os).isLittleEndian() ) ;
okeyTemplate.write( id, encapsulatedOS ) ;
EncapsulationUtility.writeOutputStream( encapsulatedOS, os ) ;
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
index ee0a535205a..8bda9dcbf0b 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
@@ -550,7 +550,7 @@ public class ORBImpl extends com.sun.corba.se.spi.orb.ORB
public synchronized org.omg.CORBA.portable.OutputStream create_output_stream()
{
checkShutdownState();
- return new EncapsOutputStream(this);
+ return sun.corba.OutputStreamFactory.newEncapsOutputStream(this);
}
/**
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java
index 9bf7a83df42..63bec8b1161 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ORBSingleton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -149,7 +149,7 @@ public class ORBSingleton extends ORB
}
public OutputStream create_output_stream() {
- return new EncapsOutputStream(this);
+ return sun.corba.OutputStreamFactory.newEncapsOutputStream(this);
}
public TypeCode create_struct_tc(String id,
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java
index a5ee15ba763..9badc182efd 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/protocol/CorbaMessageMediatorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1794,8 +1794,7 @@ public class CorbaMessageMediatorImpl
if (msg.getGIOPVersion().lessThan(GIOPVersion.V1_2)) {
// locate msgs 1.0 & 1.1 :=> grow,
- // REVISIT - build from factory
- outputObject = new CDROutputObject(
+ outputObject = sun.corba.OutputStreamFactory.newCDROutputObject(
(ORB) messageMediator.getBroker(),
this,
GIOPVersion.V1_0,
@@ -1804,8 +1803,7 @@ public class CorbaMessageMediatorImpl
ORBConstants.STREAM_FORMAT_VERSION_1);
} else {
// 1.2 :=> stream
- // REVISIT - build from factory
- outputObject = new CDROutputObject(
+ outputObject = sun.corba.OutputStreamFactory.newCDROutputObject(
(ORB) messageMediator.getBroker(),
messageMediator,
reply,
@@ -1959,7 +1957,8 @@ public class CorbaMessageMediatorImpl
ReplyMessage.NEEDS_ADDRESSING_MODE,
null, null);
// REVISIT: via acceptor factory.
- CDROutputObject outputObject = new CDROutputObject(
+ CDROutputObject outputObject =
+ sun.corba.OutputStreamFactory.newCDROutputObject(
(ORB)messageMediator.getBroker(),
this,
messageMediator.getGIOPVersion(),
@@ -2126,7 +2125,7 @@ public class CorbaMessageMediatorImpl
ex.printStackTrace(pw);
pw.flush(); // NOTE: you must flush or baos will be empty.
EncapsOutputStream encapsOutputStream =
- new EncapsOutputStream((ORB)mediator.getBroker());
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)mediator.getBroker());
encapsOutputStream.putEndian();
encapsOutputStream.write_wstring(baos.toString());
UnknownServiceContext serviceContext =
@@ -2203,12 +2202,11 @@ public class CorbaMessageMediatorImpl
// REVISIT = do not use null.
//
if (messageMediator.getConnection() == null) {
- // REVISIT - needs factory
replyOutputObject =
- new CDROutputObject(orb, messageMediator,
- messageMediator.getReplyHeader(),
- messageMediator.getStreamFormatVersion(),
- BufferManagerFactory.GROW);
+ sun.corba.OutputStreamFactory.newCDROutputObject(orb,
+ messageMediator, messageMediator.getReplyHeader(),
+ messageMediator.getStreamFormatVersion(),
+ BufferManagerFactory.GROW);
} else {
replyOutputObject = messageMediator.getConnection().getAcceptor()
.createOutputObject(messageMediator.getBroker(), messageMediator);
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaContactInfoBase.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaContactInfoBase.java
index 1a439e1b5a5..419efe7e68d 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaContactInfoBase.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaContactInfoBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -214,7 +214,7 @@ public abstract class CorbaContactInfoBase
messageMediator;
OutputObject outputObject =
- new CDROutputObject(orb, messageMediator,
+ sun.corba.OutputStreamFactory.newCDROutputObject(orb, messageMediator,
corbaMessageMediator.getRequestHeader(),
corbaMessageMediator.getStreamFormatVersion());
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SharedCDRContactInfoImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SharedCDRContactInfoImpl.java
index 08cc96f5da6..49f2b8a2062 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SharedCDRContactInfoImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SharedCDRContactInfoImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,7 @@ public class SharedCDRContactInfoImpl
messageMediator;
// NOTE: GROW.
OutputObject outputObject =
- new CDROutputObject(orb, messageMediator,
+ sun.corba.OutputStreamFactory.newCDROutputObject(orb, messageMediator,
corbaMessageMediator.getRequestHeader(),
corbaMessageMediator.getStreamFormatVersion(),
BufferManagerFactory.GROW);
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java
index 01d344b8c7f..e5fb14c754f 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -534,9 +534,9 @@ public class SocketOrChannelAcceptorImpl
{
CorbaMessageMediator corbaMessageMediator = (CorbaMessageMediator)
messageMediator;
- return new CDROutputObject((ORB) broker, corbaMessageMediator,
- corbaMessageMediator.getReplyHeader(),
- corbaMessageMediator.getStreamFormatVersion());
+ return sun.corba.OutputStreamFactory.newCDROutputObject((ORB) broker,
+ corbaMessageMediator, corbaMessageMediator.getReplyHeader(),
+ corbaMessageMediator.getStreamFormatVersion());
}
////////////////////////////////////////////////////
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
index 39fb4fecc14..fa87b568df4 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1587,8 +1587,8 @@ public class SocketOrChannelConnectionImpl
{
// REVISIT: See comments in CDROutputObject constructor.
CDROutputObject outputObject =
- new CDROutputObject((ORB)orb, null, giopVersion, this, msg,
- ORBConstants.STREAM_FORMAT_VERSION_1);
+ sun.corba.OutputStreamFactory.newCDROutputObject((ORB)orb, null, giopVersion,
+ this, msg, ORBConstants.STREAM_FORMAT_VERSION_1);
msg.write(outputObject);
outputObject.writeTo(this);
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/ior/TaggedComponentBase.java b/corba/src/share/classes/com/sun/corba/se/spi/ior/TaggedComponentBase.java
index 9e9a2a2f12a..74617235d70 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/ior/TaggedComponentBase.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/ior/TaggedComponentBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,8 @@ public abstract class TaggedComponentBase extends IdentifiableBase
public org.omg.IOP.TaggedComponent getIOPComponent(
org.omg.CORBA.ORB orb )
{
- EncapsOutputStream os = new EncapsOutputStream( (ORB)orb ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)orb);
write( os ) ;
InputStream is = (InputStream)(os.create_input_stream() ) ;
return org.omg.IOP.TaggedComponentHelper.read( is ) ;
diff --git a/corba/src/share/classes/com/sun/corba/se/spi/servicecontext/ServiceContext.java b/corba/src/share/classes/com/sun/corba/se/spi/servicecontext/ServiceContext.java
index db7a5db51b4..30994d385c3 100644
--- a/corba/src/share/classes/com/sun/corba/se/spi/servicecontext/ServiceContext.java
+++ b/corba/src/share/classes/com/sun/corba/se/spi/servicecontext/ServiceContext.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -92,7 +92,8 @@ public abstract class ServiceContext {
*/
public void write(OutputStream s, GIOPVersion gv) throws SystemException
{
- EncapsOutputStream os = new EncapsOutputStream( (ORB)(s.orb()), gv ) ;
+ EncapsOutputStream os =
+ sun.corba.OutputStreamFactory.newEncapsOutputStream((ORB)(s.orb()), gv);
os.putEndian() ;
writeData( os ) ;
byte[] data = os.toByteArray() ;
diff --git a/corba/src/share/classes/org/omg/CORBA_2_3/portable/OutputStream.java b/corba/src/share/classes/org/omg/CORBA_2_3/portable/OutputStream.java
index d29c8a04e52..b1222dfe99b 100644
--- a/corba/src/share/classes/org/omg/CORBA_2_3/portable/OutputStream.java
+++ b/corba/src/share/classes/org/omg/CORBA_2_3/portable/OutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,10 @@
package org.omg.CORBA_2_3.portable;
+import java.io.SerializablePermission;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
/**
* OutputStream provides interface for writing of all of the mapped IDL type
* to the stream. It extends org.omg.CORBA.portable.OutputStream, and defines
@@ -43,6 +47,40 @@ package org.omg.CORBA_2_3.portable;
public abstract class OutputStream extends org.omg.CORBA.portable.OutputStream {
+ private static final String ALLOW_SUBCLASS_PROP = "jdk.corba.allowOutputStreamSubclass";
+ private static final boolean allowSubclass = AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public Boolean run() {
+ String prop = System.getProperty(ALLOW_SUBCLASS_PROP);
+ return prop == null ? false :
+ (prop.equalsIgnoreCase("false") ? false : true);
+ }
+ });
+
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (!allowSubclass)
+ sm.checkPermission(new
+ SerializablePermission("enableSubclassImplementation"));
+ }
+ return null;
+ }
+ private OutputStream(Void ignore) { }
+
+ /**
+ * Create a new instance of this class.
+ *
+ * throw SecurityException if SecurityManager is installed and
+ * enableSubclassImplementation SerializablePermission
+ * is not granted or jdk.corba.allowOutputStreamSubclass system
+ * property is either not set or is set to 'false'
+ */
+ public OutputStream() {
+ this(checkPermission());
+ }
+
/**
* Marshals a value type to the output stream.
* @param value is the acutal value to write
diff --git a/corba/src/share/classes/sun/corba/OutputStreamFactory.java b/corba/src/share/classes/sun/corba/OutputStreamFactory.java
new file mode 100644
index 00000000000..d723e22c004
--- /dev/null
+++ b/corba/src/share/classes/sun/corba/OutputStreamFactory.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.corba;
+
+import com.sun.corba.se.impl.corba.AnyImpl;
+import com.sun.corba.se.impl.encoding.BufferManagerWrite;
+import com.sun.corba.se.impl.encoding.CDROutputObject;
+import com.sun.corba.se.impl.encoding.EncapsOutputStream;
+import com.sun.corba.se.impl.encoding.TypeCodeOutputStream;
+import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
+
+import com.sun.corba.se.pept.protocol.MessageMediator;
+
+import com.sun.corba.se.spi.orb.ORB;
+import com.sun.corba.se.spi.transport.CorbaConnection;
+import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
+import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public final class OutputStreamFactory {
+
+ private OutputStreamFactory() {
+ }
+
+ public static TypeCodeOutputStream newTypeCodeOutputStream(
+ final ORB orb) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public TypeCodeOutputStream run() {
+ return new TypeCodeOutputStream(orb);
+ }
+ });
+ }
+
+ public static TypeCodeOutputStream newTypeCodeOutputStream(
+ final ORB orb, final boolean littleEndian) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public TypeCodeOutputStream run() {
+ return new TypeCodeOutputStream(orb, littleEndian);
+ }
+ });
+ }
+
+ public static EncapsOutputStream newEncapsOutputStream(
+ final ORB orb) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public EncapsOutputStream run() {
+ return new EncapsOutputStream(
+ (com.sun.corba.se.spi.orb.ORB)orb);
+ }
+ });
+ }
+
+ public static EncapsOutputStream newEncapsOutputStream(
+ final ORB orb, final GIOPVersion giopVersion) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public EncapsOutputStream run() {
+ return new EncapsOutputStream(
+ (com.sun.corba.se.spi.orb.ORB)orb, giopVersion);
+ }
+ });
+ }
+
+ public static EncapsOutputStream newEncapsOutputStream(
+ final ORB orb, final boolean isLittleEndian) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public EncapsOutputStream run() {
+ return new EncapsOutputStream(
+ (com.sun.corba.se.spi.orb.ORB)orb, isLittleEndian);
+ }
+ });
+ }
+
+ public static CDROutputObject newCDROutputObject(
+ final ORB orb, final MessageMediator messageMediator,
+ final Message header, final byte streamFormatVersion) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public CDROutputObject run() {
+ return new CDROutputObject(orb, messageMediator,
+ header, streamFormatVersion);
+ }
+ });
+ }
+
+ public static CDROutputObject newCDROutputObject(
+ final ORB orb, final MessageMediator messageMediator,
+ final Message header, final byte streamFormatVersion,
+ final int strategy) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public CDROutputObject run() {
+ return new CDROutputObject(orb, messageMediator,
+ header, streamFormatVersion, strategy);
+ }
+ });
+ }
+
+ public static CDROutputObject newCDROutputObject(
+ final ORB orb, final CorbaMessageMediator mediator,
+ final GIOPVersion giopVersion, final CorbaConnection connection,
+ final Message header, final byte streamFormatVersion) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction() {
+ @Override
+ public CDROutputObject run() {
+ return new CDROutputObject(orb, mediator,
+ giopVersion, connection, header, streamFormatVersion);
+ }
+ });
+ }
+
+}
From 64831179a95c94f142b1adad7701d68232ba16d8 Mon Sep 17 00:00:00 2001
From: Bhavesh Patel
Date: Fri, 3 May 2013 08:52:33 -0700
Subject: [PATCH 006/136] 8012375: Improve Javadoc framing
Reviewed-by: mduigou, jlaskey
---
.../formats/html/markup/HtmlWriter.java | 35 +++++++++++++++-
.../testJavascript/TestJavascript.java | 41 +++++++++++++++++--
2 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
index f4d04bb69dd..afed62e6355 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
@@ -309,8 +309,41 @@ public class HtmlWriter {
String scriptCode = DocletConstants.NL + " targetPage = \"\" + window.location.search;" + DocletConstants.NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
" targetPage = targetPage.substring(1);" + DocletConstants.NL +
- " if (targetPage.indexOf(\":\") != -1)" + DocletConstants.NL +
+ " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
" targetPage = \"undefined\";" + DocletConstants.NL +
+ " function validURL(url) {" + DocletConstants.NL +
+ " if (!(url.indexOf(\".html\") == url.length - 5))" + DocletConstants.NL +
+ " return false;" + DocletConstants.NL +
+ " var allowNumber = false;" + DocletConstants.NL +
+ " var allowSep = false;" + DocletConstants.NL +
+ " var seenDot = false;" + DocletConstants.NL +
+ " for (var i = 0; i < url.length - 5; i++) {" + DocletConstants.NL +
+ " var ch = url.charAt(i);" + DocletConstants.NL +
+ " if ('a' <= ch && ch <= 'z' ||" + DocletConstants.NL +
+ " 'A' <= ch && ch <= 'Z' ||" + DocletConstants.NL +
+ " ch == '$' ||" + DocletConstants.NL +
+ " ch == '_') {" + DocletConstants.NL +
+ " allowNumber = true;" + DocletConstants.NL +
+ " allowSep = true;" + DocletConstants.NL +
+ " } else if ('0' <= ch && ch <= '9'" + DocletConstants.NL +
+ " || ch == '-') {" + DocletConstants.NL +
+ " if (!allowNumber)" + DocletConstants.NL +
+ " return false;" + DocletConstants.NL +
+ " } else if (ch == '/' || ch == '.') {" + DocletConstants.NL +
+ " if (!allowSep)" + DocletConstants.NL +
+ " return false;" + DocletConstants.NL +
+ " allowNumber = false;" + DocletConstants.NL +
+ " allowSep = false;" + DocletConstants.NL +
+ " if (ch == '.')" + DocletConstants.NL +
+ " seenDot = true;" + DocletConstants.NL +
+ " if (ch == '/' && seenDot)" + DocletConstants.NL +
+ " return false;" + DocletConstants.NL +
+ " } else {" + DocletConstants.NL +
+ " return false;"+ DocletConstants.NL +
+ " }" + DocletConstants.NL +
+ " }" + DocletConstants.NL +
+ " return true;" + DocletConstants.NL +
+ " }" + DocletConstants.NL +
" function loadFrames() {" + DocletConstants.NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + DocletConstants.NL +
" top.classFrame.location = top.targetPage;" + DocletConstants.NL +
diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
index b1293bf2919..816c9c15609 100644
--- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
+++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314
+ * @bug 4665566 4855876 7025314 8012375
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib/
@@ -35,7 +35,7 @@
public class TestJavascript extends JavadocTester {
//Test information.
- private static final String BUG_ID = "4665566-4855876";
+ private static final String BUG_ID = "4665566-4855876-8012375";
//Javadoc arguments.
private static final String[] ARGS = new String[] {
@@ -53,8 +53,41 @@ public class TestJavascript extends JavadocTester {
" targetPage = \"\" + window.location.search;" + NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + NL +
" targetPage = targetPage.substring(1);" + NL +
- " if (targetPage.indexOf(\":\") != -1)" + NL +
+ " if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + NL +
" targetPage = \"undefined\";" + NL +
+ " function validURL(url) {" + NL +
+ " if (!(url.indexOf(\".html\") == url.length - 5))" + NL +
+ " return false;" + NL +
+ " var allowNumber = false;" + NL +
+ " var allowSep = false;" + NL +
+ " var seenDot = false;" + NL +
+ " for (var i = 0; i < url.length - 5; i++) {" + NL +
+ " var ch = url.charAt(i);" + NL +
+ " if ('a' <= ch && ch <= 'z' ||" + NL +
+ " 'A' <= ch && ch <= 'Z' ||" + NL +
+ " ch == '$' ||" + NL +
+ " ch == '_') {" + NL +
+ " allowNumber = true;" + NL +
+ " allowSep = true;" + NL +
+ " } else if ('0' <= ch && ch <= '9'" + NL +
+ " || ch == '-') {" + NL +
+ " if (!allowNumber)" + NL +
+ " return false;" + NL +
+ " } else if (ch == '/' || ch == '.') {" + NL +
+ " if (!allowSep)" + NL +
+ " return false;" + NL +
+ " allowNumber = false;" + NL +
+ " allowSep = false;" + NL +
+ " if (ch == '.')" + NL +
+ " seenDot = true;" + NL +
+ " if (ch == '/' && seenDot)" + NL +
+ " return false;" + NL +
+ " } else {" + NL +
+ " return false;" + NL +
+ " }" + NL +
+ " }" + NL +
+ " return true;" + NL +
+ " }" + NL +
" function loadFrames() {" + NL +
" if (targetPage != \"\" && targetPage != \"undefined\")" + NL +
" top.classFrame.location = top.targetPage;" + NL +
From 8e6c2bb1b0cf1c6c44c47ead767593ee493eb38d Mon Sep 17 00:00:00 2001
From: Andrew Brygin
Date: Thu, 6 Jun 2013 13:57:25 +0400
Subject: [PATCH 007/136] 8013430: REGRESSION:
closed/java/awt/color/ICC_Profile/LoadProfileTest/LoadProfileTest.java fails
with java.io.StreamCorruptedException: invalid type code: EE since 8b87
Reviewed-by: prr, vadim
---
.../classes/java/awt/color/ICC_Profile.java | 3 +
.../sun/java2d/cmm/ProfileDataVerifier.java | 114 ++++++++++++++++++
2 files changed, 117 insertions(+)
create mode 100644 jdk/src/share/classes/sun/java2d/cmm/ProfileDataVerifier.java
diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
index b459f63b16d..c1534249f39 100644
--- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java
+++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java
@@ -37,6 +37,7 @@ package java.awt.color;
import sun.java2d.cmm.PCMM;
import sun.java2d.cmm.CMSManager;
+import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
import sun.java2d.cmm.ProfileActivator;
@@ -775,6 +776,8 @@ public class ICC_Profile implements Serializable {
ProfileDeferralMgr.activateProfiles();
}
+ ProfileDataVerifier.verify(data);
+
try {
theID = CMSManager.getModule().loadProfile(data);
} catch (CMMException c) {
diff --git a/jdk/src/share/classes/sun/java2d/cmm/ProfileDataVerifier.java b/jdk/src/share/classes/sun/java2d/cmm/ProfileDataVerifier.java
new file mode 100644
index 00000000000..e6100bbefd4
--- /dev/null
+++ b/jdk/src/share/classes/sun/java2d/cmm/ProfileDataVerifier.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.java2d.cmm;
+
+public class ProfileDataVerifier {
+ /**
+ * Throws an IllegalArgumentException if the data does not correspond
+ * to a valid ICC Profile.
+ *
+ * @param data the specified profile data.
+ */
+ public static void verify(byte[] data) {
+ if (data == null) {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ if (data.length < TOC_OFFSET) {
+ // not enough data for profile header
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ // check profile size
+ final int size = readInt32(data, 0);
+ final int tagCount = readInt32(data, HEADER_SIZE);
+
+ if (tagCount < 0 || tagCount > MAX_TAG_COUNT) {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ if (size < (TOC_OFFSET + (tagCount * TOC_RECORD_SIZE)) ||
+ size > data.length)
+ {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ final int sig = readInt32(data, 36);
+
+ if (PROFILE_FILE_SIGNATURE != sig) {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ // verify table of content
+ for (int i = 0; i < tagCount; i++) {
+ final int tag_offset = getTagOffset(i, data);
+ final int tag_size = getTagSize(i, data);
+
+ if (tag_offset < TOC_OFFSET || tag_offset > size) {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+
+ if (tag_size < 0 ||
+ tag_size > (Integer.MAX_VALUE - tag_offset) ||
+ tag_size + tag_offset > size)
+ {
+ throw new IllegalArgumentException("Invalid ICC Profile Data");
+ }
+ }
+ }
+
+ private static int getTagOffset(int idx, byte[] data) {
+ final int pos = TOC_OFFSET + idx * TOC_RECORD_SIZE + 4;
+ return readInt32(data, pos);
+ }
+
+ private static int getTagSize(int idx, byte[] data) {
+ final int pos = TOC_OFFSET + idx * TOC_RECORD_SIZE + 8;
+ return readInt32(data, pos);
+ }
+
+ private static int readInt32(byte[] data, int off) {
+ int res = 0;
+ for (int i = 0; i < 4; i++) {
+ res = res << 8;
+
+ res |= (0xff & data[off++]);
+ }
+ return res;
+ }
+
+ /**
+ * Lcms limit for the number of tags: 100
+ * Kcms limit for the number of tags: N/A
+ */
+ private static final int MAX_TAG_COUNT = 100;
+
+ private static final int HEADER_SIZE = 128;
+ private static final int TOC_OFFSET = HEADER_SIZE + 4;
+ private static final int TOC_RECORD_SIZE = 12;
+
+ private static final int PROFILE_FILE_SIGNATURE = 0x61637370;
+}
From c58691dc6fe1397146093948f5869f332b0cb77d Mon Sep 17 00:00:00 2001
From: Eric McCorkle
Date: Thu, 6 Jun 2013 08:48:23 -0400
Subject: [PATCH 008/136] 8015701: MethodParameters are not filled in for
synthetic captured local variables
Synthetic parameters for captured local variables in an anonymous inner class are not added to MethodParameters attributes
Reviewed-by: mcimadamore
---
.../com/sun/tools/javac/comp/Lower.java | 9 +-
.../javac/8015701/AnonymousParameters.java | 89 +++++++++++++++++++
2 files changed, 96 insertions(+), 2 deletions(-)
create mode 100644 langtools/test/tools/javac/8015701/AnonymousParameters.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index fb31aa3134f..4ee5e63fc28 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -2711,9 +2711,14 @@ public class Lower extends TreeTranslator {
if (fvs.nonEmpty()) {
List addedargtypes = List.nil();
for (List l = fvs; l.nonEmpty(); l = l.tail) {
- if (TreeInfo.isInitialConstructor(tree))
+ if (TreeInfo.isInitialConstructor(tree)) {
+ final Name pName = proxyName(l.head.name);
+ m.extraParams =
+ m.extraParams.append((VarSymbol)
+ (proxies.lookup(pName).sym));
added = added.prepend(
- initField(tree.body.pos, proxyName(l.head.name)));
+ initField(tree.body.pos, pName));
+ }
addedargtypes = addedargtypes.prepend(l.head.erasure(types));
}
Type olderasure = m.erasure(types);
diff --git a/langtools/test/tools/javac/8015701/AnonymousParameters.java b/langtools/test/tools/javac/8015701/AnonymousParameters.java
new file mode 100644
index 00000000000..746b2b9696a
--- /dev/null
+++ b/langtools/test/tools/javac/8015701/AnonymousParameters.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8015701
+ * @summary javac should generate method parameters correctly.
+ * @compile -parameters AnonymousParameters.java
+ * @run main AnonymousParameters
+ */
+import java.lang.Class;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Parameter;
+import java.util.concurrent.Callable;
+
+public class AnonymousParameters {
+
+ String[] names = {
+ "this$0",
+ "val$message"
+ };
+
+ public static void main(String... args) throws Exception {
+ new AnonymousParameters().run();
+ }
+
+ void run() throws Exception {
+ Class> cls = new ParameterNames().makeInner("hello").getClass();
+ Constructor> ctor = cls.getDeclaredConstructors()[0];
+ Parameter[] params = ctor.getParameters();
+
+ if(params.length == 2) {
+ for(int i = 0; i < 2; i++) {
+ System.err.println("Testing parameter " + params[i].getName());
+ if(!params[i].getName().equals(names[i]))
+ error("Expected parameter name " + names[i] +
+ " got " + params[i].getName());
+ }
+ } else
+ error("Expected 2 parameters");
+
+ if(0 != errors)
+ throw new Exception("MethodParameters test failed with " +
+ errors + " errors");
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
+
+class ParameterNames {
+
+ public Callable makeInner(final String message) {
+ return new Callable() {
+ public String call() throws Exception {
+ return message;
+ }
+ };
+ }
+
+ public static void main(String... args) throws Exception {
+ ParameterNames test = new ParameterNames();
+ System.out.println(test.makeInner("Hello").call());
+ }
+}
From a20d06c4c1b3939f109499a48599d82c0ed852f9 Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Thu, 6 Jun 2013 17:02:05 +0400
Subject: [PATCH 009/136] 8015976: OpenJDK part of bug JDK-8015812 [TEST_BUG]
Tests have conflicting test descriptions
Reviewed-by: serb, anthony
---
.../DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html | 6 ++----
.../DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java | 4 +---
.../KeyReleasedInAppletTest/KeyReleasedInAppletTest.java | 1 -
3 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
index 03f470d2dec..21396353d7c 100644
--- a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.html
@@ -1,6 +1,5 @@
+
Java 7 on mac os x only provides text clipboard formats
diff --git a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
index 765457e7ddd..598426f61f0 100644
--- a/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
+++ b/jdk/test/java/awt/DataFlavor/MissedHtmlAndRtfBug/MissedHtmlAndRtfBug.java
@@ -22,7 +22,6 @@
*/
/*
- @test
@bug 8005932
@summary Java 7 on mac os x only provides text clipboard formats
@author mikhail.cherkasov@oracle.com
@@ -30,10 +29,9 @@
@library ../../regtesthelpers/process
@build Util
@build ProcessResults ProcessCommunicator
-
-
@run applet/othervm MissedHtmlAndRtfBug.html
*/
+
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.*;
diff --git a/jdk/test/java/awt/event/KeyEvent/KeyReleasedInAppletTest/KeyReleasedInAppletTest.java b/jdk/test/java/awt/event/KeyEvent/KeyReleasedInAppletTest/KeyReleasedInAppletTest.java
index 71e8994e347..34bcbb531bf 100644
--- a/jdk/test/java/awt/event/KeyEvent/KeyReleasedInAppletTest/KeyReleasedInAppletTest.java
+++ b/jdk/test/java/awt/event/KeyEvent/KeyReleasedInAppletTest/KeyReleasedInAppletTest.java
@@ -39,7 +39,6 @@ import java.lang.Throwable;
import java.util.Hashtable;
/*
-@test
@bug 8010009
@summary [macosx] Unable type into online word games on MacOSX
@author petr.pchelko : area=awt.keyboard
From 1a56f32a4a387634374617b864bfa489fa0e1c8e Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Thu, 6 Jun 2013 17:06:22 +0400
Subject: [PATCH 010/136] 7109977: [macosx] MixingInHwPanel.java test fails on
Mac trying to click in the reserved corner
Reviewed-by: serb, anthony
---
jdk/test/java/awt/Mixing/MixingInHwPanel.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/jdk/test/java/awt/Mixing/MixingInHwPanel.java b/jdk/test/java/awt/Mixing/MixingInHwPanel.java
index 7aceebd0b38..27b2d96715e 100644
--- a/jdk/test/java/awt/Mixing/MixingInHwPanel.java
+++ b/jdk/test/java/awt/Mixing/MixingInHwPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/*
- @test %W% %E%
+ @test
@bug 6829858
@summary Mixing should work inside heavyweight containers
@author anthony.petrov@sun.com: area=awt.mixing
@@ -104,7 +104,7 @@ public class MixingInHwPanel
// And click the part of the button that has been previously hidden
Point bLoc = button.getLocationOnScreen();
- robot.mouseMove(bLoc.x + button.getWidth() - 6, bLoc.y + button.getHeight() / 2);
+ robot.mouseMove(bLoc.x + button.getWidth() - 15, bLoc.y + button.getHeight() / 2);
Util.waitForIdle(robot);
From 269ea64b67b3f2d130ef5d172c29709c21780cfa Mon Sep 17 00:00:00 2001
From: Dmitry Markov
Date: Thu, 6 Jun 2013 17:59:37 +0400
Subject: [PATCH 011/136] 8015853: java.lang.ArrayIndexOutOfBoundsException
when running SwingSet2 demo
Reviewed-by: alexp, serb
---
.../share/classes/javax/swing/text/View.java | 2 +-
.../swing/text/View/8015853/bug8015853.java | 82 +++++++++++++++++++
.../swing/text/View/8015853/bug8015853.txt | 67 +++++++++++++++
3 files changed, 150 insertions(+), 1 deletion(-)
create mode 100644 jdk/test/javax/swing/text/View/8015853/bug8015853.java
create mode 100644 jdk/test/javax/swing/text/View/8015853/bug8015853.txt
diff --git a/jdk/src/share/classes/javax/swing/text/View.java b/jdk/src/share/classes/javax/swing/text/View.java
index 097e6c33313..c2e1e023d5a 100644
--- a/jdk/src/share/classes/javax/swing/text/View.java
+++ b/jdk/src/share/classes/javax/swing/text/View.java
@@ -1174,7 +1174,7 @@ public abstract class View implements SwingConstants {
// formed by added elements (i.e. they will be updated
// by initialization.
index0 = Math.max(index0, 0);
- index1 = getViewIndex(elem.getDocument().getLength(), Position.Bias.Forward);
+ index1 = Math.max((getViewCount() - 1), 0);
for (int i = index0; i <= index1; i++) {
if (! ((i >= hole0) && (i <= hole1))) {
v = getView(i);
diff --git a/jdk/test/javax/swing/text/View/8015853/bug8015853.java b/jdk/test/javax/swing/text/View/8015853/bug8015853.java
new file mode 100644
index 00000000000..f63210683be
--- /dev/null
+++ b/jdk/test/javax/swing/text/View/8015853/bug8015853.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8015853
+ * @summary Tests the rendering of a large HTML document
+ * @author Dmitry Markov
+ * @run main bug8015853
+ */
+
+import java.io.*;
+import java.net.URL;
+import java.util.Scanner;
+import javax.swing.*;
+import javax.swing.text.html.HTMLEditorKit;
+
+public class bug8015853 {
+
+ private static String text = "";
+
+ public static void main(String[] args) throws Exception {
+
+ try {
+ URL path = ClassLoader.getSystemResource("bug8015853.txt");
+ File file = new File(path.toURI());
+ Scanner scanner = new Scanner(file);
+ while (scanner.hasNextLine()) {
+ text += scanner.nextLine() + "\n";
+ }
+ scanner.close();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ text += text;
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ }
+
+ private static void createAndShowGUI() {
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JEditorPane editorPane = new JEditorPane();
+ HTMLEditorKit editorKit = new HTMLEditorKit();
+ editorPane.setEditorKit(editorKit);
+ editorPane.setText(text);
+
+ frame.add(editorPane);
+ frame.setVisible(true);
+ }
+}
diff --git a/jdk/test/javax/swing/text/View/8015853/bug8015853.txt b/jdk/test/javax/swing/text/View/8015853/bug8015853.txt
new file mode 100644
index 00000000000..d9a6230684f
--- /dev/null
+++ b/jdk/test/javax/swing/text/View/8015853/bug8015853.txt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.*;
+import java.net.URL;
+import java.util.Scanner;
+import javax.swing.*;
+import javax.swing.text.html.HTMLEditorKit;
+public class bug8015853 {
+ private static String text = "" ;
+ public static void main(String[] args) throws Exception {
+
+ try {
+ URL path = ClassLoader.getSystemResource( "bug8015853.txt" );
+ File file = new File(path.toURI());
+ Scanner scanner = new Scanner(file);
+ while (scanner.hasNextLine()) {
+ text += scanner.nextLine() + "\n" ;
+ }
+ scanner.close();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+
+ System.out.println(text);
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ }
+ private static void createAndShowGUI() {
+ try {
+ UIManager.setLookAndFeel( "javax.swing.plaf.metal.MetalLookAndFeel" );
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ JFrame frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ JEditorPane editorPane = new JEditorPane();
+ HTMLEditorKit editorKit = new HTMLEditorKit();
+ editorPane.setEditorKit(editorKit);
+ editorPane.setText(text);
+ frame.add(editorPane);
+ frame.setVisible(true );
+ }
+}
\ No newline at end of file
From 884ad14bdfc9ade278f2c89eeaeceb3c618dfab9 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Thu, 6 Jun 2013 15:30:14 +0100
Subject: [PATCH 012/136] 6360970: javac erroneously accept ambiguous field
reference
Clash between ambiguous fields in superinterface and unambiguous field in subinterface is erroneously marked as unambiguous
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Resolve.java | 2 +-
.../test/tools/javac/6360970/T6360970.java | 25 +++++++++++++++++++
.../test/tools/javac/6360970/T6360970.out | 2 ++
3 files changed, 28 insertions(+), 1 deletion(-)
create mode 100644 langtools/test/tools/javac/6360970/T6360970.java
create mode 100644 langtools/test/tools/javac/6360970/T6360970.out
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 9618a00c3bb..21bdce9e16e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -1207,7 +1207,7 @@ public class Resolve {
bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
l = l.tail) {
sym = findField(env, site, name, l.head.tsym);
- if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
+ if (bestSoFar.exists() && sym.exists() &&
sym.owner != bestSoFar.owner)
bestSoFar = new AmbiguityError(bestSoFar, sym);
else if (sym.kind < bestSoFar.kind)
diff --git a/langtools/test/tools/javac/6360970/T6360970.java b/langtools/test/tools/javac/6360970/T6360970.java
new file mode 100644
index 00000000000..58936f41e21
--- /dev/null
+++ b/langtools/test/tools/javac/6360970/T6360970.java
@@ -0,0 +1,25 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 6360970
+ * @summary javac erroneously accept ambiguous field reference
+ * @compile/fail/ref=T6360970.out -XDrawDiagnostics T6360970.java
+ */
+class T6360970 {
+ interface A {
+ int i = 1;
+ }
+
+ interface B {
+ int i = 2;
+ }
+
+ interface C extends A, B { }
+
+ static class D {
+ public static final int i = 0;
+ }
+
+ static class E extends D implements C { }
+
+ int i = E.i; //ambiguous
+}
diff --git a/langtools/test/tools/javac/6360970/T6360970.out b/langtools/test/tools/javac/6360970/T6360970.out
new file mode 100644
index 00000000000..fa81e937c8a
--- /dev/null
+++ b/langtools/test/tools/javac/6360970/T6360970.out
@@ -0,0 +1,2 @@
+T6360970.java:24:14: compiler.err.ref.ambiguous: i, kindname.variable, i, T6360970.D, kindname.variable, i, T6360970.A
+1 error
From 4cb585609d4c14178ee160b6f9453ba45a6fb7dc Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Thu, 6 Jun 2013 15:32:41 +0100
Subject: [PATCH 013/136] 7139681: Enhanced for loop: local variable scope
inconsistent with JLS
For-each loop variable is incorrectly visible from the for-each expression
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Attr.java | 5 +-
.../javac/foreach/7139681/T7139681neg.java | 16 +++++++
.../javac/foreach/7139681/T7139681neg.out | 3 ++
.../javac/foreach/7139681/T7139681pos.java | 46 +++++++++++++++++++
4 files changed, 69 insertions(+), 1 deletion(-)
create mode 100644 langtools/test/tools/javac/foreach/7139681/T7139681neg.java
create mode 100644 langtools/test/tools/javac/foreach/7139681/T7139681neg.out
create mode 100644 langtools/test/tools/javac/foreach/7139681/T7139681pos.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 475ebcf7b04..0effef45451 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -1172,8 +1172,11 @@ public class Attr extends JCTree.Visitor {
Env loopEnv =
env.dup(env.tree, env.info.dup(env.info.scope.dup()));
try {
- attribStat(tree.var, loopEnv);
+ //the Formal Parameter of a for-each loop is not in the scope when
+ //attributing the for-each expression; we mimick this by attributing
+ //the for-each expression first (against original scope).
Type exprType = types.upperBound(attribExpr(tree.expr, loopEnv));
+ attribStat(tree.var, loopEnv);
chk.checkNonVoid(tree.pos(), exprType);
Type elemtype = types.elemtype(exprType); // perhaps expr is an array?
if (elemtype == null) {
diff --git a/langtools/test/tools/javac/foreach/7139681/T7139681neg.java b/langtools/test/tools/javac/foreach/7139681/T7139681neg.java
new file mode 100644
index 00000000000..e5b34a5f2d1
--- /dev/null
+++ b/langtools/test/tools/javac/foreach/7139681/T7139681neg.java
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7139681
+ * @summary Enhanced for loop: local variable scope inconsistent with JLS
+ *
+ * @compile/fail/ref=T7139681neg.out -XDrawDiagnostics T7139681neg.java
+ */
+class T7139681neg {
+ void testArray() {
+ for (int a : a) { }
+ }
+
+ void testIterable() {
+ for (Integer b : b) { }
+ }
+}
diff --git a/langtools/test/tools/javac/foreach/7139681/T7139681neg.out b/langtools/test/tools/javac/foreach/7139681/T7139681neg.out
new file mode 100644
index 00000000000..f900f9d2035
--- /dev/null
+++ b/langtools/test/tools/javac/foreach/7139681/T7139681neg.out
@@ -0,0 +1,3 @@
+T7139681neg.java:10:22: compiler.err.cant.resolve.location: kindname.variable, a, , , (compiler.misc.location: kindname.class, T7139681neg, null)
+T7139681neg.java:14:26: compiler.err.cant.resolve.location: kindname.variable, b, , , (compiler.misc.location: kindname.class, T7139681neg, null)
+2 errors
diff --git a/langtools/test/tools/javac/foreach/7139681/T7139681pos.java b/langtools/test/tools/javac/foreach/7139681/T7139681pos.java
new file mode 100644
index 00000000000..bca79e9ba80
--- /dev/null
+++ b/langtools/test/tools/javac/foreach/7139681/T7139681pos.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7139681
+ * @summary Enhanced for loop: local variable scope inconsistent with JLS
+ *
+ * @compile T7139681pos.java
+ */
+class T7139681pos {
+ int[] a;
+ Iterable b;
+
+ void testArray() {
+ for (int a : a) {
+ int a2 = a;
+ }
+ }
+
+ void testIterable() {
+ for (Integer b : b) {
+ Integer b2 = b;
+ }
+ }
+}
From 07baf8072a4a7d6e40353e4d2f9c3bb33b387be3 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Thu, 6 Jun 2013 15:33:40 +0100
Subject: [PATCH 014/136] 8008627: Compiler mishandles three-way
return-type-substitutability
Compiler should not enforce an order in how ambiguous methods should be resolved
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Check.java | 23 ++-------
.../javac/generics/rawOverride/T8008627.java | 47 +++++++++++++++++++
.../javac/lambda/funcInterfaces/NonSAM2.java | 2 +-
.../javac/lambda/funcInterfaces/NonSAM2.out | 3 +-
4 files changed, 54 insertions(+), 21 deletions(-)
create mode 100644 langtools/test/tools/javac/generics/rawOverride/T8008627.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index dad29a3a016..fcaea6a83c0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1924,24 +1924,11 @@ public class Check {
Symbol s3 = e.sym;
if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
Type st3 = types.memberType(site,s3);
- if (types.overrideEquivalent(st3, st1) && types.overrideEquivalent(st3, st2)) {
- if (s3.owner == site.tsym) {
- return true;
- }
- List tvars1 = st1.getTypeArguments();
- List tvars2 = st2.getTypeArguments();
- List tvars3 = st3.getTypeArguments();
- Type rt1 = st1.getReturnType();
- Type rt2 = st2.getReturnType();
- Type rt13 = types.subst(st3.getReturnType(), tvars3, tvars1);
- Type rt23 = types.subst(st3.getReturnType(), tvars3, tvars2);
- boolean compat =
- !rt13.isPrimitiveOrVoid() &&
- !rt23.isPrimitiveOrVoid() &&
- (types.covariantReturnType(rt13, rt1, types.noWarnings) &&
- types.covariantReturnType(rt23, rt2, types.noWarnings));
- if (compat)
- return true;
+ if (types.overrideEquivalent(st3, st1) &&
+ types.overrideEquivalent(st3, st2) &&
+ types.returnTypeSubstitutable(st3, st1) &&
+ types.returnTypeSubstitutable(st3, st2)) {
+ return true;
}
}
}
diff --git a/langtools/test/tools/javac/generics/rawOverride/T8008627.java b/langtools/test/tools/javac/generics/rawOverride/T8008627.java
new file mode 100644
index 00000000000..425cd63b92d
--- /dev/null
+++ b/langtools/test/tools/javac/generics/rawOverride/T8008627.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8008627
+ * @summary Compiler mishandles three-way return-type-substitutability
+ * @compile T8008627.java
+ */
+
+class T8008627 {
+
+ interface I {
+ Object m(Iterable l);
+ }
+
+ interface J {
+ S m(Iterable l);
+ }
+
+ interface K {
+ T m(Iterable l);
+ }
+
+ @FunctionalInterface
+ interface Functional extends I, J, K {}
+}
diff --git a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.java b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.java
index 7bbefb64607..2dd6b31800e 100644
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.java
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.java
@@ -13,7 +13,7 @@ interface Bar1 { Integer getAge(String s);}
interface Foo1Bar1 extends Foo1, Bar1 {} //types Bar1 and Foo1 are incompatible; both define getAge(String), but with unrelated return types
interface AC extends A, C {} //name clash: getOldest(List>) in C and getOldest(List) in A have the same erasure, yet neither overrides the other
-interface ABC extends A, B, C {} //name clash: getOldest(List>) in C and getOldest(List) in A have the same erasure, yet neither overrides the other
+interface ABC extends A, B, C {} //ok - raw override
interface AD extends A, D {} //name clash: getOldest(List) in D and getOldest(List) in A have the same erasure, yet neither overrides the other
interface Foo2 { void m(T arg);}
diff --git a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.out b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.out
index 00da6787e4e..b44b64cbeb9 100644
--- a/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.out
+++ b/langtools/test/tools/javac/lambda/funcInterfaces/NonSAM2.out
@@ -1,6 +1,5 @@
NonSAM2.java:13:1: compiler.err.types.incompatible.diff.ret: Bar1, Foo1, getAge(java.lang.String)
NonSAM2.java:15:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List>), C, getOldest(java.util.List), A
-NonSAM2.java:16:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List>), C, getOldest(java.util.List), A
NonSAM2.java:17:1: compiler.err.name.clash.same.erasure.no.override: getOldest(java.util.List), D, getOldest(java.util.List), A
NonSAM2.java:21:1: compiler.err.name.clash.same.erasure.no.override: m(S), Bar2, m(T), Foo2
-5 errors
+4 errors
From abaf1a5c51190d56d265f5162953f80fa0ddc514 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Thu, 6 Jun 2013 15:35:05 +0100
Subject: [PATCH 015/136] 8015432: javac crashes with stack overflow when
method called recursively from nested generic call
Check.checkMethod should only be called after inference has completed
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Attr.java | 25 +++++++--
.../com/sun/tools/javac/comp/Check.java | 55 ++++++-------------
.../test/tools/javac/6758789/T6758789b.out | 2 +-
.../tools/javac/generics/7015430/T7015430.out | 12 ++--
.../tools/javac/generics/7151802/T7151802.out | 4 +-
.../generics/inference/6718364/T6718364.out | 2 +-
.../generics/inference/7177306/T7177306a.out | 2 +-
.../test/tools/javac/lambda/TargetType74.java | 39 +++++++++++++
8 files changed, 89 insertions(+), 52 deletions(-)
create mode 100644 langtools/test/tools/javac/lambda/TargetType74.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 0effef45451..3b7b37cdf35 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -1833,9 +1833,6 @@ public class Attr extends JCTree.Visitor {
// Check that value of resulting type is admissible in the
// current context. Also, capture the return type
result = check(tree, capture(restype), VAL, resultInfo);
-
- if (localEnv.info.lastResolveVarargs())
- Assert.check(result.isErroneous() || tree.varargsElement != null);
}
chk.validate(tree.typeargs, localEnv);
}
@@ -3733,8 +3730,28 @@ public class Attr extends JCTree.Visitor {
typeargtypes,
noteWarner);
+ DeferredAttr.DeferredTypeMap checkDeferredMap =
+ deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
+
+ argtypes = Type.map(argtypes, checkDeferredMap);
+
+ if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
+ chk.warnUnchecked(env.tree.pos(),
+ "unchecked.meth.invocation.applied",
+ kindName(sym),
+ sym.name,
+ rs.methodArguments(sym.type.getParameterTypes()),
+ rs.methodArguments(Type.map(argtypes, checkDeferredMap)),
+ kindName(sym.location()),
+ sym.location());
+ owntype = new MethodType(owntype.getParameterTypes(),
+ types.erasure(owntype.getReturnType()),
+ types.erasure(owntype.getThrownTypes()),
+ syms.methodClass);
+ }
+
return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
- noteWarner.hasNonSilentLint(LintCategory.UNCHECKED), resultInfo.checkContext.inferenceContext());
+ resultInfo.checkContext.inferenceContext());
} catch (Infer.InferenceException ex) {
//invalid target type - propagate exception outwards or report error
//depending on the current check context
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index fcaea6a83c0..4854aa1cf0b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -847,25 +847,31 @@ public class Check {
(s.flags() & (STATIC | FINAL)) != 0);
}
- Type checkMethod(Type owntype,
- Symbol sym,
- Env env,
- final List argtrees,
- List argtypes,
- boolean useVarargs,
- boolean unchecked,
- InferenceContext inferenceContext) {
+ Type checkMethod(final Type mtype,
+ final Symbol sym,
+ final Env env,
+ final List argtrees,
+ final List argtypes,
+ final boolean useVarargs,
+ InferenceContext inferenceContext) {
// System.out.println("call : " + env.tree);
// System.out.println("method : " + owntype);
// System.out.println("actuals: " + argtypes);
+ if (inferenceContext.free(mtype)) {
+ inferenceContext.addFreeTypeListener(List.of(mtype), new FreeTypeListener() {
+ public void typesInferred(InferenceContext inferenceContext) {
+ checkMethod(inferenceContext.asInstType(mtype), sym, env, argtrees, argtypes, useVarargs, inferenceContext);
+ }
+ });
+ return mtype;
+ }
+ Type owntype = mtype;
List formals = owntype.getParameterTypes();
Type last = useVarargs ? formals.last() : null;
if (sym.name == names.init &&
sym.owner == syms.enumSym)
formals = formals.tail.tail;
List args = argtrees;
- DeferredAttr.DeferredTypeMap checkDeferredMap =
- deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
if (args != null) {
//this is null when type-checking a method reference
while (formals.head != last) {
@@ -886,27 +892,13 @@ public class Check {
} else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
// non-varargs call to varargs method
Type varParam = owntype.getParameterTypes().last();
- Type lastArg = checkDeferredMap.apply(argtypes.last());
+ Type lastArg = argtypes.last();
if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
!types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
log.warning(argtrees.last().pos(), "inexact.non-varargs.call",
types.elemtype(varParam), varParam);
}
}
- if (unchecked) {
- warnUnchecked(env.tree.pos(),
- "unchecked.meth.invocation.applied",
- kindName(sym),
- sym.name,
- rs.methodArguments(sym.type.getParameterTypes()),
- rs.methodArguments(Type.map(argtypes, checkDeferredMap)),
- kindName(sym.location()),
- sym.location());
- owntype = new MethodType(owntype.getParameterTypes(),
- types.erasure(owntype.getReturnType()),
- types.erasure(owntype.getThrownTypes()),
- syms.methodClass);
- }
if (useVarargs) {
Type argtype = owntype.getParameterTypes().last();
if (!types.isReifiable(argtype) &&
@@ -918,7 +910,7 @@ public class Check {
argtype);
}
if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
- setVarargsElement(env, types.elemtype(argtype), inferenceContext);
+ TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
}
}
PolyKind pkind = (sym.type.hasTag(FORALL) &&
@@ -928,17 +920,6 @@ public class Check {
return owntype;
}
//where
- private void setVarargsElement(final Env env, final Type elemtype, InferenceContext inferenceContext) {
- if (inferenceContext.free(elemtype)) {
- inferenceContext.addFreeTypeListener(List.of(elemtype), new FreeTypeListener() {
- public void typesInferred(InferenceContext inferenceContext) {
- setVarargsElement(env, inferenceContext.asInstType(elemtype), inferenceContext);
- }
- });
- }
- TreeInfo.setVarargsElement(env.tree, elemtype);
- }
-
private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
if (types.isConvertible(actual, formal, warn))
return;
diff --git a/langtools/test/tools/javac/6758789/T6758789b.out b/langtools/test/tools/javac/6758789/T6758789b.out
index 5393f9add90..5bdb51c22cd 100644
--- a/langtools/test/tools/javac/6758789/T6758789b.out
+++ b/langtools/test/tools/javac/6758789/T6758789b.out
@@ -1,5 +1,5 @@
-T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo
T6758789b.java:16:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6758789a.Foo, T6758789a.Foo, kindname.class, T6758789a
+T6758789b.java:16:11: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6758789a.Foo, T6758789a.Foo
- compiler.err.warnings.and.werror
1 error
2 warnings
diff --git a/langtools/test/tools/javac/generics/7015430/T7015430.out b/langtools/test/tools/javac/generics/7015430/T7015430.out
index 109bfe7da7f..6e33877e05e 100644
--- a/langtools/test/tools/javac/generics/7015430/T7015430.out
+++ b/langtools/test/tools/javac/generics/7015430/T7015430.out
@@ -1,15 +1,15 @@
-T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:41:14: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:41:15: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:50:41: compiler.warn.unchecked.meth.invocation.applied: kindname.method, empty, java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:50:42: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:68:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:68:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:77:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:77:40: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:104:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
-T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
+T7015430.java:104:41: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:113:9: compiler.warn.unchecked.meth.invocation.applied: kindname.constructor, , java.lang.Iterable, java.lang.Iterable, kindname.class, T7015430
+T7015430.java:113:22: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.lang.Iterable, java.lang.Iterable
T7015430.java:41:14: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
T7015430.java:68:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
T7015430.java:95:15: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception
diff --git a/langtools/test/tools/javac/generics/7151802/T7151802.out b/langtools/test/tools/javac/generics/7151802/T7151802.out
index 94f82828b91..dd708d6e91f 100644
--- a/langtools/test/tools/javac/generics/7151802/T7151802.out
+++ b/langtools/test/tools/javac/generics/7151802/T7151802.out
@@ -1,9 +1,9 @@
T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802
-T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo
T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo, T7151802.Foo, kindname.class, T7151802
+T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo
T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802
-T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo
T7151802.java:38:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get7, T7151802.Foo, T7151802.Foo, kindname.class, T7151802
+T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo
- compiler.err.warnings.and.werror
1 error
6 warnings
diff --git a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
index d637c1fbbeb..a7a70c6b9d9 100644
--- a/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
+++ b/langtools/test/tools/javac/generics/inference/6718364/T6718364.out
@@ -1,3 +1,3 @@
-T6718364.java:13:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6718364.X, T6718364.X
T6718364.java:13:10: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, T6718364.X,T, T6718364.X>,T6718364.X, kindname.class, T6718364
+T6718364.java:13:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T6718364.X, T6718364.X
2 warnings
diff --git a/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out b/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
index c455d2463ca..4a21e562164 100644
--- a/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
+++ b/langtools/test/tools/javac/generics/inference/7177306/T7177306a.out
@@ -1,5 +1,5 @@
-T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List
T7177306a.java:13:33: compiler.warn.unchecked.meth.invocation.applied: kindname.method, m, java.util.List, java.util.List, kindname.class, T7177306a
+T7177306a.java:13:34: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List
T7177306a.java:13:33: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7177306a, T7177306a
- compiler.err.warnings.and.werror
1 error
diff --git a/langtools/test/tools/javac/lambda/TargetType74.java b/langtools/test/tools/javac/lambda/TargetType74.java
new file mode 100644
index 00000000000..ffd8dbf888c
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType74.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8015432
+ * @summary javac crashes with stack overflow when method called recursively from nested generic call
+ * @compile TargetType74.java
+ */
+class TargetType74 {
+
+ static class LazySeq { }
+
+ LazySeq cons(LazySeq tailFun) { return null; }
+
+ > LazySeq mergeSorted(LazySeq a) {
+ return cons(mergeSorted(a));
+ }
+}
From 459b2cba93dfc680c4031f792b9612c8b5aef7aa Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Thu, 6 Jun 2013 15:37:23 +0100
Subject: [PATCH 016/136] 8015648: Duplicate variable in lambda causes javac
crash
Missing flag in synthetic lambda blog is causing duplicates symbol to go undetected
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Attr.java | 2 +-
.../tools/javac/lambda/LambdaScope05.java | 31 +++++++++++++++++++
.../test/tools/javac/lambda/LambdaScope05.out | 7 +++++
3 files changed, 39 insertions(+), 1 deletion(-)
create mode 100644 langtools/test/tools/javac/lambda/LambdaScope05.java
create mode 100644 langtools/test/tools/javac/lambda/LambdaScope05.out
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index 3b7b37cdf35..74974c4e7b0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -2609,7 +2609,7 @@ public class Attr extends JCTree.Visitor {
//field initializer
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared()));
lambdaEnv.info.scope.owner =
- new MethodSymbol(0, names.empty, null,
+ new MethodSymbol((owner.flags() & STATIC) | BLOCK, names.empty, null,
env.info.scope.owner);
} else {
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
diff --git a/langtools/test/tools/javac/lambda/LambdaScope05.java b/langtools/test/tools/javac/lambda/LambdaScope05.java
new file mode 100644
index 00000000000..0fbb4a20576
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/LambdaScope05.java
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8015648
+ * @summary Duplicate variable in lambda causes javac crash
+ * @compile/fail/ref=LambdaScope05.out -XDrawDiagnostics LambdaScope05.java
+ */
+
+class LambdaScope05 {
+ interface VoidFun1 {
+ void m(int i);
+ }
+
+ static Runnable r1 = () -> { VoidFun1 p = p -> { }; };
+ Runnable r2 = () -> { VoidFun1 p = p -> { }; };
+
+ static {
+ Runnable r = () -> { VoidFun1 p = p -> { }; };
+ }
+
+ {
+ Runnable r = () -> { VoidFun1 p = p -> { }; };
+ }
+
+ static void m_static() {
+ Runnable r = () -> { VoidFun1 p = p -> { }; };
+ }
+
+ void m() {
+ Runnable r = () -> { VoidFun1 p = p -> { }; };
+ }
+}
diff --git a/langtools/test/tools/javac/lambda/LambdaScope05.out b/langtools/test/tools/javac/lambda/LambdaScope05.out
new file mode 100644
index 00000000000..722e29d9be9
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/LambdaScope05.out
@@ -0,0 +1,7 @@
+LambdaScope05.java:13:47: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
+LambdaScope05.java:14:40: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.instance.init, kindname.class, LambdaScope05
+LambdaScope05.java:17:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
+LambdaScope05.java:21:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.instance.init, kindname.class, LambdaScope05
+LambdaScope05.java:25:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m_static()
+LambdaScope05.java:29:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m()
+6 errors
From 769aac6d4a00b5678a0afe5ec151545d8e4a9b4b Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Thu, 6 Jun 2013 21:41:20 +0530
Subject: [PATCH 017/136] 8015346: JSON parsing issues with escaped strings,
octal, decimal numbers
Reviewed-by: hannesw, jlaskey
---
.../internal/ir/BlockLexicalContext.java | 1 +
.../nashorn/internal/parser/JSONParser.java | 99 ++++++++++++++++++-
.../jdk/nashorn/internal/parser/Lexer.java | 21 +++-
.../internal/runtime/JSONFunctions.java | 6 +-
.../runtime/resources/Messages.properties | 2 +
nashorn/test/script/basic/JDK-8015346.js | 53 ++++++++++
6 files changed, 170 insertions(+), 12 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8015346.js
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
index a86a327ea6c..71c80a6b04f 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
@@ -63,6 +63,7 @@ public class BlockLexicalContext extends LexicalContext {
return sstack.pop();
}
+ @SuppressWarnings("unchecked")
@Override
public T pop(final T node) {
T expected = node;
diff --git a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
index aa9234efaed..fe041f3398b 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/JSONParser.java
@@ -54,10 +54,9 @@ public class JSONParser extends AbstractParser {
* Constructor
* @param source the source
* @param errors the error manager
- * @param strict are we in strict mode
*/
- public JSONParser(final Source source, final ErrorManager errors, final boolean strict) {
- super(source, errors, strict);
+ public JSONParser(final Source source, final ErrorManager errors) {
+ super(source, errors, false);
}
/**
@@ -135,6 +134,7 @@ public class JSONParser extends AbstractParser {
return ch == '\"';
}
+ // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONWhiteSpace
@Override
protected boolean isWhitespace(final char ch) {
return Lexer.isJsonWhitespace(ch);
@@ -144,6 +144,99 @@ public class JSONParser extends AbstractParser {
protected boolean isEOL(final char ch) {
return Lexer.isJsonEOL(ch);
}
+
+ // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONNumber
+ @Override
+ protected void scanNumber() {
+ // Record beginning of number.
+ final int start = position;
+ // Assume value is a decimal.
+ TokenType type = TokenType.DECIMAL;
+
+ // floating point can't start with a "." with no leading digit before
+ if (ch0 == '.') {
+ error(Lexer.message("json.invalid.number"), STRING, position, limit);
+ }
+
+ // First digit of number.
+ int digit = convertDigit(ch0, 10);
+
+ // skip first digit
+ skip(1);
+
+ if (digit != 0) {
+ // Skip over remaining digits.
+ while (convertDigit(ch0, 10) != -1) {
+ skip(1);
+ }
+ }
+
+ if (ch0 == '.' || ch0 == 'E' || ch0 == 'e') {
+ // Must be a double.
+ if (ch0 == '.') {
+ // Skip period.
+ skip(1);
+
+ boolean mantissa = false;
+ // Skip mantissa.
+ while (convertDigit(ch0, 10) != -1) {
+ mantissa = true;
+ skip(1);
+ }
+
+ if (! mantissa) {
+ // no digit after "."
+ error(Lexer.message("json.invalid.number"), STRING, position, limit);
+ }
+ }
+
+ // Detect exponent.
+ if (ch0 == 'E' || ch0 == 'e') {
+ // Skip E.
+ skip(1);
+ // Detect and skip exponent sign.
+ if (ch0 == '+' || ch0 == '-') {
+ skip(1);
+ }
+ boolean exponent = false;
+ // Skip exponent.
+ while (convertDigit(ch0, 10) != -1) {
+ exponent = true;
+ skip(1);
+ }
+
+ if (! exponent) {
+ // no digit after "E"
+ error(Lexer.message("json.invalid.number"), STRING, position, limit);
+ }
+ }
+
+ type = TokenType.FLOATING;
+ }
+
+ // Add number token.
+ add(type, start);
+ }
+
+ // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONEscapeCharacter
+ @Override
+ protected boolean isEscapeCharacter(final char ch) {
+ switch (ch) {
+ case '"':
+ case '/':
+ case '\\':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ // could be unicode escape
+ case 'u':
+ return true;
+ default:
+ return false;
+ }
+ }
};
k = -1;
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
index d9ebb365e11..cd50a22d914 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/Lexer.java
@@ -648,7 +648,7 @@ public class Lexer extends Scanner {
*
* @return The converted digit or -1 if invalid.
*/
- private static int convertDigit(final char ch, final int base) {
+ protected static int convertDigit(final char ch, final int base) {
int digit;
if ('0' <= ch && ch <= '9') {
@@ -908,7 +908,7 @@ public class Lexer extends Scanner {
/**
* Scan over a string literal.
*/
- private void scanString(final boolean add) {
+ protected void scanString(final boolean add) {
// Type of string.
TokenType type = STRING;
// Record starting quote.
@@ -925,6 +925,9 @@ public class Lexer extends Scanner {
if (ch0 == '\\') {
type = ESCSTRING;
skip(1);
+ if (! isEscapeCharacter(ch0)) {
+ error(Lexer.message("invalid.escape.char"), STRING, position, limit);
+ }
if (isEOL(ch0)) {
// Multiline string literal
skipEOL(false);
@@ -978,6 +981,16 @@ public class Lexer extends Scanner {
}
}
+ /**
+ * Is the given character a valid escape char after "\" ?
+ *
+ * @param ch character to be checked
+ * @return if the given character is valid after "\"
+ */
+ protected boolean isEscapeCharacter(final char ch) {
+ return true;
+ }
+
/**
* Convert string to number.
*
@@ -1024,7 +1037,7 @@ public class Lexer extends Scanner {
/**
* Scan a number.
*/
- private void scanNumber() {
+ protected void scanNumber() {
// Record beginning of number.
final int start = position;
// Assume value is a decimal.
@@ -1583,7 +1596,7 @@ public class Lexer extends Scanner {
return null;
}
- private static String message(final String msgId, final String... args) {
+ protected static String message(final String msgId, final String... args) {
return ECMAErrors.getMessage("lexer.error." + msgId, args);
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
index c296a87accc..33e6ef030ea 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -66,13 +66,9 @@ public final class JSONFunctions {
*/
public static Object parse(final Object text, final Object reviver) {
final String str = JSType.toString(text);
- final Context context = Context.getContextTrusted();
final JSONParser parser = new JSONParser(
new Source("", str),
- new Context.ThrowErrorManager(),
- (context != null) ?
- context.getEnv()._strict :
- false);
+ new Context.ThrowErrorManager());
Node node;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index b8d9e5e3c82..9dc0ffcfe3f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -28,6 +28,8 @@ lexer.error.missing.close.quote=Missing close quote
lexer.error.invalid.hex=Invalid hex digit
lexer.error.invalid.octal=Invalid octal digit
lexer.error.strict.no.octal=cannot use octal escapes in strict mode
+lexer.error.json.invalid.number=Invalid JSON number format
+lexer.error.invalid.escape.char=Invalid escape character
lexer.error.illegal.identifier.character=Illegal character in identifier
parser.error.illegal.continue.stmt=Illegal continue statement
diff --git a/nashorn/test/script/basic/JDK-8015346.js b/nashorn/test/script/basic/JDK-8015346.js
new file mode 100644
index 00000000000..2365cc82c67
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015346.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015346: JSON parsing issues with escaped strings, octal, decimal numbers *
+ * @test
+ * @run
+ */
+
+function checkJSON(str) {
+ try {
+ JSON.parse(str);
+ fail("should have thrown SyntaxError for JSON.parse on " + str);
+ } catch (e) {
+ if (! (e instanceof SyntaxError)) {
+ fail("Expected SyntaxError, but got " + e);
+ }
+ }
+}
+
+// invalid escape in a string
+checkJSON('"\\a"')
+
+// invalid floating point number patterns
+checkJSON("1.")
+checkJSON(".8")
+checkJSON("2.3e+")
+checkJSON("0.3E+")
+
+// octal, hexadecimal not allowed
+checkJSON("08")
+checkJSON("06")
+checkJSON('0x3')
From 53ae44836c65349748c0e80589b695eddca5ddb5 Mon Sep 17 00:00:00 2001
From: Aleksej Efimov
Date: Thu, 6 Jun 2013 20:40:43 +0400
Subject: [PATCH 018/136] 8009579: Xpathexception does not honor initcause()
Reviewed-by: alanb, dholmes, joehw
---
jaxp/src/javax/xml/xpath/XPathException.java | 55 ++++++++++++++++++--
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/jaxp/src/javax/xml/xpath/XPathException.java b/jaxp/src/javax/xml/xpath/XPathException.java
index aca84e57867..6ec9d09c4b1 100644
--- a/jaxp/src/javax/xml/xpath/XPathException.java
+++ b/jaxp/src/javax/xml/xpath/XPathException.java
@@ -26,6 +26,11 @@
package javax.xml.xpath;
import java.io.PrintWriter;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.io.InvalidClassException;
/**
* XPathException
represents a generic XPath exception.
@@ -36,7 +41,9 @@ import java.io.PrintWriter;
*/
public class XPathException extends Exception {
- private final Throwable cause;
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField( "cause", Throwable.class )
+ };
/**
* Stream Unique Identifier.
@@ -62,7 +69,6 @@ public class XPathException extends Exception {
if ( message == null ) {
throw new NullPointerException ( "message can't be null");
}
- this.cause = null;
}
/**
@@ -77,8 +83,7 @@ public class XPathException extends Exception {
* @throws NullPointerException if cause
is null
.
*/
public XPathException(Throwable cause) {
- super();
- this.cause = cause;
+ super(cause);
if ( cause == null ) {
throw new NullPointerException ( "cause can't be null");
}
@@ -90,7 +95,47 @@ public class XPathException extends Exception {
* @return Cause of this XPathException.
*/
public Throwable getCause() {
- return cause;
+ return super.getCause();
+ }
+
+ /**
+ * Writes "cause" field to the stream.
+ * The cause is got from the parent class.
+ *
+ * @param out stream used for serialization.
+ * @throws IOException thrown by ObjectOutputStream
+ *
+ */
+ private void writeObject(ObjectOutputStream out)
+ throws IOException
+ {
+ ObjectOutputStream.PutField fields = out.putFields();
+ fields.put("cause", (Throwable) super.getCause());
+ out.writeFields();
+ }
+
+ /**
+ * Reads the "cause" field from the stream.
+ * And initializes the "cause" if it wasn't
+ * done before.
+ *
+ * @param in stream used for deserialization
+ * @throws IOException thrown by ObjectInputStream
+ * @throws ClassNotFoundException thrown by ObjectInputStream
+ */
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException
+ {
+ ObjectInputStream.GetField fields = in.readFields();
+ Throwable scause = (Throwable) fields.get("cause", null);
+
+ if (super.getCause() == null && scause != null) {
+ try {
+ super.initCause(scause);
+ } catch(IllegalStateException e) {
+ throw new InvalidClassException("Inconsistent state: two causes");
+ }
+ }
}
/**
From 45c882ac0a6c82c73b6390ab322a3225d38e47ff Mon Sep 17 00:00:00 2001
From: Daniel Fuchs
Date: Thu, 6 Jun 2013 20:47:13 +0200
Subject: [PATCH 019/136] 8013434: Xalan and Xerces internal ObjectFactory need
rework
With this changeset, DTMManager and XSLTCDTMManager will always use their own default implementation.
Reviewed-by: joehw, alanb
---
.../javax.xml.transform.TransformerFactory | 1 -
.../services/javax.xml.xpath.XPathFactory | 1 -
.../services/org.apache.xml.dtm.DTMManager | 1 -
.../xalan/internal/utils/ObjectFactory.java | 439 +-----------------
.../internal/xsltc/cmdline/Transform.java | 31 +-
.../internal/xsltc/dom/DocumentCache.java | 4 +-
.../internal/xsltc/dom/XSLTCDTMManager.java | 51 +-
.../xsltc/trax/TransformerFactoryImpl.java | 85 ++--
.../xsltc/trax/TransformerHandlerImpl.java | 34 +-
.../internal/xsltc/trax/TransformerImpl.java | 37 +-
.../xerces/internal/utils/ObjectFactory.java | 205 +-------
.../apache/xml/internal/dtm/DTMManager.java | 67 +--
.../apache/xpath/internal/XPathContext.java | 64 +--
13 files changed, 153 insertions(+), 867 deletions(-)
delete mode 100644 jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.transform.TransformerFactory
delete mode 100644 jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.xpath.XPathFactory
delete mode 100644 jaxp/src/com/sun/org/apache/xalan/META-INF/services/org.apache.xml.dtm.DTMManager
diff --git a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.transform.TransformerFactory b/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.transform.TransformerFactory
deleted file mode 100644
index a607891fefd..00000000000
--- a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.transform.TransformerFactory
+++ /dev/null
@@ -1 +0,0 @@
-com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
diff --git a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.xpath.XPathFactory b/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.xpath.XPathFactory
deleted file mode 100644
index ff1d5560075..00000000000
--- a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/javax.xml.xpath.XPathFactory
+++ /dev/null
@@ -1 +0,0 @@
-com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl
\ No newline at end of file
diff --git a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/org.apache.xml.dtm.DTMManager b/jaxp/src/com/sun/org/apache/xalan/META-INF/services/org.apache.xml.dtm.DTMManager
deleted file mode 100644
index 6edf8469ef7..00000000000
--- a/jaxp/src/com/sun/org/apache/xalan/META-INF/services/org.apache.xml.dtm.DTMManager
+++ /dev/null
@@ -1 +0,0 @@
-com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java
index ff9b1a6e6a5..034d8eec84b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java
@@ -23,26 +23,11 @@
package com.sun.org.apache.xalan.internal.utils;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-
-import java.util.Properties;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
* API.
*
- * This code is designed to implement the JAXP 1.1 spec pluggability
- * feature and is designed to run on JDK version 1.1 and
- * later, and to compile on JDK 1.2 and onward.
- * The code also runs both as part of an unbundled jar file and
- * when bundled as part of the JDK.
- *
* This class was moved from the javax.xml.parsers.ObjectFactory
* class and modified to be used as a general utility for creating objects
* dynamically.
@@ -57,329 +42,9 @@ public class ObjectFactory {
private static final String XALAN_INTERNAL = "com.sun.org.apache.xalan.internal";
private static final String XERCES_INTERNAL = "com.sun.org.apache.xerces.internal";
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME =
- "xalan.properties";
-
- private static final String SERVICES_PATH = "META-INF/services/";
-
/** Set to true for debugging */
private static final boolean DEBUG = false;
- /** cache the contents of the xalan.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXalanProperties = null;
-
- /***
- * Cache the time stamp of the xalan.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // Public static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return instance of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- public static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read $java.home/lib/propertiesFilename
file
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return instance of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xalan.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- Class factoryClass = lookUpFactoryClass(factoryId,
- propertiesFilename,
- fallbackClassName);
-
- if (factoryClass == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- try{
- Object instance = factoryClass.newInstance();
- if (DEBUG) debugPrintln("created new instance of factory " + factoryId);
- return instance;
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider for factory " + factoryId
- + " could not be instantiated: " + x, x);
- }
- } // createObject(String,String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read $java.home/lib/propertiesFilename
file
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xalan.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- public static Class lookUpFactoryClass(String factoryId)
- throws ConfigurationError
- {
- return lookUpFactoryClass(factoryId, null, null);
- } // lookUpFactoryClass(String):Class
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read $java.home/lib/propertiesFilename
file
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return Class object that provides factory service, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xalan.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- public static Class lookUpFactoryClass(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- String factoryClassName = lookUpFactoryClassName(factoryId,
- propertiesFilename,
- fallbackClassName);
- ClassLoader cl = findClassLoader();
-
- if (factoryClassName == null) {
- factoryClassName = fallbackClassName;
- }
-
- // assert(className != null);
- try{
- Class providerClass = findProviderClass(factoryClassName,
- cl,
- true);
- if (DEBUG) debugPrintln("created new instance of " + providerClass +
- " using ClassLoader: " + cl);
- return providerClass;
- } catch (ClassNotFoundException x) {
- throw new ConfigurationError(
- "Provider " + factoryClassName + " not found", x);
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider "+factoryClassName+" could not be instantiated: "+x,
- x);
- }
- } // lookUpFactoryClass(String,String,String):Class
-
- /**
- * Finds the name of the required implementation class in the specified
- * order. The specified order is the following:
- *
- * query the system property using System.getProperty
- * read $java.home/lib/propertiesFilename
file
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return name of class that provides factory service, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xalan.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static String lookUpFactoryClassName(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- {
- // Use the system property first
- try {
- String systemProp = SecuritySupport.getSystemProperty(factoryId);
- if (systemProp != null) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return systemProp;
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // Try to read from propertiesFilename, or
- // $java.home/lib/xalan.properties
- String factoryClassName = null;
- // no properties file name specified; use
- // $JAVA_HOME/lib/xalan.properties:
- if (propertiesFilename == null) {
- File propertiesFile = null;
- boolean propertiesFileExists = false;
- try {
- String javah = SecuritySupport.getSystemProperty("java.home");
- propertiesFilename = javah + File.separator +
- "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
- propertiesFile = new File(propertiesFilename);
- propertiesFileExists = SecuritySupport.getFileExists(propertiesFile);
- } catch (SecurityException e) {
- // try again...
- fLastModified = -1;
- fXalanProperties = null;
- }
-
- synchronized (ObjectFactory.class) {
- boolean loadProperties = false;
- FileInputStream fis = null;
- try {
- // file existed last time
- if(fLastModified >= 0) {
- if(propertiesFileExists &&
- (fLastModified < (fLastModified = SecuritySupport.getLastModified(propertiesFile)))) {
- loadProperties = true;
- } else {
- // file has stopped existing...
- if(!propertiesFileExists) {
- fLastModified = -1;
- fXalanProperties = null;
- } // else, file wasn't modified!
- }
- } else {
- // file has started to exist:
- if(propertiesFileExists) {
- loadProperties = true;
- fLastModified = SecuritySupport.getLastModified(propertiesFile);
- } // else, nothing's changed
- }
- if(loadProperties) {
- // must never have attempted to read xalan.properties
- // before (or it's outdeated)
- fXalanProperties = new Properties();
- fis = SecuritySupport.getFileInputStream(propertiesFile);
- fXalanProperties.load(fis);
- }
- } catch (Exception x) {
- fXalanProperties = null;
- fLastModified = -1;
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if(fXalanProperties != null) {
- factoryClassName = fXalanProperties.getProperty(factoryId);
- }
- } else {
- FileInputStream fis = null;
- try {
- fis = SecuritySupport.getFileInputStream(new File(propertiesFilename));
- Properties props = new Properties();
- props.load(fis);
- factoryClassName = props.getProperty(factoryId);
- } catch (Exception x) {
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if (factoryClassName != null) {
- if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value="
- + factoryClassName);
- return factoryClassName;
- }
-
- // Try Jar Service Provider Mechanism
- return findJarServiceProviderName(factoryId);
- } // lookUpFactoryClass(String,String):String
-
- //
- // Private static methods
- //
/** Prints a message to standard error if debugging is enabled. */
private static void debugPrintln(String msg) {
@@ -393,7 +58,6 @@ public class ObjectFactory {
* the context ClassLoader.
*/
public static ClassLoader findClassLoader()
- throws ConfigurationError
{
if (System.getSecurityManager()!=null) {
//this will ensure bootclassloader is used
@@ -452,8 +116,8 @@ public class ObjectFactory {
} // findClassLoader():ClassLoader
/**
- * Create an instance of a class using the same classloader for the ObjectFactory by default
- * or bootclassloader when Security Manager is in place
+ * Create an instance of a class using the same class loader for the ObjectFactory by default
+ * or boot class loader when Security Manager is in place
*/
public static Object newInstance(String className, boolean doFallback)
throws ConfigurationError
@@ -491,10 +155,10 @@ public class ObjectFactory {
}
/**
- * Find a Class using the same classloader for the ObjectFactory by default
- * or bootclassloader when Security Manager is in place
+ * Find a Class using the same class loader for the ObjectFactory by default
+ * or boot class loader when Security Manager is in place
*/
- public static Class findProviderClass(String className, boolean doFallback)
+ public static Class> findProviderClass(String className, boolean doFallback)
throws ClassNotFoundException, ConfigurationError
{
if (System.getSecurityManager()!=null) {
@@ -508,7 +172,7 @@ public class ObjectFactory {
/**
* Find a Class using the specified ClassLoader
*/
- static Class findProviderClass(String className, ClassLoader cl,
+ private static Class> findProviderClass(String className, ClassLoader cl,
boolean doFallback)
throws ClassNotFoundException, ConfigurationError
{
@@ -531,7 +195,7 @@ public class ObjectFactory {
throw e;
}
- Class providerClass;
+ Class> providerClass;
if (cl == null) {
// XXX Use the bootstrap ClassLoader. There is no way to
// load a class using the bootstrap ClassLoader that works
@@ -567,93 +231,4 @@ public class ObjectFactory {
return providerClass;
}
- /**
- * Find the name of service provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static String findJarServiceProviderName(String factoryId)
- {
- String serviceId = SERVICES_PATH + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = SecuritySupport.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = SecuritySupport.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is));
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return factoryClassName;
- }
-
- // No provider found
- return null;
- }
-
} // class ObjectFactory
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java
index e2df8e31c36..a81cd779594 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java
@@ -23,34 +23,30 @@
package com.sun.org.apache.xalan.internal.xsltc.cmdline;
-import java.io.FileNotFoundException;
-import java.net.MalformedURLException;
-import java.net.UnknownHostException;
-import java.util.Vector;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import javax.xml.transform.sax.SAXSource;
-
+import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
+import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
-import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
+import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter;
import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Constants;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Parameter;
import com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory;
+import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
-
+import java.io.FileNotFoundException;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.util.Vector;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
-import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
-import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
-import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
-
/**
* @author Jacek Ambroziak
* @author Santiago Pericas-Geertsen
@@ -115,8 +111,7 @@ final public class Transform {
// Set the DOM's DOM builder as the XMLReader's SAX2 content handler
XSLTCDTMManager dtmManager =
- (XSLTCDTMManager)XSLTCDTMManager.getDTMManagerClass()
- .newInstance();
+ XSLTCDTMManager.createNewDTMManagerInstance();
DTMWSFilter wsfilter;
if (translet != null && translet instanceof StripFilter) {
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/DocumentCache.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/DocumentCache.java
index d5695187c0f..79f982489a5 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/DocumentCache.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/DocumentCache.java
@@ -156,8 +156,7 @@ public final class DocumentCache implements DOMCache {
public DocumentCache(int size) throws SAXException {
this(size, null);
try {
- _dtmManager = (XSLTCDTMManager)XSLTCDTMManager.getDTMManagerClass()
- .newInstance();
+ _dtmManager = XSLTCDTMManager.createNewDTMManagerInstance();
} catch (Exception e) {
throw new SAXException(e);
}
@@ -255,6 +254,7 @@ public final class DocumentCache implements DOMCache {
* Returns a document either by finding it in the cache or
* downloading it and putting it in the cache.
*/
+ @Override
public DOM retrieveDocument(String baseURI, String href, Translet trs) {
CachedDocument doc;
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java
index 43eb1024c3e..0cc6d073164 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java
@@ -30,7 +30,6 @@ import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stax.StAXSource;
-
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
import com.sun.org.apache.xml.internal.dtm.DTMException;
@@ -42,7 +41,6 @@ import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
import com.sun.org.apache.xalan.internal.xsltc.trax.DOM2SAX;
import com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX;
import com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
@@ -55,13 +53,6 @@ import org.xml.sax.XMLReader;
public class XSLTCDTMManager extends DTMManagerDefault
{
- /** The default class name to use as the manager. */
- private static final String DEFAULT_CLASS_NAME =
- "com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager";
-
- private static final String DEFAULT_PROP_NAME =
- "com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager";
-
/** Set this to true if you want a dump of the DTM after creation */
private static final boolean DUMPTREE = false;
@@ -88,42 +79,13 @@ public class XSLTCDTMManager extends DTMManagerDefault
}
/**
- * Look up the class that provides the XSLTC DTM Manager service.
- * The following lookup procedure is used to find the service provider.
- *
- * The value of the
- * com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager
property, is
- * checked.
- * The xalan.propeties
file is checked for a property
- * of the same name.
- * The
- * META-INF/services/com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager
- * file is checked.
- *
- * The default is com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager
.
+ * Creates a new instance of the XSLTC DTM Manager service.
+ * Creates a new instance of the default class
+ * com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager
.
*/
- public static Class getDTMManagerClass() {
- return getDTMManagerClass(true);
- }
-
- public static Class getDTMManagerClass(boolean useServicesMechanism) {
- Class mgrClass = null;
- if (useServicesMechanism) {
- mgrClass = ObjectFactory.lookUpFactoryClass(DEFAULT_PROP_NAME,
- null,
- DEFAULT_CLASS_NAME);
- } else {
- try {
- mgrClass = ObjectFactory.findProviderClass(DEFAULT_CLASS_NAME, true);
- } catch (Exception e) {
- //will not happen
- }
- }
- // If no class found, default to this one. (This should never happen -
- // the ObjectFactory has already been told that the current class is
- // the default).
- return (mgrClass != null) ? mgrClass : XSLTCDTMManager.class;
- }
+ public static XSLTCDTMManager createNewDTMManagerInstance() {
+ return newInstance();
+ }
/**
* Get an instance of a DTM, loaded with the content from the
@@ -146,6 +108,7 @@ public class XSLTCDTMManager extends DTMManagerDefault
*
* @return a non-null DTM reference.
*/
+ @Override
public DTM getDTM(Source source, boolean unique,
DTMWSFilter whiteSpaceFilter, boolean incremental,
boolean doIndexing)
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
index a15d8fad536..fdd89643721 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java
@@ -23,6 +23,17 @@
package com.sun.org.apache.xalan.internal.xsltc.trax;
+import com.sun.org.apache.xalan.internal.XalanConstants;
+import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
+import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
+import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;
+import com.sun.org.apache.xml.internal.utils.StopParseException;
+import com.sun.org.apache.xml.internal.utils.StylesheetPIHandler;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
@@ -37,11 +48,9 @@ import java.util.Properties;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-
import javax.xml.XMLConstants;
-import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
@@ -58,23 +67,9 @@ import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stax.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
-import javax.xml.transform.stax.*;
-
-import com.sun.org.apache.xml.internal.utils.StylesheetPIHandler;
-import com.sun.org.apache.xml.internal.utils.StopParseException;
-
-import com.sun.org.apache.xalan.internal.XalanConstants;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC;
-import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
-import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;
-import com.sun.org.apache.xalan.internal.utils.ObjectFactory;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
@@ -200,14 +195,6 @@ public class TransformerFactoryImpl
*/
private int _indentNumber = -1;
- /**
- * The provider of the XSLTC DTM Manager service. This is fixed for any
- * instance of this class. In order to change service providers, a new
- * XSLTC TransformerFactory
must be instantiated.
- * @see XSLTCDTMManager#getDTMManagerClass()
- */
- private Class m_DTMManagerClass;
-
/**
* State of secure processing feature.
*/
@@ -246,7 +233,6 @@ public class TransformerFactoryImpl
}
private TransformerFactoryImpl(boolean useServicesMechanism) {
- this.m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(useServicesMechanism);
this._useServicesMechanism = useServicesMechanism;
String defaultAccess = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
@@ -269,6 +255,7 @@ public class TransformerFactoryImpl
* @param listener The error listener to use with the TransformerFactory
* @throws IllegalArgumentException
*/
+ @Override
public void setErrorListener(ErrorListener listener)
throws IllegalArgumentException
{
@@ -286,6 +273,7 @@ public class TransformerFactoryImpl
*
* @return The error listener used with the TransformerFactory
*/
+ @Override
public ErrorListener getErrorListener() {
return _errorListener;
}
@@ -298,6 +286,7 @@ public class TransformerFactoryImpl
* @return An object representing the attribute value
* @throws IllegalArgumentException
*/
+ @Override
public Object getAttribute(String name)
throws IllegalArgumentException
{
@@ -337,6 +326,7 @@ public class TransformerFactoryImpl
* @param value An object representing the attribute value
* @throws IllegalArgumentException
*/
+ @Override
public void setAttribute(String name, Object value)
throws IllegalArgumentException
{
@@ -459,6 +449,7 @@ public class TransformerFactoryImpl
* or the Transformer
s or Template
s it creates cannot support this feature.
* @throws NullPointerException If the name
parameter is null.
*/
+ @Override
public void setFeature(String name, boolean value)
throws TransformerConfigurationException {
@@ -503,6 +494,7 @@ public class TransformerFactoryImpl
* @param name The feature name
* @return 'true' if feature is supported, 'false' if not
*/
+ @Override
public boolean getFeature(String name) {
// All supported features should be listed here
String[] features = {
@@ -554,6 +546,7 @@ public class TransformerFactoryImpl
* @return The URLResolver used for this TransformerFactory and all
* Templates and Transformer objects created using this factory
*/
+ @Override
public URIResolver getURIResolver() {
return _uriResolver;
}
@@ -568,6 +561,7 @@ public class TransformerFactoryImpl
* @param resolver The URLResolver used for this TransformerFactory and all
* Templates and Transformer objects created using this factory
*/
+ @Override
public void setURIResolver(URIResolver resolver) {
_uriResolver = resolver;
}
@@ -587,13 +581,14 @@ public class TransformerFactoryImpl
* @return A Source object suitable for passing to the TransformerFactory.
* @throws TransformerConfigurationException
*/
+ @Override
public Source getAssociatedStylesheet(Source source, String media,
String title, String charset)
throws TransformerConfigurationException {
String baseId;
- XMLReader reader = null;
- InputSource isource = null;
+ XMLReader reader;
+ InputSource isource;
/**
@@ -675,6 +670,7 @@ public class TransformerFactoryImpl
* @return A Transformer object that simply copies the source to the result.
* @throws TransformerConfigurationException
*/
+ @Override
public Transformer newTransformer()
throws TransformerConfigurationException
{
@@ -700,6 +696,7 @@ public class TransformerFactoryImpl
* @return A Templates object that can be used to create Transformers.
* @throws TransformerConfigurationException
*/
+ @Override
public Transformer newTransformer(Source source) throws
TransformerConfigurationException
{
@@ -763,6 +760,7 @@ public class TransformerFactoryImpl
* @return A Templates object that can be used to create Transformers.
* @throws TransformerConfigurationException
*/
+ @Override
public Templates newTemplates(Source source)
throws TransformerConfigurationException
{
@@ -796,7 +794,7 @@ public class TransformerFactoryImpl
// If _autoTranslet is true, we will try to load the bytecodes
// from the translet classes without compiling the stylesheet.
if (_autoTranslet) {
- byte[][] bytecodes = null;
+ byte[][] bytecodes;
String transletClassName = getTransletBaseName(source);
if (_packageName != null)
@@ -918,7 +916,7 @@ public class TransformerFactoryImpl
// Check that the transformation went well before returning
if (bytecodes == null) {
Vector errs = xsltc.getErrors();
- ErrorMsg err = null;
+ ErrorMsg err;
if (errs != null) {
err = (ErrorMsg)errs.elementAt(errs.size()-1);
} else {
@@ -963,6 +961,7 @@ public class TransformerFactoryImpl
* @return A TemplatesHandler object that can handle SAX events
* @throws TransformerConfigurationException
*/
+ @Override
public TemplatesHandler newTemplatesHandler()
throws TransformerConfigurationException
{
@@ -982,6 +981,7 @@ public class TransformerFactoryImpl
* @return A TransformerHandler object that can handle SAX events
* @throws TransformerConfigurationException
*/
+ @Override
public TransformerHandler newTransformerHandler()
throws TransformerConfigurationException
{
@@ -1002,6 +1002,7 @@ public class TransformerFactoryImpl
* @return A TransformerHandler object that can handle SAX events
* @throws TransformerConfigurationException
*/
+ @Override
public TransformerHandler newTransformerHandler(Source src)
throws TransformerConfigurationException
{
@@ -1022,6 +1023,7 @@ public class TransformerFactoryImpl
* @return A TransformerHandler object that can handle SAX events
* @throws TransformerConfigurationException
*/
+ @Override
public TransformerHandler newTransformerHandler(Templates templates)
throws TransformerConfigurationException
{
@@ -1039,6 +1041,7 @@ public class TransformerFactoryImpl
* @return An XMLFilter object, or null if this feature is not supported.
* @throws TransformerConfigurationException
*/
+ @Override
public XMLFilter newXMLFilter(Source src)
throws TransformerConfigurationException
{
@@ -1056,6 +1059,7 @@ public class TransformerFactoryImpl
* @return An XMLFilter object, or null if this feature is not supported.
* @throws TransformerConfigurationException
*/
+ @Override
public XMLFilter newXMLFilter(Templates templates)
throws TransformerConfigurationException
{
@@ -1087,6 +1091,7 @@ public class TransformerFactoryImpl
* @throws TransformerException if the application chooses to discontinue
* the transformation (always does in our case).
*/
+ @Override
public void error(TransformerException e)
throws TransformerException
{
@@ -1115,6 +1120,7 @@ public class TransformerFactoryImpl
* @throws TransformerException if the application chooses to discontinue
* the transformation (always does in our case).
*/
+ @Override
public void fatalError(TransformerException e)
throws TransformerException
{
@@ -1143,6 +1149,7 @@ public class TransformerFactoryImpl
* @throws TransformerException if the application chooses to discontinue
* the transformation (never does in our case).
*/
+ @Override
public void warning(TransformerException e)
throws TransformerException
{
@@ -1166,6 +1173,7 @@ public class TransformerFactoryImpl
* @param xsltc The compiler that resuests the document
* @return An InputSource with the loaded document
*/
+ @Override
public InputSource loadSource(String href, String context, XSLTC xsltc) {
try {
if (_uriResolver != null) {
@@ -1252,7 +1260,7 @@ public class TransformerFactoryImpl
Vector bytecodes = new Vector();
int fileLength = (int)transletFile.length();
if (fileLength > 0) {
- FileInputStream input = null;
+ FileInputStream input;
try {
input = new FileInputStream(transletFile);
}
@@ -1284,6 +1292,7 @@ public class TransformerFactoryImpl
// Find all the auxiliary files which have a name pattern of "transletClass$nnn.class".
final String transletAuxPrefix = transletName + "$";
File[] auxfiles = transletParentFile.listFiles(new FilenameFilter() {
+ @Override
public boolean accept(File dir, String name)
{
return (name.endsWith(".class") && name.startsWith(transletAuxPrefix));
@@ -1347,7 +1356,7 @@ public class TransformerFactoryImpl
xslFile = new File(xslFileName);
// Construct the path for the jar file
- String jarPath = null;
+ String jarPath;
if (_destinationDirectory != null)
jarPath = _destinationDirectory + "/" + _jarFileName;
else {
@@ -1372,7 +1381,7 @@ public class TransformerFactoryImpl
}
// Create a ZipFile object for the jar file
- ZipFile jarFile = null;
+ ZipFile jarFile;
try {
jarFile = new ZipFile(file);
}
@@ -1490,7 +1499,7 @@ public class TransformerFactoryImpl
if (file.exists())
return systemId;
else {
- URL url = null;
+ URL url;
try {
url = new URL(systemId);
}
@@ -1509,9 +1518,9 @@ public class TransformerFactoryImpl
}
/**
- * Returns the Class object the provides the XSLTC DTM Manager service.
+ * Returns a new instance of the XSLTC DTM Manager service.
*/
- protected Class getDTMManagerClass() {
- return m_DTMManagerClass;
+ protected final XSLTCDTMManager createNewDTMManagerInstance() {
+ return XSLTCDTMManager.createNewDTMManagerInstance();
}
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerHandlerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerHandlerImpl.java
index e1bb5141b64..cd4b4be14e2 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerHandlerImpl.java
@@ -96,6 +96,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* resolved.
* @return The systemID that was set with setSystemId(String id)
*/
+ @Override
public String getSystemId() {
return _systemId;
}
@@ -106,6 +107,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* resolved.
* @param id Base URI for this stylesheet
*/
+ @Override
public void setSystemId(String id) {
_systemId = id;
}
@@ -116,6 +118,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* order to set parameters and output properties.
* @return The Transformer object
*/
+ @Override
public Transformer getTransformer() {
return _transformer;
}
@@ -127,6 +130,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* @param result A Result instance, should not be null
* @throws IllegalArgumentException if result is invalid for some reason
*/
+ @Override
public void setResult(Result result) throws IllegalArgumentException {
_result = result;
@@ -166,6 +170,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.characters()
* Receive notification of character data.
*/
+ @Override
public void characters(char[] ch, int start, int length)
throws SAXException
{
@@ -176,6 +181,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.startDocument()
* Receive notification of the beginning of a document.
*/
+ @Override
public void startDocument() throws SAXException {
// Make sure setResult() was called before the first SAX event
if (_result == null) {
@@ -189,10 +195,8 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
// Create an internal DOM (not W3C) and get SAX2 input handler
try {
- dtmManager =
- (XSLTCDTMManager)_transformer.getTransformerFactory()
- .getDTMManagerClass()
- .newInstance();
+ dtmManager = _transformer.getTransformerFactory()
+ .createNewDTMManagerInstance();
} catch (Exception e) {
throw new SAXException(e);
}
@@ -230,6 +234,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.endDocument()
* Receive notification of the end of a document.
*/
+ @Override
public void endDocument() throws SAXException {
// Signal to the DOMBuilder that the document is complete
_handler.endDocument();
@@ -260,6 +265,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.startElement()
* Receive notification of the beginning of an element.
*/
+ @Override
public void startElement(String uri, String localName,
String qname, Attributes attributes)
throws SAXException
@@ -271,6 +277,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.endElement()
* Receive notification of the end of an element.
*/
+ @Override
public void endElement(String namespaceURI, String localName, String qname)
throws SAXException
{
@@ -281,6 +288,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.processingInstruction()
* Receive notification of a processing instruction.
*/
+ @Override
public void processingInstruction(String target, String data)
throws SAXException
{
@@ -290,6 +298,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.startCDATA()
*/
+ @Override
public void startCDATA() throws SAXException {
if (_lexHandler != null) {
_lexHandler.startCDATA();
@@ -299,6 +308,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.endCDATA()
*/
+ @Override
public void endCDATA() throws SAXException {
if (_lexHandler != null) {
_lexHandler.endCDATA();
@@ -309,6 +319,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ext.LexicalHandler.comment()
* Receieve notification of a comment
*/
+ @Override
public void comment(char[] ch, int start, int length)
throws SAXException
{
@@ -322,6 +333,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Receive notification of ignorable whitespace in element
* content. Similar to characters(char[], int, int).
*/
+ @Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException
{
@@ -332,6 +344,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.setDocumentLocator()
* Receive an object for locating the origin of SAX document events.
*/
+ @Override
public void setDocumentLocator(Locator locator) {
_locator = locator;
@@ -344,6 +357,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.skippedEntity()
* Receive notification of a skipped entity.
*/
+ @Override
public void skippedEntity(String name) throws SAXException {
_handler.skippedEntity(name);
}
@@ -352,6 +366,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.startPrefixMapping()
* Begin the scope of a prefix-URI Namespace mapping.
*/
+ @Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
_handler.startPrefixMapping(prefix, uri);
@@ -361,6 +376,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
* Implements org.xml.sax.ContentHandler.endPrefixMapping()
* End the scope of a prefix-URI Namespace mapping.
*/
+ @Override
public void endPrefixMapping(String prefix) throws SAXException {
_handler.endPrefixMapping(prefix);
}
@@ -368,6 +384,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.startDTD()
*/
+ @Override
public void startDTD(String name, String publicId, String systemId)
throws SAXException
{
@@ -379,6 +396,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.endDTD()
*/
+ @Override
public void endDTD() throws SAXException {
if (_lexHandler != null) {
_lexHandler.endDTD();
@@ -388,6 +406,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.startEntity()
*/
+ @Override
public void startEntity(String name) throws SAXException {
if (_lexHandler != null) {
_lexHandler.startEntity(name);
@@ -397,6 +416,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.LexicalHandler.endEntity()
*/
+ @Override
public void endEntity(String name) throws SAXException {
if (_lexHandler != null) {
_lexHandler.endEntity(name);
@@ -406,6 +426,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.DTDHandler.unparsedEntityDecl()
*/
+ @Override
public void unparsedEntityDecl(String name, String publicId,
String systemId, String notationName) throws SAXException
{
@@ -418,6 +439,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.DTDHandler.notationDecl()
*/
+ @Override
public void notationDecl(String name, String publicId, String systemId)
throws SAXException
{
@@ -429,6 +451,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.DeclHandler.attributeDecl()
*/
+ @Override
public void attributeDecl(String eName, String aName, String type,
String valueDefault, String value) throws SAXException
{
@@ -440,6 +463,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.DeclHandler.elementDecl()
*/
+ @Override
public void elementDecl(String name, String model)
throws SAXException
{
@@ -451,6 +475,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
*/
+ @Override
public void externalEntityDecl(String name, String publicId, String systemId)
throws SAXException
{
@@ -462,6 +487,7 @@ public class TransformerHandlerImpl implements TransformerHandler, DeclHandler {
/**
* Implements org.xml.sax.ext.DeclHandler.externalEntityDecl()
*/
+ @Override
public void internalEntityDecl(String name, String value)
throws SAXException
{
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
index a32ab8267f8..63446e734e2 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java
@@ -99,10 +99,6 @@ import org.xml.sax.ext.LexicalHandler;
public final class TransformerImpl extends Transformer
implements DOMCache, ErrorListener
{
- private final static String EMPTY_STRING = "";
- private final static String NO_STRING = "no";
- private final static String YES_STRING = "yes";
- private final static String XML_STRING = "xml";
private final static String LEXICAL_HANDLER_PROPERTY =
"http://xml.org/sax/properties/lexical-handler";
@@ -156,7 +152,7 @@ public final class TransformerImpl extends Transformer
private TransletOutputHandlerFactory _tohFactory = null;
/**
- * A reference to a internal DOM represenation of the input.
+ * A reference to a internal DOM representation of the input.
*/
private DOM _dom = null;
@@ -238,6 +234,7 @@ public final class TransformerImpl extends Transformer
_errorListener = errorListener;
}
+ @Override
public void displayMessage(String msg) {
if(_errorListener == null) {
System.err.println(msg);
@@ -323,6 +320,7 @@ public final class TransformerImpl extends Transformer
* @param result Will contain the output from the transformation
* @throws TransformerException
*/
+ @Override
public void transform(Source source, Result result)
throws TransformerException
{
@@ -465,7 +463,7 @@ public final class TransformerImpl extends Transformer
// System Id may be in one of several forms, (1) a uri
// that starts with 'file:', (2) uri that starts with 'http:'
// or (3) just a filename on the local system.
- URL url = null;
+ URL url;
if (systemId.startsWith("file:")) {
// if StreamResult(File) or setSystemID(File) was used,
// the systemId will be URI encoded as a result of File.toURI(),
@@ -537,7 +535,7 @@ public final class TransformerImpl extends Transformer
*/
private DOM getDOM(Source source) throws TransformerException {
try {
- DOM dom = null;
+ DOM dom;
if (source != null) {
DTMWSFilter wsfilter;
@@ -552,8 +550,7 @@ public final class TransformerImpl extends Transformer
if (_dtmManager == null) {
_dtmManager =
- (XSLTCDTMManager)_tfactory.getDTMManagerClass()
- .newInstance();
+ _tfactory.createNewDTMManagerInstance();
_dtmManager.setServicesMechnism(_useServicesMechanism);
}
dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
@@ -676,8 +673,8 @@ public final class TransformerImpl extends Transformer
}
} else if (source instanceof StAXSource) {
final StAXSource staxSource = (StAXSource)source;
- StAXEvent2SAX staxevent2sax = null;
- StAXStream2SAX staxStream2SAX = null;
+ StAXEvent2SAX staxevent2sax;
+ StAXStream2SAX staxStream2SAX;
if (staxSource.getXMLEventReader() != null) {
final XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
staxevent2sax = new StAXEvent2SAX(xmlEventReader);
@@ -770,6 +767,7 @@ public final class TransformerImpl extends Transformer
*
* @return The error event handler currently in effect
*/
+ @Override
public ErrorListener getErrorListener() {
return _errorListener;
}
@@ -783,6 +781,7 @@ public final class TransformerImpl extends Transformer
* @param listener The error event listener to use
* @throws IllegalArgumentException
*/
+ @Override
public void setErrorListener(ErrorListener listener)
throws IllegalArgumentException {
if (listener == null) {
@@ -830,7 +829,7 @@ public final class TransformerImpl extends Transformer
// Return a 'null' string if no CDATA section elements were specified
if (cdata == null) return null;
- StringBuffer result = new StringBuffer();
+ final StringBuilder result = new StringBuilder();
// Get an enumeration of all the elements in the hashtable
Enumeration elements = cdata.keys();
@@ -857,6 +856,7 @@ public final class TransformerImpl extends Transformer
*
* @return Properties in effect for this Transformer
*/
+ @Override
public Properties getOutputProperties() {
return (Properties) _properties.clone();
}
@@ -870,6 +870,7 @@ public final class TransformerImpl extends Transformer
* @param name A non-null string that contains the name of the property
* @throws IllegalArgumentException if the property name is not known
*/
+ @Override
public String getOutputProperty(String name)
throws IllegalArgumentException
{
@@ -889,6 +890,7 @@ public final class TransformerImpl extends Transformer
* @param properties The properties to use for the Transformer
* @throws IllegalArgumentException Never, errors are ignored
*/
+ @Override
public void setOutputProperties(Properties properties)
throws IllegalArgumentException
{
@@ -925,6 +927,7 @@ public final class TransformerImpl extends Transformer
* @param value The value to assign to the property
* @throws IllegalArgumentException Never, errors are ignored
*/
+ @Override
public void setOutputProperty(String name, String value)
throws IllegalArgumentException
{
@@ -1205,6 +1208,7 @@ public final class TransformerImpl extends Transformer
* @param name The name of the parameter
* @param value The value to assign to the parameter
*/
+ @Override
public void setParameter(String name, Object value) {
if (value == null) {
@@ -1228,6 +1232,7 @@ public final class TransformerImpl extends Transformer
* Clear all parameters set with setParameter. Clears the translet's
* parameter stack.
*/
+ @Override
public void clearParameters() {
if (_isIdentity && _parameters != null) {
_parameters.clear();
@@ -1245,6 +1250,7 @@ public final class TransformerImpl extends Transformer
* @param name The name of the parameter
* @return An object that contains the value assigned to the parameter
*/
+ @Override
public final Object getParameter(String name) {
if (_isIdentity) {
return (_parameters != null) ? _parameters.get(name) : null;
@@ -1260,6 +1266,7 @@ public final class TransformerImpl extends Transformer
*
* @return The URLResolver object currently in use
*/
+ @Override
public URIResolver getURIResolver() {
return _uriResolver;
}
@@ -1270,6 +1277,7 @@ public final class TransformerImpl extends Transformer
*
* @param resolver The URIResolver to use in document()
*/
+ @Override
public void setURIResolver(URIResolver resolver) {
_uriResolver = resolver;
}
@@ -1288,6 +1296,7 @@ public final class TransformerImpl extends Transformer
* @param href The href argument passed to the document function.
* @param translet A reference to the translet requesting the document
*/
+ @Override
public DOM retrieveDocument(String baseURI, String href, Translet translet) {
try {
// Argument to document function was: document('');
@@ -1330,6 +1339,7 @@ public final class TransformerImpl extends Transformer
* @throws TransformerException if the application chooses to discontinue
* the transformation (always does in our case).
*/
+ @Override
public void error(TransformerException e)
throws TransformerException
{
@@ -1358,6 +1368,7 @@ public final class TransformerImpl extends Transformer
* @throws TransformerException if the application chooses to discontinue
* the transformation (always does in our case).
*/
+ @Override
public void fatalError(TransformerException e)
throws TransformerException
{
@@ -1386,6 +1397,7 @@ public final class TransformerImpl extends Transformer
* @throws TransformerException if the application chooses to discontinue
* the transformation (never does in our case).
*/
+ @Override
public void warning(TransformerException e)
throws TransformerException
{
@@ -1406,6 +1418,7 @@ public final class TransformerImpl extends Transformer
* created
* @since 1.5
*/
+ @Override
public void reset() {
_method = null;
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java
index 63ce5e59b08..2e4ceeae001 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java
@@ -20,15 +20,6 @@
package com.sun.org.apache.xerces.internal.utils;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-
-import java.util.Properties;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
@@ -50,113 +41,9 @@ public final class ObjectFactory {
//
private static final String DEFAULT_INTERNAL_CLASSES = "com.sun.org.apache.";
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
-
/** Set to true for debugging */
private static final boolean DEBUG = isDebugEnabled();
- /**
- * Default columns per line.
- */
- private static final int DEFAULT_LINE_LENGTH = 80;
-
- /** cache the contents of the xerces.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXercesProperties = null;
-
- /***
- * Cache the time stamp of the xerces.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- public static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- * query the system property using System.getProperty
- * read $java.home/lib/propertiesFilename
file
- * read META-INF/services/factoryId
file
- * use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xerces.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- public static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- if (DEBUG) debugPrintln("debug is on");
-
- ClassLoader cl = findClassLoader();
-
- // Use the system property first
- try {
- String systemProp = SecuritySupport.getSystemProperty(factoryId);
- if (systemProp != null && systemProp.length() > 0) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return newInstance(systemProp, cl, true);
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // JAXP specific change
- // always use fallback class to avoid the expense of constantly
- // "stat"ing a non-existent "xerces.properties" and jar SPI entry
- // see CR 6400863: Expensive creating of SAX parser in Mustang
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
-
- } // createObject(String,String,String):Object
//
// Private static methods
@@ -235,7 +122,7 @@ public final class ObjectFactory {
// Check for any extension ClassLoaders in chain up to
// boot ClassLoader
chain = SecuritySupport.getParentClassLoader(chain);
- };
+ }
// Assert: Context ClassLoader not in chain of
// boot/extension/system ClassLoaders
@@ -343,94 +230,4 @@ public final class ObjectFactory {
return providerClass;
}
- /*
- * Try to find provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static Object findJarServiceProvider(String factoryId)
- throws ConfigurationError
- {
- String serviceId = "META-INF/services/" + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = SecuritySupport.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = SecuritySupport.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return newInstance(factoryClassName, cl, false);
- }
-
- // No provider found
- return null;
- }
-
} // class ObjectFactory
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java b/jaxp/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java
index 711814e80e1..d629b9fd8db 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java
@@ -52,14 +52,6 @@ import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
public abstract class DTMManager
{
- /** The default property name to load the manager. */
- private static final String defaultPropName =
- "com.sun.org.apache.xml.internal.dtm.DTMManager";
-
- /** The default class name to use as the manager. */
- private static String defaultClassName =
- "com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault";
-
/**
* Factory for creating XMLString objects.
* %TBD% Make this set by the caller.
@@ -97,29 +89,7 @@ public abstract class DTMManager
/**
* Obtain a new instance of a DTMManager
.
* This static method creates a new factory instance
- * This method uses the following ordered lookup procedure to determine
- * the DTMManager
implementation class to
- * load:
- *
- *
- * Use the com.sun.org.apache.xml.internal.dtm.DTMManager
system
- * property.
- *
- *
- * Use the JAVA_HOME(the parent directory where jdk is
- * installed)/lib/xalan.properties for a property file that contains the
- * name of the implementation class keyed on the same value as the
- * system property defined above.
- *
- *
- * Use the Services API (as detailed in the JAR specification), if
- * available, to determine the classname. The Services API will look
- * for a classname in the file
- * META-INF/services/com.sun.org.apache.xml.internal.dtm.DTMManager
- * in jars available to the runtime.
- *
- *
- * Use the default DTMManager
classname, which is
+ * using the default DTMManager
implementation, which is
* com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault
.
*
*
@@ -136,39 +106,10 @@ public abstract class DTMManager
public static DTMManager newInstance(XMLStringFactory xsf)
throws DTMConfigurationException
{
- return newInstance(xsf, true);
- }
+ final DTMManager factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault();
+ factoryImpl.setXMLStringFactory(xsf);
- public static DTMManager newInstance(XMLStringFactory xsf, boolean useServicesMechanism)
- throws DTMConfigurationException
- {
- DTMManager factoryImpl = null;
- try
- {
- if (useServicesMechanism) {
- factoryImpl = (DTMManager) ObjectFactory
- .createObject(defaultPropName, defaultClassName);
- } else {
- factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault();
- }
- }
- catch (ConfigurationError e)
- {
- throw new DTMConfigurationException(XMLMessages.createXMLMessage(
- XMLErrorResources.ER_NO_DEFAULT_IMPL, null), e.getException());
- //"No default implementation found");
- }
-
- if (factoryImpl == null)
- {
- throw new DTMConfigurationException(XMLMessages.createXMLMessage(
- XMLErrorResources.ER_NO_DEFAULT_IMPL, null));
- //"No default implementation found");
- }
-
- factoryImpl.setXMLStringFactory(xsf);
-
- return factoryImpl;
+ return factoryImpl;
}
/**
diff --git a/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java b/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java
index dc1063e8f3d..e71f61e6243 100644
--- a/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java
+++ b/jaxp/src/com/sun/org/apache/xpath/internal/XPathContext.java
@@ -22,17 +22,6 @@
*/
package com.sun.org.apache.xpath.internal;
-import java.lang.reflect.Method;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.HashMap;
-import java.util.Iterator;
-
-import javax.xml.transform.ErrorListener;
-import javax.xml.transform.SourceLocator;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.URIResolver;
-
import com.sun.org.apache.xalan.internal.extensions.ExpressionContext;
import com.sun.org.apache.xalan.internal.res.XSLMessages;
import com.sun.org.apache.xml.internal.dtm.Axis;
@@ -46,14 +35,21 @@ import com.sun.org.apache.xml.internal.utils.IntStack;
import com.sun.org.apache.xml.internal.utils.NodeVector;
import com.sun.org.apache.xml.internal.utils.ObjectStack;
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
-import com.sun.org.apache.xml.internal.utils.SAXSourceLocator;
import com.sun.org.apache.xml.internal.utils.XMLString;
import com.sun.org.apache.xpath.internal.axes.SubContextList;
-import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.objects.DTMXRTreeFrag;
+import com.sun.org.apache.xpath.internal.objects.XObject;
import com.sun.org.apache.xpath.internal.objects.XString;
import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
-
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
import org.xml.sax.XMLReader;
/**
@@ -339,8 +335,8 @@ public class XPathContext extends DTMManager // implements ExpressionContext
m_saxLocations.push(null);
m_useServicesMechanism = useServicesMechanism;
m_dtmManager = DTMManager.newInstance(
- com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(),
- m_useServicesMechanism);
+ com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
+ );
}
/**
@@ -363,8 +359,8 @@ public class XPathContext extends DTMManager // implements ExpressionContext
m_dtmManager = DTMManager.newInstance(
- com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(),
- m_useServicesMechanism);
+ com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()
+ );
m_saxLocations.removeAllElements();
m_axesIteratorStack.removeAllElements();
@@ -622,32 +618,6 @@ public class XPathContext extends DTMManager // implements ExpressionContext
/** Misnamed string manager for XPath messages. */
// private static XSLMessages m_XSLMessages = new XSLMessages();
- /**
- * Tell the user of an assertion error, and probably throw an
- * exception.
- *
- * @param b If false, a TransformerException will be thrown.
- * @param msg The assertion message, which should be informative.
- *
- * @throws javax.xml.transform.TransformerException if b is false.
- */
- private void assertion(boolean b, String msg) throws javax.xml.transform.TransformerException
- {
- if (!b)
- {
- ErrorListener errorHandler = getErrorListener();
-
- if (errorHandler != null)
- {
- errorHandler.fatalError(
- new TransformerException(
- XSLMessages.createMessage(
- XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
- new Object[]{ msg }), (SAXSourceLocator)this.getSAXLocator()));
- }
- }
- }
-
//==========================================================
// SECTION: Execution context state tracking
//==========================================================
@@ -664,7 +634,7 @@ public class XPathContext extends DTMManager // implements ExpressionContext
* Get the current context node list.
*
* @return the current node list ,
- * also refered to here as a context node list .
+ * also referred to here as a context node list .
*/
public final DTMIterator getContextNodeList()
{
@@ -679,7 +649,7 @@ public class XPathContext extends DTMManager // implements ExpressionContext
* Set the current context node list.
*
* @param nl the current node list ,
- * also refered to here as a context node list .
+ * also referred to here as a context node list .
* @xsl.usage internal
*/
public final void pushContextNodeList(DTMIterator nl)
@@ -700,7 +670,7 @@ public class XPathContext extends DTMManager // implements ExpressionContext
}
/**
- * The ammount to use for stacks that record information during the
+ * The amount to use for stacks that record information during the
* recursive execution.
*/
public static final int RECURSIONLIMIT = (1024*4);
From e89bdfbdc33ecd84afa5c906c1471f4aca33b06d Mon Sep 17 00:00:00 2001
From: Joe Wang
Date: Thu, 6 Jun 2013 15:03:55 -0700
Subject: [PATCH 020/136] 8015016: Improve JAXP 1.5 error message
Reviewed-by: lancea
---
.../xalan/internal/xsltc/compiler/util/ErrorMessages.java | 2 +-
.../apache/xerces/internal/impl/msg/XMLMessages.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_de.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_es.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_fr.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_it.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_ja.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_ko.properties | 4 ++--
.../xerces/internal/impl/msg/XMLMessages_pt_BR.properties | 4 ++--
.../apache/xerces/internal/impl/msg/XMLMessages_sv.properties | 4 ++--
.../xerces/internal/impl/msg/XMLMessages_zh_CN.properties | 4 ++--
.../xerces/internal/impl/msg/XMLMessages_zh_TW.properties | 4 ++--
.../xerces/internal/impl/msg/XMLSchemaMessages.properties | 2 +-
13 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
index 90655c6fe45..8595d82bc21 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java
@@ -449,7 +449,7 @@ public class ErrorMessages extends ListResourceBundle {
* Note to translators: access to the stylesheet target is denied
*/
{ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
- "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."},
+ "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalStylesheet property."},
/*
* Note to translators: This message represents an internal error in
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
index 3bf9ebdc987..1a5d62af9bb 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
@@ -261,8 +261,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = The entity \"{0}\" was referenced, but not declared.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
index 3cf21e56482..e37d70e8c82 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Externe Entit\u00E4tsreferenz \"&{0};\" ist in einem Attributwert nicht zul\u00E4ssig.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = Entit\u00E4t \"{0}\" wurde referenziert aber nicht deklariert.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
index 5ebfaf0eb2a..9daf7ba5d24 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = La referencia de entidad externa \"&{0};\" no est\u00E1 permitida en un valor de atributo.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = Se hizo referencia a la entidad \"{0}\", pero no se declar\u00F3.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
index f60b07301ee..9d946086a79 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = La r\u00E9f\u00E9rence d''entit\u00E9 externe \"&{0};\" n''est pas autoris\u00E9e dans une valeur d''attribut.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = L''entit\u00E9 \"{0}\" \u00E9tait r\u00E9f\u00E9renc\u00E9e, mais pas d\u00E9clar\u00E9e.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
index e525777850b..3271a13fd4d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Il riferimento di entit\u00E0 esterna \"&{0};\" non \u00E8 consentito in un valore di attributo.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = L''entit\u00E0 \"{0}\" \u00E8 indicata da un riferimento, ma non \u00E8 dichiarata.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
index ed548694ec4..2d2fc6257c0 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5916\u90E8\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u3001\u5C5E\u6027\u5024\u3067\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\"{0}\"\u304C\u53C2\u7167\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
index 882f8085758..6b98b4d7b8d 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \uC18D\uC131\uAC12\uC5D0\uC11C\uB294 \uC678\uBD80 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC774 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = \"{0}\" \uC5D4\uD2F0\uD2F0\uAC00 \uCC38\uC870\uB418\uC5C8\uC9C0\uB9CC \uC120\uC5B8\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
index 57770dcde09..914fb56ec03 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = A refer\u00EAncia da entidade externa \"&{0};\" n\u00E3o \u00E9 permitida em um valor do atributo.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = A entidade \"{0}\" foi referenciada, mas n\u00E3o declarada.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
index 8c0bb0f0f8d..2817bf470d3 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = Den externa enhetsreferensen \"&{0};\" till\u00E5ts inte i ett attributv\u00E4rde.
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = Enheten \"{0}\" har refererats, men \u00E4r inte deklarerad.
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
index 74a7a061c2b..022680b5859 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5C5E\u6027\u503C\u4E2D\u4E0D\u5141\u8BB8\u91C7\u7528\u5916\u90E8\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = \u5F15\u7528\u4E86\u5B9E\u4F53 \"{0}\", \u4F46\u672A\u58F0\u660E\u5B83\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
index 1a953819503..7a2028f0c54 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties
@@ -289,8 +289,8 @@
# Entity related messages
# 3.1 Start-Tags, End-Tags, and Empty-Element Tags
ReferenceToExternalEntity = \u5C6C\u6027\u503C\u4E0D\u5141\u8A31\u53C3\u7167\u5916\u90E8\u500B\u9AD4 \"&{0};\"\u3002
- AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed.
- AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed.
+ AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
+ AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property.
# 4.1 Character and Entity References
EntityNotDeclared = \u53C3\u7167\u4E86\u500B\u9AD4 \"{0}\"\uFF0C\u4F46\u662F\u672A\u5BA3\u544A\u3002
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
index 23234a4bf61..d986140a86e 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties
@@ -86,7 +86,7 @@
#schema valid (3.X.3)
- schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed.
+ schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalSchema property.
schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not .
src-annotation = src-annotation: elements can only contain and elements, but ''{0}'' was found.
src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them.
From 34dc5002fd9b4dca6337dd053caa726ac3658c57 Mon Sep 17 00:00:00 2001
From: Andrew Brygin
Date: Fri, 7 Jun 2013 14:45:29 +0400
Subject: [PATCH 021/136] 6830714: cmm test failures with OpenJDK
Reviewed-by: prr
---
.../cmm/ColorConvertOp/ColConvCCMTest.java | 6 ++--
.../cmm/ColorConvertOp/ColConvDCMTest.java | 11 +++++--
.../cmm/ColorConvertOp/ColConvTest.java | 30 +++++++++++++++++++
3 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
index 89bd29af056..12418c0ed2a 100644
--- a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
+++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvCCMTest.java
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6476665 7033534
+ * @bug 6476665 7033534 6830714
* @summary Verifies color conversion of Component Color Model based images
* @run main ColConvCCMTest
*/
@@ -57,9 +57,9 @@ public class ColConvCCMTest extends ColConvTest {
final static double [] ACCURACY = {
// Accuracy for color conversions
2.5, // sRGB
- 6.5, // LINEAR_RGB
+ (isOpenProfile() ? 45.0 : 10.1), // LINEAR_RGB
10.5, // GRAY
- 45.5, // PYCC
+ (isOpenProfile() ? 207 : 45.5), // PYCC
47.5 // CIEXYZ
};
diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvDCMTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvDCMTest.java
index b9f85c72519..9ad05689942 100644
--- a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvDCMTest.java
+++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvDCMTest.java
@@ -62,7 +62,11 @@ public class ColConvDCMTest extends ColConvTest {
ColorSpace.CS_LINEAR_RGB,
};
- final static double ACCURACY = 2.5;
+ final static double [] ACCURACY = {
+ // Accuracy for color conversions
+ 2.5, // sRGB
+ (isOpenProfile() ? 45.0 : 2.5), // LINEAR_RGB
+ };
final static String [] gldImgNames = {
"SRGB.png", "SRGB555.png", "SRGB565.png", "LRGB.png", "LRGB555.png",
@@ -142,7 +146,7 @@ public class ColConvDCMTest extends ColConvTest {
if (!testImage(imgTypes[i][0], imgTypes[i][1], imgTypes[i][2],
imgTypes[i][3], cSpaces[imgTypes[i][4]], gldImage,
- ACCURACY))
+ ACCURACY[imgTypes[i][4]]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
@@ -154,7 +158,8 @@ public class ColConvDCMTest extends ColConvTest {
if (!testSubImage(SI_X, SI_Y, SI_W, SI_H, imgTypes[i][0],
imgTypes[i][1], imgTypes[i][2], imgTypes[i][3],
- cSpaces[imgTypes[i][4]], gldImage, ACCURACY))
+ cSpaces[imgTypes[i][4]], gldImage,
+ ACCURACY[imgTypes[i][4]]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
diff --git a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvTest.java b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvTest.java
index db3719134f1..b3f1c2e4da2 100644
--- a/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvTest.java
+++ b/jdk/test/sun/java2d/cmm/ColorConvertOp/ColConvTest.java
@@ -22,6 +22,7 @@
*/
import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
@@ -126,4 +127,33 @@ public abstract class ColConvTest implements Runnable {
public boolean isPassed() {
return passed;
}
+
+ private static Boolean isOpenProfile = null;
+
+ public static boolean isOpenProfile() {
+ if (isOpenProfile == null) {
+ ICC_Profile p = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
+
+ byte[] h = p.getData(ICC_Profile.icSigHead);
+
+ if (h == null || h.length < 128) {
+ throw new RuntimeException("Test failed: invalid sRGB header");
+ }
+
+ final byte[] lcmsID = new byte[] {
+ (byte)0x6c, // l
+ (byte)0x63, // c
+ (byte)0x6d, // m
+ (byte)0x73, // s
+ };
+
+ int off = ICC_Profile.icHdrCmmId;
+
+ isOpenProfile = ((h[off + 0] == lcmsID[0])
+ && (h[off + 1] == lcmsID[1])
+ && (h[off + 2] == lcmsID[2])
+ && (h[off + 3] == lcmsID[3]));
+ }
+ return isOpenProfile;
+ }
}
From 690abe1b20b6bcd79958fb84119560362ba72fb4 Mon Sep 17 00:00:00 2001
From: Morris Meyer
Date: Fri, 7 Jun 2013 07:33:35 -0700
Subject: [PATCH 022/136] 8015437: SPARC cbcond branch offset out of 10-bit
range
Forced SPARC MacroAssembler eden_alloate to use long branch to slow case
Reviewed-by: kvn, twisti
---
hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
index 578650a3419..c17b7c2b32c 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
@@ -3540,7 +3540,8 @@ void MacroAssembler::eden_allocate(
if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
// No allocation in the shared eden.
- ba_short(slow_case);
+ ba(slow_case);
+ delayed()->nop();
} else {
// get eden boundaries
// note: we need both top & top_addr!
From 2bc5557936d1b23f461ed39af58f71105336f73d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Fri, 7 Jun 2013 17:44:25 +0200
Subject: [PATCH 023/136] 8012291: NativeArray is inconsistent in using long
for length and index in some places and int for the same in other places
Reviewed-by: lagergren, jlaskey
---
.../internal/codegen/FieldObjectCreator.java | 2 +-
.../nashorn/internal/codegen/MapCreator.java | 2 +-
.../internal/objects/ArrayBufferView.java | 13 +-
.../internal/objects/NativeArguments.java | 91 ++++++-----
.../nashorn/internal/objects/NativeArray.java | 24 ++-
.../internal/objects/NativeString.java | 25 ++-
.../internal/runtime/JSONFunctions.java | 8 +-
.../internal/runtime/ScriptObject.java | 147 +++++++++---------
.../internal/runtime/arrays/ArrayIndex.java | 130 +++++-----------
.../runtime/arrays/SparseArrayData.java | 8 +-
.../runtime/resources/Messages.properties | 1 +
nashorn/test/examples/array-micro.js | 114 ++++++++++++++
nashorn/test/script/basic/JDK-8012291.js | 48 ++++++
.../test/script/basic/JDK-8012291.js.EXPECTED | 5 +
14 files changed, 367 insertions(+), 251 deletions(-)
create mode 100644 nashorn/test/examples/array-micro.js
create mode 100644 nashorn/test/script/basic/JDK-8012291.js
create mode 100644 nashorn/test/script/basic/JDK-8012291.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
index 16ad2709762..974b5ba81a7 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
@@ -126,7 +126,7 @@ public abstract class FieldObjectCreator extends ObjectCreator {
final T value = valueIter.next();
if (symbol != null && value != null) {
- final int index = ArrayIndex.getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (index < 0) {
putField(method, key, symbol.getFieldIndex(), value);
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
index 153e0367f3f..609fac9b3ff 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
@@ -79,7 +79,7 @@ public class MapCreator {
final String key = keys[i];
final Symbol symbol = symbols[i];
- if (symbol != null && !ArrayIndex.isIndexKey(key)) {
+ if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) {
properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
index d85b31cbae6..2011daebb33 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -33,6 +33,8 @@ import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
+
@ScriptClass("ArrayBufferView")
abstract class ArrayBufferView extends ScriptObject {
@@ -305,11 +307,11 @@ abstract class ArrayBufferView extends ScriptObject {
dst = factory.construct(length);
} else if (arg0 instanceof NativeArray) {
// Constructor(type[] array)
- length = (int) (((NativeArray) arg0).getArray().length() & 0x7fff_ffff);
+ length = lengthToInt(((NativeArray) arg0).getArray().length());
dst = factory.construct(length);
} else {
// Constructor(unsigned long length)
- length = JSType.toInt32(arg0);
+ length = lengthToInt(JSType.toInt64(arg0));
return factory.construct(length);
}
@@ -354,6 +356,13 @@ abstract class ArrayBufferView extends ScriptObject {
}
}
+ private static int lengthToInt(final long length) {
+ if (length > Integer.MAX_VALUE || length < 0) {
+ throw rangeError("inappropriate.array.buffer.length", JSType.toString(length));
+ }
+ return (int) (length & Integer.MAX_VALUE);
+ }
+
protected static Object subarrayImpl(final Object self, final Object begin0, final Object end0) {
final ArrayBufferView arrayView = ((ArrayBufferView)self);
final int elementLength = arrayView.elementLength();
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
index efab674b1df..d92d7fb3ee7 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
@@ -27,7 +27,6 @@ package jdk.nashorn.internal.objects;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
@@ -132,103 +131,103 @@ public final class NativeArguments extends ScriptObject {
@Override
public int getInt(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
}
@Override
public int getInt(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
}
@Override
public int getInt(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
}
@Override
public int getInt(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
}
@Override
public long getLong(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
}
@Override
public long getLong(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
}
@Override
public long getLong(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
}
@Override
public long getLong(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
}
@Override
public double getDouble(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
}
@Override
public double getDouble(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
}
@Override
public double getDouble(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
}
@Override
public double getDouble(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
}
@Override
public Object get(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
}
@Override
public Object get(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
}
@Override
public Object get(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
}
@Override
public Object get(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
}
@Override
public void set(final Object key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -238,7 +237,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final Object key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -248,7 +247,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final Object key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -258,7 +257,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final Object key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -268,7 +267,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final double key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -278,7 +277,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final double key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -288,7 +287,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final double key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -298,7 +297,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final double key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -308,7 +307,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final long key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -318,7 +317,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final long key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -328,7 +327,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final long key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -338,7 +337,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final long key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -348,7 +347,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final int key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -358,7 +357,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final int key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -368,7 +367,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final int key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -378,7 +377,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public void set(final int key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (isMapped(index)) {
namedArgs = namedArgs.set(index, value, strict);
} else {
@@ -388,55 +387,55 @@ public final class NativeArguments extends ScriptObject {
@Override
public boolean has(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.has(key);
}
@Override
public boolean has(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.has(key);
}
@Override
public boolean has(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.has(key);
}
@Override
public boolean has(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.has(key);
}
@Override
public boolean hasOwnProperty(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) || super.hasOwnProperty(key);
}
@Override
public boolean delete(final int key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final boolean success = super.delete(key, strict);
if (success && namedArgs.has(index)) {
setDeleted(index);
@@ -446,7 +445,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public boolean delete(final long key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final boolean success = super.delete(key, strict);
if (success && namedArgs.has(index)) {
setDeleted(index);
@@ -456,7 +455,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public boolean delete(final double key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final boolean success = super.delete(key, strict);
if (success && namedArgs.has(index)) {
setDeleted(index);
@@ -466,7 +465,7 @@ public final class NativeArguments extends ScriptObject {
@Override
public boolean delete(final Object key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final boolean success = super.delete(key, strict);
if (success && namedArgs.has(index)) {
setDeleted(index);
@@ -480,7 +479,7 @@ public final class NativeArguments extends ScriptObject {
*/
@Override
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
- final int index = ArrayIndex.getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0) {
final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
if (!allowed) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
index 9736376bc9b..1898d4c8afa 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -228,7 +228,7 @@ public final class NativeArray extends ScriptObject {
}
// Step 4a
- final int index = ArrayIndex.getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
final long longIndex = ArrayIndex.toLongIndex(index);
// Step 4b
@@ -770,7 +770,7 @@ public final class NativeArray extends ScriptObject {
final NativeArray copy = new NativeArray(0);
for (long n = 0; k < finale; n++, k++) {
- copy.defineOwnProperty((int) n, sobj.get(k));
+ copy.defineOwnProperty(ArrayIndex.getArrayIndex(n), sobj.get(k));
}
return copy;
@@ -835,28 +835,26 @@ public final class NativeArray extends ScriptObject {
final ScriptObject sobj = (ScriptObject) self;
final boolean strict = sobj.isStrictContext();
final long len = JSType.toUint32(sobj.getLength());
+ ArrayData array = sobj.getArray();
if (len > 1) {
// Get only non-missing elements. Missing elements go at the end
// of the sorted array. So, just don't copy these to sort input.
-
final ArrayList src = new ArrayList<>();
- for (int i = 0; i < (int)len; i++) {
- if (sobj.has(i)) {
- src.add(sobj.get(i));
+ for (long i = 0; i < len; i = array.nextIndex(i)) {
+ if (array.has((int) i)) {
+ src.add(array.getObject((int) i));
}
}
final Object[] sorted = sort(src.toArray(), comparefn);
for (int i = 0; i < sorted.length; i++) {
- sobj.set(i, sorted[i], strict);
+ array = array.set(i, sorted[i], strict);
}
// delete missing elements - which are at the end of sorted array
- for (int j = sorted.length; j < (int)len; j++) {
- sobj.delete(j, strict);
- }
+ sobj.setArray(array.delete(sorted.length, len - 1));
}
return sobj;
@@ -906,7 +904,7 @@ public final class NativeArray extends ScriptObject {
final long from = actualStart + k;
if (sobj.has(from)) {
- array.defineOwnProperty((int) k, sobj.get(from));
+ array.defineOwnProperty(ArrayIndex.getArrayIndex(k), sobj.get(from));
}
}
@@ -1143,7 +1141,7 @@ public final class NativeArray extends ScriptObject {
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
final Object r = MAP_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self);
- result.defineOwnProperty((int)index, r);
+ result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r);
return true;
}
@@ -1172,7 +1170,7 @@ public final class NativeArray extends ScriptObject {
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
if ((boolean)FILTER_CALLBACK_INVOKER.invokeExact(callbackfn, thisArg, val, i, self)) {
- result.defineOwnProperty((int)(to++), val);
+ result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val);
}
return true;
}
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
index df4aa1bff38..fda265e6065 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
@@ -29,7 +29,6 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -156,7 +155,7 @@ public final class NativeString extends ScriptObject {
@SuppressWarnings("unused")
private static Object get(final Object self, final Object key) {
final CharSequence cs = JSType.toCharSequence(self);
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0 && index < cs.length()) {
return String.valueOf(cs.charAt(index));
}
@@ -191,7 +190,7 @@ public final class NativeString extends ScriptObject {
// String characters can be accessed with array-like indexing..
@Override
public Object get(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0 && index < value.length()) {
return String.valueOf(value.charAt(index));
}
@@ -284,7 +283,7 @@ public final class NativeString extends ScriptObject {
@Override
public boolean has(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.has(key);
}
@@ -295,19 +294,19 @@ public final class NativeString extends ScriptObject {
@Override
public boolean has(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.has(key);
}
@Override
public boolean has(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.has(key);
}
@Override
public boolean hasOwnProperty(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.hasOwnProperty(key);
}
@@ -318,13 +317,13 @@ public final class NativeString extends ScriptObject {
@Override
public boolean hasOwnProperty(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return isValid(index) || super.hasOwnProperty(key);
}
@@ -335,19 +334,19 @@ public final class NativeString extends ScriptObject {
@Override
public boolean delete(final long key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final Object key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
}
@@ -364,7 +363,7 @@ public final class NativeString extends ScriptObject {
@Override
public Object getOwnPropertyDescriptor(final String key) {
- final int index = ArrayIndex.getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0 && index < value.length()) {
final Global global = Global.instance();
return global.newDataDescriptor(String.valueOf(value.charAt(index)), false, true, false);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
index 33e6ef030ea..d371fbc0cc6 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -25,9 +25,6 @@
package jdk.nashorn.internal.runtime;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
-
import java.lang.invoke.MethodHandle;
import java.util.Iterator;
import jdk.nashorn.internal.ir.LiteralNode;
@@ -37,6 +34,7 @@ import jdk.nashorn.internal.ir.PropertyNode;
import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.parser.JSONParser;
import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
/**
@@ -188,8 +186,8 @@ public final class JSONFunctions {
// add a new property if does not exist already, or else set old property
private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(name);
- if (isValidArrayIndex(index)) {
+ final int index = ArrayIndex.getArrayIndex(name);
+ if (ArrayIndex.isValidArrayIndex(index)) {
// array index key
sobj.defineOwnProperty(index, value);
} else if (sobj.getMap().findProperty(name) != null) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 331687ad3c9..46e39b77407 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -37,8 +37,6 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.SET;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
-import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
@@ -65,6 +63,7 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.objects.AccessorPropertyDescriptor;
import jdk.nashorn.internal.objects.DataPropertyDescriptor;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
@@ -333,7 +332,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable);
}
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -533,21 +532,23 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* from any object in proto chain such as Array.prototype, Object.prototype.
* This method directly sets a particular element value in the current object.
*
- * @param index index key for property
+ * @param index key for property
* @param value value to define
*/
protected final void defineOwnProperty(final int index, final Object value) {
- if (index >= getArray().length()) {
+ assert ArrayIndex.isValidArrayIndex(index) : "invalid array index";
+ final long longIndex = ArrayIndex.toLongIndex(index);
+ if (longIndex >= getArray().length()) {
// make array big enough to hold..
- setArray(getArray().ensure(index));
+ setArray(getArray().ensure(longIndex));
}
setArray(getArray().set(index, value, false));
}
private void checkIntegerKey(final String key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
@@ -557,7 +558,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private void removeArraySlot(final String key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2238,7 +2239,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private int getInt(final int index, final String key) {
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
final FindProperty find = object.findProperty(key, false, false, this);
@@ -2269,7 +2270,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public int getInt(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2281,7 +2282,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public int getInt(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2293,7 +2294,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public int getInt(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2315,7 +2316,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private long getLong(final int index, final String key) {
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
final FindProperty find = object.findProperty(key, false, false, this);
@@ -2346,7 +2347,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public long getLong(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2358,7 +2359,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public long getLong(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2370,7 +2371,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public long getLong(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2392,7 +2393,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private double getDouble(final int index, final String key) {
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
final FindProperty find = object.findProperty(key, false, false, this);
@@ -2423,7 +2424,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public double getDouble(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2435,7 +2436,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public double getDouble(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2447,7 +2448,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public double getDouble(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2469,7 +2470,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private Object get(final int index, final String key) {
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
final FindProperty find = object.findProperty(key, false, false, this);
@@ -2500,7 +2501,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public Object get(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2512,7 +2513,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public Object get(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2524,7 +2525,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public Object get(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -2640,9 +2641,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final Object key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2657,9 +2658,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final Object key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2674,9 +2675,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final Object key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2691,9 +2692,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final Object key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2711,9 +2712,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final double key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2728,9 +2729,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final double key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2745,9 +2746,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final double key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2762,9 +2763,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final double key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2779,9 +2780,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final long key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2796,9 +2797,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final long key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2813,9 +2814,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final long key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2830,9 +2831,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final long key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2847,9 +2848,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final int key, final int value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2864,9 +2865,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final int key, final long value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2881,9 +2882,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final int key, final double value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2898,9 +2899,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final int key, final Object value, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@@ -2915,9 +2916,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean has(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@@ -2932,9 +2933,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean has(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@@ -2949,9 +2950,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean has(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@@ -2966,9 +2967,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean has(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
- if (isValidArrayIndex(index)) {
+ if (ArrayIndex.isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@@ -2983,7 +2984,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean hasOwnProperty(final Object key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (getArray().has(index)) {
return true;
@@ -2996,7 +2997,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean hasOwnProperty(final int key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (getArray().has(index)) {
return true;
@@ -3009,7 +3010,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean hasOwnProperty(final long key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (getArray().has(index)) {
return true;
@@ -3022,7 +3023,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean hasOwnProperty(final double key) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
if (getArray().has(index)) {
return true;
@@ -3035,7 +3036,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean delete(final int key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -3051,7 +3052,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean delete(final long key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -3067,7 +3068,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean delete(final double key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
@@ -3083,7 +3084,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public boolean delete(final Object key, final boolean strict) {
- final int index = getArrayIndexNoThrow(key);
+ final int index = ArrayIndex.getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java
index 531c56b50f8..f59229c40ec 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java
@@ -44,7 +44,7 @@ public final class ArrayIndex {
/**
* Fast conversion of non-negative integer string to long.
* @param key Key as a string.
- * @return long value of string or -1.
+ * @return long value of string or {@code -1} if string does not represent a valid index.
*/
private static long fromString(final String key) {
long value = 0;
@@ -52,7 +52,7 @@ public final class ArrayIndex {
// Check for empty string or leading 0
if (length == 0 || (length > 1 && key.charAt(0) == '0')) {
- return -1;
+ return INVALID_ARRAY_INDEX;
}
// Fast toNumber.
@@ -61,7 +61,7 @@ public final class ArrayIndex {
// If not a digit.
if (digit < '0' || digit > '9') {
- return -1;
+ return INVALID_ARRAY_INDEX;
}
// Insert digit.
@@ -69,7 +69,7 @@ public final class ArrayIndex {
// Check for overflow (need to catch before wrap around.)
if (value > MAX_ARRAY_INDEX) {
- return -1;
+ return INVALID_ARRAY_INDEX;
}
}
@@ -81,136 +81,78 @@ public final class ArrayIndex {
* routine needs to perform quickly since all keys are tested with it.
*
* @param key key to check for array index
- * @return valid array index, or negative value if not valid
+ * @return the array index, or {@code -1} if {@code key} does not represent a valid index.
+ * Note that negative return values other than {@code -1} are considered valid and can be converted to
+ * the actual index using {@link #toLongIndex(int)}.
*/
- public static int getArrayIndexNoThrow(final Object key) {
+ public static int getArrayIndex(final Object key) {
if (key instanceof Integer) {
- return getArrayIndexNoThrow(((Integer)key).intValue());
+ return getArrayIndex(((Integer) key).intValue());
} else if (key instanceof Number) {
- return getArrayIndexNoThrow(((Number)key).doubleValue());
+ return getArrayIndex(((Number) key).doubleValue());
} else if (key instanceof String) {
- return (int)fromString((String)key);
+ return (int)fromString((String) key);
} else if (key instanceof ConsString) {
return (int)fromString(key.toString());
}
- return -1;
+ return INVALID_ARRAY_INDEX;
}
/**
- * Returns a valid array index in an int, if the object represents one
+ * Returns a valid array index in an int, if the long represents one.
*
* @param key key to check
- * @return array index for key
- * @throws InvalidArrayIndexException if not a valid array index key
+ * @return the array index, or {@code -1} if long is not a valid array index.
+ * Note that negative return values other than {@code -1} are considered valid and can be converted to
+ * the actual index using {@link #toLongIndex(int)}.
*/
- public static int getArrayIndex(final Object key) throws InvalidArrayIndexException {
- final int index = getArrayIndexNoThrow(key);
- if (index != -1) {
- return index;
- }
-
- throw new InvalidArrayIndexException(key);
- }
-
- /**
- * Returns a valid array index in an int, if the long represents one
- *
- * @param key key to check
- * @return valid index or a negative value if long is not a valid array index
- */
- public static int getArrayIndexNoThrow(final long key) {
+ public static int getArrayIndex(final long key) {
if (key >= 0 && key <= MAX_ARRAY_INDEX) {
return (int)key;
}
- return -1;
- }
-
- /**
- * Returns a valid array index in an int, if the long represents one
- *
- * @param key key to check
- * @return valid index for the long
- * @throws InvalidArrayIndexException if long is not a valid array index
- */
- public static int getArrayIndex(final long key) throws InvalidArrayIndexException {
- final int index = getArrayIndexNoThrow(key);
- if (index != -1) {
- return index;
- }
-
- throw new InvalidArrayIndexException(key);
+ return INVALID_ARRAY_INDEX;
}
/**
- * Return a valid index for this double, if it represents one
+ * Return a valid index for this double, if it represents one.
*
* Doubles that aren't representable exactly as longs/ints aren't working
* array indexes, however, array[1.1] === array["1.1"] in JavaScript.
*
* @param key the key to check
- * @return the array index this double represents or a negative value if this isn't an index
+ * @return the array index this double represents or {@code -1} if this isn't a valid index.
+ * Note that negative return values other than {@code -1} are considered valid and can be converted to
+ * the actual index using {@link #toLongIndex(int)}.
*/
- public static int getArrayIndexNoThrow(final double key) {
+ public static int getArrayIndex(final double key) {
if (JSType.isRepresentableAsInt(key)) {
final int intKey = (int)key;
if (intKey >= 0) {
return intKey;
}
} else if (JSType.isRepresentableAsLong(key)) {
- return getArrayIndexNoThrow((long)key);
+ return getArrayIndex((long) key);
}
- return -1;
+ return INVALID_ARRAY_INDEX;
}
- /**
- * Return a valid array index for this double, if it represents one
- *
- * Doubles that aren't representable exactly as longs/ints aren't working
- * array indexes, however, array[1.1] === array["1.1"] in JavaScript.
- *
- * @param key the key to check
- * @return the array index this double represents
- * @throws InvalidArrayIndexException if this isn't an array index
- */
- public static int getArrayIndex(final double key) throws InvalidArrayIndexException {
- final int index = getArrayIndexNoThrow(key);
- if (index != -1) {
- return index;
- }
-
- throw new InvalidArrayIndexException(key);
- }
/**
- * Return a valid array index for this string, if it represents one
+ * Return a valid array index for this string, if it represents one.
*
* @param key the key to check
- * @return the array index this string represents or a negative value if this isn't an index
+ * @return the array index this string represents or {@code -1} if this isn't a valid index.
+ * Note that negative return values other than {@code -1} are considered valid and can be converted to
+ * the actual index using {@link #toLongIndex(int)}.
*/
- public static int getArrayIndexNoThrow(final String key) {
+ public static int getArrayIndex(final String key) {
return (int)fromString(key);
}
- /**
- * Return a valid array index for this string, if it represents one
- *
- * @param key the key to check
- * @return the array index this string represents
- * @throws InvalidArrayIndexException if the string isn't an array index
- */
- public static int getArrayIndex(final String key) throws InvalidArrayIndexException {
- final int index = getArrayIndexNoThrow(key);
- if (index != -1) {
- return index;
- }
-
- throw new InvalidArrayIndexException(key);
- }
-
/**
* Check whether an index is valid as an array index. This check only tests if
* it is the special "invalid array index" type, not if it is e.g. less than zero
@@ -226,7 +168,7 @@ public final class ArrayIndex {
/**
* Convert an index to a long value. This basically amounts to ANDing it
* with {@link JSType#MAX_UINT}, as the maximum array index in JavaScript
- * is 0xffffffff
+ * is 0xfffffffe
*
* @param index index to convert to long form
* @return index as uint32 in a long
@@ -236,14 +178,14 @@ public final class ArrayIndex {
}
/**
- * Check whether a key string can be used as a valid numeric array index in
- * JavaScript
+ * Check whether a key string represents a valid array index in JavaScript and is small enough
+ * to fit into a positive int.
*
* @param key the key
- * @return true if key works as a valid numeric array index
+ * @return true if key works as a valid int array index
*/
- public static boolean isIndexKey(final String key) {
- return ArrayIndex.getArrayIndexNoThrow(key) >= 0;
+ public static boolean isIntArrayIndex(final String key) {
+ return getArrayIndex(key) >= 0;
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
index 04ac661f8b7..fd52f22db83 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java
@@ -61,13 +61,15 @@ class SparseArrayData extends ArrayData {
@Override
public Object[] asObjectArray() {
- final Object[] objArray = new Object[Math.min((int) length(), Integer.MAX_VALUE)];
+ final int length = (int) Math.min(length(), Integer.MAX_VALUE);
+ final int underlyingLength = (int) Math.min(length, underlying.length());
+ final Object[] objArray = new Object[length];
- for (int i = 0; i < underlying.length(); i++) {
+ for (int i = 0; i < underlyingLength; i++) {
objArray[i] = underlying.getObject(i);
}
- Arrays.fill(objArray, (int) underlying.length(), objArray.length, ScriptRuntime.UNDEFINED);
+ Arrays.fill(objArray, underlyingLength, length, ScriptRuntime.UNDEFINED);
for (final Map.Entry entry : sparseMap.entrySet()) {
final long key = entry.getKey();
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index 9dc0ffcfe3f..f08f383daca 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -129,6 +129,7 @@ type.error.method.not.constructor=Java method {0} can't be used as a constructor
type.error.env.not.object=$ENV must be an Object.
type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
range.error.inappropriate.array.length=inappropriate array length: {0}
+range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
range.error.invalid.precision=precision argument toPrecision() must be in [1, 21]
range.error.invalid.radix=radix argument must be in [2, 36]
diff --git a/nashorn/test/examples/array-micro.js b/nashorn/test/examples/array-micro.js
new file mode 100644
index 00000000000..075e78d8c30
--- /dev/null
+++ b/nashorn/test/examples/array-micro.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+function bench(name, func) {
+ var start = Date.now();
+ for (var iter = 0; iter < 5e6; iter++) {
+ func();
+ }
+ print((Date.now() - start) + "\t" + name);
+}
+
+bench("[]", function() {
+ [];
+ [];
+ [];
+});
+
+bench("[1, 2, 3]", function() {
+ [1, 2, 3];
+ [1, 2, 3];
+ [1, 2, 3];
+});
+
+bench("[1 .. 20]", function() {
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
+});
+
+bench("new Array()", function() {
+ new Array();
+ new Array();
+ new Array();
+});
+
+
+bench("new Array(1, 2, 3)", function() {
+ new Array(1, 2, 3);
+ new Array(1, 2, 3);
+ new Array(1, 2, 3);
+});
+
+bench("new Array(10)", function() {
+ new Array(10);
+ new Array(10);
+ new Array(10);
+});
+
+var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+bench("get", function() {
+ array[0];
+ array[3];
+ array[6];
+});
+
+bench("set", function() {
+ array[0] = 0;
+ array[3] = 3;
+ array[6] = 6;
+});
+
+var all = function(e) { return true; };
+var none = function(e) { return false; };
+
+bench("filter all", function() {
+ array.filter(all);
+});
+
+bench("filter none", function() {
+ array.filter(none);
+});
+
+var up = function(a, b) { return a > b ? 1 : -1; };
+var down = function(a, b) { return a < b ? 1 : -1; };
+
+bench("sort up", function() {
+ [1, 2, 3, 4].sort(up);
+});
+
+bench("sort down", function() {
+ [1, 2, 3, 4].sort(down);
+});
+
diff --git a/nashorn/test/script/basic/JDK-8012291.js b/nashorn/test/script/basic/JDK-8012291.js
new file mode 100644
index 00000000000..b902df4788a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8012291.js
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8012291: NativeArray is inconsistent in using long for length and index in some places and int for the same in other places
+ *
+ * @test
+ * @run
+ */
+
+// Make sure JSON parser correctly handles large array keys
+var obj = JSON.parse('{"4294967294": 1}');
+print(obj[4294967294]);
+
+// Make sure Array.prototype.sort handles large index correctly
+obj.length = 4294967295;
+Array.prototype.sort.call(obj);
+print(obj[0]);
+print(obj[4294967294]);
+print(obj.length);
+
+var arr = [];
+arr[4294967294] = 1;
+try {
+ new Int32Array(arr);
+} catch (e) {
+ print(e);
+}
diff --git a/nashorn/test/script/basic/JDK-8012291.js.EXPECTED b/nashorn/test/script/basic/JDK-8012291.js.EXPECTED
new file mode 100644
index 00000000000..7d723f1d6cb
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8012291.js.EXPECTED
@@ -0,0 +1,5 @@
+1
+1
+undefined
+4294967295
+RangeError: inappropriate array buffer length: 4294967295
From 6b2c468c35edc2e568bf0ec93676822a93bd1860 Mon Sep 17 00:00:00 2001
From: Alejandro Murillo
Date: Fri, 7 Jun 2013 09:33:01 -0700
Subject: [PATCH 024/136] 8016078: new hotspot build - hs25-b37
Reviewed-by: jcoomes
---
hotspot/make/hotspot_version | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index c88d7286682..e16392a9273 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=36
+HS_BUILD_NUMBER=37
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
From 75e22e5c54ea957ba5f3aba2b1a6f3e6d0032dfa Mon Sep 17 00:00:00 2001
From: Patrick Reinhart
Date: Fri, 7 Jun 2013 10:26:29 -0700
Subject: [PATCH 025/136] 8013810: PrintServiceLookup.lookupPrintServices()
does not return consistent result
Reviewed-by: prr, jgodinez
---
.../sun/print/UnixPrintServiceLookup.java | 25 +++++++-
.../PrintServiceLookup/GetPrintServices.java | 58 +++++++++++++++++++
2 files changed, 82 insertions(+), 1 deletion(-)
create mode 100644 jdk/test/javax/print/PrintServiceLookup/GetPrintServices.java
diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java
index 9fcbb86c756..c682634b7b6 100644
--- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java
@@ -362,10 +362,33 @@ public class UnixPrintServiceLookup extends PrintServiceLookup
*/
private PrintService getServiceByName(PrinterName nameAttr) {
String name = nameAttr.getValue();
- PrintService printer = null;
if (name == null || name.equals("") || !checkPrinterName(name)) {
return null;
}
+ /* check is all printers are already available */
+ if (printServices != null) {
+ for (PrintService printService : printServices) {
+ if (printService.getName().equals(name)) {
+ return printService;
+ }
+ }
+ }
+ /* take CUPS into account first */
+ if (CUPSPrinter.isCupsRunning()) {
+ try {
+ return new IPPPrintService(name,
+ new URL("http://"+
+ CUPSPrinter.getServer()+":"+
+ CUPSPrinter.getPort()+"/"+
+ name));
+ } catch (Exception e) {
+ IPPPrintService.debug_println(debugPrefix+
+ " getServiceByName Exception "+
+ e);
+ }
+ }
+ /* fallback if nothing not having a printer at this point */
+ PrintService printer = null;
if (isMac() || isSysV()) {
printer = getNamedPrinterNameSysV(name);
} else {
diff --git a/jdk/test/javax/print/PrintServiceLookup/GetPrintServices.java b/jdk/test/javax/print/PrintServiceLookup/GetPrintServices.java
new file mode 100644
index 00000000000..f8373a6383a
--- /dev/null
+++ b/jdk/test/javax/print/PrintServiceLookup/GetPrintServices.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+import javax.print.attribute.AttributeSet;
+import javax.print.attribute.HashAttributeSet;
+import javax.print.attribute.standard.PrinterName;
+
+/*
+ * @test
+ * @bug 8013810
+ * @summary Test that print service returned without filter are of the same class as with name filter
+ */
+public class GetPrintServices {
+
+ public static void main(String[] args) throws Exception {
+ for (PrintService service : PrintServiceLookup.lookupPrintServices(null, null)) {
+ String serviceName = service.getName();
+ PrintService serviceByName = lookupByName(serviceName);
+ if (!service.equals(serviceByName)) {
+ throw new RuntimeException("NOK " + serviceName
+ + " expected: " + service.getClass().getName()
+ + " got: " + serviceByName.getClass().getName());
+ }
+ }
+ System.out.println("Test PASSED");
+ }
+
+ private static PrintService lookupByName(String name) {
+ AttributeSet attributes = new HashAttributeSet();
+ attributes.add(new PrinterName(name, null));
+ for (PrintService service : PrintServiceLookup.lookupPrintServices(null, attributes)) {
+ return service;
+ }
+ return null;
+ }
+}
From a476a195ac9d7df2be8c2e45558af6692f9ccb22 Mon Sep 17 00:00:00 2001
From: Jonathan Gibbons
Date: Fri, 7 Jun 2013 15:35:38 -0700
Subject: [PATCH 026/136] 8016193: Fix OAC issue in langtools docs
Reviewed-by: darcy
---
.../share/classes/com/sun/javadoc/Tag.java | 32 ++++++++++++-------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/langtools/src/share/classes/com/sun/javadoc/Tag.java b/langtools/src/share/classes/com/sun/javadoc/Tag.java
index 2e129f50505..1d8c5907be2 100644
--- a/langtools/src/share/classes/com/sun/javadoc/Tag.java
+++ b/langtools/src/share/classes/com/sun/javadoc/Tag.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,36 +54,44 @@ public interface Tag {
* {@link}
, the curly brackets
* are not part of the name, so in this example the name
* would be simply @link
.
+ *
+ * @return the name of this tag
*/
String name();
/**
* Return the containing {@link Doc} of this Tag element.
+ *
+ * @return the containing {@link Doc} of this Tag element
*/
Doc holder();
/**
* Return the kind of this tag.
- * similar or synonymous tags. For most tags,
+ * For most tags,
* kind() == name()
;
* the following table lists those cases where there is more
* than one tag of a given kind:
*
- *
- * kind() name()
- * @throws @throws
- * @throws @exception
- * @see @see
- * @see @link
- * @see @linkplain
- * @serial @serial
- * @serial @serialData
+ *
+ * {@code kind() } {@code name() }
+ * {@code @throws } {@code @throws }
+ * {@code @throws } {@code @exception }
+ * {@code @see } {@code @see }
+ * {@code @see } {@code @link }
+ * {@code @see } {@code @linkplain }
+ * {@code @serial } {@code @serial }
+ * {@code @serial } {@code @serialData }
*
+ *
+ * @return the kind of this tag.
*/
String kind();
/**
- * Return the text of this tag, that is, portion beyond tag name.
+ * Return the text of this tag, that is, the portion beyond tag name.
+ *
+ * @return the text of this tag
*/
String text();
From 3f6b61d75e2011b347538b233d2fd60f0a588811 Mon Sep 17 00:00:00 2001
From: Bhavesh Patel
Date: Fri, 7 Jun 2013 16:12:04 -0700
Subject: [PATCH 027/136] 8015997: Additional improvement in Javadoc framing
Reviewed-by: jjg
---
.../sun/tools/doclets/formats/html/markup/HtmlWriter.java | 3 ++-
.../test/com/sun/javadoc/testJavascript/TestJavascript.java | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
index 2c45b1953ed..5369733893b 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java
@@ -314,7 +314,8 @@ public class HtmlWriter {
" if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + DocletConstants.NL +
" targetPage = \"undefined\";" + DocletConstants.NL +
" function validURL(url) {" + DocletConstants.NL +
- " if (!(url.indexOf(\".html\") == url.length - 5))" + DocletConstants.NL +
+ " var pos = url.indexOf(\".html\");" + DocletConstants.NL +
+ " if (pos == -1 || pos != url.length - 5)" + DocletConstants.NL +
" return false;" + DocletConstants.NL +
" var allowNumber = false;" + DocletConstants.NL +
" var allowSep = false;" + DocletConstants.NL +
diff --git a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
index 816c9c15609..763566a03ac 100644
--- a/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
+++ b/langtools/test/com/sun/javadoc/testJavascript/TestJavascript.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4665566 4855876 7025314 8012375
+ * @bug 4665566 4855876 7025314 8012375 8015997
* @summary Verify that the output has the right javascript.
* @author jamieh
* @library ../lib/
@@ -56,7 +56,8 @@ public class TestJavascript extends JavadocTester {
" if (targetPage.indexOf(\":\") != -1 || (targetPage != \"\" && !validURL(targetPage)))" + NL +
" targetPage = \"undefined\";" + NL +
" function validURL(url) {" + NL +
- " if (!(url.indexOf(\".html\") == url.length - 5))" + NL +
+ " var pos = url.indexOf(\".html\");" + NL +
+ " if (pos == -1 || pos != url.length - 5)" + NL +
" return false;" + NL +
" var allowNumber = false;" + NL +
" var allowSep = false;" + NL +
From 5b2339a7a286d5bec22e8863579923798633710e Mon Sep 17 00:00:00 2001
From: Morris Meyer
Date: Fri, 7 Jun 2013 16:46:37 -0700
Subject: [PATCH 028/136] 8008407: remove SPARC V8 support
Removed most of the SPARC V8 instructions
Reviewed-by: kvn, twisti
---
hotspot/src/cpu/sparc/vm/assembler_sparc.hpp | 95 +---
.../cpu/sparc/vm/assembler_sparc.inline.hpp | 28 --
.../cpu/sparc/vm/c1_LIRAssembler_sparc.cpp | 70 +--
.../cpu/sparc/vm/c1_MacroAssembler_sparc.cpp | 6 +-
hotspot/src/cpu/sparc/vm/c2_init_sparc.cpp | 1 -
.../src/cpu/sparc/vm/disassembler_sparc.hpp | 3 +-
hotspot/src/cpu/sparc/vm/globals_sparc.hpp | 3 -
.../src/cpu/sparc/vm/interp_masm_sparc.cpp | 6 +-
.../src/cpu/sparc/vm/macroAssembler_sparc.cpp | 414 ++----------------
.../src/cpu/sparc/vm/macroAssembler_sparc.hpp | 41 --
.../sparc/vm/macroAssembler_sparc.inline.hpp | 65 +--
hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp | 14 +-
hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp | 3 +-
hotspot/src/cpu/sparc/vm/register_sparc.hpp | 2 -
.../src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 2 +-
hotspot/src/cpu/sparc/vm/sparc.ad | 7 +-
.../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 150 +------
.../src/cpu/sparc/vm/stubRoutines_sparc.cpp | 4 -
.../src/cpu/sparc/vm/stubRoutines_sparc.hpp | 32 --
.../sparc/vm/templateInterpreter_sparc.cpp | 2 +-
.../src/cpu/sparc/vm/templateTable_sparc.cpp | 60 +--
hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp | 25 +-
hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp | 4 -
.../linux_sparc/vm/assembler_linux_sparc.cpp | 47 --
.../vm/atomic_linux_sparc.inline.hpp | 1 -
.../vm/assembler_solaris_sparc.cpp | 61 ---
.../vm/atomic_solaris_sparc.inline.hpp | 13 -
.../os_cpu/solaris_sparc/vm/solaris_sparc.il | 17 -
hotspot/src/share/vm/runtime/arguments.cpp | 15 -
29 files changed, 135 insertions(+), 1056 deletions(-)
delete mode 100644 hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp
delete mode 100644 hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp
diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
index 5541eb865b2..3192a855569 100644
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
@@ -57,7 +57,6 @@ class Assembler : public AbstractAssembler {
fbp_op2 = 5,
br_op2 = 2,
bp_op2 = 1,
- cb_op2 = 7, // V8
sethi_op2 = 4
};
@@ -145,7 +144,6 @@ class Assembler : public AbstractAssembler {
ldsh_op3 = 0x0a,
ldx_op3 = 0x0b,
- ldstub_op3 = 0x0d,
stx_op3 = 0x0e,
swap_op3 = 0x0f,
@@ -163,15 +161,6 @@ class Assembler : public AbstractAssembler {
prefetch_op3 = 0x2d,
-
- ldc_op3 = 0x30,
- ldcsr_op3 = 0x31,
- lddc_op3 = 0x33,
- stc_op3 = 0x34,
- stcsr_op3 = 0x35,
- stdcq_op3 = 0x36,
- stdc_op3 = 0x37,
-
casa_op3 = 0x3c,
casxa_op3 = 0x3e,
@@ -574,17 +563,11 @@ class Assembler : public AbstractAssembler {
static void vis3_only() { assert( VM_Version::has_vis3(), "This instruction only works on SPARC with VIS3"); }
// instruction only in v9
- static void v9_only() { assert( VM_Version::v9_instructions_work(), "This instruction only works on SPARC V9"); }
-
- // instruction only in v8
- static void v8_only() { assert( VM_Version::v8_instructions_work(), "This instruction only works on SPARC V8"); }
+ static void v9_only() { } // do nothing
// instruction deprecated in v9
static void v9_dep() { } // do nothing for now
- // some float instructions only exist for single prec. on v8
- static void v8_s_only(FloatRegisterImpl::Width w) { if (w != FloatRegisterImpl::S) v9_only(); }
-
// v8 has no CC field
static void v8_no_cc(CC cc) { if (cc) v9_only(); }
@@ -730,11 +713,6 @@ public:
inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none );
inline void bp( Condition c, bool a, CC cc, Predict p, Label& L );
- // pp 121 (V8)
-
- inline void cb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none );
- inline void cb( Condition c, bool a, Label& L );
-
// pp 149
inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
@@ -775,8 +753,8 @@ public:
// pp 157
- void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); }
- void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { v8_no_cc(cc); emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); }
+ void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); }
+ void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); }
// pp 159
@@ -794,21 +772,11 @@ public:
// pp 162
- void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); }
+ void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); }
- void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); }
+ void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); }
- // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fnegs is the only instruction available
- // on v8 to do negation of single, double and quad precision floats.
-
- void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x05) | fs2(sd, w)); }
-
- void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v8_s_only(w); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); }
-
- // page 144 sparc v8 architecture (double prec works on v8 if the source and destination registers are the same). fabss is the only instruction available
- // on v8 to do abs operation on single/double/quad precision floats.
-
- void fabs( FloatRegisterImpl::Width w, FloatRegister sd ) { if (VM_Version::v9_instructions_work()) emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(sd, w)); else emit_int32( op(arith_op) | fd(sd, w) | op3(fpop1_op3) | opf(0x09) | fs2(sd, w)); }
+ void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); }
// pp 163
@@ -839,11 +807,6 @@ public:
void impdep1( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); }
void impdep2( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); }
- // pp 149 (v8)
-
- void cpop1( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep1_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); }
- void cpop2( int opc, int cr1, int cr2, int crd ) { v8_only(); emit_int32( op(arith_op) | fcn(crd) | op3(impdep2_op3) | u_field(cr1, 18, 14) | opf(opc) | u_field(cr2, 4, 0)); }
-
// pp 170
void jmpl( Register s1, Register s2, Register d );
@@ -860,16 +823,6 @@ public:
inline void ldxfsr( Register s1, Register s2 );
inline void ldxfsr( Register s1, int simm13a);
- // pp 94 (v8)
-
- inline void ldc( Register s1, Register s2, int crd );
- inline void ldc( Register s1, int simm13a, int crd);
- inline void lddc( Register s1, Register s2, int crd );
- inline void lddc( Register s1, int simm13a, int crd);
- inline void ldcsr( Register s1, Register s2, int crd );
- inline void ldcsr( Register s1, int simm13a, int crd);
-
-
// 173
void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
@@ -910,18 +863,6 @@ public:
void lduwa( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
- void ldda( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
- void ldda( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
-
- // pp 179
-
- inline void ldstub( Register s1, Register s2, Register d );
- inline void ldstub( Register s1, int simm13a, Register d);
-
- // pp 180
-
- void ldstuba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
- void ldstuba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
// pp 181
@@ -992,11 +933,6 @@ public:
void smulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); }
void smulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
- // pp 199
-
- void mulscc( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | rs2(s2) ); }
- void mulscc( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(mulscc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
-
// pp 201
void nop() { emit_int32( op(branch_op) | op2(sethi_op2) ); }
@@ -1116,17 +1052,6 @@ public:
void stda( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); }
void stda( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
- // pp 97 (v8)
-
- inline void stc( int crd, Register s1, Register s2 );
- inline void stc( int crd, Register s1, int simm13a);
- inline void stdc( int crd, Register s1, Register s2 );
- inline void stdc( int crd, Register s1, int simm13a);
- inline void stcsr( int crd, Register s1, Register s2 );
- inline void stcsr( int crd, Register s1, int simm13a);
- inline void stdcq( int crd, Register s1, Register s2 );
- inline void stdcq( int crd, Register s1, int simm13a);
-
// pp 230
void sub( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); }
@@ -1153,20 +1078,16 @@ public:
void taddcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); }
void taddcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
- void taddcctv( Register s1, Register s2, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | rs2(s2) ); }
- void taddcctv( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(taddcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
// pp 235
void tsubcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); }
void tsubcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
- void tsubcctv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | rs2(s2) ); }
- void tsubcctv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcctv_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); }
// pp 237
- void trap( Condition c, CC cc, Register s1, Register s2 ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); }
- void trap( Condition c, CC cc, Register s1, int trapa ) { v8_no_cc(cc); emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); }
+ void trap( Condition c, CC cc, Register s1, Register s2 ) { emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); }
+ void trap( Condition c, CC cc, Register s1, int trapa ) { emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); }
// simple uncond. trap
void trap( int trapa ) { trap( always, icc, G0, trapa ); }
diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
index 23904f9e1f2..ade531a3f82 100644
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
@@ -63,9 +63,6 @@ inline void Assembler::fb( Condition c, bool a, Label& L ) { fb(c, a, target(L))
inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt ) { v9_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(fbp_op2) | branchcc(cc) | predict(p) | wdisp(intptr_t(d), intptr_t(pc()), 19), rt); has_delay_slot(); }
inline void Assembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L ) { fbp(c, a, cc, p, target(L)); }
-inline void Assembler::cb( Condition c, bool a, address d, relocInfo::relocType rt ) { v8_only(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(cb_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
-inline void Assembler::cb( Condition c, bool a, Label& L ) { cb(c, a, target(L)); }
-
inline void Assembler::br( Condition c, bool a, address d, relocInfo::relocType rt ) { v9_dep(); cti(); emit_data( op(branch_op) | annul(a) | cond(c) | op2(br_op2) | wdisp(intptr_t(d), intptr_t(pc()), 22), rt); has_delay_slot(); }
inline void Assembler::br( Condition c, bool a, Label& L ) { br(c, a, target(L)); }
@@ -88,18 +85,9 @@ inline void Assembler::jmpl( Register s1, int simm13a, Register d, RelocationHol
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13), rspec); }
-inline void Assembler::ldfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::ldfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
inline void Assembler::ldxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(ldfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::ldc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::ldc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::lddc( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::lddc( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(lddc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::ldcsr( Register s1, Register s2, int crd) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::ldcsr( Register s1, int simm13a, int crd) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(ldcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-
inline void Assembler::ldsb( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldsb( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldsb_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
@@ -119,9 +107,6 @@ inline void Assembler::ldx( Register s1, int simm13a, Register d) { v9_only();
inline void Assembler::ldd( Register s1, Register s2, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::ldd( Register s1, int simm13a, Register d) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(ldd_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::ldstub( Register s1, Register s2, Register d) { emit_int32( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::ldstub( Register s1, int simm13a, Register d) { emit_data( op(ldst_op) | rd(d) | op3(ldstub_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-
inline void Assembler::rett( Register s1, Register s2 ) { cti(); emit_int32( op(arith_op) | op3(rett_op3) | rs1(s1) | rs2(s2)); has_delay_slot(); }
inline void Assembler::rett( Register s1, int simm13a, relocInfo::relocType rt) { cti(); emit_data( op(arith_op) | op3(rett_op3) | rs1(s1) | immed(true) | simm(simm13a, 13), rt); has_delay_slot(); }
@@ -132,8 +117,6 @@ inline void Assembler::sethi( int imm22a, Register d, RelocationHolder const& rs
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2) { emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | rs2(s2) ); }
inline void Assembler::stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a) { emit_data( op(ldst_op) | fd(d, w) | alt_op3(stf_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::stfsr( Register s1, Register s2) { v9_dep(); emit_int32( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::stfsr( Register s1, int simm13a) { v9_dep(); emit_data( op(ldst_op) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
inline void Assembler::stxfsr( Register s1, Register s2) { v9_only(); emit_int32( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::stxfsr( Register s1, int simm13a) { v9_only(); emit_data( op(ldst_op) | rd(G1) | op3(stfsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
@@ -152,17 +135,6 @@ inline void Assembler::stx( Register d, Register s1, int simm13a) { v9_only();
inline void Assembler::std( Register d, Register s1, Register s2) { v9_dep(); assert(d->is_even(), "not even"); emit_int32( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | rs2(s2) ); }
inline void Assembler::std( Register d, Register s1, int simm13a) { v9_dep(); assert(d->is_even(), "not even"); emit_data( op(ldst_op) | rd(d) | op3(std_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-// v8 p 99
-
-inline void Assembler::stc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::stc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::stdc( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::stdc( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdc_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::stcsr( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::stcsr( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stcsr_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-inline void Assembler::stdcq( int crd, Register s1, Register s2) { v8_only(); emit_int32( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | rs2(s2) ); }
-inline void Assembler::stdcq( int crd, Register s1, int simm13a) { v8_only(); emit_data( op(ldst_op) | fcn(crd) | op3(stdcq_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
-
// pp 231
inline void Assembler::swap( Register s1, Register s2, Register d) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); }
diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
index 7c4c54ea37f..1cbc5c41316 100644
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
@@ -597,13 +597,6 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) {
__ sra(Rdividend, 31, Rscratch);
__ wry(Rscratch);
- if (!VM_Version::v9_instructions_work()) {
- // v9 doesn't require these nops
- __ nop();
- __ nop();
- __ nop();
- __ nop();
- }
add_debug_info_for_div0_here(op->info());
@@ -652,10 +645,6 @@ void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
case lir_cond_lessEqual: acond = (is_unordered ? Assembler::f_unorderedOrLessOrEqual : Assembler::f_lessOrEqual); break;
case lir_cond_greaterEqual: acond = (is_unordered ? Assembler::f_unorderedOrGreaterOrEqual: Assembler::f_greaterOrEqual); break;
default : ShouldNotReachHere();
- };
-
- if (!VM_Version::v9_instructions_work()) {
- __ nop();
}
__ fb( acond, false, Assembler::pn, *(op->label()));
} else {
@@ -725,9 +714,6 @@ void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
Label L;
// result must be 0 if value is NaN; test by comparing value to itself
__ fcmp(FloatRegisterImpl::S, Assembler::fcc0, rsrc, rsrc);
- if (!VM_Version::v9_instructions_work()) {
- __ nop();
- }
__ fb(Assembler::f_unordered, true, Assembler::pn, L);
__ delayed()->st(G0, addr); // annuled if contents of rsrc is not NaN
__ ftoi(FloatRegisterImpl::S, rsrc, rsrc);
@@ -1909,7 +1895,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
switch (code) {
case lir_add: __ add (lreg, rreg, res); break;
case lir_sub: __ sub (lreg, rreg, res); break;
- case lir_mul: __ mult (lreg, rreg, res); break;
+ case lir_mul: __ mulx (lreg, rreg, res); break;
default: ShouldNotReachHere();
}
}
@@ -1924,7 +1910,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
switch (code) {
case lir_add: __ add (lreg, simm13, res); break;
case lir_sub: __ sub (lreg, simm13, res); break;
- case lir_mul: __ mult (lreg, simm13, res); break;
+ case lir_mul: __ mulx (lreg, simm13, res); break;
default: ShouldNotReachHere();
}
} else {
@@ -1936,7 +1922,7 @@ void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr
switch (code) {
case lir_add: __ add (lreg, (int)con, res); break;
case lir_sub: __ sub (lreg, (int)con, res); break;
- case lir_mul: __ mult (lreg, (int)con, res); break;
+ case lir_mul: __ mulx (lreg, (int)con, res); break;
default: ShouldNotReachHere();
}
}
@@ -3234,48 +3220,26 @@ void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type,
Register base = mem_addr->base()->as_register();
if (src->is_register() && dest->is_address()) {
// G4 is high half, G5 is low half
- if (VM_Version::v9_instructions_work()) {
- // clear the top bits of G5, and scale up G4
- __ srl (src->as_register_lo(), 0, G5);
- __ sllx(src->as_register_hi(), 32, G4);
- // combine the two halves into the 64 bits of G4
- __ or3(G4, G5, G4);
- null_check_offset = __ offset();
- if (idx == noreg) {
- __ stx(G4, base, disp);
- } else {
- __ stx(G4, base, idx);
- }
+ // clear the top bits of G5, and scale up G4
+ __ srl (src->as_register_lo(), 0, G5);
+ __ sllx(src->as_register_hi(), 32, G4);
+ // combine the two halves into the 64 bits of G4
+ __ or3(G4, G5, G4);
+ null_check_offset = __ offset();
+ if (idx == noreg) {
+ __ stx(G4, base, disp);
} else {
- __ mov (src->as_register_hi(), G4);
- __ mov (src->as_register_lo(), G5);
- null_check_offset = __ offset();
- if (idx == noreg) {
- __ std(G4, base, disp);
- } else {
- __ std(G4, base, idx);
- }
+ __ stx(G4, base, idx);
}
} else if (src->is_address() && dest->is_register()) {
null_check_offset = __ offset();
- if (VM_Version::v9_instructions_work()) {
- if (idx == noreg) {
- __ ldx(base, disp, G5);
- } else {
- __ ldx(base, idx, G5);
- }
- __ srax(G5, 32, dest->as_register_hi()); // fetch the high half into hi
- __ mov (G5, dest->as_register_lo()); // copy low half into lo
+ if (idx == noreg) {
+ __ ldx(base, disp, G5);
} else {
- if (idx == noreg) {
- __ ldd(base, disp, G4);
- } else {
- __ ldd(base, idx, G4);
- }
- // G4 is high half, G5 is low half
- __ mov (G4, dest->as_register_hi());
- __ mov (G5, dest->as_register_lo());
+ __ ldx(base, idx, G5);
}
+ __ srax(G5, 32, dest->as_register_hi()); // fetch the high half into hi
+ __ mov (G5, dest->as_register_lo()); // copy low half into lo
} else {
Unimplemented();
}
diff --git a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
index 05db22c93f9..bf4074b30fd 100644
--- a/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
@@ -108,7 +108,7 @@ void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox
// compare object markOop with Rmark and if equal exchange Rscratch with object markOop
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casx_under_lock(mark_addr.base(), Rmark, Rscratch, (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), Rmark, Rscratch);
// if compare/exchange succeeded we found an unlocked object and we now have locked it
// hence we are done
cmp(Rmark, Rscratch);
@@ -149,7 +149,7 @@ void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rb
// Check if it is still a light weight lock, this is is true if we see
// the stack address of the basicLock in the markOop of the object
- casx_under_lock(mark_addr.base(), Rbox, Rmark, (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), Rbox, Rmark);
cmp(Rbox, Rmark);
brx(Assembler::notEqual, false, Assembler::pn, slow_case);
@@ -276,7 +276,7 @@ void C1_MacroAssembler::initialize_object(
sub(var_size_in_bytes, hdr_size_in_bytes, t2); // compute size of body
initialize_body(t1, t2);
#ifndef _LP64
- } else if (VM_Version::v9_instructions_work() && con_size_in_bytes < threshold * 2) {
+ } else if (con_size_in_bytes < threshold * 2) {
// on v9 we can do double word stores to fill twice as much space.
assert(hdr_size_in_bytes % 8 == 0, "double word aligned");
assert(con_size_in_bytes % 8 == 0, "double word aligned");
diff --git a/hotspot/src/cpu/sparc/vm/c2_init_sparc.cpp b/hotspot/src/cpu/sparc/vm/c2_init_sparc.cpp
index 685a39dbf0f..6ad04df863d 100644
--- a/hotspot/src/cpu/sparc/vm/c2_init_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c2_init_sparc.cpp
@@ -30,5 +30,4 @@
void Compile::pd_compiler2_init() {
guarantee(CodeEntryAlignment >= InteriorEntryAlignment, "" );
- guarantee( VM_Version::v9_instructions_work(), "Server compiler does not run on V8 systems" );
}
diff --git a/hotspot/src/cpu/sparc/vm/disassembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/disassembler_sparc.hpp
index 761d0e3810e..a1f576b26a7 100644
--- a/hotspot/src/cpu/sparc/vm/disassembler_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/disassembler_sparc.hpp
@@ -30,8 +30,7 @@
}
static const char* pd_cpu_opts() {
- return (VM_Version::v9_instructions_work()?
- (VM_Version::v8_instructions_work()? "" : "v9only") : "v8only");
+ return "v9only";
}
#endif // CPU_SPARC_VM_DISASSEMBLER_SPARC_HPP
diff --git a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
index 35886ce8ea9..acffc90f2cf 100644
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
@@ -110,8 +110,5 @@ define_pd_global(uintx, CMSYoungGenPerWorker, 16*M); // default max size of CMS
\
product(uintx, ArraycopyDstPrefetchDistance, 0, \
"Distance to prefetch destination array in arracopy") \
- \
- develop(intx, V8AtomicOperationUnderLockSpinCount, 50, \
- "Number of times to spin wait on a v8 atomic operation lock") \
#endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
index 9775d2f871a..454b23c920b 100644
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
@@ -1210,8 +1210,7 @@ void InterpreterMacroAssembler::lock_object(Register lock_reg, Register Object)
st_ptr(mark_reg, lock_addr, BasicLock::displaced_header_offset_in_bytes());
// compare and exchange object_addr, markOop | 1, stack address of basicLock
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), mark_reg, temp_reg);
// if the compare and exchange succeeded we are done (we saw an unlocked object)
cmp_and_brx_short(mark_reg, temp_reg, Assembler::equal, Assembler::pt, done);
@@ -1291,8 +1290,7 @@ void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
// we expect to see the stack address of the basicLock in case the
// lock is still a light weight lock (lock_reg)
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casx_under_lock(mark_addr.base(), lock_reg, displaced_header_reg,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), lock_reg, displaced_header_reg);
cmp(lock_reg, displaced_header_reg);
brx(Assembler::equal, true, Assembler::pn, done);
delayed()->st_ptr(G0, lockobj_addr); // free entry
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
index c17b7c2b32c..5de1f0b2a75 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp
@@ -118,7 +118,6 @@ int MacroAssembler::patched_branch(int dest_pos, int inst, int inst_pos) {
case bp_op2: m = wdisp( word_aligned_ones, 0, 19); v = wdisp( dest_pos, inst_pos, 19); break;
case fb_op2: m = wdisp( word_aligned_ones, 0, 22); v = wdisp( dest_pos, inst_pos, 22); break;
case br_op2: m = wdisp( word_aligned_ones, 0, 22); v = wdisp( dest_pos, inst_pos, 22); break;
- case cb_op2: m = wdisp( word_aligned_ones, 0, 22); v = wdisp( dest_pos, inst_pos, 22); break;
case bpr_op2: {
if (is_cbcond(inst)) {
m = wdisp10(word_aligned_ones, 0);
@@ -149,7 +148,6 @@ int MacroAssembler::branch_destination(int inst, int pos) {
case bp_op2: r = inv_wdisp( inst, pos, 19); break;
case fb_op2: r = inv_wdisp( inst, pos, 22); break;
case br_op2: r = inv_wdisp( inst, pos, 22); break;
- case cb_op2: r = inv_wdisp( inst, pos, 22); break;
case bpr_op2: {
if (is_cbcond(inst)) {
r = inv_wdisp10(inst, pos);
@@ -325,12 +323,6 @@ void MacroAssembler::breakpoint_trap() {
trap(ST_RESERVED_FOR_USER_0);
}
-// flush windows (except current) using flushw instruction if avail.
-void MacroAssembler::flush_windows() {
- if (VM_Version::v9_instructions_work()) flushw();
- else flush_windows_trap();
-}
-
// Write serialization page so VM thread can do a pseudo remote membar
// We use the current thread pointer to calculate a thread specific
// offset to write to within the page. This minimizes bus traffic
@@ -358,88 +350,6 @@ void MacroAssembler::leave() {
Unimplemented();
}
-void MacroAssembler::mult(Register s1, Register s2, Register d) {
- if(VM_Version::v9_instructions_work()) {
- mulx (s1, s2, d);
- } else {
- smul (s1, s2, d);
- }
-}
-
-void MacroAssembler::mult(Register s1, int simm13a, Register d) {
- if(VM_Version::v9_instructions_work()) {
- mulx (s1, simm13a, d);
- } else {
- smul (s1, simm13a, d);
- }
-}
-
-
-#ifdef ASSERT
-void MacroAssembler::read_ccr_v8_assert(Register ccr_save) {
- const Register s1 = G3_scratch;
- const Register s2 = G4_scratch;
- Label get_psr_test;
- // Get the condition codes the V8 way.
- read_ccr_trap(s1);
- mov(ccr_save, s2);
- // This is a test of V8 which has icc but not xcc
- // so mask off the xcc bits
- and3(s2, 0xf, s2);
- // Compare condition codes from the V8 and V9 ways.
- subcc(s2, s1, G0);
- br(Assembler::notEqual, true, Assembler::pt, get_psr_test);
- delayed()->breakpoint_trap();
- bind(get_psr_test);
-}
-
-void MacroAssembler::write_ccr_v8_assert(Register ccr_save) {
- const Register s1 = G3_scratch;
- const Register s2 = G4_scratch;
- Label set_psr_test;
- // Write out the saved condition codes the V8 way
- write_ccr_trap(ccr_save, s1, s2);
- // Read back the condition codes using the V9 instruction
- rdccr(s1);
- mov(ccr_save, s2);
- // This is a test of V8 which has icc but not xcc
- // so mask off the xcc bits
- and3(s2, 0xf, s2);
- and3(s1, 0xf, s1);
- // Compare the V8 way with the V9 way.
- subcc(s2, s1, G0);
- br(Assembler::notEqual, true, Assembler::pt, set_psr_test);
- delayed()->breakpoint_trap();
- bind(set_psr_test);
-}
-#else
-#define read_ccr_v8_assert(x)
-#define write_ccr_v8_assert(x)
-#endif // ASSERT
-
-void MacroAssembler::read_ccr(Register ccr_save) {
- if (VM_Version::v9_instructions_work()) {
- rdccr(ccr_save);
- // Test code sequence used on V8. Do not move above rdccr.
- read_ccr_v8_assert(ccr_save);
- } else {
- read_ccr_trap(ccr_save);
- }
-}
-
-void MacroAssembler::write_ccr(Register ccr_save) {
- if (VM_Version::v9_instructions_work()) {
- // Test code sequence used on V8. Do not move below wrccr.
- write_ccr_v8_assert(ccr_save);
- wrccr(ccr_save);
- } else {
- const Register temp_reg1 = G3_scratch;
- const Register temp_reg2 = G4_scratch;
- write_ccr_trap(ccr_save, temp_reg1, temp_reg2);
- }
-}
-
-
// Calls to C land
#ifdef ASSERT
@@ -465,8 +375,8 @@ void MacroAssembler::get_thread() {
#ifdef ASSERT
AddressLiteral last_get_thread_addrlit(&last_get_thread);
set(last_get_thread_addrlit, L3);
- inc(L4, get_pc(L4) + 2 * BytesPerInstWord); // skip getpc() code + inc + st_ptr to point L4 at call
- st_ptr(L4, L3, 0);
+ rdpc(L4);
+ inc(L4, 3 * BytesPerInstWord); // skip rdpc + inc + st_ptr to point L4 at call st_ptr(L4, L3, 0);
#endif
call(CAST_FROM_FN_PTR(address, reinitialize_thread), relocInfo::runtime_call_type);
delayed()->nop();
@@ -1327,7 +1237,7 @@ void RegistersForDebugging::print(outputStream* s) {
void RegistersForDebugging::save_registers(MacroAssembler* a) {
a->sub(FP, round_to(sizeof(RegistersForDebugging), sizeof(jdouble)) - STACK_BIAS, O0);
- a->flush_windows();
+ a->flushw();
int i;
for (i = 0; i < 8; ++i) {
a->ld_ptr(as_iRegister(i)->address_in_saved_window().after_save(), L1); a->st_ptr( L1, O0, i_offset(i));
@@ -1338,7 +1248,7 @@ void RegistersForDebugging::save_registers(MacroAssembler* a) {
for (i = 0; i < 32; ++i) {
a->stf(FloatRegisterImpl::S, as_FloatRegister(i), O0, f_offset(i));
}
- for (i = 0; i < (VM_Version::v9_instructions_work() ? 64 : 32); i += 2) {
+ for (i = 0; i < 64; i += 2) {
a->stf(FloatRegisterImpl::D, as_FloatRegister(i), O0, d_offset(i));
}
}
@@ -1350,7 +1260,7 @@ void RegistersForDebugging::restore_registers(MacroAssembler* a, Register r) {
for (int j = 0; j < 32; ++j) {
a->ldf(FloatRegisterImpl::S, O0, f_offset(j), as_FloatRegister(j));
}
- for (int k = 0; k < (VM_Version::v9_instructions_work() ? 64 : 32); k += 2) {
+ for (int k = 0; k < 64; k += 2) {
a->ldf(FloatRegisterImpl::D, O0, d_offset(k), as_FloatRegister(k));
}
}
@@ -1465,8 +1375,6 @@ address MacroAssembler::_verify_oop_implicit_branch[3] = { NULL };
// the high bits of the O-regs if they contain Long values. Acts as a 'leaf'
// call.
void MacroAssembler::verify_oop_subroutine() {
- assert( VM_Version::v9_instructions_work(), "VerifyOops not supported for V8" );
-
// Leaf call; no frame.
Label succeed, fail, null_or_fail;
@@ -1870,26 +1778,17 @@ void MacroAssembler::lcmp( Register Ra_hi, Register Ra_low,
// And the equals case for the high part does not need testing,
// since that triplet is reached only after finding the high halves differ.
- if (VM_Version::v9_instructions_work()) {
- mov(-1, Rresult);
- ba(done); delayed()-> movcc(greater, false, icc, 1, Rresult);
- } else {
- br(less, true, pt, done); delayed()-> set(-1, Rresult);
- br(greater, true, pt, done); delayed()-> set( 1, Rresult);
- }
+ mov(-1, Rresult);
+ ba(done);
+ delayed()->movcc(greater, false, icc, 1, Rresult);
- bind( check_low_parts );
+ bind(check_low_parts);
- if (VM_Version::v9_instructions_work()) {
- mov( -1, Rresult);
- movcc(equal, false, icc, 0, Rresult);
- movcc(greaterUnsigned, false, icc, 1, Rresult);
- } else {
- set(-1, Rresult);
- br(equal, true, pt, done); delayed()->set( 0, Rresult);
- br(greaterUnsigned, true, pt, done); delayed()->set( 1, Rresult);
- }
- bind( done );
+ mov( -1, Rresult);
+ movcc(equal, false, icc, 0, Rresult);
+ movcc(greaterUnsigned, false, icc, 1, Rresult);
+
+ bind(done);
}
void MacroAssembler::lneg( Register Rhi, Register Rlow ) {
@@ -2117,119 +2016,24 @@ void MacroAssembler::store_sized_value(Register src, Address dst, size_t size_in
void MacroAssembler::float_cmp( bool is_float, int unordered_result,
FloatRegister Fa, FloatRegister Fb,
Register Rresult) {
-
- fcmp(is_float ? FloatRegisterImpl::S : FloatRegisterImpl::D, fcc0, Fa, Fb);
-
- Condition lt = unordered_result == -1 ? f_unorderedOrLess : f_less;
- Condition eq = f_equal;
- Condition gt = unordered_result == 1 ? f_unorderedOrGreater : f_greater;
-
- if (VM_Version::v9_instructions_work()) {
-
- mov(-1, Rresult);
- movcc(eq, true, fcc0, 0, Rresult);
- movcc(gt, true, fcc0, 1, Rresult);
-
+ if (is_float) {
+ fcmp(FloatRegisterImpl::S, fcc0, Fa, Fb);
} else {
- Label done;
+ fcmp(FloatRegisterImpl::D, fcc0, Fa, Fb);
+ }
- set( -1, Rresult );
- //fb(lt, true, pn, done); delayed()->set( -1, Rresult );
- fb( eq, true, pn, done); delayed()->set( 0, Rresult );
- fb( gt, true, pn, done); delayed()->set( 1, Rresult );
-
- bind (done);
+ if (unordered_result == 1) {
+ mov( -1, Rresult);
+ movcc(f_equal, true, fcc0, 0, Rresult);
+ movcc(f_unorderedOrGreater, true, fcc0, 1, Rresult);
+ } else {
+ mov( -1, Rresult);
+ movcc(f_equal, true, fcc0, 0, Rresult);
+ movcc(f_greater, true, fcc0, 1, Rresult);
}
}
-void MacroAssembler::fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d)
-{
- if (VM_Version::v9_instructions_work()) {
- Assembler::fneg(w, s, d);
- } else {
- if (w == FloatRegisterImpl::S) {
- Assembler::fneg(w, s, d);
- } else if (w == FloatRegisterImpl::D) {
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 1) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 1) == 0), "float register alignment check");
-
- Assembler::fneg(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- } else {
- assert(w == FloatRegisterImpl::Q, "Invalid float register width");
-
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 3) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 3) == 0), "float register alignment check");
-
- Assembler::fneg(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor(), d->successor()->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor()->successor(), d->successor()->successor()->successor());
- }
- }
-}
-
-void MacroAssembler::fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d)
-{
- if (VM_Version::v9_instructions_work()) {
- Assembler::fmov(w, s, d);
- } else {
- if (w == FloatRegisterImpl::S) {
- Assembler::fmov(w, s, d);
- } else if (w == FloatRegisterImpl::D) {
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 1) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 1) == 0), "float register alignment check");
-
- Assembler::fmov(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- } else {
- assert(w == FloatRegisterImpl::Q, "Invalid float register width");
-
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 3) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 3) == 0), "float register alignment check");
-
- Assembler::fmov(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor(), d->successor()->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor()->successor(), d->successor()->successor()->successor());
- }
- }
-}
-
-void MacroAssembler::fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d)
-{
- if (VM_Version::v9_instructions_work()) {
- Assembler::fabs(w, s, d);
- } else {
- if (w == FloatRegisterImpl::S) {
- Assembler::fabs(w, s, d);
- } else if (w == FloatRegisterImpl::D) {
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 1) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 1) == 0), "float register alignment check");
-
- Assembler::fabs(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- } else {
- assert(w == FloatRegisterImpl::Q, "Invalid float register width");
-
- // number() does a sanity check on the alignment.
- assert(((s->encoding(FloatRegisterImpl::D) & 3) == 0) &&
- ((d->encoding(FloatRegisterImpl::D) & 3) == 0), "float register alignment check");
-
- Assembler::fabs(FloatRegisterImpl::S, s, d);
- Assembler::fmov(FloatRegisterImpl::S, s->successor(), d->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor(), d->successor()->successor());
- Assembler::fmov(FloatRegisterImpl::S, s->successor()->successor()->successor(), d->successor()->successor()->successor());
- }
- }
-}
-
void MacroAssembler::save_all_globals_into_locals() {
mov(G1,L1);
mov(G2,L2);
@@ -2250,135 +2054,6 @@ void MacroAssembler::restore_globals_from_locals() {
mov(L7,G7);
}
-// Use for 64 bit operation.
-void MacroAssembler::casx_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg, address lock_addr, bool use_call_vm)
-{
- // store ptr_reg as the new top value
-#ifdef _LP64
- casx(top_ptr_reg, top_reg, ptr_reg);
-#else
- cas_under_lock(top_ptr_reg, top_reg, ptr_reg, lock_addr, use_call_vm);
-#endif // _LP64
-}
-
-// [RGV] This routine does not handle 64 bit operations.
-// use casx_under_lock() or casx directly!!!
-void MacroAssembler::cas_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg, address lock_addr, bool use_call_vm)
-{
- // store ptr_reg as the new top value
- if (VM_Version::v9_instructions_work()) {
- cas(top_ptr_reg, top_reg, ptr_reg);
- } else {
-
- // If the register is not an out nor global, it is not visible
- // after the save. Allocate a register for it, save its
- // value in the register save area (the save may not flush
- // registers to the save area).
-
- Register top_ptr_reg_after_save;
- Register top_reg_after_save;
- Register ptr_reg_after_save;
-
- if (top_ptr_reg->is_out() || top_ptr_reg->is_global()) {
- top_ptr_reg_after_save = top_ptr_reg->after_save();
- } else {
- Address reg_save_addr = top_ptr_reg->address_in_saved_window();
- top_ptr_reg_after_save = L0;
- st(top_ptr_reg, reg_save_addr);
- }
-
- if (top_reg->is_out() || top_reg->is_global()) {
- top_reg_after_save = top_reg->after_save();
- } else {
- Address reg_save_addr = top_reg->address_in_saved_window();
- top_reg_after_save = L1;
- st(top_reg, reg_save_addr);
- }
-
- if (ptr_reg->is_out() || ptr_reg->is_global()) {
- ptr_reg_after_save = ptr_reg->after_save();
- } else {
- Address reg_save_addr = ptr_reg->address_in_saved_window();
- ptr_reg_after_save = L2;
- st(ptr_reg, reg_save_addr);
- }
-
- const Register& lock_reg = L3;
- const Register& lock_ptr_reg = L4;
- const Register& value_reg = L5;
- const Register& yield_reg = L6;
- const Register& yieldall_reg = L7;
-
- save_frame();
-
- if (top_ptr_reg_after_save == L0) {
- ld(top_ptr_reg->address_in_saved_window().after_save(), top_ptr_reg_after_save);
- }
-
- if (top_reg_after_save == L1) {
- ld(top_reg->address_in_saved_window().after_save(), top_reg_after_save);
- }
-
- if (ptr_reg_after_save == L2) {
- ld(ptr_reg->address_in_saved_window().after_save(), ptr_reg_after_save);
- }
-
- Label(retry_get_lock);
- Label(not_same);
- Label(dont_yield);
-
- assert(lock_addr, "lock_address should be non null for v8");
- set((intptr_t)lock_addr, lock_ptr_reg);
- // Initialize yield counter
- mov(G0,yield_reg);
- mov(G0, yieldall_reg);
- set(StubRoutines::Sparc::locked, lock_reg);
-
- bind(retry_get_lock);
- cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dont_yield);
-
- if(use_call_vm) {
- Untested("Need to verify global reg consistancy");
- call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::yield_all), yieldall_reg);
- } else {
- // Save the regs and make space for a C call
- save(SP, -96, SP);
- save_all_globals_into_locals();
- call(CAST_FROM_FN_PTR(address,os::yield_all));
- delayed()->mov(yieldall_reg, O0);
- restore_globals_from_locals();
- restore();
- }
-
- // reset the counter
- mov(G0,yield_reg);
- add(yieldall_reg, 1, yieldall_reg);
-
- bind(dont_yield);
- // try to get lock
- Assembler::swap(lock_ptr_reg, 0, lock_reg);
-
- // did we get the lock?
- cmp(lock_reg, StubRoutines::Sparc::unlocked);
- br(Assembler::notEqual, true, Assembler::pn, retry_get_lock);
- delayed()->add(yield_reg,1,yield_reg);
-
- // yes, got lock. do we have the same top?
- ld(top_ptr_reg_after_save, 0, value_reg);
- cmp_and_br_short(value_reg, top_reg_after_save, Assembler::notEqual, Assembler::pn, not_same);
-
- // yes, same top.
- st(ptr_reg_after_save, top_ptr_reg_after_save, 0);
- membar(Assembler::StoreStore);
-
- bind(not_same);
- mov(value_reg, ptr_reg_after_save);
- st(lock_reg, lock_ptr_reg, 0); // unlock
-
- restore();
- }
-}
-
RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
Register tmp,
int offset) {
@@ -2970,7 +2645,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place,
mark_reg);
or3(G2_thread, mark_reg, temp_reg);
- casn(mark_addr.base(), mark_reg, temp_reg);
+ cas_ptr(mark_addr.base(), mark_reg, temp_reg);
// If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the
@@ -2998,7 +2673,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, Klass::prototype_header_offset()), temp_reg);
or3(G2_thread, temp_reg, temp_reg);
- casn(mark_addr.base(), mark_reg, temp_reg);
+ cas_ptr(mark_addr.base(), mark_reg, temp_reg);
// If the biasing toward our thread failed, this means that
// another thread succeeded in biasing it toward itself and we
// need to revoke that bias. The revocation will occur in the
@@ -3027,7 +2702,7 @@ void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
// bits in this situation. Should attempt to preserve them.
load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, Klass::prototype_header_offset()), temp_reg);
- casn(mark_addr.base(), mark_reg, temp_reg);
+ cas_ptr(mark_addr.base(), mark_reg, temp_reg);
// Fall through to the normal CAS-based lock, because no matter what
// the result of the above CAS, some thread must have succeeded in
// removing the bias bit from the object's header.
@@ -3058,15 +2733,6 @@ void MacroAssembler::biased_locking_exit (Address mark_addr, Register temp_reg,
}
-// CASN -- 32-64 bit switch hitter similar to the synthetic CASN provided by
-// Solaris/SPARC's "as". Another apt name would be cas_ptr()
-
-void MacroAssembler::casn (Register addr_reg, Register cmp_reg, Register set_reg ) {
- casx_under_lock (addr_reg, cmp_reg, set_reg, (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
-}
-
-
-
// compiler_lock_object() and compiler_unlock_object() are direct transliterations
// of i486.ad fast_lock() and fast_unlock(). See those methods for detailed comments.
// The code could be tightened up considerably.
@@ -3129,8 +2795,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
// compare object markOop with Rmark and if equal exchange Rscratch with object markOop
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casx_under_lock(mark_addr.base(), Rmark, Rscratch,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), Rmark, Rscratch);
// if compare/exchange succeeded we found an unlocked object and we now have locked it
// hence we are done
@@ -3176,7 +2841,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
mov(Rbox, Rscratch);
or3(Rmark, markOopDesc::unlocked_value, Rmark);
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casn(mark_addr.base(), Rmark, Rscratch);
+ cas_ptr(mark_addr.base(), Rmark, Rscratch);
cmp(Rmark, Rscratch);
brx(Assembler::equal, false, Assembler::pt, done);
delayed()->sub(Rscratch, SP, Rscratch);
@@ -3207,7 +2872,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
// Invariant: if we acquire the lock then _recursions should be 0.
add(Rmark, ObjectMonitor::owner_offset_in_bytes()-2, Rmark);
mov(G2_thread, Rscratch);
- casn(Rmark, G0, Rscratch);
+ cas_ptr(Rmark, G0, Rscratch);
cmp(Rscratch, G0);
// Intentional fall-through into done
} else {
@@ -3240,7 +2905,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
mov(0, Rscratch);
or3(Rmark, markOopDesc::unlocked_value, Rmark);
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casn(mark_addr.base(), Rmark, Rscratch);
+ cas_ptr(mark_addr.base(), Rmark, Rscratch);
// prefetch (mark_addr, Assembler::severalWritesAndPossiblyReads);
cmp(Rscratch, Rmark);
brx(Assembler::notZero, false, Assembler::pn, Recursive);
@@ -3266,7 +2931,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
// the fast-path stack-lock code from the interpreter and always passed
// control to the "slow" operators in synchronizer.cpp.
- // RScratch contains the fetched obj->mark value from the failed CASN.
+ // RScratch contains the fetched obj->mark value from the failed CAS.
#ifdef _LP64
sub(Rscratch, STACK_BIAS, Rscratch);
#endif
@@ -3300,7 +2965,7 @@ void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark,
// Invariant: if we acquire the lock then _recursions should be 0.
add(Rmark, ObjectMonitor::owner_offset_in_bytes()-2, Rmark);
mov(G2_thread, Rscratch);
- casn(Rmark, G0, Rscratch);
+ cas_ptr(Rmark, G0, Rscratch);
cmp(Rscratch, G0);
// ST box->displaced_header = NonZero.
// Any non-zero value suffices:
@@ -3336,8 +3001,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
// Check if it is still a light weight lock, this is is true if we see
// the stack address of the basicLock in the markOop of the object
assert(mark_addr.disp() == 0, "cas must take a zero displacement");
- casx_under_lock(mark_addr.base(), Rbox, Rmark,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(mark_addr.base(), Rbox, Rmark);
ba(done);
delayed()->cmp(Rbox, Rmark);
bind(done);
@@ -3398,7 +3062,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
delayed()->andcc(G0, G0, G0);
add(Rmark, ObjectMonitor::owner_offset_in_bytes()-2, Rmark);
mov(G2_thread, Rscratch);
- casn(Rmark, G0, Rscratch);
+ cas_ptr(Rmark, G0, Rscratch);
// invert icc.zf and goto done
br_notnull(Rscratch, false, Assembler::pt, done);
delayed()->cmp(G0, G0);
@@ -3440,7 +3104,7 @@ void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark,
// A prototype implementation showed excellent results, although
// the scavenger and timeout code was rather involved.
- casn(mark_addr.base(), Rbox, Rscratch);
+ cas_ptr(mark_addr.base(), Rbox, Rscratch);
cmp(Rbox, Rscratch);
// Intentional fall through into done ...
@@ -3584,7 +3248,7 @@ void MacroAssembler::eden_allocate(
// Compare obj with the value at top_addr; if still equal, swap the value of
// end with the value at top_addr. If not equal, read the value at top_addr
// into end.
- casx_under_lock(top_addr, obj, end, (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ cas_ptr(top_addr, obj, end);
// if someone beat us on the allocation, try again, otherwise continue
cmp(obj, end);
brx(Assembler::notEqual, false, Assembler::pn, retry);
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
index 26605cbfa4c..6306449b329 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp
@@ -1056,13 +1056,6 @@ public:
void breakpoint_trap();
void breakpoint_trap(Condition c, CC cc);
- void flush_windows_trap();
- void clean_windows_trap();
- void get_psr_trap();
- void set_psr_trap();
-
- // V8/V9 flush_windows
- void flush_windows();
// Support for serializing memory accesses between threads
void serialize_memory(Register thread, Register tmp1, Register tmp2);
@@ -1071,14 +1064,6 @@ public:
void enter();
void leave();
- // V8/V9 integer multiply
- void mult(Register s1, Register s2, Register d);
- void mult(Register s1, int simm13a, Register d);
-
- // V8/V9 read and write of condition codes.
- void read_ccr(Register d);
- void write_ccr(Register s);
-
// Manipulation of C++ bools
// These are idioms to flag the need for care with accessing bools but on
// this platform we assume byte size
@@ -1162,21 +1147,6 @@ public:
// check_and_forward_exception to handle exceptions when it is safe
void check_and_forward_exception(Register scratch_reg);
- private:
- // For V8
- void read_ccr_trap(Register ccr_save);
- void write_ccr_trap(Register ccr_save1, Register scratch1, Register scratch2);
-
-#ifdef ASSERT
- // For V8 debugging. Uses V8 instruction sequence and checks
- // result with V9 insturctions rdccr and wrccr.
- // Uses Gscatch and Gscatch2
- void read_ccr_v8_assert(Register ccr_save);
- void write_ccr_v8_assert(Register ccr_save);
-#endif // ASSERT
-
- public:
-
// Write to card table for - register is destroyed afterwards.
void card_table_write(jbyte* byte_map_base, Register tmp, Register obj);
@@ -1314,20 +1284,9 @@ public:
FloatRegister Fa, FloatRegister Fb,
Register Rresult);
- void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
- void fneg( FloatRegisterImpl::Width w, FloatRegister sd ) { Assembler::fneg(w, sd); }
- void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
- void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d);
-
void save_all_globals_into_locals();
void restore_globals_from_locals();
- void casx_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg,
- address lock_addr=0, bool use_call_vm=false);
- void cas_under_lock(Register top_ptr_reg, Register top_reg, Register ptr_reg,
- address lock_addr=0, bool use_call_vm=false);
- void casn (Register addr_reg, Register cmp_reg, Register set_reg) ;
-
// These set the icc condition code to equal if the lock succeeded
// and notEqual if it failed and requires a slow case
void compiler_lock_object(Register Roop, Register Rmark, Register Rbox,
diff --git a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp
index 871853c684d..fab14c0677f 100644
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.inline.hpp
@@ -229,10 +229,7 @@ inline void MacroAssembler::sll_ptr( Register s1, RegisterOrConstant s2, Registe
// Use the right branch for the platform
inline void MacroAssembler::br( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) {
- if (VM_Version::v9_instructions_work())
- Assembler::bp(c, a, icc, p, d, rt);
- else
- Assembler::br(c, a, d, rt);
+ Assembler::bp(c, a, icc, p, d, rt);
}
inline void MacroAssembler::br( Condition c, bool a, Predict p, Label& L ) {
@@ -268,10 +265,7 @@ inline void MacroAssembler::bp( Condition c, bool a, CC cc, Predict p, Label& L
}
inline void MacroAssembler::fb( Condition c, bool a, Predict p, address d, relocInfo::relocType rt ) {
- if (VM_Version::v9_instructions_work())
- fbp(c, a, fcc0, p, d, rt);
- else
- Assembler::fb(c, a, d, rt);
+ fbp(c, a, fcc0, p, d, rt);
}
inline void MacroAssembler::fb( Condition c, bool a, Predict p, Label& L ) {
@@ -334,7 +328,7 @@ inline void MacroAssembler::callr( Register s1, int simm13a, RelocationHolder co
// prefetch instruction
inline void MacroAssembler::iprefetch( address d, relocInfo::relocType rt ) {
- if (VM_Version::v9_instructions_work())
+ Assembler::bp( never, true, xcc, pt, d, rt );
Assembler::bp( never, true, xcc, pt, d, rt );
}
inline void MacroAssembler::iprefetch( Label& L) { iprefetch( target(L) ); }
@@ -344,15 +338,7 @@ inline void MacroAssembler::iprefetch( Label& L) { iprefetch( target(L) ); }
// returns delta from gotten pc to addr after
inline int MacroAssembler::get_pc( Register d ) {
int x = offset();
- if (VM_Version::v9_instructions_work())
- rdpc(d);
- else {
- Label lbl;
- Assembler::call(lbl, relocInfo::none); // No relocation as this is call to pc+0x8
- if (d == O7) delayed()->nop();
- else delayed()->mov(O7, d);
- bind(lbl);
- }
+ rdpc(d);
return offset() - x;
}
@@ -646,41 +632,26 @@ inline void MacroAssembler::ldf(FloatRegisterImpl::Width w, const Address& a, Fl
// returns if membar generates anything, obviously this code should mirror
// membar below.
inline bool MacroAssembler::membar_has_effect( Membar_mask_bits const7a ) {
- if( !os::is_MP() ) return false; // Not needed on single CPU
- if( VM_Version::v9_instructions_work() ) {
- const Membar_mask_bits effective_mask =
- Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore));
- return (effective_mask != 0);
- } else {
- return true;
- }
+ if (!os::is_MP())
+ return false; // Not needed on single CPU
+ const Membar_mask_bits effective_mask =
+ Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore));
+ return (effective_mask != 0);
}
inline void MacroAssembler::membar( Membar_mask_bits const7a ) {
// Uniprocessors do not need memory barriers
- if (!os::is_MP()) return;
+ if (!os::is_MP())
+ return;
// Weakened for current Sparcs and TSO. See the v9 manual, sections 8.4.3,
// 8.4.4.3, a.31 and a.50.
- if( VM_Version::v9_instructions_work() ) {
- // Under TSO, setting bit 3, 2, or 0 is redundant, so the only value
- // of the mmask subfield of const7a that does anything that isn't done
- // implicitly is StoreLoad.
- const Membar_mask_bits effective_mask =
- Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore));
- if ( effective_mask != 0 ) {
- Assembler::membar( effective_mask );
- }
- } else {
- // stbar is the closest there is on v8. Equivalent to membar(StoreStore). We
- // do not issue the stbar because to my knowledge all v8 machines implement TSO,
- // which guarantees that all stores behave as if an stbar were issued just after
- // each one of them. On these machines, stbar ought to be a nop. There doesn't
- // appear to be an equivalent of membar(StoreLoad) on v8: TSO doesn't require it,
- // it can't be specified by stbar, nor have I come up with a way to simulate it.
- //
- // Addendum. Dave says that ldstub guarantees a write buffer flush to coherent
- // space. Put one here to be on the safe side.
- Assembler::ldstub(SP, 0, G0);
+ // Under TSO, setting bit 3, 2, or 0 is redundant, so the only value
+ // of the mmask subfield of const7a that does anything that isn't done
+ // implicitly is StoreLoad.
+ const Membar_mask_bits effective_mask =
+ Membar_mask_bits(const7a & ~(LoadLoad | LoadStore | StoreStore));
+ if (effective_mask != 0) {
+ Assembler::membar(effective_mask);
}
}
diff --git a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp
index 71a938e59fc..81f29d2671b 100644
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp
@@ -162,7 +162,7 @@ void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
int i1 = ((int*)code_buffer)[1];
int* contention_addr = (int*) n_call->addr_at(1*BytesPerInstWord);
assert(inv_op(*contention_addr) == Assembler::arith_op ||
- *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
+ *contention_addr == nop_instruction(),
"must not interfere with original call");
// The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order
n_call->set_long_at(1*BytesPerInstWord, i1);
@@ -181,7 +181,7 @@ void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) {
// Make sure the first-patched instruction, which may co-exist
// briefly with the call, will do something harmless.
assert(inv_op(*contention_addr) == Assembler::arith_op ||
- *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
+ *contention_addr == nop_instruction(),
"must not interfere with original call");
}
@@ -933,11 +933,7 @@ void NativeJump::patch_verified_entry(address entry, address verified_entry, add
int code_size = 1 * BytesPerInstWord;
CodeBuffer cb(verified_entry, code_size + 1);
MacroAssembler* a = new MacroAssembler(&cb);
- if (VM_Version::v9_instructions_work()) {
- a->ldsw(G0, 0, O7); // "ld" must agree with code in the signal handler
- } else {
- a->lduw(G0, 0, O7); // "ld" must agree with code in the signal handler
- }
+ a->ldsw(G0, 0, O7); // "ld" must agree with code in the signal handler
ICache::invalidate_range(verified_entry, code_size);
}
@@ -1024,7 +1020,7 @@ void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer)
int i1 = ((int*)code_buffer)[1];
int* contention_addr = (int*) h_jump->addr_at(1*BytesPerInstWord);
assert(inv_op(*contention_addr) == Assembler::arith_op ||
- *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
+ *contention_addr == nop_instruction(),
"must not interfere with original call");
// The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order
h_jump->set_long_at(1*BytesPerInstWord, i1);
@@ -1043,6 +1039,6 @@ void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer)
// Make sure the first-patched instruction, which may co-exist
// briefly with the call, will do something harmless.
assert(inv_op(*contention_addr) == Assembler::arith_op ||
- *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(),
+ *contention_addr == nop_instruction(),
"must not interfere with original call");
}
diff --git a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp
index 3c9a5e9b7a7..aa362012dcf 100644
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp
@@ -70,8 +70,7 @@ class NativeInstruction VALUE_OBJ_CLASS_SPEC {
bool is_zombie() {
int x = long_at(0);
return is_op3(x,
- VM_Version::v9_instructions_work() ?
- Assembler::ldsw_op3 : Assembler::lduw_op3,
+ Assembler::ldsw_op3,
Assembler::ldst_op)
&& Assembler::inv_rs1(x) == G0
&& Assembler::inv_rd(x) == O7;
diff --git a/hotspot/src/cpu/sparc/vm/register_sparc.hpp b/hotspot/src/cpu/sparc/vm/register_sparc.hpp
index 945866e539f..423a424c936 100644
--- a/hotspot/src/cpu/sparc/vm/register_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/register_sparc.hpp
@@ -249,12 +249,10 @@ class FloatRegisterImpl: public AbstractRegisterImpl {
case D:
assert(c < 64 && (c & 1) == 0, "bad double float register");
- assert(c < 32 || VM_Version::v9_instructions_work(), "V9 float work only on V9 platform");
return (c & 0x1e) | ((c & 0x20) >> 5);
case Q:
assert(c < 64 && (c & 3) == 0, "bad quad float register");
- assert(c < 32 || VM_Version::v9_instructions_work(), "V9 float work only on V9 platform");
return (c & 0x1c) | ((c & 0x20) >> 5);
}
ShouldNotReachHere();
diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
index b6a338c34ee..3149dbd76d2 100644
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
@@ -2459,7 +2459,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
// Finally just about ready to make the JNI call
- __ flush_windows();
+ __ flushw();
if (inner_frame_created) {
__ restore();
} else {
diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad
index ebbce2e7741..932da4a5930 100644
--- a/hotspot/src/cpu/sparc/vm/sparc.ad
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad
@@ -2778,10 +2778,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
Register Rold = reg_to_register_object($old$$reg);
Register Rnew = reg_to_register_object($new$$reg);
- // casx_under_lock picks 1 of 3 encodings:
- // For 32-bit pointers you get a 32-bit CAS
- // For 64-bit pointers you get a 64-bit CASX
- __ casn(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
+ __ cas_ptr(Rmem, Rold, Rnew); // Swap(*Rmem,Rnew) if *Rmem == Rold
__ cmp( Rold, Rnew );
%}
@@ -3067,7 +3064,7 @@ enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI r
AddressLiteral last_rethrow_addrlit(&last_rethrow);
__ sethi(last_rethrow_addrlit, L1);
Address addr(L1, last_rethrow_addrlit.low10());
- __ get_pc(L2);
+ __ rdpc(L2);
__ inc(L2, 3 * BytesPerInstWord); // skip this & 2 more insns to point at jump_to
__ st_ptr(L2, addr);
__ restore();
diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
index 3cd4ff2d3f5..494c1bc405a 100644
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
@@ -566,7 +566,7 @@ class StubGenerator: public StubCodeGenerator {
StubCodeMark mark(this, "StubRoutines", "flush_callers_register_windows");
address start = __ pc();
- __ flush_windows();
+ __ flushw();
__ retl(false);
__ delayed()->add( FP, STACK_BIAS, O0 );
// The returned value must be a stack pointer whose register save area
@@ -575,67 +575,9 @@ class StubGenerator: public StubCodeGenerator {
return start;
}
- // Helper functions for v8 atomic operations.
- //
- void get_v8_oop_lock_ptr(Register lock_ptr_reg, Register mark_oop_reg, Register scratch_reg) {
- if (mark_oop_reg == noreg) {
- address lock_ptr = (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr();
- __ set((intptr_t)lock_ptr, lock_ptr_reg);
- } else {
- assert(scratch_reg != noreg, "just checking");
- address lock_ptr = (address)StubRoutines::Sparc::_v8_oop_lock_cache;
- __ set((intptr_t)lock_ptr, lock_ptr_reg);
- __ and3(mark_oop_reg, StubRoutines::Sparc::v8_oop_lock_mask_in_place, scratch_reg);
- __ add(lock_ptr_reg, scratch_reg, lock_ptr_reg);
- }
- }
-
- void generate_v8_lock_prologue(Register lock_reg, Register lock_ptr_reg, Register yield_reg, Label& retry, Label& dontyield, Register mark_oop_reg = noreg, Register scratch_reg = noreg) {
-
- get_v8_oop_lock_ptr(lock_ptr_reg, mark_oop_reg, scratch_reg);
- __ set(StubRoutines::Sparc::locked, lock_reg);
- // Initialize yield counter
- __ mov(G0,yield_reg);
-
- __ BIND(retry);
- __ cmp_and_br_short(yield_reg, V8AtomicOperationUnderLockSpinCount, Assembler::less, Assembler::pt, dontyield);
-
- // This code can only be called from inside the VM, this
- // stub is only invoked from Atomic::add(). We do not
- // want to use call_VM, because _last_java_sp and such
- // must already be set.
- //
- // Save the regs and make space for a C call
- __ save(SP, -96, SP);
- __ save_all_globals_into_locals();
- BLOCK_COMMENT("call os::naked_sleep");
- __ call(CAST_FROM_FN_PTR(address, os::naked_sleep));
- __ delayed()->nop();
- __ restore_globals_from_locals();
- __ restore();
- // reset the counter
- __ mov(G0,yield_reg);
-
- __ BIND(dontyield);
-
- // try to get lock
- __ swap(lock_ptr_reg, 0, lock_reg);
-
- // did we get the lock?
- __ cmp(lock_reg, StubRoutines::Sparc::unlocked);
- __ br(Assembler::notEqual, true, Assembler::pn, retry);
- __ delayed()->add(yield_reg,1,yield_reg);
-
- // yes, got lock. do the operation here.
- }
-
- void generate_v8_lock_epilogue(Register lock_reg, Register lock_ptr_reg, Register yield_reg, Label& retry, Label& dontyield, Register mark_oop_reg = noreg, Register scratch_reg = noreg) {
- __ st(lock_reg, lock_ptr_reg, 0); // unlock
- }
-
// Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
//
- // Arguments :
+ // Arguments:
//
// exchange_value: O0
// dest: O1
@@ -656,33 +598,14 @@ class StubGenerator: public StubCodeGenerator {
__ mov(O0, O3); // scratch copy of exchange value
__ ld(O1, 0, O2); // observe the previous value
// try to replace O2 with O3
- __ cas_under_lock(O1, O2, O3,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
+ __ cas(O1, O2, O3);
__ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
__ retl(false);
__ delayed()->mov(O2, O0); // report previous value to caller
-
} else {
- if (VM_Version::v9_instructions_work()) {
- __ retl(false);
- __ delayed()->swap(O1, 0, O0);
- } else {
- const Register& lock_reg = O2;
- const Register& lock_ptr_reg = O3;
- const Register& yield_reg = O4;
-
- Label retry;
- Label dontyield;
-
- generate_v8_lock_prologue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- // got the lock, do the swap
- __ swap(O1, 0, O0);
-
- generate_v8_lock_epilogue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- __ retl(false);
- __ delayed()->nop();
- }
+ __ retl(false);
+ __ delayed()->swap(O1, 0, O0);
}
return start;
@@ -691,7 +614,7 @@ class StubGenerator: public StubCodeGenerator {
// Support for jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value)
//
- // Arguments :
+ // Arguments:
//
// exchange_value: O0
// dest: O1
@@ -701,15 +624,12 @@ class StubGenerator: public StubCodeGenerator {
//
// O0: the value previously stored in dest
//
- // Overwrites (v8): O3,O4,O5
- //
address generate_atomic_cmpxchg() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg");
address start = __ pc();
// cmpxchg(dest, compare_value, exchange_value)
- __ cas_under_lock(O1, O2, O0,
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr(),false);
+ __ cas(O1, O2, O0);
__ retl(false);
__ delayed()->nop();
@@ -718,7 +638,7 @@ class StubGenerator: public StubCodeGenerator {
// Support for jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong *dest, jlong compare_value)
//
- // Arguments :
+ // Arguments:
//
// exchange_value: O1:O0
// dest: O2
@@ -728,17 +648,12 @@ class StubGenerator: public StubCodeGenerator {
//
// O1:O0: the value previously stored in dest
//
- // This only works on V9, on V8 we don't generate any
- // code and just return NULL.
- //
// Overwrites: G1,G2,G3
//
address generate_atomic_cmpxchg_long() {
StubCodeMark mark(this, "StubRoutines", "atomic_cmpxchg_long");
address start = __ pc();
- if (!VM_Version::supports_cx8())
- return NULL;;
__ sllx(O0, 32, O0);
__ srl(O1, 0, O1);
__ or3(O0,O1,O0); // O0 holds 64-bit value from compare_value
@@ -756,7 +671,7 @@ class StubGenerator: public StubCodeGenerator {
// Support for jint Atomic::add(jint add_value, volatile jint* dest).
//
- // Arguments :
+ // Arguments:
//
// add_value: O0 (e.g., +1 or -1)
// dest: O1
@@ -765,47 +680,22 @@ class StubGenerator: public StubCodeGenerator {
//
// O0: the new value stored in dest
//
- // Overwrites (v9): O3
- // Overwrites (v8): O3,O4,O5
+ // Overwrites: O3
//
address generate_atomic_add() {
StubCodeMark mark(this, "StubRoutines", "atomic_add");
address start = __ pc();
__ BIND(_atomic_add_stub);
- if (VM_Version::v9_instructions_work()) {
- Label(retry);
- __ BIND(retry);
+ Label(retry);
+ __ BIND(retry);
- __ lduw(O1, 0, O2);
- __ add(O0, O2, O3);
- __ cas(O1, O2, O3);
- __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
- __ retl(false);
- __ delayed()->add(O0, O2, O0); // note that cas made O2==O3
- } else {
- const Register& lock_reg = O2;
- const Register& lock_ptr_reg = O3;
- const Register& value_reg = O4;
- const Register& yield_reg = O5;
-
- Label(retry);
- Label(dontyield);
-
- generate_v8_lock_prologue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
- // got lock, do the increment
- __ ld(O1, 0, value_reg);
- __ add(O0, value_reg, value_reg);
- __ st(value_reg, O1, 0);
-
- // %%% only for RMO and PSO
- __ membar(Assembler::StoreStore);
-
- generate_v8_lock_epilogue(lock_reg, lock_ptr_reg, yield_reg, retry, dontyield);
-
- __ retl(false);
- __ delayed()->mov(value_reg, O0);
- }
+ __ lduw(O1, 0, O2);
+ __ add(O0, O2, O3);
+ __ cas(O1, O2, O3);
+ __ cmp_and_br_short(O2, O3, Assembler::notEqual, Assembler::pn, retry);
+ __ retl(false);
+ __ delayed()->add(O0, O2, O0); // note that cas made O2==O3
return start;
}
@@ -841,7 +731,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(G3, L3);
__ mov(G4, L4);
__ mov(G5, L5);
- for (i = 0; i < (VM_Version::v9_instructions_work() ? 64 : 32); i += 2) {
+ for (i = 0; i < 64; i += 2) {
__ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
}
@@ -855,7 +745,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(L3, G3);
__ mov(L4, G4);
__ mov(L5, G5);
- for (i = 0; i < (VM_Version::v9_instructions_work() ? 64 : 32); i += 2) {
+ for (i = 0; i < 64; i += 2) {
__ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
}
diff --git a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp
index 3a544be2e16..da9e9040683 100644
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.cpp
@@ -52,7 +52,3 @@ address StubRoutines::Sparc::_stop_subroutine_entry = NULL;
address StubRoutines::Sparc::_flush_callers_register_windows_entry = CAST_FROM_FN_PTR(address, bootstrap_flush_windows);
address StubRoutines::Sparc::_partial_subtype_check = NULL;
-
-int StubRoutines::Sparc::_atomic_memory_operation_lock = StubRoutines::Sparc::unlocked;
-
-int StubRoutines::Sparc::_v8_oop_lock_cache[StubRoutines::Sparc::nof_v8_oop_lock_cache_entries];
diff --git a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp
index b0a24306295..1b23479a1f9 100644
--- a/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/stubRoutines_sparc.hpp
@@ -47,46 +47,14 @@ enum /* platform_dependent_constants */ {
class Sparc {
friend class StubGenerator;
- public:
- enum { nof_instance_allocators = 10 };
-
- // allocator lock values
- enum {
- unlocked = 0,
- locked = 1
- };
-
- enum {
- v8_oop_lock_ignore_bits = 2,
- v8_oop_lock_bits = 4,
- nof_v8_oop_lock_cache_entries = 1 << (v8_oop_lock_bits+v8_oop_lock_ignore_bits),
- v8_oop_lock_mask = right_n_bits(v8_oop_lock_bits),
- v8_oop_lock_mask_in_place = v8_oop_lock_mask << v8_oop_lock_ignore_bits
- };
-
- static int _v8_oop_lock_cache[nof_v8_oop_lock_cache_entries];
-
private:
static address _test_stop_entry;
static address _stop_subroutine_entry;
static address _flush_callers_register_windows_entry;
- static int _atomic_memory_operation_lock;
-
static address _partial_subtype_check;
public:
- // %%% global lock for everyone who needs to use atomic_compare_and_exchange
- // %%% or atomic_increment -- should probably use more locks for more
- // %%% scalability-- for instance one for each eden space or group of
-
- // address of the lock for atomic_compare_and_exchange
- static int* atomic_memory_operation_lock_addr() { return &_atomic_memory_operation_lock; }
-
- // accessor and mutator for _atomic_memory_operation_lock
- static int atomic_memory_operation_lock() { return _atomic_memory_operation_lock; }
- static void set_atomic_memory_operation_lock(int value) { _atomic_memory_operation_lock = value; }
-
// test assembler stop routine by setting registers
static void (*test_stop_entry()) () { return CAST_TO_FN_PTR(void (*)(void), _test_stop_entry); }
diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index 135760ec0b4..7b9a494dff0 100644
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -1054,7 +1054,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
// flush the windows now. We don't care about the current (protection) frame
// only the outer frames
- __ flush_windows();
+ __ flushw();
// mark windows as flushed
Address flags(G2_thread, JavaThread::frame_anchor_offset() + JavaFrameAnchor::flags_offset());
diff --git a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
index 00d1079742b..c3e8b298d6e 100644
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
@@ -1338,14 +1338,13 @@ void TemplateTable::lneg() {
void TemplateTable::fneg() {
transition(ftos, ftos);
- __ fneg(FloatRegisterImpl::S, Ftos_f);
+ __ fneg(FloatRegisterImpl::S, Ftos_f, Ftos_f);
}
void TemplateTable::dneg() {
transition(dtos, dtos);
- // v8 has fnegd if source and dest are the same
- __ fneg(FloatRegisterImpl::D, Ftos_f);
+ __ fneg(FloatRegisterImpl::D, Ftos_f, Ftos_f);
}
@@ -1470,19 +1469,10 @@ void TemplateTable::convert() {
__ st_long(Otos_l, __ d_tmp);
__ ldf(FloatRegisterImpl::D, __ d_tmp, Ftos_d);
- if (VM_Version::v9_instructions_work()) {
- if (bytecode() == Bytecodes::_l2f) {
- __ fxtof(FloatRegisterImpl::S, Ftos_d, Ftos_f);
- } else {
- __ fxtof(FloatRegisterImpl::D, Ftos_d, Ftos_d);
- }
+ if (bytecode() == Bytecodes::_l2f) {
+ __ fxtof(FloatRegisterImpl::S, Ftos_d, Ftos_f);
} else {
- __ call_VM_leaf(
- Lscratch,
- bytecode() == Bytecodes::_l2f
- ? CAST_FROM_FN_PTR(address, SharedRuntime::l2f)
- : CAST_FROM_FN_PTR(address, SharedRuntime::l2d)
- );
+ __ fxtof(FloatRegisterImpl::D, Ftos_d, Ftos_d);
}
break;
@@ -1490,11 +1480,6 @@ void TemplateTable::convert() {
Label isNaN;
// result must be 0 if value is NaN; test by comparing value to itself
__ fcmp(FloatRegisterImpl::S, Assembler::fcc0, Ftos_f, Ftos_f);
- // According to the v8 manual, you have to have a non-fp instruction
- // between fcmp and fb.
- if (!VM_Version::v9_instructions_work()) {
- __ nop();
- }
__ fb(Assembler::f_unordered, true, Assembler::pn, isNaN);
__ delayed()->clr(Otos_i); // NaN
__ ftoi(FloatRegisterImpl::S, Ftos_f, F30);
@@ -1537,16 +1522,7 @@ void TemplateTable::convert() {
break;
case Bytecodes::_d2f:
- if (VM_Version::v9_instructions_work()) {
__ ftof( FloatRegisterImpl::D, FloatRegisterImpl::S, Ftos_d, Ftos_f);
- }
- else {
- // must uncache tos
- __ push_d();
- __ pop_i(O0);
- __ pop_i(O1);
- __ call_VM_leaf(Lscratch, CAST_FROM_FN_PTR(address, SharedRuntime::d2f));
- }
break;
default: ShouldNotReachHere();
@@ -1956,17 +1932,8 @@ void TemplateTable::fast_binaryswitch() {
__ ld( Rarray, Rscratch, Rscratch );
// (Rscratch is already in the native byte-ordering.)
__ cmp( Rkey, Rscratch );
- if ( VM_Version::v9_instructions_work() ) {
- __ movcc( Assembler::less, false, Assembler::icc, Rh, Rj ); // j = h if (key < array[h].fast_match())
- __ movcc( Assembler::greaterEqual, false, Assembler::icc, Rh, Ri ); // i = h if (key >= array[h].fast_match())
- }
- else {
- Label end_of_if;
- __ br( Assembler::less, true, Assembler::pt, end_of_if );
- __ delayed()->mov( Rh, Rj ); // if (<) Rj = Rh
- __ mov( Rh, Ri ); // else i = h
- __ bind(end_of_if); // }
- }
+ __ movcc( Assembler::less, false, Assembler::icc, Rh, Rj ); // j = h if (key < array[h].fast_match())
+ __ movcc( Assembler::greaterEqual, false, Assembler::icc, Rh, Ri ); // i = h if (key >= array[h].fast_match())
// while (i+1 < j)
__ bind( entry );
@@ -3418,9 +3385,7 @@ void TemplateTable::_new() {
// has been allocated.
__ cmp_and_brx_short(RnewTopValue, RendValue, Assembler::greaterUnsigned, Assembler::pn, slow_case);
- __ casx_under_lock(RtopAddr, RoldTopValue, RnewTopValue,
- VM_Version::v9_instructions_work() ? NULL :
- (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
+ __ cas_ptr(RtopAddr, RoldTopValue, RnewTopValue);
// if someone beat us on the allocation, try again, otherwise continue
__ cmp_and_brx_short(RoldTopValue, RnewTopValue, Assembler::notEqual, Assembler::pn, retry);
@@ -3701,14 +3666,7 @@ void TemplateTable::monitorenter() {
__ verify_oop(O4); // verify each monitor's oop
__ tst(O4); // is this entry unused?
- if (VM_Version::v9_instructions_work())
- __ movcc( Assembler::zero, false, Assembler::ptr_cc, O3, O1);
- else {
- Label L;
- __ br( Assembler::zero, true, Assembler::pn, L );
- __ delayed()->mov(O3, O1); // rememeber this one if match
- __ bind(L);
- }
+ __ movcc( Assembler::zero, false, Assembler::ptr_cc, O3, O1);
__ cmp(O4, O0); // check if current entry is for same object
__ brx( Assembler::equal, false, Assembler::pn, exit );
diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
index 03670106924..392b7f5d927 100644
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
@@ -75,23 +75,14 @@ void VM_Version::initialize() {
FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
}
- if (has_v9()) {
- assert(ArraycopySrcPrefetchDistance < 4096, "invalid value");
- if (ArraycopySrcPrefetchDistance >= 4096)
- ArraycopySrcPrefetchDistance = 4064;
- assert(ArraycopyDstPrefetchDistance < 4096, "invalid value");
- if (ArraycopyDstPrefetchDistance >= 4096)
- ArraycopyDstPrefetchDistance = 4064;
- } else {
- if (ArraycopySrcPrefetchDistance > 0) {
- warning("prefetch instructions are not available on this CPU");
- FLAG_SET_DEFAULT(ArraycopySrcPrefetchDistance, 0);
- }
- if (ArraycopyDstPrefetchDistance > 0) {
- warning("prefetch instructions are not available on this CPU");
- FLAG_SET_DEFAULT(ArraycopyDstPrefetchDistance, 0);
- }
- }
+ guarantee(VM_Version::has_v9(), "only SPARC v9 is supported");
+
+ assert(ArraycopySrcPrefetchDistance < 4096, "invalid value");
+ if (ArraycopySrcPrefetchDistance >= 4096)
+ ArraycopySrcPrefetchDistance = 4064;
+ assert(ArraycopyDstPrefetchDistance < 4096, "invalid value");
+ if (ArraycopyDstPrefetchDistance >= 4096)
+ ArraycopyDstPrefetchDistance = 4064;
UseSSE = 0; // Only on x86 and x64
diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
index d602fd08cfb..f4cc8bf56b3 100644
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
@@ -177,10 +177,6 @@ public:
return AllocatePrefetchDistance > 0 ? AllocatePrefetchStyle : 0;
}
- // Legacy
- static bool v8_instructions_work() { return has_v8() && !has_v9(); }
- static bool v9_instructions_work() { return has_v9(); }
-
// Assembler testing
static void allow_all();
static void revert();
diff --git a/hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp b/hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp
deleted file mode 100644
index e13dc36700e..00000000000
--- a/hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.hpp"
-#include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-#include
-
-void MacroAssembler::read_ccr_trap(Register ccr_save) {
- // No implementation
- breakpoint_trap();
-}
-
-void MacroAssembler::write_ccr_trap(Register ccr_save, Register scratch1, Register scratch2) {
- // No implementation
- breakpoint_trap();
-}
-
-void MacroAssembler::flush_windows_trap() { trap(SP_TRAP_FWIN); }
-void MacroAssembler::clean_windows_trap() { trap(SP_TRAP_CWIN); }
-
-// Use software breakpoint trap until we figure out how to do this on Linux
-void MacroAssembler::get_psr_trap() { trap(SP_TRAP_SBPT); }
-void MacroAssembler::set_psr_trap() { trap(SP_TRAP_SBPT); }
diff --git a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp
index fa31a50c327..9de203c1191 100644
--- a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp
+++ b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp
@@ -169,7 +169,6 @@ inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong*
: "memory");
return rv;
#else
- assert(VM_Version::v9_instructions_work(), "cas only supported on v9");
volatile jlong_accessor evl, cvl, rv;
evl.long_value = exchange_value;
cvl.long_value = compare_value;
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp
deleted file mode 100644
index c9e4c2cc0d0..00000000000
--- a/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "asm/macroAssembler.inline.hpp"
-#include "runtime/os.hpp"
-#include "runtime/threadLocalStorage.hpp"
-
-#include // For trap numbers
-#include // For V8 compatibility
-
-void MacroAssembler::read_ccr_trap(Register ccr_save) {
- // Execute a trap to get the PSR, mask and shift
- // to get the condition codes.
- get_psr_trap();
- nop();
- set(PSR_ICC, ccr_save);
- and3(O0, ccr_save, ccr_save);
- srl(ccr_save, PSR_ICC_SHIFT, ccr_save);
-}
-
-void MacroAssembler::write_ccr_trap(Register ccr_save, Register scratch1, Register scratch2) {
- // Execute a trap to get the PSR, shift back
- // the condition codes, mask the condition codes
- // back into and PSR and trap to write back the
- // PSR.
- sll(ccr_save, PSR_ICC_SHIFT, scratch2);
- get_psr_trap();
- nop();
- set(~PSR_ICC, scratch1);
- and3(O0, scratch1, O0);
- or3(O0, scratch2, O0);
- set_psr_trap();
- nop();
-}
-
-void MacroAssembler::flush_windows_trap() { trap(ST_FLUSH_WINDOWS); }
-void MacroAssembler::clean_windows_trap() { trap(ST_CLEAN_WINDOWS); }
-void MacroAssembler::get_psr_trap() { trap(ST_GETPSR); }
-void MacroAssembler::set_psr_trap() { trap(ST_SETPSR); }
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp
index b91214748c2..7d17fdf39cd 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp
@@ -60,21 +60,10 @@ inline jlong Atomic::load(volatile jlong* src) { return *src; }
#else
-extern "C" void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst);
extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst);
inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
-#ifdef COMPILER2
- // Compiler2 does not support v8, it is used only for v9.
_Atomic_move_long_v9(src, dst);
-#else
- // The branch is cheaper then emulated LDD.
- if (VM_Version::v9_instructions_work()) {
- _Atomic_move_long_v9(src, dst);
- } else {
- _Atomic_move_long_v8(src, dst);
- }
-#endif
}
inline jlong Atomic::load(volatile jlong* src) {
@@ -209,7 +198,6 @@ inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong*
: "memory");
return rv;
#else //_LP64
- assert(VM_Version::v9_instructions_work(), "cas only supported on v9");
volatile jlong_accessor evl, cvl, rv;
evl.long_value = exchange_value;
cvl.long_value = compare_value;
@@ -318,7 +306,6 @@ inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong*
// Return 64 bit value in %o0
return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value);
#else // _LP64
- assert (VM_Version::v9_instructions_work(), "only supported on v9");
// Return 64 bit value in %o0,%o1 by hand
return _Atomic_casl(exchange_value, dest, compare_value);
#endif // _LP64
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
index 2821c7077f0..47398351b39 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il
@@ -152,23 +152,6 @@
.nonvolatile
.end
- // Support for jlong Atomic::load and Atomic::store on v8.
- //
- // void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst)
- //
- // Arguments:
- // src: O0
- // dest: O1
- //
- // Overwrites O2 and O3
-
- .inline _Atomic_move_long_v8,2
- .volatile
- ldd [%o0], %o2
- std %o2, [%o1]
- .nonvolatile
- .end
-
// Support for jlong Atomic::load and Atomic::store on v9.
//
// void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst)
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 7cfd7a42eb7..37fc8cd6492 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -1885,21 +1885,6 @@ bool Arguments::check_vm_args_consistency() {
// Note: Needs platform-dependent factoring.
bool status = true;
-#if ( (defined(COMPILER2) && defined(SPARC)))
- // NOTE: The call to VM_Version_init depends on the fact that VM_Version_init
- // on sparc doesn't require generation of a stub as is the case on, e.g.,
- // x86. Normally, VM_Version_init must be called from init_globals in
- // init.cpp, which is called by the initial java thread *after* arguments
- // have been parsed. VM_Version_init gets called twice on sparc.
- extern void VM_Version_init();
- VM_Version_init();
- if (!VM_Version::has_v9()) {
- jio_fprintf(defaultStream::error_stream(),
- "V8 Machine detected, Server requires V9\n");
- status = false;
- }
-#endif /* COMPILER2 && SPARC */
-
// Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product
// builds so the cost of stack banging can be measured.
#if (defined(PRODUCT) && defined(SOLARIS))
From 718f3252f64e4a4da739b1419dc520dd60e3b6dc Mon Sep 17 00:00:00 2001
From: Staffan Larsen
Date: Mon, 10 Jun 2013 11:30:51 +0200
Subject: [PATCH 029/136] 8005849: JEP 167: Event-Based JVM Tracing
Co-authored-by: Karen Kinnear
Co-authored-by: Bengt Rutisson
Co-authored-by: Calvin Cheung
Co-authored-by: Erik Gahlin
Co-authored-by: Erik Helin
Co-authored-by: Jesper Wilhelmsson
Co-authored-by: Keith McGuigan
Co-authored-by: Mattias Tobiasson
Co-authored-by: Markus Gronlund
Co-authored-by: Mikael Auno
Co-authored-by: Nils Eliasson
Co-authored-by: Nils Loodin
Co-authored-by: Rickard Backman
Co-authored-by: Stefan Karlsson
Co-authored-by: Yekaterina Kantserova
Reviewed-by: acorn, coleenp, sla
---
hotspot/make/Makefile | 2 +-
hotspot/make/bsd/makefiles/buildtree.make | 14 +-
hotspot/make/bsd/makefiles/minimal1.make | 3 +-
hotspot/make/bsd/makefiles/top.make | 8 +-
hotspot/make/bsd/makefiles/trace.make | 121 ++++++
hotspot/make/bsd/makefiles/vm.make | 24 +-
hotspot/make/defs.make | 13 +-
hotspot/make/excludeSrc.make | 6 +-
hotspot/make/linux/makefiles/buildtree.make | 18 +-
hotspot/make/linux/makefiles/minimal1.make | 3 +-
hotspot/make/linux/makefiles/top.make | 8 +-
hotspot/make/linux/makefiles/trace.make | 120 ++++++
hotspot/make/linux/makefiles/vm.make | 30 +-
hotspot/make/solaris/makefiles/buildtree.make | 16 +-
hotspot/make/solaris/makefiles/top.make | 10 +-
hotspot/make/solaris/makefiles/trace.make | 116 ++++++
hotspot/make/solaris/makefiles/vm.make | 24 +-
hotspot/make/windows/build.make | 7 +
hotspot/make/windows/create_obj_files.sh | 8 +-
hotspot/make/windows/makefiles/generated.make | 10 +-
.../windows/makefiles/projectcreator.make | 18 +-
hotspot/make/windows/makefiles/trace.make | 121 ++++++
hotspot/make/windows/makefiles/vm.make | 20 +-
.../make/windows/projectfiles/common/Makefile | 14 +-
hotspot/src/cpu/sparc/vm/frame_sparc.cpp | 14 +-
hotspot/src/cpu/x86/vm/frame_x86.cpp | 70 +++-
hotspot/src/os/bsd/vm/osThread_bsd.hpp | 4 +-
hotspot/src/os/bsd/vm/os_bsd.cpp | 311 +++++++++++----
hotspot/src/os/bsd/vm/os_bsd.hpp | 34 +-
hotspot/src/os/bsd/vm/os_bsd.inline.hpp | 16 -
hotspot/src/os/linux/vm/osThread_linux.hpp | 4 +-
hotspot/src/os/linux/vm/os_linux.cpp | 252 +++++++++---
hotspot/src/os/linux/vm/os_linux.hpp | 31 +-
hotspot/src/os/linux/vm/os_linux.inline.hpp | 16 -
.../src/os/solaris/vm/osThread_solaris.cpp | 176 +--------
.../src/os/solaris/vm/osThread_solaris.hpp | 58 +--
.../src/os/solaris/vm/os_share_solaris.hpp | 24 +-
hotspot/src/os/solaris/vm/os_solaris.cpp | 243 +++++++++++-
hotspot/src/os/solaris/vm/os_solaris.hpp | 6 +-
hotspot/src/os/windows/vm/os_windows.cpp | 65 +++
.../src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp | 12 +-
.../src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp | 9 +-
.../os_cpu/linux_x86/vm/thread_linux_x86.cpp | 11 +-
.../os_cpu/linux_x86/vm/thread_linux_x86.hpp | 7 +-
.../solaris_sparc/vm/os_solaris_sparc.cpp | 32 +-
.../solaris_sparc/vm/thread_solaris_sparc.cpp | 14 +-
.../solaris_sparc/vm/thread_solaris_sparc.hpp | 7 +-
.../os_cpu/solaris_x86/vm/os_solaris_x86.cpp | 32 +-
.../solaris_x86/vm/thread_solaris_x86.cpp | 13 +-
.../solaris_x86/vm/thread_solaris_x86.hpp | 8 +-
.../windows_x86/vm/thread_windows_x86.cpp | 12 +-
.../windows_x86/vm/thread_windows_x86.hpp | 8 +-
.../tools/ProjectCreator/BuildConfig.java | 4 +-
.../share/vm/classfile/classFileParser.cpp | 1 +
.../share/vm/classfile/classLoaderData.cpp | 61 +++
.../share/vm/classfile/classLoaderData.hpp | 16 +-
.../src/share/vm/classfile/javaClasses.cpp | 2 +-
.../share/vm/classfile/systemDictionary.cpp | 54 ++-
.../share/vm/classfile/systemDictionary.hpp | 5 +
hotspot/src/share/vm/code/codeCache.cpp | 21 +-
hotspot/src/share/vm/code/codeCache.hpp | 9 +-
.../src/share/vm/compiler/compileBroker.cpp | 31 +-
.../src/share/vm/compiler/compileBroker.hpp | 19 +-
.../concurrentMarkSweepGeneration.cpp | 170 ++++++--
.../concurrentMarkSweepGeneration.hpp | 34 +-
.../concurrentMarkSweepThread.cpp | 4 +-
.../concurrentMarkSweep/vmCMSOperations.cpp | 20 +-
.../gc_implementation/g1/concurrentMark.cpp | 23 +-
.../gc_implementation/g1/concurrentMark.hpp | 4 +-
.../g1/concurrentMarkThread.cpp | 8 +-
.../gc_implementation/g1/evacuationInfo.hpp | 81 ++++
.../gc_implementation/g1/g1CollectedHeap.cpp | 208 +++++++---
.../gc_implementation/g1/g1CollectedHeap.hpp | 57 ++-
.../g1/g1CollectorPolicy.cpp | 8 +-
.../g1/g1CollectorPolicy.hpp | 5 +-
.../gc_implementation/g1/g1GCPhaseTimes.hpp | 2 +-
.../vm/gc_implementation/g1/g1MarkSweep.cpp | 27 +-
.../vm/gc_implementation/g1/g1MarkSweep.hpp | 5 +-
.../g1/g1MonitoringSupport.hpp | 3 +-
.../vm/gc_implementation/g1/g1YCTypes.hpp | 51 +++
.../gc_implementation/g1/vm_operations_g1.cpp | 6 +-
.../parNew/parNewGeneration.cpp | 122 +++---
.../parNew/parNewGeneration.hpp | 21 +-
.../parallelScavenge/parallelScavengeHeap.cpp | 33 +-
.../parallelScavenge/parallelScavengeHeap.hpp | 11 +-
.../parallelScavenge/pcTasks.cpp | 30 +-
.../parallelScavenge/psMarkSweep.cpp | 37 +-
.../parallelScavenge/psParallelCompact.cpp | 74 ++--
.../parallelScavenge/psParallelCompact.hpp | 9 +-
.../parallelScavenge/psPromotionManager.cpp | 18 +-
.../parallelScavenge/psPromotionManager.hpp | 10 +-
.../psPromotionManager.inline.hpp | 4 +-
.../parallelScavenge/psScavenge.cpp | 75 ++--
.../parallelScavenge/psScavenge.hpp | 9 +-
.../shared/copyFailedInfo.hpp | 90 +++++
.../shared/gcHeapSummary.hpp | 142 +++++++
.../vm/gc_implementation/shared/gcTimer.cpp | 374 ++++++++++++++++++
.../vm/gc_implementation/shared/gcTimer.hpp | 195 +++++++++
.../vm/gc_implementation/shared/gcTrace.cpp | 207 ++++++++++
.../vm/gc_implementation/shared/gcTrace.hpp | 255 ++++++++++++
.../gc_implementation/shared/gcTraceSend.cpp | 318 +++++++++++++++
.../gc_implementation/shared/gcTraceTime.cpp | 79 ++++
.../gc_implementation/shared/gcTraceTime.hpp | 44 +++
.../vm/gc_implementation/shared/gcWhen.hpp | 48 +++
.../vm/gc_implementation/shared/markSweep.cpp | 9 +-
.../vm/gc_implementation/shared/markSweep.hpp | 10 +-
.../shared/vmGCOperations.cpp | 41 +-
.../shared/vmGCOperations.hpp | 7 +-
.../src/share/vm/gc_interface/allocTracer.cpp | 48 +++
.../src/share/vm/gc_interface/allocTracer.hpp | 37 ++
.../share/vm/gc_interface/collectedHeap.cpp | 93 ++++-
.../share/vm/gc_interface/collectedHeap.hpp | 61 ++-
.../vm/gc_interface/collectedHeap.inline.hpp | 22 +-
hotspot/src/share/vm/gc_interface/gcCause.cpp | 3 +
hotspot/src/share/vm/gc_interface/gcCause.hpp | 1 +
hotspot/src/share/vm/gc_interface/gcName.hpp | 61 +++
hotspot/src/share/vm/memory/allocation.hpp | 3 +-
.../src/share/vm/memory/defNewGeneration.cpp | 45 ++-
.../src/share/vm/memory/defNewGeneration.hpp | 12 +-
.../src/share/vm/memory/genCollectedHeap.cpp | 13 +-
hotspot/src/share/vm/memory/genMarkSweep.cpp | 28 +-
hotspot/src/share/vm/memory/generation.cpp | 20 +-
.../src/share/vm/memory/heapInspection.cpp | 74 ++--
.../src/share/vm/memory/heapInspection.hpp | 33 +-
.../src/share/vm/memory/klassInfoClosure.hpp | 36 ++
hotspot/src/share/vm/memory/metaspace.hpp | 7 +-
hotspot/src/share/vm/memory/oopFactory.hpp | 3 +-
.../share/vm/memory/referenceProcessor.cpp | 86 ++--
.../share/vm/memory/referenceProcessor.hpp | 38 +-
.../vm/memory/referenceProcessorStats.hpp | 73 ++++
hotspot/src/share/vm/memory/referenceType.hpp | 41 ++
hotspot/src/share/vm/memory/universe.cpp | 35 +-
hotspot/src/share/vm/memory/universe.hpp | 28 +-
hotspot/src/share/vm/oops/instanceKlass.hpp | 2 +
hotspot/src/share/vm/oops/klass.cpp | 3 +-
hotspot/src/share/vm/opto/compile.cpp | 51 ++-
hotspot/src/share/vm/opto/compile.hpp | 37 +-
hotspot/src/share/vm/opto/escape.cpp | 4 +-
hotspot/src/share/vm/opto/library_call.cpp | 3 +-
hotspot/src/share/vm/opto/loopnode.cpp | 10 +-
hotspot/src/share/vm/opto/matcher.cpp | 6 +-
hotspot/src/share/vm/opto/phasetype.hpp | 98 +++++
.../src/share/vm/precompiled/precompiled.hpp | 1 -
hotspot/src/share/vm/prims/jni.cpp | 19 +-
hotspot/src/share/vm/prims/jvm.cpp | 11 +
hotspot/src/share/vm/prims/jvmtiGen.java | 4 +-
hotspot/src/share/vm/prims/jvmtiImpl.cpp | 28 +-
hotspot/src/share/vm/prims/jvmtiImpl.hpp | 77 ++--
hotspot/src/share/vm/prims/unsafe.cpp | 11 +-
hotspot/src/share/vm/runtime/frame.hpp | 3 +-
hotspot/src/share/vm/runtime/frame.inline.hpp | 6 +-
hotspot/src/share/vm/runtime/globals.hpp | 12 +-
hotspot/src/share/vm/runtime/java.cpp | 12 +-
hotspot/src/share/vm/runtime/mutexLocker.cpp | 11 +-
.../src/share/vm/runtime/objectMonitor.cpp | 58 ++-
.../src/share/vm/runtime/objectMonitor.hpp | 15 +-
hotspot/src/share/vm/runtime/os.cpp | 26 +-
hotspot/src/share/vm/runtime/os.hpp | 98 +++++
hotspot/src/share/vm/runtime/perfData.cpp | 4 +
hotspot/src/share/vm/runtime/perfData.hpp | 3 +
hotspot/src/share/vm/runtime/stubRoutines.hpp | 4 +-
hotspot/src/share/vm/runtime/sweeper.cpp | 81 +++-
hotspot/src/share/vm/runtime/sweeper.hpp | 30 +-
hotspot/src/share/vm/runtime/synchronizer.cpp | 4 +-
hotspot/src/share/vm/runtime/task.cpp | 10 +-
hotspot/src/share/vm/runtime/thread.cpp | 24 +-
hotspot/src/share/vm/runtime/thread.hpp | 8 +-
hotspot/src/share/vm/runtime/timer.cpp | 46 +--
hotspot/src/share/vm/runtime/timer.hpp | 18 +-
hotspot/src/share/vm/runtime/vmStructs.cpp | 1 +
hotspot/src/share/vm/runtime/vmThread.cpp | 19 +-
.../src/share/vm/runtime/vm_operations.cpp | 21 +-
.../src/share/vm/runtime/vm_operations.hpp | 4 +-
.../src/share/vm/services/attachListener.cpp | 2 +-
.../share/vm/services/diagnosticArgument.cpp | 29 +-
.../share/vm/services/diagnosticCommand.cpp | 6 +-
hotspot/src/share/vm/services/memBaseline.cpp | 1 +
hotspot/src/share/vm/trace/noTraceBackend.hpp | 48 +++
hotspot/src/share/vm/trace/trace.dtd | 86 ++++
hotspot/src/share/vm/trace/trace.xml | 367 +++++++++++++++++
hotspot/src/share/vm/trace/traceBackend.hpp | 70 ++++
hotspot/src/share/vm/trace/traceDataTypes.hpp | 67 ++++
hotspot/src/share/vm/trace/traceEvent.hpp | 150 +++++++
.../src/share/vm/trace/traceEventClasses.xsl | 246 ++++++++++++
hotspot/src/share/vm/trace/traceEventIds.xsl | 74 ++++
hotspot/src/share/vm/trace/traceMacros.hpp | 16 +-
hotspot/src/share/vm/trace/traceStream.hpp | 121 ++++++
.../{traceEventTypes.hpp => traceTime.hpp} | 11 +-
hotspot/src/share/vm/trace/traceTypes.xsl | 72 ++++
hotspot/src/share/vm/trace/tracetypes.xml | 368 +++++++++++++++++
hotspot/src/share/vm/trace/tracing.hpp | 5 +-
hotspot/src/share/vm/trace/xinclude.mod | 61 +++
hotspot/src/share/vm/trace/xsl_util.xsl | 78 ++++
.../share/vm/utilities/globalDefinitions.hpp | 12 -
hotspot/src/share/vm/utilities/macros.hpp | 4 +
195 files changed, 7628 insertions(+), 1484 deletions(-)
create mode 100644 hotspot/make/bsd/makefiles/trace.make
create mode 100644 hotspot/make/linux/makefiles/trace.make
create mode 100644 hotspot/make/solaris/makefiles/trace.make
create mode 100644 hotspot/make/windows/makefiles/trace.make
create mode 100644 hotspot/src/share/vm/gc_implementation/g1/evacuationInfo.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1YCTypes.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/copyFailedInfo.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTimer.cpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTimer.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp
create mode 100644 hotspot/src/share/vm/gc_implementation/shared/gcWhen.hpp
create mode 100644 hotspot/src/share/vm/gc_interface/allocTracer.cpp
create mode 100644 hotspot/src/share/vm/gc_interface/allocTracer.hpp
create mode 100644 hotspot/src/share/vm/gc_interface/gcName.hpp
create mode 100644 hotspot/src/share/vm/memory/klassInfoClosure.hpp
create mode 100644 hotspot/src/share/vm/memory/referenceProcessorStats.hpp
create mode 100644 hotspot/src/share/vm/memory/referenceType.hpp
create mode 100644 hotspot/src/share/vm/opto/phasetype.hpp
create mode 100644 hotspot/src/share/vm/trace/noTraceBackend.hpp
create mode 100644 hotspot/src/share/vm/trace/trace.dtd
create mode 100644 hotspot/src/share/vm/trace/trace.xml
create mode 100644 hotspot/src/share/vm/trace/traceBackend.hpp
create mode 100644 hotspot/src/share/vm/trace/traceDataTypes.hpp
create mode 100644 hotspot/src/share/vm/trace/traceEvent.hpp
create mode 100644 hotspot/src/share/vm/trace/traceEventClasses.xsl
create mode 100644 hotspot/src/share/vm/trace/traceEventIds.xsl
create mode 100644 hotspot/src/share/vm/trace/traceStream.hpp
rename hotspot/src/share/vm/trace/{traceEventTypes.hpp => traceTime.hpp} (81%)
create mode 100644 hotspot/src/share/vm/trace/traceTypes.xsl
create mode 100644 hotspot/src/share/vm/trace/tracetypes.xml
create mode 100644 hotspot/src/share/vm/trace/xinclude.mod
create mode 100644 hotspot/src/share/vm/trace/xsl_util.xsl
diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile
index 526ed2393f2..2975088cb49 100644
--- a/hotspot/make/Makefile
+++ b/hotspot/make/Makefile
@@ -486,7 +486,7 @@ $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/services/%
JFR_EXISTS=$(shell if [ -d $(HS_ALT_SRC) ]; then echo 1; else echo 0; fi)
# export jfr.h
ifeq ($JFR_EXISTS,1)
-$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/agent/%
+$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/%
$(install-file)
else
$(EXPORT_INCLUDE_DIR)/jfr.h:
diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make
index 16a0f9a64ff..ca9d19e0d23 100644
--- a/hotspot/make/bsd/makefiles/buildtree.make
+++ b/hotspot/make/bsd/makefiles/buildtree.make
@@ -47,6 +47,7 @@
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
# adlc.make -
+# trace.make - generate tracing event and type definitions
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
#
@@ -119,6 +120,7 @@ SIMPLE_DIRS = \
$(PLATFORM_DIR)/generated/dependencies \
$(PLATFORM_DIR)/generated/adfiles \
$(PLATFORM_DIR)/generated/jvmtifiles \
+ $(PLATFORM_DIR)/generated/tracefiles \
$(PLATFORM_DIR)/generated/dtracefiles
TARGETS = debug fastdebug optimized product
@@ -128,7 +130,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
# dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make dtrace.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make dtrace.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -331,6 +333,16 @@ jvmti.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
+trace.make: $(BUILDTREE_MAKE)
+ @echo Creating $@ ...
+ $(QUIETLY) ( \
+ $(BUILDTREE_COMMENT); \
+ echo; \
+ echo include flags.make; \
+ echo; \
+ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+ ) > $@
+
sa.make: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
diff --git a/hotspot/make/bsd/makefiles/minimal1.make b/hotspot/make/bsd/makefiles/minimal1.make
index abfbc4c9490..42d794ab747 100644
--- a/hotspot/make/bsd/makefiles/minimal1.make
+++ b/hotspot/make/bsd/makefiles/minimal1.make
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
TYPE=MINIMAL1
@@ -32,6 +32,7 @@ INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
+INCLUDE_TRACE ?= false
INCLUDE_CDS ?= false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
diff --git a/hotspot/make/bsd/makefiles/top.make b/hotspot/make/bsd/makefiles/top.make
index 647e132b076..aebadebe35c 100644
--- a/hotspot/make/bsd/makefiles/top.make
+++ b/hotspot/make/bsd/makefiles/top.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@ default: vm_build_preliminaries the_vm
@echo All done.
# This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff dtrace_stuff
+vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff dtrace_stuff
@# We need a null action here, so implicit rules don't get consulted.
$(Cached_plat): $(Plat_File)
@@ -94,6 +94,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
+# generate trace files
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+ @$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
ifeq ($(OS_VENDOR), Darwin)
# generate dtrace header files
dtrace_stuff: $(Cached_plat) $(adjust-mflags)
diff --git a/hotspot/make/bsd/makefiles/trace.make b/hotspot/make/bsd/makefiles/trace.make
new file mode 100644
index 00000000000..ceb40c87846
--- /dev/null
+++ b/hotspot/make/bsd/makefiles/trace.make
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/bsd/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+ echo "true"; else echo "false";\
+ fi)
+
+TOPDIR = $(shell echo `pwd`)
+GENERATED = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames = \
+ traceEventClasses.hpp \
+ traceEventIds.hpp \
+ traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
+
+ifneq ($(INCLUDE_TRACE), false)
+TraceGeneratedNames += traceProducer.cpp
+endif
+
+endif
+
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
+ $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+ XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+ $(QUIETLY) echo Generating $@; \
+ $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+ test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+
+clean cleanall:
+ rm $(TraceGeneratedFiles)
+
diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make
index 7342ca3a1a7..ba2eb0756a3 100644
--- a/hotspot/make/bsd/makefiles/vm.make
+++ b/hotspot/make/bsd/makefiles/vm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Rules to build JVM and related libraries, included from vm.make in the build
@@ -52,7 +52,7 @@ endif
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
# The adfiles directory contains ad_.[ch]pp.
# The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
VPATH += $(Src_Dirs_V:%=%:)
# set INCLUDES for C preprocessor.
@@ -66,7 +66,7 @@ else
SYMFLAG =
endif
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
# in $(GAMMADIR)/make/defs.make
ifeq ($(HOTSPOT_BUILD_VERSION),)
BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
@@ -93,7 +93,7 @@ CXXFLAGS = \
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date.
+# a time and date.
CXXFLAGS/vm_version.o += ${JRE_VERSION}
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -105,10 +105,6 @@ ifdef DEFAULT_LIBPATH
CXXFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
endif
-ifndef JAVASE_EMBEDDED
-CFLAGS += -DINCLUDE_TRACE
-endif
-
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN/BYFILE)
@@ -165,15 +161,15 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
-ifndef JAVASE_EMBEDDED
-SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
fi)
endif
-CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
-CORE_PATHS+=$(GENERATED)/jvmtifiles
-
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make
index 4e4c2cb0120..5ebf167e290 100644
--- a/hotspot/make/defs.make
+++ b/hotspot/make/defs.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# The common definitions for hotspot builds.
@@ -236,7 +236,7 @@ ifneq ($(ALT_JDK_IMAGE_DIR),)
JDK_IMAGE_DIR=$(ALT_JDK_IMAGE_DIR)
endif
-# The platform dependent defs.make defines platform specific variable such
+# The platform dependent defs.make defines platform specific variable such
# as ARCH, EXPORT_LIST etc. We must place the include here after BOOTDIR is defined.
include $(GAMMADIR)/make/$(OSNAME)/makefiles/defs.make
@@ -258,7 +258,7 @@ ifneq ($(OSNAME),windows)
# LIBARCH - directory name in JDK/JRE
# Use uname output for SRCARCH, but deal with platform differences. If ARCH
- # is not explicitly listed below, it is treated as x86.
+ # is not explicitly listed below, it is treated as x86.
SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc zero,$(ARCH)))
ARCH/ = x86
ARCH/sparc = sparc
@@ -337,8 +337,5 @@ EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
-ifndef JAVASE_EMBEDDED
-EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
-endif
-
.PHONY: $(HS_ALT_MAKE)/defs.make
+
diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make
index 2ce60e0a656..88bab5c39ad 100644
--- a/hotspot/make/excludeSrc.make
+++ b/hotspot/make/excludeSrc.make
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
ifeq ($(INCLUDE_JVMTI), false)
CXXFLAGS += -DINCLUDE_JVMTI=0
@@ -100,7 +100,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp
-endif
+endif
ifeq ($(INCLUDE_NMT), false)
CXXFLAGS += -DINCLUDE_NMT=0
@@ -110,3 +110,5 @@ ifeq ($(INCLUDE_NMT), false)
memBaseline.cpp memPtr.cpp memRecorder.cpp memReporter.cpp memSnapshot.cpp memTrackWorker.cpp \
memTracker.cpp nmtDCmd.cpp
endif
+
+-include $(HS_ALT_MAKE)/excludeSrc.make
diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make
index 3b715773554..fd6c52513fe 100644
--- a/hotspot/make/linux/makefiles/buildtree.make
+++ b/hotspot/make/linux/makefiles/buildtree.make
@@ -47,6 +47,7 @@
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
# adlc.make -
+# trace.make - generate tracing event and type definitions
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
#
@@ -114,7 +115,8 @@ COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
SIMPLE_DIRS = \
$(PLATFORM_DIR)/generated/dependencies \
$(PLATFORM_DIR)/generated/adfiles \
- $(PLATFORM_DIR)/generated/jvmtifiles
+ $(PLATFORM_DIR)/generated/jvmtifiles \
+ $(PLATFORM_DIR)/generated/tracefiles
TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
@@ -122,7 +124,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -269,6 +271,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
echo && \
echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
+ [ -n "$(INCLUDE_TRACE)" ] && \
+ echo && echo "INCLUDE_TRACE = $(INCLUDE_TRACE)"; \
echo; \
[ -n "$(SPEC)" ] && \
echo "include $(SPEC)"; \
@@ -337,6 +341,16 @@ jvmti.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
+trace.make: $(BUILDTREE_MAKE)
+ @echo Creating $@ ...
+ $(QUIETLY) ( \
+ $(BUILDTREE_COMMENT); \
+ echo; \
+ echo include flags.make; \
+ echo; \
+ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+ ) > $@
+
sa.make: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
diff --git a/hotspot/make/linux/makefiles/minimal1.make b/hotspot/make/linux/makefiles/minimal1.make
index abfbc4c9490..42d794ab747 100644
--- a/hotspot/make/linux/makefiles/minimal1.make
+++ b/hotspot/make/linux/makefiles/minimal1.make
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
TYPE=MINIMAL1
@@ -32,6 +32,7 @@ INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
+INCLUDE_TRACE ?= false
INCLUDE_CDS ?= false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
diff --git a/hotspot/make/linux/makefiles/top.make b/hotspot/make/linux/makefiles/top.make
index 011d46a05b8..95e6e6856e8 100644
--- a/hotspot/make/linux/makefiles/top.make
+++ b/hotspot/make/linux/makefiles/top.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@ default: vm_build_preliminaries the_vm
@echo All done.
# This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
+vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) trace_stuff jvmti_stuff sa_stuff
@# We need a null action here, so implicit rules don't get consulted.
$(Cached_plat): $(Plat_File)
@@ -94,6 +94,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
+# generate trace files
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+ @$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
# generate SA jar files and native header
sa_stuff:
@$(MAKE) -f sa.make $(MFLAGS-adjusted)
diff --git a/hotspot/make/linux/makefiles/trace.make b/hotspot/make/linux/makefiles/trace.make
new file mode 100644
index 00000000000..f173e0ad3ab
--- /dev/null
+++ b/hotspot/make/linux/makefiles/trace.make
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/linux/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+ echo "true"; else echo "false";\
+ fi)
+
+TOPDIR = $(shell echo `pwd`)
+GENERATED = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames = \
+ traceEventClasses.hpp \
+ traceEventIds.hpp \
+ traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp
+
+ifneq ($(INCLUDE_TRACE), false)
+TraceGeneratedNames += traceProducer.cpp
+endif
+
+endif
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
+ $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+ XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+ $(QUIETLY) echo Generating $@; \
+ $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+ test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+clean cleanall:
+ rm $(TraceGeneratedFiles)
+
+
diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make
index 79a926a8c4f..d9db77744a4 100644
--- a/hotspot/make/linux/makefiles/vm.make
+++ b/hotspot/make/linux/makefiles/vm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Rules to build JVM and related libraries, included from vm.make in the build
@@ -52,7 +52,7 @@ endif
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
# The adfiles directory contains ad_.[ch]pp.
# The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
VPATH += $(Src_Dirs_V:%=%:)
# set INCLUDES for C preprocessor.
@@ -72,7 +72,7 @@ else
endif
endif
-# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
+# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
# in $(GAMMADIR)/make/defs.make
ifeq ($(HOTSPOT_BUILD_VERSION),)
BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
@@ -99,7 +99,7 @@ CXXFLAGS = \
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date.
+# a time and date.
CXXFLAGS/vm_version.o += ${JRE_VERSION}
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -108,12 +108,6 @@ CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
CXXFLAGS += $(CXXFLAGS/BYFILE)
-ifndef JAVASE_EMBEDDED
-ifneq (${ARCH},arm)
-CFLAGS += -DINCLUDE_TRACE
-endif
-endif
-
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN/BYFILE)
@@ -158,16 +152,14 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
-ifndef JAVASE_EMBEDDED
-ifneq (${ARCH},arm)
-SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
fi)
endif
-endif
-
-CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
-CORE_PATHS+=$(GENERATED)/jvmtifiles
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
@@ -316,7 +308,7 @@ endif
# With more recent Redhat releases (or the cutting edge version Fedora), if
# SELinux is configured to be enabled, the runtime linker will fail to apply
# the text relocation to libjvm.so considering that it is built as a non-PIC
-# DSO. To workaround that, we run chcon to libjvm.so after it is built. See
+# DSO. To workaround that, we run chcon to libjvm.so after it is built. See
# details in bug 6538311.
$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
$(QUIETLY) { \
diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make
index 5827c4ff7d9..ca602a81e3c 100644
--- a/hotspot/make/solaris/makefiles/buildtree.make
+++ b/hotspot/make/solaris/makefiles/buildtree.make
@@ -47,6 +47,7 @@
# flags.make - with macro settings
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
# adlc.make -
+# trace.make - generate tracing event and type definitions
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
# sa.make - generate SA jar file and natives
#
@@ -107,7 +108,8 @@ COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
SIMPLE_DIRS = \
$(PLATFORM_DIR)/generated/dependencies \
$(PLATFORM_DIR)/generated/adfiles \
- $(PLATFORM_DIR)/generated/jvmtifiles
+ $(PLATFORM_DIR)/generated/jvmtifiles \
+ $(PLATFORM_DIR)/generated/tracefiles
TARGETS = debug fastdebug optimized product
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
@@ -115,7 +117,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
# For dependencies and recursive makes.
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
-BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
+BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
@@ -327,6 +329,16 @@ jvmti.make: $(BUILDTREE_MAKE)
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
) > $@
+trace.make: $(BUILDTREE_MAKE)
+ @echo Creating $@ ...
+ $(QUIETLY) ( \
+ $(BUILDTREE_COMMENT); \
+ echo; \
+ echo include flags.make; \
+ echo; \
+ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
+ ) > $@
+
sa.make: $(BUILDTREE_MAKE)
@echo Creating $@ ...
$(QUIETLY) ( \
diff --git a/hotspot/make/solaris/makefiles/top.make b/hotspot/make/solaris/makefiles/top.make
index 1d31f1e8d55..81e34afdee5 100644
--- a/hotspot/make/solaris/makefiles/top.make
+++ b/hotspot/make/solaris/makefiles/top.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@ default: vm_build_preliminaries the_vm
@echo All done.
# This is an explicit dependency for the sake of parallel makes.
-vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
+vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff
@# We need a null action here, so implicit rules don't get consulted.
$(Cached_plat): $(Plat_File)
@@ -87,6 +87,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
+# generate trace files
+trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
+ @$(MAKE) -f trace.make $(MFLAGS-adjusted)
+
# generate SA jar files and native header
sa_stuff:
@$(MAKE) -f sa.make $(MFLAGS-adjusted)
@@ -127,5 +131,5 @@ realclean:
rm -fr $(GENERATED)
.PHONY: default vm_build_preliminaries
-.PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
+.PHONY: lists ad_stuff jvmti_stuff trace_stuff sa_stuff the_vm clean realclean
.PHONY: checks check_os_version install
diff --git a/hotspot/make/solaris/makefiles/trace.make b/hotspot/make/solaris/makefiles/trace.make
new file mode 100644
index 00000000000..16c82cd780b
--- /dev/null
+++ b/hotspot/make/solaris/makefiles/trace.make
@@ -0,0 +1,116 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+include $(GAMMADIR)/make/solaris/makefiles/rules.make
+include $(GAMMADIR)/make/altsrc.make
+
+# #########################################################################
+
+HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
+ echo "true"; else echo "false";\
+ fi)
+
+TOPDIR = $(shell echo `pwd`)
+GENERATED = $(TOPDIR)/../generated
+JvmtiOutDir = $(GENERATED)/jvmtifiles
+TraceOutDir = $(GENERATED)/tracefiles
+
+TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
+TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
+
+# set VPATH so make knows where to look for source files
+Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
+VPATH += $(Src_Dirs_V:%=%:)
+
+TraceGeneratedNames = \
+ traceEventClasses.hpp \
+ traceEventIds.hpp \
+ traceTypes.hpp
+
+ifeq ($(HAS_ALT_SRC), true)
+TraceGeneratedNames += \
+ traceRequestables.hpp \
+ traceEventControl.hpp \
+ traceProducer.cpp
+endif
+
+TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
+
+XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
+ $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+ifeq ($(HAS_ALT_SRC), true)
+ XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
+endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+all: $(TraceGeneratedFiles)
+
+GENERATE_CODE= \
+ $(QUIETLY) echo Generating $@; \
+ $(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
+ test -f $@
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+ifeq ($(HAS_ALT_SRC), false)
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+ $(GENERATE_CODE)
+
+endif
+
+# #########################################################################
+
+clean cleanall:
+ rm $(TraceGeneratedFiles)
+
+
diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make
index 855f7f18861..d57716c7aab 100644
--- a/hotspot/make/solaris/makefiles/vm.make
+++ b/hotspot/make/solaris/makefiles/vm.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -19,7 +19,7 @@
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
-#
+#
#
# Rules to build JVM and related libraries, included from vm.make in the build
@@ -48,7 +48,7 @@ include $(MAKEFILES_DIR)/$(BUILDARCH).make
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
# The adfiles directory contains ad_.[ch]pp.
# The jvmtifiles directory contains jvmti*.[ch]pp
-Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
+Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
VPATH += $(Src_Dirs_V:%=%:)
# set INCLUDES for C preprocessor
@@ -87,7 +87,7 @@ CXXFLAGS = \
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
-# a time and date.
+# a time and date.
CXXFLAGS/vm_version.o += ${JRE_VERSION}
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
@@ -103,7 +103,7 @@ CFLAGS += $(CFLAGS_WARN)
CFLAGS += $(CFLAGS/NOEX)
# Extra flags from gnumake's invocation or environment
-CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE
+CFLAGS += $(EXTRA_CFLAGS)
# Math Library (libm.so), do not use -lm.
# There might be two versions of libm.so on the build system:
@@ -137,9 +137,7 @@ else
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
endif # sparcWorks
-ifeq ("${Platform_arch}", "sparc")
LIBS += -lkstat
-endif
# By default, link the *.o into the library, not the executable.
LINK_INTO$(LINK_INTO) = LIBJVM
@@ -177,12 +175,14 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
-SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
+CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
+CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
+
+ifneq ($(INCLUDE_TRACE), false)
+CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
fi)
-
-CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
-CORE_PATHS+=$(GENERATED)/jvmtifiles
+endif
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
@@ -287,7 +287,7 @@ else
LINK_VM = $(LINK_LIB.CXX)
endif
# making the library:
-$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
+$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
@echo Linking vm...
$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
diff --git a/hotspot/make/windows/build.make b/hotspot/make/windows/build.make
index c072a170135..7c66b206c3e 100644
--- a/hotspot/make/windows/build.make
+++ b/hotspot/make/windows/build.make
@@ -196,6 +196,12 @@ HS_BUILD_VER=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)
# End VERSIONINFO parameters
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+!ifndef OPENJDK
+!if !exists($(WorkSpace)\src\closed)
+OPENJDK=true
+!endif
+!endif
# We don't support SA on ia64, and we can't
# build it if we are using a version of Vis Studio
@@ -273,6 +279,7 @@ $(variantDir)\local.make: checks
@ echo HS_COMPANY=$(COMPANY_NAME) >> $@
@ echo HS_FILEDESC=$(HS_FILEDESC) >> $@
@ echo HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) >> $@
+ @ if "$(OPENJDK)" NEQ "" echo OPENJDK=$(OPENJDK) >> $@
@ echo HS_COPYRIGHT=$(HOTSPOT_VM_COPYRIGHT) >> $@
@ echo HS_NAME=$(PRODUCT_NAME) $(JDK_MKTG_VERSION) >> $@
@ echo HS_BUILD_VER=$(HS_BUILD_VER) >> $@
diff --git a/hotspot/make/windows/create_obj_files.sh b/hotspot/make/windows/create_obj_files.sh
index 257b3f140d2..b162bd07b60 100644
--- a/hotspot/make/windows/create_obj_files.sh
+++ b/hotspot/make/windows/create_obj_files.sh
@@ -71,13 +71,11 @@ for sd in \
BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/${sd}"
done
-BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles"
+BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles"
if [ -d "${ALTSRC}/share/vm/jfr" ]; then
- BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent"
- BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent/isolated_deps/util"
- BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/jvm"
- BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+ BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers"
fi
BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods"
diff --git a/hotspot/make/windows/makefiles/generated.make b/hotspot/make/windows/makefiles/generated.make
index d5add4b030f..aaaa8e7c2b6 100644
--- a/hotspot/make/windows/makefiles/generated.make
+++ b/hotspot/make/windows/makefiles/generated.make
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,15 +30,19 @@
JvmtiOutDir=jvmtifiles
!include $(WorkSpace)/make/windows/makefiles/jvmti.make
+# Pick up rules for building trace
+TraceOutDir=tracefiles
+!include $(WorkSpace)/make/windows/makefiles/trace.make
+
# Pick up rules for building SA
!include $(WorkSpace)/make/windows/makefiles/sa.make
AdlcOutDir=adfiles
!if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
-default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) buildobjfiles
+default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
!else
-default:: $(JvmtiGeneratedFiles) buildobjfiles
+default:: $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
!endif
buildobjfiles:
diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make
index f142852ed12..7aa3ef65cad 100644
--- a/hotspot/make/windows/makefiles/projectcreator.make
+++ b/hotspot/make/windows/makefiles/projectcreator.make
@@ -19,7 +19,7 @@
# Please 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 $(WorkSpace)/make/windows/makefiles/rules.make
@@ -72,7 +72,7 @@ ProjectCreatorIncludesPRIVATE=\
-ignorePath ppc \
-ignorePath zero \
-hidePath .hg
-
+
# This is referenced externally by both the IDE and batch builds
ProjectCreatorOptions=
@@ -89,7 +89,7 @@ ProjectCreatorIDEOptions = \
-disablePch bytecodeInterpreter.cpp \
-disablePch bytecodeInterpreterWithChecks.cpp \
-disablePch getThread_windows_$(Platform_arch).cpp \
- -disablePch_compiler2 opcodes.cpp
+ -disablePch_compiler2 opcodes.cpp
# Common options for the IDE builds for core, c1, and c2
ProjectCreatorIDEOptions=\
@@ -115,7 +115,7 @@ ProjectCreatorIDEOptions=\
-define TARGET_OS_ARCH_windows_x86 \
-define TARGET_OS_FAMILY_windows \
-define TARGET_COMPILER_visCPP \
- -define INCLUDE_TRACE \
+ -define INCLUDE_TRACE=1 \
$(ProjectCreatorIncludesPRIVATE)
# Add in build-specific options
@@ -203,4 +203,12 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
-additionalFile jvmtiEnter.cpp \
-additionalFile jvmtiEnterTrace.cpp \
-additionalFile jvmti.h \
- -additionalFile bytecodeInterpreterWithChecks.cpp
+ -additionalFile bytecodeInterpreterWithChecks.cpp \
+ -additionalFile traceEventClasses.hpp \
+ -additionalFile traceEventIds.hpp \
+!if "$(OPENJDK)" != "true"
+ -additionalFile traceRequestables.hpp \
+ -additionalFile traceEventControl.hpp \
+ -additionalFile traceProducer.cpp \
+!endif
+ -additionalFile traceTypes.hpp
diff --git a/hotspot/make/windows/makefiles/trace.make b/hotspot/make/windows/makefiles/trace.make
new file mode 100644
index 00000000000..82422b173cf
--- /dev/null
+++ b/hotspot/make/windows/makefiles/trace.make
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+
+# This makefile (trace.make) is included from the trace.make in the
+# build directories.
+#
+# It knows how to build and run the tools to generate trace files.
+
+!include $(WorkSpace)/make/windows/makefiles/rules.make
+
+# #########################################################################
+
+
+TraceAltSrcDir = $(WorkSpace)/src/closed/share/vm/trace
+TraceSrcDir = $(WorkSpace)/src/share/vm/trace
+
+TraceGeneratedNames = \
+ traceEventClasses.hpp \
+ traceEventIds.hpp \
+ traceTypes.hpp
+
+
+!if "$(OPENJDK)" != "true"
+TraceGeneratedNames = $(TraceGeneratedNames) \
+ traceRequestables.hpp \
+ traceEventControl.hpp \
+ traceProducer.cpp
+!endif
+
+
+#Note: TraceGeneratedFiles must be kept in sync with TraceGeneratedNames by hand.
+#Should be equivalent to "TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)"
+TraceGeneratedFiles = \
+ $(TraceOutDir)/traceEventClasses.hpp \
+ $(TraceOutDir)/traceEventIds.hpp \
+ $(TraceOutDir)/traceTypes.hpp
+
+!if "$(OPENJDK)" != "true"
+TraceGeneratedFiles = $(TraceGeneratedFiles) \
+ $(TraceOutDir)/traceRequestables.hpp \
+ $(TraceOutDir)/traceEventControl.hpp \
+ $(TraceOutDir)/traceProducer.cpp
+!endif
+
+XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
+
+XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
+ $(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
+
+!if "$(OPENJDK)" != "true"
+XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml
+!endif
+
+.PHONY: all clean cleanall
+
+# #########################################################################
+
+default::
+ @if not exist $(TraceOutDir) mkdir $(TraceOutDir)
+
+$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventIds.xsl -OUT $(TraceOutDir)/traceEventIds.hpp
+
+$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
+
+!if "$(OPENJDK)" == "true"
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+
+!else
+
+$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
+
+$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
+
+$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
+
+$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
+ @echo Generating $@
+ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
+
+!endif
+
+# #########################################################################
+
+cleanall :
+ rm $(TraceGeneratedFiles)
+
+
diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make
index 9e7c64b8f33..54ba1eef5b8 100644
--- a/hotspot/make/windows/makefiles/vm.make
+++ b/hotspot/make/windows/makefiles/vm.make
@@ -66,10 +66,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\""
CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
-!ifndef JAVASE_EMBEDDED
-CXX_FLAGS=$(CXX_FLAGS) /D "INCLUDE_TRACE"
-!endif
-
CXX_FLAGS=$(CXX_FLAGS) $(CXX_INCLUDE_DIRS)
# Define that so jni.h is on correct side
@@ -144,6 +140,7 @@ CXX_USE_PCH=$(CXX_DONT_USE_PCH)
VM_PATH=../generated
VM_PATH=$(VM_PATH);../generated/adfiles
VM_PATH=$(VM_PATH);../generated/jvmtifiles
+VM_PATH=$(VM_PATH);../generated/tracefiles
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
@@ -172,10 +169,8 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
!if exists($(ALTSRC)\share\vm\jfr)
-VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent
-VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent/isolated_deps/util
-VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/jvm
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr
+VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/buffers
!endif
VM_PATH={$(VM_PATH)}
@@ -384,16 +379,13 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{..\generated\jvmtifiles}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+{..\generated\tracefiles}.cpp.obj::
+ $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
{$(ALTSRC)\share\vm\jfr}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj::
- $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
-{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj::
- $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
-
-{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj::
+{$(ALTSRC)\share\vm\jfr\buffers}.cpp.obj::
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
default::
diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile
index 5556aae5149..8ae363be7d5 100644
--- a/hotspot/make/windows/projectfiles/common/Makefile
+++ b/hotspot/make/windows/projectfiles/common/Makefile
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,12 @@ BootStrapDir=$(HOTSPOTJDKDIST)
!endif
!endif
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+!ifndef OPENJDK
+!if !exists($(WorkSpace)\src\closed)
+OPENJDK=true
+!endif
+!endif
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make
@@ -54,6 +60,10 @@ BootStrapDir=$(HOTSPOTJDKDIST)
JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/jvmti.make
+# Pick up rules for building trace
+TraceOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\tracefiles
+!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/trace.make
+
!if "$(Variant)" == "compiler2"
# Pick up rules for building adlc
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make
@@ -66,7 +76,7 @@ JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
HS_INTERNAL_NAME=jvm
-default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
+default:: $(AdditionalTargets) $(JvmtiGeneratedFiles) $(TraceGeneratedFiles)
!include $(HOTSPOTWORKSPACE)/make/hotspot_version
diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
index 94cef1a9a25..b550d77a8bf 100644
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
@@ -252,6 +252,16 @@ bool frame::safe_for_sender(JavaThread *thread) {
return false;
}
+ // Could be a zombie method
+ if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+ return false;
+ }
+
+ // Could be a zombie method
+ if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+ return false;
+ }
+
// It should be safe to construct the sender though it might not be valid
frame sender(_SENDER_SP, younger_sp, adjusted_stack);
@@ -294,10 +304,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
return jcw_safe;
}
- // If the frame size is 0 something is bad because every nmethod has a non-zero frame size
+ // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
// because you must allocate window space
- if (sender_blob->frame_size() == 0) {
+ if (sender_blob->frame_size() <= 0) {
assert(!sender_blob->is_nmethod(), "should count return address at least");
return false;
}
diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp
index 93180c8e37d..92587985dab 100644
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
+#include "runtime/os.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
@@ -54,16 +55,22 @@ bool frame::safe_for_sender(JavaThread *thread) {
address sp = (address)_sp;
address fp = (address)_fp;
address unextended_sp = (address)_unextended_sp;
- // sp must be within the stack
- bool sp_safe = (sp <= thread->stack_base()) &&
- (sp >= thread->stack_base() - thread->stack_size());
+
+ // consider stack guards when trying to determine "safe" stack pointers
+ static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
+ size_t usable_stack_size = thread->stack_size() - stack_guard_size;
+
+ // sp must be within the usable part of the stack (not in guards)
+ bool sp_safe = (sp < thread->stack_base()) &&
+ (sp >= thread->stack_base() - usable_stack_size);
+
if (!sp_safe) {
return false;
}
// unextended sp must be within the stack and above or equal sp
- bool unextended_sp_safe = (unextended_sp <= thread->stack_base()) &&
+ bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
(unextended_sp >= sp);
if (!unextended_sp_safe) {
@@ -71,7 +78,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
// an fp must be within the stack and above (but not equal) sp
- bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
+ // second evaluation on fp+ is added to handle situation where fp is -1
+ bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
// We know sp/unextended_sp are safe only fp is questionable here
@@ -86,6 +94,13 @@ bool frame::safe_for_sender(JavaThread *thread) {
// other generic buffer blobs are more problematic so we just assume they are
// ok. adapter blobs never have a frame complete and are never ok.
+ // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
+
+ if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) {
+ //assert(0, "Invalid frame_size");
+ return false;
+ }
+
if (!_cb->is_frame_complete_at(_pc)) {
if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
return false;
@@ -107,7 +122,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
address jcw = (address)entry_frame_call_wrapper();
- bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > fp);
+ bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
return jcw_safe;
@@ -134,12 +149,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
sender_pc = (address) *(sender_sp-1);
}
- // We must always be able to find a recognizable pc
- CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
- if (sender_pc == NULL || sender_blob == NULL) {
- return false;
- }
-
// If the potential sender is the interpreter then we can do some more checking
if (Interpreter::contains(sender_pc)) {
@@ -149,7 +158,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// is really a frame pointer.
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
- bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
+ bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
return false;
@@ -163,6 +172,17 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
+ // We must always be able to find a recognizable pc
+ CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
+ if (sender_pc == NULL || sender_blob == NULL) {
+ return false;
+ }
+
+ // Could be a zombie method
+ if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
+ return false;
+ }
+
// Could just be some random pointer within the codeBlob
if (!sender_blob->code_contains(sender_pc)) {
return false;
@@ -174,10 +194,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
// Could be the call_stub
-
if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
- bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
+ bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
return false;
@@ -190,15 +209,24 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
- bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > (address)sender.fp());
+ bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
return jcw_safe;
}
- // If the frame size is 0 something is bad because every nmethod has a non-zero frame size
+ if (sender_blob->is_nmethod()) {
+ nmethod* nm = sender_blob->as_nmethod_or_null();
+ if (nm != NULL) {
+ if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
+ return false;
+ }
+ }
+ }
+
+ // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
// because the return address counts against the callee's frame.
- if (sender_blob->frame_size() == 0) {
+ if (sender_blob->frame_size() <= 0) {
assert(!sender_blob->is_nmethod(), "should count return address at least");
return false;
}
@@ -208,7 +236,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
// should not be anything but the call stub (already covered), the interpreter (already covered)
// or an nmethod.
- assert(sender_blob->is_nmethod(), "Impossible call chain");
+ if (!sender_blob->is_nmethod()) {
+ return false;
+ }
// Could put some more validation for the potential non-interpreted sender
// frame we'd create by calling sender if I could think of any. Wait for next crash in forte...
diff --git a/hotspot/src/os/bsd/vm/osThread_bsd.hpp b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
index b49c3caec6e..fe903eb58d2 100644
--- a/hotspot/src/os/bsd/vm/osThread_bsd.hpp
+++ b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@ public:
// flags that support signal based suspend/resume on Bsd are in a
// separate class to avoid confusion with many flags in OSThread that
// are used by VM level suspend/resume.
- os::Bsd::SuspendResume sr;
+ os::SuspendResume sr;
// _ucontext and _siginfo are used by SR_handler() to save thread context,
// and they will later be used to walk the stack or reposition thread PC.
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index 0eea30991a4..e1864effbcf 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -1852,17 +1852,118 @@ static volatile jint pending_signals[NSIG+1] = { 0 };
// Bsd(POSIX) specific hand shaking semaphore.
#ifdef __APPLE__
-static semaphore_t sig_sem;
+typedef semaphore_t os_semaphore_t;
#define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
-#define SEM_WAIT(sem) semaphore_wait(sem);
-#define SEM_POST(sem) semaphore_signal(sem);
+#define SEM_WAIT(sem) semaphore_wait(sem)
+#define SEM_POST(sem) semaphore_signal(sem)
+#define SEM_DESTROY(sem) semaphore_destroy(mach_task_self(), sem)
#else
-static sem_t sig_sem;
+typedef sem_t os_semaphore_t;
#define SEM_INIT(sem, value) sem_init(&sem, 0, value)
-#define SEM_WAIT(sem) sem_wait(&sem);
-#define SEM_POST(sem) sem_post(&sem);
+#define SEM_WAIT(sem) sem_wait(&sem)
+#define SEM_POST(sem) sem_post(&sem)
+#define SEM_DESTROY(sem) sem_destroy(&sem)
#endif
+class Semaphore : public StackObj {
+ public:
+ Semaphore();
+ ~Semaphore();
+ void signal();
+ void wait();
+ bool trywait();
+ bool timedwait(unsigned int sec, int nsec);
+ private:
+ jlong currenttime() const;
+ semaphore_t _semaphore;
+};
+
+Semaphore::Semaphore() : _semaphore(0) {
+ SEM_INIT(_semaphore, 0);
+}
+
+Semaphore::~Semaphore() {
+ SEM_DESTROY(_semaphore);
+}
+
+void Semaphore::signal() {
+ SEM_POST(_semaphore);
+}
+
+void Semaphore::wait() {
+ SEM_WAIT(_semaphore);
+}
+
+jlong Semaphore::currenttime() const {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
+}
+
+#ifdef __APPLE__
+bool Semaphore::trywait() {
+ return timedwait(0, 0);
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+ kern_return_t kr = KERN_ABORTED;
+ mach_timespec_t waitspec;
+ waitspec.tv_sec = sec;
+ waitspec.tv_nsec = nsec;
+
+ jlong starttime = currenttime();
+
+ kr = semaphore_timedwait(_semaphore, waitspec);
+ while (kr == KERN_ABORTED) {
+ jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec;
+
+ jlong current = currenttime();
+ jlong passedtime = current - starttime;
+
+ if (passedtime >= totalwait) {
+ waitspec.tv_sec = 0;
+ waitspec.tv_nsec = 0;
+ } else {
+ jlong waittime = totalwait - (current - starttime);
+ waitspec.tv_sec = waittime / NANOSECS_PER_SEC;
+ waitspec.tv_nsec = waittime % NANOSECS_PER_SEC;
+ }
+
+ kr = semaphore_timedwait(_semaphore, waitspec);
+ }
+
+ return kr == KERN_SUCCESS;
+}
+
+#else
+
+bool Semaphore::trywait() {
+ return sem_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+ struct timespec ts;
+ jlong endtime = unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+ while (1) {
+ int result = sem_timedwait(&_semaphore, &ts);
+ if (result == 0) {
+ return true;
+ } else if (errno == EINTR) {
+ continue;
+ } else if (errno == ETIMEDOUT) {
+ return false;
+ } else {
+ return false;
+ }
+ }
+}
+
+#endif // __APPLE__
+
+static os_semaphore_t sig_sem;
+static Semaphore sr_semaphore;
+
void os::signal_init_pd() {
// Initialize signal structures
::memset((void*)pending_signals, 0, sizeof(pending_signals));
@@ -2616,9 +2717,6 @@ void os::hint_no_preempt() {}
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
osthread->set_siginfo(NULL);
-
- // notify the suspend action is completed, we have now resumed
- osthread->sr.clear_suspended();
}
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
@@ -2638,7 +2736,7 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
// its signal handlers run and prevents sigwait()'s use with the
// mutex granting granting signal.
//
-// Currently only ever called on the VMThread
+// Currently only ever called on the VMThread or JavaThread
//
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// Save and restore errno to avoid confusing native code with EINTR
@@ -2647,38 +2745,48 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
- assert(thread->is_VM_thread(), "Must be VMThread");
- // read current suspend action
- int action = osthread->sr.suspend_action();
- if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+ os::SuspendResume::State current = osthread->sr.state();
+ if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);
- // Notify the suspend action is about to be completed. do_suspend()
- // waits until SR_SUSPENDED is set and then returns. We will wait
- // here for a resume signal and that completes the suspend-other
- // action. do_suspend/do_resume is always called as a pair from
- // the same thread - so there are no races
+ // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+ os::SuspendResume::State state = osthread->sr.suspended();
+ if (state == os::SuspendResume::SR_SUSPENDED) {
+ sigset_t suspend_set; // signals for sigsuspend()
- // notify the caller
- osthread->sr.set_suspended();
+ // get current set of blocked signals and unblock resume signal
+ pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
+ sigdelset(&suspend_set, SR_signum);
- sigset_t suspend_set; // signals for sigsuspend()
+ sr_semaphore.signal();
+ // wait here until we are resumed
+ while (1) {
+ sigsuspend(&suspend_set);
- // get current set of blocked signals and unblock resume signal
- pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
- sigdelset(&suspend_set, SR_signum);
+ os::SuspendResume::State result = osthread->sr.running();
+ if (result == os::SuspendResume::SR_RUNNING) {
+ sr_semaphore.signal();
+ break;
+ } else if (result != os::SuspendResume::SR_SUSPENDED) {
+ ShouldNotReachHere();
+ }
+ }
- // wait here until we are resumed
- do {
- sigsuspend(&suspend_set);
- // ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
+ } else if (state == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else {
+ ShouldNotReachHere();
+ }
resume_clear_context(osthread);
-
+ } else if (current == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // ignore
} else {
- assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
- // nothing special to do - just leave the handler
+ // ignore
}
errno = old_errno;
@@ -2722,42 +2830,82 @@ static int SR_initialize() {
return 0;
}
+static int sr_notify(OSThread* osthread) {
+ int status = pthread_kill(osthread->pthread_id(), SR_signum);
+ assert_status(status == 0, status, "pthread_kill");
+ return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
// returns true on success and false on error - really an error is fatal
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
- // mark as suspended and send signal
- osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
- int status = pthread_kill(osthread->pthread_id(), SR_signum);
- assert_status(status == 0, status, "pthread_kill");
+ assert(osthread->sr.is_running(), "thread should be running");
+ assert(!sr_semaphore.trywait(), "semaphore has invalid state");
- // check status and wait until notified of suspension
- if (status == 0) {
- for (int i = 0; !osthread->sr.is_suspended(); i++) {
- os::yield_all(i);
- }
- osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
- return true;
- }
- else {
- osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
+ // mark as suspended and send signal
+ if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+ // failed to switch, state wasn't running?
+ ShouldNotReachHere();
return false;
}
+
+ if (sr_notify(osthread) != 0) {
+ ShouldNotReachHere();
+ }
+
+ // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+ while (true) {
+ if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+ break;
+ } else {
+ // timeout
+ os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+ if (cancelled == os::SuspendResume::SR_RUNNING) {
+ return false;
+ } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+ // make sure that we consume the signal on the semaphore as well
+ sr_semaphore.wait();
+ break;
+ } else {
+ ShouldNotReachHere();
+ return false;
+ }
+ }
+ }
+
+ guarantee(osthread->sr.is_suspended(), "Must be suspended");
+ return true;
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
+ assert(!sr_semaphore.trywait(), "invalid semaphore state");
- int status = pthread_kill(osthread->pthread_id(), SR_signum);
- assert_status(status == 0, status, "pthread_kill");
- // check status and wait unit notified of resumption
- if (status == 0) {
- for (int i = 0; osthread->sr.is_suspended(); i++) {
- os::yield_all(i);
+ if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // failed to switch to WAKEUP_REQUEST
+ ShouldNotReachHere();
+ return;
+ }
+
+ while (true) {
+ if (sr_notify(osthread) == 0) {
+ if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+ if (osthread->sr.is_running()) {
+ return;
+ }
+ }
+ } else {
+ ShouldNotReachHere();
}
}
- osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
+
+ guarantee(osthread->sr.is_running(), "Must be running!");
}
////////////////////////////////////////////////////////////////////////////////
@@ -3508,7 +3656,40 @@ bool os::bind_to_processor(uint processor_id) {
return false;
}
+void os::SuspendedThreadTask::internal_do_task() {
+ if (do_suspend(_thread->osthread())) {
+ SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+ do_task(context);
+ do_resume(_thread->osthread());
+ }
+}
+
///
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+ PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+ ExtendedPC result();
+protected:
+ void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+ ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+ guarantee(is_done(), "task is not done yet.");
+ return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+ Thread* thread = context.thread();
+ OSThread* osthread = thread->osthread();
+ if (osthread->ucontext() != NULL) {
+ _epc = os::Bsd::ucontext_get_pc((ucontext_t *) context.ucontext());
+ } else {
+ // NULL context is unexpected, double-check this is the VMThread
+ guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+ }
+}
// Suspends the target using the signal mechanism and then grabs the PC before
// resuming the target. Used by the flat-profiler only
@@ -3517,22 +3698,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
assert(thread->is_VM_thread(), "Can only be called for VMThread");
- ExtendedPC epc;
-
- OSThread* osthread = thread->osthread();
- if (do_suspend(osthread)) {
- if (osthread->ucontext() != NULL) {
- epc = os::Bsd::ucontext_get_pc(osthread->ucontext());
- } else {
- // NULL context is unexpected, double-check this is the VMThread
- guarantee(thread->is_VM_thread(), "can only be called for VMThread");
- }
- do_resume(osthread);
- }
- // failure means pthread_kill failed for some reason - arguably this is
- // a fatal problem, but such problems are ignored elsewhere
-
- return epc;
+ PcFetcher fetcher(thread);
+ fetcher.run();
+ return fetcher.result();
}
int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
@@ -4517,3 +4685,4 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
return n;
}
+
diff --git a/hotspot/src/os/bsd/vm/os_bsd.hpp b/hotspot/src/os/bsd/vm/os_bsd.hpp
index 81562b4f8d3..f18bb88637f 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.hpp
@@ -145,36 +145,6 @@ class Bsd {
// BsdThreads work-around for 6292965
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
-
- // Bsd suspend/resume support - this helper is a shadow of its former
- // self now that low-level suspension is barely used, and old workarounds
- // for BsdThreads are no longer needed.
- class SuspendResume {
- private:
- volatile int _suspend_action;
- volatile jint _state;
- public:
- // values for suspend_action:
- enum {
- SR_NONE = 0x00,
- SR_SUSPEND = 0x01, // suspend request
- SR_CONTINUE = 0x02, // resume request
- SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
- };
-
- SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
-
- int suspend_action() const { return _suspend_action; }
- void set_suspend_action(int x) { _suspend_action = x; }
-
- // atomic updates for _state
- inline void set_suspended();
- inline void clear_suspended();
- bool is_suspended() { return _state & SR_SUSPENDED; }
-
- #undef SR_SUSPENDED
- };
-
private:
typedef int (*sched_getcpu_func_t)(void);
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
@@ -250,7 +220,7 @@ class PlatformEvent : public CHeapObj {
int TryPark () ;
int park (jlong millis) ;
void SetAssociation (Thread * a) { _Assoc = a ; }
-} ;
+};
class PlatformParker : public CHeapObj {
protected:
@@ -268,6 +238,6 @@ class PlatformParker : public CHeapObj {
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
}
-} ;
+};
#endif // OS_BSD_VM_OS_BSD_HPP
diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
index 723543efe92..33ebec9fffc 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
@@ -286,20 +286,4 @@ inline int os::set_sock_opt(int fd, int level, int optname,
return ::setsockopt(fd, level, optname, optval, optlen);
}
-inline void os::Bsd::SuspendResume::set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
-}
-
-inline void os::Bsd::SuspendResume::clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
-}
-
#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
diff --git a/hotspot/src/os/linux/vm/osThread_linux.hpp b/hotspot/src/os/linux/vm/osThread_linux.hpp
index 904ab52e68f..c9e53c249a7 100644
--- a/hotspot/src/os/linux/vm/osThread_linux.hpp
+++ b/hotspot/src/os/linux/vm/osThread_linux.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@ public:
// flags that support signal based suspend/resume on Linux are in a
// separate class to avoid confusion with many flags in OSThread that
// are used by VM level suspend/resume.
- os::Linux::SuspendResume sr;
+ os::SuspendResume sr;
// _ucontext and _siginfo are used by SR_handler() to save thread context,
// and they will later be used to walk the stack or reposition thread PC.
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index dbf30c48178..4b975461ee9 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -151,6 +151,9 @@ sigset_t SR_sigset;
/* Used to protect dlsym() calls */
static pthread_mutex_t dl_mutex;
+// Declarations
+static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
+
#ifdef JAVASE_EMBEDDED
class MemNotifyThread: public Thread {
friend class VMStructs;
@@ -2407,6 +2410,57 @@ void* os::user_handler() {
return CAST_FROM_FN_PTR(void*, UserHandler);
}
+class Semaphore : public StackObj {
+ public:
+ Semaphore();
+ ~Semaphore();
+ void signal();
+ void wait();
+ bool trywait();
+ bool timedwait(unsigned int sec, int nsec);
+ private:
+ sem_t _semaphore;
+};
+
+
+Semaphore::Semaphore() {
+ sem_init(&_semaphore, 0, 0);
+}
+
+Semaphore::~Semaphore() {
+ sem_destroy(&_semaphore);
+}
+
+void Semaphore::signal() {
+ sem_post(&_semaphore);
+}
+
+void Semaphore::wait() {
+ sem_wait(&_semaphore);
+}
+
+bool Semaphore::trywait() {
+ return sem_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+ struct timespec ts;
+ unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+ while (1) {
+ int result = sem_timedwait(&_semaphore, &ts);
+ if (result == 0) {
+ return true;
+ } else if (errno == EINTR) {
+ continue;
+ } else if (errno == ETIMEDOUT) {
+ return false;
+ } else {
+ return false;
+ }
+ }
+}
+
extern "C" {
typedef void (*sa_handler_t)(int);
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -2446,6 +2500,7 @@ static volatile jint pending_signals[NSIG+1] = { 0 };
// Linux(POSIX) specific hand shaking semaphore.
static sem_t sig_sem;
+static Semaphore sr_semaphore;
void os::signal_init_pd() {
// Initialize signal structures
@@ -3559,9 +3614,6 @@ void os::hint_no_preempt() {}
static void resume_clear_context(OSThread *osthread) {
osthread->set_ucontext(NULL);
osthread->set_siginfo(NULL);
-
- // notify the suspend action is completed, we have now resumed
- osthread->sr.clear_suspended();
}
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
@@ -3581,7 +3633,7 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
// its signal handlers run and prevents sigwait()'s use with the
// mutex granting granting signal.
//
-// Currently only ever called on the VMThread
+// Currently only ever called on the VMThread and JavaThreads (PC sampling)
//
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
// Save and restore errno to avoid confusing native code with EINTR
@@ -3590,38 +3642,46 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
- assert(thread->is_VM_thread(), "Must be VMThread");
- // read current suspend action
- int action = osthread->sr.suspend_action();
- if (action == os::Linux::SuspendResume::SR_SUSPEND) {
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+ os::SuspendResume::State current = osthread->sr.state();
+ if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
suspend_save_context(osthread, siginfo, context);
- // Notify the suspend action is about to be completed. do_suspend()
- // waits until SR_SUSPENDED is set and then returns. We will wait
- // here for a resume signal and that completes the suspend-other
- // action. do_suspend/do_resume is always called as a pair from
- // the same thread - so there are no races
+ // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+ os::SuspendResume::State state = osthread->sr.suspended();
+ if (state == os::SuspendResume::SR_SUSPENDED) {
+ sigset_t suspend_set; // signals for sigsuspend()
- // notify the caller
- osthread->sr.set_suspended();
+ // get current set of blocked signals and unblock resume signal
+ pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
+ sigdelset(&suspend_set, SR_signum);
- sigset_t suspend_set; // signals for sigsuspend()
+ sr_semaphore.signal();
+ // wait here until we are resumed
+ while (1) {
+ sigsuspend(&suspend_set);
- // get current set of blocked signals and unblock resume signal
- pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
- sigdelset(&suspend_set, SR_signum);
+ os::SuspendResume::State result = osthread->sr.running();
+ if (result == os::SuspendResume::SR_RUNNING) {
+ sr_semaphore.signal();
+ break;
+ }
+ }
- // wait here until we are resumed
- do {
- sigsuspend(&suspend_set);
- // ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE);
+ } else if (state == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else {
+ ShouldNotReachHere();
+ }
resume_clear_context(osthread);
-
+ } else if (current == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // ignore
} else {
- assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action");
- // nothing special to do - just leave the handler
+ // ignore
}
errno = old_errno;
@@ -3665,42 +3725,82 @@ static int SR_initialize() {
return 0;
}
+static int sr_notify(OSThread* osthread) {
+ int status = pthread_kill(osthread->pthread_id(), SR_signum);
+ assert_status(status == 0, status, "pthread_kill");
+ return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
// returns true on success and false on error - really an error is fatal
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
- // mark as suspended and send signal
- osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND);
- int status = pthread_kill(osthread->pthread_id(), SR_signum);
- assert_status(status == 0, status, "pthread_kill");
+ assert(osthread->sr.is_running(), "thread should be running");
+ assert(!sr_semaphore.trywait(), "semaphore has invalid state");
- // check status and wait until notified of suspension
- if (status == 0) {
- for (int i = 0; !osthread->sr.is_suspended(); i++) {
- os::yield_all(i);
- }
- osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
- return true;
- }
- else {
- osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
+ // mark as suspended and send signal
+ if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+ // failed to switch, state wasn't running?
+ ShouldNotReachHere();
return false;
}
+
+ if (sr_notify(osthread) != 0) {
+ ShouldNotReachHere();
+ }
+
+ // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+ while (true) {
+ if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+ break;
+ } else {
+ // timeout
+ os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+ if (cancelled == os::SuspendResume::SR_RUNNING) {
+ return false;
+ } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+ // make sure that we consume the signal on the semaphore as well
+ sr_semaphore.wait();
+ break;
+ } else {
+ ShouldNotReachHere();
+ return false;
+ }
+ }
+ }
+
+ guarantee(osthread->sr.is_suspended(), "Must be suspended");
+ return true;
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE);
+ assert(!sr_semaphore.trywait(), "invalid semaphore state");
- int status = pthread_kill(osthread->pthread_id(), SR_signum);
- assert_status(status == 0, status, "pthread_kill");
- // check status and wait unit notified of resumption
- if (status == 0) {
- for (int i = 0; osthread->sr.is_suspended(); i++) {
- os::yield_all(i);
+ if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // failed to switch to WAKEUP_REQUEST
+ ShouldNotReachHere();
+ return;
+ }
+
+ while (true) {
+ if (sr_notify(osthread) == 0) {
+ if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+ if (osthread->sr.is_running()) {
+ return;
+ }
+ }
+ } else {
+ ShouldNotReachHere();
}
}
- osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
+
+ guarantee(osthread->sr.is_running(), "Must be running!");
}
////////////////////////////////////////////////////////////////////////////////
@@ -4472,6 +4572,40 @@ bool os::bind_to_processor(uint processor_id) {
///
+void os::SuspendedThreadTask::internal_do_task() {
+ if (do_suspend(_thread->osthread())) {
+ SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+ do_task(context);
+ do_resume(_thread->osthread());
+ }
+}
+
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+ PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+ ExtendedPC result();
+protected:
+ void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+ ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+ guarantee(is_done(), "task is not done yet.");
+ return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+ Thread* thread = context.thread();
+ OSThread* osthread = thread->osthread();
+ if (osthread->ucontext() != NULL) {
+ _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
+ } else {
+ // NULL context is unexpected, double-check this is the VMThread
+ guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+ }
+}
+
// Suspends the target using the signal mechanism and then grabs the PC before
// resuming the target. Used by the flat-profiler only
ExtendedPC os::get_thread_pc(Thread* thread) {
@@ -4479,22 +4613,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
assert(thread->is_VM_thread(), "Can only be called for VMThread");
- ExtendedPC epc;
-
- OSThread* osthread = thread->osthread();
- if (do_suspend(osthread)) {
- if (osthread->ucontext() != NULL) {
- epc = os::Linux::ucontext_get_pc(osthread->ucontext());
- } else {
- // NULL context is unexpected, double-check this is the VMThread
- guarantee(thread->is_VM_thread(), "can only be called for VMThread");
- }
- do_resume(osthread);
- }
- // failure means pthread_kill failed for some reason - arguably this is
- // a fatal problem, but such problems are ignored elsewhere
-
- return epc;
+ PcFetcher fetcher(thread);
+ fetcher.run();
+ return fetcher.result();
}
int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
@@ -5616,4 +5737,5 @@ void MemNotifyThread::start() {
new MemNotifyThread(fd);
}
}
+
#endif // JAVASE_EMBEDDED
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index c2ce765bc4b..41c29f680a7 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -210,35 +210,6 @@ class Linux {
// LinuxThreads work-around for 6292965
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
-
- // Linux suspend/resume support - this helper is a shadow of its former
- // self now that low-level suspension is barely used, and old workarounds
- // for LinuxThreads are no longer needed.
- class SuspendResume {
- private:
- volatile int _suspend_action;
- volatile jint _state;
- public:
- // values for suspend_action:
- enum {
- SR_NONE = 0x00,
- SR_SUSPEND = 0x01, // suspend request
- SR_CONTINUE = 0x02, // resume request
- SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
- };
-
- SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
-
- int suspend_action() const { return _suspend_action; }
- void set_suspend_action(int x) { _suspend_action = x; }
-
- // atomic updates for _state
- inline void set_suspended();
- inline void clear_suspended();
- bool is_suspended() { return _state & SR_SUSPENDED; }
-
- };
-
private:
typedef int (*sched_getcpu_func_t)(void);
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
@@ -333,6 +304,6 @@ class PlatformParker : public CHeapObj {
status = pthread_mutex_init (_mutex, NULL);
assert_status(status == 0, status, "mutex_init");
}
-} ;
+};
#endif // OS_LINUX_VM_OS_LINUX_HPP
diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp
index 87494dfd96f..1afae5cc4e5 100644
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp
@@ -288,20 +288,4 @@ inline int os::set_sock_opt(int fd, int level, int optname,
return ::setsockopt(fd, level, optname, optval, optlen);
}
-inline void os::Linux::SuspendResume::set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
-}
-
-inline void os::Linux::SuspendResume::clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
-}
-
#endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.cpp b/hotspot/src/os/solaris/vm/osThread_solaris.cpp
index 6310471f5e0..9cbd632e578 100644
--- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,10 +41,6 @@ void OSThread::pd_initialize() {
_thread_id = 0;
sigemptyset(&_caller_sigmask);
- _current_callback = NULL;
- _current_callback_lock = VM_Version::supports_compare_and_exchange() ? NULL
- : new Mutex(Mutex::suspend_resume, "Callback_lock", true);
-
_saved_interrupt_thread_state = _thread_new;
_vm_created_thread = false;
}
@@ -52,172 +48,6 @@ void OSThread::pd_initialize() {
void OSThread::pd_destroy() {
}
-// Synchronous interrupt support
-//
-// _current_callback == NULL no pending callback
-// == 1 callback_in_progress
-// == other value pointer to the pending callback
-//
-
-// CAS on v8 is implemented by using a global atomic_memory_operation_lock,
-// which is shared by other atomic functions. It is OK for normal uses, but
-// dangerous if used after some thread is suspended or if used in signal
-// handlers. Instead here we use a special per-thread lock to synchronize
-// updating _current_callback if we are running on v8. Note in general trying
-// to grab locks after a thread is suspended is not safe, but it is safe for
-// updating _current_callback, because synchronous interrupt callbacks are
-// currently only used in:
-// 1. GetThreadPC_Callback - used by WatcherThread to profile VM thread
-// There is no overlap between the callbacks, which means we won't try to
-// grab a thread's sync lock after the thread has been suspended while holding
-// the same lock.
-
-// used after a thread is suspended
-static intptr_t compare_and_exchange_current_callback (
- intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) {
- if (VM_Version::supports_compare_and_exchange()) {
- return Atomic::cmpxchg_ptr(callback, addr, compare_value);
- } else {
- MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
- if (*addr == compare_value) {
- *addr = callback;
- return compare_value;
- } else {
- return callback;
- }
- }
-}
-
-// used in signal handler
-static intptr_t exchange_current_callback(intptr_t callback, intptr_t *addr, Mutex *sync) {
- if (VM_Version::supports_compare_and_exchange()) {
- return Atomic::xchg_ptr(callback, addr);
- } else {
- MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
- intptr_t cb = *addr;
- *addr = callback;
- return cb;
- }
-}
-
-// one interrupt at a time. spin if _current_callback != NULL
-int OSThread::set_interrupt_callback(Sync_Interrupt_Callback * cb) {
- int count = 0;
- while (compare_and_exchange_current_callback(
- (intptr_t)cb, (intptr_t *)&_current_callback, (intptr_t)NULL, _current_callback_lock) != NULL) {
- while (_current_callback != NULL) {
- count++;
-#ifdef ASSERT
- if ((WarnOnStalledSpinLock > 0) &&
- (count % WarnOnStalledSpinLock == 0)) {
- warning("_current_callback seems to be stalled: %p", _current_callback);
- }
-#endif
- os::yield_all(count);
- }
- }
- return 0;
-}
-
-// reset _current_callback, spin if _current_callback is callback_in_progress
-void OSThread::remove_interrupt_callback(Sync_Interrupt_Callback * cb) {
- int count = 0;
- while (compare_and_exchange_current_callback(
- (intptr_t)NULL, (intptr_t *)&_current_callback, (intptr_t)cb, _current_callback_lock) != (intptr_t)cb) {
-#ifdef ASSERT
- intptr_t p = (intptr_t)_current_callback;
- assert(p == (intptr_t)callback_in_progress ||
- p == (intptr_t)cb, "wrong _current_callback value");
-#endif
- while (_current_callback != cb) {
- count++;
-#ifdef ASSERT
- if ((WarnOnStalledSpinLock > 0) &&
- (count % WarnOnStalledSpinLock == 0)) {
- warning("_current_callback seems to be stalled: %p", _current_callback);
- }
-#endif
- os::yield_all(count);
- }
- }
-}
-
-void OSThread::do_interrupt_callbacks_at_interrupt(InterruptArguments *args) {
- Sync_Interrupt_Callback * cb;
- cb = (Sync_Interrupt_Callback *)exchange_current_callback(
- (intptr_t)callback_in_progress, (intptr_t *)&_current_callback, _current_callback_lock);
-
- if (cb == NULL) {
- // signal is delivered too late (thread is masking interrupt signal??).
- // there is nothing we need to do because requesting thread has given up.
- } else if ((intptr_t)cb == (intptr_t)callback_in_progress) {
- fatal("invalid _current_callback state");
- } else {
- assert(cb->target()->osthread() == this, "wrong target");
- cb->execute(args);
- cb->leave_callback(); // notify the requester
- }
-
- // restore original _current_callback value
- intptr_t p;
- p = exchange_current_callback((intptr_t)cb, (intptr_t *)&_current_callback, _current_callback_lock);
- assert(p == (intptr_t)callback_in_progress, "just checking");
-}
-
-// Called by the requesting thread to send a signal to target thread and
-// execute "this" callback from the signal handler.
-int OSThread::Sync_Interrupt_Callback::interrupt(Thread * target, int timeout) {
- // Let signals to the vm_thread go even if the Threads_lock is not acquired
- assert(Threads_lock->owned_by_self() || (target == VMThread::vm_thread()),
- "must have threads lock to call this");
-
- OSThread * osthread = target->osthread();
-
- // may block if target thread already has a pending callback
- osthread->set_interrupt_callback(this);
-
- _target = target;
-
- int rslt = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
- assert(rslt == 0, "thr_kill != 0");
-
- bool status = false;
- jlong t1 = os::javaTimeMillis();
- { // don't use safepoint check because we might be the watcher thread.
- MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
- while (!is_done()) {
- status = _sync->wait(Mutex::_no_safepoint_check_flag, timeout);
-
- // status == true if timed out
- if (status) break;
-
- // update timeout
- jlong t2 = os::javaTimeMillis();
- timeout -= t2 - t1;
- t1 = t2;
- }
- }
-
- // reset current_callback
- osthread->remove_interrupt_callback(this);
-
- return status;
-}
-
-void OSThread::Sync_Interrupt_Callback::leave_callback() {
- if (!_sync->owned_by_self()) {
- // notify requesting thread
- MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
- _is_done = true;
- _sync->notify_all();
- } else {
- // Current thread is interrupted while it is holding the _sync lock, trying
- // to grab it again will deadlock. The requester will timeout anyway,
- // so just return.
- _is_done = true;
- }
-}
-
// copied from synchronizer.cpp
void OSThread::handle_spinlock_contention(int tries) {
@@ -229,3 +59,7 @@ void OSThread::handle_spinlock_contention(int tries) {
os::yield(); // Yield to threads of same or higher priority
}
}
+
+void OSThread::SR_handler(Thread* thread, ucontext_t* uc) {
+ os::Solaris::SR_handler(thread, uc);
+}
diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.hpp b/hotspot/src/os/solaris/vm/osThread_solaris.hpp
index 2a7a2470a08..c3f96699421 100644
--- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -72,61 +72,15 @@
// ***************************************************************
public:
-
- class InterruptArguments : StackObj {
- private:
- Thread* _thread; // the thread to signal was dispatched to
- ucontext_t* _ucontext; // the machine context at the time of the signal
-
- public:
- InterruptArguments(Thread* thread, ucontext_t* ucontext) {
- _thread = thread;
- _ucontext = ucontext;
- }
-
- Thread* thread() const { return _thread; }
- ucontext_t* ucontext() const { return _ucontext; }
- };
-
- // There are currently no asynchronous callbacks - and we'd better not
- // support them in the future either, as they need to be deallocated from
- // the interrupt handler, which is not safe; they also require locks to
- // protect the callback queue.
-
- class Sync_Interrupt_Callback : private StackObj {
- protected:
- volatile bool _is_done;
- Monitor* _sync;
- Thread* _target;
- public:
- Sync_Interrupt_Callback(Monitor * sync) {
- _is_done = false; _target = NULL; _sync = sync;
- }
-
- bool is_done() const { return _is_done; }
- Thread* target() const { return _target; }
-
- int interrupt(Thread * target, int timeout);
-
- // override to implement the callback.
- virtual void execute(InterruptArguments *args) = 0;
-
- void leave_callback();
- };
+ os::SuspendResume sr;
private:
-
- Sync_Interrupt_Callback * volatile _current_callback;
- enum {
- callback_in_progress = 1
- };
- Mutex * _current_callback_lock; // only used on v8
+ ucontext_t* _ucontext;
public:
-
- int set_interrupt_callback (Sync_Interrupt_Callback * cb);
- void remove_interrupt_callback(Sync_Interrupt_Callback * cb);
- void do_interrupt_callbacks_at_interrupt(InterruptArguments *args);
+ ucontext_t* ucontext() const { return _ucontext; }
+ void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; }
+ static void SR_handler(Thread* thread, ucontext_t* uc);
// ***************************************************************
// java.lang.Thread.interrupt state.
diff --git a/hotspot/src/os/solaris/vm/os_share_solaris.hpp b/hotspot/src/os/solaris/vm/os_share_solaris.hpp
index a7c1ce8c0ee..40143c6c6a9 100644
--- a/hotspot/src/os/solaris/vm/os_share_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/os_share_solaris.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,28 +27,6 @@
// Defines the interfaces to Solaris operating systems that vary across platforms
-
-// This is a simple callback that just fetches a PC for an interrupted thread.
-// The thread need not be suspended and the fetched PC is just a hint.
-// Returned PC and nPC are not necessarily consecutive.
-// This one is currently used for profiling the VMThread ONLY!
-
-// Must be synchronous
-class GetThreadPC_Callback : public OSThread::Sync_Interrupt_Callback {
- private:
- ExtendedPC _addr;
-
- public:
-
- GetThreadPC_Callback(Monitor *sync) :
- OSThread::Sync_Interrupt_Callback(sync) { }
- ExtendedPC addr() const { return _addr; }
-
- void set_addr(ExtendedPC addr) { _addr = addr; }
-
- void execute(OSThread::InterruptArguments *args);
-};
-
// misc
extern "C" {
void signalHandler(int, siginfo_t*, void*);
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 09204157d65..5df7a8b403b 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -240,6 +240,8 @@ extern "C" {
static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
}
+static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
+
// Thread Local Storage
// This is common to all Solaris platforms so it is defined here,
// in this common file.
@@ -2580,6 +2582,57 @@ void* os::user_handler() {
return CAST_FROM_FN_PTR(void*, UserHandler);
}
+class Semaphore : public StackObj {
+ public:
+ Semaphore();
+ ~Semaphore();
+ void signal();
+ void wait();
+ bool trywait();
+ bool timedwait(unsigned int sec, int nsec);
+ private:
+ sema_t _semaphore;
+};
+
+
+Semaphore::Semaphore() {
+ sema_init(&_semaphore, 0, NULL, NULL);
+}
+
+Semaphore::~Semaphore() {
+ sema_destroy(&_semaphore);
+}
+
+void Semaphore::signal() {
+ sema_post(&_semaphore);
+}
+
+void Semaphore::wait() {
+ sema_wait(&_semaphore);
+}
+
+bool Semaphore::trywait() {
+ return sema_trywait(&_semaphore) == 0;
+}
+
+bool Semaphore::timedwait(unsigned int sec, int nsec) {
+ struct timespec ts;
+ unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
+
+ while (1) {
+ int result = sema_timedwait(&_semaphore, &ts);
+ if (result == 0) {
+ return true;
+ } else if (errno == EINTR) {
+ continue;
+ } else if (errno == ETIME) {
+ return false;
+ } else {
+ return false;
+ }
+ }
+}
+
extern "C" {
typedef void (*sa_handler_t)(int);
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
@@ -4164,6 +4217,68 @@ void os::hint_no_preempt() {
schedctl_start(schedctl_init());
}
+static void resume_clear_context(OSThread *osthread) {
+ osthread->set_ucontext(NULL);
+}
+
+static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
+ osthread->set_ucontext(context);
+}
+
+static Semaphore sr_semaphore;
+
+void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
+ // Save and restore errno to avoid confusing native code with EINTR
+ // after sigsuspend.
+ int old_errno = errno;
+
+ OSThread* osthread = thread->osthread();
+ assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
+
+ os::SuspendResume::State current = osthread->sr.state();
+ if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
+ suspend_save_context(osthread, uc);
+
+ // attempt to switch the state, we assume we had a SUSPEND_REQUEST
+ os::SuspendResume::State state = osthread->sr.suspended();
+ if (state == os::SuspendResume::SR_SUSPENDED) {
+ sigset_t suspend_set; // signals for sigsuspend()
+
+ // get current set of blocked signals and unblock resume signal
+ thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
+ sigdelset(&suspend_set, os::Solaris::SIGasync());
+
+ sr_semaphore.signal();
+ // wait here until we are resumed
+ while (1) {
+ sigsuspend(&suspend_set);
+
+ os::SuspendResume::State result = osthread->sr.running();
+ if (result == os::SuspendResume::SR_RUNNING) {
+ sr_semaphore.signal();
+ break;
+ }
+ }
+
+ } else if (state == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else {
+ ShouldNotReachHere();
+ }
+
+ resume_clear_context(osthread);
+ } else if (current == os::SuspendResume::SR_RUNNING) {
+ // request was cancelled, continue
+ } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // ignore
+ } else {
+ // ignore
+ }
+
+ errno = old_errno;
+}
+
+
void os::interrupt(Thread* thread) {
assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
@@ -4247,6 +4362,116 @@ int os::message_box(const char* title, const char* message) {
return buf[0] == 'y' || buf[0] == 'Y';
}
+static int sr_notify(OSThread* osthread) {
+ int status = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
+ assert_status(status == 0, status, "thr_kill");
+ return status;
+}
+
+// "Randomly" selected value for how long we want to spin
+// before bailing out on suspending a thread, also how often
+// we send a signal to a thread we want to resume
+static const int RANDOMLY_LARGE_INTEGER = 1000000;
+static const int RANDOMLY_LARGE_INTEGER2 = 100;
+
+static bool do_suspend(OSThread* osthread) {
+ assert(osthread->sr.is_running(), "thread should be running");
+ assert(!sr_semaphore.trywait(), "semaphore has invalid state");
+
+ // mark as suspended and send signal
+ if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
+ // failed to switch, state wasn't running?
+ ShouldNotReachHere();
+ return false;
+ }
+
+ if (sr_notify(osthread) != 0) {
+ ShouldNotReachHere();
+ }
+
+ // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
+ while (true) {
+ if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) {
+ break;
+ } else {
+ // timeout
+ os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
+ if (cancelled == os::SuspendResume::SR_RUNNING) {
+ return false;
+ } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
+ // make sure that we consume the signal on the semaphore as well
+ sr_semaphore.wait();
+ break;
+ } else {
+ ShouldNotReachHere();
+ return false;
+ }
+ }
+ }
+
+ guarantee(osthread->sr.is_suspended(), "Must be suspended");
+ return true;
+}
+
+static void do_resume(OSThread* osthread) {
+ assert(osthread->sr.is_suspended(), "thread should be suspended");
+ assert(!sr_semaphore.trywait(), "invalid semaphore state");
+
+ if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
+ // failed to switch to WAKEUP_REQUEST
+ ShouldNotReachHere();
+ return;
+ }
+
+ while (true) {
+ if (sr_notify(osthread) == 0) {
+ if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
+ if (osthread->sr.is_running()) {
+ return;
+ }
+ }
+ } else {
+ ShouldNotReachHere();
+ }
+ }
+
+ guarantee(osthread->sr.is_running(), "Must be running!");
+}
+
+void os::SuspendedThreadTask::internal_do_task() {
+ if (do_suspend(_thread->osthread())) {
+ SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
+ do_task(context);
+ do_resume(_thread->osthread());
+ }
+}
+
+class PcFetcher : public os::SuspendedThreadTask {
+public:
+ PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
+ ExtendedPC result();
+protected:
+ void do_task(const os::SuspendedThreadTaskContext& context);
+private:
+ ExtendedPC _epc;
+};
+
+ExtendedPC PcFetcher::result() {
+ guarantee(is_done(), "task is not done yet.");
+ return _epc;
+}
+
+void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
+ Thread* thread = context.thread();
+ OSThread* osthread = thread->osthread();
+ if (osthread->ucontext() != NULL) {
+ _epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext());
+ } else {
+ // NULL context is unexpected, double-check this is the VMThread
+ guarantee(thread->is_VM_thread(), "can only be called for VMThread");
+ }
+}
+
// A lightweight implementation that does not suspend the target thread and
// thus returns only a hint. Used for profiling only!
ExtendedPC os::get_thread_pc(Thread* thread) {
@@ -4254,21 +4479,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
// For now, is only used to profile the VM Thread
assert(thread->is_VM_thread(), "Can only be called for VMThread");
- ExtendedPC epc;
-
- GetThreadPC_Callback cb(ProfileVM_lock);
- OSThread *osthread = thread->osthread();
- const int time_to_wait = 400; // 400ms wait for initial response
- int status = cb.interrupt(thread, time_to_wait);
-
- if (cb.is_done() ) {
- epc = cb.addr();
- } else {
- DEBUG_ONLY(tty->print_cr("Failed to get pc for thread: %d got %d status",
- osthread->thread_id(), status););
- // epc is already NULL
- }
- return epc;
+ PcFetcher fetcher(thread);
+ fetcher.run();
+ return fetcher.result();
}
diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp
index c1dff0cf193..99b757cd6ad 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,6 @@ class Solaris {
static void set_SIGinterrupt(int newsig) { _SIGinterrupt = newsig; }
static void set_SIGasync(int newsig) { _SIGasync = newsig; }
-
public:
// Large Page Support--ISM.
static bool largepage_range(char* addr, size_t size);
@@ -145,6 +144,7 @@ class Solaris {
static intptr_t* ucontext_get_sp(ucontext_t* uc);
// ucontext_get_fp() is only used by Solaris X86 (see note below)
static intptr_t* ucontext_get_fp(ucontext_t* uc);
+ static address ucontext_get_pc(ucontext_t* uc);
// For Analyzer Forte AsyncGetCallTrace profiling support:
// Parameter ret_fp is only used by Solaris X86.
@@ -157,6 +157,8 @@ class Solaris {
static void hotspot_sigmask(Thread* thread);
+ // SR_handler
+ static void SR_handler(Thread* thread, ucontext_t* uc);
protected:
// Solaris-specific interface goes here
static julong available_memory();
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 33ebe5987a1..baa17768215 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -5048,6 +5048,71 @@ int os::set_sock_opt(int fd, int level, int optname,
return ::setsockopt(fd, level, optname, optval, optlen);
}
+// WINDOWS CONTEXT Flags for THREAD_SAMPLING
+#if defined(IA32)
+# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
+#elif defined (AMD64)
+# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
+#endif
+
+// returns true if thread could be suspended,
+// false otherwise
+static bool do_suspend(HANDLE* h) {
+ if (h != NULL) {
+ if (SuspendThread(*h) != ~0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// resume the thread
+// calling resume on an active thread is a no-op
+static void do_resume(HANDLE* h) {
+ if (h != NULL) {
+ ResumeThread(*h);
+ }
+}
+
+// retrieve a suspend/resume context capable handle
+// from the tid. Caller validates handle return value.
+void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {
+ if (h != NULL) {
+ *h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
+ }
+}
+
+//
+// Thread sampling implementation
+//
+void os::SuspendedThreadTask::internal_do_task() {
+ CONTEXT ctxt;
+ HANDLE h = NULL;
+
+ // get context capable handle for thread
+ get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());
+
+ // sanity
+ if (h == NULL || h == INVALID_HANDLE_VALUE) {
+ return;
+ }
+
+ // suspend the thread
+ if (do_suspend(&h)) {
+ ctxt.ContextFlags = sampling_context_flags;
+ // get thread context
+ GetThreadContext(h, &ctxt);
+ SuspendedThreadTaskContext context(_thread, &ctxt);
+ // pass context to Thread Sampling impl
+ do_task(context);
+ // resume thread
+ do_resume(&h);
+ }
+
+ // close handle
+ CloseHandle(h);
+}
+
// Kernel32 API
typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
index f508ab9ec22..8d167adaf5a 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,16 @@
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
-
assert(Thread::current() == this, "caller must be current thread");
- assert(this->is_Java_thread(), "must be JavaThread");
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
+ assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
// If we have a last_Java_frame, then we should use it even if
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp
index 69dba9b3a82..1d7921c7114 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,13 @@
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
+ bool isInJava);
+
+private:
+ bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+public:
+
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
static bool register_stack_overflow() { return false; }
diff --git a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
index 69414cf7f3d..77affdd52e6 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,15 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
assert(Thread::current() == this, "caller must be current thread");
- assert(this->is_Java_thread(), "must be JavaThread");
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
+ assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
// If we have a last_Java_frame, then we should use it even if
diff --git a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp
index 7a7d222521f..75fb7df5787 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,11 @@
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+private:
+ bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+public:
+
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
static bool register_stack_overflow() { return false; }
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
index 78902e1b477..939def32fec 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,6 +194,11 @@ intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
return NULL;
}
+address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+ return (address) uc->uc_mcontext.gregs[REG_PC];
+}
+
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
// is currently interrupted by SIGPROF.
//
@@ -265,22 +270,6 @@ frame os::current_frame() {
}
}
-
-void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
- Thread* thread = args->thread();
- ucontext_t* uc = args->ucontext();
- intptr_t* sp;
-
- assert(ProfileVM && thread->is_VM_thread(), "just checking");
-
- // Skip the mcontext corruption verification. If if occasionally
- // things get corrupt, it is ok for profiling - we will just get an unresolved
- // function name
- ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
- _addr = new_addr;
-}
-
-
static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
char lwpstatusfile[PROCFILE_LENGTH];
int lwpfd, err;
@@ -358,13 +347,8 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
if (sig == os::Solaris::SIGasync()) {
- if (thread) {
- OSThread::InterruptArguments args(thread, uc);
- thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
- return true;
- } else if (vmthread) {
- OSThread::InterruptArguments args(vmthread, uc);
- vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
+ if (thread || vmthread) {
+ OSThread::SR_handler(t, uc);
return true;
} else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
return true;
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
index f0fbc6699cc..9964114a787 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,21 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
assert(Thread::current() == this, "caller must be current thread");
+ return pd_get_top_frame(fr_addr, ucontext, isInJava, true);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+ // get ucontext somehow
+ return pd_get_top_frame(fr_addr, ucontext, isInJava, false);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr,
+ void* ucontext, bool isInJava, bool makeWalkable) {
assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
- if (!isInJava) {
+ if (!isInJava && makeWalkable) {
// make_walkable flushes register windows and grabs last_Java_pc
// which can not be done if the ucontext sp matches last_Java_sp
// stack walking utilities assume last_Java_pc set if marked flushed
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp
index 1cd0709b6e3..84b31736187 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -93,6 +93,11 @@ public:
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+private:
+ bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava, bool makeWalkable);
+public:
+
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
static bool register_stack_overflow() { return false; }
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
index 51846441ecd..4ed094db734 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -183,6 +183,10 @@ intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
}
+address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
+ return (address) uc->uc_mcontext.gregs[REG_PC];
+}
+
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
// is currently interrupted by SIGPROF.
//
@@ -252,22 +256,6 @@ frame os::current_frame() {
}
}
-// This is a simple callback that just fetches a PC for an interrupted thread.
-// The thread need not be suspended and the fetched PC is just a hint.
-// This one is currently used for profiling the VMThread ONLY!
-
-// Must be synchronous
-void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
- Thread* thread = args->thread();
- ucontext_t* uc = args->ucontext();
- intptr_t* sp;
-
- assert(ProfileVM && thread->is_VM_thread(), "just checking");
-
- ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
- _addr = new_addr;
-}
-
static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
char lwpstatusfile[PROCFILE_LENGTH];
int lwpfd, err;
@@ -419,14 +407,8 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
if (sig == os::Solaris::SIGasync()) {
- if(thread){
- OSThread::InterruptArguments args(thread, uc);
- thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
- return true;
- }
- else if(vmthread){
- OSThread::InterruptArguments args(vmthread, uc);
- vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
+ if(thread || vmthread){
+ OSThread::SR_handler(t, uc);
return true;
} else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
return true;
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
index 7c04d02726c..3007c6bee79 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
+++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,17 @@
// currently interrupted by SIGPROF
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
-
assert(Thread::current() == this, "caller must be current thread");
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr,
+ void* ucontext, bool isInJava) {
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr,
+ void* ucontext, bool isInJava) {
assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp
index d9665d3925c..7589a81a83b 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp
+++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,12 @@
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
+ bool isInJava);
+private:
+ bool pd_get_top_frame(frame* fr_addr, void* ucontext,
+ bool isInJava);
+public:
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
diff --git a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
index 308bd94767f..7180fe1d9fd 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,15 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
void* ucontext, bool isInJava) {
assert(Thread::current() == this, "caller must be current thread");
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
+ return pd_get_top_frame(fr_addr, ucontext, isInJava);
+}
+
+bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
+
assert(this->is_Java_thread(), "must be JavaThread");
JavaThread* jt = (JavaThread *)this;
@@ -87,4 +96,3 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
}
void JavaThread::cache_global_variables() { }
-
diff --git a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp
index 1199a3c5b45..65aac35109a 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,12 @@
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
bool isInJava);
+ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
+
+private:
+ bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
+
+ public:
// These routines are only used on cpu architectures that
// have separate register stacks (Itanium).
static bool register_stack_overflow() { return false; }
diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
index f9283886a87..a9b07e03e62 100644
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
+++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,7 @@ class BuildConfig {
sysDefines.add("_WINDOWS");
sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
- sysDefines.add("INCLUDE_TRACE");
+ sysDefines.add("INCLUDE_TRACE=1");
sysDefines.add("_JNI_IMPLEMENTATION_");
if (vars.get("PlatformName").equals("Win32")) {
sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 263409f15d8..65cd2333a9d 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -39,6 +39,7 @@
#include "memory/gcLocker.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
+#include "memory/referenceType.hpp"
#include "memory/universe.inline.hpp"
#include "oops/constantPool.hpp"
#include "oops/fieldStreams.hpp"
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.cpp b/hotspot/src/share/vm/classfile/classLoaderData.cpp
index c030645f64b..1d39afd7f88 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp
@@ -64,6 +64,11 @@
#include "utilities/growableArray.hpp"
#include "utilities/ostream.hpp"
+#if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+#endif
+
+
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
@@ -120,6 +125,12 @@ void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
}
}
+void ClassLoaderData::classes_do(void f(Klass * const)) {
+ for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
+ f(k);
+ }
+}
+
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
if (k->oop_is_instance()) {
@@ -583,6 +594,19 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
}
}
+void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
+ for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
+ cld->classes_do(f);
+ }
+}
+
+void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+ for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
+ cld->classes_do(f);
+ }
+}
+
GrowableArray* ClassLoaderDataGraph::new_clds() {
assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
@@ -687,6 +711,11 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
dead->set_next(_unloading);
_unloading = dead;
}
+
+ if (seen_dead_loader) {
+ post_class_unload_events();
+ }
+
return seen_dead_loader;
}
@@ -702,6 +731,20 @@ void ClassLoaderDataGraph::purge() {
Metaspace::purge();
}
+void ClassLoaderDataGraph::post_class_unload_events(void) {
+#if INCLUDE_TRACE
+ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
+ if (Tracing::enabled()) {
+ if (Tracing::is_event_enabled(TraceClassUnloadEvent)) {
+ assert(_unloading != NULL, "need class loader data unload list!");
+ _class_unload_time = Tracing::time();
+ classes_unloading_do(&class_unload_event);
+ }
+ Tracing::on_unloading_classes();
+ }
+#endif
+}
+
// CDS support
// Global metaspaces for writing information to the shared archive. When
@@ -769,3 +812,21 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
class_loader()->print_value_on(out);
}
}
+
+#if INCLUDE_TRACE
+
+TracingTime ClassLoaderDataGraph::_class_unload_time;
+
+void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
+
+ // post class unload event
+ EventClassUnload event(UNTIMED);
+ event.set_endtime(_class_unload_time);
+ event.set_unloadedClass(k);
+ oop defining_class_loader = k->class_loader();
+ event.set_definingClassLoader(defining_class_loader != NULL ?
+ defining_class_loader->klass() : (Klass*)NULL);
+ event.commit();
+}
+
+#endif /* INCLUDE_TRACE */
diff --git a/hotspot/src/share/vm/classfile/classLoaderData.hpp b/hotspot/src/share/vm/classfile/classLoaderData.hpp
index 2a7e43082b2..6d5747483d4 100644
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp
@@ -32,6 +32,10 @@
#include "runtime/mutex.hpp"
#include "utilities/growableArray.hpp"
+#if INCLUDE_TRACE
+# include "trace/traceTime.hpp"
+#endif
+
//
// A class loader represents a linkset. Conceptually, a linkset identifies
// the complete transitive closure of resolved links that a dynamic linker can
@@ -49,6 +53,7 @@ class ClassLoaderData;
class JNIMethodBlock;
class JNIHandleBlock;
class Metadebug;
+
// GC root for walking class loader data created
class ClassLoaderDataGraph : public AllStatic {
@@ -63,6 +68,7 @@ class ClassLoaderDataGraph : public AllStatic {
static ClassLoaderData* _saved_head;
static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
+ static void post_class_unload_events(void);
public:
static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
static void purge();
@@ -71,6 +77,8 @@ class ClassLoaderDataGraph : public AllStatic {
static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
static void classes_do(KlassClosure* klass_closure);
+ static void classes_do(void f(Klass* const));
+ static void classes_unloading_do(void f(Klass* const));
static bool do_unloading(BoolObjectClosure* is_alive);
// CMS support.
@@ -86,6 +94,12 @@ class ClassLoaderDataGraph : public AllStatic {
static bool contains(address x);
static bool contains_loader_data(ClassLoaderData* loader_data);
#endif
+
+#if INCLUDE_TRACE
+ private:
+ static TracingTime _class_unload_time;
+ static void class_unload_event(Klass* const k);
+#endif
};
// ClassLoaderData class
@@ -171,7 +185,7 @@ class ClassLoaderData : public CHeapObj {
void unload();
bool keep_alive() const { return _keep_alive; }
bool is_alive(BoolObjectClosure* is_alive_closure) const;
-
+ void classes_do(void f(Klass*));
void classes_do(void f(InstanceKlass*));
// Deallocate free list during class unloading.
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index cbe3581ff4a..65dfa45001a 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -961,7 +961,7 @@ void java_lang_Thread::set_thread_status(oop java_thread,
// Read thread status value from threadStatus field in java.lang.Thread java class.
java_lang_Thread::ThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
- assert(Thread::current()->is_VM_thread() ||
+ assert(Thread::current()->is_Watcher_thread() || Thread::current()->is_VM_thread() ||
JavaThread::current()->thread_state() == _thread_in_vm,
"Java Thread is not running in vm");
// The threadStatus is only present starting in 1.5
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index 682309035f3..c0d50ca9a47 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -56,6 +56,11 @@
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
+#if INCLUDE_TRACE
+ #include "trace/tracing.hpp"
+ #include "trace/traceMacros.hpp"
+#endif
+
Dictionary* SystemDictionary::_dictionary = NULL;
PlaceholderTable* SystemDictionary::_placeholders = NULL;
@@ -586,10 +591,15 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load(
}
-Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) {
+Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
+ Handle class_loader,
+ Handle protection_domain,
+ TRAPS) {
assert(name != NULL && !FieldType::is_array(name) &&
!FieldType::is_obj(name), "invalid class name");
+ TracingTime class_load_start_time = Tracing::time();
+
// UseNewReflection
// Fix for 4474172; see evaluation for more details
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
@@ -804,8 +814,9 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// during compilations.
MutexLocker mu(Compile_lock, THREAD);
update_dictionary(d_index, d_hash, p_index, p_hash,
- k, class_loader, THREAD);
+ k, class_loader, THREAD);
}
+
if (JvmtiExport::should_post_class_load()) {
Thread *thread = THREAD;
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
@@ -861,8 +872,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// This brackets the SystemDictionary updates for both defining
// and initiating loaders
MutexLocker mu(SystemDictionary_lock, THREAD);
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
- SystemDictionary_lock->notify_all();
+ placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
+ SystemDictionary_lock->notify_all();
}
}
@@ -870,6 +881,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
return NULL;
}
+ post_class_load_event(class_load_start_time, k, class_loader);
+
#ifdef ASSERT
{
ClassLoaderData* loader_data = k->class_loader_data();
@@ -993,6 +1006,8 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
TRAPS) {
TempNewSymbol parsed_name = NULL;
+ TracingTime class_load_start_time = Tracing::time();
+
ClassLoaderData* loader_data;
if (host_klass.not_null()) {
// Create a new CLD for anonymous class, that uses the same class loader
@@ -1048,6 +1063,8 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_load((JavaThread *) THREAD, k());
}
+
+ post_class_load_event(class_load_start_time, k, class_loader);
}
assert(host_klass.not_null() || cp_patches == NULL,
"cp_patches only found with host_klass");
@@ -1435,6 +1452,7 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
JvmtiExport::post_class_load((JavaThread *) THREAD, k());
}
+
}
// Support parallel classloading
@@ -1678,6 +1696,7 @@ int SystemDictionary::calculate_systemdictionary_size(int classcount) {
}
return newsize;
}
+
// Assumes classes in the SystemDictionary are only unloaded at a safepoint
// Note: anonymous classes are not in the SD.
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
@@ -2024,12 +2043,6 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
}
}
- // Assign a classid if one has not already been assigned. The
- // counter does not need to be atomically incremented since this
- // is only done while holding the SystemDictionary_lock.
- // All loaded classes get a unique ID.
- TRACE_INIT_ID(k);
-
// Make a new system dictionary entry.
Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
if (sd_check == NULL) {
@@ -2612,6 +2625,27 @@ void SystemDictionary::verify_obj_klass_present(Symbol* class_name,
"Loaded klasses should be in SystemDictionary");
}
+// utility function for class load event
+void SystemDictionary::post_class_load_event(TracingTime start_time,
+ instanceKlassHandle k,
+ Handle initiating_loader) {
+#if INCLUDE_TRACE
+ EventClassLoad event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_endtime(Tracing::time());
+ event.set_starttime(start_time);
+ event.set_loadedClass(k());
+ oop defining_class_loader = k->class_loader();
+ event.set_definingClassLoader(defining_class_loader != NULL ?
+ defining_class_loader->klass() : (Klass*)NULL);
+ oop class_loader = initiating_loader.is_null() ? (oop)NULL : initiating_loader();
+ event.set_initiatingClassLoader(class_loader != NULL ?
+ class_loader->klass() : (Klass*)NULL);
+ event.commit();
+ }
+#endif /* INCLUDE_TRACE */
+}
+
#ifndef PRODUCT
// statistics code
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
index 98e8f433e14..a2a1a857517 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
@@ -31,9 +31,11 @@
#include "oops/symbol.hpp"
#include "runtime/java.hpp"
#include "runtime/reflectionUtils.hpp"
+#include "trace/traceTime.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp"
+
// The system dictionary stores all loaded classes and maps:
//
// [class name,class loader] -> class i.e. [Symbol*,oop] -> Klass*
@@ -636,6 +638,9 @@ private:
// Setup link to hierarchy
static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
+ // event based tracing
+ static void post_class_load_event(TracingTime start_time, instanceKlassHandle k,
+ Handle initiating_loader);
// We pass in the hashtable index so we can calculate it outside of
// the SystemDictionary_lock.
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index 44d65e23345..65c1e5f2eb5 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
#include "services/memoryService.hpp"
+#include "trace/tracing.hpp"
#include "utilities/xmlstream.hpp"
// Helper class for printing in CodeCache
@@ -114,7 +115,6 @@ class CodeBlob_sizes {
}
};
-
// CodeCache implementation
CodeHeap * CodeCache::_heap = new CodeHeap();
@@ -126,6 +126,7 @@ bool CodeCache::_needs_cache_clean = false;
nmethod* CodeCache::_scavenge_root_nmethods = NULL;
nmethod* CodeCache::_saved_nmethods = NULL;
+int CodeCache::_codemem_full_count = 0;
CodeBlob* CodeCache::first() {
assert_locked_or_safepoint(CodeCache_lock);
@@ -829,6 +830,22 @@ void CodeCache::verify() {
}
}
+void CodeCache::report_codemem_full() {
+ _codemem_full_count++;
+ EventCodeCacheFull event;
+ if (event.should_commit()) {
+ event.set_startAddress((u8)low_bound());
+ event.set_commitedTopAddress((u8)high());
+ event.set_reservedTopAddress((u8)high_bound());
+ event.set_entryCount(nof_blobs());
+ event.set_methodCount(nof_nmethods());
+ event.set_adaptorCount(nof_adapters());
+ event.set_unallocatedCapacity(unallocated_capacity()/K);
+ event.set_fullCount(_codemem_full_count);
+ event.commit();
+ }
+}
+
//------------------------------------------------------------------------------------------------
// Non-product version
diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp
index 3dde92702e3..3e8eda6e2b2 100644
--- a/hotspot/src/share/vm/code/codeCache.hpp
+++ b/hotspot/src/share/vm/code/codeCache.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,11 +64,15 @@ class CodeCache : AllStatic {
static void mark_scavenge_root_nmethods() PRODUCT_RETURN;
static void verify_perm_nmethods(CodeBlobClosure* f_or_null) PRODUCT_RETURN;
+ static int _codemem_full_count;
+
public:
// Initialization
static void initialize();
+ static void report_codemem_full();
+
// Allocation/administration
static CodeBlob* allocate(int size, bool is_critical = false); // allocates a new CodeBlob
static void commit(CodeBlob* cb); // called when the allocated CodeBlob has been filled
@@ -155,6 +159,7 @@ class CodeCache : AllStatic {
// The full limits of the codeCache
static address low_bound() { return (address) _heap->low_boundary(); }
static address high_bound() { return (address) _heap->high_boundary(); }
+ static address high() { return (address) _heap->high(); }
// Profiling
static address first_address(); // first address used for CodeBlobs
@@ -186,6 +191,8 @@ class CodeCache : AllStatic {
// tells how many nmethods have dependencies
static int number_of_nmethods_with_dependencies();
+
+ static int get_codemem_full_count() { return _codemem_full_count; }
};
#endif // SHARE_VM_CODE_CODECACHE_HPP
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 73c00bf11e2..685cd74c70a 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/sweeper.hpp"
+#include "trace/tracing.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#ifdef COMPILER1
@@ -179,9 +180,11 @@ int CompileBroker::_sum_standard_bytes_compiled = 0;
int CompileBroker::_sum_nmethod_size = 0;
int CompileBroker::_sum_nmethod_code_size = 0;
-CompileQueue* CompileBroker::_c2_method_queue = NULL;
-CompileQueue* CompileBroker::_c1_method_queue = NULL;
-CompileTask* CompileBroker::_task_free_list = NULL;
+long CompileBroker::_peak_compilation_time = 0;
+
+CompileQueue* CompileBroker::_c2_method_queue = NULL;
+CompileQueue* CompileBroker::_c1_method_queue = NULL;
+CompileTask* CompileBroker::_task_free_list = NULL;
GrowableArray* CompileBroker::_method_threads = NULL;
@@ -1795,6 +1798,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
ciMethod* target = ci_env.get_method_from_handle(target_handle);
TraceTime t1("compilation", &time);
+ EventCompilation event;
AbstractCompiler *comp = compiler(task_level);
if (comp == NULL) {
@@ -1836,6 +1840,16 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
}
// simulate crash during compilation
assert(task->compile_id() != CICrashAt, "just as planned");
+ if (event.should_commit()) {
+ event.set_method(target->get_Method());
+ event.set_compileID(compile_id);
+ event.set_compileLevel(task->comp_level());
+ event.set_succeded(task->is_success());
+ event.set_isOsr(is_osr);
+ event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size());
+ event.set_inlinedBytes(task->num_inlined_bytecodes());
+ event.commit();
+ }
}
pop_jni_handle_block();
@@ -1916,6 +1930,10 @@ void CompileBroker::handle_full_code_cache() {
}
warning("CodeCache is full. Compiler has been disabled.");
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
+
+ CodeCache::report_codemem_full();
+
+
#ifndef PRODUCT
if (CompileTheWorld || ExitOnFullCodeCache) {
codecache_print(/* detailed= */ true);
@@ -2073,8 +2091,10 @@ void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time
// java.lang.management.CompilationMBean
_perf_total_compilation->inc(time.ticks());
+ _t_total_compilation.add(time);
+ _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time;
+
if (CITime) {
- _t_total_compilation.add(time);
if (is_osr) {
_t_osr_compilation.add(time);
_sum_osr_bytes_compiled += method->code_size() + task->num_inlined_bytecodes();
@@ -2172,7 +2192,6 @@ void CompileBroker::print_times() {
tty->print_cr(" nmethod total size : %6d bytes", CompileBroker::_sum_nmethod_size);
}
-
// Debugging output for failure
void CompileBroker::print_last_compile() {
if ( _last_compile_level != CompLevel_none &&
diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp
index 27fe52851d3..f336497a31d 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -299,17 +299,17 @@ class CompileBroker: AllStatic {
static elapsedTimer _t_osr_compilation;
static elapsedTimer _t_standard_compilation;
+ static int _total_compile_count;
static int _total_bailout_count;
static int _total_invalidated_count;
- static int _total_compile_count;
static int _total_native_compile_count;
static int _total_osr_compile_count;
static int _total_standard_compile_count;
-
static int _sum_osr_bytes_compiled;
static int _sum_standard_bytes_compiled;
static int _sum_nmethod_size;
static int _sum_nmethod_code_size;
+ static long _peak_compilation_time;
static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS);
static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
@@ -421,6 +421,19 @@ class CompileBroker: AllStatic {
// compiler name for debugging
static const char* compiler_name(int comp_level);
+
+ static int get_total_compile_count() { return _total_compile_count; }
+ static int get_total_bailout_count() { return _total_bailout_count; }
+ static int get_total_invalidated_count() { return _total_invalidated_count; }
+ static int get_total_native_compile_count() { return _total_native_compile_count; }
+ static int get_total_osr_compile_count() { return _total_osr_compile_count; }
+ static int get_total_standard_compile_count() { return _total_standard_compile_count; }
+ static int get_sum_osr_bytes_compiled() { return _sum_osr_bytes_compiled; }
+ static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; }
+ static int get_sum_nmethod_size() { return _sum_nmethod_size;}
+ static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }
+ static long get_peak_compilation_time() { return _peak_compilation_time; }
+ static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }
};
#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 2cc054e9123..85c7b73172e 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -37,8 +37,12 @@
#include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
#include "gc_implementation/parNew/parNewGeneration.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/allocation.hpp"
#include "memory/cardTableRS.hpp"
#include "memory/collectorPolicy.hpp"
#include "memory/gcLocker.inline.hpp"
@@ -60,7 +64,8 @@
// statics
CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
-bool CMSCollector::_full_gc_requested = false;
+bool CMSCollector::_full_gc_requested = false;
+GCCause::Cause CMSCollector::_full_gc_cause = GCCause::_no_gc;
//////////////////////////////////////////////////////////////////
// In support of CMS/VM thread synchronization
@@ -591,7 +596,10 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_concurrent_cycles_since_last_unload(0),
_roots_scanning_options(0),
_inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
- _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding)
+ _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
+ _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()),
+ _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
+ _cms_start_registered(false)
{
if (ExplicitGCInvokesConcurrentAndUnloadsClasses) {
ExplicitGCInvokesConcurrent = true;
@@ -1676,18 +1684,38 @@ void CMSCollector::collect(bool full,
_full_gcs_since_conc_gc++;
}
-void CMSCollector::request_full_gc(unsigned int full_gc_count) {
+void CMSCollector::request_full_gc(unsigned int full_gc_count, GCCause::Cause cause) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
unsigned int gc_count = gch->total_full_collections();
if (gc_count == full_gc_count) {
MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
_full_gc_requested = true;
+ _full_gc_cause = cause;
CGC_lock->notify(); // nudge CMS thread
} else {
assert(gc_count > full_gc_count, "Error: causal loop");
}
}
+bool CMSCollector::is_external_interruption() {
+ GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
+ return GCCause::is_user_requested_gc(cause) ||
+ GCCause::is_serviceability_requested_gc(cause);
+}
+
+void CMSCollector::report_concurrent_mode_interruption() {
+ if (is_external_interruption()) {
+ if (PrintGCDetails) {
+ gclog_or_tty->print(" (concurrent mode interrupted)");
+ }
+ } else {
+ if (PrintGCDetails) {
+ gclog_or_tty->print(" (concurrent mode failure)");
+ }
+ _gc_tracer_cm->report_concurrent_mode_failure();
+ }
+}
+
// The foreground and background collectors need to coordinate in order
// to make sure that they do not mutually interfere with CMS collections.
@@ -1845,14 +1873,8 @@ NOT_PRODUCT(
}
)
- if (PrintGCDetails && first_state > Idling) {
- GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause();
- if (GCCause::is_user_requested_gc(cause) ||
- GCCause::is_serviceability_requested_gc(cause)) {
- gclog_or_tty->print(" (concurrent mode interrupted)");
- } else {
- gclog_or_tty->print(" (concurrent mode failure)");
- }
+ if (first_state > Idling) {
+ report_concurrent_mode_interruption();
}
set_did_compact(should_compact);
@@ -1868,6 +1890,10 @@ NOT_PRODUCT(
// Reference objects are active.
ref_processor()->clean_up_discovered_references();
+ if (first_state > Idling) {
+ save_heap_summary();
+ }
+
do_compaction_work(clear_all_soft_refs);
// Has the GC time limit been exceeded?
@@ -1971,7 +1997,14 @@ void CMSCollector::decide_foreground_collection_type(
// a mark-sweep-compact.
void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
- TraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, gclog_or_tty);
+
+ STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
+ gc_timer->register_gc_start(os::elapsed_counter());
+
+ SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+ gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
+ GCTraceTime t("CMS:MSC ", PrintGCDetails && Verbose, true, NULL);
if (PrintGC && Verbose && !(GCCause::is_user_requested_gc(gch->gc_cause()))) {
gclog_or_tty->print_cr("Compact ConcurrentMarkSweepGeneration after %d "
"collections passed to foreground collector", _full_gcs_since_conc_gc);
@@ -2062,6 +2095,10 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
size_policy()->msc_collection_end(gch->gc_cause());
}
+ gc_timer->register_gc_end(os::elapsed_counter());
+
+ gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
+
// For a mark-sweep-compact, compute_new_size() will be called
// in the heap's do_collection() method.
}
@@ -2093,7 +2130,7 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
// required.
_collectorState = FinalMarking;
}
- collect_in_foreground(clear_all_soft_refs);
+ collect_in_foreground(clear_all_soft_refs, GenCollectedHeap::heap()->gc_cause());
// For a mark-sweep, compute_new_size() will be called
// in the heap's do_collection() method.
@@ -2153,7 +2190,7 @@ class ReleaseForegroundGC: public StackObj {
// one "collect" method between the background collector and the foreground
// collector but the if-then-else required made it cleaner to have
// separate methods.
-void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
+void CMSCollector::collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause) {
assert(Thread::current()->is_ConcurrentGC_thread(),
"A CMS asynchronous collection is only allowed on a CMS thread.");
@@ -2172,6 +2209,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
} else {
assert(_collectorState == Idling, "Should be idling before start.");
_collectorState = InitialMarking;
+ register_gc_start(cause);
// Reset the expansion cause, now that we are about to begin
// a new cycle.
clear_expansion_cause();
@@ -2184,6 +2222,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
// ensuing concurrent GC cycle.
update_should_unload_classes();
_full_gc_requested = false; // acks all outstanding full gc requests
+ _full_gc_cause = GCCause::_no_gc;
// Signal that we are about to start a collection
gch->increment_total_full_collections(); // ... starting a collection cycle
_collection_count_start = gch->total_full_collections();
@@ -2263,7 +2302,6 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
{
ReleaseForegroundGC x(this);
stats().record_cms_begin();
-
VM_CMS_Initial_Mark initial_mark_op(this);
VMThread::execute(&initial_mark_op);
}
@@ -2343,6 +2381,7 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
CMSTokenSync z(true); // not strictly needed.
if (_collectorState == Resizing) {
compute_new_size();
+ save_heap_summary();
_collectorState = Resetting;
} else {
assert(_collectorState == Idling, "The state should only change"
@@ -2401,7 +2440,39 @@ void CMSCollector::collect_in_background(bool clear_all_soft_refs) {
}
}
-void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
+void CMSCollector::register_foreground_gc_start(GCCause::Cause cause) {
+ if (!_cms_start_registered) {
+ register_gc_start(cause);
+ }
+}
+
+void CMSCollector::register_gc_start(GCCause::Cause cause) {
+ _cms_start_registered = true;
+ _gc_timer_cm->register_gc_start(os::elapsed_counter());
+ _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start());
+}
+
+void CMSCollector::register_gc_end() {
+ if (_cms_start_registered) {
+ report_heap_summary(GCWhen::AfterGC);
+
+ _gc_timer_cm->register_gc_end(os::elapsed_counter());
+ _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
+ _cms_start_registered = false;
+ }
+}
+
+void CMSCollector::save_heap_summary() {
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ _last_heap_summary = gch->create_heap_summary();
+ _last_metaspace_summary = gch->create_metaspace_summary();
+}
+
+void CMSCollector::report_heap_summary(GCWhen::Type when) {
+ _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_metaspace_summary);
+}
+
+void CMSCollector::collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause) {
assert(_foregroundGCIsActive && !_foregroundGCShouldWait,
"Foreground collector should be waiting, not executing");
assert(Thread::current()->is_VM_thread(), "A foreground collection"
@@ -2409,8 +2480,8 @@ void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
assert(ConcurrentMarkSweepThread::vm_thread_has_cms_token(),
"VM thread should have CMS token");
- NOT_PRODUCT(TraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
- true, gclog_or_tty);)
+ NOT_PRODUCT(GCTraceTime t("CMS:MS (foreground) ", PrintGCDetails && Verbose,
+ true, NULL);)
if (UseAdaptiveSizePolicy) {
size_policy()->ms_collection_begin();
}
@@ -2434,6 +2505,7 @@ void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
}
switch (_collectorState) {
case InitialMarking:
+ register_foreground_gc_start(cause);
init_mark_was_synchronous = true; // fact to be exploited in re-mark
checkpointRootsInitial(false);
assert(_collectorState == Marking, "Collector state should have changed"
@@ -2482,6 +2554,7 @@ void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) {
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
Universe::verify("Verify before reset: ");
}
+ save_heap_summary();
reset(false);
assert(_collectorState == Idling, "Collector state should "
"have changed");
@@ -3504,6 +3577,9 @@ void CMSCollector::checkpointRootsInitial(bool asynch) {
check_correct_thread_executing();
TraceCMSMemoryManagerStats tms(_collectorState,GenCollectedHeap::heap()->gc_cause());
+ save_heap_summary();
+ report_heap_summary(GCWhen::BeforeGC);
+
ReferenceProcessor* rp = ref_processor();
SpecializationStats::clear();
assert(_restart_addr == NULL, "Control point invariant");
@@ -3549,8 +3625,8 @@ void CMSCollector::checkpointRootsInitialWork(bool asynch) {
// CMS collection cycle.
setup_cms_unloading_and_verification_state();
- NOT_PRODUCT(TraceTime t("\ncheckpointRootsInitialWork",
- PrintGCDetails && Verbose, true, gclog_or_tty);)
+ NOT_PRODUCT(GCTraceTime t("\ncheckpointRootsInitialWork",
+ PrintGCDetails && Verbose, true, _gc_timer_cm);)
if (UseAdaptiveSizePolicy) {
size_policy()->checkpoint_roots_initial_begin();
}
@@ -4542,8 +4618,10 @@ size_t CMSCollector::preclean_work(bool clean_refs, bool clean_survivor) {
// The code in this method may need further
// tweaking for better performance and some restructuring
// for cleaner interfaces.
+ GCTimer *gc_timer = NULL; // Currently not tracing concurrent phases
rp->preclean_discovered_references(
- rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl);
+ rp->is_alive_non_header(), &keep_alive, &complete_trace, &yield_cl,
+ gc_timer);
}
if (clean_survivor) { // preclean the active survivor space(s)
@@ -4885,8 +4963,8 @@ void CMSCollector::checkpointRootsFinal(bool asynch,
// Temporarily set flag to false, GCH->do_collection will
// expect it to be false and set to true
FlagSetting fl(gch->_is_gc_active, false);
- NOT_PRODUCT(TraceTime t("Scavenge-Before-Remark",
- PrintGCDetails && Verbose, true, gclog_or_tty);)
+ NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark",
+ PrintGCDetails && Verbose, true, _gc_timer_cm);)
int level = _cmsGen->level() - 1;
if (level >= 0) {
gch->do_collection(true, // full (i.e. force, see below)
@@ -4915,7 +4993,7 @@ void CMSCollector::checkpointRootsFinal(bool asynch,
void CMSCollector::checkpointRootsFinalWork(bool asynch,
bool clear_all_soft_refs, bool init_mark_was_synchronous) {
- NOT_PRODUCT(TraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, gclog_or_tty);)
+ NOT_PRODUCT(GCTraceTime tr("checkpointRootsFinalWork", PrintGCDetails, false, _gc_timer_cm);)
assert(haveFreelistLocks(), "must have free list locks");
assert_lock_strong(bitMapLock());
@@ -4966,11 +5044,11 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
// the most recent young generation GC, minus those cleaned up by the
// concurrent precleaning.
if (CMSParallelRemarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
- TraceTime t("Rescan (parallel) ", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("Rescan (parallel) ", PrintGCDetails, false, _gc_timer_cm);
do_remark_parallel();
} else {
- TraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
- gclog_or_tty);
+ GCTraceTime t("Rescan (non-parallel) ", PrintGCDetails, false,
+ _gc_timer_cm);
do_remark_non_parallel();
}
}
@@ -4983,7 +5061,7 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
verify_overflow_empty();
{
- NOT_PRODUCT(TraceTime ts("refProcessingWork", PrintGCDetails, false, gclog_or_tty);)
+ NOT_PRODUCT(GCTraceTime ts("refProcessingWork", PrintGCDetails, false, _gc_timer_cm);)
refProcessingWork(asynch, clear_all_soft_refs);
}
verify_work_stacks_empty();
@@ -5044,6 +5122,8 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
verify_after_remark();
}
+ _gc_tracer_cm->report_object_count_after_gc(&_is_alive_closure);
+
// Change under the freelistLocks.
_collectorState = Sweeping;
// Call isAllClear() under bitMapLock
@@ -5697,7 +5777,7 @@ void CMSCollector::do_remark_non_parallel() {
NULL, // space is set further below
&_markBitMap, &_markStack, &mrias_cl);
{
- TraceTime t("grey object rescan", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("grey object rescan", PrintGCDetails, false, _gc_timer_cm);
// Iterate over the dirty cards, setting the corresponding bits in the
// mod union table.
{
@@ -5734,7 +5814,7 @@ void CMSCollector::do_remark_non_parallel() {
Universe::verify();
}
{
- TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("root rescan", PrintGCDetails, false, _gc_timer_cm);
verify_work_stacks_empty();
@@ -5756,7 +5836,7 @@ void CMSCollector::do_remark_non_parallel() {
}
{
- TraceTime t("visit unhandled CLDs", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("visit unhandled CLDs", PrintGCDetails, false, _gc_timer_cm);
verify_work_stacks_empty();
@@ -5775,7 +5855,7 @@ void CMSCollector::do_remark_non_parallel() {
}
{
- TraceTime t("dirty klass scan", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("dirty klass scan", PrintGCDetails, false, _gc_timer_cm);
verify_work_stacks_empty();
@@ -5977,7 +6057,9 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
_span, &_markBitMap, &_markStack,
&cmsKeepAliveClosure, false /* !preclean */);
{
- TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm);
+
+ ReferenceProcessorStats stats;
if (rp->processing_is_mt()) {
// Set the degree of MT here. If the discovery is done MT, there
// may have been a different number of threads doing the discovery
@@ -5996,16 +6078,20 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
}
rp->set_active_mt_degree(active_workers);
CMSRefProcTaskExecutor task_executor(*this);
- rp->process_discovered_references(&_is_alive_closure,
+ stats = rp->process_discovered_references(&_is_alive_closure,
&cmsKeepAliveClosure,
&cmsDrainMarkingStackClosure,
- &task_executor);
+ &task_executor,
+ _gc_timer_cm);
} else {
- rp->process_discovered_references(&_is_alive_closure,
+ stats = rp->process_discovered_references(&_is_alive_closure,
&cmsKeepAliveClosure,
&cmsDrainMarkingStackClosure,
- NULL);
+ NULL,
+ _gc_timer_cm);
}
+ _gc_tracer_cm->report_gc_reference_stats(stats);
+
}
// This is the point where the entire marking should have completed.
@@ -6013,7 +6099,7 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
if (should_unload_classes()) {
{
- TraceTime t("class unloading", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("class unloading", PrintGCDetails, false, _gc_timer_cm);
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure);
@@ -6026,7 +6112,7 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
}
{
- TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("scrub symbol table", PrintGCDetails, false, _gc_timer_cm);
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
}
@@ -6035,7 +6121,7 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) {
// CMS doesn't use the StringTable as hard roots when class unloading is turned off.
// Need to check if we really scanned the StringTable.
if ((roots_scanning_options() & SharedHeap::SO_Strings) == 0) {
- TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t("scrub string table", PrintGCDetails, false, _gc_timer_cm);
// Delete entries for dead interned strings.
StringTable::unlink(&_is_alive_closure);
}
@@ -6380,12 +6466,14 @@ void CMSCollector::reset(bool asynch) {
_cmsGen->rotate_debug_collection_type();
}
)
+
+ register_gc_end();
}
void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
- TraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+ GCTraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
TraceCollectorStats tcs(counters());
switch (op) {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
index 8d627c75792..bb485f4a83e 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
@@ -25,8 +25,10 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
+#include "gc_implementation/shared/gcHeapSummary.hpp"
#include "gc_implementation/shared/gSpaceCounters.hpp"
#include "gc_implementation/shared/gcStats.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
#include "memory/freeBlockDictionary.hpp"
#include "memory/generation.hpp"
@@ -53,6 +55,8 @@
class CMSAdaptiveSizePolicy;
class CMSConcMarkingTask;
class CMSGCAdaptivePolicyCounters;
+class CMSTracer;
+class ConcurrentGCTimer;
class ConcurrentMarkSweepGeneration;
class ConcurrentMarkSweepPolicy;
class ConcurrentMarkSweepThread;
@@ -61,6 +65,7 @@ class FreeChunk;
class PromotionInfo;
class ScanMarkedObjectsAgainCarefullyClosure;
class TenuredGeneration;
+class SerialOldTracer;
// A generic CMS bit map. It's the basis for both the CMS marking bit map
// as well as for the mod union table (in each case only a subset of the
@@ -567,8 +572,9 @@ class CMSCollector: public CHeapObj {
bool _completed_initialization;
// In support of ExplicitGCInvokesConcurrent
- static bool _full_gc_requested;
- unsigned int _collection_count_start;
+ static bool _full_gc_requested;
+ static GCCause::Cause _full_gc_cause;
+ unsigned int _collection_count_start;
// Should we unload classes this concurrent cycle?
bool _should_unload_classes;
@@ -609,6 +615,20 @@ class CMSCollector: public CHeapObj {
AdaptivePaddedAverage _inter_sweep_estimate;
AdaptivePaddedAverage _intra_sweep_estimate;
+ CMSTracer* _gc_tracer_cm;
+ ConcurrentGCTimer* _gc_timer_cm;
+
+ bool _cms_start_registered;
+
+ GCHeapSummary _last_heap_summary;
+ MetaspaceSummary _last_metaspace_summary;
+
+ void register_foreground_gc_start(GCCause::Cause cause);
+ void register_gc_start(GCCause::Cause cause);
+ void register_gc_end();
+ void save_heap_summary();
+ void report_heap_summary(GCWhen::Type when);
+
protected:
ConcurrentMarkSweepGeneration* _cmsGen; // old gen (CMS)
MemRegion _span; // span covering above two
@@ -827,6 +847,10 @@ class CMSCollector: public CHeapObj {
void do_mark_sweep_work(bool clear_all_soft_refs,
CollectorState first_state, bool should_start_over);
+ // Work methods for reporting concurrent mode interruption or failure
+ bool is_external_interruption();
+ void report_concurrent_mode_interruption();
+
// If the backgrould GC is active, acquire control from the background
// GC and do the collection.
void acquire_control_and_collect(bool full, bool clear_all_soft_refs);
@@ -876,11 +900,11 @@ class CMSCollector: public CHeapObj {
bool clear_all_soft_refs,
size_t size,
bool tlab);
- void collect_in_background(bool clear_all_soft_refs);
- void collect_in_foreground(bool clear_all_soft_refs);
+ void collect_in_background(bool clear_all_soft_refs, GCCause::Cause cause);
+ void collect_in_foreground(bool clear_all_soft_refs, GCCause::Cause cause);
// In support of ExplicitGCInvokesConcurrent
- static void request_full_gc(unsigned int full_gc_count);
+ static void request_full_gc(unsigned int full_gc_count, GCCause::Cause cause);
// Should we unload classes in a particular concurrent cycle?
bool should_unload_classes() const {
return _should_unload_classes;
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp
index 7bc1c1ea949..f8b0ccb90fe 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp
@@ -140,7 +140,9 @@ void ConcurrentMarkSweepThread::run() {
while (!_should_terminate) {
sleepBeforeNextCycle();
if (_should_terminate) break;
- _collector->collect_in_background(false); // !clear_all_soft_refs
+ GCCause::Cause cause = _collector->_full_gc_requested ?
+ _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
+ _collector->collect_in_background(false, cause);
}
assert(_should_terminate, "just checking");
// Check that the state of any protocol for synchronization
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
index eacd2a9f6e0..3e24c2419e5 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,12 @@
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp"
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
#include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "memory/gcLocker.inline.hpp"
#include "runtime/interfaceSupport.hpp"
+#include "runtime/os.hpp"
#include "utilities/dtrace.hpp"
@@ -60,6 +63,7 @@ void VM_CMS_Operation::release_and_notify_pending_list_lock() {
void VM_CMS_Operation::verify_before_gc() {
if (VerifyBeforeGC &&
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+ GCTraceTime tm("Verify Before", false, false, _collector->_gc_timer_cm);
HandleMark hm;
FreelistLocker x(_collector);
MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -71,6 +75,7 @@ void VM_CMS_Operation::verify_before_gc() {
void VM_CMS_Operation::verify_after_gc() {
if (VerifyAfterGC &&
GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
+ GCTraceTime tm("Verify After", false, false, _collector->_gc_timer_cm);
HandleMark hm;
FreelistLocker x(_collector);
MutexLockerEx y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
@@ -140,6 +145,8 @@ void VM_CMS_Initial_Mark::doit() {
);
#endif /* USDT2 */
+ _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter());
+
GenCollectedHeap* gch = GenCollectedHeap::heap();
GCCauseSetter gccs(gch, GCCause::_cms_initial_mark);
@@ -149,6 +156,9 @@ void VM_CMS_Initial_Mark::doit() {
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial, gch->gc_cause());
VM_CMS_Operation::verify_after_gc();
+
+ _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+
#ifndef USDT2
HS_DTRACE_PROBE(hs_private, cms__initmark__end);
#else /* USDT2 */
@@ -172,6 +182,8 @@ void VM_CMS_Final_Remark::doit() {
);
#endif /* USDT2 */
+ _collector->_gc_timer_cm->register_gc_pause_start("Final Mark", os::elapsed_counter());
+
GenCollectedHeap* gch = GenCollectedHeap::heap();
GCCauseSetter gccs(gch, GCCause::_cms_final_remark);
@@ -181,6 +193,10 @@ void VM_CMS_Final_Remark::doit() {
_collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal, gch->gc_cause());
VM_CMS_Operation::verify_after_gc();
+
+ _collector->save_heap_summary();
+ _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter());
+
#ifndef USDT2
HS_DTRACE_PROBE(hs_private, cms__remark__end);
#else /* USDT2 */
@@ -225,7 +241,7 @@ void VM_GenCollectFullConcurrent::doit() {
// In case CMS thread was in icms_wait(), wake it up.
CMSCollector::start_icms();
// Nudge the CMS thread to start a concurrent collection.
- CMSCollector::request_full_gc(_full_gc_count_before);
+ CMSCollector::request_full_gc(_full_gc_count_before, _gc_cause);
} else {
assert(_full_gc_count_before < gch->total_full_collections(), "Error");
FullGCCount_lock->notify_all(); // Inform the Java thread its work is done
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 137f76c0974..13a34a45156 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -36,6 +36,9 @@
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/referencePolicy.hpp"
#include "memory/resourceArea.hpp"
@@ -1342,6 +1345,9 @@ void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) {
_remark_times.add((now - start) * 1000.0);
g1p->record_concurrent_mark_remark_end();
+
+ G1CMIsAliveClosure is_alive(g1h);
+ g1h->gc_tracer_cm()->report_object_count_after_gc(&is_alive);
}
// Base class of the closures that finalize and verify the
@@ -2129,6 +2135,7 @@ void ConcurrentMark::cleanup() {
}
g1h->verify_region_sets_optional();
+ g1h->trace_heap_after_concurrent_cycle();
}
void ConcurrentMark::completeCleanup() {
@@ -2439,7 +2446,7 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
if (G1Log::finer()) {
gclog_or_tty->put(' ');
}
- TraceTime t("GC ref-proc", G1Log::finer(), false, gclog_or_tty);
+ GCTraceTime t("GC ref-proc", G1Log::finer(), false, g1h->gc_timer_cm());
ReferenceProcessor* rp = g1h->ref_processor_cm();
@@ -2491,10 +2498,13 @@ void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
rp->set_active_mt_degree(active_workers);
// Process the weak references.
- rp->process_discovered_references(&g1_is_alive,
- &g1_keep_alive,
- &g1_drain_mark_stack,
- executor);
+ const ReferenceProcessorStats& stats =
+ rp->process_discovered_references(&g1_is_alive,
+ &g1_keep_alive,
+ &g1_drain_mark_stack,
+ executor,
+ g1h->gc_timer_cm());
+ g1h->gc_tracer_cm()->report_gc_reference_stats(stats);
// The do_oop work routines of the keep_alive and drain_marking_stack
// oop closures will set the has_overflown flag if we overflow the
@@ -3227,6 +3237,9 @@ void ConcurrentMark::abort() {
satb_mq_set.set_active_all_threads(
false, /* new active value */
satb_mq_set.is_active() /* expected_active */);
+
+ _g1h->trace_heap_after_concurrent_cycle();
+ _g1h->register_concurrent_cycle_end();
}
static void print_ms_time_info(const char* prefix, const char* name,
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index 0e576488d4b..794224b66a7 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -569,8 +569,6 @@ protected:
void clear_has_overflown() { _has_overflown = false; }
bool restart_for_overflow() { return _restart_for_overflow; }
- bool has_aborted() { return _has_aborted; }
-
// Methods to enter the two overflow sync barriers
void enter_first_sync_barrier(uint worker_id);
void enter_second_sync_barrier(uint worker_id);
@@ -821,6 +819,8 @@ public:
// Called to abort the marking cycle after a Full GC takes palce.
void abort();
+ bool has_aborted() { return _has_aborted; }
+
// This prints the global/local fingers. It is used for debugging.
NOT_PRODUCT(void print_finger();)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
index a961fda8f51..ee53c3ba6e3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
@@ -93,7 +93,6 @@ void ConcurrentMarkThread::run() {
ResourceMark rm;
HandleMark hm;
double cycle_start = os::elapsedVTime();
- char verbose_str[128];
// We have to ensure that we finish scanning the root regions
// before the next GC takes place. To ensure this we have to
@@ -155,8 +154,7 @@ void ConcurrentMarkThread::run() {
}
CMCheckpointRootsFinalClosure final_cl(_cm);
- sprintf(verbose_str, "GC remark");
- VM_CGC_Operation op(&final_cl, verbose_str, true /* needs_pll */);
+ VM_CGC_Operation op(&final_cl, "GC remark", true /* needs_pll */);
VMThread::execute(&op);
}
if (cm()->restart_for_overflow()) {
@@ -187,8 +185,7 @@ void ConcurrentMarkThread::run() {
}
CMCleanUp cl_cl(_cm);
- sprintf(verbose_str, "GC cleanup");
- VM_CGC_Operation op(&cl_cl, verbose_str, false /* needs_pll */);
+ VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
VMThread::execute(&op);
} else {
// We don't want to update the marking status if a GC pause
@@ -292,6 +289,7 @@ void ConcurrentMarkThread::run() {
// called System.gc() with +ExplicitGCInvokesConcurrent).
_sts.join();
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
+ g1h->register_concurrent_cycle_end();
_sts.leave();
}
assert(_should_terminate, "just checking");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/evacuationInfo.hpp b/hotspot/src/share/vm/gc_implementation/g1/evacuationInfo.hpp
new file mode 100644
index 00000000000..97e0ab2f735
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/evacuationInfo.hpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
+
+#include "memory/allocation.hpp"
+
+class EvacuationInfo : public StackObj {
+ uint _collectionset_regions;
+ uint _allocation_regions;
+ size_t _collectionset_used_before;
+ size_t _collectionset_used_after;
+ size_t _alloc_regions_used_before;
+ size_t _bytes_copied;
+ uint _regions_freed;
+
+public:
+ EvacuationInfo() : _collectionset_regions(0), _allocation_regions(0), _collectionset_used_before(0),
+ _collectionset_used_after(0), _alloc_regions_used_before(0),
+ _bytes_copied(0), _regions_freed(0) { }
+
+ void set_collectionset_regions(uint collectionset_regions) {
+ _collectionset_regions = collectionset_regions;
+ }
+
+ void set_allocation_regions(uint allocation_regions) {
+ _allocation_regions = allocation_regions;
+ }
+
+ void set_collectionset_used_before(size_t used) {
+ _collectionset_used_before = used;
+ }
+
+ void increment_collectionset_used_after(size_t used) {
+ _collectionset_used_after += used;
+ }
+
+ void set_alloc_regions_used_before(size_t used) {
+ _alloc_regions_used_before = used;
+ }
+
+ void set_bytes_copied(size_t copied) {
+ _bytes_copied = copied;
+ }
+
+ void set_regions_freed(uint freed) {
+ _regions_freed += freed;
+ }
+
+ uint collectionset_regions() { return _collectionset_regions; }
+ uint allocation_regions() { return _allocation_regions; }
+ size_t collectionset_used_before() { return _collectionset_used_before; }
+ size_t collectionset_used_after() { return _collectionset_used_after; }
+ size_t alloc_regions_used_before() { return _alloc_regions_used_before; }
+ size_t bytes_copied() { return _bytes_copied; }
+ uint regions_freed() { return _regions_freed; }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_EVACUATIONINFO_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 0505822e873..db8f863ad25 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -38,10 +38,15 @@
#include "gc_implementation/g1/g1MarkSweep.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
#include "gc_implementation/g1/heapRegion.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "gc_implementation/g1/vm_operations_g1.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "memory/gcLocker.inline.hpp"
#include "memory/genOopClosures.inline.hpp"
@@ -76,7 +81,7 @@ size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
// The number of GC workers is passed to heap_region_par_iterate_chunked().
// It does use run_task() which sets _n_workers in the task.
// G1ParTask executes g1_process_strong_roots() ->
-// SharedHeap::process_strong_roots() which calls eventuall to
+// SharedHeap::process_strong_roots() which calls eventually to
// CardTableModRefBS::par_non_clean_card_iterate_work() which uses
// SequentialSubTasksDone. SharedHeap::process_strong_roots() also
// directly uses SubTasksDone (_process_strong_tasks field in SharedHeap).
@@ -457,7 +462,7 @@ bool G1CollectedHeap::is_in_partial_collection(const void* p) {
#endif
// Returns true if the reference points to an object that
-// can move in an incremental collecction.
+// can move in an incremental collection.
bool G1CollectedHeap::is_scavengable(const void* p) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1p = g1h->g1_policy();
@@ -548,7 +553,7 @@ G1CollectedHeap::new_region_try_secondary_free_list() {
return res;
}
- // Wait here until we get notifed either when (a) there are no
+ // Wait here until we get notified either when (a) there are no
// more free regions coming or (b) some regions have been moved on
// the secondary_free_list.
SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag);
@@ -623,7 +628,7 @@ uint G1CollectedHeap::humongous_obj_allocate_find_first(uint num_regions,
uint first = G1_NULL_HRS_INDEX;
if (num_regions == 1) {
// Only one region to allocate, no need to go through the slower
- // path. The caller will attempt the expasion if this fails, so
+ // path. The caller will attempt the expansion if this fails, so
// let's not try to expand here too.
HeapRegion* hr = new_region(word_size, false /* do_expand */);
if (hr != NULL) {
@@ -688,7 +693,7 @@ G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
// the first region.
HeapWord* new_obj = first_hr->bottom();
// This will be the new end of the first region in the series that
- // should also match the end of the last region in the seriers.
+ // should also match the end of the last region in the series.
HeapWord* new_end = new_obj + word_size_sum;
// This will be the new top of the first region that will reflect
// this allocation.
@@ -863,7 +868,7 @@ G1CollectedHeap::mem_allocate(size_t word_size,
bool* gc_overhead_limit_was_exceeded) {
assert_heap_not_locked_and_not_at_safepoint();
- // Loop until the allocation is satisified, or unsatisfied after GC.
+ // Loop until the allocation is satisfied, or unsatisfied after GC.
for (int try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) {
unsigned int gc_count_before;
@@ -1003,7 +1008,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size,
(*gclocker_retry_count_ret) += 1;
}
- // We can reach here if we were unsuccessul in scheduling a
+ // We can reach here if we were unsuccessful in scheduling a
// collection (because another thread beat us to it) or if we were
// stalled due to the GC locker. In either can we should retry the
// allocation attempt in case another thread successfully
@@ -1128,7 +1133,7 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size,
(*gclocker_retry_count_ret) += 1;
}
- // We can reach here if we were unsuccessul in scheduling a
+ // We can reach here if we were unsuccessful in scheduling a
// collection (because another thread beat us to it) or if we were
// stalled due to the GC locker. In either can we should retry the
// allocation attempt in case another thread successfully
@@ -1298,10 +1303,17 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
return false;
}
+ STWGCTimer* gc_timer = G1MarkSweep::gc_timer();
+ gc_timer->register_gc_start(os::elapsed_counter());
+
+ SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer();
+ gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start());
+
SvcGCMarker sgcm(SvcGCMarker::FULL);
ResourceMark rm;
print_heap_before_gc();
+ trace_heap_before_gc(gc_tracer);
size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes();
@@ -1322,7 +1334,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
{
- TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
+ GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL);
TraceCollectorStats tcs(g1mm()->full_collection_counters());
TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
@@ -1351,7 +1363,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
verify_before_gc();
- pre_full_gc_dump();
+ pre_full_gc_dump(gc_timer);
COMPILER2_PRESENT(DerivedPointerTable::clear());
@@ -1433,7 +1445,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
reset_gc_time_stamp();
// Since everything potentially moved, we will clear all remembered
- // sets, and clear all cards. Later we will rebuild remebered
+ // sets, and clear all cards. Later we will rebuild remembered
// sets. We will also reset the GC time stamps of the regions.
clear_rsets_post_compaction();
check_gc_time_stamps();
@@ -1553,8 +1565,12 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
}
print_heap_after_gc();
+ trace_heap_after_gc(gc_tracer);
- post_full_gc_dump();
+ post_full_gc_dump(gc_timer);
+
+ gc_timer->register_gc_end(os::elapsed_counter());
+ gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions());
}
return true;
@@ -1919,7 +1935,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_ref_processor_stw(NULL),
_process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)),
_bot_shared(NULL),
- _evac_failure_scan_stack(NULL) ,
+ _evac_failure_scan_stack(NULL),
_mark_in_progress(false),
_cg1r(NULL), _summary_bytes_used(0),
_g1mm(NULL),
@@ -1939,12 +1955,18 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_surviving_young_words(NULL),
_old_marking_cycles_started(0),
_old_marking_cycles_completed(0),
+ _concurrent_cycle_started(false),
_in_cset_fast_test(NULL),
_in_cset_fast_test_base(NULL),
_dirty_cards_region_list(NULL),
_worker_cset_start_region(NULL),
- _worker_cset_start_region_time_stamp(NULL) {
- _g1h = this; // To catch bugs.
+ _worker_cset_start_region_time_stamp(NULL),
+ _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()),
+ _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
+ _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
+ _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
+
+ _g1h = this;
if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) {
vm_exit_during_initialization("Failed necessary allocation.");
}
@@ -1959,13 +1981,14 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues, mtGC);
_worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(unsigned int, n_queues, mtGC);
+ _evacuation_failed_info_array = NEW_C_HEAP_ARRAY(EvacuationFailedInfo, n_queues, mtGC);
for (int i = 0; i < n_queues; i++) {
RefToScanQueue* q = new RefToScanQueue();
q->initialize();
_task_queues->register_queue(i, q);
+ ::new (&_evacuation_failed_info_array[i]) EvacuationFailedInfo();
}
-
clear_cset_start_regions();
// Initialize the G1EvacuationFailureALot counters and flags.
@@ -2025,7 +2048,7 @@ jint G1CollectedHeap::initialize() {
HeapRegion::GrainBytes);
// It is important to do this in a way such that concurrent readers can't
- // temporarily think somethings in the heap. (I've actually seen this
+ // temporarily think something is in the heap. (I've actually seen this
// happen in asserts: DLD.)
_reserved.set_word_size(0);
_reserved.set_start((HeapWord*)heap_rs.base());
@@ -2462,7 +2485,7 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) {
// We need to clear the "in_progress" flag in the CM thread before
// we wake up any waiters (especially when ExplicitInvokesConcurrent
// is set) so that if a waiter requests another System.gc() it doesn't
- // incorrectly see that a marking cyle is still in progress.
+ // incorrectly see that a marking cycle is still in progress.
if (concurrent) {
_cmThread->clear_in_progress();
}
@@ -2474,6 +2497,49 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) {
FullGCCount_lock->notify_all();
}
+void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) {
+ _concurrent_cycle_started = true;
+ _gc_timer_cm->register_gc_start(start_time);
+
+ _gc_tracer_cm->report_gc_start(gc_cause(), _gc_timer_cm->gc_start());
+ trace_heap_before_gc(_gc_tracer_cm);
+}
+
+void G1CollectedHeap::register_concurrent_cycle_end() {
+ if (_concurrent_cycle_started) {
+ _gc_timer_cm->register_gc_end(os::elapsed_counter());
+
+ if (_cm->has_aborted()) {
+ _gc_tracer_cm->report_concurrent_mode_failure();
+ }
+ _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
+
+ _concurrent_cycle_started = false;
+ }
+}
+
+void G1CollectedHeap::trace_heap_after_concurrent_cycle() {
+ if (_concurrent_cycle_started) {
+ trace_heap_after_gc(_gc_tracer_cm);
+ }
+}
+
+G1YCType G1CollectedHeap::yc_type() {
+ bool is_young = g1_policy()->gcs_are_young();
+ bool is_initial_mark = g1_policy()->during_initial_mark_pause();
+ bool is_during_mark = mark_in_progress();
+
+ if (is_initial_mark) {
+ return InitialMark;
+ } else if (is_during_mark) {
+ return DuringMark;
+ } else if (is_young) {
+ return Normal;
+ } else {
+ return Mixed;
+ }
+}
+
void G1CollectedHeap::collect(GCCause::Cause cause) {
assert_heap_not_locked();
@@ -2676,13 +2742,13 @@ G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
break;
}
- // Noone should have claimed it directly. We can given
+ // No one should have claimed it directly. We can given
// that we claimed its "starts humongous" region.
assert(chr->claim_value() != claim_value, "sanity");
assert(chr->humongous_start_region() == r, "sanity");
if (chr->claimHeapRegion(claim_value)) {
- // we should always be able to claim it; noone else should
+ // we should always be able to claim it; no one else should
// be trying to claim this region
bool res2 = cl->doHeapRegion(chr);
@@ -2976,7 +3042,7 @@ size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
// the min TLAB size.
// Also, this value can be at most the humongous object threshold,
- // since we can't allow tlabs to grow big enough to accomodate
+ // since we can't allow tlabs to grow big enough to accommodate
// humongous objects.
HeapRegion* hr = _mutator_alloc_region.get();
@@ -3743,10 +3809,15 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
return false;
}
+ _gc_timer_stw->register_gc_start(os::elapsed_counter());
+
+ _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start());
+
SvcGCMarker sgcm(SvcGCMarker::MINOR);
ResourceMark rm;
print_heap_before_gc();
+ trace_heap_before_gc(_gc_tracer_stw);
HRSPhaseSetter x(HRSPhaseEvacuation);
verify_region_sets_optional();
@@ -3771,11 +3842,17 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
// Inner scope for scope based logging, timers, and stats collection
{
+ EvacuationInfo evacuation_info;
+
if (g1_policy()->during_initial_mark_pause()) {
// We are about to start a marking cycle, so we increment the
// full collection counter.
increment_old_marking_cycles_started();
+ register_concurrent_cycle_start(_gc_timer_stw->gc_start());
}
+
+ _gc_tracer_stw->report_yc_type(yc_type());
+
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
@@ -3885,7 +3962,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
#endif // YOUNG_LIST_VERBOSE
- g1_policy()->finalize_cset(target_pause_time_ms);
+ g1_policy()->finalize_cset(target_pause_time_ms, evacuation_info);
_cm->note_start_of_gc();
// We should not verify the per-thread SATB buffers given that
@@ -3921,10 +3998,10 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
setup_surviving_young_words();
// Initialize the GC alloc regions.
- init_gc_alloc_regions();
+ init_gc_alloc_regions(evacuation_info);
// Actually do the work...
- evacuate_collection_set();
+ evacuate_collection_set(evacuation_info);
// We do this to mainly verify the per-thread SATB buffers
// (which have been filtered by now) since we didn't verify
@@ -3936,7 +4013,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
true /* verify_thread_buffers */,
true /* verify_fingers */);
- free_collection_set(g1_policy()->collection_set());
+ free_collection_set(g1_policy()->collection_set(), evacuation_info);
g1_policy()->clear_collection_set();
cleanup_surviving_young_words();
@@ -3964,13 +4041,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
#endif // YOUNG_LIST_VERBOSE
g1_policy()->record_survivor_regions(_young_list->survivor_length(),
- _young_list->first_survivor_region(),
- _young_list->last_survivor_region());
+ _young_list->first_survivor_region(),
+ _young_list->last_survivor_region());
_young_list->reset_auxilary_lists();
if (evacuation_failed()) {
_summary_bytes_used = recalculate_used();
+ uint n_queues = MAX2((int)ParallelGCThreads, 1);
+ for (uint i = 0; i < n_queues; i++) {
+ if (_evacuation_failed_info_array[i].has_failed()) {
+ _gc_tracer_stw->report_evacuation_failed(_evacuation_failed_info_array[i]);
+ }
+ }
} else {
// The "used" of the the collection set have already been subtracted
// when they were freed. Add in the bytes evacuated.
@@ -4013,7 +4096,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
}
}
- // We redo the verificaiton but now wrt to the new CSet which
+ // We redo the verification but now wrt to the new CSet which
// has just got initialized after the previous CSet was freed.
_cm->verify_no_cset_oops(true /* verify_stacks */,
true /* verify_enqueued_buffers */,
@@ -4026,7 +4109,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
// investigate this in CR 7178365.
double sample_end_time_sec = os::elapsedTime();
double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
- g1_policy()->record_collection_pause_end(pause_time_ms);
+ g1_policy()->record_collection_pause_end(pause_time_ms, evacuation_info);
MemoryService::track_memory_usage();
@@ -4093,14 +4176,19 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
print_heap_after_gc();
+ trace_heap_after_gc(_gc_tracer_stw);
// We must call G1MonitoringSupport::update_sizes() in the same scoping level
// as an active TraceMemoryManagerStats object (i.e. before the destructor for the
// TraceMemoryManagerStats is called) so that the G1 memory pools are updated
// before any GC notifications are raised.
g1mm()->update_sizes();
- }
+ _gc_tracer_stw->report_evacuation_info(&evacuation_info);
+ _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold());
+ _gc_timer_stw->register_gc_end(os::elapsed_counter());
+ _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions());
+ }
// It should now be safe to tell the concurrent mark thread to start
// without its logging output interfering with the logging output
// that came from the pause.
@@ -4152,7 +4240,7 @@ void G1CollectedHeap::release_mutator_alloc_region() {
assert(_mutator_alloc_region.get() == NULL, "post-condition");
}
-void G1CollectedHeap::init_gc_alloc_regions() {
+void G1CollectedHeap::init_gc_alloc_regions(EvacuationInfo& evacuation_info) {
assert_at_safepoint(true /* should_be_vm_thread */);
_survivor_gc_alloc_region.init();
@@ -4167,7 +4255,7 @@ void G1CollectedHeap::init_gc_alloc_regions() {
// a cleanup and it should be on the free list now), or
// d) it's humongous (this means that it was emptied
// during a cleanup and was added to the free list, but
- // has been subseqently used to allocate a humongous
+ // has been subsequently used to allocate a humongous
// object that may be less than the region size).
if (retained_region != NULL &&
!retained_region->in_collection_set() &&
@@ -4184,10 +4272,13 @@ void G1CollectedHeap::init_gc_alloc_regions() {
retained_region->note_start_of_copying(during_im);
_old_gc_alloc_region.set(retained_region);
_hr_printer.reuse(retained_region);
+ evacuation_info.set_alloc_regions_used_before(retained_region->used());
}
}
-void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers) {
+void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) {
+ evacuation_info.set_allocation_regions(_survivor_gc_alloc_region.count() +
+ _old_gc_alloc_region.count());
_survivor_gc_alloc_region.release();
// If we have an old GC alloc region to release, we'll save it in
// _retained_old_gc_alloc_region. If we don't
@@ -4270,7 +4361,7 @@ void G1CollectedHeap::drain_evac_failure_scan_stack() {
}
oop
-G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
+G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state,
oop old) {
assert(obj_in_cs(old),
err_msg("obj: "PTR_FORMAT" should still be in the CSet",
@@ -4279,7 +4370,12 @@ G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
oop forward_ptr = old->forward_to_atomic(old);
if (forward_ptr == NULL) {
// Forward-to-self succeeded.
+ assert(_par_scan_state != NULL, "par scan state");
+ OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure();
+ uint queue_num = _par_scan_state->queue_num();
+ _evacuation_failed = true;
+ _evacuation_failed_info_array[queue_num].register_copy_failure(old->size());
if (_evac_failure_closure != cl) {
MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag);
assert(!_drain_in_progress,
@@ -4310,8 +4406,6 @@ G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl,
}
void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) {
- set_evacuation_failed(true);
-
preserve_mark_if_necessary(old, m);
HeapRegion* r = heap_region_containing(old);
@@ -4561,8 +4655,7 @@ oop G1ParCopyClosure
if (obj_ptr == NULL) {
// This will either forward-to-self, or detect that someone else has
// installed a forwarding pointer.
- OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure();
- return _g1->handle_evacuation_failure_par(cl, old);
+ return _g1->handle_evacuation_failure_par(_par_scan_state, old);
}
oop obj = oop(obj_ptr);
@@ -5166,7 +5259,7 @@ public:
// will be copied, the reference field set to point to the
// new location, and the RSet updated. Otherwise we need to
// use the the non-heap or metadata closures directly to copy
- // the refernt object and update the pointer, while avoiding
+ // the referent object and update the pointer, while avoiding
// updating the RSet.
if (_g1h->is_in_g1_reserved(p)) {
@@ -5334,7 +5427,7 @@ public:
}
};
-// Driver routine for parallel reference enqueing.
+// Driver routine for parallel reference enqueueing.
// Creates an instance of the ref enqueueing gang
// task and has the worker threads execute it.
@@ -5463,7 +5556,7 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
// processor would have seen that the reference object had already
// been 'discovered' and would have skipped discovering the reference,
// but would not have treated the reference object as a regular oop.
- // As a reult the copy closure would not have been applied to the
+ // As a result the copy closure would not have been applied to the
// referent object.
//
// We need to explicitly copy these referent objects - the references
@@ -5539,21 +5632,28 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
// Setup the soft refs policy...
rp->setup_policy(false);
+ ReferenceProcessorStats stats;
if (!rp->processing_is_mt()) {
// Serial reference processing...
- rp->process_discovered_references(&is_alive,
- &keep_alive,
- &drain_queue,
- NULL);
+ stats = rp->process_discovered_references(&is_alive,
+ &keep_alive,
+ &drain_queue,
+ NULL,
+ _gc_timer_stw);
} else {
// Parallel reference processing
assert(rp->num_q() == no_of_gc_workers, "sanity");
assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
- rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor);
+ stats = rp->process_discovered_references(&is_alive,
+ &keep_alive,
+ &drain_queue,
+ &par_task_executor,
+ _gc_timer_stw);
}
+ _gc_tracer_stw->report_gc_reference_stats(stats);
// We have completed copying any necessary live referent objects
// (that were not copied during the actual pause) so we can
// retire any active alloc buffers
@@ -5577,7 +5677,7 @@ void G1CollectedHeap::enqueue_discovered_references(uint no_of_gc_workers) {
// Serial reference processing...
rp->enqueue_discovered_references();
} else {
- // Parallel reference enqueuing
+ // Parallel reference enqueueing
assert(no_of_gc_workers == workers()->active_workers(),
"Need to reset active workers");
@@ -5594,15 +5694,15 @@ void G1CollectedHeap::enqueue_discovered_references(uint no_of_gc_workers) {
// FIXME
// CM's reference processing also cleans up the string and symbol tables.
// Should we do that here also? We could, but it is a serial operation
- // and could signicantly increase the pause time.
+ // and could significantly increase the pause time.
double ref_enq_time = os::elapsedTime() - ref_enq_start;
g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
}
-void G1CollectedHeap::evacuate_collection_set() {
+void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
_expand_heap_after_alloc_failure = true;
- set_evacuation_failed(false);
+ _evacuation_failed = false;
// Should G1EvacuationFailureALot be in effect for this GC?
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
@@ -5691,7 +5791,7 @@ void G1CollectedHeap::evacuate_collection_set() {
JNIHandles::weak_oops_do(&is_alive, &keep_alive);
}
- release_gc_alloc_regions(n_workers);
+ release_gc_alloc_regions(n_workers, evacuation_info);
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
// Reset and re-enable the hot card cache.
@@ -5714,7 +5814,7 @@ void G1CollectedHeap::evacuate_collection_set() {
// Enqueue any remaining references remaining on the STW
// reference processor's discovered lists. We need to do
// this after the card table is cleaned (and verified) as
- // the act of enqueuing entries on to the pending list
+ // the act of enqueueing entries on to the pending list
// will log these updates (and dirty their associated
// cards). We need these updates logged to update any
// RSets.
@@ -5942,7 +6042,7 @@ void G1CollectedHeap::cleanUpCardTable() {
g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0);
}
-void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) {
+void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info) {
size_t pre_used = 0;
FreeRegionList local_free_list("Local List for CSet Freeing");
@@ -6028,10 +6128,12 @@ void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) {
cur->set_evacuation_failed(false);
// The region is now considered to be old.
_old_set.add(cur);
+ evacuation_info.increment_collectionset_used_after(cur->used());
}
cur = next;
}
+ evacuation_info.set_regions_freed(local_free_list.length());
policy->record_max_rs_lengths(rs_lengths);
policy->cset_regions_freed();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index 3f22247e8e1..6843d13f736 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_HPP
#include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/evacuationInfo.hpp"
#include "gc_implementation/g1/g1AllocRegion.hpp"
#include "gc_implementation/g1/g1HRPrinter.hpp"
-#include "gc_implementation/g1/g1RemSet.hpp"
#include "gc_implementation/g1/g1MonitoringSupport.hpp"
+#include "gc_implementation/g1/g1RemSet.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp"
#include "gc_implementation/g1/heapRegionSets.hpp"
#include "gc_implementation/shared/hSpaceCounters.hpp"
@@ -61,7 +63,12 @@ class HeapRegionRemSetIterator;
class ConcurrentMark;
class ConcurrentMarkThread;
class ConcurrentG1Refine;
+class ConcurrentGCTimer;
class GenerationCounters;
+class STWGCTimer;
+class G1NewTracer;
+class G1OldTracer;
+class EvacuationFailedInfo;
typedef OverflowTaskQueue RefToScanQueue;
typedef GenericTaskQueueSet RefToScanQueueSet;
@@ -160,7 +167,7 @@ public:
// An instance is embedded into the G1CH and used as the
// (optional) _is_alive_non_header closure in the STW
// reference processor. It is also extensively used during
-// refence processing during STW evacuation pauses.
+// reference processing during STW evacuation pauses.
class G1STWIsAliveClosure: public BoolObjectClosure {
G1CollectedHeap* _g1;
public:
@@ -323,10 +330,10 @@ private:
void release_mutator_alloc_region();
// It initializes the GC alloc regions at the start of a GC.
- void init_gc_alloc_regions();
+ void init_gc_alloc_regions(EvacuationInfo& evacuation_info);
// It releases the GC alloc regions at the end of a GC.
- void release_gc_alloc_regions(uint no_of_gc_workers);
+ void release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info);
// It does any cleanup that needs to be done on the GC alloc regions
// before a Full GC.
@@ -389,6 +396,8 @@ private:
// concurrent cycles) we have completed.
volatile unsigned int _old_marking_cycles_completed;
+ bool _concurrent_cycle_started;
+
// This is a non-product method that is helpful for testing. It is
// called at the end of a GC and artificially expands the heap by
// allocating a number of dead regions. This way we can induce very
@@ -734,6 +743,12 @@ public:
return _old_marking_cycles_completed;
}
+ void register_concurrent_cycle_start(jlong start_time);
+ void register_concurrent_cycle_end();
+ void trace_heap_after_concurrent_cycle();
+
+ G1YCType yc_type();
+
G1HRPrinter* hr_printer() { return &_hr_printer; }
protected:
@@ -769,7 +784,7 @@ protected:
bool do_collection_pause_at_safepoint(double target_pause_time_ms);
// Actually do the work of evacuating the collection set.
- void evacuate_collection_set();
+ void evacuate_collection_set(EvacuationInfo& evacuation_info);
// The g1 remembered set of the heap.
G1RemSet* _g1_rem_set;
@@ -794,7 +809,7 @@ protected:
// After a collection pause, make the regions in the CS into free
// regions.
- void free_collection_set(HeapRegion* cs_head);
+ void free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info);
// Abandon the current collection set without recording policy
// statistics or updating free lists.
@@ -863,9 +878,7 @@ protected:
// True iff a evacuation has failed in the current collection.
bool _evacuation_failed;
- // Set the attribute indicating whether evacuation has failed in the
- // current collection.
- void set_evacuation_failed(bool b) { _evacuation_failed = b; }
+ EvacuationFailedInfo* _evacuation_failed_info_array;
// Failed evacuations cause some logical from-space objects to have
// forwarding pointers to themselves. Reset them.
@@ -907,7 +920,7 @@ protected:
void finalize_for_evac_failure();
// An attempt to evacuate "obj" has failed; take necessary steps.
- oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj);
+ oop handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state, oop obj);
void handle_evacuation_failure_common(oop obj, markOop m);
#ifndef PRODUCT
@@ -939,13 +952,13 @@ protected:
inline bool evacuation_should_fail();
// Reset the G1EvacuationFailureALot counters. Should be called at
- // the end of an evacuation pause in which an evacuation failure ocurred.
+ // the end of an evacuation pause in which an evacuation failure occurred.
inline void reset_evacuation_should_fail();
#endif // !PRODUCT
// ("Weak") Reference processing support.
//
- // G1 has 2 instances of the referece processor class. One
+ // G1 has 2 instances of the reference processor class. One
// (_ref_processor_cm) handles reference object discovery
// and subsequent processing during concurrent marking cycles.
//
@@ -995,6 +1008,12 @@ protected:
// The (stw) reference processor...
ReferenceProcessor* _ref_processor_stw;
+ STWGCTimer* _gc_timer_stw;
+ ConcurrentGCTimer* _gc_timer_cm;
+
+ G1OldTracer* _gc_tracer_cm;
+ G1NewTracer* _gc_tracer_stw;
+
// During reference object discovery, the _is_alive_non_header
// closure (if non-null) is applied to the referent object to
// determine whether the referent is live. If so then the
@@ -1140,9 +1159,12 @@ public:
// The STW reference processor....
ReferenceProcessor* ref_processor_stw() const { return _ref_processor_stw; }
- // The Concurent Marking reference processor...
+ // The Concurrent Marking reference processor...
ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; }
+ ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; }
+ G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; }
+
virtual size_t capacity() const;
virtual size_t used() const;
// This should be called when we're not holding the heap lock. The
@@ -1200,7 +1222,7 @@ public:
// verify_region_sets_optional() is planted in the code for
// list verification in non-product builds (and it can be enabled in
- // product builds by definning HEAP_REGION_SET_FORCE_VERIFY to be 1).
+ // product builds by defining HEAP_REGION_SET_FORCE_VERIFY to be 1).
#if HEAP_REGION_SET_FORCE_VERIFY
void verify_region_sets_optional() {
verify_region_sets();
@@ -1266,7 +1288,7 @@ public:
// The same as above but assume that the caller holds the Heap_lock.
void collect_locked(GCCause::Cause cause);
- // True iff a evacuation has failed in the most-recent collection.
+ // True iff an evacuation has failed in the most-recent collection.
bool evacuation_failed() { return _evacuation_failed; }
// It will free a region if it has allocated objects in it that are
@@ -1554,6 +1576,7 @@ public:
// Override; it uses the "prev" marking information
virtual void verify(bool silent);
+
virtual void print_on(outputStream* st) const;
virtual void print_extended_on(outputStream* st) const;
virtual void print_on_error(outputStream* st) const;
@@ -1839,7 +1862,7 @@ protected:
G1ParScanHeapEvacClosure* _evac_cl;
G1ParScanPartialArrayClosure* _partial_scan_cl;
- int _hash_seed;
+ int _hash_seed;
uint _queue_num;
size_t _term_attempts;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 741c6b7130a..3bd04281955 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -909,7 +909,7 @@ bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc
// Anything below that is considered to be zero
#define MIN_TIMER_GRANULARITY 0.0000001
-void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, EvacuationInfo& evacuation_info) {
double end_time_sec = os::elapsedTime();
assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(),
"otherwise, the subtraction below does not make sense");
@@ -941,6 +941,9 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
_mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
end_time_sec, false);
+ evacuation_info.set_collectionset_used_before(_collection_set_bytes_used_before);
+ evacuation_info.set_bytes_copied(_bytes_copied_during_gc);
+
if (update_stats) {
_trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
// this is where we update the allocation rate of the application
@@ -1896,7 +1899,7 @@ uint G1CollectorPolicy::calc_max_old_cset_length() {
}
-void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
+void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info) {
double young_start_time_sec = os::elapsedTime();
YoungList* young_list = _g1->young_list();
@@ -2102,6 +2105,7 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
double non_young_end_time_sec = os::elapsedTime();
phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
+ evacuation_info.set_collectionset_regions(cset_region_length());
}
void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index 90106c00a34..a497f2fa3b6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -671,7 +671,7 @@ public:
// Record the start and end of an evacuation pause.
void record_collection_pause_start(double start_time_sec);
- void record_collection_pause_end(double pause_time_ms);
+ void record_collection_pause_end(double pause_time_ms, EvacuationInfo& evacuation_info);
// Record the start and end of a full collection.
void record_full_collection_start();
@@ -720,7 +720,7 @@ public:
// Choose a new collection set. Marks the chosen regions as being
// "in_collection_set", and links them together. The head and number of
// the collection set are available via access methods.
- void finalize_cset(double target_pause_time_ms);
+ void finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info);
// The head of the list (via "next_in_collection_set()") representing the
// current collection set.
@@ -879,6 +879,7 @@ private:
ageTable _survivors_age_table;
public:
+ uint tenuring_threshold() const { return _tenuring_threshold; }
inline GCAllocPurpose
evacuation_destination(HeapRegion* src_region, uint age, size_t word_sz) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
index 2fa5300b141..a1c5739f1ae 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
@@ -38,7 +38,7 @@ class WorkerDataArray : public CHeapObj {
NOT_PRODUCT(static const T _uninitialized;)
// We are caching the sum and average to only have to calculate them once.
- // This is not done in an MT-safe way. It is intetened to allow single
+ // This is not done in an MT-safe way. It is intended to allow single
// threaded code to call sum() and average() multiple times in any order
// without having to worry about the cost.
bool _has_new_data;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
index d87a6cca135..adde08f2177 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,10 @@
#include "code/icBuffer.hpp"
#include "gc_implementation/g1/g1Log.hpp"
#include "gc_implementation/g1/g1MarkSweep.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "memory/gcLocker.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/modRefBarrierSet.hpp"
@@ -119,7 +123,7 @@ void G1MarkSweep::allocate_stacks() {
void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them
- TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer());
GenMarkSweep::trace(" 1");
SharedHeap* sh = SharedHeap::heap();
@@ -139,10 +143,13 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity");
rp->setup_policy(clear_all_softrefs);
- rp->process_discovered_references(&GenMarkSweep::is_alive,
- &GenMarkSweep::keep_alive,
- &GenMarkSweep::follow_stack_closure,
- NULL);
+ const ReferenceProcessorStats& stats =
+ rp->process_discovered_references(&GenMarkSweep::is_alive,
+ &GenMarkSweep::keep_alive,
+ &GenMarkSweep::follow_stack_closure,
+ NULL,
+ gc_timer());
+ gc_tracer()->report_gc_reference_stats(stats);
// This is the point where the entire marking should have completed.
@@ -185,6 +192,8 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
gclog_or_tty->print_cr("]");
}
}
+
+ gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
}
class G1PrepareCompactClosure: public HeapRegionClosure {
@@ -257,7 +266,7 @@ void G1MarkSweep::mark_sweep_phase2() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer());
GenMarkSweep::trace("2");
// find the first region
@@ -294,7 +303,7 @@ void G1MarkSweep::mark_sweep_phase3() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
// Adjust the pointers to reflect the new locations
- TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer());
GenMarkSweep::trace("3");
SharedHeap* sh = SharedHeap::heap();
@@ -353,7 +362,7 @@ void G1MarkSweep::mark_sweep_phase4() {
// to use a higher index (saved from phase2) when verifying perm_gen.
G1CollectedHeap* g1h = G1CollectedHeap::heap();
- TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer());
GenMarkSweep::trace("4");
G1SpaceCompactClosure blk;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
index c49bc19398a..f1b9d8356c3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,9 @@ class G1MarkSweep : AllStatic {
static void invoke_at_safepoint(ReferenceProcessor* rp,
bool clear_all_softrefs);
+ static STWGCTimer* gc_timer() { return GenMarkSweep::_gc_timer; }
+ static SerialOldTracer* gc_tracer() { return GenMarkSweep::_gc_tracer; }
+
private:
// Mark live objects
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
index 4e1761e260b..03b7300ae51 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -224,6 +224,7 @@ class G1MonitoringSupport : public CHeapObj {
// Monitoring support used by
// MemoryService
// jstat counters
+ // Tracing
size_t overall_reserved() { return _overall_reserved; }
size_t overall_committed() { return _overall_committed; }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1YCTypes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1YCTypes.hpp
new file mode 100644
index 00000000000..7d2216059cb
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1YCTypes.hpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
+
+#include "utilities/debug.hpp"
+
+enum G1YCType {
+ Normal,
+ InitialMark,
+ DuringMark,
+ Mixed,
+ G1YCTypeEndSentinel
+};
+
+class G1YCTypeHelper {
+ public:
+ static const char* to_string(G1YCType type) {
+ switch(type) {
+ case Normal: return "Normal";
+ case InitialMark: return "Initial Mark";
+ case DuringMark: return "During Mark";
+ case Mixed: return "Mixed";
+ default: ShouldNotReachHere(); return NULL;
+ }
+ }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1YCTYPES_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
index cf7488ffebd..3be06e6ae10 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/g1/g1Log.hpp"
#include "gc_implementation/g1/vm_operations_g1.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "gc_implementation/g1/vm_operations_g1.hpp"
#include "runtime/interfaceSupport.hpp"
@@ -227,7 +229,7 @@ void VM_CGC_Operation::release_and_notify_pending_list_lock() {
void VM_CGC_Operation::doit() {
gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
- TraceTime t(_printGCMessage, G1Log::fine(), true, gclog_or_tty);
+ GCTraceTime t(_printGCMessage, G1Log::fine(), true, G1CollectedHeap::heap()->gc_timer_cm());
SharedHeap* sh = SharedHeap::heap();
// This could go away if CollectedHeap gave access to _gc_is_active...
if (sh != NULL) {
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
index e868d870990..c104533a47b 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,11 @@
#include "gc_implementation/shared/adaptiveSizePolicy.hpp"
#include "gc_implementation/shared/ageTable.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/defNewGeneration.inline.hpp"
#include "memory/genCollectedHeap.hpp"
@@ -75,7 +80,6 @@ ParScanThreadState::ParScanThreadState(Space* to_space_,
work_queue_set_, &term_),
_is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
_keep_alive_closure(&_scan_weak_ref_closure),
- _promotion_failure_size(0),
_strong_roots_time(0.0), _term_time(0.0)
{
#if TASKQUEUE_STATS
@@ -279,13 +283,10 @@ void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
}
}
-void ParScanThreadState::print_and_clear_promotion_failure_size() {
- if (_promotion_failure_size != 0) {
- if (PrintPromotionFailure) {
- gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
- _thread_num, _promotion_failure_size);
- }
- _promotion_failure_size = 0;
+void ParScanThreadState::print_promotion_failure_size() {
+ if (_promotion_failed_info.has_failed() && PrintPromotionFailure) {
+ gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
+ _thread_num, _promotion_failed_info.first_size());
}
}
@@ -305,6 +306,7 @@ public:
inline ParScanThreadState& thread_state(int i);
+ void trace_promotion_failed(YoungGCTracer& gc_tracer);
void reset(int active_workers, bool promotion_failed);
void flush();
@@ -353,13 +355,21 @@ inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i)
return ((ParScanThreadState*)_data)[i];
}
+void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
+ for (int i = 0; i < length(); ++i) {
+ if (thread_state(i).promotion_failed()) {
+ gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info());
+ thread_state(i).promotion_failed_info().reset();
+ }
+ }
+}
void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed)
{
_term.reset_for_reuse(active_threads);
if (promotion_failed) {
for (int i = 0; i < length(); ++i) {
- thread_state(i).print_and_clear_promotion_failure_size();
+ thread_state(i).print_promotion_failure_size();
}
}
}
@@ -583,14 +593,6 @@ void ParNewGenTask::set_for_termination(int active_workers) {
gch->set_n_termination(active_workers);
}
-// The "i" passed to this method is the part of the work for
-// this thread. It is not the worker ID. The "i" is derived
-// from _started_workers which is incremented in internal_note_start()
-// called in GangWorker loop() and which is called under the
-// which is called under the protection of the gang monitor and is
-// called after a task is started. So "i" is based on
-// first-come-first-served.
-
void ParNewGenTask::work(uint worker_id) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
// Since this is being done in a separate thread, need new resource
@@ -876,16 +878,45 @@ void EvacuateFollowersClosureGeneral::do_void() {
}
+// A Generation that does parallel young-gen collection.
+
bool ParNewGeneration::_avoid_promotion_undo = false;
-// A Generation that does parallel young-gen collection.
+void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
+ assert(_promo_failure_scan_stack.is_empty(), "post condition");
+ _promo_failure_scan_stack.clear(true); // Clear cached segments.
+
+ remove_forwarding_pointers();
+ if (PrintGCDetails) {
+ gclog_or_tty->print(" (promotion failed)");
+ }
+ // All the spaces are in play for mark-sweep.
+ swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
+ from()->set_next_compaction_space(to());
+ gch->set_incremental_collection_failed();
+ // Inform the next generation that a promotion failure occurred.
+ _next_gen->promotion_failure_occurred();
+
+ // Trace promotion failure in the parallel GC threads
+ thread_state_set.trace_promotion_failed(gc_tracer);
+ // Single threaded code may have reported promotion failure to the global state
+ if (_promotion_failed_info.has_failed()) {
+ gc_tracer.report_promotion_failed(_promotion_failed_info);
+ }
+ // Reset the PromotionFailureALot counters.
+ NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+}
void ParNewGeneration::collect(bool full,
bool clear_all_soft_refs,
size_t size,
bool is_tlab) {
assert(full || size > 0, "otherwise we don't want to collect");
+
GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+ _gc_timer->register_gc_start(os::elapsed_counter());
+
assert(gch->kind() == CollectedHeap::GenCollectedHeap,
"not a CMS generational heap");
AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
@@ -906,7 +937,7 @@ void ParNewGeneration::collect(bool full,
set_avoid_promotion_undo(true);
}
- // If the next generation is too full to accomodate worst-case promotion
+ // If the next generation is too full to accommodate worst-case promotion
// from this generation, pass on collection; let the next generation
// do it.
if (!collection_attempt_is_safe()) {
@@ -915,6 +946,10 @@ void ParNewGeneration::collect(bool full,
}
assert(to()->is_empty(), "Else not collection_attempt_is_safe");
+ ParNewTracer gc_tracer;
+ gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
+ gch->trace_heap_before_gc(&gc_tracer);
+
init_assuming_no_promotion_failure();
if (UseAdaptiveSizePolicy) {
@@ -922,7 +957,7 @@ void ParNewGeneration::collect(bool full,
size_policy->minor_collection_begin();
}
- TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
// Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used();
@@ -975,17 +1010,21 @@ void ParNewGeneration::collect(bool full,
rp->setup_policy(clear_all_soft_refs);
// Can the mt_degree be set later (at run_task() time would be best)?
rp->set_active_mt_degree(active_workers);
+ ReferenceProcessorStats stats;
if (rp->processing_is_mt()) {
ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
- rp->process_discovered_references(&is_alive, &keep_alive,
- &evacuate_followers, &task_executor);
+ stats = rp->process_discovered_references(&is_alive, &keep_alive,
+ &evacuate_followers, &task_executor,
+ _gc_timer);
} else {
thread_state_set.flush();
gch->set_par_threads(0); // 0 ==> non-parallel.
gch->save_marks();
- rp->process_discovered_references(&is_alive, &keep_alive,
- &evacuate_followers, NULL);
+ stats = rp->process_discovered_references(&is_alive, &keep_alive,
+ &evacuate_followers, NULL,
+ _gc_timer);
}
+ gc_tracer.report_gc_reference_stats(stats);
if (!promotion_failed()) {
// Swap the survivor spaces.
eden()->clear(SpaceDecorator::Mangle);
@@ -1010,22 +1049,7 @@ void ParNewGeneration::collect(bool full,
adjust_desired_tenuring_threshold();
} else {
- assert(_promo_failure_scan_stack.is_empty(), "post condition");
- _promo_failure_scan_stack.clear(true); // Clear cached segments.
-
- remove_forwarding_pointers();
- if (PrintGCDetails) {
- gclog_or_tty->print(" (promotion failed)");
- }
- // All the spaces are in play for mark-sweep.
- swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
- from()->set_next_compaction_space(to());
- gch->set_incremental_collection_failed();
- // Inform the next generation that a promotion failure occurred.
- _next_gen->promotion_failure_occurred();
-
- // Reset the PromotionFailureALot counters.
- NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
+ handle_promotion_failed(gch, thread_state_set, gc_tracer);
}
// set new iteration safe limit for the survivor spaces
from()->set_concurrent_iteration_safe_limit(from()->top());
@@ -1065,6 +1089,13 @@ void ParNewGeneration::collect(bool full,
rp->enqueue_discovered_references(NULL);
}
rp->verify_no_references_recorded();
+
+ gch->trace_heap_after_gc(&gc_tracer);
+ gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
+ _gc_timer->register_gc_end(os::elapsed_counter());
+
+ gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
}
static int sum;
@@ -1174,8 +1205,7 @@ oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
new_obj = old;
preserve_mark_if_necessary(old, m);
- // Log the size of the maiden promotion failure
- par_scan_state->log_promotion_failure(sz);
+ par_scan_state->register_promotion_failure(sz);
}
old->forward_to(new_obj);
@@ -1300,8 +1330,7 @@ oop ParNewGeneration::copy_to_survivor_space_with_undo(
failed_to_promote = true;
preserve_mark_if_necessary(old, m);
- // Log the size of the maiden promotion failure
- par_scan_state->log_promotion_failure(sz);
+ par_scan_state->register_promotion_failure(sz);
}
} else {
// Is in to-space; do copying ourselves.
@@ -1599,8 +1628,7 @@ bool ParNewGeneration::take_from_overflow_list_work(ParScanThreadState* par_scan
}
#undef BUSY
-void ParNewGeneration::ref_processor_init()
-{
+void ParNewGeneration::ref_processor_init() {
if (_ref_processor == NULL) {
// Allocate and initialize a reference processor
_ref_processor =
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
index 487552bfba9..987767b1640 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
@@ -25,7 +25,9 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
+#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/defNewGeneration.hpp"
#include "utilities/taskqueue.hpp"
@@ -105,7 +107,7 @@ class ParScanThreadState {
#endif // TASKQUEUE_STATS
// Stats for promotion failure
- size_t _promotion_failure_size;
+ PromotionFailedInfo _promotion_failed_info;
// Timing numbers.
double _start;
@@ -180,13 +182,16 @@ class ParScanThreadState {
void undo_alloc_in_to_space(HeapWord* obj, size_t word_sz);
// Promotion failure stats
- size_t promotion_failure_size() { return promotion_failure_size(); }
- void log_promotion_failure(size_t sz) {
- if (_promotion_failure_size == 0) {
- _promotion_failure_size = sz;
- }
+ void register_promotion_failure(size_t sz) {
+ _promotion_failed_info.register_copy_failure(sz);
}
- void print_and_clear_promotion_failure_size();
+ PromotionFailedInfo& promotion_failed_info() {
+ return _promotion_failed_info;
+ }
+ bool promotion_failed() {
+ return _promotion_failed_info.has_failed();
+ }
+ void print_promotion_failure_size();
#if TASKQUEUE_STATS
TaskQueueStats & taskqueue_stats() const { return _work_queue->stats; }
@@ -337,6 +342,8 @@ class ParNewGeneration: public DefNewGeneration {
// word being overwritten with a self-forwarding-pointer.
void preserve_mark_if_necessary(oop obj, markOop m);
+ void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer);
+
protected:
bool _survivor_overflow;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
index 9ea2fa856c3..d5b6c054005 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,8 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/vmPSOperations.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
@@ -642,6 +644,29 @@ void ParallelScavengeHeap::prepare_for_verify() {
ensure_parsability(false); // no need to retire TLABs for verification
}
+PSHeapSummary ParallelScavengeHeap::create_ps_heap_summary() {
+ PSOldGen* old = old_gen();
+ HeapWord* old_committed_end = (HeapWord*)old->virtual_space()->committed_high_addr();
+ VirtualSpaceSummary old_summary(old->reserved().start(), old_committed_end, old->reserved().end());
+ SpaceSummary old_space(old->reserved().start(), old_committed_end, old->used_in_bytes());
+
+ PSYoungGen* young = young_gen();
+ VirtualSpaceSummary young_summary(young->reserved().start(),
+ (HeapWord*)young->virtual_space()->committed_high_addr(), young->reserved().end());
+
+ MutableSpace* eden = young_gen()->eden_space();
+ SpaceSummary eden_space(eden->bottom(), eden->end(), eden->used_in_bytes());
+
+ MutableSpace* from = young_gen()->from_space();
+ SpaceSummary from_space(from->bottom(), from->end(), from->used_in_bytes());
+
+ MutableSpace* to = young_gen()->to_space();
+ SpaceSummary to_space(to->bottom(), to->end(), to->used_in_bytes());
+
+ VirtualSpaceSummary heap_summary = create_heap_space_summary();
+ return PSHeapSummary(heap_summary, used(), old_summary, old_space, young_summary, eden_space, from_space, to_space);
+}
+
void ParallelScavengeHeap::print_on(outputStream* st) const {
young_gen()->print_on(st);
old_gen()->print_on(st);
@@ -706,6 +731,12 @@ void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
}
}
+void ParallelScavengeHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
+ const PSHeapSummary& heap_summary = create_ps_heap_summary();
+ const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
+ gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+}
+
ParallelScavengeHeap* ParallelScavengeHeap::heap() {
assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap");
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
index 98e9c0435ab..11ef5325120 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,14 +30,18 @@
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
#include "gc_implementation/shared/gcPolicyCounters.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "utilities/ostream.hpp"
class AdjoiningGenerations;
+class CollectorPolicy;
+class GCHeapSummary;
class GCTaskManager;
-class PSAdaptiveSizePolicy;
class GenerationSizer;
class CollectorPolicy;
+class PSAdaptiveSizePolicy;
+class PSHeapSummary;
class ParallelScavengeHeap : public CollectedHeap {
friend class VMStructs;
@@ -65,6 +69,8 @@ class ParallelScavengeHeap : public CollectedHeap {
static GCTaskManager* _gc_task_manager; // The task manager.
+ void trace_heap(GCWhen::Type when, GCTracer* tracer);
+
protected:
static inline size_t total_invocations();
HeapWord* allocate_new_tlab(size_t size);
@@ -219,6 +225,7 @@ class ParallelScavengeHeap : public CollectedHeap {
jlong millis_since_last_gc();
void prepare_for_verify();
+ PSHeapSummary create_ps_heap_summary();
virtual void print_on(outputStream* st) const;
virtual void print_on_error(outputStream* st) const;
virtual void print_gc_threads_on(outputStream* st) const;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
index fa3cf7bccdc..14be13a2660 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
@@ -27,6 +27,8 @@
#include "code/codeCache.hpp"
#include "gc_implementation/parallelScavenge/pcTasks.hpp"
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/universe.hpp"
#include "oops/objArrayKlass.inline.hpp"
@@ -48,8 +50,8 @@ void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
ResourceMark rm;
- NOT_PRODUCT(TraceTime tm("ThreadRootsMarkingTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
@@ -77,8 +79,8 @@ void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
assert(Universe::heap()->is_gc_active(), "called outside gc");
- NOT_PRODUCT(TraceTime tm("MarkFromRootsTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
@@ -148,8 +150,8 @@ void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which)
{
assert(Universe::heap()->is_gc_active(), "called outside gc");
- NOT_PRODUCT(TraceTime tm("RefProcTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("RefProcTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
@@ -204,8 +206,8 @@ StealMarkingTask::StealMarkingTask(ParallelTaskTerminator* t) :
void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
assert(Universe::heap()->is_gc_active(), "called outside gc");
- NOT_PRODUCT(TraceTime tm("StealMarkingTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
@@ -237,8 +239,8 @@ StealRegionCompactionTask::StealRegionCompactionTask(ParallelTaskTerminator* t):
void StealRegionCompactionTask::do_it(GCTaskManager* manager, uint which) {
assert(Universe::heap()->is_gc_active(), "called outside gc");
- NOT_PRODUCT(TraceTime tm("StealRegionCompactionTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("StealRegionCompactionTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
@@ -304,8 +306,8 @@ UpdateDensePrefixTask::UpdateDensePrefixTask(
void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
- NOT_PRODUCT(TraceTime tm("UpdateDensePrefixTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("UpdateDensePrefixTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
@@ -319,8 +321,8 @@ void UpdateDensePrefixTask::do_it(GCTaskManager* manager, uint which) {
void DrainStacksCompactionTask::do_it(GCTaskManager* manager, uint which) {
assert(Universe::heap()->is_gc_active(), "called outside gc");
- NOT_PRODUCT(TraceTime tm("DrainStacksCompactionTask",
- PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
+ NOT_PRODUCT(GCTraceTime tm("DrainStacksCompactionTask",
+ PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
ParCompactionManager* cm =
ParCompactionManager::gc_thread_compaction_manager(which);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index 01b3a5b6d1e..dcdc21806af 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -34,6 +34,10 @@
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "gc_implementation/shared/markSweep.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
@@ -108,8 +112,12 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
}
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
- GCCause::Cause gc_cause = heap->gc_cause();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
+ GCCause::Cause gc_cause = heap->gc_cause();
+
+ _gc_timer->register_gc_start(os::elapsed_counter());
+ _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start());
+
PSAdaptiveSizePolicy* size_policy = heap->size_policy();
// The scope of casr should end after code that can change
@@ -131,6 +139,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
heap->print_heap_before_gc();
+ heap->trace_heap_before_gc(_gc_tracer);
// Fill in TLABs
heap->accumulate_statistics_all_tlabs();
@@ -147,7 +156,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
old_gen->verify_object_start_array();
}
- heap->pre_full_gc_dump();
+ heap->pre_full_gc_dump(_gc_timer);
// Filled in below to track the state of the young gen after the collection.
bool eden_empty;
@@ -159,7 +168,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
- TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
@@ -374,13 +383,18 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
heap->print_heap_after_gc();
+ heap->trace_heap_after_gc(_gc_tracer);
- heap->post_full_gc_dump();
+ heap->post_full_gc_dump(_gc_timer);
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
+ _gc_timer->register_gc_end(os::elapsed_counter());
+
+ _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
+
return true;
}
@@ -498,7 +512,7 @@ void PSMarkSweep::deallocate_stacks() {
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them
- TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer);
trace(" 1");
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -531,8 +545,10 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Process reference objects found during marking
{
ref_processor()->setup_policy(clear_all_softrefs);
- ref_processor()->process_discovered_references(
- is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
+ const ReferenceProcessorStats& stats =
+ ref_processor()->process_discovered_references(
+ is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer);
+ gc_tracer()->report_gc_reference_stats(stats);
}
// This is the point where the entire marking should have completed.
@@ -552,11 +568,12 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
+ _gc_tracer->report_object_count_after_gc(is_alive_closure());
}
void PSMarkSweep::mark_sweep_phase2() {
- TraceTime tm("phase 2", PrintGCDetails && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer);
trace("2");
// Now all live objects are marked, compute the new object addresses.
@@ -586,7 +603,7 @@ static PSAlwaysTrueClosure always_true;
void PSMarkSweep::mark_sweep_phase3() {
// Adjust the pointers to reflect the new locations
- TraceTime tm("phase 3", PrintGCDetails && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer);
trace("3");
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -629,7 +646,7 @@ void PSMarkSweep::mark_sweep_phase3() {
void PSMarkSweep::mark_sweep_phase4() {
EventMark m("4 compact heap");
- TraceTime tm("phase 4", PrintGCDetails && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer);
trace("4");
// All pointers are now adjusted, move objects accordingly
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index be437f3272f..27a42de95a6 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -39,6 +39,10 @@
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
#include "gc_implementation/parallelScavenge/psYoungGen.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "gc_interface/gcCause.hpp"
#include "memory/gcLocker.inline.hpp"
@@ -799,6 +803,8 @@ void ParallelCompactData::verify_clear()
}
#endif // #ifdef ASSERT
+STWGCTimer PSParallelCompact::_gc_timer;
+ParallelOldTracer PSParallelCompact::_gc_tracer;
elapsedTimer PSParallelCompact::_accumulated_time;
unsigned int PSParallelCompact::_total_invocations = 0;
unsigned int PSParallelCompact::_maximum_compaction_gc_num = 0;
@@ -972,7 +978,7 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
// at each young gen gc. Do the update unconditionally (even though a
// promotion failure does not swap spaces) because an unknown number of minor
// collections will have swapped the spaces an unknown number of times.
- TraceTime tm("pre compact", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("pre compact", print_phases(), true, &_gc_timer);
ParallelScavengeHeap* heap = gc_heap();
_space_info[from_space_id].set_space(heap->young_gen()->from_space());
_space_info[to_space_id].set_space(heap->young_gen()->to_space());
@@ -989,6 +995,7 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
_total_invocations++;
heap->print_heap_before_gc();
+ heap->trace_heap_before_gc(&_gc_tracer);
// Fill in TLABs
heap->accumulate_statistics_all_tlabs();
@@ -1014,7 +1021,7 @@ void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
void PSParallelCompact::post_compact()
{
- TraceTime tm("post compact", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("post compact", print_phases(), true, &_gc_timer);
for (unsigned int id = old_space_id; id < last_space_id; ++id) {
// Clear the marking bitmap, summary data and split info.
@@ -1840,7 +1847,7 @@ void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id,
void PSParallelCompact::summary_phase(ParCompactionManager* cm,
bool maximum_compaction)
{
- TraceTime tm("summary phase", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("summary phase", print_phases(), true, &_gc_timer);
// trace("2");
#ifdef ASSERT
@@ -1998,11 +2005,15 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
return false;
}
+ ParallelScavengeHeap* heap = gc_heap();
+
+ _gc_timer.register_gc_start(os::elapsed_counter());
+ _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
+
TimeStamp marking_start;
TimeStamp compaction_start;
TimeStamp collection_exit;
- ParallelScavengeHeap* heap = gc_heap();
GCCause::Cause gc_cause = heap->gc_cause();
PSYoungGen* young_gen = heap->young_gen();
PSOldGen* old_gen = heap->old_gen();
@@ -2018,7 +2029,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
heap->record_gen_tops_before_GC();
}
- heap->pre_full_gc_dump();
+ heap->pre_full_gc_dump(&_gc_timer);
_print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
@@ -2045,7 +2056,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
- TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
@@ -2065,7 +2076,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
bool marked_for_unloading = false;
marking_start.update();
- marking_phase(vmthread_cm, maximum_heap_compaction);
+ marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer);
bool max_on_system_gc = UseMaximumCompactionOnSystemGC
&& gc_cause == GCCause::_java_lang_system_gc;
@@ -2218,6 +2229,8 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
collection_exit.update();
heap->print_heap_after_gc();
+ heap->trace_heap_after_gc(&_gc_tracer);
+
if (PrintGCTaskTimeStamps) {
gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " "
INT64_FORMAT,
@@ -2226,12 +2239,17 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
gc_task_manager()->print_task_time_stamps();
}
- heap->post_full_gc_dump();
+ heap->post_full_gc_dump(&_gc_timer);
#ifdef TRACESPINNING
ParallelTaskTerminator::print_termination_counts();
#endif
+ _gc_timer.register_gc_end(os::elapsed_counter());
+
+ _gc_tracer.report_dense_prefix(dense_prefix(old_space_id));
+ _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
+
return true;
}
@@ -2330,9 +2348,10 @@ GCTaskManager* const PSParallelCompact::gc_task_manager() {
}
void PSParallelCompact::marking_phase(ParCompactionManager* cm,
- bool maximum_heap_compaction) {
+ bool maximum_heap_compaction,
+ ParallelOldTracer *gc_tracer) {
// Recursively traverse all live objects and mark them
- TraceTime tm("marking phase", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer);
ParallelScavengeHeap* heap = gc_heap();
uint parallel_gc_threads = heap->gc_task_manager()->workers();
@@ -2347,7 +2366,8 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
ClassLoaderDataGraph::clear_claimed_marks();
{
- TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm_m("par mark", print_phases(), true, &_gc_timer);
+
ParallelScavengeHeap::ParStrongRootsScope psrs;
GCTaskQueue* q = GCTaskQueue::create();
@@ -2375,19 +2395,24 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
// Process reference objects found during marking
{
- TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer);
+
+ ReferenceProcessorStats stats;
if (ref_processor()->processing_is_mt()) {
RefProcTaskExecutor task_executor;
- ref_processor()->process_discovered_references(
+ stats = ref_processor()->process_discovered_references(
is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
- &task_executor);
+ &task_executor, &_gc_timer);
} else {
- ref_processor()->process_discovered_references(
- is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL);
+ stats = ref_processor()->process_discovered_references(
+ is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL,
+ &_gc_timer);
}
+
+ gc_tracer->report_gc_reference_stats(stats);
}
- TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer);
// This is the point where the entire marking should have completed.
assert(cm->marking_stacks_empty(), "Marking should have completed");
@@ -2406,6 +2431,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
+ _gc_tracer.report_object_count_after_gc(is_alive_closure());
}
void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) {
@@ -2446,7 +2472,7 @@ static PSAlwaysTrueClosure always_true;
void PSParallelCompact::adjust_roots() {
// Adjust the pointers to reflect the new locations
- TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("adjust roots", print_phases(), true, &_gc_timer);
// Need new claim bits when tracing through and adjusting pointers.
ClassLoaderDataGraph::clear_claimed_marks();
@@ -2482,7 +2508,7 @@ void PSParallelCompact::adjust_roots() {
void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
uint parallel_gc_threads)
{
- TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("drain task setup", print_phases(), true, &_gc_timer);
// Find the threads that are active
unsigned int which = 0;
@@ -2556,7 +2582,7 @@ void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
uint parallel_gc_threads) {
- TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("dense prefix task setup", print_phases(), true, &_gc_timer);
ParallelCompactData& sd = PSParallelCompact::summary_data();
@@ -2638,7 +2664,7 @@ void PSParallelCompact::enqueue_region_stealing_tasks(
GCTaskQueue* q,
ParallelTaskTerminator* terminator_ptr,
uint parallel_gc_threads) {
- TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("steal task setup", print_phases(), true, &_gc_timer);
// Once a thread has drained it's stack, it should try to steal regions from
// other threads.
@@ -2686,7 +2712,7 @@ void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
void PSParallelCompact::compact() {
// trace("5");
- TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm("compaction phase", print_phases(), true, &_gc_timer);
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
@@ -2703,7 +2729,7 @@ void PSParallelCompact::compact() {
enqueue_region_stealing_tasks(q, &terminator, active_gc_threads);
{
- TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm_pc("par compact", print_phases(), true, &_gc_timer);
gc_task_manager()->execute_and_wait(q);
@@ -2717,7 +2743,7 @@ void PSParallelCompact::compact() {
{
// Update the deferred objects, if any. Any compaction manager can be used.
- TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty);
+ GCTraceTime tm_du("deferred updates", print_phases(), true, &_gc_timer);
ParCompactionManager* cm = ParCompactionManager::manager_array(0);
for (unsigned int id = old_space_id; id < last_space_id; ++id) {
update_deferred_objects(cm, SpaceId(id));
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
index c3a00c7e232..2ba4eb45f5c 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
@@ -46,6 +46,8 @@ class GCTaskQueue;
class PreGCValues;
class MoveAndUpdateClosure;
class RefProcTaskExecutor;
+class ParallelOldTracer;
+class STWGCTimer;
// The SplitInfo class holds the information needed to 'split' a source region
// so that the live data can be copied to two destination *spaces*. Normally,
@@ -972,6 +974,8 @@ class PSParallelCompact : AllStatic {
friend class RefProcTaskProxy;
private:
+ static STWGCTimer _gc_timer;
+ static ParallelOldTracer _gc_tracer;
static elapsedTimer _accumulated_time;
static unsigned int _total_invocations;
static unsigned int _maximum_compaction_gc_num;
@@ -1015,7 +1019,8 @@ class PSParallelCompact : AllStatic {
// Mark live objects
static void marking_phase(ParCompactionManager* cm,
- bool maximum_heap_compaction);
+ bool maximum_heap_compaction,
+ ParallelOldTracer *gc_tracer);
template
static inline void follow_root(ParCompactionManager* cm, T* p);
@@ -1284,6 +1289,8 @@ class PSParallelCompact : AllStatic {
// Reference Processing
static ReferenceProcessor* const ref_processor() { return _ref_processor; }
+ static STWGCTimer* gc_timer() { return &_gc_timer; }
+
// Return the SpaceId for the given address.
static SpaceId space_id(HeapWord* addr);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
index ee54e55bf78..32929e7a55c 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "gc_implementation/parallelScavenge/psOldGen.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/mutableSpace.hpp"
#include "memory/memRegion.hpp"
#include "oops/oop.inline.hpp"
@@ -49,7 +50,7 @@ void PSPromotionManager::initialize() {
guarantee(_manager_array != NULL, "Could not initialize promotion manager");
_stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
- guarantee(_stack_array_depth != NULL, "Cound not initialize promotion manager");
+ guarantee(_stack_array_depth != NULL, "Could not initialize promotion manager");
// Create and register the PSPromotionManager(s) for the worker threads.
for(uint i=0; iclaimed_stack_depth()->is_empty(), "should be empty");
+ if (manager->_promotion_failed_info.has_failed()) {
+ gc_tracer.report_promotion_failed(manager->_promotion_failed_info);
+ promotion_failure_occurred = true;
+ }
manager->flush_labs();
}
+ return promotion_failure_occurred;
}
#if TASKQUEUE_STATS
@@ -187,6 +195,8 @@ void PSPromotionManager::reset() {
_old_lab.initialize(MemRegion(lab_base, (size_t)0));
_old_gen_is_full = false;
+ _promotion_failed_info.reset();
+
TASKQUEUE_STATS_ONLY(reset_stats());
}
@@ -305,6 +315,8 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
// We won any races, we "own" this object.
assert(obj == obj->forwardee(), "Sanity");
+ _promotion_failed_info.register_copy_failure(obj->size());
+
obj->push_contents(this);
// Save the mark if needed
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
index 0e429edc660..8f4731428ac 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP
#include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/allocation.hpp"
#include "utilities/taskqueue.hpp"
@@ -33,7 +35,7 @@
// psPromotionManager is used by a single thread to manage object survival
// during a scavenge. The promotion manager contains thread local data only.
//
-// NOTE! Be carefull when allocating the stacks on cheap. If you are going
+// NOTE! Be careful when allocating the stacks on cheap. If you are going
// to use a promotion manager in more than one thread, the stacks MUST be
// on cheap. This can lead to memory leaks, though, as they are not auto
// deallocated.
@@ -85,6 +87,8 @@ class PSPromotionManager : public CHeapObj {
uint _array_chunk_size;
uint _min_array_size_for_chunking;
+ PromotionFailedInfo _promotion_failed_info;
+
// Accessors
static PSOldGen* old_gen() { return _old_gen; }
static MutableSpace* young_space() { return _young_space; }
@@ -149,7 +153,7 @@ class PSPromotionManager : public CHeapObj {
static void initialize();
static void pre_scavenge();
- static void post_scavenge();
+ static bool post_scavenge(YoungGCTracer& gc_tracer);
static PSPromotionManager* gc_thread_promotion_manager(int index);
static PSPromotionManager* vm_thread_promotion_manager();
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
index 96cd4cec706..841ef64f20b 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,7 @@ oop PSPromotionManager::copy_to_survivor_space(oop o) {
// This is the promotion failed test, and code handling.
// The code belongs here for two reasons. It is slightly
- // different thatn the code below, and cannot share the
+ // different than the code below, and cannot share the
// CAS testing code. Keeping the code here also minimizes
// the impact on the common case fast path code.
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 96a679a6654..60c0267bbe3 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -34,6 +34,10 @@
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "gc_implementation/parallelScavenge/psTasks.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/isGCActiveMark.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "gc_interface/gcCause.hpp"
@@ -63,10 +67,11 @@ uint PSScavenge::_tenuring_threshold = 0;
HeapWord* PSScavenge::_young_generation_boundary = NULL;
uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
elapsedTimer PSScavenge::_accumulated_time;
+STWGCTimer PSScavenge::_gc_timer;
+ParallelScavengeTracer PSScavenge::_gc_tracer;
Stack PSScavenge::_preserved_mark_stack;
Stack PSScavenge::_preserved_oop_stack;
CollectorCounters* PSScavenge::_counters = NULL;
-bool PSScavenge::_promotion_failed = false;
// Define before use
class PSIsAliveClosure: public BoolObjectClosure {
@@ -259,6 +264,8 @@ bool PSScavenge::invoke_no_policy() {
assert(_preserved_mark_stack.is_empty(), "should be empty");
assert(_preserved_oop_stack.is_empty(), "should be empty");
+ _gc_timer.register_gc_start(os::elapsed_counter());
+
TimeStamp scavenge_entry;
TimeStamp scavenge_midpoint;
TimeStamp scavenge_exit;
@@ -278,11 +285,14 @@ bool PSScavenge::invoke_no_policy() {
return false;
}
+ _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());
+
bool promotion_failure_occurred = false;
PSYoungGen* young_gen = heap->young_gen();
PSOldGen* old_gen = heap->old_gen();
PSAdaptiveSizePolicy* size_policy = heap->size_policy();
+
heap->increment_total_collections();
AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
@@ -299,12 +309,12 @@ bool PSScavenge::invoke_no_policy() {
}
heap->print_heap_before_gc();
+ heap->trace_heap_before_gc(&_gc_tracer);
assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity");
assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity");
size_t prev_used = heap->used();
- assert(promotion_failed() == false, "Sanity");
// Fill in TLABs
heap->accumulate_statistics_all_tlabs();
@@ -321,7 +331,7 @@ bool PSScavenge::invoke_no_policy() {
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
- TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL);
TraceCollectorStats tcs(counters());
TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
@@ -387,7 +397,7 @@ bool PSScavenge::invoke_no_policy() {
// We'll use the promotion manager again later.
PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager();
{
- // TraceTime("Roots");
+ GCTraceTime tm("Scavenge", false, false, &_gc_timer);
ParallelScavengeHeap::ParStrongRootsScope psrs;
GCTaskQueue* q = GCTaskQueue::create();
@@ -429,36 +439,41 @@ bool PSScavenge::invoke_no_policy() {
// Process reference objects discovered during scavenge
{
+ GCTraceTime tm("References", false, false, &_gc_timer);
+
reference_processor()->setup_policy(false); // not always_clear
reference_processor()->set_active_mt_degree(active_workers);
PSKeepAliveClosure keep_alive(promotion_manager);
PSEvacuateFollowersClosure evac_followers(promotion_manager);
+ ReferenceProcessorStats stats;
if (reference_processor()->processing_is_mt()) {
PSRefProcTaskExecutor task_executor;
- reference_processor()->process_discovered_references(
- &_is_alive_closure, &keep_alive, &evac_followers, &task_executor);
+ stats = reference_processor()->process_discovered_references(
+ &_is_alive_closure, &keep_alive, &evac_followers, &task_executor,
+ &_gc_timer);
} else {
- reference_processor()->process_discovered_references(
- &_is_alive_closure, &keep_alive, &evac_followers, NULL);
+ stats = reference_processor()->process_discovered_references(
+ &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer);
+ }
+
+ _gc_tracer.report_gc_reference_stats(stats);
+
+ // Enqueue reference objects discovered during scavenge.
+ if (reference_processor()->processing_is_mt()) {
+ PSRefProcTaskExecutor task_executor;
+ reference_processor()->enqueue_discovered_references(&task_executor);
+ } else {
+ reference_processor()->enqueue_discovered_references(NULL);
}
}
- // Enqueue reference objects discovered during scavenge.
- if (reference_processor()->processing_is_mt()) {
- PSRefProcTaskExecutor task_executor;
- reference_processor()->enqueue_discovered_references(&task_executor);
- } else {
- reference_processor()->enqueue_discovered_references(NULL);
- }
-
+ GCTraceTime tm("StringTable", false, false, &_gc_timer);
// Unlink any dead interned Strings and process the remaining live ones.
PSScavengeRootsClosure root_closure(promotion_manager);
StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
- PSPromotionManager::post_scavenge();
-
- promotion_failure_occurred = promotion_failed();
+ promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer);
if (promotion_failure_occurred) {
clean_up_failed_promotion();
if (PrintGC) {
@@ -473,8 +488,6 @@ bool PSScavenge::invoke_no_policy() {
if (!promotion_failure_occurred) {
// Swap the survivor spaces.
-
-
young_gen->eden_space()->clear(SpaceDecorator::Mangle);
young_gen->from_space()->clear(SpaceDecorator::Mangle);
young_gen->swap_spaces();
@@ -612,7 +625,11 @@ bool PSScavenge::invoke_no_policy() {
NOT_PRODUCT(reference_processor()->verify_no_references_recorded());
- CodeCache::prune_scavenge_root_nmethods();
+ {
+ GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer);
+
+ CodeCache::prune_scavenge_root_nmethods();
+ }
// Re-verify object start arrays
if (VerifyObjectStartArray &&
@@ -652,6 +669,8 @@ bool PSScavenge::invoke_no_policy() {
}
heap->print_heap_after_gc();
+ heap->trace_heap_after_gc(&_gc_tracer);
+ _gc_tracer.report_tenuring_threshold(tenuring_threshold());
if (ZapUnusedHeapArea) {
young_gen->eden_space()->check_mangled_unused_area_complete();
@@ -672,6 +691,11 @@ bool PSScavenge::invoke_no_policy() {
ParallelTaskTerminator::print_termination_counts();
#endif
+
+ _gc_timer.register_gc_end(os::elapsed_counter());
+
+ _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());
+
return !promotion_failure_occurred;
}
@@ -681,7 +705,6 @@ bool PSScavenge::invoke_no_policy() {
void PSScavenge::clean_up_failed_promotion() {
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
- assert(promotion_failed(), "Sanity");
PSYoungGen* young_gen = heap->young_gen();
@@ -706,7 +729,6 @@ void PSScavenge::clean_up_failed_promotion() {
// Clear the preserved mark and oop stack caches.
_preserved_mark_stack.clear(true);
_preserved_oop_stack.clear(true);
- _promotion_failed = false;
}
// Reset the PromotionFailureALot counters.
@@ -717,11 +739,10 @@ void PSScavenge::clean_up_failed_promotion() {
// fails. Some markOops will need preservation, some will not. Note
// that the entire eden is traversed after a failed promotion, with
// all forwarded headers replaced by the default markOop. This means
-// it is not neccessary to preserve most markOops.
+// it is not necessary to preserve most markOops.
void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
- _promotion_failed = true;
if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
- // Should use per-worker private stakcs hetre rather than
+ // Should use per-worker private stacks here rather than
// locking a common pair of stacks.
ThreadCritical tc;
_preserved_oop_stack.push(obj);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
index 7523f5bf603..896b705c204 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
#include "gc_implementation/parallelScavenge/psVirtualspace.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "utilities/stack.hpp"
@@ -37,8 +38,10 @@ class GCTaskQueue;
class OopStack;
class ReferenceProcessor;
class ParallelScavengeHeap;
+class ParallelScavengeTracer;
class PSIsAliveClosure;
class PSRefProcTaskExecutor;
+class STWGCTimer;
class PSScavenge: AllStatic {
friend class PSIsAliveClosure;
@@ -68,6 +71,8 @@ class PSScavenge: AllStatic {
static bool _survivor_overflow; // Overflow this collection
static uint _tenuring_threshold; // tenuring threshold for next scavenge
static elapsedTimer _accumulated_time; // total time spent on scavenge
+ static STWGCTimer _gc_timer; // GC time book keeper
+ static ParallelScavengeTracer _gc_tracer; // GC tracing
// The lowest address possible for the young_gen.
// This is used to decide if an oop should be scavenged,
// cards should be marked, etc.
@@ -77,7 +82,6 @@ class PSScavenge: AllStatic {
static Stack _preserved_mark_stack; // List of marks to be restored after failed promotion
static Stack _preserved_oop_stack; // List of oops that need their mark restored.
static CollectorCounters* _counters; // collector performance counters
- static bool _promotion_failed;
static void clean_up_failed_promotion();
@@ -93,7 +97,6 @@ class PSScavenge: AllStatic {
// Accessors
static uint tenuring_threshold() { return _tenuring_threshold; }
static elapsedTimer* accumulated_time() { return &_accumulated_time; }
- static bool promotion_failed() { return _promotion_failed; }
static int consecutive_skipped_scavenges()
{ return _consecutive_skipped_scavenges; }
diff --git a/hotspot/src/share/vm/gc_implementation/shared/copyFailedInfo.hpp b/hotspot/src/share/vm/gc_implementation/shared/copyFailedInfo.hpp
new file mode 100644
index 00000000000..2f30f5e8f16
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/copyFailedInfo.hpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP
+
+#include "runtime/thread.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class CopyFailedInfo : public CHeapObj {
+ size_t _first_size;
+ size_t _smallest_size;
+ size_t _total_size;
+ uint _count;
+
+ public:
+ CopyFailedInfo() : _first_size(0), _smallest_size(0), _total_size(0), _count(0) {}
+
+ virtual void register_copy_failure(size_t size) {
+ if (_first_size == 0) {
+ _first_size = size;
+ _smallest_size = size;
+ } else if (size < _smallest_size) {
+ _smallest_size = size;
+ }
+ _total_size += size;
+ _count++;
+ }
+
+ virtual void reset() {
+ _first_size = 0;
+ _smallest_size = 0;
+ _total_size = 0;
+ _count = 0;
+ }
+
+ bool has_failed() const { return _count != 0; }
+ size_t first_size() const { return _first_size; }
+ size_t smallest_size() const { return _smallest_size; }
+ size_t total_size() const { return _total_size; }
+ uint failed_count() const { return _count; }
+};
+
+class PromotionFailedInfo : public CopyFailedInfo {
+ OSThread* _thread;
+
+ public:
+ PromotionFailedInfo() : CopyFailedInfo(), _thread(NULL) {}
+
+ void register_copy_failure(size_t size) {
+ CopyFailedInfo::register_copy_failure(size);
+ if (_thread == NULL) {
+ _thread = Thread::current()->osthread();
+ } else {
+ assert(_thread == Thread::current()->osthread(), "The PromotionFailedInfo should be thread local.");
+ }
+ }
+
+ void reset() {
+ CopyFailedInfo::reset();
+ _thread = NULL;
+ }
+
+ OSThread* thread() const { return _thread; }
+};
+
+class EvacuationFailedInfo : public CopyFailedInfo {};
+
+#endif /* SHARE_VM_GC_IMPLEMENTATION_SHARED_COPYFAILEDINFO_HPP */
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp
new file mode 100644
index 00000000000..4e79b8f93d5
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
+
+#include "memory/allocation.hpp"
+
+class VirtualSpaceSummary : public StackObj {
+ HeapWord* _start;
+ HeapWord* _committed_end;
+ HeapWord* _reserved_end;
+public:
+ VirtualSpaceSummary() :
+ _start(NULL), _committed_end(NULL), _reserved_end(NULL) { }
+ VirtualSpaceSummary(HeapWord* start, HeapWord* committed_end, HeapWord* reserved_end) :
+ _start(start), _committed_end(committed_end), _reserved_end(reserved_end) { }
+
+ HeapWord* start() const { return _start; }
+ HeapWord* committed_end() const { return _committed_end; }
+ HeapWord* reserved_end() const { return _reserved_end; }
+ size_t committed_size() const { return (uintptr_t)_committed_end - (uintptr_t)_start; }
+ size_t reserved_size() const { return (uintptr_t)_reserved_end - (uintptr_t)_start; }
+};
+
+class SpaceSummary : public StackObj {
+ HeapWord* _start;
+ HeapWord* _end;
+ size_t _used;
+public:
+ SpaceSummary() :
+ _start(NULL), _end(NULL), _used(0) { }
+ SpaceSummary(HeapWord* start, HeapWord* end, size_t used) :
+ _start(start), _end(end), _used(used) { }
+
+ HeapWord* start() const { return _start; }
+ HeapWord* end() const { return _end; }
+ size_t used() const { return _used; }
+ size_t size() const { return (uintptr_t)_end - (uintptr_t)_start; }
+};
+
+class MetaspaceSizes : public StackObj {
+ size_t _capacity;
+ size_t _used;
+ size_t _reserved;
+
+ public:
+ MetaspaceSizes() : _capacity(0), _used(0), _reserved(0) {}
+ MetaspaceSizes(size_t capacity, size_t used, size_t reserved) :
+ _capacity(capacity), _used(used), _reserved(reserved) {}
+
+ size_t capacity() const { return _capacity; }
+ size_t used() const { return _used; }
+ size_t reserved() const { return _reserved; }
+};
+
+class GCHeapSummary;
+class PSHeapSummary;
+
+class GCHeapSummaryVisitor {
+ public:
+ virtual void visit(const GCHeapSummary* heap_summary) const = 0;
+ virtual void visit(const PSHeapSummary* heap_summary) const {}
+};
+
+class GCHeapSummary : public StackObj {
+ VirtualSpaceSummary _heap;
+ size_t _used;
+
+ public:
+ GCHeapSummary() :
+ _heap(), _used(0) { }
+ GCHeapSummary(VirtualSpaceSummary& heap_space, size_t used) :
+ _heap(heap_space), _used(used) { }
+
+ const VirtualSpaceSummary& heap() const { return _heap; }
+ size_t used() const { return _used; }
+
+ virtual void accept(GCHeapSummaryVisitor* visitor) const {
+ visitor->visit(this);
+ }
+};
+
+class PSHeapSummary : public GCHeapSummary {
+ VirtualSpaceSummary _old;
+ SpaceSummary _old_space;
+ VirtualSpaceSummary _young;
+ SpaceSummary _eden;
+ SpaceSummary _from;
+ SpaceSummary _to;
+ public:
+ PSHeapSummary(VirtualSpaceSummary& heap_space, size_t heap_used, VirtualSpaceSummary old, SpaceSummary old_space, VirtualSpaceSummary young, SpaceSummary eden, SpaceSummary from, SpaceSummary to) :
+ GCHeapSummary(heap_space, heap_used), _old(old), _old_space(old_space), _young(young), _eden(eden), _from(from), _to(to) { }
+ const VirtualSpaceSummary& old() const { return _old; }
+ const SpaceSummary& old_space() const { return _old_space; }
+ const VirtualSpaceSummary& young() const { return _young; }
+ const SpaceSummary& eden() const { return _eden; }
+ const SpaceSummary& from() const { return _from; }
+ const SpaceSummary& to() const { return _to; }
+
+ virtual void accept(GCHeapSummaryVisitor* visitor) const {
+ visitor->visit(this);
+ }
+};
+
+class MetaspaceSummary : public StackObj {
+ MetaspaceSizes _meta_space;
+ MetaspaceSizes _data_space;
+ MetaspaceSizes _class_space;
+
+ public:
+ MetaspaceSummary() : _meta_space(), _data_space(), _class_space() {}
+ MetaspaceSummary(const MetaspaceSizes& meta_space, const MetaspaceSizes& data_space, const MetaspaceSizes& class_space) :
+ _meta_space(meta_space), _data_space(data_space), _class_space(class_space) { }
+
+ const MetaspaceSizes& meta_space() const { return _meta_space; }
+ const MetaspaceSizes& data_space() const { return _data_space; }
+ const MetaspaceSizes& class_space() const { return _class_space; }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCHEAPSUMMARY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTimer.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTimer.cpp
new file mode 100644
index 00000000000..6d011700c88
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTimer.cpp
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "utilities/growableArray.hpp"
+
+void GCTimer::register_gc_start(jlong time) {
+ _time_partitions.clear();
+ _gc_start = time;
+}
+
+void GCTimer::register_gc_end(jlong time) {
+ assert(!_time_partitions.has_active_phases(),
+ "We should have ended all started phases, before ending the GC");
+
+ _gc_end = time;
+}
+
+void GCTimer::register_gc_pause_start(const char* name, jlong time) {
+ _time_partitions.report_gc_phase_start(name, time);
+}
+
+void GCTimer::register_gc_pause_end(jlong time) {
+ _time_partitions.report_gc_phase_end(time);
+}
+
+void GCTimer::register_gc_phase_start(const char* name, jlong time) {
+ _time_partitions.report_gc_phase_start(name, time);
+}
+
+void GCTimer::register_gc_phase_end(jlong time) {
+ _time_partitions.report_gc_phase_end(time);
+}
+
+
+void STWGCTimer::register_gc_start(jlong time) {
+ GCTimer::register_gc_start(time);
+ register_gc_pause_start("GC Pause", time);
+}
+
+void STWGCTimer::register_gc_end(jlong time) {
+ register_gc_pause_end(time);
+ GCTimer::register_gc_end(time);
+}
+
+void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) {
+ GCTimer::register_gc_pause_start(name, time);
+}
+
+void ConcurrentGCTimer::register_gc_pause_end(jlong time) {
+ GCTimer::register_gc_pause_end(time);
+}
+
+void PhasesStack::clear() {
+ _next_phase_level = 0;
+}
+
+void PhasesStack::push(int phase_index) {
+ assert(_next_phase_level < PHASE_LEVELS, "Overflow");
+
+ _phase_indices[_next_phase_level] = phase_index;
+
+ _next_phase_level++;
+}
+
+int PhasesStack::pop() {
+ assert(_next_phase_level > 0, "Underflow");
+
+ _next_phase_level--;
+
+ return _phase_indices[_next_phase_level];
+}
+
+int PhasesStack::count() const {
+ return _next_phase_level;
+}
+
+
+TimePartitions::TimePartitions() {
+ _phases = new (ResourceObj::C_HEAP, mtGC) GrowableArray(INITIAL_CAPACITY, true, mtGC);
+ clear();
+}
+
+TimePartitions::~TimePartitions() {
+ delete _phases;
+ _phases = NULL;
+}
+
+void TimePartitions::clear() {
+ _phases->clear();
+ _active_phases.clear();
+ _sum_of_pauses = 0;
+ _longest_pause = 0;
+}
+
+void TimePartitions::report_gc_phase_start(const char* name, jlong time) {
+ assert(_phases->length() <= 1000, "Too many recored phases?");
+
+ int level = _active_phases.count();
+
+ PausePhase phase;
+ phase.set_level(level);
+ phase.set_name(name);
+ phase.set_start(time);
+
+ int index = _phases->append(phase);
+
+ _active_phases.push(index);
+}
+
+void TimePartitions::update_statistics(GCPhase* phase) {
+ // FIXME: This should only be done for pause phases
+ if (phase->level() == 0) {
+ jlong pause = phase->end() - phase->start();
+ _sum_of_pauses += pause;
+ _longest_pause = MAX2(pause, _longest_pause);
+ }
+}
+
+void TimePartitions::report_gc_phase_end(jlong time) {
+ int phase_index = _active_phases.pop();
+ GCPhase* phase = _phases->adr_at(phase_index);
+ phase->set_end(time);
+ update_statistics(phase);
+}
+
+int TimePartitions::num_phases() const {
+ return _phases->length();
+}
+
+GCPhase* TimePartitions::phase_at(int index) const {
+ assert(index >= 0, "Out of bounds");
+ assert(index < _phases->length(), "Out of bounds");
+
+ return _phases->adr_at(index);
+}
+
+jlong TimePartitions::sum_of_pauses() {
+ return _sum_of_pauses;
+}
+
+jlong TimePartitions::longest_pause() {
+ return _longest_pause;
+}
+
+bool TimePartitions::has_active_phases() {
+ return _active_phases.count() > 0;
+}
+
+bool TimePartitionPhasesIterator::has_next() {
+ return _next < _time_partitions->num_phases();
+}
+
+GCPhase* TimePartitionPhasesIterator::next() {
+ assert(has_next(), "Must have phases left");
+ return _time_partitions->phase_at(_next++);
+}
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class TimePartitionPhasesIteratorTest {
+ public:
+ static void all() {
+ one_pause();
+ two_pauses();
+ one_sub_pause_phase();
+ many_sub_pause_phases();
+ many_sub_pause_phases2();
+ max_nested_pause_phases();
+ }
+
+ static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) {
+ assert(phase->level() == level, "Incorrect level");
+ assert(strcmp(phase->name(), name) == 0, "Incorrect name");
+ assert(phase->start() == start, "Incorrect start");
+ assert(phase->end() == end, "Incorrect end");
+ }
+
+ static void one_pause() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase", 2);
+ time_partitions.report_gc_phase_end(8);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8);
+ assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect");
+ assert(time_partitions.longest_pause() == 8-2, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+
+ static void two_pauses() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase1", 2);
+ time_partitions.report_gc_phase_end(3);
+ time_partitions.report_gc_phase_start("PausePhase2", 4);
+ time_partitions.report_gc_phase_end(6);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3);
+ validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6);
+
+ assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
+ assert(time_partitions.longest_pause() == 2, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+
+ static void one_sub_pause_phase() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase", 2);
+ time_partitions.report_gc_phase_start("SubPhase", 3);
+ time_partitions.report_gc_phase_end(4);
+ time_partitions.report_gc_phase_end(5);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5);
+ validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4);
+
+ assert(time_partitions.sum_of_pauses() == 3, "Incorrect");
+ assert(time_partitions.longest_pause() == 3, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+
+ static void max_nested_pause_phases() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase", 2);
+ time_partitions.report_gc_phase_start("SubPhase1", 3);
+ time_partitions.report_gc_phase_start("SubPhase2", 4);
+ time_partitions.report_gc_phase_start("SubPhase3", 5);
+ time_partitions.report_gc_phase_end(6);
+ time_partitions.report_gc_phase_end(7);
+ time_partitions.report_gc_phase_end(8);
+ time_partitions.report_gc_phase_end(9);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 9);
+ validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8);
+ validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7);
+ validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6);
+
+ assert(time_partitions.sum_of_pauses() == 7, "Incorrect");
+ assert(time_partitions.longest_pause() == 7, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+
+ static void many_sub_pause_phases() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase", 2);
+
+ time_partitions.report_gc_phase_start("SubPhase1", 3);
+ time_partitions.report_gc_phase_end(4);
+ time_partitions.report_gc_phase_start("SubPhase2", 5);
+ time_partitions.report_gc_phase_end(6);
+ time_partitions.report_gc_phase_start("SubPhase3", 7);
+ time_partitions.report_gc_phase_end(8);
+ time_partitions.report_gc_phase_start("SubPhase4", 9);
+ time_partitions.report_gc_phase_end(10);
+
+ time_partitions.report_gc_phase_end(11);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 11);
+ validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 4);
+ validate_pause_phase(iter.next(), 1, "SubPhase2", 5, 6);
+ validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8);
+ validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10);
+
+ assert(time_partitions.sum_of_pauses() == 9, "Incorrect");
+ assert(time_partitions.longest_pause() == 9, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+
+ static void many_sub_pause_phases2() {
+ TimePartitions time_partitions;
+ time_partitions.report_gc_phase_start("PausePhase", 2);
+
+ time_partitions.report_gc_phase_start("SubPhase1", 3);
+ time_partitions.report_gc_phase_start("SubPhase11", 4);
+ time_partitions.report_gc_phase_end(5);
+ time_partitions.report_gc_phase_start("SubPhase12", 6);
+ time_partitions.report_gc_phase_end(7);
+ time_partitions.report_gc_phase_end(8);
+ time_partitions.report_gc_phase_start("SubPhase2", 9);
+ time_partitions.report_gc_phase_start("SubPhase21", 10);
+ time_partitions.report_gc_phase_end(11);
+ time_partitions.report_gc_phase_start("SubPhase22", 12);
+ time_partitions.report_gc_phase_end(13);
+ time_partitions.report_gc_phase_end(14);
+ time_partitions.report_gc_phase_start("SubPhase3", 15);
+ time_partitions.report_gc_phase_end(16);
+
+ time_partitions.report_gc_phase_end(17);
+
+ TimePartitionPhasesIterator iter(&time_partitions);
+
+ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 17);
+ validate_pause_phase(iter.next(), 1, "SubPhase1", 3, 8);
+ validate_pause_phase(iter.next(), 2, "SubPhase11", 4, 5);
+ validate_pause_phase(iter.next(), 2, "SubPhase12", 6, 7);
+ validate_pause_phase(iter.next(), 1, "SubPhase2", 9, 14);
+ validate_pause_phase(iter.next(), 2, "SubPhase21", 10, 11);
+ validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13);
+ validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16);
+
+ assert(time_partitions.sum_of_pauses() == 15, "Incorrect");
+ assert(time_partitions.longest_pause() == 15, "Incorrect");
+
+ assert(!iter.has_next(), "Too many elements");
+ }
+};
+
+class GCTimerTest {
+public:
+ static void all() {
+ gc_start();
+ gc_end();
+ }
+
+ static void gc_start() {
+ GCTimer gc_timer;
+ gc_timer.register_gc_start(1);
+
+ assert(gc_timer.gc_start() == 1, "Incorrect");
+ }
+
+ static void gc_end() {
+ GCTimer gc_timer;
+ gc_timer.register_gc_start(1);
+ gc_timer.register_gc_end(2);
+
+ assert(gc_timer.gc_end() == 2, "Incorrect");
+ }
+};
+
+void GCTimerAllTest::all() {
+ GCTimerTest::all();
+ TimePartitionPhasesIteratorTest::all();
+}
+
+#endif
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTimer.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcTimer.hpp
new file mode 100644
index 00000000000..b29e7c5445a
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTimer.hpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
+
+#include "memory/allocation.hpp"
+#include "prims/jni_md.h"
+#include "utilities/macros.hpp"
+
+class ConcurrentPhase;
+class GCPhase;
+class PausePhase;
+
+template class GrowableArray;
+
+class PhaseVisitor {
+ public:
+ virtual void visit(GCPhase* phase) = 0;
+ virtual void visit(PausePhase* phase) { visit((GCPhase*)phase); }
+ virtual void visit(ConcurrentPhase* phase) { visit((GCPhase*)phase); }
+};
+
+class GCPhase {
+ const char* _name;
+ int _level;
+ jlong _start;
+ jlong _end;
+
+ public:
+ void set_name(const char* name) { _name = name; }
+ const char* name() { return _name; }
+
+ int level() { return _level; }
+ void set_level(int level) { _level = level; }
+
+ jlong start() { return _start; }
+ void set_start(jlong time) { _start = time; }
+
+ jlong end() { return _end; }
+ void set_end(jlong time) { _end = time; }
+
+ virtual void accept(PhaseVisitor* visitor) = 0;
+};
+
+class PausePhase : public GCPhase {
+ public:
+ void accept(PhaseVisitor* visitor) {
+ visitor->visit(this);
+ }
+};
+
+class ConcurrentPhase : public GCPhase {
+ void accept(PhaseVisitor* visitor) {
+ visitor->visit(this);
+ }
+};
+
+class PhasesStack {
+ public:
+ // FIXME: Temporary set to 5 (used to be 4), since Reference processing needs it.
+ static const int PHASE_LEVELS = 5;
+
+ private:
+ int _phase_indices[PHASE_LEVELS];
+ int _next_phase_level;
+
+ public:
+ PhasesStack() { clear(); }
+ void clear();
+
+ void push(int phase_index);
+ int pop();
+ int count() const;
+};
+
+class TimePartitions {
+ static const int INITIAL_CAPACITY = 10;
+
+ // Currently we only support pause phases.
+ GrowableArray* _phases;
+ PhasesStack _active_phases;
+
+ jlong _sum_of_pauses;
+ jlong _longest_pause;
+
+ public:
+ TimePartitions();
+ ~TimePartitions();
+ void clear();
+
+ void report_gc_phase_start(const char* name, jlong time);
+ void report_gc_phase_end(jlong time);
+
+ int num_phases() const;
+ GCPhase* phase_at(int index) const;
+
+ jlong sum_of_pauses();
+ jlong longest_pause();
+
+ bool has_active_phases();
+ private:
+ void update_statistics(GCPhase* phase);
+};
+
+class PhasesIterator {
+ public:
+ virtual bool has_next() = 0;
+ virtual GCPhase* next() = 0;
+};
+
+class GCTimer : public ResourceObj {
+ NOT_PRODUCT(friend class GCTimerTest;)
+ protected:
+ jlong _gc_start;
+ jlong _gc_end;
+ TimePartitions _time_partitions;
+
+ public:
+ virtual void register_gc_start(jlong time);
+ virtual void register_gc_end(jlong time);
+
+ void register_gc_phase_start(const char* name, jlong time);
+ void register_gc_phase_end(jlong time);
+
+ jlong gc_start() { return _gc_start; }
+ jlong gc_end() { return _gc_end; }
+
+ TimePartitions* time_partitions() { return &_time_partitions; }
+
+ long longest_pause();
+ long sum_of_pauses();
+
+ protected:
+ void register_gc_pause_start(const char* name, jlong time);
+ void register_gc_pause_end(jlong time);
+};
+
+class STWGCTimer : public GCTimer {
+ public:
+ virtual void register_gc_start(jlong time);
+ virtual void register_gc_end(jlong time);
+};
+
+class ConcurrentGCTimer : public GCTimer {
+ public:
+ void register_gc_pause_start(const char* name, jlong time);
+ void register_gc_pause_end(jlong time);
+};
+
+class TimePartitionPhasesIterator {
+ TimePartitions* _time_partitions;
+ int _next;
+
+ public:
+ TimePartitionPhasesIterator(TimePartitions* time_partitions) : _time_partitions(time_partitions), _next(0) { }
+
+ virtual bool has_next();
+ virtual GCPhase* next();
+};
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class GCTimerAllTest {
+ public:
+ static void all();
+};
+
+#endif
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTIMER_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp
new file mode 100644
index 00000000000..6c53670425b
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/heapInspection.hpp"
+#include "memory/referenceProcessorStats.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/evacuationInfo.hpp"
+#endif
+
+#define assert_unset_gc_id() assert(_shared_gc_info.id() == SharedGCInfo::UNSET_GCID, "GC already started?")
+#define assert_set_gc_id() assert(_shared_gc_info.id() != SharedGCInfo::UNSET_GCID, "GC not started?")
+
+static jlong GCTracer_next_gc_id = 0;
+static GCId create_new_gc_id() {
+ return GCTracer_next_gc_id++;
+}
+
+void GCTracer::report_gc_start_impl(GCCause::Cause cause, jlong timestamp) {
+ assert_unset_gc_id();
+
+ GCId gc_id = create_new_gc_id();
+ _shared_gc_info.set_id(gc_id);
+ _shared_gc_info.set_cause(cause);
+ _shared_gc_info.set_start_timestamp(timestamp);
+}
+
+void GCTracer::report_gc_start(GCCause::Cause cause, jlong timestamp) {
+ assert_unset_gc_id();
+
+ report_gc_start_impl(cause, timestamp);
+}
+
+bool GCTracer::has_reported_gc_start() const {
+ return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID;
+}
+
+void GCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+
+ _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses());
+ _shared_gc_info.set_longest_pause(time_partitions->longest_pause());
+ _shared_gc_info.set_end_timestamp(timestamp);
+
+ send_phase_events(time_partitions);
+ send_garbage_collection_event();
+}
+
+void GCTracer::report_gc_end(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+
+ report_gc_end_impl(timestamp, time_partitions);
+
+ _shared_gc_info.set_id(SharedGCInfo::UNSET_GCID);
+}
+
+void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const {
+ assert_set_gc_id();
+
+ send_reference_stats_event(REF_SOFT, rps.soft_count());
+ send_reference_stats_event(REF_WEAK, rps.weak_count());
+ send_reference_stats_event(REF_FINAL, rps.final_count());
+ send_reference_stats_event(REF_PHANTOM, rps.phantom_count());
+}
+
+#if INCLUDE_SERVICES
+void ObjectCountEventSenderClosure::do_cinfo(KlassInfoEntry* entry) {
+ if (should_send_event(entry)) {
+ send_event(entry);
+ }
+}
+
+void ObjectCountEventSenderClosure::send_event(KlassInfoEntry* entry) {
+ _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(),
+ entry->words() * BytesPerWord);
+}
+
+bool ObjectCountEventSenderClosure::should_send_event(KlassInfoEntry* entry) const {
+ double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
+ return percentage_of_heap > _size_threshold_percentage;
+}
+
+void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) {
+ assert_set_gc_id();
+
+ if (should_send_object_count_after_gc_event()) {
+ ResourceMark rm;
+
+ KlassInfoTable cit(false);
+ if (!cit.allocation_failed()) {
+ HeapInspection hi(false, false, false, NULL);
+ hi.populate_table(&cit, is_alive_cl);
+
+ ObjectCountEventSenderClosure event_sender(this, cit.size_of_instances_in_words());
+ cit.iterate(&event_sender);
+ }
+ }
+}
+#endif
+
+void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const {
+ assert_set_gc_id();
+
+ send_gc_heap_summary_event(when, heap_summary);
+ send_meta_space_summary_event(when, meta_space_summary);
+}
+
+void YoungGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+ assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported");
+
+ GCTracer::report_gc_end_impl(timestamp, time_partitions);
+ send_young_gc_event();
+
+ _tenuring_threshold = UNSET_TENURING_THRESHOLD;
+}
+
+void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) {
+ assert_set_gc_id();
+
+ send_promotion_failed_event(pf_info);
+}
+
+void YoungGCTracer::report_tenuring_threshold(const uint tenuring_threshold) {
+ _tenuring_threshold = tenuring_threshold;
+}
+
+void OldGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+
+ GCTracer::report_gc_end_impl(timestamp, time_partitions);
+ send_old_gc_event();
+}
+
+void ParallelOldTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+
+ OldGCTracer::report_gc_end_impl(timestamp, time_partitions);
+ send_parallel_old_event();
+}
+
+void ParallelOldTracer::report_dense_prefix(void* dense_prefix) {
+ assert_set_gc_id();
+
+ _parallel_old_gc_info.report_dense_prefix(dense_prefix);
+}
+
+void OldGCTracer::report_concurrent_mode_failure() {
+ assert_set_gc_id();
+
+ send_concurrent_mode_failure_event();
+}
+
+#if INCLUDE_ALL_GCS
+void G1NewTracer::report_yc_type(G1YCType type) {
+ assert_set_gc_id();
+
+ _g1_young_gc_info.set_type(type);
+}
+
+void G1NewTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) {
+ assert_set_gc_id();
+
+ YoungGCTracer::report_gc_end_impl(timestamp, time_partitions);
+ send_g1_young_gc_event();
+}
+
+void G1NewTracer::report_evacuation_info(EvacuationInfo* info) {
+ assert_set_gc_id();
+
+ send_evacuation_info_event(info);
+}
+
+void G1NewTracer::report_evacuation_failed(EvacuationFailedInfo& ef_info) {
+ assert_set_gc_id();
+
+ send_evacuation_failed_event(ef_info);
+ ef_info.reset();
+}
+#endif
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp
new file mode 100644
index 00000000000..29ee55b685d
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
+
+#include "gc_interface/gcCause.hpp"
+#include "gc_interface/gcName.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "memory/allocation.hpp"
+#include "memory/klassInfoClosure.hpp"
+#include "memory/referenceType.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/g1YCTypes.hpp"
+#endif
+#include "utilities/macros.hpp"
+
+typedef uint GCId;
+
+class EvacuationInfo;
+class GCHeapSummary;
+class MetaspaceSummary;
+class PSHeapSummary;
+class ReferenceProcessorStats;
+class TimePartitions;
+class BoolObjectClosure;
+
+class SharedGCInfo VALUE_OBJ_CLASS_SPEC {
+ static const jlong UNSET_TIMESTAMP = -1;
+
+ public:
+ static const GCId UNSET_GCID = (GCId)-1;
+
+ private:
+ GCId _id;
+ GCName _name;
+ GCCause::Cause _cause;
+ jlong _start_timestamp;
+ jlong _end_timestamp;
+ jlong _sum_of_pauses;
+ jlong _longest_pause;
+
+ public:
+ SharedGCInfo(GCName name) : _id(UNSET_GCID), _name(name), _cause(GCCause::_last_gc_cause),
+ _start_timestamp(UNSET_TIMESTAMP), _end_timestamp(UNSET_TIMESTAMP), _sum_of_pauses(0), _longest_pause(0) {}
+
+ void set_id(GCId id) { _id = id; }
+ GCId id() const { return _id; }
+
+ void set_start_timestamp(jlong timestamp) { _start_timestamp = timestamp; }
+ jlong start_timestamp() const { return _start_timestamp; }
+
+ void set_end_timestamp(jlong timestamp) { _end_timestamp = timestamp; }
+ jlong end_timestamp() const { return _end_timestamp; }
+
+ void set_name(GCName name) { _name = name; }
+ GCName name() const { return _name; }
+
+ void set_cause(GCCause::Cause cause) { _cause = cause; }
+ GCCause::Cause cause() const { return _cause; }
+
+ void set_sum_of_pauses(jlong duration) { _sum_of_pauses = duration; }
+ jlong sum_of_pauses() const { return _sum_of_pauses; }
+
+ void set_longest_pause(jlong duration) { _longest_pause = duration; }
+ jlong longest_pause() const { return _longest_pause; }
+};
+
+class ParallelOldGCInfo VALUE_OBJ_CLASS_SPEC {
+ void* _dense_prefix;
+ public:
+ ParallelOldGCInfo() : _dense_prefix(NULL) {}
+ void report_dense_prefix(void* addr) {
+ _dense_prefix = addr;
+ }
+ void* dense_prefix() const { return _dense_prefix; }
+};
+
+#if INCLUDE_ALL_GCS
+
+class G1YoungGCInfo VALUE_OBJ_CLASS_SPEC {
+ G1YCType _type;
+ public:
+ G1YoungGCInfo() : _type(G1YCTypeEndSentinel) {}
+ void set_type(G1YCType type) {
+ _type = type;
+ }
+ G1YCType type() const { return _type; }
+};
+
+#endif // INCLUDE_ALL_GCS
+
+class GCTracer : public ResourceObj {
+ friend class ObjectCountEventSenderClosure;
+ protected:
+ SharedGCInfo _shared_gc_info;
+
+ public:
+ void report_gc_start(GCCause::Cause cause, jlong timestamp);
+ void report_gc_end(jlong timestamp, TimePartitions* time_partitions);
+ void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const;
+ void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;
+ void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN;
+
+ bool has_reported_gc_start() const;
+
+ protected:
+ GCTracer(GCName name) : _shared_gc_info(name) {}
+ virtual void report_gc_start_impl(GCCause::Cause cause, jlong timestamp);
+ virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ private:
+ void send_garbage_collection_event() const;
+ void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const;
+ void send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const;
+ void send_reference_stats_event(ReferenceType type, size_t count) const;
+ void send_phase_events(TimePartitions* time_partitions) const;
+ void send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const NOT_SERVICES_RETURN;
+ bool should_send_object_count_after_gc_event() const;
+};
+
+class ObjectCountEventSenderClosure : public KlassInfoClosure {
+ GCTracer* _gc_tracer;
+ const double _size_threshold_percentage;
+ const size_t _total_size_in_words;
+ public:
+ ObjectCountEventSenderClosure(GCTracer* gc_tracer, size_t total_size_in_words) :
+ _gc_tracer(gc_tracer),
+ _size_threshold_percentage(ObjectCountCutOffPercent / 100),
+ _total_size_in_words(total_size_in_words)
+ {}
+ virtual void do_cinfo(KlassInfoEntry* entry);
+ protected:
+ virtual void send_event(KlassInfoEntry* entry);
+ private:
+ bool should_send_event(KlassInfoEntry* entry) const;
+};
+
+class YoungGCTracer : public GCTracer {
+ static const uint UNSET_TENURING_THRESHOLD = (uint) -1;
+
+ uint _tenuring_threshold;
+
+ protected:
+ YoungGCTracer(GCName name) : GCTracer(name), _tenuring_threshold(UNSET_TENURING_THRESHOLD) {}
+ virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ public:
+ void report_promotion_failed(const PromotionFailedInfo& pf_info);
+ void report_tenuring_threshold(const uint tenuring_threshold);
+
+ private:
+ void send_young_gc_event() const;
+ void send_promotion_failed_event(const PromotionFailedInfo& pf_info) const;
+};
+
+class OldGCTracer : public GCTracer {
+ protected:
+ OldGCTracer(GCName name) : GCTracer(name) {}
+ virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ public:
+ void report_concurrent_mode_failure();
+
+ private:
+ void send_old_gc_event() const;
+ void send_concurrent_mode_failure_event();
+};
+
+class ParallelOldTracer : public OldGCTracer {
+ ParallelOldGCInfo _parallel_old_gc_info;
+
+ public:
+ ParallelOldTracer() : OldGCTracer(ParallelOld) {}
+ void report_dense_prefix(void* dense_prefix);
+
+ protected:
+ void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+
+ private:
+ void send_parallel_old_event() const;
+};
+
+class SerialOldTracer : public OldGCTracer {
+ public:
+ SerialOldTracer() : OldGCTracer(SerialOld) {}
+};
+
+class ParallelScavengeTracer : public YoungGCTracer {
+ public:
+ ParallelScavengeTracer() : YoungGCTracer(ParallelScavenge) {}
+};
+
+class DefNewTracer : public YoungGCTracer {
+ public:
+ DefNewTracer() : YoungGCTracer(DefNew) {}
+};
+
+class ParNewTracer : public YoungGCTracer {
+ public:
+ ParNewTracer() : YoungGCTracer(ParNew) {}
+};
+
+#if INCLUDE_ALL_GCS
+class G1NewTracer : public YoungGCTracer {
+ G1YoungGCInfo _g1_young_gc_info;
+
+ public:
+ G1NewTracer() : YoungGCTracer(G1New) {}
+
+ void report_yc_type(G1YCType type);
+ void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions);
+ void report_evacuation_info(EvacuationInfo* info);
+ void report_evacuation_failed(EvacuationFailedInfo& ef_info);
+
+ private:
+ void send_g1_young_gc_event();
+ void send_evacuation_info_event(EvacuationInfo* info);
+ void send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const;
+};
+#endif
+
+class CMSTracer : public OldGCTracer {
+ public:
+ CMSTracer() : OldGCTracer(ConcurrentMarkSweep) {}
+};
+
+class G1OldTracer : public OldGCTracer {
+ public:
+ G1OldTracer() : OldGCTracer(G1Old) {}
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACE_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp
new file mode 100644
index 00000000000..4af7e3c2fbf
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceBackend.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/evacuationInfo.hpp"
+#include "gc_implementation/g1/g1YCTypes.hpp"
+#endif
+
+// All GC dependencies against the trace framework is contained within this file.
+
+typedef uintptr_t TraceAddress;
+
+void GCTracer::send_garbage_collection_event() const {
+ EventGCGarbageCollection event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_gcId(_shared_gc_info.id());
+ event.set_name(_shared_gc_info.name());
+ event.set_cause((u2) _shared_gc_info.cause());
+ event.set_sumOfPauses(_shared_gc_info.sum_of_pauses());
+ event.set_longestPause(_shared_gc_info.longest_pause());
+ event.set_starttime(_shared_gc_info.start_timestamp());
+ event.set_endtime(_shared_gc_info.end_timestamp());
+ event.commit();
+ }
+}
+
+void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const {
+ EventGCReferenceStatistics e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_type((u1)type);
+ e.set_count(count);
+ e.commit();
+ }
+}
+
+void ParallelOldTracer::send_parallel_old_event() const {
+ EventGCParallelOld e(UNTIMED);
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_densePrefix((TraceAddress)_parallel_old_gc_info.dense_prefix());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+ e.commit();
+ }
+}
+
+void YoungGCTracer::send_young_gc_event() const {
+ EventGCYoungGarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_tenuringThreshold(_tenuring_threshold);
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+ e.commit();
+ }
+}
+
+void OldGCTracer::send_old_gc_event() const {
+ EventGCOldGarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+ e.commit();
+ }
+}
+
+static TraceStructCopyFailed to_trace_struct(const CopyFailedInfo& cf_info) {
+ TraceStructCopyFailed failed_info;
+ failed_info.set_objectCount(cf_info.failed_count());
+ failed_info.set_firstSize(cf_info.first_size());
+ failed_info.set_smallestSize(cf_info.smallest_size());
+ failed_info.set_totalSize(cf_info.total_size());
+ return failed_info;
+}
+
+void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const {
+ EventPromotionFailed e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_data(to_trace_struct(pf_info));
+ e.set_thread(pf_info.thread()->thread_id());
+ e.commit();
+ }
+}
+
+// Common to CMS and G1
+void OldGCTracer::send_concurrent_mode_failure_event() {
+ EventConcurrentModeFailure e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.commit();
+ }
+}
+
+#if INCLUDE_SERVICES
+void GCTracer::send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const {
+ EventObjectCountAfterGC e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_class(klass);
+ e.set_count(count);
+ e.set_totalSize(total_size);
+ e.commit();
+ }
+}
+#endif
+
+bool GCTracer::should_send_object_count_after_gc_event() const {
+#if INCLUDE_TRACE
+ return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId);
+#else
+ return false;
+#endif
+}
+
+#if INCLUDE_ALL_GCS
+void G1NewTracer::send_g1_young_gc_event() {
+ EventGCG1GarbageCollection e(UNTIMED);
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_type(_g1_young_gc_info.type());
+ e.set_starttime(_shared_gc_info.start_timestamp());
+ e.set_endtime(_shared_gc_info.end_timestamp());
+ e.commit();
+ }
+}
+
+void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) {
+ EventEvacuationInfo e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_cSetRegions(info->collectionset_regions());
+ e.set_cSetUsedBefore(info->collectionset_used_before());
+ e.set_cSetUsedAfter(info->collectionset_used_after());
+ e.set_allocationRegions(info->allocation_regions());
+ e.set_allocRegionsUsedBefore(info->alloc_regions_used_before());
+ e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied());
+ e.set_bytesCopied(info->bytes_copied());
+ e.set_regionsFreed(info->regions_freed());
+ e.commit();
+ }
+}
+
+void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const {
+ EventEvacuationFailed e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_data(to_trace_struct(ef_info));
+ e.commit();
+ }
+}
+#endif
+
+static TraceStructVirtualSpace to_trace_struct(const VirtualSpaceSummary& summary) {
+ TraceStructVirtualSpace space;
+ space.set_start((TraceAddress)summary.start());
+ space.set_committedEnd((TraceAddress)summary.committed_end());
+ space.set_committedSize(summary.committed_size());
+ space.set_reservedEnd((TraceAddress)summary.reserved_end());
+ space.set_reservedSize(summary.reserved_size());
+ return space;
+}
+
+static TraceStructObjectSpace to_trace_struct(const SpaceSummary& summary) {
+ TraceStructObjectSpace space;
+ space.set_start((TraceAddress)summary.start());
+ space.set_end((TraceAddress)summary.end());
+ space.set_used(summary.used());
+ space.set_size(summary.size());
+ return space;
+}
+
+class GCHeapSummaryEventSender : public GCHeapSummaryVisitor {
+ GCId _id;
+ GCWhen::Type _when;
+ public:
+ GCHeapSummaryEventSender(GCId id, GCWhen::Type when) : _id(id), _when(when) {}
+
+ void visit(const GCHeapSummary* heap_summary) const {
+ const VirtualSpaceSummary& heap_space = heap_summary->heap();
+
+ EventGCHeapSummary e;
+ if (e.should_commit()) {
+ e.set_gcId(_id);
+ e.set_when((u1)_when);
+ e.set_heapSpace(to_trace_struct(heap_space));
+ e.set_heapUsed(heap_summary->used());
+ e.commit();
+ }
+ }
+
+ void visit(const PSHeapSummary* ps_heap_summary) const {
+ visit((GCHeapSummary*)ps_heap_summary);
+
+ const VirtualSpaceSummary& old_summary = ps_heap_summary->old();
+ const SpaceSummary& old_space = ps_heap_summary->old_space();
+ const VirtualSpaceSummary& young_summary = ps_heap_summary->young();
+ const SpaceSummary& eden_space = ps_heap_summary->eden();
+ const SpaceSummary& from_space = ps_heap_summary->from();
+ const SpaceSummary& to_space = ps_heap_summary->to();
+
+ EventPSHeapSummary e;
+ if (e.should_commit()) {
+ e.set_gcId(_id);
+ e.set_when((u1)_when);
+
+ e.set_oldSpace(to_trace_struct(ps_heap_summary->old()));
+ e.set_oldObjectSpace(to_trace_struct(ps_heap_summary->old_space()));
+ e.set_youngSpace(to_trace_struct(ps_heap_summary->young()));
+ e.set_edenSpace(to_trace_struct(ps_heap_summary->eden()));
+ e.set_fromSpace(to_trace_struct(ps_heap_summary->from()));
+ e.set_toSpace(to_trace_struct(ps_heap_summary->to()));
+ e.commit();
+ }
+ }
+};
+
+void GCTracer::send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
+ GCHeapSummaryEventSender visitor(_shared_gc_info.id(), when);
+ heap_summary.accept(&visitor);
+}
+
+static TraceStructMetaspaceSizes to_trace_struct(const MetaspaceSizes& sizes) {
+ TraceStructMetaspaceSizes meta_sizes;
+
+ meta_sizes.set_capacity(sizes.capacity());
+ meta_sizes.set_used(sizes.used());
+ meta_sizes.set_reserved(sizes.reserved());
+
+ return meta_sizes;
+}
+
+void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const {
+ EventMetaspaceSummary e;
+ if (e.should_commit()) {
+ e.set_gcId(_shared_gc_info.id());
+ e.set_when((u1) when);
+ e.set_metaspace(to_trace_struct(meta_space_summary.meta_space()));
+ e.set_dataSpace(to_trace_struct(meta_space_summary.data_space()));
+ e.set_classSpace(to_trace_struct(meta_space_summary.class_space()));
+ e.commit();
+ }
+}
+
+class PhaseSender : public PhaseVisitor {
+ GCId _gc_id;
+ public:
+ PhaseSender(GCId gc_id) : _gc_id(gc_id) {}
+
+ template
+ void send_phase(PausePhase* pause) {
+ T event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_gcId(_gc_id);
+ event.set_name(pause->name());
+ event.set_starttime(pause->start());
+ event.set_endtime(pause->end());
+ event.commit();
+ }
+ }
+
+ void visit(GCPhase* pause) { ShouldNotReachHere(); }
+ void visit(ConcurrentPhase* pause) { Unimplemented(); }
+ void visit(PausePhase* pause) {
+ assert(PhasesStack::PHASE_LEVELS == 5, "Need more event types");
+
+ switch (pause->level()) {
+ case 0: send_phase(pause); break;
+ case 1: send_phase(pause); break;
+ case 2: send_phase(pause); break;
+ case 3: send_phase(pause); break;
+ default: /* Ignore sending this phase */ break;
+ }
+ }
+
+#undef send_phase
+};
+
+void GCTracer::send_phase_events(TimePartitions* time_partitions) const {
+ PhaseSender phase_reporter(_shared_gc_info.id());
+
+ TimePartitionPhasesIterator iter(time_partitions);
+ while (iter.has_next()) {
+ GCPhase* phase = iter.next();
+ phase->accept(&phase_reporter);
+ }
+}
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp
new file mode 100644
index 00000000000..1c137047c42
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/timer.hpp"
+#include "utilities/ostream.hpp"
+
+
+GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) :
+ _title(title), _doit(doit), _print_cr(print_cr), _timer(timer) {
+ if (_doit || _timer != NULL) {
+ _start_counter = os::elapsed_counter();
+ }
+
+ if (_timer != NULL) {
+ assert(SafepointSynchronize::is_at_safepoint(), "Tracing currently only supported at safepoints");
+ assert(Thread::current()->is_VM_thread(), "Tracing currently only supported from the VM thread");
+
+ _timer->register_gc_phase_start(title, _start_counter);
+ }
+
+ if (_doit) {
+ if (PrintGCTimeStamps) {
+ gclog_or_tty->stamp();
+ gclog_or_tty->print(": ");
+ }
+ gclog_or_tty->print("[%s", title);
+ gclog_or_tty->flush();
+ }
+}
+
+GCTraceTime::~GCTraceTime() {
+ jlong stop_counter = 0;
+
+ if (_doit || _timer != NULL) {
+ stop_counter = os::elapsed_counter();
+ }
+
+ if (_timer != NULL) {
+ _timer->register_gc_phase_end(stop_counter);
+ }
+
+ if (_doit) {
+ double seconds = TimeHelper::counter_to_seconds(stop_counter - _start_counter);
+ if (_print_cr) {
+ gclog_or_tty->print_cr(", %3.7f secs]", seconds);
+ } else {
+ gclog_or_tty->print(", %3.7f secs]", seconds);
+ }
+ gclog_or_tty->flush();
+ }
+}
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp
new file mode 100644
index 00000000000..5d92b4d339a
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceTime.hpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
+
+#include "prims/jni_md.h"
+
+class GCTimer;
+
+class GCTraceTime {
+ const char* _title;
+ bool _doit;
+ bool _print_cr;
+ GCTimer* _timer;
+ jlong _start_counter;
+
+ public:
+ GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer);
+ ~GCTraceTime();
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcWhen.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcWhen.hpp
new file mode 100644
index 00000000000..5713ba4e8ae
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcWhen.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+class GCWhen : AllStatic {
+ public:
+ enum Type {
+ BeforeGC,
+ AfterGC,
+ GCWhenEndSentinel
+ };
+
+ static const char* to_string(GCWhen::Type when) {
+ switch (when) {
+ case BeforeGC: return "Before GC";
+ case AfterGC: return "After GC";
+ default: ShouldNotReachHere(); return NULL;
+ }
+ }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCWHEN_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
index 1a977bbcefa..7bdcd55f587 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "compiler/compileBroker.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "oops/methodData.hpp"
@@ -41,6 +43,8 @@ size_t MarkSweep::_preserved_count = 0;
size_t MarkSweep::_preserved_count_max = 0;
PreservedMark* MarkSweep::_preserved_marks = NULL;
ReferenceProcessor* MarkSweep::_ref_processor = NULL;
+STWGCTimer* MarkSweep::_gc_timer = NULL;
+SerialOldTracer* MarkSweep::_gc_tracer = NULL;
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
@@ -173,7 +177,10 @@ MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
-void marksweep_init() { /* empty */ }
+void marksweep_init() {
+ MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
+ MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
+}
#ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index ab5e6ef322c..2c08a6897f4 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,8 @@
class ReferenceProcessor;
class DataLayout;
+class SerialOldTracer;
+class STWGCTimer;
// MarkSweep takes care of global mark-compact garbage collection for a
// GenCollectedHeap using a four-phase pointer forwarding algorithm. All
@@ -128,6 +130,9 @@ class MarkSweep : AllStatic {
// Reference processing (used in ...follow_contents)
static ReferenceProcessor* _ref_processor;
+ static STWGCTimer* _gc_timer;
+ static SerialOldTracer* _gc_tracer;
+
// Non public closures
static KeepAliveClosure keep_alive;
@@ -151,6 +156,9 @@ class MarkSweep : AllStatic {
// Reference Processing
static ReferenceProcessor* const ref_processor() { return _ref_processor; }
+ static STWGCTimer* gc_timer() { return _gc_timer; }
+ static SerialOldTracer* gc_tracer() { return _gc_tracer; }
+
// Call backs for marking
static void mark_object(oop obj);
// Mark pointer and follow contents. Empty marking stack afterwards.
diff --git a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
index 211a084ab38..31e6bddf421 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp
@@ -145,32 +145,37 @@ bool VM_GC_HeapInspection::skip_operation() const {
return false;
}
+bool VM_GC_HeapInspection::collect() {
+ if (GC_locker::is_active()) {
+ return false;
+ }
+ Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
+ return true;
+}
+
void VM_GC_HeapInspection::doit() {
HandleMark hm;
- CollectedHeap* ch = Universe::heap();
- ch->ensure_parsability(false); // must happen, even if collection does
- // not happen (e.g. due to GC_locker)
+ Universe::heap()->ensure_parsability(false); // must happen, even if collection does
+ // not happen (e.g. due to GC_locker)
+ // or _full_gc being false
if (_full_gc) {
- // The collection attempt below would be skipped anyway if
- // the gc locker is held. The following dump may then be a tad
- // misleading to someone expecting only live objects to show
- // up in the dump (see CR 6944195). Just issue a suitable warning
- // in that case and do not attempt to do a collection.
- // The latter is a subtle point, because even a failed attempt
- // to GC will, in fact, induce one in the future, which we
- // probably want to avoid in this case because the GC that we may
- // be about to attempt holds value for us only
- // if it happens now and not if it happens in the eventual
- // future.
- if (GC_locker::is_active()) {
+ if (!collect()) {
+ // The collection attempt was skipped because the gc locker is held.
+ // The following dump may then be a tad misleading to someone expecting
+ // only live objects to show up in the dump (see CR 6944195). Just issue
+ // a suitable warning in that case and do not attempt to do a collection.
+ // The latter is a subtle point, because even a failed attempt
+ // to GC will, in fact, induce one in the future, which we
+ // probably want to avoid in this case because the GC that we may
+ // be about to attempt holds value for us only
+ // if it happens now and not if it happens in the eventual
+ // future.
warning("GC locker is held; pre-dump GC was skipped");
- } else {
- ch->collect_as_vm_thread(GCCause::_heap_inspection);
}
}
HeapInspection inspect(_csv_format, _print_help, _print_class_stats,
_columns);
- inspect.heap_inspection(_out, _need_prologue /* need_prologue */);
+ inspect.heap_inspection(_out);
}
diff --git a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
index 2a416f22843..60b3a9679c1 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp
@@ -129,21 +129,18 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
private:
outputStream* _out;
bool _full_gc;
- bool _need_prologue;
bool _csv_format; // "comma separated values" format for spreadsheet.
bool _print_help;
bool _print_class_stats;
const char* _columns;
public:
- VM_GC_HeapInspection(outputStream* out, bool request_full_gc,
- bool need_prologue) :
+ VM_GC_HeapInspection(outputStream* out, bool request_full_gc) :
VM_GC_Operation(0 /* total collections, dummy, ignored */,
GCCause::_heap_inspection /* GC Cause */,
0 /* total full collections, dummy, ignored */,
request_full_gc) {
_out = out;
_full_gc = request_full_gc;
- _need_prologue = need_prologue;
_csv_format = false;
_print_help = false;
_print_class_stats = false;
@@ -159,6 +156,8 @@ class VM_GC_HeapInspection: public VM_GC_Operation {
void set_print_help(bool value) {_print_help = value;}
void set_print_class_stats(bool value) {_print_class_stats = value;}
void set_columns(const char* value) {_columns = value;}
+ protected:
+ bool collect();
};
diff --git a/hotspot/src/share/vm/gc_interface/allocTracer.cpp b/hotspot/src/share/vm/gc_interface/allocTracer.cpp
new file mode 100644
index 00000000000..d3440cd8534
--- /dev/null
+++ b/hotspot/src/share/vm/gc_interface/allocTracer.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_interface/allocTracer.hpp"
+#include "trace/tracing.hpp"
+#include "runtime/handles.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+void AllocTracer::send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size) {
+ EventAllocObjectOutsideTLAB event;
+ if (event.should_commit()) {
+ event.set_class(klass());
+ event.set_allocationSize(alloc_size);
+ event.commit();
+ }
+}
+
+void AllocTracer::send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size) {
+ EventAllocObjectInNewTLAB event;
+ if (event.should_commit()) {
+ event.set_class(klass());
+ event.set_allocationSize(alloc_size);
+ event.set_tlabSize(tlab_size);
+ event.commit();
+ }
+}
diff --git a/hotspot/src/share/vm/gc_interface/allocTracer.hpp b/hotspot/src/share/vm/gc_interface/allocTracer.hpp
new file mode 100644
index 00000000000..33e6f19f3a8
--- /dev/null
+++ b/hotspot/src/share/vm/gc_interface/allocTracer.hpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
+#define SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/handles.hpp"
+
+class AllocTracer : AllStatic {
+ public:
+ static void send_allocation_outside_tlab_event(KlassHandle klass, size_t alloc_size);
+ static void send_allocation_in_new_tlab_event(KlassHandle klass, size_t tlab_size, size_t alloc_size);
+};
+
+#endif /* SHARE_VM_GC_INTERFACE_ALLOCTRACER_HPP */
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
index f6555979dbe..4c6c026e74b 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,15 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
+#include "gc_interface/allocTracer.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/metaspace.hpp"
#include "oops/oop.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "runtime/init.hpp"
@@ -65,11 +71,71 @@ void GCHeapLog::log_heap(bool before) {
}
}
+VirtualSpaceSummary CollectedHeap::create_heap_space_summary() {
+ size_t capacity_in_words = capacity() / HeapWordSize;
+
+ return VirtualSpaceSummary(
+ reserved_region().start(), reserved_region().start() + capacity_in_words, reserved_region().end());
+}
+
+GCHeapSummary CollectedHeap::create_heap_summary() {
+ VirtualSpaceSummary heap_space = create_heap_space_summary();
+ return GCHeapSummary(heap_space, used());
+}
+
+MetaspaceSummary CollectedHeap::create_metaspace_summary() {
+ const MetaspaceSizes meta_space(
+ 0, /*MetaspaceAux::capacity_in_bytes(),*/
+ 0, /*MetaspaceAux::used_in_bytes(),*/
+ MetaspaceAux::reserved_in_bytes());
+ const MetaspaceSizes data_space(
+ 0, /*MetaspaceAux::capacity_in_bytes(Metaspace::NonClassType),*/
+ 0, /*MetaspaceAux::used_in_bytes(Metaspace::NonClassType),*/
+ MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType));
+ const MetaspaceSizes class_space(
+ 0, /*MetaspaceAux::capacity_in_bytes(Metaspace::ClassType),*/
+ 0, /*MetaspaceAux::used_in_bytes(Metaspace::ClassType),*/
+ MetaspaceAux::reserved_in_bytes(Metaspace::ClassType));
+
+ return MetaspaceSummary(meta_space, data_space, class_space);
+}
+
+void CollectedHeap::print_heap_before_gc() {
+ if (PrintHeapAtGC) {
+ Universe::print_heap_before_gc();
+ }
+ if (_gc_heap_log != NULL) {
+ _gc_heap_log->log_heap_before();
+ }
+}
+
+void CollectedHeap::print_heap_after_gc() {
+ if (PrintHeapAtGC) {
+ Universe::print_heap_after_gc();
+ }
+ if (_gc_heap_log != NULL) {
+ _gc_heap_log->log_heap_after();
+ }
+}
+
+void CollectedHeap::trace_heap(GCWhen::Type when, GCTracer* gc_tracer) {
+ const GCHeapSummary& heap_summary = create_heap_summary();
+ const MetaspaceSummary& metaspace_summary = create_metaspace_summary();
+ gc_tracer->report_gc_heap_summary(when, heap_summary, metaspace_summary);
+}
+
+void CollectedHeap::trace_heap_before_gc(GCTracer* gc_tracer) {
+ trace_heap(GCWhen::BeforeGC, gc_tracer);
+}
+
+void CollectedHeap::trace_heap_after_gc(GCTracer* gc_tracer) {
+ trace_heap(GCWhen::AfterGC, gc_tracer);
+}
+
// Memory state functions.
CollectedHeap::CollectedHeap() : _n_par_threads(0)
-
{
const size_t max_len = size_t(arrayOopDesc::max_array_length(T_INT));
const size_t elements_per_word = HeapWordSize / sizeof(jint);
@@ -185,7 +251,7 @@ void CollectedHeap::check_for_valid_allocation_state() {
}
#endif
-HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size) {
// Retain tlab and allocate object in shared space if
// the amount free in the tlab is too large to discard.
@@ -209,6 +275,9 @@ HeapWord* CollectedHeap::allocate_from_tlab_slow(Thread* thread, size_t size) {
if (obj == NULL) {
return NULL;
}
+
+ AllocTracer::send_allocation_in_new_tlab_event(klass, new_tlab_size * HeapWordSize, size * HeapWordSize);
+
if (ZeroTLAB) {
// ..and clear it.
Copy::zero_to_words(obj, new_tlab_size);
@@ -458,28 +527,28 @@ void CollectedHeap::resize_all_tlabs() {
}
}
-void CollectedHeap::pre_full_gc_dump() {
+void CollectedHeap::pre_full_gc_dump(GCTimer* timer) {
if (HeapDumpBeforeFullGC) {
- TraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime tt("Heap Dump (before full gc): ", PrintGCDetails, false, timer);
// We are doing a "major" collection and a heap dump before
// major collection has been requested.
HeapDumper::dump_heap();
}
if (PrintClassHistogramBeforeFullGC) {
- TraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, gclog_or_tty);
- VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */, false /* ! prologue */);
+ GCTraceTime tt("Class Histogram (before full gc): ", PrintGCDetails, true, timer);
+ VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
inspector.doit();
}
}
-void CollectedHeap::post_full_gc_dump() {
+void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
if (HeapDumpAfterFullGC) {
- TraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime tt("Heap Dump (after full gc): ", PrintGCDetails, false, timer);
HeapDumper::dump_heap();
}
if (PrintClassHistogramAfterFullGC) {
- TraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, gclog_or_tty);
- VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */, false /* ! prologue */);
+ GCTraceTime tt("Class Histogram (after full gc): ", PrintGCDetails, true, timer);
+ VM_GC_HeapInspection inspector(gclog_or_tty, false /* ! full gc */);
inspector.doit();
}
}
@@ -490,7 +559,7 @@ oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle r
assert(size >= 0, "int won't convert to size_t");
HeapWord* obj;
assert(ScavengeRootsInCode > 0, "must be");
- obj = common_mem_allocate_init(size, CHECK_NULL);
+ obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
post_allocation_setup_common(klass, obj);
assert(Universe::is_bootstrapping() ||
!((oop)obj)->is_array(), "must not be an array");
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
index 88929343c08..1f42cfe4839 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_HPP
#include "gc_interface/gcCause.hpp"
+#include "gc_implementation/shared/gcWhen.hpp"
#include "memory/allocation.hpp"
#include "memory/barrierSet.hpp"
#include "runtime/handles.hpp"
@@ -38,11 +39,16 @@
// class defines the functions that a heap must implement, and contains
// infrastructure common to all heaps.
-class BarrierSet;
-class ThreadClosure;
class AdaptiveSizePolicy;
-class Thread;
+class BarrierSet;
class CollectorPolicy;
+class GCHeapSummary;
+class GCTimer;
+class GCTracer;
+class MetaspaceSummary;
+class Thread;
+class ThreadClosure;
+class VirtualSpaceSummary;
class GCMessage : public FormatBuffer<1024> {
public:
@@ -128,16 +134,16 @@ class CollectedHeap : public CHeapObj {
virtual void resize_all_tlabs();
// Allocate from the current thread's TLAB, with broken-out slow path.
- inline static HeapWord* allocate_from_tlab(Thread* thread, size_t size);
- static HeapWord* allocate_from_tlab_slow(Thread* thread, size_t size);
+ inline static HeapWord* allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size);
+ static HeapWord* allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size);
// Allocate an uninitialized block of the given size, or returns NULL if
// this is impossible.
- inline static HeapWord* common_mem_allocate_noinit(size_t size, TRAPS);
+ inline static HeapWord* common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS);
// Like allocate_init, but the block returned by a successful allocation
// is guaranteed initialized to zeros.
- inline static HeapWord* common_mem_allocate_init(size_t size, TRAPS);
+ inline static HeapWord* common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS);
// Helper functions for (VM) allocation.
inline static void post_allocation_setup_common(KlassHandle klass, HeapWord* obj);
@@ -166,6 +172,8 @@ class CollectedHeap : public CHeapObj {
// Fill with a single object (either an int array or a java.lang.Object).
static inline void fill_with_object_impl(HeapWord* start, size_t words, bool zap = true);
+ virtual void trace_heap(GCWhen::Type when, GCTracer* tracer);
+
// Verification functions
virtual void check_for_bad_heap_word_value(HeapWord* addr, size_t size)
PRODUCT_RETURN;
@@ -202,8 +210,6 @@ class CollectedHeap : public CHeapObj {
MemRegion reserved_region() const { return _reserved; }
address base() const { return (address)reserved_region().start(); }
- // Future cleanup here. The following functions should specify bytes or
- // heapwords as part of their signature.
virtual size_t capacity() const = 0;
virtual size_t used() const = 0;
@@ -550,8 +556,13 @@ class CollectedHeap : public CHeapObj {
virtual void prepare_for_verify() = 0;
// Generate any dumps preceding or following a full gc
- void pre_full_gc_dump();
- void post_full_gc_dump();
+ void pre_full_gc_dump(GCTimer* timer);
+ void post_full_gc_dump(GCTimer* timer);
+
+ VirtualSpaceSummary create_heap_space_summary();
+ GCHeapSummary create_heap_summary();
+
+ MetaspaceSummary create_metaspace_summary();
// Print heap information on the given outputStream.
virtual void print_on(outputStream* st) const = 0;
@@ -560,7 +571,7 @@ class CollectedHeap : public CHeapObj {
print_on(tty);
}
// Print more detailed heap information on the given
- // outputStream. The default behaviour is to call print_on(). It is
+ // outputStream. The default behavior is to call print_on(). It is
// up to each subclass to override it and add any additional output
// it needs.
virtual void print_extended_on(outputStream* st) const {
@@ -589,23 +600,11 @@ class CollectedHeap : public CHeapObj {
// Default implementation does nothing.
virtual void print_tracing_info() const = 0;
- // If PrintHeapAtGC is set call the appropriate routi
- void print_heap_before_gc() {
- if (PrintHeapAtGC) {
- Universe::print_heap_before_gc();
- }
- if (_gc_heap_log != NULL) {
- _gc_heap_log->log_heap_before();
- }
- }
- void print_heap_after_gc() {
- if (PrintHeapAtGC) {
- Universe::print_heap_after_gc();
- }
- if (_gc_heap_log != NULL) {
- _gc_heap_log->log_heap_after();
- }
- }
+ void print_heap_before_gc();
+ void print_heap_after_gc();
+
+ void trace_heap_before_gc(GCTracer* gc_tracer);
+ void trace_heap_after_gc(GCTracer* gc_tracer);
// Heap verification
virtual void verify(bool silent, VerifyOption option) = 0;
@@ -619,7 +618,7 @@ class CollectedHeap : public CHeapObj {
inline bool promotion_should_fail();
// Reset the PromotionFailureALot counters. Should be called at the end of a
- // GC in which promotion failure ocurred.
+ // GC in which promotion failure occurred.
inline void reset_promotion_should_fail(volatile size_t* count);
inline void reset_promotion_should_fail();
#endif // #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
index c57b057c69f..d17b82f2158 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
#define SHARE_VM_GC_INTERFACE_COLLECTEDHEAP_INLINE_HPP
+#include "gc_interface/allocTracer.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "memory/threadLocalAllocBuffer.inline.hpp"
#include "memory/universe.hpp"
@@ -107,7 +108,7 @@ void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
post_allocation_notify(klass, (oop)obj);
}
-HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
+HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) {
// Clear unhandled oops for memory allocation. Memory allocation might
// not take out a lock if from tlab, so clear here.
@@ -120,7 +121,7 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
HeapWord* result = NULL;
if (UseTLAB) {
- result = CollectedHeap::allocate_from_tlab(THREAD, size);
+ result = allocate_from_tlab(klass, THREAD, size);
if (result != NULL) {
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
@@ -136,6 +137,9 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
assert(!HAS_PENDING_EXCEPTION,
"Unexpected exception, will result in uninitialized storage");
THREAD->incr_allocated_bytes(size * HeapWordSize);
+
+ AllocTracer::send_allocation_outside_tlab_event(klass, size * HeapWordSize);
+
return result;
}
@@ -165,13 +169,13 @@ HeapWord* CollectedHeap::common_mem_allocate_noinit(size_t size, TRAPS) {
}
}
-HeapWord* CollectedHeap::common_mem_allocate_init(size_t size, TRAPS) {
- HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
+ HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
init_obj(obj, size);
return obj;
}
-HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
+HeapWord* CollectedHeap::allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size) {
assert(UseTLAB, "should use UseTLAB");
HeapWord* obj = thread->tlab().allocate(size);
@@ -179,7 +183,7 @@ HeapWord* CollectedHeap::allocate_from_tlab(Thread* thread, size_t size) {
return obj;
}
// Otherwise...
- return allocate_from_tlab_slow(thread, size);
+ return allocate_from_tlab_slow(klass, thread, size);
}
void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
@@ -194,7 +198,7 @@ oop CollectedHeap::obj_allocate(KlassHandle klass, int size, TRAPS) {
debug_only(check_for_valid_allocation_state());
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
assert(size >= 0, "int won't convert to size_t");
- HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+ HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
post_allocation_setup_obj(klass, obj);
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
return (oop)obj;
@@ -207,7 +211,7 @@ oop CollectedHeap::array_allocate(KlassHandle klass,
debug_only(check_for_valid_allocation_state());
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
assert(size >= 0, "int won't convert to size_t");
- HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
+ HeapWord* obj = common_mem_allocate_init(klass, size, CHECK_NULL);
post_allocation_setup_array(klass, obj, length);
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
return (oop)obj;
@@ -220,7 +224,7 @@ oop CollectedHeap::array_allocate_nozero(KlassHandle klass,
debug_only(check_for_valid_allocation_state());
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
assert(size >= 0, "int won't convert to size_t");
- HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
+ HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
((oop)obj)->set_klass_gap(0);
post_allocation_setup_array(klass, obj, length);
#ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_interface/gcCause.cpp b/hotspot/src/share/vm/gc_interface/gcCause.cpp
index 0ac45d911c8..e7e7e43f440 100644
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp
@@ -72,6 +72,9 @@ const char* GCCause::to_string(GCCause::Cause cause) {
case _cms_final_remark:
return "CMS Final Remark";
+ case _cms_concurrent_mark:
+ return "CMS Concurrent Mark";
+
case _old_generation_expanded_on_last_scavenge:
return "Old Generation Expanded On Last Scavenge";
diff --git a/hotspot/src/share/vm/gc_interface/gcCause.hpp b/hotspot/src/share/vm/gc_interface/gcCause.hpp
index 58abc2e6f5e..06f11882c95 100644
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp
@@ -60,6 +60,7 @@ class GCCause : public AllStatic {
_cms_generation_full,
_cms_initial_mark,
_cms_final_remark,
+ _cms_concurrent_mark,
_old_generation_expanded_on_last_scavenge,
_old_generation_too_full_to_scavenge,
diff --git a/hotspot/src/share/vm/gc_interface/gcName.hpp b/hotspot/src/share/vm/gc_interface/gcName.hpp
new file mode 100644
index 00000000000..c48c2483805
--- /dev/null
+++ b/hotspot/src/share/vm/gc_interface/gcName.hpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_INTERFACE_GCNAME_HPP
+#define SHARE_VM_GC_INTERFACE_GCNAME_HPP
+
+#include "utilities/debug.hpp"
+
+enum GCName {
+ ParallelOld,
+ SerialOld,
+ PSMarkSweep,
+ ParallelScavenge,
+ DefNew,
+ ParNew,
+ G1New,
+ ConcurrentMarkSweep,
+ G1Old,
+ GCNameEndSentinel
+};
+
+class GCNameHelper {
+ public:
+ static const char* to_string(GCName name) {
+ switch(name) {
+ case ParallelOld: return "ParallelOld";
+ case SerialOld: return "SerialOld";
+ case PSMarkSweep: return "PSMarkSweep";
+ case ParallelScavenge: return "ParallelScavenge";
+ case DefNew: return "DefNew";
+ case ParNew: return "ParNew";
+ case G1New: return "G1New";
+ case ConcurrentMarkSweep: return "ConcurrentMarkSweep";
+ case G1Old: return "G1Old";
+ default: ShouldNotReachHere(); return NULL;
+ }
+ }
+};
+
+#endif // SHARE_VM_GC_INTERFACE_GCNAME_HPP
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index ebdb29cd26c..65df6ee052d 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -157,7 +157,8 @@ enum MemoryType {
mtJavaHeap = 0x0C00, // Java heap
mtClassShared = 0x0D00, // class data sharing
mtTest = 0x0E00, // Test type for verifying NMT
- mt_number_of_types = 0x000E, // number of memory types (mtDontTrack
+ mtTracing = 0x0F00, // memory used for Tracing
+ mt_number_of_types = 0x000F, // number of memory types (mtDontTrack
// is not included as validate type)
mtDontTrack = 0x0F00, // memory we do not or cannot track
mt_masks = 0x7F00,
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp
index 39bbd14c49b..88afd70a739 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,10 @@
#include "precompiled.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
#include "gc_implementation/shared/gcPolicyCounters.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "memory/defNewGeneration.inline.hpp"
#include "memory/gcLocker.inline.hpp"
@@ -223,6 +227,8 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
_next_gen = NULL;
_tenuring_threshold = MaxTenuringThreshold;
_pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
+
+ _gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
}
void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size,
@@ -558,12 +564,18 @@ void DefNewGeneration::collect(bool full,
size_t size,
bool is_tlab) {
assert(full || size > 0, "otherwise we don't want to collect");
+
GenCollectedHeap* gch = GenCollectedHeap::heap();
+
+ _gc_timer->register_gc_start(os::elapsed_counter());
+ DefNewTracer gc_tracer;
+ gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
+
_next_gen = gch->next_gen(this);
assert(_next_gen != NULL,
"This must be the youngest gen, and not the only gen");
- // If the next generation is too full to accomodate promotion
+ // If the next generation is too full to accommodate promotion
// from this generation, pass on collection; let the next generation
// do it.
if (!collection_attempt_is_safe()) {
@@ -577,10 +589,12 @@ void DefNewGeneration::collect(bool full,
init_assuming_no_promotion_failure();
- TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
// Capture heap used before collection (for printing).
size_t gch_prev_used = gch->used();
+ gch->trace_heap_before_gc(&gc_tracer);
+
SpecializationStats::clear();
// These can be shared for all code paths
@@ -631,9 +645,12 @@ void DefNewGeneration::collect(bool full,
FastKeepAliveClosure keep_alive(this, &scan_weak_ref);
ReferenceProcessor* rp = ref_processor();
rp->setup_policy(clear_all_soft_refs);
+ const ReferenceProcessorStats& stats =
rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers,
- NULL);
- if (!promotion_failed()) {
+ NULL, _gc_timer);
+ gc_tracer.report_gc_reference_stats(stats);
+
+ if (!_promotion_failed) {
// Swap the survivor spaces.
eden()->clear(SpaceDecorator::Mangle);
from()->clear(SpaceDecorator::Mangle);
@@ -680,6 +697,7 @@ void DefNewGeneration::collect(bool full,
// Inform the next generation that a promotion failure occurred.
_next_gen->promotion_failure_occurred();
+ gc_tracer.report_promotion_failed(_promotion_failed_info);
// Reset the PromotionFailureALot counters.
NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
@@ -689,11 +707,18 @@ void DefNewGeneration::collect(bool full,
to()->set_concurrent_iteration_safe_limit(to()->top());
SpecializationStats::print();
- // We need to use a monotonically non-deccreasing time in ms
+ // We need to use a monotonically non-decreasing time in ms
// or we will see time-warp warnings and os::javaTimeMillis()
// does not guarantee monotonicity.
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
update_time_of_last_gc(now);
+
+ gch->trace_heap_after_gc(&gc_tracer);
+ gc_tracer.report_tenuring_threshold(tenuring_threshold());
+
+ _gc_timer->register_gc_end(os::elapsed_counter());
+
+ gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
}
class RemoveForwardPointerClosure: public ObjectClosure {
@@ -705,6 +730,7 @@ public:
void DefNewGeneration::init_assuming_no_promotion_failure() {
_promotion_failed = false;
+ _promotion_failed_info.reset();
from()->set_next_compaction_space(NULL);
}
@@ -726,7 +752,7 @@ void DefNewGeneration::remove_forwarding_pointers() {
}
void DefNewGeneration::preserve_mark(oop obj, markOop m) {
- assert(promotion_failed() && m->must_be_preserved_for_promotion_failure(obj),
+ assert(_promotion_failed && m->must_be_preserved_for_promotion_failure(obj),
"Oversaving!");
_objs_with_preserved_marks.push(obj);
_preserved_marks_of_objs.push(m);
@@ -744,6 +770,7 @@ void DefNewGeneration::handle_promotion_failure(oop old) {
old->size());
}
_promotion_failed = true;
+ _promotion_failed_info.register_copy_failure(old->size());
preserve_mark_if_necessary(old, old->mark());
// forward to self
old->forward_to(old);
@@ -962,6 +989,10 @@ void DefNewGeneration::record_spaces_top() {
from()->set_top_for_allocations();
}
+void DefNewGeneration::ref_processor_init() {
+ Generation::ref_processor_init();
+}
+
void DefNewGeneration::update_counters() {
if (UsePerfData) {
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp
index ee2871820f2..c538e0a4f35 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
#include "gc_implementation/shared/ageTable.hpp"
#include "gc_implementation/shared/cSpaceCounters.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
+#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/generation.inline.hpp"
#include "utilities/stack.hpp"
class EdenSpace;
class ContiguousSpace;
class ScanClosure;
+class STWGCTimer;
// DefNewGeneration is a young generation containing eden, from- and
// to-space.
@@ -46,15 +48,17 @@ protected:
uint _tenuring_threshold; // Tenuring threshold for next collection.
ageTable _age_table;
// Size of object to pretenure in words; command line provides bytes
- size_t _pretenure_size_threshold_words;
+ size_t _pretenure_size_threshold_words;
ageTable* age_table() { return &_age_table; }
+
// Initialize state to optimistically assume no promotion failure will
// happen.
void init_assuming_no_promotion_failure();
// True iff a promotion has failed in the current collection.
bool _promotion_failed;
bool promotion_failed() { return _promotion_failed; }
+ PromotionFailedInfo _promotion_failed_info;
// Handling promotion failure. A young generation collection
// can fail if a live object cannot be copied out of its
@@ -132,6 +136,8 @@ protected:
ContiguousSpace* _from_space;
ContiguousSpace* _to_space;
+ STWGCTimer* _gc_timer;
+
enum SomeProtectedConstants {
// Generations are GenGrain-aligned and have size that are multiples of
// GenGrain.
@@ -203,6 +209,8 @@ protected:
DefNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level,
const char* policy="Copy");
+ virtual void ref_processor_init();
+
virtual Generation::Name kind() { return Generation::DefNew; }
// Accessing spaces
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
index 8c2eb34d262..a74533d4321 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/filemap.hpp"
@@ -388,7 +389,7 @@ void GenCollectedHeap::do_collection(bool full,
const char* gc_cause_prefix = complete ? "Full GC" : "GC";
gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
- TraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, gclog_or_tty);
+ GCTraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, NULL);
gc_prologue(complete);
increment_total_collections(complete);
@@ -417,10 +418,11 @@ void GenCollectedHeap::do_collection(bool full,
// The full_collections increment was missed above.
increment_total_full_collections();
}
- pre_full_gc_dump(); // do any pre full gc dumps
+ pre_full_gc_dump(NULL); // do any pre full gc dumps
}
// Timer for individual generations. Last argument is false: no CR
- TraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, gclog_or_tty);
+ // FIXME: We should try to start the timing earlier to cover more of the GC pause
+ GCTraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, NULL);
TraceCollectorStats tcs(_gens[i]->counters());
TraceMemoryManagerStats tmms(_gens[i]->kind(),gc_cause());
@@ -534,7 +536,8 @@ void GenCollectedHeap::do_collection(bool full,
complete = complete || (max_level_collected == n_gens() - 1);
if (complete) { // We did a "major" collection
- post_full_gc_dump(); // do any post full gc dumps
+ // FIXME: See comment at pre_full_gc_dump call
+ post_full_gc_dump(NULL); // do any post full gc dumps
}
if (PrintGCDetails) {
diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp
index 6d0fd9b49d6..e53e742be70 100644
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,10 @@
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/icBuffer.hpp"
+#include "gc_implementation/shared/gcHeapSummary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/genCollectedHeap.hpp"
#include "memory/genMarkSweep.hpp"
@@ -65,7 +69,9 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
_ref_processor = rp;
rp->setup_policy(clear_all_softrefs);
- TraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
+ GCTraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL);
+
+ gch->trace_heap_before_gc(_gc_tracer);
// When collecting the permanent generation Method*s may be moving,
// so we either have to flush all bcp data or convert it into bci.
@@ -155,6 +161,8 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
// does not guarantee monotonicity.
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
gch->update_time_of_last_gc(now);
+
+ gch->trace_heap_after_gc(_gc_tracer);
}
void GenMarkSweep::allocate_stacks() {
@@ -192,7 +200,7 @@ void GenMarkSweep::deallocate_stacks() {
void GenMarkSweep::mark_sweep_phase1(int level,
bool clear_all_softrefs) {
// Recursively traverse all live objects and mark them
- TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer);
trace(" 1");
GenCollectedHeap* gch = GenCollectedHeap::heap();
@@ -219,8 +227,10 @@ void GenMarkSweep::mark_sweep_phase1(int level,
// Process reference objects found during marking
{
ref_processor()->setup_policy(clear_all_softrefs);
- ref_processor()->process_discovered_references(
- &is_alive, &keep_alive, &follow_stack_closure, NULL);
+ const ReferenceProcessorStats& stats =
+ ref_processor()->process_discovered_references(
+ &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer);
+ gc_tracer()->report_gc_reference_stats(stats);
}
// This is the point where the entire marking should have completed.
@@ -240,6 +250,8 @@ void GenMarkSweep::mark_sweep_phase1(int level,
// Clean up unreferenced symbols in symbol table.
SymbolTable::unlink();
+
+ gc_tracer()->report_object_count_after_gc(&is_alive);
}
@@ -259,7 +271,7 @@ void GenMarkSweep::mark_sweep_phase2() {
GenCollectedHeap* gch = GenCollectedHeap::heap();
- TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer);
trace("2");
gch->prepare_for_compaction();
@@ -276,7 +288,7 @@ void GenMarkSweep::mark_sweep_phase3(int level) {
GenCollectedHeap* gch = GenCollectedHeap::heap();
// Adjust the pointers to reflect the new locations
- TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer);
trace("3");
// Need new claim bits for the pointer adjustment tracing.
@@ -331,7 +343,7 @@ void GenMarkSweep::mark_sweep_phase4() {
// to use a higher index (saved from phase2) when verifying perm_gen.
GenCollectedHeap* gch = GenCollectedHeap::heap();
- TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty);
+ GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer);
trace("4");
GenCompactClosure blk;
diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp
index b608874658e..9fa46b34af4 100644
--- a/hotspot/src/share/vm/memory/generation.cpp
+++ b/hotspot/src/share/vm/memory/generation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,8 @@
*/
#include "precompiled.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/spaceDecorator.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
@@ -624,12 +626,26 @@ void OneContigSpaceCardGeneration::collect(bool full,
bool clear_all_soft_refs,
size_t size,
bool is_tlab) {
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+
SpecializationStats::clear();
// Temporarily expand the span of our ref processor, so
// refs discovery is over the entire heap, not just this generation
ReferenceProcessorSpanMutator
- x(ref_processor(), GenCollectedHeap::heap()->reserved_region());
+ x(ref_processor(), gch->reserved_region());
+
+ STWGCTimer* gc_timer = GenMarkSweep::gc_timer();
+ gc_timer->register_gc_start(os::elapsed_counter());
+
+ SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
+ gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
+
GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
+
+ gc_timer->register_gc_end(os::elapsed_counter());
+
+ gc_tracer->report_gc_end(os::elapsed_counter(), gc_timer->time_partitions());
+
SpecializationStats::print();
}
diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp
index d9310495458..2afecb68092 100644
--- a/hotspot/src/share/vm/memory/heapInspection.cpp
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp
@@ -95,7 +95,7 @@ KlassInfoEntry* KlassInfoBucket::lookup(Klass* const k) {
}
elt = elt->next();
}
- elt = new KlassInfoEntry(k, list());
+ elt = new (std::nothrow) KlassInfoEntry(k, list());
// We may be out of space to allocate the new entry.
if (elt != NULL) {
set_list(elt);
@@ -127,13 +127,15 @@ void KlassInfoTable::AllClassesFinder::do_klass(Klass* k) {
_table->lookup(k);
}
-KlassInfoTable::KlassInfoTable(int size, HeapWord* ref,
- bool need_class_stats) {
+KlassInfoTable::KlassInfoTable(bool need_class_stats) {
+ _size_of_instances_in_words = 0;
_size = 0;
- _ref = ref;
- _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
+ _ref = (HeapWord*) Universe::boolArrayKlassObj();
+ _buckets =
+ (KlassInfoBucket*) AllocateHeap(sizeof(KlassInfoBucket) * _num_buckets,
+ mtInternal, 0, AllocFailStrategy::RETURN_NULL);
if (_buckets != NULL) {
- _size = size;
+ _size = _num_buckets;
for (int index = 0; index < _size; index++) {
_buckets[index].initialize();
}
@@ -179,6 +181,7 @@ bool KlassInfoTable::record_instance(const oop obj) {
if (elt != NULL) {
elt->set_count(elt->count() + 1);
elt->set_words(elt->words() + obj->size());
+ _size_of_instances_in_words += obj->size();
return true;
} else {
return false;
@@ -192,14 +195,18 @@ void KlassInfoTable::iterate(KlassInfoClosure* cic) {
}
}
+size_t KlassInfoTable::size_of_instances_in_words() const {
+ return _size_of_instances_in_words;
+}
+
int KlassInfoHisto::sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2) {
return (*e1)->compare(*e1,*e2);
}
-KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title, int estimatedCount) :
+KlassInfoHisto::KlassInfoHisto(KlassInfoTable* cit, const char* title) :
_cit(cit),
_title(title) {
- _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(estimatedCount,true);
+ _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(_histo_initial_size, true);
}
KlassInfoHisto::~KlassInfoHisto() {
@@ -444,25 +451,37 @@ class RecordInstanceClosure : public ObjectClosure {
private:
KlassInfoTable* _cit;
size_t _missed_count;
+ BoolObjectClosure* _filter;
public:
- RecordInstanceClosure(KlassInfoTable* cit) :
- _cit(cit), _missed_count(0) {}
+ RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) :
+ _cit(cit), _missed_count(0), _filter(filter) {}
void do_object(oop obj) {
- if (!_cit->record_instance(obj)) {
- _missed_count++;
+ if (should_visit(obj)) {
+ if (!_cit->record_instance(obj)) {
+ _missed_count++;
+ }
}
}
size_t missed_count() { return _missed_count; }
+
+ private:
+ bool should_visit(oop obj) {
+ return _filter == NULL || _filter->do_object_b(obj);
+ }
};
-void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) {
+size_t HeapInspection::populate_table(KlassInfoTable* cit, BoolObjectClosure *filter) {
+ ResourceMark rm;
+
+ RecordInstanceClosure ric(cit, filter);
+ Universe::heap()->object_iterate(&ric);
+ return ric.missed_count();
+}
+
+void HeapInspection::heap_inspection(outputStream* st) {
ResourceMark rm;
- // Get some random number for ref (the hash key)
- HeapWord* ref = (HeapWord*) Universe::boolArrayKlassObj();
- CollectedHeap* heap = Universe::heap();
- bool is_shared_heap = false;
if (_print_help) {
for (int c=0; cobject_iterate(&ric);
-
- // Report if certain classes are not counted because of
- // running out of C-heap for the histogram.
- size_t missed_count = ric.missed_count();
+ size_t missed_count = populate_table(&cit);
if (missed_count != 0) {
st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT
" total instances in data below",
missed_count);
}
+
// Sort and print klass instance info
const char *title = "\n"
" num #instances #bytes class name\n"
"----------------------------------------------";
- KlassInfoHisto histo(&cit, title, KlassInfoHisto::histo_initial_size);
+ KlassInfoHisto histo(&cit, title);
HistoClosure hc(&histo);
+
cit.iterate(&hc);
+
histo.sort();
histo.print_histo_on(st, _print_class_stats, _csv_format, _columns);
} else {
st->print_cr("WARNING: Ran out of C-heap; histogram not generated");
}
st->flush();
-
- if (need_prologue && is_shared_heap) {
- SharedHeap* sh = (SharedHeap*)heap;
- sh->gc_epilogue(false /* !full */); // release all acquired locks, etc.
- }
}
class FindInstanceClosure : public ObjectClosure {
diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp
index ccf39bad5d1..c286e48658f 100644
--- a/hotspot/src/share/vm/memory/heapInspection.hpp
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_MEMORY_HEAPINSPECTION_HPP
#include "memory/allocation.inline.hpp"
+#include "memory/klassInfoClosure.hpp"
#include "oops/oop.inline.hpp"
#include "oops/annotations.hpp"
#include "utilities/macros.hpp"
@@ -203,12 +204,6 @@ class KlassInfoEntry: public CHeapObj {
const char* name() const;
};
-class KlassInfoClosure: public StackObj {
- public:
- // Called for each KlassInfoEntry.
- virtual void do_cinfo(KlassInfoEntry* cie) = 0;
-};
-
class KlassInfoBucket: public CHeapObj {
private:
KlassInfoEntry* _list;
@@ -224,6 +219,8 @@ class KlassInfoBucket: public CHeapObj {
class KlassInfoTable: public StackObj {
private:
int _size;
+ static const int _num_buckets = 20011;
+ size_t _size_of_instances_in_words;
// An aligned reference address (typically the least
// address in the perm gen) used for hashing klass
@@ -242,21 +239,19 @@ class KlassInfoTable: public StackObj {
};
public:
- // Table size
- enum {
- cit_size = 20011
- };
- KlassInfoTable(int size, HeapWord* ref, bool need_class_stats);
+ KlassInfoTable(bool need_class_stats);
~KlassInfoTable();
bool record_instance(const oop obj);
void iterate(KlassInfoClosure* cic);
bool allocation_failed() { return _buckets == NULL; }
+ size_t size_of_instances_in_words() const;
friend class KlassInfoHisto;
};
class KlassInfoHisto : public StackObj {
private:
+ static const int _histo_initial_size = 1000;
KlassInfoTable *_cit;
GrowableArray* _elements;
GrowableArray* elements() const { return _elements; }
@@ -334,11 +329,7 @@ class KlassInfoHisto : public StackObj {
}
public:
- enum {
- histo_initial_size = 1000
- };
- KlassInfoHisto(KlassInfoTable* cit, const char* title,
- int estimatedCount);
+ KlassInfoHisto(KlassInfoTable* cit, const char* title);
~KlassInfoHisto();
void add(KlassInfoEntry* cie);
void print_histo_on(outputStream* st, bool print_class_stats, bool csv_format, const char *columns);
@@ -347,6 +338,11 @@ class KlassInfoHisto : public StackObj {
#endif // INCLUDE_SERVICES
+// These declarations are needed since teh declaration of KlassInfoTable and
+// KlassInfoClosure are guarded by #if INLCUDE_SERVICES
+class KlassInfoTable;
+class KlassInfoClosure;
+
class HeapInspection : public StackObj {
bool _csv_format; // "comma separated values" format for spreadsheet.
bool _print_help;
@@ -357,8 +353,11 @@ class HeapInspection : public StackObj {
bool print_class_stats, const char *columns) :
_csv_format(csv_format), _print_help(print_help),
_print_class_stats(print_class_stats), _columns(columns) {}
- void heap_inspection(outputStream* st, bool need_prologue) NOT_SERVICES_RETURN;
+ void heap_inspection(outputStream* st) NOT_SERVICES_RETURN;
+ size_t populate_table(KlassInfoTable* cit, BoolObjectClosure* filter = NULL) NOT_SERVICES_RETURN;
static void find_instances_at_safepoint(Klass* k, GrowableArray* result) NOT_SERVICES_RETURN;
+ private:
+ void iterate_over_heap(KlassInfoTable* cit, BoolObjectClosure* filter = NULL);
};
#endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP
diff --git a/hotspot/src/share/vm/memory/klassInfoClosure.hpp b/hotspot/src/share/vm/memory/klassInfoClosure.hpp
new file mode 100644
index 00000000000..b945a19e038
--- /dev/null
+++ b/hotspot/src/share/vm/memory/klassInfoClosure.hpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
+#define SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
+
+class KlassInfoEntry;
+
+class KlassInfoClosure : public StackObj {
+ public:
+ // Called for each KlassInfoEntry.
+ virtual void do_cinfo(KlassInfoEntry* cie) = 0;
+};
+
+#endif // SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
index 70acbb1667f..cd499341c1d 100644
--- a/hotspot/src/share/vm/memory/metaspace.hpp
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
@@ -193,7 +193,10 @@ class Metaspace : public CHeapObj {
};
class MetaspaceAux : AllStatic {
+ static size_t free_chunks_total(Metaspace::MetadataType mdtype);
+ static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
+ public:
// Statistics for class space and data space in metaspace.
// These methods iterate over the classloader data graph
@@ -205,10 +208,6 @@ class MetaspaceAux : AllStatic {
// Iterates over the virtual space list.
static size_t reserved_in_bytes(Metaspace::MetadataType mdtype);
- static size_t free_chunks_total(Metaspace::MetadataType mdtype);
- static size_t free_chunks_total_in_bytes(Metaspace::MetadataType mdtype);
-
- public:
// Running sum of space in all Metachunks that has been
// allocated to a Metaspace. This is used instead of
// iterating over all the classloaders. One for each
diff --git a/hotspot/src/share/vm/memory/oopFactory.hpp b/hotspot/src/share/vm/memory/oopFactory.hpp
index bd034669043..1d14010e278 100644
--- a/hotspot/src/share/vm/memory/oopFactory.hpp
+++ b/hotspot/src/share/vm/memory/oopFactory.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
+#include "memory/referenceType.hpp"
#include "memory/universe.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.hpp"
diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp
index 20ae92ac0f9..1333c082c54 100644
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
#include "precompiled.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/systemDictionary.hpp"
+#include "gc_implementation/shared/gcTimer.hpp"
+#include "gc_implementation/shared/gcTraceTime.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/referencePolicy.hpp"
@@ -180,11 +182,20 @@ void ReferenceProcessor::update_soft_ref_master_clock() {
// past clock value.
}
-void ReferenceProcessor::process_discovered_references(
+size_t ReferenceProcessor::total_count(DiscoveredList lists[]) {
+ size_t total = 0;
+ for (uint i = 0; i < _max_num_q; ++i) {
+ total += lists[i].length();
+ }
+ return total;
+}
+
+ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc,
- AbstractRefProcTaskExecutor* task_executor) {
+ AbstractRefProcTaskExecutor* task_executor,
+ GCTimer* gc_timer) {
NOT_PRODUCT(verify_ok_to_handle_reflists());
assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
@@ -202,34 +213,43 @@ void ReferenceProcessor::process_discovered_references(
_soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
bool trace_time = PrintGCDetails && PrintReferenceGC;
+
// Soft references
+ size_t soft_count = 0;
{
- TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);
- process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
- is_alive, keep_alive, complete_gc, task_executor);
+ GCTraceTime tt("SoftReference", trace_time, false, gc_timer);
+ soft_count =
+ process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
+ is_alive, keep_alive, complete_gc, task_executor);
}
update_soft_ref_master_clock();
// Weak references
+ size_t weak_count = 0;
{
- TraceTime tt("WeakReference", trace_time, false, gclog_or_tty);
- process_discovered_reflist(_discoveredWeakRefs, NULL, true,
- is_alive, keep_alive, complete_gc, task_executor);
+ GCTraceTime tt("WeakReference", trace_time, false, gc_timer);
+ weak_count =
+ process_discovered_reflist(_discoveredWeakRefs, NULL, true,
+ is_alive, keep_alive, complete_gc, task_executor);
}
// Final references
+ size_t final_count = 0;
{
- TraceTime tt("FinalReference", trace_time, false, gclog_or_tty);
- process_discovered_reflist(_discoveredFinalRefs, NULL, false,
- is_alive, keep_alive, complete_gc, task_executor);
+ GCTraceTime tt("FinalReference", trace_time, false, gc_timer);
+ final_count =
+ process_discovered_reflist(_discoveredFinalRefs, NULL, false,
+ is_alive, keep_alive, complete_gc, task_executor);
}
// Phantom references
+ size_t phantom_count = 0;
{
- TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty);
- process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
- is_alive, keep_alive, complete_gc, task_executor);
+ GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);
+ phantom_count =
+ process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
+ is_alive, keep_alive, complete_gc, task_executor);
}
// Weak global JNI references. It would make more sense (semantically) to
@@ -238,12 +258,14 @@ void ReferenceProcessor::process_discovered_references(
// thus use JNI weak references to circumvent the phantom references and
// resurrect a "post-mortem" object.
{
- TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty);
+ GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
if (task_executor != NULL) {
task_executor->set_single_threaded_mode();
}
process_phaseJNI(is_alive, keep_alive, complete_gc);
}
+
+ return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count);
}
#ifndef PRODUCT
@@ -878,7 +900,7 @@ void ReferenceProcessor::balance_all_queues() {
balance_queues(_discoveredPhantomRefs);
}
-void
+size_t
ReferenceProcessor::process_discovered_reflist(
DiscoveredList refs_lists[],
ReferencePolicy* policy,
@@ -901,12 +923,11 @@ ReferenceProcessor::process_discovered_reflist(
must_balance) {
balance_queues(refs_lists);
}
+
+ size_t total_list_count = total_count(refs_lists);
+
if (PrintReferenceGC && PrintGCDetails) {
- size_t total = 0;
- for (uint i = 0; i < _max_num_q; ++i) {
- total += refs_lists[i].length();
- }
- gclog_or_tty->print(", %u refs", total);
+ gclog_or_tty->print(", %u refs", total_list_count);
}
// Phase 1 (soft refs only):
@@ -951,6 +972,8 @@ ReferenceProcessor::process_discovered_reflist(
is_alive, keep_alive, complete_gc);
}
}
+
+ return total_list_count;
}
void ReferenceProcessor::clean_up_discovered_references() {
@@ -1266,14 +1289,15 @@ void ReferenceProcessor::preclean_discovered_references(
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc,
- YieldClosure* yield) {
+ YieldClosure* yield,
+ GCTimer* gc_timer) {
NOT_PRODUCT(verify_ok_to_handle_reflists());
// Soft references
{
- TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
- false, gclog_or_tty);
+ GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
+ false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
@@ -1285,8 +1309,8 @@ void ReferenceProcessor::preclean_discovered_references(
// Weak references
{
- TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
- false, gclog_or_tty);
+ GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
+ false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
@@ -1298,8 +1322,8 @@ void ReferenceProcessor::preclean_discovered_references(
// Final references
{
- TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
- false, gclog_or_tty);
+ GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
+ false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
@@ -1311,8 +1335,8 @@ void ReferenceProcessor::preclean_discovered_references(
// Phantom references
{
- TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
- false, gclog_or_tty);
+ GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
+ false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
diff --git a/hotspot/src/share/vm/memory/referenceProcessor.hpp b/hotspot/src/share/vm/memory/referenceProcessor.hpp
index 1050863f44d..252cc6d6240 100644
--- a/hotspot/src/share/vm/memory/referenceProcessor.hpp
+++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,12 @@
#define SHARE_VM_MEMORY_REFERENCEPROCESSOR_HPP
#include "memory/referencePolicy.hpp"
+#include "memory/referenceProcessorStats.hpp"
+#include "memory/referenceType.hpp"
#include "oops/instanceRefKlass.hpp"
+class GCTimer;
+
// ReferenceProcessor class encapsulates the per-"collector" processing
// of java.lang.Reference objects for GC. The interface is useful for supporting
// a generational abstraction, in particular when there are multiple
@@ -204,6 +208,10 @@ public:
};
class ReferenceProcessor : public CHeapObj {
+
+ private:
+ size_t total_count(DiscoveredList lists[]);
+
protected:
// Compatibility with pre-4965777 JDK's
static bool _pending_list_uses_discovered_field;
@@ -282,13 +290,13 @@ class ReferenceProcessor : public CHeapObj {
}
// Process references with a certain reachability level.
- void process_discovered_reflist(DiscoveredList refs_lists[],
- ReferencePolicy* policy,
- bool clear_referent,
- BoolObjectClosure* is_alive,
- OopClosure* keep_alive,
- VoidClosure* complete_gc,
- AbstractRefProcTaskExecutor* task_executor);
+ size_t process_discovered_reflist(DiscoveredList refs_lists[],
+ ReferencePolicy* policy,
+ bool clear_referent,
+ BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ AbstractRefProcTaskExecutor* task_executor);
void process_phaseJNI(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
@@ -349,7 +357,8 @@ class ReferenceProcessor : public CHeapObj {
void preclean_discovered_references(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc,
- YieldClosure* yield);
+ YieldClosure* yield,
+ GCTimer* gc_timer);
// Delete entries in the discovered lists that have
// either a null referent or are not active. Such
@@ -500,12 +509,13 @@ class ReferenceProcessor : public CHeapObj {
bool discover_reference(oop obj, ReferenceType rt);
// Process references found during GC (called by the garbage collector)
- void process_discovered_references(BoolObjectClosure* is_alive,
- OopClosure* keep_alive,
- VoidClosure* complete_gc,
- AbstractRefProcTaskExecutor* task_executor);
+ ReferenceProcessorStats
+ process_discovered_references(BoolObjectClosure* is_alive,
+ OopClosure* keep_alive,
+ VoidClosure* complete_gc,
+ AbstractRefProcTaskExecutor* task_executor,
+ GCTimer *gc_timer);
- public:
// Enqueue references at end of GC (called by the garbage collector)
bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
diff --git a/hotspot/src/share/vm/memory/referenceProcessorStats.hpp b/hotspot/src/share/vm/memory/referenceProcessorStats.hpp
new file mode 100644
index 00000000000..7f4a05ba97f
--- /dev/null
+++ b/hotspot/src/share/vm/memory/referenceProcessorStats.hpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_REFERENCEPROCESSORSTATS_HPP
+#define SHARE_VM_MEMORY_REFERENCEPROCESSORSTATS_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+class ReferenceProcessor;
+
+// ReferenceProcessorStats contains statistics about how many references that
+// have been traversed when processing references during garbage collection.
+class ReferenceProcessorStats {
+ size_t _soft_count;
+ size_t _weak_count;
+ size_t _final_count;
+ size_t _phantom_count;
+
+ public:
+ ReferenceProcessorStats() :
+ _soft_count(0),
+ _weak_count(0),
+ _final_count(0),
+ _phantom_count(0) {}
+
+ ReferenceProcessorStats(size_t soft_count,
+ size_t weak_count,
+ size_t final_count,
+ size_t phantom_count) :
+ _soft_count(soft_count),
+ _weak_count(weak_count),
+ _final_count(final_count),
+ _phantom_count(phantom_count)
+ {}
+
+ size_t soft_count() const {
+ return _soft_count;
+ }
+
+ size_t weak_count() const {
+ return _weak_count;
+ }
+
+ size_t final_count() const {
+ return _final_count;
+ }
+
+ size_t phantom_count() const {
+ return _phantom_count;
+ }
+};
+#endif
diff --git a/hotspot/src/share/vm/memory/referenceType.hpp b/hotspot/src/share/vm/memory/referenceType.hpp
new file mode 100644
index 00000000000..9496e41ed9c
--- /dev/null
+++ b/hotspot/src/share/vm/memory/referenceType.hpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_REFRERENCETYPE_HPP
+#define SHARE_VM_MEMORY_REFRERENCETYPE_HPP
+
+#include "utilities/debug.hpp"
+
+// ReferenceType is used to distinguish between java/lang/ref/Reference subclasses
+
+enum ReferenceType {
+ REF_NONE, // Regular class
+ REF_OTHER, // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
+ REF_SOFT, // Subclass of java/lang/ref/SoftReference
+ REF_WEAK, // Subclass of java/lang/ref/WeakReference
+ REF_FINAL, // Subclass of java/lang/ref/FinalReference
+ REF_PHANTOM // Subclass of java/lang/ref/PhantomReference
+};
+
+#endif // SHARE_VM_MEMORY_REFRERENCETYPE_HPP
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 22af6d6906c..e98ef0c77ad 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -819,12 +819,14 @@ jint Universe::initialize_heap() {
// keep the Universe::narrow_oop_base() set in Universe::reserve_heap()
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
if (verbose) {
- tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base());
+ tty->print(", %s: "PTR_FORMAT,
+ narrow_oop_mode_to_string(HeapBasedNarrowOop),
+ Universe::narrow_oop_base());
}
} else {
Universe::set_narrow_oop_base(0);
if (verbose) {
- tty->print(", zero based Compressed Oops");
+ tty->print(", %s", narrow_oop_mode_to_string(ZeroBasedNarrowOop));
}
#ifdef _WIN64
if (!Universe::narrow_oop_use_implicit_null_checks()) {
@@ -839,7 +841,7 @@ jint Universe::initialize_heap() {
} else {
Universe::set_narrow_oop_shift(0);
if (verbose) {
- tty->print(", 32-bits Oops");
+ tty->print(", %s", narrow_oop_mode_to_string(UnscaledNarrowOop));
}
}
}
@@ -946,6 +948,33 @@ void Universe::update_heap_info_at_gc() {
}
+const char* Universe::narrow_oop_mode_to_string(Universe::NARROW_OOP_MODE mode) {
+ switch (mode) {
+ case UnscaledNarrowOop:
+ return "32-bits Oops";
+ case ZeroBasedNarrowOop:
+ return "zero based Compressed Oops";
+ case HeapBasedNarrowOop:
+ return "Compressed Oops with base";
+ }
+
+ ShouldNotReachHere();
+ return "";
+}
+
+
+Universe::NARROW_OOP_MODE Universe::narrow_oop_mode() {
+ if (narrow_oop_base() != 0) {
+ return HeapBasedNarrowOop;
+ }
+
+ if (narrow_oop_shift() != 0) {
+ return ZeroBasedNarrowOop;
+ }
+
+ return UnscaledNarrowOop;
+}
+
void universe2_init() {
EXCEPTION_MARK;
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index 6daf75d2c7f..b9ff266a008 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -253,19 +253,6 @@ class Universe: AllStatic {
return m;
}
- // Narrow Oop encoding mode:
- // 0 - Use 32-bits oops without encoding when
- // NarrowOopHeapBaseMin + heap_size < 4Gb
- // 1 - Use zero based compressed oops with encoding when
- // NarrowOopHeapBaseMin + heap_size < 32Gb
- // 2 - Use compressed oops with heap base + encoding.
- enum NARROW_OOP_MODE {
- UnscaledNarrowOop = 0,
- ZeroBasedNarrowOop = 1,
- HeapBasedNarrowOop = 2
- };
- static char* preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
- static char* preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
static void set_narrow_oop_base(address base) {
assert(UseCompressedOops, "no compressed oops?");
_narrow_oop._base = base;
@@ -380,6 +367,21 @@ class Universe: AllStatic {
static CollectedHeap* heap() { return _collectedHeap; }
// For UseCompressedOops
+ // Narrow Oop encoding mode:
+ // 0 - Use 32-bits oops without encoding when
+ // NarrowOopHeapBaseMin + heap_size < 4Gb
+ // 1 - Use zero based compressed oops with encoding when
+ // NarrowOopHeapBaseMin + heap_size < 32Gb
+ // 2 - Use compressed oops with heap base + encoding.
+ enum NARROW_OOP_MODE {
+ UnscaledNarrowOop = 0,
+ ZeroBasedNarrowOop = 1,
+ HeapBasedNarrowOop = 2
+ };
+ static NARROW_OOP_MODE narrow_oop_mode();
+ static const char* narrow_oop_mode_to_string(NARROW_OOP_MODE mode);
+ static char* preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode);
+ static char* preferred_metaspace_base(size_t heap_size, NARROW_OOP_MODE mode);
static address narrow_oop_base() { return _narrow_oop._base; }
static bool is_narrow_oop_base(void* addr) { return (narrow_oop_base() == (address)addr); }
static int narrow_oop_shift() { return _narrow_oop._shift; }
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index e158cdf3cf4..7d09f8132ce 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -26,6 +26,7 @@
#define SHARE_VM_OOPS_INSTANCEKLASS_HPP
#include "classfile/classLoaderData.hpp"
+#include "memory/referenceType.hpp"
#include "oops/annotations.hpp"
#include "oops/constMethod.hpp"
#include "oops/fieldInfo.hpp"
@@ -37,6 +38,7 @@
#include "utilities/accessFlags.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/macros.hpp"
+#include "trace/traceMacros.hpp"
// An InstanceKlass is the VM level representation of a Java class.
// It contains all information needed for at class at execution runtime.
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index f7a7334afb1..4739425568c 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -37,6 +37,7 @@
#include "oops/klass.inline.hpp"
#include "oops/oop.inline2.hpp"
#include "runtime/atomic.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/stack.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_ALL_GCS
@@ -168,7 +169,7 @@ Klass::Klass() {
set_next_sibling(NULL);
set_next_link(NULL);
set_alloc_count(0);
- TRACE_SET_KLASS_TRACE_ID(this, 0);
+ TRACE_INIT_ID(this);
set_prototype_header(markOopDesc::prototype());
set_biased_lock_revocation_count(0);
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 3222e2596e9..cd650b00156 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,6 +63,7 @@
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/timer.hpp"
+#include "trace/tracing.hpp"
#include "utilities/copy.hpp"
#ifdef TARGET_ARCH_MODEL_x86_32
# include "adfiles/ad_x86_32.hpp"
@@ -786,7 +787,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
if (failing()) return;
- print_method("Before RemoveUseless", 3);
+ print_method(PHASE_BEFORE_REMOVEUSELESS, 3);
// Remove clutter produced by parsing.
if (!failing()) {
@@ -1801,9 +1802,9 @@ void Compile::inline_string_calls(bool parse_time) {
{
ResourceMark rm;
- print_method("Before StringOpts", 3);
+ print_method(PHASE_BEFORE_STRINGOPTS, 3);
PhaseStringOpts pso(initial_gvn(), for_igvn());
- print_method("After StringOpts", 3);
+ print_method(PHASE_AFTER_STRINGOPTS, 3);
}
// now inline anything that we skipped the first time around
@@ -1958,7 +1959,7 @@ void Compile::Optimize() {
NOT_PRODUCT( verify_graph_edges(); )
- print_method("After Parsing");
+ print_method(PHASE_AFTER_PARSING);
{
// Iterative Global Value Numbering, including ideal transforms
@@ -1969,7 +1970,7 @@ void Compile::Optimize() {
igvn.optimize();
}
- print_method("Iter GVN 1", 2);
+ print_method(PHASE_ITER_GVN1, 2);
if (failing()) return;
@@ -1978,7 +1979,7 @@ void Compile::Optimize() {
inline_incrementally(igvn);
}
- print_method("Incremental Inline", 2);
+ print_method(PHASE_INCREMENTAL_INLINE, 2);
if (failing()) return;
@@ -1987,7 +1988,7 @@ void Compile::Optimize() {
// Inline valueOf() methods now.
inline_boxing_calls(igvn);
- print_method("Incremental Boxing Inline", 2);
+ print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2);
if (failing()) return;
}
@@ -2002,7 +2003,7 @@ void Compile::Optimize() {
// Cleanup graph (remove dead nodes).
TracePhase t2("idealLoop", &_t_idealLoop, true);
PhaseIdealLoop ideal_loop( igvn, false, true );
- if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
+ if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2);
if (failing()) return;
}
ConnectionGraph::do_analysis(this, &igvn);
@@ -2011,7 +2012,7 @@ void Compile::Optimize() {
// Optimize out fields loads from scalar replaceable allocations.
igvn.optimize();
- print_method("Iter GVN after EA", 2);
+ print_method(PHASE_ITER_GVN_AFTER_EA, 2);
if (failing()) return;
@@ -2022,7 +2023,7 @@ void Compile::Optimize() {
igvn.set_delay_transform(false);
igvn.optimize();
- print_method("Iter GVN after eliminating allocations and locks", 2);
+ print_method(PHASE_ITER_GVN_AFTER_ELIMINATION, 2);
if (failing()) return;
}
@@ -2038,7 +2039,7 @@ void Compile::Optimize() {
TracePhase t2("idealLoop", &_t_idealLoop, true);
PhaseIdealLoop ideal_loop( igvn, true );
loop_opts_cnt--;
- if (major_progress()) print_method("PhaseIdealLoop 1", 2);
+ if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2);
if (failing()) return;
}
// Loop opts pass if partial peeling occurred in previous pass
@@ -2046,7 +2047,7 @@ void Compile::Optimize() {
TracePhase t3("idealLoop", &_t_idealLoop, true);
PhaseIdealLoop ideal_loop( igvn, false );
loop_opts_cnt--;
- if (major_progress()) print_method("PhaseIdealLoop 2", 2);
+ if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2);
if (failing()) return;
}
// Loop opts pass for loop-unrolling before CCP
@@ -2054,7 +2055,7 @@ void Compile::Optimize() {
TracePhase t4("idealLoop", &_t_idealLoop, true);
PhaseIdealLoop ideal_loop( igvn, false );
loop_opts_cnt--;
- if (major_progress()) print_method("PhaseIdealLoop 3", 2);
+ if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2);
}
if (!failing()) {
// Verify that last round of loop opts produced a valid graph
@@ -2071,7 +2072,7 @@ void Compile::Optimize() {
TracePhase t2("ccp", &_t_ccp, true);
ccp.do_transform();
}
- print_method("PhaseCPP 1", 2);
+ print_method(PHASE_CPP1, 2);
assert( true, "Break here to ccp.dump_old2new_map()");
@@ -2082,7 +2083,7 @@ void Compile::Optimize() {
igvn.optimize();
}
- print_method("Iter GVN 2", 2);
+ print_method(PHASE_ITER_GVN2, 2);
if (failing()) return;
@@ -2095,7 +2096,7 @@ void Compile::Optimize() {
assert( cnt++ < 40, "infinite cycle in loop optimization" );
PhaseIdealLoop ideal_loop( igvn, true);
loop_opts_cnt--;
- if (major_progress()) print_method("PhaseIdealLoop iterations", 2);
+ if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2);
if (failing()) return;
}
}
@@ -2128,7 +2129,7 @@ void Compile::Optimize() {
}
}
- print_method("Optimize finished", 2);
+ print_method(PHASE_OPTIMIZE_FINISHED, 2);
}
@@ -2176,7 +2177,7 @@ void Compile::Code_Gen() {
cfg.GlobalCodeMotion(m,unique(),proj_list);
if (failing()) return;
- print_method("Global code motion", 2);
+ print_method(PHASE_GLOBAL_CODE_MOTION, 2);
NOT_PRODUCT( verify_graph_edges(); )
@@ -2229,7 +2230,7 @@ void Compile::Code_Gen() {
Output();
}
- print_method("Final Code");
+ print_method(PHASE_FINAL_CODE);
// He's dead, Jim.
_cfg = (PhaseCFG*)0xdeadbeef;
@@ -3316,8 +3317,16 @@ void Compile::record_failure(const char* reason) {
// Record the first failure reason.
_failure_reason = reason;
}
+
+ EventCompilerFailure event;
+ if (event.should_commit()) {
+ event.set_compileID(Compile::compile_id());
+ event.set_failure(reason);
+ event.commit();
+ }
+
if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
- C->print_method(_failure_reason);
+ C->print_method(PHASE_FAILURE);
}
_root = NULL; // flush the graph, too
}
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index e0f1cd23d16..60787464bd0 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,10 +36,12 @@
#include "libadt/vectset.hpp"
#include "memory/resourceArea.hpp"
#include "opto/idealGraphPrinter.hpp"
+#include "opto/phasetype.hpp"
#include "opto/phase.hpp"
#include "opto/regmask.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/vmThread.hpp"
+#include "trace/tracing.hpp"
class Block;
class Bundle;
@@ -322,6 +324,7 @@ class Compile : public Phase {
IdealGraphPrinter* _printer;
#endif
+
// Node management
uint _unique; // Counter for unique Node indices
VectorSet _dead_node_list; // Set of dead nodes
@@ -573,17 +576,43 @@ class Compile : public Phase {
bool has_method_handle_invokes() const { return _has_method_handle_invokes; }
void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; }
+ jlong _latest_stage_start_counter;
+
void begin_method() {
#ifndef PRODUCT
if (_printer) _printer->begin_method(this);
#endif
+ C->_latest_stage_start_counter = os::elapsed_counter();
}
- void print_method(const char * name, int level = 1) {
+
+ void print_method(CompilerPhaseType cpt, int level = 1) {
+ EventCompilerPhase event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_starttime(C->_latest_stage_start_counter);
+ event.set_endtime(os::elapsed_counter());
+ event.set_phase((u1) cpt);
+ event.set_compileID(C->_compile_id);
+ event.set_phaseLevel(level);
+ event.commit();
+ }
+
+
#ifndef PRODUCT
- if (_printer) _printer->print_method(this, name, level);
+ if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level);
#endif
+ C->_latest_stage_start_counter = os::elapsed_counter();
}
- void end_method() {
+
+ void end_method(int level = 1) {
+ EventCompilerPhase event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_starttime(C->_latest_stage_start_counter);
+ event.set_endtime(os::elapsed_counter());
+ event.set_phase((u1) PHASE_END);
+ event.set_compileID(C->_compile_id);
+ event.set_phaseLevel(level);
+ event.commit();
+ }
#ifndef PRODUCT
if (_printer) _printer->end_method();
#endif
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index 96f0011b3b2..fd561a0c20c 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -277,7 +277,7 @@ bool ConnectionGraph::compute_escape() {
// scalar replaceable objects.
split_unique_types(alloc_worklist);
if (C->failing()) return false;
- C->print_method("After Escape Analysis", 2);
+ C->print_method(PHASE_AFTER_EA, 2);
#ifdef ASSERT
} else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 609b7022608..728d892534b 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
#include "opto/subnode.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "trace/traceMacros.hpp"
class LibraryIntrinsic : public InlineCallGenerator {
// Extend the set of intrinsics known to the runtime:
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
index c323d02f842..ab05d186ba4 100644
--- a/hotspot/src/share/vm/opto/loopnode.cpp
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -440,7 +440,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
// ---- SUCCESS! Found A Trip-Counted Loop! -----
//
assert(x->Opcode() == Op_Loop, "regular loops only");
- C->print_method("Before CountedLoop", 3);
+ C->print_method(PHASE_BEFORE_CLOOPS, 3);
Node *hook = new (C) Node(6);
@@ -791,7 +791,7 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
}
#endif
- C->print_method("After CountedLoop", 3);
+ C->print_method(PHASE_AFTER_CLOOPS, 3);
return true;
}
@@ -2164,7 +2164,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts)
// Split shared headers and insert loop landing pads.
// Do not bother doing this on the Root loop of course.
if( !_verify_me && !_verify_only && _ltree_root->_child ) {
- C->print_method("Before beautify loops", 3);
+ C->print_method(PHASE_BEFORE_BEAUTIFY_LOOPS, 3);
if( _ltree_root->_child->beautify_loops( this ) ) {
// Re-build loop tree!
_ltree_root->_child = NULL;
@@ -2178,7 +2178,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts)
// Reset loop nesting depth
_ltree_root->set_nest( 0 );
- C->print_method("After beautify loops", 3);
+ C->print_method(PHASE_AFTER_BEAUTIFY_LOOPS, 3);
}
}
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 91b4448c9bc..4f3aad763f5 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -317,7 +317,7 @@ void Matcher::match( ) {
find_shared( C->root() );
find_shared( C->top() );
- C->print_method("Before Matching");
+ C->print_method(PHASE_BEFORE_MATCHING);
// Create new ideal node ConP #NULL even if it does exist in old space
// to avoid false sharing if the corresponding mach node is not used.
@@ -1848,7 +1848,7 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
for( uint i=0; kid != NULL && i<2; kid = s->_kids[1], i++ ) { // binary tree
int newrule;
- if( i == 0 )
+ if( i == 0)
newrule = kid->_rule[_leftOp[rule]];
else
newrule = kid->_rule[_rightOp[rule]];
diff --git a/hotspot/src/share/vm/opto/phasetype.hpp b/hotspot/src/share/vm/opto/phasetype.hpp
new file mode 100644
index 00000000000..ba769d41015
--- /dev/null
+++ b/hotspot/src/share/vm/opto/phasetype.hpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_OPTO_PHASETYPE_HPP
+#define SHARE_VM_OPTO_PHASETYPE_HPP
+
+enum CompilerPhaseType {
+ PHASE_BEFORE_STRINGOPTS,
+ PHASE_AFTER_STRINGOPTS,
+ PHASE_BEFORE_REMOVEUSELESS,
+ PHASE_AFTER_PARSING,
+ PHASE_ITER_GVN1,
+ PHASE_PHASEIDEAL_BEFORE_EA,
+ PHASE_ITER_GVN_AFTER_EA,
+ PHASE_ITER_GVN_AFTER_ELIMINATION,
+ PHASE_PHASEIDEALLOOP1,
+ PHASE_PHASEIDEALLOOP2,
+ PHASE_PHASEIDEALLOOP3,
+ PHASE_CPP1,
+ PHASE_ITER_GVN2,
+ PHASE_PHASEIDEALLOOP_ITERATIONS,
+ PHASE_OPTIMIZE_FINISHED,
+ PHASE_GLOBAL_CODE_MOTION,
+ PHASE_FINAL_CODE,
+ PHASE_AFTER_EA,
+ PHASE_BEFORE_CLOOPS,
+ PHASE_AFTER_CLOOPS,
+ PHASE_BEFORE_BEAUTIFY_LOOPS,
+ PHASE_AFTER_BEAUTIFY_LOOPS,
+ PHASE_BEFORE_MATCHING,
+ PHASE_INCREMENTAL_INLINE,
+ PHASE_INCREMENTAL_BOXING_INLINE,
+ PHASE_END,
+ PHASE_FAILURE,
+
+ PHASE_NUM_TYPES
+};
+
+class CompilerPhaseTypeHelper {
+ public:
+ static const char* to_string(CompilerPhaseType cpt) {
+ switch (cpt) {
+ case PHASE_BEFORE_STRINGOPTS: return "Before StringOpts";
+ case PHASE_AFTER_STRINGOPTS: return "After StringOpts";
+ case PHASE_BEFORE_REMOVEUSELESS: return "Before RemoveUseless";
+ case PHASE_AFTER_PARSING: return "After Parsing";
+ case PHASE_ITER_GVN1: return "Iter GVN 1";
+ case PHASE_PHASEIDEAL_BEFORE_EA: return "PhaseIdealLoop before EA";
+ case PHASE_ITER_GVN_AFTER_EA: return "Iter GVN after EA";
+ case PHASE_ITER_GVN_AFTER_ELIMINATION: return "Iter GVN after eliminating allocations and locks";
+ case PHASE_PHASEIDEALLOOP1: return "PhaseIdealLoop 1";
+ case PHASE_PHASEIDEALLOOP2: return "PhaseIdealLoop 2";
+ case PHASE_PHASEIDEALLOOP3: return "PhaseIdealLoop 3";
+ case PHASE_CPP1: return "PhaseCPP 1";
+ case PHASE_ITER_GVN2: return "Iter GVN 2";
+ case PHASE_PHASEIDEALLOOP_ITERATIONS: return "PhaseIdealLoop iterations";
+ case PHASE_OPTIMIZE_FINISHED: return "Optimize finished";
+ case PHASE_GLOBAL_CODE_MOTION: return "Global code motion";
+ case PHASE_FINAL_CODE: return "Final Code";
+ case PHASE_AFTER_EA: return "After Escape Analysis";
+ case PHASE_BEFORE_CLOOPS: return "Before CountedLoop";
+ case PHASE_AFTER_CLOOPS: return "After CountedLoop";
+ case PHASE_BEFORE_BEAUTIFY_LOOPS: return "Before beautify loops";
+ case PHASE_AFTER_BEAUTIFY_LOOPS: return "After beautify loops";
+ case PHASE_BEFORE_MATCHING: return "Before Matching";
+ case PHASE_INCREMENTAL_INLINE: return "Incremental Inline";
+ case PHASE_INCREMENTAL_BOXING_INLINE: return "Incremental Boxing Inline";
+ case PHASE_END: return "End";
+ case PHASE_FAILURE: return "Failure";
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+ }
+};
+
+#endif //SHARE_VM_OPTO_PHASETYPE_HPP
diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp
index 118fe9c1bde..d4be22e6cd0 100644
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp
@@ -26,7 +26,6 @@
// or if the user passes USE_PRECOMPILED_HEADER=0 to the makefiles.
#ifndef DONT_USE_PRECOMPILED_HEADER
-
# include "asm/assembler.hpp"
# include "asm/assembler.inline.hpp"
# include "asm/codeBuffer.hpp"
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index 2c81df1ab4e..85f3e2e0e41 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -74,7 +74,6 @@
#include "runtime/vm_operations.hpp"
#include "services/runtimeService.hpp"
#include "trace/tracing.hpp"
-#include "trace/traceEventTypes.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
@@ -5014,6 +5013,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
#ifndef PRODUCT
+#include "gc_implementation/shared/gcTimer.hpp"
#include "gc_interface/collectedHeap.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/heapRegionRemSet.hpp"
@@ -5031,6 +5031,7 @@ void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) {
tty->print_cr("Running internal VM tests");
run_unit_test(GlobalDefinitions::test_globals());
+ run_unit_test(GCTimerAllTest::all());
run_unit_test(arrayOopDesc::test_max_array_length());
run_unit_test(CollectedHeap::test_is_in());
run_unit_test(QuickSort::test_quick_sort());
@@ -5131,9 +5132,11 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
JvmtiExport::post_thread_start(thread);
}
- EVENT_BEGIN(TraceEventThreadStart, event);
- EVENT_COMMIT(event,
- EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+ EventThreadStart event;
+ if (event.should_commit()) {
+ event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.commit();
+ }
// Check if we should compile all classes on bootclasspath
NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
@@ -5334,9 +5337,11 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae
JvmtiExport::post_thread_start(thread);
}
- EVENT_BEGIN(TraceEventThreadStart, event);
- EVENT_COMMIT(event,
- EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+ EventThreadStart event;
+ if (event.should_commit()) {
+ event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.commit();
+ }
*(JNIEnv**)penv = thread->jni_environment();
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 733d04a1b69..8df99043dbc 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -59,6 +59,7 @@
#include "services/attachListener.hpp"
#include "services/management.hpp"
#include "services/threadService.hpp"
+#include "trace/tracing.hpp"
#include "utilities/copy.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
@@ -2999,6 +3000,8 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
millis);
#endif /* USDT2 */
+ EventThreadSleep event;
+
if (millis == 0) {
// When ConvertSleepToYield is on, this matches the classic VM implementation of
// JVM_Sleep. Critical for similar threading behaviour (Win32)
@@ -3019,6 +3022,10 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
// An asynchronous exception (e.g., ThreadDeathException) could have been thrown on
// us while we were sleeping. We do not overwrite those.
if (!HAS_PENDING_EXCEPTION) {
+ if (event.should_commit()) {
+ event.set_time(millis);
+ event.commit();
+ }
#ifndef USDT2
HS_DTRACE_PROBE1(hotspot, thread__sleep__end,1);
#else /* USDT2 */
@@ -3032,6 +3039,10 @@ JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
}
thread->osthread()->set_state(old_state);
}
+ if (event.should_commit()) {
+ event.set_time(millis);
+ event.commit();
+ }
#ifndef USDT2
HS_DTRACE_PROBE1(hotspot, thread__sleep__end,0);
#else /* USDT2 */
diff --git a/hotspot/src/share/vm/prims/jvmtiGen.java b/hotspot/src/share/vm/prims/jvmtiGen.java
index 74191ed6070..f2cdbe9ae72 100644
--- a/hotspot/src/share/vm/prims/jvmtiGen.java
+++ b/hotspot/src/share/vm/prims/jvmtiGen.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@ import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
-
// For write operation
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
@@ -129,6 +128,7 @@ public class jvmtiGen
factory.setNamespaceAware(true);
factory.setValidating(true);
+ factory.setXIncludeAware(true);
try {
File datafile = new File(inFileName);
diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
index c569b8fdcb4..6f8b41297a4 100644
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
@@ -360,19 +360,14 @@ void VM_ChangeBreakpoints::doit() {
case CLEAR_BREAKPOINT:
_breakpoints->clear_at_safepoint(*_bp);
break;
- case CLEAR_ALL_BREAKPOINT:
- _breakpoints->clearall_at_safepoint();
- break;
default:
assert(false, "Unknown operation");
}
}
void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
- // This operation keeps breakpoints alive
- if (_breakpoints != NULL) {
- _breakpoints->oops_do(f);
- }
+ // The JvmtiBreakpoints in _breakpoints will be visited via
+ // JvmtiExport::oops_do.
if (_bp != NULL) {
_bp->oops_do(f);
}
@@ -433,23 +428,13 @@ void JvmtiBreakpoints::clear_at_safepoint(JvmtiBreakpoint& bp) {
}
}
-void JvmtiBreakpoints::clearall_at_safepoint() {
- assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-
- int len = _bps.length();
- for (int i=0; iparker(), (int) isAbsolute, time);
#else /* USDT2 */
@@ -1218,6 +1220,13 @@ UNSAFE_ENTRY(void, Unsafe_Park(JNIEnv *env, jobject unsafe, jboolean isAbsolute,
HOTSPOT_THREAD_PARK_END(
(uintptr_t) thread->parker());
#endif /* USDT2 */
+ if (event.should_commit()) {
+ oop obj = thread->current_park_blocker();
+ event.set_klass(obj ? obj->klass() : NULL);
+ event.set_timeout(time);
+ event.set_address(obj ? (TYPE_ADDRESS) (uintptr_t) obj : 0);
+ event.commit();
+ }
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_Unpark(JNIEnv *env, jobject unsafe, jobject jthread))
diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp
index 1baa38fb6c3..87581ab8da1 100644
--- a/hotspot/src/share/vm/runtime/frame.hpp
+++ b/hotspot/src/share/vm/runtime/frame.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,6 +134,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
bool is_interpreted_frame() const;
bool is_java_frame() const;
bool is_entry_frame() const; // Java frame called from C?
+ bool is_stub_frame() const;
bool is_ignored_frame() const;
bool is_native_frame() const;
bool is_runtime_frame() const;
diff --git a/hotspot/src/share/vm/runtime/frame.inline.hpp b/hotspot/src/share/vm/runtime/frame.inline.hpp
index 7c1890438f8..e00d2cf9d09 100644
--- a/hotspot/src/share/vm/runtime/frame.inline.hpp
+++ b/hotspot/src/share/vm/runtime/frame.inline.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,10 @@ inline bool frame::is_entry_frame() const {
return StubRoutines::returns_to_call_stub(pc());
}
+inline bool frame::is_stub_frame() const {
+ return StubRoutines::is_stub_code(pc()) || (_cb != NULL && _cb->is_adapter_blob());
+}
+
inline bool frame::is_first_frame() const {
return is_entry_frame() && entry_frame_is_first();
}
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index aec1736a43c..b1adcf7fce1 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -2311,6 +2311,10 @@ class CommandLineFlags {
"Print diagnostic message when GC is stalled" \
"by JNI critical section") \
\
+ experimental(double, ObjectCountCutOffPercent, 0.5, \
+ "The percentage of the used heap that the instances of a class " \
+ "must occupy for the class to generate a trace event.") \
+ \
/* GC log rotation setting */ \
\
product(bool, UseGCLogFileRotation, false, \
@@ -3688,7 +3692,13 @@ class CommandLineFlags {
experimental(uintx, ArrayAllocatorMallocLimit, \
SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx), \
"Allocation less than this value will be allocated " \
- "using malloc. Larger allocations will use mmap.")
+ "using malloc. Larger allocations will use mmap.") \
+ \
+ product(bool, EnableTracing, false, \
+ "Enable event-based tracing") \
+ product(bool, UseLockedTracing, false, \
+ "Use locked-tracing when doing event-based tracing")
+
/*
* Macros for factoring of globals
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index f9be22344b1..7795fb92a87 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,6 @@
#include "services/memReporter.hpp"
#include "services/memTracker.hpp"
#include "trace/tracing.hpp"
-#include "trace/traceEventTypes.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/histogram.hpp"
@@ -528,9 +527,12 @@ void before_exit(JavaThread * thread) {
JvmtiExport::post_thread_end(thread);
}
- EVENT_BEGIN(TraceEventThreadEnd, event);
- EVENT_COMMIT(event,
- EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(thread->threadObj())));
+
+ EventThreadEnd event;
+ if (event.should_commit()) {
+ event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
+ event.commit();
+ }
// Always call even when there are not JVMTI environments yet, since environments
// may be attached late and JVMTI must track phases of VM execution
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp
index c386ae8f4e8..14e65081d62 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -270,13 +270,12 @@ void mutex_init() {
def(MethodCompileQueue_lock , Monitor, nonleaf+4, true );
def(Debug2_lock , Mutex , nonleaf+4, true );
def(Debug3_lock , Mutex , nonleaf+4, true );
- def(ProfileVM_lock , Monitor, nonleaf+4, false); // used for profiling of the VMThread
+ def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread
def(CompileThread_lock , Monitor, nonleaf+5, false );
- def(JfrQuery_lock , Monitor, nonleaf, true); // JFR locks, keep these in consecutive order
- def(JfrMsg_lock , Monitor, nonleaf+2, true);
- def(JfrBuffer_lock , Mutex, nonleaf+3, true);
- def(JfrStream_lock , Mutex, nonleaf+4, true);
+ def(JfrMsg_lock , Monitor, leaf, true);
+ def(JfrBuffer_lock , Mutex, nonleaf+1, true);
+ def(JfrStream_lock , Mutex, nonleaf+2, true);
def(PeriodicTask_lock , Monitor, nonleaf+5, true);
}
diff --git a/hotspot/src/share/vm/runtime/objectMonitor.cpp b/hotspot/src/share/vm/runtime/objectMonitor.cpp
index 27b6243a503..523887502ca 100644
--- a/hotspot/src/share/vm/runtime/objectMonitor.cpp
+++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp
@@ -36,7 +36,10 @@
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#include "services/threadService.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/dtrace.hpp"
+#include "utilities/macros.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "os_linux.inline.hpp"
@@ -371,6 +374,8 @@ void ATTR ObjectMonitor::enter(TRAPS) {
// Ensure the object-monitor relationship remains stable while there's contention.
Atomic::inc_ptr(&_count);
+ EventJavaMonitorEnter event;
+
{ // Change java thread status to indicate blocked on monitor enter.
JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this);
@@ -402,7 +407,7 @@ void ATTR ObjectMonitor::enter(TRAPS) {
//
_recursions = 0 ;
_succ = NULL ;
- exit (Self) ;
+ exit (false, Self) ;
jt->java_suspend_self();
}
@@ -435,6 +440,14 @@ void ATTR ObjectMonitor::enter(TRAPS) {
if (JvmtiExport::should_post_monitor_contended_entered()) {
JvmtiExport::post_monitor_contended_entered(jt, this);
}
+
+ if (event.should_commit()) {
+ event.set_klass(((oop)this->object())->klass());
+ event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid);
+ event.set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
+ event.commit();
+ }
+
if (ObjectMonitor::_sync_ContendedLockAttempts != NULL) {
ObjectMonitor::_sync_ContendedLockAttempts->inc() ;
}
@@ -917,7 +930,7 @@ void ObjectMonitor::UnlinkAfterAcquire (Thread * Self, ObjectWaiter * SelfNode)
// Both impinge on OS scalability. Given that, at most one thread parked on
// a monitor will use a timer.
-void ATTR ObjectMonitor::exit(TRAPS) {
+void ATTR ObjectMonitor::exit(bool not_suspended, TRAPS) {
Thread * Self = THREAD ;
if (THREAD != _owner) {
if (THREAD->is_lock_owned((address) _owner)) {
@@ -954,6 +967,14 @@ void ATTR ObjectMonitor::exit(TRAPS) {
_Responsible = NULL ;
}
+#if INCLUDE_TRACE
+ // get the owner's thread id for the MonitorEnter event
+ // if it is enabled and the thread isn't suspended
+ if (not_suspended && Tracing::is_event_enabled(TraceJavaMonitorEnterEvent)) {
+ _previous_owner_tid = SharedRuntime::get_java_tid(Self);
+ }
+#endif
+
for (;;) {
assert (THREAD == _owner, "invariant") ;
@@ -1343,7 +1364,7 @@ intptr_t ObjectMonitor::complete_exit(TRAPS) {
guarantee(Self == _owner, "complete_exit not owner");
intptr_t save = _recursions; // record the old recursion count
_recursions = 0; // set the recursion level to be 0
- exit (Self) ; // exit the monitor
+ exit (true, Self) ; // exit the monitor
guarantee (_owner != Self, "invariant");
return save;
}
@@ -1397,6 +1418,20 @@ static int Adjust (volatile int * adr, int dx) {
for (v = *adr ; Atomic::cmpxchg (v + dx, adr, v) != v; v = *adr) ;
return v ;
}
+
+// helper method for posting a monitor wait event
+void ObjectMonitor::post_monitor_wait_event(EventJavaMonitorWait* event,
+ jlong notifier_tid,
+ jlong timeout,
+ bool timedout) {
+ event->set_klass(((oop)this->object())->klass());
+ event->set_timeout((TYPE_ULONG)timeout);
+ event->set_address((TYPE_ADDRESS)(uintptr_t)(this->object_addr()));
+ event->set_notifier((TYPE_OSTHREAD)notifier_tid);
+ event->set_timedOut((TYPE_BOOLEAN)timedout);
+ event->commit();
+}
+
// -----------------------------------------------------------------------------
// Wait/Notify/NotifyAll
//
@@ -1412,6 +1447,8 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
// Throw IMSX or IEX.
CHECK_OWNER();
+ EventJavaMonitorWait event;
+
// check for a pending interrupt
if (interruptible && Thread::is_interrupted(Self, true) && !HAS_PENDING_EXCEPTION) {
// post monitor waited event. Note that this is past-tense, we are done waiting.
@@ -1420,10 +1457,14 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
// wait was not timed out due to thread interrupt.
JvmtiExport::post_monitor_waited(jt, this, false);
}
+ if (event.should_commit()) {
+ post_monitor_wait_event(&event, 0, millis, false);
+ }
TEVENT (Wait - Throw IEX) ;
THROW(vmSymbols::java_lang_InterruptedException());
return ;
}
+
TEVENT (Wait) ;
assert (Self->_Stalled == 0, "invariant") ;
@@ -1455,7 +1496,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
intptr_t save = _recursions; // record the old recursion count
_waiters++; // increment the number of waiters
_recursions = 0; // set the recursion level to be 1
- exit (Self) ; // exit the monitor
+ exit (true, Self) ; // exit the monitor
guarantee (_owner != Self, "invariant") ;
// As soon as the ObjectMonitor's ownership is dropped in the exit()
@@ -1555,6 +1596,11 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
if (JvmtiExport::should_post_monitor_waited()) {
JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT);
}
+
+ if (event.should_commit()) {
+ post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT);
+ }
+
OrderAccess::fence() ;
assert (Self->_Stalled != 0, "invariant") ;
@@ -1634,6 +1680,8 @@ void ObjectMonitor::notify(TRAPS) {
iterator->TState = ObjectWaiter::TS_ENTER ;
}
iterator->_notified = 1 ;
+ Thread * Self = THREAD;
+ iterator->_notifier_tid = Self->osthread()->thread_id();
ObjectWaiter * List = _EntryList ;
if (List != NULL) {
@@ -1758,6 +1806,8 @@ void ObjectMonitor::notifyAll(TRAPS) {
guarantee (iterator->TState == ObjectWaiter::TS_WAIT, "invariant") ;
guarantee (iterator->_notified == 0, "invariant") ;
iterator->_notified = 1 ;
+ Thread * Self = THREAD;
+ iterator->_notifier_tid = Self->osthread()->thread_id();
if (Policy != 4) {
iterator->TState = ObjectWaiter::TS_ENTER ;
}
diff --git a/hotspot/src/share/vm/runtime/objectMonitor.hpp b/hotspot/src/share/vm/runtime/objectMonitor.hpp
index df4b0279cc0..f0e6ed5f8d5 100644
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
#include "runtime/park.hpp"
#include "runtime/perfData.hpp"
-
// ObjectWaiter serves as a "proxy" or surrogate thread.
// TODO-FIXME: Eliminate ObjectWaiter and use the thread-specific
// ParkEvent instead. Beware, however, that the JVMTI code
@@ -43,6 +42,7 @@ class ObjectWaiter : public StackObj {
ObjectWaiter * volatile _next;
ObjectWaiter * volatile _prev;
Thread* _thread;
+ jlong _notifier_tid;
ParkEvent * _event;
volatile int _notified ;
volatile TStates TState ;
@@ -55,6 +55,9 @@ class ObjectWaiter : public StackObj {
void wait_reenter_end(ObjectMonitor *mon);
};
+// forward declaration to avoid include tracing.hpp
+class EventJavaMonitorWait;
+
// WARNING:
// This is a very sensitive and fragile class. DO NOT make any
// change unless you are fully aware of the underlying semantics.
@@ -151,6 +154,7 @@ class ObjectMonitor {
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
+ _previous_owner_tid = 0;
}
~ObjectMonitor() {
@@ -192,7 +196,7 @@ public:
bool try_enter (TRAPS) ;
void enter(TRAPS);
- void exit(TRAPS);
+ void exit(bool not_suspended, TRAPS);
void wait(jlong millis, bool interruptable, TRAPS);
void notify(TRAPS);
void notifyAll(TRAPS);
@@ -218,6 +222,10 @@ public:
void ctAsserts () ;
void ExitEpilog (Thread * Self, ObjectWaiter * Wakee) ;
bool ExitSuspendEquivalent (JavaThread * Self) ;
+ void post_monitor_wait_event(EventJavaMonitorWait * event,
+ jlong notifier_tid,
+ jlong timeout,
+ bool timedout);
private:
friend class ObjectSynchronizer;
@@ -240,6 +248,7 @@ public:
protected: // protected for jvmtiRawMonitor
void * volatile _owner; // pointer to owning thread OR BasicLock
+ volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
volatile intptr_t _recursions; // recursion count, 0 for first entry
private:
int OwnerIsThread ; // _owner is (Thread *) vs SP/BasicLock
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index e9c5b261206..7775d9410d5 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -265,8 +265,7 @@ static void signal_thread_entry(JavaThread* thread, TRAPS) {
VMThread::execute(&op1);
Universe::print_heap_at_SIGBREAK();
if (PrintClassHistogram) {
- VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */,
- true /* need_prologue */);
+ VM_GC_HeapInspection op1(gclog_or_tty, true /* force full GC before heap inspection */);
VMThread::execute(&op1);
}
if (JvmtiExport::should_post_data_dump()) {
@@ -1444,11 +1443,16 @@ int os::get_line_chars(int fd, char* buf, const size_t bsize){
return (int) i;
}
+void os::SuspendedThreadTask::run() {
+ assert(Threads_lock->owned_by_self() || (_thread == VMThread::vm_thread()), "must have threads lock to call this");
+ internal_do_task();
+ _done = true;
+}
+
bool os::create_stack_guard_pages(char* addr, size_t bytes) {
return os::pd_create_stack_guard_pages(addr, bytes);
}
-
char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
char* result = pd_reserve_memory(bytes, addr, alignment_hint);
if (result != NULL) {
@@ -1551,3 +1555,19 @@ void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
pd_realign_memory(addr, bytes, alignment_hint);
}
+#ifndef TARGET_OS_FAMILY_windows
+/* try to switch state from state "from" to state "to"
+ * returns the state set after the method is complete
+ */
+os::SuspendResume::State os::SuspendResume::switch_state(os::SuspendResume::State from,
+ os::SuspendResume::State to)
+{
+ os::SuspendResume::State result =
+ (os::SuspendResume::State) Atomic::cmpxchg((jint) to, (jint *) &_state, (jint) from);
+ if (result == from) {
+ // success
+ return to;
+ }
+ return result;
+}
+#endif
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index 51fc54ddc1a..3f2554399f4 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -781,6 +781,104 @@ class os: AllStatic {
// ResumeThread call)
static void pause();
+ class SuspendedThreadTaskContext {
+ public:
+ SuspendedThreadTaskContext(Thread* thread, void *ucontext) : _thread(thread), _ucontext(ucontext) {}
+ Thread* thread() const { return _thread; }
+ void* ucontext() const { return _ucontext; }
+ private:
+ Thread* _thread;
+ void* _ucontext;
+ };
+
+ class SuspendedThreadTask {
+ public:
+ SuspendedThreadTask(Thread* thread) : _thread(thread), _done(false) {}
+ virtual ~SuspendedThreadTask() {}
+ void run();
+ bool is_done() { return _done; }
+ virtual void do_task(const SuspendedThreadTaskContext& context) = 0;
+ protected:
+ private:
+ void internal_do_task();
+ Thread* _thread;
+ bool _done;
+ };
+
+#ifndef TARGET_OS_FAMILY_windows
+ // Suspend/resume support
+ // Protocol:
+ //
+ // a thread starts in SR_RUNNING
+ //
+ // SR_RUNNING can go to
+ // * SR_SUSPEND_REQUEST when the WatcherThread wants to suspend it
+ // SR_SUSPEND_REQUEST can go to
+ // * SR_RUNNING if WatcherThread decides it waited for SR_SUSPENDED too long (timeout)
+ // * SR_SUSPENDED if the stopped thread receives the signal and switches state
+ // SR_SUSPENDED can go to
+ // * SR_WAKEUP_REQUEST when the WatcherThread has done the work and wants to resume
+ // SR_WAKEUP_REQUEST can go to
+ // * SR_RUNNING when the stopped thread receives the signal
+ // * SR_WAKEUP_REQUEST on timeout (resend the signal and try again)
+ class SuspendResume {
+ public:
+ enum State {
+ SR_RUNNING,
+ SR_SUSPEND_REQUEST,
+ SR_SUSPENDED,
+ SR_WAKEUP_REQUEST
+ };
+
+ private:
+ volatile State _state;
+
+ private:
+ /* try to switch state from state "from" to state "to"
+ * returns the state set after the method is complete
+ */
+ State switch_state(State from, State to);
+
+ public:
+ SuspendResume() : _state(SR_RUNNING) { }
+
+ State state() const { return _state; }
+
+ State request_suspend() {
+ return switch_state(SR_RUNNING, SR_SUSPEND_REQUEST);
+ }
+
+ State cancel_suspend() {
+ return switch_state(SR_SUSPEND_REQUEST, SR_RUNNING);
+ }
+
+ State suspended() {
+ return switch_state(SR_SUSPEND_REQUEST, SR_SUSPENDED);
+ }
+
+ State request_wakeup() {
+ return switch_state(SR_SUSPENDED, SR_WAKEUP_REQUEST);
+ }
+
+ State running() {
+ return switch_state(SR_WAKEUP_REQUEST, SR_RUNNING);
+ }
+
+ bool is_running() const {
+ return _state == SR_RUNNING;
+ }
+
+ bool is_suspend_request() const {
+ return _state == SR_SUSPEND_REQUEST;
+ }
+
+ bool is_suspended() const {
+ return _state == SR_SUSPENDED;
+ }
+ };
+#endif
+
+
protected:
static long _rand_seed; // seed for random number generator
static int _processor_count; // number of processors
diff --git a/hotspot/src/share/vm/runtime/perfData.cpp b/hotspot/src/share/vm/runtime/perfData.cpp
index 777ea27f906..60b71fde184 100644
--- a/hotspot/src/share/vm/runtime/perfData.cpp
+++ b/hotspot/src/share/vm/runtime/perfData.cpp
@@ -323,6 +323,10 @@ void PerfDataManager::add_item(PerfData* p, bool sampled) {
}
}
+PerfData* PerfDataManager::find_by_name(const char* name) {
+ return _all->find_by_name(name);
+}
+
PerfDataList* PerfDataManager::all() {
MutexLocker ml(PerfDataManager_lock);
diff --git a/hotspot/src/share/vm/runtime/perfData.hpp b/hotspot/src/share/vm/runtime/perfData.hpp
index 07dc9c9565d..94996df1a18 100644
--- a/hotspot/src/share/vm/runtime/perfData.hpp
+++ b/hotspot/src/share/vm/runtime/perfData.hpp
@@ -693,6 +693,9 @@ class PerfDataManager : AllStatic {
// the given name.
static bool exists(const char* name) { return _all->contains(name); }
+ // method to search for a instrumentation object by name
+ static PerfData* find_by_name(const char* name);
+
// method to map a CounterNS enumeration to a namespace string
static const char* ns_to_string(CounterNS ns) {
return _name_spaces[ns];
diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp
index 91f273e6515..7ad66371300 100644
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -223,6 +223,8 @@ class StubRoutines: AllStatic {
static void initialize1(); // must happen before universe::genesis
static void initialize2(); // must happen after universe::genesis
+ static bool is_stub_code(address addr) { return contains(addr); }
+
static bool contains(address addr) {
return
(_code1 != NULL && _code1->blob_contains(addr)) ||
diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp
index 2921b2544b7..ebecda50be0 100644
--- a/hotspot/src/share/vm/runtime/sweeper.cpp
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
#include "runtime/os.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/vm_operations.hpp"
+#include "trace/tracing.hpp"
#include "utilities/events.hpp"
#include "utilities/xmlstream.hpp"
@@ -130,6 +131,9 @@ void NMethodSweeper::record_sweep(nmethod* nm, int line) {
long NMethodSweeper::_traversals = 0; // No. of stack traversals performed
nmethod* NMethodSweeper::_current = NULL; // Current nmethod
int NMethodSweeper::_seen = 0 ; // No. of nmethods we have currently processed in current pass of CodeCache
+int NMethodSweeper::_flushed_count = 0; // Nof. nmethods flushed in current sweep
+int NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
+int NMethodSweeper::_marked_count = 0; // Nof. nmethods marked for reclaim in current sweep
volatile int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass
volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
@@ -143,6 +147,15 @@ int NMethodSweeper::_highest_marked = 0;
int NMethodSweeper::_dead_compile_ids = 0;
long NMethodSweeper::_last_flush_traversal_id = 0;
+int NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
+int NMethodSweeper::_total_nof_methods_reclaimed = 0;
+jlong NMethodSweeper::_total_time_sweeping = 0;
+jlong NMethodSweeper::_total_time_this_sweep = 0;
+jlong NMethodSweeper::_peak_sweep_time = 0;
+jlong NMethodSweeper::_peak_sweep_fraction_time = 0;
+jlong NMethodSweeper::_total_disconnect_time = 0;
+jlong NMethodSweeper::_peak_disconnect_time = 0;
+
class MarkActivationClosure: public CodeBlobClosure {
public:
virtual void do_code_blob(CodeBlob* cb) {
@@ -176,6 +189,8 @@ void NMethodSweeper::scan_stacks() {
_invocations = NmethodSweepFraction;
_current = CodeCache::first_nmethod();
_traversals += 1;
+ _total_time_this_sweep = 0;
+
if (PrintMethodFlushing) {
tty->print_cr("### Sweep: stack traversal %d", _traversals);
}
@@ -229,12 +244,13 @@ void NMethodSweeper::possibly_sweep() {
}
void NMethodSweeper::sweep_code_cache() {
-#ifdef ASSERT
- jlong sweep_start;
- if (PrintMethodFlushing) {
- sweep_start = os::javaTimeMillis();
- }
-#endif
+
+ jlong sweep_start_counter = os::elapsed_counter();
+
+ _flushed_count = 0;
+ _zombified_count = 0;
+ _marked_count = 0;
+
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
}
@@ -302,14 +318,34 @@ void NMethodSweeper::sweep_code_cache() {
}
}
+ jlong sweep_end_counter = os::elapsed_counter();
+ jlong sweep_time = sweep_end_counter - sweep_start_counter;
+ _total_time_sweeping += sweep_time;
+ _total_time_this_sweep += sweep_time;
+ _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
+ _total_nof_methods_reclaimed += _flushed_count;
+
+ EventSweepCodeCache event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_starttime(sweep_start_counter);
+ event.set_endtime(sweep_end_counter);
+ event.set_sweepIndex(_traversals);
+ event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1);
+ event.set_sweptCount(todo);
+ event.set_flushedCount(_flushed_count);
+ event.set_markedCount(_marked_count);
+ event.set_zombifiedCount(_zombified_count);
+ event.commit();
+ }
+
#ifdef ASSERT
if(PrintMethodFlushing) {
- jlong sweep_end = os::javaTimeMillis();
- tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
+ tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time);
}
#endif
if (_invocations == 1) {
+ _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
log_sweep("finished");
}
@@ -388,12 +424,14 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
}
release_nmethod(nm);
+ _flushed_count++;
} else {
if (PrintMethodFlushing && Verbose) {
tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
}
nm->mark_for_reclamation();
_resweep = true;
+ _marked_count++;
SWEEP(nm);
}
} else if (nm->is_not_entrant()) {
@@ -405,6 +443,7 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
}
nm->make_zombie();
_resweep = true;
+ _zombified_count++;
SWEEP(nm);
} else {
// Still alive, clean up its inline caches
@@ -420,13 +459,16 @@ void NMethodSweeper::process_nmethod(nmethod *nm) {
// Unloaded code, just make it a zombie
if (PrintMethodFlushing && Verbose)
tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
+
if (nm->is_osr_method()) {
SWEEP(nm);
// No inline caches will ever point to osr methods, so we can just remove it
release_nmethod(nm);
+ _flushed_count++;
} else {
nm->make_zombie();
_resweep = true;
+ _zombified_count++;
SWEEP(nm);
}
} else {
@@ -484,7 +526,7 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
// If there was a race in detecting full code cache, only run
// one vm op for it or keep the compiler shut off
- debug_only(jlong start = os::javaTimeMillis();)
+ jlong disconnect_start_counter = os::elapsed_counter();
// Traverse the code cache trying to dump the oldest nmethods
int curr_max_comp_id = CompileBroker::get_compilation_id();
@@ -541,13 +583,28 @@ void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
_last_full_flush_time = os::javaTimeMillis();
}
+ jlong disconnect_end_counter = os::elapsed_counter();
+ jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
+ _total_disconnect_time += disconnect_time;
+ _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
+
+ EventCleanCodeCache event(UNTIMED);
+ if (event.should_commit()) {
+ event.set_starttime(disconnect_start_counter);
+ event.set_endtime(disconnect_end_counter);
+ event.set_disconnectedCount(disconnected);
+ event.set_madeNonEntrantCount(made_not_entrant);
+ event.commit();
+ }
+ _number_of_flushes++;
+
// After two more traversals the sweeper will get rid of unrestored nmethods
_last_flush_traversal_id = _traversals;
_resweep = true;
#ifdef ASSERT
- jlong end = os::javaTimeMillis();
+
if(PrintMethodFlushing && Verbose) {
- tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start);
+ tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
}
#endif
}
diff --git a/hotspot/src/share/vm/runtime/sweeper.hpp b/hotspot/src/share/vm/runtime/sweeper.hpp
index ff63029f1cf..4bad5bd9be4 100644
--- a/hotspot/src/share/vm/runtime/sweeper.hpp
+++ b/hotspot/src/share/vm/runtime/sweeper.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,12 @@
//
class NMethodSweeper : public AllStatic {
- static long _traversals; // Stack traversal count
- static nmethod* _current; // Current nmethod
- static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache
+ static long _traversals; // Stack scan count, also sweep ID.
+ static nmethod* _current; // Current nmethod
+ static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache
+ static int _flushed_count; // Nof. nmethods flushed in current sweep
+ static int _zombified_count; // Nof. nmethods made zombie in current sweep
+ static int _marked_count; // Nof. nmethods marked for reclaim in current sweep
static volatile int _invocations; // No. of invocations left until we are completed with this pass
static volatile int _sweep_started; // Flag to control conc sweeper
@@ -53,6 +56,16 @@ class NMethodSweeper : public AllStatic {
static int _highest_marked; // highest compile id dumped at last emergency unloading
static int _dead_compile_ids; // number of compile ids that where not in the cache last flush
+ // Stat counters
+ static int _number_of_flushes; // Total of full traversals caused by full cache
+ static int _total_nof_methods_reclaimed; // Accumulated nof methods flushed
+ static jlong _total_time_sweeping; // Accumulated time sweeping
+ static jlong _total_time_this_sweep; // Total time this sweep
+ static jlong _peak_sweep_time; // Peak time for a full sweep
+ static jlong _peak_sweep_fraction_time; // Peak time sweeping one fraction
+ static jlong _total_disconnect_time; // Total time cleaning code mem
+ static jlong _peak_disconnect_time; // Peak time cleaning code mem
+
static void process_nmethod(nmethod *nm);
static void release_nmethod(nmethod* nm);
@@ -60,7 +73,14 @@ class NMethodSweeper : public AllStatic {
static bool sweep_in_progress();
public:
- static long traversal_count() { return _traversals; }
+ static long traversal_count() { return _traversals; }
+ static int number_of_flushes() { return _number_of_flushes; }
+ static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; }
+ static jlong total_time_sweeping() { return _total_time_sweeping; }
+ static jlong peak_sweep_time() { return _peak_sweep_time; }
+ static jlong peak_sweep_fraction_time() { return _peak_sweep_fraction_time; }
+ static jlong total_disconnect_time() { return _total_disconnect_time; }
+ static jlong peak_disconnect_time() { return _peak_disconnect_time; }
#ifdef ASSERT
// Keep track of sweeper activity in the ring buffer
diff --git a/hotspot/src/share/vm/runtime/synchronizer.cpp b/hotspot/src/share/vm/runtime/synchronizer.cpp
index ede9affb9f2..015dd757b23 100644
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp
@@ -213,7 +213,7 @@ void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
}
}
- ObjectSynchronizer::inflate(THREAD, object)->exit (THREAD) ;
+ ObjectSynchronizer::inflate(THREAD, object)->exit (true, THREAD) ;
}
// -----------------------------------------------------------------------------
@@ -343,7 +343,7 @@ void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
// If this thread has locked the object, exit the monitor. Note: can't use
// monitor->check(CHECK); must exit even if an exception is pending.
if (monitor->check(THREAD)) {
- monitor->exit(THREAD);
+ monitor->exit(true, THREAD);
}
}
diff --git a/hotspot/src/share/vm/runtime/task.cpp b/hotspot/src/share/vm/runtime/task.cpp
index 9d2286f2d8c..ef57dcd68cc 100644
--- a/hotspot/src/share/vm/runtime/task.cpp
+++ b/hotspot/src/share/vm/runtime/task.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -114,9 +114,11 @@ PeriodicTask::~PeriodicTask() {
disenroll();
}
+/* enroll could be called from a JavaThread, so we have to check for
+ * safepoint when taking the lock to avoid deadlocking */
void PeriodicTask::enroll() {
MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
- NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ NULL : PeriodicTask_lock);
if (_num_tasks == PeriodicTask::max_tasks) {
fatal("Overflow in PeriodicTask table");
@@ -131,9 +133,11 @@ void PeriodicTask::enroll() {
}
}
+/* disenroll could be called from a JavaThread, so we have to check for
+ * safepoint when taking the lock to avoid deadlocking */
void PeriodicTask::disenroll() {
MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
- NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+ NULL : PeriodicTask_lock);
int index;
for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index 7c3e256e2ef..79642c2e4a9 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -77,7 +77,8 @@
#include "services/management.hpp"
#include "services/memTracker.hpp"
#include "services/threadService.hpp"
-#include "trace/traceEventTypes.hpp"
+#include "trace/tracing.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
@@ -238,7 +239,6 @@ Thread::Thread() {
CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
_jvmti_env_iteration_count = 0;
set_allocated_bytes(0);
- set_trace_buffer(NULL);
_vm_operation_started_count = 0;
_vm_operation_completed_count = 0;
_current_pending_monitor = NULL;
@@ -1659,9 +1659,11 @@ void JavaThread::run() {
JvmtiExport::post_thread_start(this);
}
- EVENT_BEGIN(TraceEventThreadStart, event);
- EVENT_COMMIT(event,
- EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+ EventThreadStart event;
+ if (event.should_commit()) {
+ event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+ event.commit();
+ }
// We call another function to do the rest so we are sure that the stack addresses used
// from there will be lower than the stack base just computed
@@ -1791,9 +1793,11 @@ void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
// Called before the java thread exit since we want to read info
// from java_lang_Thread object
- EVENT_BEGIN(TraceEventThreadEnd, event);
- EVENT_COMMIT(event,
- EVENT_SET(event, javalangthread, java_lang_Thread::thread_id(this->threadObj())));
+ EventThreadEnd event;
+ if (event.should_commit()) {
+ event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj()));
+ event.commit();
+ }
// Call after last event on thread
EVENT_THREAD_EXIT(this);
@@ -3648,8 +3652,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
// Notify JVMTI agents that VM initialization is complete - nop if no agents.
JvmtiExport::post_vm_initialized();
- if (!TRACE_START()) {
- vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
+ if (TRACE_START() != JNI_OK) {
+ vm_exit_during_initialization("Failed to start tracing backend.");
}
if (CleanChunkPoolAsync) {
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index 71007590bbf..8b8e6dd4e62 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -47,7 +47,8 @@
#include "services/memRecorder.hpp"
#endif // INCLUDE_NMT
-#include "trace/tracing.hpp"
+#include "trace/traceBackend.hpp"
+#include "trace/traceMacros.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/top.hpp"
#if INCLUDE_ALL_GCS
@@ -258,7 +259,7 @@ class Thread: public ThreadShadow {
jlong _allocated_bytes; // Cumulative number of bytes allocated on
// the Java heap
- TRACE_BUFFER _trace_buffer; // Thread-local buffer for tracing
+ TRACE_DATA _trace_data; // Thread-local data for tracing
int _vm_operation_started_count; // VM_Operation support
int _vm_operation_completed_count; // VM_Operation support
@@ -449,8 +450,7 @@ class Thread: public ThreadShadow {
return allocated_bytes;
}
- TRACE_BUFFER trace_buffer() { return _trace_buffer; }
- void set_trace_buffer(TRACE_BUFFER buf) { _trace_buffer = buf; }
+ TRACE_DATA* trace_data() { return &_trace_data; }
// VM operation support
int vm_operation_ticket() { return ++_vm_operation_started_count; }
diff --git a/hotspot/src/share/vm/runtime/timer.cpp b/hotspot/src/share/vm/runtime/timer.cpp
index 838262650e9..12c32660b04 100644
--- a/hotspot/src/share/vm/runtime/timer.cpp
+++ b/hotspot/src/share/vm/runtime/timer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,11 @@
# include "os_bsd.inline.hpp"
#endif
+double TimeHelper::counter_to_seconds(jlong counter) {
+ double count = (double) counter;
+ double freq = (double) os::elapsed_frequency();
+ return counter/freq;
+}
void elapsedTimer::add(elapsedTimer t) {
_counter += t._counter;
@@ -59,9 +64,7 @@ void elapsedTimer::stop() {
}
double elapsedTimer::seconds() const {
- double count = (double) _counter;
- double freq = (double) os::elapsed_frequency();
- return count/freq;
+ return TimeHelper::counter_to_seconds(_counter);
}
jlong elapsedTimer::milliseconds() const {
@@ -90,9 +93,7 @@ void TimeStamp::update() {
double TimeStamp::seconds() const {
assert(is_updated(), "must not be clear");
jlong new_count = os::elapsed_counter();
- double count = (double) new_count - _counter;
- double freq = (double) os::elapsed_frequency();
- return count/freq;
+ return TimeHelper::counter_to_seconds(new_count - _counter);
}
jlong TimeStamp::milliseconds() const {
@@ -110,19 +111,15 @@ jlong TimeStamp::ticks_since_update() const {
}
TraceTime::TraceTime(const char* title,
- bool doit,
- bool print_cr,
- outputStream* logfile) {
+ bool doit) {
_active = doit;
_verbose = true;
- _print_cr = print_cr;
- _logfile = (logfile != NULL) ? logfile : tty;
if (_active) {
_accum = NULL;
- _logfile->stamp(PrintGCTimeStamps);
- _logfile->print("[%s", title);
- _logfile->flush();
+ tty->stamp(PrintGCTimeStamps);
+ tty->print("[%s", title);
+ tty->flush();
_t.start();
}
}
@@ -130,17 +127,14 @@ TraceTime::TraceTime(const char* title,
TraceTime::TraceTime(const char* title,
elapsedTimer* accumulator,
bool doit,
- bool verbose,
- outputStream* logfile) {
+ bool verbose) {
_active = doit;
_verbose = verbose;
- _print_cr = true;
- _logfile = (logfile != NULL) ? logfile : tty;
if (_active) {
if (_verbose) {
- _logfile->stamp(PrintGCTimeStamps);
- _logfile->print("[%s", title);
- _logfile->flush();
+ tty->stamp(PrintGCTimeStamps);
+ tty->print("[%s", title);
+ tty->flush();
}
_accum = accumulator;
_t.start();
@@ -152,12 +146,8 @@ TraceTime::~TraceTime() {
_t.stop();
if (_accum!=NULL) _accum->add(_t);
if (_verbose) {
- if (_print_cr) {
- _logfile->print_cr(", %3.7f secs]", _t.seconds());
- } else {
- _logfile->print(", %3.7f secs]", _t.seconds());
- }
- _logfile->flush();
+ tty->print_cr(", %3.7f secs]", _t.seconds());
+ tty->flush();
}
}
}
diff --git a/hotspot/src/share/vm/runtime/timer.hpp b/hotspot/src/share/vm/runtime/timer.hpp
index 388a821c11a..7e694d5bdb8 100644
--- a/hotspot/src/share/vm/runtime/timer.hpp
+++ b/hotspot/src/share/vm/runtime/timer.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -82,21 +82,16 @@ class TraceTime: public StackObj {
private:
bool _active; // do timing
bool _verbose; // report every timing
- bool _print_cr; // add a CR to the end of the timer report
elapsedTimer _t; // timer
elapsedTimer* _accum; // accumulator
- outputStream* _logfile; // output log file
public:
- // Constuctors
+ // Constructors
TraceTime(const char* title,
- bool doit = true,
- bool print_cr = true,
- outputStream *logfile = NULL);
+ bool doit = true);
TraceTime(const char* title,
elapsedTimer* accumulator,
bool doit = true,
- bool verbose = false,
- outputStream *logfile = NULL );
+ bool verbose = false);
~TraceTime();
// Accessors
@@ -125,4 +120,9 @@ class TraceCPUTime: public StackObj {
~TraceCPUTime();
};
+class TimeHelper {
+ public:
+ static double counter_to_seconds(jlong counter);
+};
+
#endif // SHARE_VM_RUNTIME_TIMER_HPP
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 6e12cd447fc..dff270f1631 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -60,6 +60,7 @@
#include "memory/generationSpec.hpp"
#include "memory/heap.hpp"
#include "memory/metablock.hpp"
+#include "memory/referenceType.hpp"
#include "memory/space.hpp"
#include "memory/tenuredGeneration.hpp"
#include "memory/universe.hpp"
diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp
index 8c321721e27..bdb508208d4 100644
--- a/hotspot/src/share/vm/runtime/vmThread.cpp
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp
@@ -35,6 +35,7 @@
#include "runtime/vmThread.hpp"
#include "runtime/vm_operations.hpp"
#include "services/runtimeService.hpp"
+#include "trace/tracing.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/xmlstream.hpp"
@@ -365,7 +366,23 @@ void VMThread::evaluate_operation(VM_Operation* op) {
(char *) op->name(), strlen(op->name()),
op->evaluation_mode());
#endif /* USDT2 */
+
+ EventExecuteVMOperation event;
+
op->evaluate();
+
+ if (event.should_commit()) {
+ bool is_concurrent = op->evaluate_concurrently();
+ event.set_operation(op->type());
+ event.set_safepoint(op->evaluate_at_safepoint());
+ event.set_blocking(!is_concurrent);
+ // Only write caller thread information for non-concurrent vm operations.
+ // For concurrent vm operations, the thread id is set to 0 indicating thread is unknown.
+ // This is because the caller thread could have exited already.
+ event.set_caller(is_concurrent ? 0 : op->calling_thread()->osthread()->thread_id());
+ event.commit();
+ }
+
#ifndef USDT2
HS_DTRACE_PROBE3(hotspot, vmops__end, op->name(), strlen(op->name()),
op->evaluation_mode());
@@ -601,7 +618,7 @@ void VMThread::execute(VM_Operation* op) {
{
VMOperationQueue_lock->lock_without_safepoint_check();
bool ok = _vm_queue->add(op);
- op->set_timestamp(os::javaTimeMillis());
+ op->set_timestamp(os::javaTimeMillis());
VMOperationQueue_lock->notify();
VMOperationQueue_lock->unlock();
// VM_Operation got skipped
diff --git a/hotspot/src/share/vm/runtime/vm_operations.cpp b/hotspot/src/share/vm/runtime/vm_operations.cpp
index 53ea0bd9852..5166cfdaae1 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.cpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
#include "runtime/thread.inline.hpp"
#include "runtime/vm_operations.hpp"
#include "services/threadService.hpp"
+#include "trace/tracing.hpp"
#define VM_OP_NAME_INITIALIZE(name) #name,
@@ -62,19 +63,21 @@ void VM_Operation::evaluate() {
}
}
+const char* VM_Operation::mode_to_string(Mode mode) {
+ switch(mode) {
+ case _safepoint : return "safepoint";
+ case _no_safepoint : return "no safepoint";
+ case _concurrent : return "concurrent";
+ case _async_safepoint: return "async safepoint";
+ default : return "unknown";
+ }
+}
// Called by fatal error handler.
void VM_Operation::print_on_error(outputStream* st) const {
st->print("VM_Operation (" PTR_FORMAT "): ", this);
st->print("%s", name());
- const char* mode;
- switch(evaluation_mode()) {
- case _safepoint : mode = "safepoint"; break;
- case _no_safepoint : mode = "no safepoint"; break;
- case _concurrent : mode = "concurrent"; break;
- case _async_safepoint: mode = "async safepoint"; break;
- default : mode = "unknown"; break;
- }
+ const char* mode = mode_to_string(evaluation_mode());
st->print(", mode: %s", mode);
if (calling_thread()) {
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
index 9d79b2c0d7c..b6555b45704 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,6 +178,8 @@ class VM_Operation: public CHeapObj {
evaluation_mode() == _async_safepoint;
}
+ static const char* mode_to_string(Mode mode);
+
// Debugging
void print_on_error(outputStream* st) const;
const char* name() const { return _names[type()]; }
diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp
index 564b20f4b3b..bf002e7fa88 100644
--- a/hotspot/src/share/vm/services/attachListener.cpp
+++ b/hotspot/src/share/vm/services/attachListener.cpp
@@ -227,7 +227,7 @@ static jint heap_inspection(AttachOperation* op, outputStream* out) {
}
live_objects_only = strcmp(arg0, "-live") == 0;
}
- VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */, true /* need_prologue */);
+ VM_GC_HeapInspection heapop(out, live_objects_only /* request full gc */);
VMThread::execute(&heapop);
return JNI_OK;
}
diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp
index 022687db416..e3e14053270 100644
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
#include "runtime/thread.hpp"
#include "services/diagnosticArgument.hpp"
@@ -86,9 +87,18 @@ void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {
template <> void DCmdArgument::parse_value(const char* str,
size_t len, TRAPS) {
- if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Integer parsing error in diagnostic command arguments\n");
+ int scanned = -1;
+ if (str == NULL
+ || sscanf(str, JLONG_FORMAT"%n", &_value, &scanned) != 1
+ || (size_t)scanned != len)
+ {
+ ResourceMark rm;
+
+ char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(buf, str, len);
+ buf[len] = '\0';
+ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
+ "Integer parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
}
}
@@ -96,7 +106,7 @@ template <> void DCmdArgument::init_value(TRAPS) {
if (has_default()) {
this->parse_value(_default_string, strlen(_default_string), THREAD);
if (HAS_PENDING_EXCEPTION) {
- fatal("Default string must be parsable");
+ fatal("Default string must be parseable");
}
} else {
set_value(0);
@@ -116,8 +126,13 @@ template <> void DCmdArgument::parse_value(const char* str,
} else if (len == strlen("false") && strncasecmp(str, "false", len) == 0) {
set_value(false);
} else {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Boolean parsing error in diagnostic command arguments");
+ ResourceMark rm;
+
+ char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(buf, str, len);
+ buf[len] = '\0';
+ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(),
+ "Boolean parsing error in command argument '%s'. Could not parse: %s.", _name, buf);
}
}
}
@@ -168,7 +183,7 @@ template <> void DCmdArgument::parse_value(const char* str,
size_t len, TRAPS) {
if (str == NULL) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
- "Integer parsing error nanotime value: syntax error");
+ "Integer parsing error nanotime value: syntax error, value is null");
}
int argc = sscanf(str, JLONG_FORMAT, &_value._time);
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp
index 5deaae0d416..79c922a8586 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp
@@ -320,8 +320,7 @@ ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
VM_GC_HeapInspection heapop(output(),
- !_all.value() /* request full gc if false */,
- true /* need_prologue */);
+ !_all.value() /* request full gc if false */);
VMThread::execute(&heapop);
}
@@ -361,8 +360,7 @@ void ClassStatsDCmd::execute(DCmdSource source, TRAPS) {
}
VM_GC_HeapInspection heapop(output(),
- true, /* request_full_gc */
- true /* need_prologue */);
+ true /* request_full_gc */);
heapop.set_csv_format(_csv.value());
heapop.set_print_help(_help.value());
heapop.set_print_class_stats(true);
diff --git a/hotspot/src/share/vm/services/memBaseline.cpp b/hotspot/src/share/vm/services/memBaseline.cpp
index b090e95acc7..c2d04106c8b 100644
--- a/hotspot/src/share/vm/services/memBaseline.cpp
+++ b/hotspot/src/share/vm/services/memBaseline.cpp
@@ -41,6 +41,7 @@ MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
{mtOther, "Other"},
{mtSymbol, "Symbol"},
{mtNMT, "Memory Tracking"},
+ {mtTracing, "Tracing"},
{mtChunk, "Pooled Free Chunks"},
{mtClassShared,"Shared spaces for classes"},
{mtTest, "Test"},
diff --git a/hotspot/src/share/vm/trace/noTraceBackend.hpp b/hotspot/src/share/vm/trace/noTraceBackend.hpp
new file mode 100644
index 00000000000..4755487263d
--- /dev/null
+++ b/hotspot/src/share/vm/trace/noTraceBackend.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_TRACE_NOTRACEBACKEND_HPP
+#define SHARE_VM_TRACE_NOTRACEBACKEND_HPP
+
+#include "prims/jni.h"
+
+typedef jlong TracingTime;
+typedef jlong RelativeTracingTime;
+
+class NoTraceBackend {
+public:
+ static TracingTime time() {
+ return 0;
+ }
+};
+
+class TraceThreadData {
+public:
+ TraceThreadData() {}
+};
+
+typedef NoTraceBackend Tracing;
+
+#endif
+
+
diff --git a/hotspot/src/share/vm/trace/trace.dtd b/hotspot/src/share/vm/trace/trace.dtd
new file mode 100644
index 00000000000..a61984aaa26
--- /dev/null
+++ b/hotspot/src/share/vm/trace/trace.dtd
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/src/share/vm/trace/trace.xml b/hotspot/src/share/vm/trace/trace.xml
new file mode 100644
index 00000000000..c530bbc3c16
--- /dev/null
+++ b/hotspot/src/share/vm/trace/trace.xml
@@ -0,0 +1,367 @@
+
+
+
+
+
+%xinclude;
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/src/share/vm/trace/traceBackend.hpp b/hotspot/src/share/vm/trace/traceBackend.hpp
new file mode 100644
index 00000000000..cd348dfa427
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceBackend.hpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#ifndef SHARE_VM_TRACE_TRACEBACKEND_HPP
+#define SHARE_VM_TRACE_TRACEBACKEND_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "runtime/globals.hpp"
+#include "runtime/os.hpp"
+#include "trace/traceTime.hpp"
+#include "tracefiles/traceEventIds.hpp"
+
+class TraceBackend {
+public:
+ static bool enabled(void) {
+ return EnableTracing;
+ }
+
+ static bool is_event_enabled(TraceEventId id) {
+ return enabled();
+ }
+
+ static TracingTime time() {
+ return os::elapsed_counter();
+ }
+
+ static TracingTime time_adjustment(jlong time) {
+ return time;
+ }
+
+ static void on_unloading_classes(void) {
+ }
+};
+
+class TraceThreadData {
+public:
+ TraceThreadData() {}
+};
+
+typedef TraceBackend Tracing;
+
+#else /* INCLUDE_TRACE */
+
+#include "trace/noTraceBackend.hpp"
+
+#endif /* INCLUDE_TRACE */
+#endif /* SHARE_VM_TRACE_TRACEBACKEND_HPP */
diff --git a/hotspot/src/share/vm/trace/traceDataTypes.hpp b/hotspot/src/share/vm/trace/traceDataTypes.hpp
new file mode 100644
index 00000000000..437ac447e73
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceDataTypes.hpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACEDATATYPES_HPP
+#define SHARE_VM_TRACE_TRACEDATATYPES_HPP
+
+#include
+
+#include "utilities/globalDefinitions.hpp"
+
+enum {
+ CONTENT_TYPE_NONE = 0,
+ CONTENT_TYPE_BYTES = 1,
+ CONTENT_TYPE_EPOCHMILLIS = 2,
+ CONTENT_TYPE_MILLIS = 3,
+ CONTENT_TYPE_NANOS = 4,
+ CONTENT_TYPE_TICKS = 5,
+ CONTENT_TYPE_ADDRESS = 6,
+
+ CONTENT_TYPE_OSTHREAD,
+ CONTENT_TYPE_JAVALANGTHREAD,
+ CONTENT_TYPE_STACKTRACE,
+ CONTENT_TYPE_CLASS,
+ CONTENT_TYPE_PERCENTAGE,
+
+ JVM_CONTENT_TYPES_START = 30,
+ JVM_CONTENT_TYPES_END = 100
+};
+
+enum ReservedEvent {
+ EVENT_PRODUCERS,
+ EVENT_CHECKPOINT,
+ EVENT_BUFFERLOST,
+
+ NUM_RESERVED_EVENTS
+};
+
+typedef enum ReservedEvent ReservedEvent;
+
+typedef u8 classid;
+typedef u8 stacktraceid;
+typedef u8 methodid;
+typedef u8 fieldid;
+
+#endif // SHARE_VM_TRACE_TRACEDATATYPES_HPP
+
diff --git a/hotspot/src/share/vm/trace/traceEvent.hpp b/hotspot/src/share/vm/trace/traceEvent.hpp
new file mode 100644
index 00000000000..364c2df4805
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceEvent.hpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACEEVENT_HPP
+#define SHARE_VM_TRACE_TRACEEVENT_HPP
+
+enum EventStartTime {
+ UNTIMED,
+ TIMED
+};
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "trace/traceBackend.hpp"
+#include "trace/tracing.hpp"
+#include "tracefiles/traceEventIds.hpp"
+#include "tracefiles/traceTypes.hpp"
+
+template
+class TraceEvent : public StackObj {
+ protected:
+ jlong _startTime;
+ jlong _endTime;
+
+ private:
+ bool _started;
+#ifdef ASSERT
+ bool _committed;
+ bool _cancelled;
+ protected:
+ bool _ignore_check;
+#endif
+
+ public:
+ TraceEvent(EventStartTime timing=TIMED) :
+ _startTime(0),
+ _endTime(0),
+ _started(false)
+#ifdef ASSERT
+ ,
+ _committed(false),
+ _cancelled(false),
+ _ignore_check(false)
+#endif
+ {
+ if (T::is_enabled()) {
+ _started = true;
+ if (timing == TIMED && !T::isInstant) {
+ static_cast(this)->set_starttime(Tracing::time());
+ }
+ }
+ }
+
+ static bool is_enabled() {
+ return Tracing::is_event_enabled(T::eventId);
+ }
+
+ bool should_commit() {
+ return _started;
+ }
+
+ void ignoreCheck() {
+ DEBUG_ONLY(_ignore_check = true);
+ }
+
+ void commit() {
+ if (!should_commit()) {
+ cancel();
+ return;
+ }
+ if (_endTime == 0) {
+ static_cast(this)->set_endtime(Tracing::time());
+ }
+ if (static_cast(this)->should_write()) {
+ static_cast(this)->writeEvent();
+ }
+ set_commited();
+ }
+
+ void set_starttime(jlong time) {
+ _startTime = time;
+ }
+
+ void set_endtime(jlong time) {
+ _endTime = time;
+ }
+
+ TraceEventId id() const {
+ return T::eventId;
+ }
+
+ bool is_instant() const {
+ return T::isInstant;
+ }
+
+ bool is_requestable() const {
+ return T::isRequestable;
+ }
+
+ bool has_thread() const {
+ return T::hasThread;
+ }
+
+ bool has_stacktrace() const {
+ return T::hasStackTrace;
+ }
+
+ void cancel() {
+ assert(!_committed && !_cancelled, "event was already committed/cancelled");
+ DEBUG_ONLY(_cancelled = true);
+ }
+
+ void set_commited() {
+ assert(!_committed, "event has already been committed");
+ DEBUG_ONLY(_committed = true);
+ }
+
+ ~TraceEvent() {
+ if (_started) {
+ assert(_ignore_check || _committed || _cancelled, "event was not committed/cancelled");
+ }
+ }
+};
+
+#endif /* INCLUDE_TRACE */
+
+#endif /* SHARE_VM_TRACE_TRACEEVENT_HPP */
diff --git a/hotspot/src/share/vm/trace/traceEventClasses.xsl b/hotspot/src/share/vm/trace/traceEventClasses.xsl
new file mode 100644
index 00000000000..70ac9c03759
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceEventClasses.xsl
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+
+
+#ifndef TRACEFILES_TRACEEVENTCLASSES_HPP
+#define TRACEFILES_TRACEEVENTCLASSES_HPP
+
+// On purpose outside the INCLUDE_TRACE
+// Some parts of traceEvent.hpp are used outside of
+// INCLUDE_TRACE
+
+#include "memory/resourceArea.hpp"
+#include "tracefiles/traceTypes.hpp"
+#include "trace/traceEvent.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+
+#include "trace/traceStream.hpp"
+#include "utilities/ostream.hpp"
+
+
+
+
+#else
+
+class TraceEvent {
+public:
+ TraceEvent() {}
+ void set_starttime(jlong time) const {}
+ void set_endtime(jlong time) const {}
+ bool should_commit() const { return false; }
+ void commit() const {}
+};
+
+
+
+
+#endif
+
+#endif
+
+
+
+struct TraceStruct
+{
+private:
+
+public:
+
+
+ void writeStruct(TraceStream& ts) {
+
+ }
+};
+
+
+
+
+struct TraceStruct
+{
+public:
+
+};
+
+
+
+
+
+{
+ public:
+
+
+
+
+
+};
+
+
+
+
+
+
+{
+ public:
+ static const bool hasThread = ;
+ static const bool hasStackTrace = ;
+ static const bool isInstant = ;
+ static const bool isRequestable = ;
+ static const TraceEventId eventId = ;
+
+ private:
+
+
+ void writeEventContent(void) {
+ TraceStream ts(*tty);
+ ts.print(" : [");
+
+ ts.print("]\n");
+ }
+
+ public:
+
+
+ bool should_write(void) {
+ return true;
+ }
+
+
+
+
+ void writeEvent(void) {
+ ResourceMark rm;
+ if (UseLockedTracing) {
+ ttyLocker lock;
+ writeEventContent();
+ } else {
+ writeEventContent();
+ }
+ }
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if INCLUDE_TRACE
+
+#else
+
+#endif
+
+
+
+#if INCLUDE_TRACE
+
+#else
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ts.print(", ");
+
+
+
+
+
+
+
+
+ ts.print(", ");
+
+
+
+
+
diff --git a/hotspot/src/share/vm/trace/traceEventIds.xsl b/hotspot/src/share/vm/trace/traceEventIds.xsl
new file mode 100644
index 00000000000..737377cadd7
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceEventIds.xsl
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+#ifndef TRACEFILES_JFREVENTIDS_HPP
+#define TRACEFILES_JFREVENTIDS_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "trace/traceDataTypes.hpp"
+
+/**
+ * Enum of the event types in the JVM
+ */
+enum TraceEventId {
+ _traceeventbase = (NUM_RESERVED_EVENTS-1), // Make sure we start at right index.
+
+ // Events -> enum entry
+
+
+
+ MaxTraceEventId
+};
+
+/**
+ * Struct types in the JVM
+ */
+enum TraceStructId {
+
+
+
+
+
+
+ MaxTraceStructId
+};
+
+typedef enum TraceEventId TraceEventId;
+typedef enum TraceStructId TraceStructId;
+
+#endif
+#endif
+
+
+
diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp
index 44103192083..1a6dd644935 100644
--- a/hotspot/src/share/vm/trace/traceMacros.hpp
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,22 +25,14 @@
#ifndef SHARE_VM_TRACE_TRACE_MACRO_HPP
#define SHARE_VM_TRACE_TRACE_MACRO_HPP
-#define EVENT_BEGIN(type, name)
-#define EVENT_SET(name, field, value)
-#define EVENT_COMMIT(name, ...)
-#define EVENT_STARTED(name, time)
-#define EVENT_ENDED(name, time)
#define EVENT_THREAD_EXIT(thread)
-#define TRACE_ENABLED 0
-
#define TRACE_INIT_ID(k)
-#define TRACE_BUFFER void*
+#define TRACE_DATA TraceThreadData
-#define TRACE_START() true
-#define TRACE_INITIALIZE() 0
+#define TRACE_START() JNI_OK
+#define TRACE_INITIALIZE() JNI_OK
-#define TRACE_SET_KLASS_TRACE_ID(x1, x2) do { } while (0)
#define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1
#define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2
#define TRACE_DEFINE_OFFSET typedef int ___IGNORED_hs_trace_type3
diff --git a/hotspot/src/share/vm/trace/traceStream.hpp b/hotspot/src/share/vm/trace/traceStream.hpp
new file mode 100644
index 00000000000..4acbbb88498
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceStream.hpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_TRACE_TRACESTREAM_HPP
+#define SHARE_VM_TRACE_TRACESTREAM_HPP
+
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
+
+#include "oops/klass.hpp"
+#include "oops/method.hpp"
+#include "oops/symbol.hpp"
+#include "utilities/ostream.hpp"
+
+class TraceStream : public StackObj {
+ private:
+ outputStream& _st;
+
+ public:
+ TraceStream(outputStream& stream): _st(stream) {}
+
+ void print_val(const char* label, u1 val) {
+ _st.print("%s = "UINT32_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, u2 val) {
+ _st.print("%s = "UINT32_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, s2 val) {
+ _st.print("%s = "INT32_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, u4 val) {
+ _st.print("%s = "UINT32_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, s4 val) {
+ _st.print("%s = "INT32_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, u8 val) {
+ _st.print("%s = "UINT64_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, s8 val) {
+ _st.print("%s = "INT64_FORMAT, label, val);
+ }
+
+ void print_val(const char* label, bool val) {
+ _st.print("%s = %s", label, val ? "true" : "false");
+ }
+
+ void print_val(const char* label, float val) {
+ _st.print("%s = %f", label, val);
+ }
+
+ void print_val(const char* label, double val) {
+ _st.print("%s = %f", label, val);
+ }
+
+ // Caller is machine generated code located in traceEventClasses.hpp
+ // Event::writeEvent() (pseudocode) contains the
+ // necessary ResourceMark for the resource allocations below.
+ // See traceEventClasses.xsl for details.
+ void print_val(const char* label, const Klass* const val) {
+ const char* description = "NULL";
+ if (val != NULL) {
+ Symbol* name = val->name();
+ if (name != NULL) {
+ description = name->as_C_string();
+ }
+ }
+ _st.print("%s = %s", label, description);
+ }
+
+ // Caller is machine generated code located in traceEventClasses.hpp
+ // Event::writeEvent() (pseudocode) contains the
+ // necessary ResourceMark for the resource allocations below.
+ // See traceEventClasses.xsl for details.
+ void print_val(const char* label, const Method* const val) {
+ const char* description = "NULL";
+ if (val != NULL) {
+ description = val->name_and_sig_as_C_string();
+ }
+ _st.print("%s = %s", label, description);
+ }
+
+ void print_val(const char* label, const char* val) {
+ _st.print("%s = '%s'", label, val);
+ }
+
+ void print(const char* val) {
+ _st.print(val);
+ }
+};
+
+#endif /* INCLUDE_TRACE */
+#endif /* SHARE_VM_TRACE_TRACESTREAM_HPP */
diff --git a/hotspot/src/share/vm/trace/traceEventTypes.hpp b/hotspot/src/share/vm/trace/traceTime.hpp
similarity index 81%
rename from hotspot/src/share/vm/trace/traceEventTypes.hpp
rename to hotspot/src/share/vm/trace/traceTime.hpp
index e7448aaebdf..3a0fe20377f 100644
--- a/hotspot/src/share/vm/trace/traceEventTypes.hpp
+++ b/hotspot/src/share/vm/trace/traceTime.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,9 +22,12 @@
*
*/
-#ifndef SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
-#define SHARE_VM_TRACE_TRACE_EVENT_TYPES_HPP
+#ifndef SHARE_VM_TRACE_TRACETIME_HPP
+#define SHARE_VM_TRACE_TRACETIME_HPP
-/* Empty, just a placeholder for tracing events */
+#include "prims/jni.h"
+
+typedef jlong TracingTime;
+typedef jlong RelativeTracingTime;
#endif
diff --git a/hotspot/src/share/vm/trace/traceTypes.xsl b/hotspot/src/share/vm/trace/traceTypes.xsl
new file mode 100644
index 00000000000..b06b604cedd
--- /dev/null
+++ b/hotspot/src/share/vm/trace/traceTypes.xsl
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+#ifndef TRACEFILES_JFRTYPES_HPP
+#define TRACEFILES_JFRTYPES_HPP
+
+#include "trace/traceDataTypes.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "oops/symbol.hpp"
+
+enum JVMContentType {
+ _not_a_content_type = (JVM_CONTENT_TYPES_START - 1),
+
+
+
+
+ NUM_JVM_CONTENT_TYPES
+};
+
+
+enum JVMEventRelations {
+ JVM_REL_NOT_AVAILABLE = 0,
+
+
+
+
+ NUM_EVENT_RELATIONS
+};
+
+/**
+ * Create typedefs for the JRA types:
+ * typedef s8 TYPE_LONG;
+ * typedef s4 TYPE_INTEGER;
+ * typedef const char * TYPE_STRING;
+ * ...
+ */
+
+typedef TYPE_ ;
+
+
+#endif // JFRFILES_JFRTYPES_HPP
+
+
+
diff --git a/hotspot/src/share/vm/trace/tracetypes.xml b/hotspot/src/share/vm/trace/tracetypes.xml
new file mode 100644
index 00000000000..7f0460e691a
--- /dev/null
+++ b/hotspot/src/share/vm/trace/tracetypes.xml
@@ -0,0 +1,368 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/src/share/vm/trace/tracing.hpp b/hotspot/src/share/vm/trace/tracing.hpp
index c56e2dc2dc8..72530e74594 100644
--- a/hotspot/src/share/vm/trace/tracing.hpp
+++ b/hotspot/src/share/vm/trace/tracing.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_TRACE_TRACING_HPP
#define SHARE_VM_TRACE_TRACING_HPP
-#include "trace/traceMacros.hpp"
+#include "tracefiles/traceEventClasses.hpp"
+#include "tracefiles/traceEventIds.hpp"
#endif
diff --git a/hotspot/src/share/vm/trace/xinclude.mod b/hotspot/src/share/vm/trace/xinclude.mod
new file mode 100644
index 00000000000..17d259cdf59
--- /dev/null
+++ b/hotspot/src/share/vm/trace/xinclude.mod
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/src/share/vm/trace/xsl_util.xsl b/hotspot/src/share/vm/trace/xsl_util.xsl
new file mode 100644
index 00000000000..fb82914c7b3
--- /dev/null
+++ b/hotspot/src/share/vm/trace/xsl_util.xsl
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "
+
+
+
+ /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index d9088307a97..e7f3f3f7080 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -763,18 +763,6 @@ inline BasicType as_BasicType(TosState state) {
TosState as_TosState(BasicType type);
-// ReferenceType is used to distinguish between java/lang/ref/Reference subclasses
-
-enum ReferenceType {
- REF_NONE, // Regular class
- REF_OTHER, // Subclass of java/lang/ref/Reference, but not subclass of one of the classes below
- REF_SOFT, // Subclass of java/lang/ref/SoftReference
- REF_WEAK, // Subclass of java/lang/ref/WeakReference
- REF_FINAL, // Subclass of java/lang/ref/FinalReference
- REF_PHANTOM // Subclass of java/lang/ref/PhantomReference
-};
-
-
// JavaThreadState keeps track of which part of the code a thread is executing in. This
// information is needed by the safepoint code.
//
diff --git a/hotspot/src/share/vm/utilities/macros.hpp b/hotspot/src/share/vm/utilities/macros.hpp
index a97e9e7d039..468c18fddf9 100644
--- a/hotspot/src/share/vm/utilities/macros.hpp
+++ b/hotspot/src/share/vm/utilities/macros.hpp
@@ -160,6 +160,10 @@
#define NOT_NMT_RETURN_(code) { return code; }
#endif // INCLUDE_NMT
+#ifndef INCLUDE_TRACE
+#define INCLUDE_TRACE 1
+#endif // INCLUDE_TRACE
+
// COMPILER1 variant
#ifdef COMPILER1
#ifdef COMPILER2
From ce8819512fb5abaa90b679efd5b5c51d5e9a8929 Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Mon, 10 Jun 2013 13:21:29 +0200
Subject: [PATCH 030/136] 8015892: canBeUndefined too conservative for some use
before declaration cases
Reviewed-by: attila, hannesw
---
.../jdk/nashorn/internal/codegen/Attr.java | 34 ++++++++++
.../src/jdk/nashorn/internal/ir/Symbol.java | 2 +-
nashorn/test/script/basic/JDK-8015892.js | 38 +++++++++++
nashorn/test/script/basic/fib_wtf.js | 38 +++++++++++
nashorn/test/script/basic/fib_wtf.js.EXPECTED | 65 +++++++++++++++++++
5 files changed, 176 insertions(+), 1 deletion(-)
create mode 100644 nashorn/test/script/basic/JDK-8015892.js
create mode 100644 nashorn/test/script/basic/fib_wtf.js
create mode 100644 nashorn/test/script/basic/fib_wtf.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
index d0b5a00a77c..f330fb80d0d 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
@@ -202,18 +202,52 @@ final class Attr extends NodeOperatorVisitor {
private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
// This visitor will assign symbol to all declared variables, except function declarations (which are taken care
// in a separate step above) and "var" declarations in for loop initializers.
+ //
+ // It also handles the case that a variable can be undefined, e.g
+ // if (cond) {
+ // x = x.y;
+ // }
+ // var x = 17;
+ //
+ // by making sure that no identifier has been found earlier in the body than the
+ // declaration - if such is the case the identifier is flagged as caBeUndefined to
+ // be safe if it turns into a local var. Otherwise corrupt bytecode results
+
body.accept(new NodeVisitor(new LexicalContext()) {
+ private final Set uses = new HashSet<>();
+ private final Set canBeUndefined = new HashSet<>();
+
@Override
public boolean enterFunctionNode(final FunctionNode nestedFn) {
return false;
}
+ @Override
+ public Node leaveIdentNode(final IdentNode identNode) {
+ uses.add(identNode.getName());
+ return identNode;
+ }
+
+ @Override
+ public boolean enterVarNode(final VarNode varNode) {
+ final String name = varNode.getName().getName();
+ //if this is used the var node symbol needs to be tagged as can be undefined
+ if (uses.contains(name)) {
+ canBeUndefined.add(name);
+ }
+ return true;
+ }
+
@Override
public Node leaveVarNode(final VarNode varNode) {
// any declared symbols that aren't visited need to be typed as well, hence the list
if (varNode.isStatement()) {
final IdentNode ident = varNode.getName();
final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR);
+ if (canBeUndefined.contains(ident.getName())) {
+ symbol.setType(Type.OBJECT);
+ symbol.setCanBeUndefined();
+ }
functionNode.addDeclaredSymbol(symbol);
if (varNode.isFunctionDeclaration()) {
newType(symbol, FunctionNode.FUNCTION_TYPE);
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
index d26fe561627..2f7ec12946d 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -462,7 +462,7 @@ public final class Symbol implements Comparable {
*/
public void setCanBeUndefined() {
assert type.isObject() : type;
- if(!canBeUndefined()) {
+ if (!isParam() && !canBeUndefined()) {//parameters are never undefined
assert !isShared();
flags |= CAN_BE_UNDEFINED;
}
diff --git a/nashorn/test/script/basic/JDK-8015892.js b/nashorn/test/script/basic/JDK-8015892.js
new file mode 100644
index 00000000000..a6ab4c8b428
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015892.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015892.js : use before definition with valid declaration that turns into
+ * local var must be "canBeUndefined"
+ *
+ * @test
+ * @run
+ */
+
+function doIt() {
+ if (something) {
+ x = x.obj;
+ } else {
+ var x = "x";
+ }
+}
diff --git a/nashorn/test/script/basic/fib_wtf.js b/nashorn/test/script/basic/fib_wtf.js
new file mode 100644
index 00000000000..a48ebc5c19b
--- /dev/null
+++ b/nashorn/test/script/basic/fib_wtf.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * fib_wtf - obfuscated fibonacci
+ *
+ * @test
+ * @run
+ */
+
+function fib(_) {
+ for(_=[+[],++[[]][+[]],+[],_],_[++[++[++[[]][+[]]][+[]]][+[]]]=(((_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]]))&(((--[[]][+[]])>>>(++[[]][+[]]))))===(_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])))?(_[++[++[[]][+[]]][+[]]]=++[[]][+[]],_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])):+[];_[++[++[++[[]][+[]]][+[]]][+[]]]--;_[+[]]=(_[++[[]][+[]]]=_[++[++[[]][+[]]][+[]]]=_[+[]]+_[++[[]][+[]]])-_[+[]]);
+ return _[++[++[[]][+[]]][+[]]];
+}
+
+for (var x = -1; x <= 63; x++) {
+ print(fib(x));
+}
diff --git a/nashorn/test/script/basic/fib_wtf.js.EXPECTED b/nashorn/test/script/basic/fib_wtf.js.EXPECTED
new file mode 100644
index 00000000000..c33277ca705
--- /dev/null
+++ b/nashorn/test/script/basic/fib_wtf.js.EXPECTED
@@ -0,0 +1,65 @@
+0
+0
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
+144
+233
+377
+610
+987
+1597
+2584
+4181
+6765
+10946
+17711
+28657
+46368
+75025
+121393
+196418
+317811
+514229
+832040
+1346269
+2178309
+3524578
+5702887
+9227465
+14930352
+24157817
+39088169
+63245986
+102334155
+165580141
+267914296
+433494437
+701408733
+1134903170
+1836311903
+2971215073
+4807526976
+7778742049
+12586269025
+20365011074
+32951280099
+53316291173
+86267571272
+139583862445
+225851433717
+365435296162
+591286729879
+956722026041
+1548008755920
+2504730781961
+4052739537881
+6557470319842
From 2d2e7fe029c0abfe6112a12d5dc4b92e7414ec3b Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Mon, 10 Jun 2013 13:27:07 +0200
Subject: [PATCH 031/136] 8016226: backing out test without third party license
approval
Reviewed-by: attila, sundar
---
nashorn/test/script/basic/fib_wtf.js | 38 -----------
nashorn/test/script/basic/fib_wtf.js.EXPECTED | 65 -------------------
2 files changed, 103 deletions(-)
delete mode 100644 nashorn/test/script/basic/fib_wtf.js
delete mode 100644 nashorn/test/script/basic/fib_wtf.js.EXPECTED
diff --git a/nashorn/test/script/basic/fib_wtf.js b/nashorn/test/script/basic/fib_wtf.js
deleted file mode 100644
index a48ebc5c19b..00000000000
--- a/nashorn/test/script/basic/fib_wtf.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * fib_wtf - obfuscated fibonacci
- *
- * @test
- * @run
- */
-
-function fib(_) {
- for(_=[+[],++[[]][+[]],+[],_],_[++[++[++[[]][+[]]][+[]]][+[]]]=(((_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]]))&(((--[[]][+[]])>>>(++[[]][+[]]))))===(_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])))?(_[++[++[[]][+[]]][+[]]]=++[[]][+[]],_[++[++[++[[]][+[]]][+[]]][+[]]]-(++[[]][+[]])):+[];_[++[++[++[[]][+[]]][+[]]][+[]]]--;_[+[]]=(_[++[[]][+[]]]=_[++[++[[]][+[]]][+[]]]=_[+[]]+_[++[[]][+[]]])-_[+[]]);
- return _[++[++[[]][+[]]][+[]]];
-}
-
-for (var x = -1; x <= 63; x++) {
- print(fib(x));
-}
diff --git a/nashorn/test/script/basic/fib_wtf.js.EXPECTED b/nashorn/test/script/basic/fib_wtf.js.EXPECTED
deleted file mode 100644
index c33277ca705..00000000000
--- a/nashorn/test/script/basic/fib_wtf.js.EXPECTED
+++ /dev/null
@@ -1,65 +0,0 @@
-0
-0
-1
-1
-2
-3
-5
-8
-13
-21
-34
-55
-89
-144
-233
-377
-610
-987
-1597
-2584
-4181
-6765
-10946
-17711
-28657
-46368
-75025
-121393
-196418
-317811
-514229
-832040
-1346269
-2178309
-3524578
-5702887
-9227465
-14930352
-24157817
-39088169
-63245986
-102334155
-165580141
-267914296
-433494437
-701408733
-1134903170
-1836311903
-2971215073
-4807526976
-7778742049
-12586269025
-20365011074
-32951280099
-53316291173
-86267571272
-139583862445
-225851433717
-365435296162
-591286729879
-956722026041
-1548008755920
-2504730781961
-4052739537881
-6557470319842
From 3039fb09eb46da3750da455a2c93bb079089ff67 Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Mon, 10 Jun 2013 16:44:40 +0400
Subject: [PATCH 032/136] 7105030: [TEST_BUG] [macosx] The tests never finishes
Reviewed-by: alexsch, serb
---
.../javax/swing/JMenu/4692443/bug4692443.java | 132 ++++++++++++++++++
1 file changed, 132 insertions(+)
create mode 100644 jdk/test/javax/swing/JMenu/4692443/bug4692443.java
diff --git a/jdk/test/javax/swing/JMenu/4692443/bug4692443.java b/jdk/test/javax/swing/JMenu/4692443/bug4692443.java
new file mode 100644
index 00000000000..6032287e534
--- /dev/null
+++ b/jdk/test/javax/swing/JMenu/4692443/bug4692443.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library ../../regtesthelpers
+ * @build Util
+ * @bug 4692443 7105030
+ * @summary JMenu: MenuListener.menuSelected() event fired too late when using mnemonics
+ * @author Alexander Zuev
+ * @run main bug4692443
+ */
+
+import javax.swing.*;
+import javax.swing.event.*;
+import java.awt.event.*;
+import java.awt.*;
+import sun.awt.SunToolkit;
+
+public class bug4692443 {
+
+ public static PassedListener pass;
+ public static FailedListener fail;
+ public static volatile Boolean passed;
+
+ public static void main(String args[]) throws Throwable {
+
+ fail = new FailedListener();
+ pass = new PassedListener();
+ passed = false;
+ Robot robo = new Robot();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ toolkit.realSync();
+
+ try {
+ robo = new Robot();
+ } catch (AWTException e) {
+ throw new RuntimeException("Robot could not be created");
+ }
+ int altKey = java.awt.event.KeyEvent.VK_ALT;
+ robo.setAutoDelay(100);
+ Util.hitMnemonics(robo, KeyEvent.VK_F); // Enter File menu
+ robo.keyPress(KeyEvent.VK_S); // Enter submenu
+ robo.keyRelease(KeyEvent.VK_S);
+ robo.keyPress(KeyEvent.VK_O); // Launch "One" action
+ robo.keyRelease(KeyEvent.VK_O);
+ robo.keyPress(KeyEvent.VK_M); // Launch "One" action
+ robo.keyRelease(KeyEvent.VK_M);
+
+ toolkit.realSync();
+
+ if (!passed) {
+ throw new RuntimeException("Test failed.");
+ }
+
+ }
+
+ private static void createAndShowGUI() {
+ JFrame mainFrame = new JFrame("Bug 4692443");
+ JMenuBar mbar = new JMenuBar();
+ JMenu menu = new JMenu("File");
+ menu.setMnemonic('F');
+ menu.add(new JMenuItem("Menu Item 1")).setMnemonic('I');
+ final JMenu submenu = new JMenu("Submenu");
+ submenu.setMnemonic('S');
+ submenu.addMenuListener(new MenuListener() {
+ public void menuSelected(MenuEvent e) {
+ JMenuItem item = submenu.add(new JMenuItem("One", 'O'));
+ item.addActionListener(pass);
+ submenu.add(new JMenuItem("Two", 'w'));
+ submenu.add(new JMenuItem("Three", 'r'));
+ }
+ public void menuDeselected(MenuEvent e) {
+ submenu.removeAll();
+ }
+ public void menuCanceled(MenuEvent e) {
+ submenu.removeAll();
+ }
+ });
+ menu.add(submenu);
+ JMenuItem menuItem = menu.add(new JMenuItem("Menu Item 2"));
+ menuItem.setMnemonic('M');
+ menuItem.addActionListener(fail);
+ mbar.add(menu);
+ mainFrame.setJMenuBar(mbar);
+
+ mainFrame.setSize(200, 200);
+ mainFrame.setLocation(200, 200);
+ mainFrame.setVisible(true);
+ mainFrame.toFront();
+ }
+
+ public static class FailedListener implements ActionListener {
+ public void actionPerformed(ActionEvent ev) {
+ throw new RuntimeException("Test failed.");
+ }
+ }
+
+ public static class PassedListener implements ActionListener {
+ public void actionPerformed(ActionEvent ev) {
+ passed = true;
+ }
+ }
+
+}
From 7258bbbfde083c4108cb0fced1310a8b68cd7ace Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Mon, 10 Jun 2013 15:18:47 +0100
Subject: [PATCH 033/136] 7113519: test/tools/javac/VersionOpt.java passes on
windows
Reviewed-by: jjg
---
langtools/test/tools/javac/VersionOpt.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/langtools/test/tools/javac/VersionOpt.java b/langtools/test/tools/javac/VersionOpt.java
index 285489c5d67..560d47dda62 100644
--- a/langtools/test/tools/javac/VersionOpt.java
+++ b/langtools/test/tools/javac/VersionOpt.java
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@ public class VersionOpt {
javaHome = javaHome.getParentFile();
File toolsJar = new File(new File(javaHome, "lib"), "tools.jar");
- if (!javacHome.equals(toolsJar.toURI().toString())){
+ if (!javacHome.equalsIgnoreCase(toolsJar.toURI().toString())) {
System.err.println("javac not found in tools.jar: " + javacHome);
System.err.println("rest of test skipped");
return;
From be9816a81e36b62aec0be77fa8161e9bfe994cf4 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Mon, 10 Jun 2013 19:54:07 +0530
Subject: [PATCH 034/136] 8016239: loadWithNewGlobal should support user
supplied arguments from the caller
Reviewed-by: lagergren, attila, jlaskey
---
.../jdk/nashorn/internal/objects/Global.java | 7 +--
.../jdk/nashorn/internal/runtime/Context.java | 6 ++-
nashorn/test/script/basic/JDK-8016239.js | 43 +++++++++++++++++++
.../test/script/basic/JDK-8016239.js.EXPECTED | 4 ++
4 files changed, 56 insertions(+), 4 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8016239.js
create mode 100644 nashorn/test/script/basic/JDK-8016239.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
index 04daa8b58cc..d1954a62973 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
@@ -372,7 +372,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class);
private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class);
private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class);
- private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object.class);
+ private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object.class, Object[].class);
private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class);
private final Context context;
@@ -752,14 +752,15 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
*
* @param self scope
* @param source source to load
+ * @param args (optional) arguments to be passed to the loaded script
*
* @return result of load (undefined)
*
* @throws IOException if source could not be read
*/
- public static Object loadWithNewGlobal(final Object self, final Object source) throws IOException {
+ public static Object loadWithNewGlobal(final Object self, final Object source, final Object...args) throws IOException {
final Global global = Global.instance();
- return global.context.loadWithNewGlobal(source);
+ return global.context.loadWithNewGlobal(source, args);
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
index d0e3b0200da..1b5cebb7137 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
@@ -496,12 +496,13 @@ public final class Context {
* expression, after creating a new global scope.
*
* @param from source expression for script
+ * @param args (optional) arguments to be passed to the loaded script
*
* @return return value for load call (undefined)
*
* @throws IOException if source cannot be found or loaded
*/
- public Object loadWithNewGlobal(final Object from) throws IOException {
+ public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
final ScriptObject oldGlobal = getGlobalTrusted();
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction() {
@Override
@@ -518,6 +519,9 @@ public final class Context {
});
setGlobalTrusted(newGlobal);
+ final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, newGlobal);
+ newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped));
+
try {
return ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal);
} finally {
diff --git a/nashorn/test/script/basic/JDK-8016239.js b/nashorn/test/script/basic/JDK-8016239.js
new file mode 100644
index 00000000000..84849ae4376
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8016239.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8016239: loadWithNewGlobal should support user supplied arguments from the caller
+ *
+ * @test
+ * @run
+ */
+
+var jmap = new java.util.HashMap();
+jmap.put("foo", "bar");
+
+loadWithNewGlobal({
+ name: "",
+ script:
+ " print(arguments[0]); "+
+ " print(arguments[1]); " +
+ " print(arguments[2].foo); " +
+ " print(arguments[3])"
+ },
+ "hello", 23, { foo: 33}, jmap
+);
diff --git a/nashorn/test/script/basic/JDK-8016239.js.EXPECTED b/nashorn/test/script/basic/JDK-8016239.js.EXPECTED
new file mode 100644
index 00000000000..3ed10c072a3
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8016239.js.EXPECTED
@@ -0,0 +1,4 @@
+hello
+23
+33
+{foo=bar}
From 72a51a0c44ee62f4b5fe0098a74ef16af9e70258 Mon Sep 17 00:00:00 2001
From: "Daniel D. Daugherty"
Date: Thu, 13 Jun 2013 11:16:38 -0700
Subject: [PATCH 035/136] 8013057: assert(_needs_gc ||
SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
Detect mmap() commit failures in Linux and Solaris os::commit_memory() impls and call vm_exit_out_of_memory(). Add os::commit_memory_or_exit(). Also tidy up some NMT accounting and some mmap() return value checking.
Reviewed-by: zgu, stefank, dholmes, dsamersoff
---
hotspot/src/os/bsd/vm/os_bsd.cpp | 46 ++++++-
hotspot/src/os/bsd/vm/perfMemory_bsd.cpp | 4 +-
hotspot/src/os/linux/vm/os_linux.cpp | 118 ++++++++++++++++--
hotspot/src/os/linux/vm/os_linux.hpp | 4 +
hotspot/src/os/linux/vm/perfMemory_linux.cpp | 4 +-
hotspot/src/os/solaris/vm/os_solaris.cpp | 93 ++++++++++++--
hotspot/src/os/solaris/vm/os_solaris.hpp | 3 +
.../src/os/solaris/vm/perfMemory_solaris.cpp | 4 +-
hotspot/src/os/windows/vm/os_windows.cpp | 59 +++++++--
.../src/os/windows/vm/perfMemory_windows.cpp | 4 +-
.../parallelScavenge/cardTableExtension.cpp | 10 +-
.../parallelScavenge/psVirtualspace.cpp | 12 +-
.../src/share/vm/memory/allocation.inline.hpp | 5 +-
.../src/share/vm/memory/cardTableModRefBS.cpp | 16 +--
hotspot/src/share/vm/prims/whitebox.cpp | 2 +-
hotspot/src/share/vm/runtime/os.cpp | 12 ++
hotspot/src/share/vm/runtime/os.hpp | 26 +++-
hotspot/src/share/vm/runtime/virtualspace.cpp | 15 ++-
18 files changed, 357 insertions(+), 80 deletions(-)
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index e1864effbcf..0297ef2d927 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -2074,6 +2074,13 @@ void bsd_wrap_code(char* base, size_t size) {
}
}
+static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
+ int err) {
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
+ strerror(err), err);
+}
+
// NOTE: Bsd kernel does not really reserve the pages for us.
// All it does is to check if there are enough free pages
// left at the time of mmap(). This could be a potential
@@ -2082,18 +2089,45 @@ bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
#ifdef __OpenBSD__
// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
- return ::mprotect(addr, size, prot) == 0;
+ if (::mprotect(addr, size, prot) == 0) {
+ return true;
+ }
#else
uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
- return res != (uintptr_t) MAP_FAILED;
+ if (res != (uintptr_t) MAP_FAILED) {
+ return true;
+ }
#endif
-}
+ // Warn about any commit errors we see in non-product builds just
+ // in case mmap() doesn't work as described on the man page.
+ NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)
+
+ return false;
+}
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
bool exec) {
- return commit_memory(addr, size, exec);
+ // alignment_hint is ignored on this OS
+ return pd_commit_memory(addr, size, exec);
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ if (!pd_commit_memory(addr, size, exec)) {
+ // add extra info in product mode for vm_exit_out_of_memory():
+ PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)
+ vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+ }
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size,
+ size_t alignment_hint, bool exec,
+ const char* mesg) {
+ // alignment_hint is ignored on this OS
+ pd_commit_memory_or_exit(addr, size, exec, mesg);
}
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
@@ -2148,7 +2182,7 @@ bool os::pd_uncommit_memory(char* addr, size_t size) {
}
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
- return os::commit_memory(addr, size);
+ return os::commit_memory(addr, size, !ExecMem);
}
// If this is a growable mapping, remove the guard pages entirely by
@@ -3512,7 +3546,7 @@ jint os::init_2(void)
if (!UseMembar) {
address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
+ guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
os::set_memory_serialize_page( mem_serialize_page );
#ifndef PRODUCT
diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
index 3b794b70230..5d82c4d988b 100644
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@ static char* create_standard_memory(size_t size) {
}
// commit memory
- if (!os::commit_memory(mapAddress, size)) {
+ if (!os::commit_memory(mapAddress, size, !ExecMem)) {
if (PrintMiscellaneous && Verbose) {
warning("Could not commit PerfData memory\n");
}
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 4b975461ee9..159ff430cec 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -2612,11 +2612,49 @@ void linux_wrap_code(char* base, size_t size) {
}
}
+static bool recoverable_mmap_error(int err) {
+ // See if the error is one we can let the caller handle. This
+ // list of errno values comes from JBS-6843484. I can't find a
+ // Linux man page that documents this specific set of errno
+ // values so while this list currently matches Solaris, it may
+ // change as we gain experience with this failure mode.
+ switch (err) {
+ case EBADF:
+ case EINVAL:
+ case ENOTSUP:
+ // let the caller deal with these errors
+ return true;
+
+ default:
+ // Any remaining errors on this OS can cause our reserved mapping
+ // to be lost. That can cause confusion where different data
+ // structures think they have the same memory mapped. The worst
+ // scenario is if both the VM and a library think they have the
+ // same memory mapped.
+ return false;
+ }
+}
+
+static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
+ int err) {
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
+ strerror(err), err);
+}
+
+static void warn_fail_commit_memory(char* addr, size_t size,
+ size_t alignment_hint, bool exec,
+ int err) {
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
+ alignment_hint, exec, strerror(err), err);
+}
+
// NOTE: Linux kernel does not really reserve the pages for us.
// All it does is to check if there are enough free pages
// left at the time of mmap(). This could be a potential
// problem.
-bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
+int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
@@ -2624,9 +2662,32 @@ bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
if (UseNUMAInterleaving) {
numa_make_global(addr, size);
}
- return true;
+ return 0;
+ }
+
+ int err = errno; // save errno from mmap() call above
+
+ if (!recoverable_mmap_error(err)) {
+ warn_fail_commit_memory(addr, size, exec, err);
+ vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
+ }
+
+ return err;
+}
+
+bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
+ return os::Linux::commit_memory_impl(addr, size, exec) == 0;
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ int err = os::Linux::commit_memory_impl(addr, size, exec);
+ if (err != 0) {
+ // the caller wants all commit errors to exit with the specified mesg:
+ warn_fail_commit_memory(addr, size, exec, err);
+ vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
}
- return false;
}
// Define MAP_HUGETLB here so we can build HotSpot on old systems.
@@ -2639,8 +2700,9 @@ bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
#define MADV_HUGEPAGE 14
#endif
-bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
- bool exec) {
+int os::Linux::commit_memory_impl(char* addr, size_t size,
+ size_t alignment_hint, bool exec) {
+ int err;
if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
uintptr_t res =
@@ -2651,16 +2713,46 @@ bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
if (UseNUMAInterleaving) {
numa_make_global(addr, size);
}
- return true;
+ return 0;
+ }
+
+ err = errno; // save errno from mmap() call above
+
+ if (!recoverable_mmap_error(err)) {
+ // However, it is not clear that this loss of our reserved mapping
+ // happens with large pages on Linux or that we cannot recover
+ // from the loss. For now, we just issue a warning and we don't
+ // call vm_exit_out_of_memory(). This issue is being tracked by
+ // JBS-8007074.
+ warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
+// vm_exit_out_of_memory(size, OOM_MMAP_ERROR,
+// "committing reserved memory.");
}
// Fall through and try to use small pages
}
- if (commit_memory(addr, size, exec)) {
+ err = os::Linux::commit_memory_impl(addr, size, exec);
+ if (err == 0) {
realign_memory(addr, size, alignment_hint);
- return true;
}
- return false;
+ return err;
+}
+
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
+ bool exec) {
+ return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size,
+ size_t alignment_hint, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
+ if (err != 0) {
+ // the caller wants all commit errors to exit with the specified mesg:
+ warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
+ vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+ }
}
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
@@ -2678,7 +2770,7 @@ void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
// small pages on top of the SHM segment. This method always works for small pages, so we
// allow that in any case.
if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
- commit_memory(addr, bytes, alignment_hint, false);
+ commit_memory(addr, bytes, alignment_hint, !ExecMem);
}
}
@@ -2931,7 +3023,7 @@ bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
}
- return os::commit_memory(addr, size);
+ return os::commit_memory(addr, size, !ExecMem);
}
// If this is a growable mapping, remove the guard pages entirely by
@@ -3053,7 +3145,7 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
-1, 0);
- if (p != (void *) -1) {
+ if (p != MAP_FAILED) {
// We don't know if this really is a huge page or not.
FILE *fp = fopen("/proc/self/maps", "r");
if (fp) {
@@ -4393,7 +4485,7 @@ jint os::init_2(void)
if (!UseMembar) {
address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
+ guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
os::set_memory_serialize_page( mem_serialize_page );
#ifndef PRODUCT
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index 41c29f680a7..8c5032fc23b 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -76,6 +76,10 @@ class Linux {
static julong physical_memory() { return _physical_memory; }
static void initialize_system_info();
+ static int commit_memory_impl(char* addr, size_t bytes, bool exec);
+ static int commit_memory_impl(char* addr, size_t bytes,
+ size_t alignment_hint, bool exec);
+
static void set_glibc_version(const char *s) { _glibc_version = s; }
static void set_libpthread_version(const char *s) { _libpthread_version = s; }
diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
index d1859b9a6c5..91b5f26c681 100644
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@ static char* create_standard_memory(size_t size) {
}
// commit memory
- if (!os::commit_memory(mapAddress, size)) {
+ if (!os::commit_memory(mapAddress, size, !ExecMem)) {
if (PrintMiscellaneous && Verbose) {
warning("Could not commit PerfData memory\n");
}
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 5df7a8b403b..73e9f064a78 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -2784,7 +2784,42 @@ int os::vm_allocation_granularity() {
return page_size;
}
-bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
+static bool recoverable_mmap_error(int err) {
+ // See if the error is one we can let the caller handle. This
+ // list of errno values comes from the Solaris mmap(2) man page.
+ switch (err) {
+ case EBADF:
+ case EINVAL:
+ case ENOTSUP:
+ // let the caller deal with these errors
+ return true;
+
+ default:
+ // Any remaining errors on this OS can cause our reserved mapping
+ // to be lost. That can cause confusion where different data
+ // structures think they have the same memory mapped. The worst
+ // scenario is if both the VM and a library think they have the
+ // same memory mapped.
+ return false;
+ }
+}
+
+static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec,
+ int err) {
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec,
+ strerror(err), err);
+}
+
+static void warn_fail_commit_memory(char* addr, size_t bytes,
+ size_t alignment_hint, bool exec,
+ int err) {
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes,
+ alignment_hint, exec, strerror(err), err);
+}
+
+int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) {
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
size_t size = bytes;
char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
@@ -2792,14 +2827,38 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
if (UseNUMAInterleaving) {
numa_make_global(addr, bytes);
}
- return true;
+ return 0;
}
- return false;
+
+ int err = errno; // save errno from mmap() call in mmap_chunk()
+
+ if (!recoverable_mmap_error(err)) {
+ warn_fail_commit_memory(addr, bytes, exec, err);
+ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory.");
+ }
+
+ return err;
}
-bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
- bool exec) {
- if (commit_memory(addr, bytes, exec)) {
+bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
+ return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
+ if (err != 0) {
+ // the caller wants all commit errors to exit with the specified mesg:
+ warn_fail_commit_memory(addr, bytes, exec, err);
+ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
+ }
+}
+
+int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
+ size_t alignment_hint, bool exec) {
+ int err = Solaris::commit_memory_impl(addr, bytes, exec);
+ if (err == 0) {
if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
// If the large page size has been set and the VM
// is using large pages, use the large page size
@@ -2821,9 +2880,25 @@ bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
// Since this is a hint, ignore any failures.
(void)Solaris::set_mpss_range(addr, bytes, page_size);
}
- return true;
}
- return false;
+ return err;
+}
+
+bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
+ bool exec) {
+ return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t bytes,
+ size_t alignment_hint, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec);
+ if (err != 0) {
+ // the caller wants all commit errors to exit with the specified mesg:
+ warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err);
+ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
+ }
}
// Uncommit the pages in a specified region.
@@ -2835,7 +2910,7 @@ void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) {
}
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
- return os::commit_memory(addr, size);
+ return os::commit_memory(addr, size, !ExecMem);
}
bool os::remove_stack_guard_pages(char* addr, size_t size) {
diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp
index 99b757cd6ad..f7f0a3d7283 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp
@@ -168,6 +168,9 @@ class Solaris {
static int _dev_zero_fd;
static int get_dev_zero_fd() { return _dev_zero_fd; }
static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; }
+ static int commit_memory_impl(char* addr, size_t bytes, bool exec);
+ static int commit_memory_impl(char* addr, size_t bytes,
+ size_t alignment_hint, bool exec);
static char* mmap_chunk(char *addr, size_t size, int flags, int prot);
static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed);
static bool mpss_sanity_check(bool warn, size_t * page_size);
diff --git a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
index 3b7744a482e..4da5f19aef0 100644
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@ static char* create_standard_memory(size_t size) {
}
// commit memory
- if (!os::commit_memory(mapAddress, size)) {
+ if (!os::commit_memory(mapAddress, size, !ExecMem)) {
if (PrintMiscellaneous && Verbose) {
warning("Could not commit PerfData memory\n");
}
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index baa17768215..dd462804856 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -2524,7 +2524,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
addr = (address)((uintptr_t)addr &
(~((uintptr_t)os::vm_page_size() - (uintptr_t)1)));
os::commit_memory((char *)addr, thread->stack_base() - addr,
- false );
+ !ExecMem);
return EXCEPTION_CONTINUE_EXECUTION;
}
else
@@ -3172,6 +3172,15 @@ bool os::release_memory_special(char* base, size_t bytes) {
void os::print_statistics() {
}
+static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec) {
+ int err = os::get_last_error();
+ char buf[256];
+ size_t buf_len = os::lasterror(buf, sizeof(buf));
+ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+ ", %d) failed; error='%s' (DOS error/errno=%d)", addr, bytes,
+ exec, buf_len != 0 ? buf : "", err);
+}
+
bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
if (bytes == 0) {
// Don't bother the OS with noops.
@@ -3186,11 +3195,17 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
// is always within a reserve covered by a single VirtualAlloc
// in that case we can just do a single commit for the requested size
if (!UseNUMAInterleaving) {
- if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false;
+ if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) {
+ NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
+ return false;
+ }
if (exec) {
DWORD oldprot;
// Windows doc says to use VirtualProtect to get execute permissions
- if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
+ if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) {
+ NOT_PRODUCT(warn_fail_commit_memory(addr, bytes, exec);)
+ return false;
+ }
}
return true;
} else {
@@ -3205,12 +3220,20 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
MEMORY_BASIC_INFORMATION alloc_info;
VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
- if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL)
+ if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT,
+ PAGE_READWRITE) == NULL) {
+ NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
+ exec);)
return false;
+ }
if (exec) {
DWORD oldprot;
- if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
+ if (!VirtualProtect(next_alloc_addr, bytes_to_rq,
+ PAGE_EXECUTE_READWRITE, &oldprot)) {
+ NOT_PRODUCT(warn_fail_commit_memory(next_alloc_addr, bytes_to_rq,
+ exec);)
return false;
+ }
}
bytes_remaining -= bytes_to_rq;
next_alloc_addr += bytes_to_rq;
@@ -3222,7 +3245,24 @@ bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
bool exec) {
- return commit_memory(addr, size, exec);
+ // alignment_hint is ignored on this OS
+ return pd_commit_memory(addr, size, exec);
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
+ const char* mesg) {
+ assert(mesg != NULL, "mesg must be specified");
+ if (!pd_commit_memory(addr, size, exec)) {
+ warn_fail_commit_memory(addr, size, exec);
+ vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
+ }
+}
+
+void os::pd_commit_memory_or_exit(char* addr, size_t size,
+ size_t alignment_hint, bool exec,
+ const char* mesg) {
+ // alignment_hint is ignored on this OS
+ pd_commit_memory_or_exit(addr, size, exec, mesg);
}
bool os::pd_uncommit_memory(char* addr, size_t bytes) {
@@ -3240,7 +3280,7 @@ bool os::pd_release_memory(char* addr, size_t bytes) {
}
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
- return os::commit_memory(addr, size);
+ return os::commit_memory(addr, size, !ExecMem);
}
bool os::remove_stack_guard_pages(char* addr, size_t size) {
@@ -3264,8 +3304,9 @@ bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
// Strange enough, but on Win32 one can change protection only for committed
// memory, not a big deal anyway, as bytes less or equal than 64K
- if (!is_committed && !commit_memory(addr, bytes, prot == MEM_PROT_RWX)) {
- fatal("cannot commit protection page");
+ if (!is_committed) {
+ commit_memory_or_exit(addr, bytes, prot == MEM_PROT_RWX,
+ "cannot commit protection page");
}
// One cannot use os::guard_memory() here, as on Win32 guard page
// have different (one-shot) semantics, from MSDN on PAGE_GUARD:
diff --git a/hotspot/src/os/windows/vm/perfMemory_windows.cpp b/hotspot/src/os/windows/vm/perfMemory_windows.cpp
index 2f25414d1b7..2c3463edb30 100644
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@ static char* create_standard_memory(size_t size) {
}
// commit memory
- if (!os::commit_memory(mapAddress, size)) {
+ if (!os::commit_memory(mapAddress, size, !ExecMem)) {
if (PrintMiscellaneous && Verbose) {
warning("Could not commit PerfData memory\n");
}
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
index b2134f10e92..82ea39b525a 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -565,11 +565,9 @@ bool CardTableExtension::resize_commit_uncommit(int changed_region,
if(new_start_aligned < new_end_for_commit) {
MemRegion new_committed =
MemRegion(new_start_aligned, new_end_for_commit);
- if (!os::commit_memory((char*)new_committed.start(),
- new_committed.byte_size())) {
- vm_exit_out_of_memory(new_committed.byte_size(), OOM_MMAP_ERROR,
- "card table expansion");
- }
+ os::commit_memory_or_exit((char*)new_committed.start(),
+ new_committed.byte_size(), !ExecMem,
+ "card table expansion");
}
result = true;
} else if (new_start_aligned > cur_committed.start()) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
index e194767073d..9999527302a 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,7 +101,8 @@ bool PSVirtualSpace::expand_by(size_t bytes) {
}
char* const base_addr = committed_high_addr();
- bool result = special() || os::commit_memory(base_addr, bytes, alignment());
+ bool result = special() ||
+ os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
if (result) {
_committed_high_addr += bytes;
}
@@ -154,7 +155,7 @@ PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
if (tmp_bytes > 0) {
char* const commit_base = committed_high_addr();
if (other_space->special() ||
- os::commit_memory(commit_base, tmp_bytes, alignment())) {
+ os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
// Reduce the reserved region in the other space.
other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
other_space->reserved_high_addr(),
@@ -269,7 +270,8 @@ bool PSVirtualSpaceHighToLow::expand_by(size_t bytes) {
}
char* const base_addr = committed_low_addr() - bytes;
- bool result = special() || os::commit_memory(base_addr, bytes, alignment());
+ bool result = special() ||
+ os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
if (result) {
_committed_low_addr -= bytes;
}
@@ -322,7 +324,7 @@ size_t PSVirtualSpaceHighToLow::expand_into(PSVirtualSpace* other_space,
if (tmp_bytes > 0) {
char* const commit_base = committed_low_addr() - tmp_bytes;
if (other_space->special() ||
- os::commit_memory(commit_base, tmp_bytes, alignment())) {
+ os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem)) {
// Reduce the reserved region in the other space.
other_space->set_reserved(other_space->reserved_low_addr(),
other_space->reserved_high_addr() - tmp_bytes,
diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp
index 138dd660a9c..f59ae5b4f0e 100644
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp
@@ -146,10 +146,7 @@ E* ArrayAllocator::allocate(size_t length) {
vm_exit_out_of_memory(_size, OOM_MMAP_ERROR, "Allocator (reserve)");
}
- bool success = os::commit_memory(_addr, _size, false /* executable */);
- if (!success) {
- vm_exit_out_of_memory(_size, OOM_MMAP_ERROR, "Allocator (commit)");
- }
+ os::commit_memory_or_exit(_addr, _size, !ExecMem, "Allocator (commit)");
return (E*)_addr;
}
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
index 7cc68debfe5..39f717ba0c6 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
@@ -110,11 +110,8 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
jbyte* guard_card = &_byte_map[_guard_index];
uintptr_t guard_page = align_size_down((uintptr_t)guard_card, _page_size);
_guard_region = MemRegion((HeapWord*)guard_page, _page_size);
- if (!os::commit_memory((char*)guard_page, _page_size, _page_size)) {
- // Do better than this for Merlin
- vm_exit_out_of_memory(_page_size, OOM_MMAP_ERROR, "card table last card");
- }
-
+ os::commit_memory_or_exit((char*)guard_page, _page_size, _page_size,
+ !ExecMem, "card table last card");
*guard_card = last_card;
_lowest_non_clean =
@@ -312,12 +309,9 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
MemRegion(cur_committed.end(), new_end_for_commit);
assert(!new_committed.is_empty(), "Region should not be empty here");
- if (!os::commit_memory((char*)new_committed.start(),
- new_committed.byte_size(), _page_size)) {
- // Do better than this for Merlin
- vm_exit_out_of_memory(new_committed.byte_size(), OOM_MMAP_ERROR,
- "card table expansion");
- }
+ os::commit_memory_or_exit((char*)new_committed.start(),
+ new_committed.byte_size(), _page_size,
+ !ExecMem, "card table expansion");
// Use new_end_aligned (as opposed to new_end_for_commit) because
// the cur_committed region may include the guard region.
} else if (new_end_aligned < cur_committed.end()) {
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
index 92f2349bb7c..3552ff2062f 100644
--- a/hotspot/src/share/vm/prims/whitebox.cpp
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -159,7 +159,7 @@ WB_END
WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
- os::commit_memory((char *)(uintptr_t)addr, size);
+ os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
WB_END
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 7775d9410d5..eb929bce838 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -1503,6 +1503,18 @@ bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
return res;
}
+void os::commit_memory_or_exit(char* addr, size_t bytes, bool executable,
+ const char* mesg) {
+ pd_commit_memory_or_exit(addr, bytes, executable, mesg);
+ MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
+}
+
+void os::commit_memory_or_exit(char* addr, size_t size, size_t alignment_hint,
+ bool executable, const char* mesg) {
+ os::pd_commit_memory_or_exit(addr, size, alignment_hint, executable, mesg);
+ MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
+}
+
bool os::uncommit_memory(char* addr, size_t bytes) {
bool res = pd_uncommit_memory(addr, bytes);
if (res) {
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index 3f2554399f4..e1866919df4 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -78,6 +78,10 @@ enum ThreadPriority { // JLS 20.20.1-3
CriticalPriority = 11 // Critical thread priority
};
+// Executable parameter flag for os::commit_memory() and
+// os::commit_memory_or_exit().
+const bool ExecMem = true;
+
// Typedef for structured exception handling support
typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
@@ -104,9 +108,16 @@ class os: AllStatic {
static char* pd_attempt_reserve_memory_at(size_t bytes, char* addr);
static void pd_split_reserved_memory(char *base, size_t size,
size_t split, bool realloc);
- static bool pd_commit_memory(char* addr, size_t bytes, bool executable = false);
+ static bool pd_commit_memory(char* addr, size_t bytes, bool executable);
static bool pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
- bool executable = false);
+ bool executable);
+ // Same as pd_commit_memory() that either succeeds or calls
+ // vm_exit_out_of_memory() with the specified mesg.
+ static void pd_commit_memory_or_exit(char* addr, size_t bytes,
+ bool executable, const char* mesg);
+ static void pd_commit_memory_or_exit(char* addr, size_t size,
+ size_t alignment_hint,
+ bool executable, const char* mesg);
static bool pd_uncommit_memory(char* addr, size_t bytes);
static bool pd_release_memory(char* addr, size_t bytes);
@@ -261,9 +272,16 @@ class os: AllStatic {
static char* attempt_reserve_memory_at(size_t bytes, char* addr);
static void split_reserved_memory(char *base, size_t size,
size_t split, bool realloc);
- static bool commit_memory(char* addr, size_t bytes, bool executable = false);
+ static bool commit_memory(char* addr, size_t bytes, bool executable);
static bool commit_memory(char* addr, size_t size, size_t alignment_hint,
- bool executable = false);
+ bool executable);
+ // Same as commit_memory() that either succeeds or calls
+ // vm_exit_out_of_memory() with the specified mesg.
+ static void commit_memory_or_exit(char* addr, size_t bytes,
+ bool executable, const char* mesg);
+ static void commit_memory_or_exit(char* addr, size_t size,
+ size_t alignment_hint,
+ bool executable, const char* mesg);
static bool uncommit_memory(char* addr, size_t bytes);
static bool release_memory(char* addr, size_t bytes);
diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp
index ba68e887e17..9096a034cef 100644
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp
@@ -533,11 +533,13 @@ bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
lower_high() + lower_needs <= lower_high_boundary(),
"must not expand beyond region");
if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
- debug_only(warning("os::commit_memory failed"));
+ debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
+ ", lower_needs=" SIZE_FORMAT ", %d) failed",
+ lower_high(), lower_needs, _executable);)
return false;
} else {
_lower_high += lower_needs;
- }
+ }
}
if (middle_needs > 0) {
assert(lower_high_boundary() <= middle_high() &&
@@ -545,7 +547,10 @@ bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
"must not expand beyond region");
if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
_executable)) {
- debug_only(warning("os::commit_memory failed"));
+ debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
+ ", middle_needs=" SIZE_FORMAT ", " SIZE_FORMAT
+ ", %d) failed", middle_high(), middle_needs,
+ middle_alignment(), _executable);)
return false;
}
_middle_high += middle_needs;
@@ -555,7 +560,9 @@ bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
upper_high() + upper_needs <= upper_high_boundary(),
"must not expand beyond region");
if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
- debug_only(warning("os::commit_memory failed"));
+ debug_only(warning("INFO: os::commit_memory(" PTR_FORMAT
+ ", upper_needs=" SIZE_FORMAT ", %d) failed",
+ upper_high(), upper_needs, _executable);)
return false;
} else {
_upper_high += upper_needs;
From e72f763439f0cfef0670b030e8450a92ceea4e71 Mon Sep 17 00:00:00 2001
From: Christian Tornqvist
Date: Thu, 13 Jun 2013 21:57:56 +0200
Subject: [PATCH 036/136] 8016065: Write regression test for 7167142
Regression tests written for both test cases (.hotspotrc and .hotspot_compiler). Also reviewed by mikhailo.seledtsov@oracle.com
Reviewed-by: zgu, coleenp
---
.../CompilerConfigFileWarning.java | 50 +++++++++++++++++++
.../CommandLine/ConfigFileWarning.java | 50 +++++++++++++++++++
2 files changed, 100 insertions(+)
create mode 100644 hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java
create mode 100644 hotspot/test/runtime/CommandLine/ConfigFileWarning.java
diff --git a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java
new file mode 100644
index 00000000000..1f1894419ab
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7167142
+ * @summary Warn if unused .hotspot_compiler file is present
+ * @library /testlibrary
+ */
+
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+public class CompilerConfigFileWarning {
+ public static void main(String[] args) throws Exception {
+ String vmVersion = System.getProperty("java.vm.version");
+ if (vmVersion.toLowerCase().contains("debug") || vmVersion.toLowerCase().contains("jvmg")) {
+ System.out.println("Skip on debug builds since we'll always read the file there");
+ return;
+ }
+
+ PrintWriter pw = new PrintWriter(".hotspot_compiler");
+ pw.println("aa");
+ pw.close();
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file.");
+ }
+}
diff --git a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java
new file mode 100644
index 00000000000..470808eaff3
--- /dev/null
+++ b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 7167142
+ * @summary Warn if unused .hotspot_rc file is present
+ * @library /testlibrary
+ */
+
+import java.io.PrintWriter;
+import com.oracle.java.testlibrary.*;
+
+public class ConfigFileWarning {
+ public static void main(String[] args) throws Exception {
+ String vmVersion = System.getProperty("java.vm.version");
+ if (vmVersion.toLowerCase().contains("debug") || vmVersion.toLowerCase().contains("jvmg")) {
+ System.out.println("Skip on debug builds since we'll always read the file there");
+ return;
+ }
+
+ PrintWriter pw = new PrintWriter(".hotspotrc");
+ pw.println("aa");
+ pw.close();
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file.");
+ }
+}
From e1219b994da3ab31bf5bc8f8af912c52a00fbb97 Mon Sep 17 00:00:00 2001
From: Mikhailo Seledtsov
Date: Thu, 13 Jun 2013 22:00:06 +0200
Subject: [PATCH 037/136] 8015324: Create tests for CDS feature
Wrote tests for use of CDS with ObjectAlignmentInBytes CL option
Reviewed-by: coleenp, ctornqvi, hseigel
---
.../CdsDifferentObjectAlignment.java | 88 ++++++++++++++++++
.../CdsSameObjectAlignment.java | 92 +++++++++++++++++++
.../com/oracle/java/testlibrary/Platform.java | 62 +++++++++++++
.../oracle/java/testlibrary/ProcessTools.java | 4 +-
4 files changed, 243 insertions(+), 3 deletions(-)
create mode 100644 hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java
create mode 100644 hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java
create mode 100644 hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java
new file mode 100644
index 00000000000..0e9bb07762f
--- /dev/null
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentObjectAlignment.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 CdsDifferentObjectAlignment
+ * @summary Testing CDS (class data sharing) using varying object alignment.
+ * Using different object alignment for each dump/load pair.
+ * This is a negative test; using object alignment for loading that
+ * is different from object alignment for creating a CDS file
+ * should fail when loading.
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CdsDifferentObjectAlignment {
+ public static void main(String[] args) throws Exception {
+ String nativeWordSize = System.getProperty("sun.arch.data.model");
+ if (!Platform.is64bit()) {
+ System.out.println("ObjectAlignmentInBytes for CDS is only " +
+ "supported on 64bit platforms; this plaform is " +
+ nativeWordSize);
+ System.out.println("Skipping the test");
+ } else {
+ createAndLoadSharedArchive(16, 64);
+ createAndLoadSharedArchive(64, 32);
+ }
+ }
+
+
+ // Parameters are object alignment expressed in bytes
+ private static void
+ createAndLoadSharedArchive(int createAlignment, int loadAlignment)
+ throws Exception {
+ String createAlignmentArgument = "-XX:ObjectAlignmentInBytes=" +
+ createAlignment;
+ String loadAlignmentArgument = "-XX:ObjectAlignmentInBytes=" +
+ loadAlignment;
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa",
+ "-Xshare:dump",
+ createAlignmentArgument);
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa",
+ "-Xshare:on",
+ loadAlignmentArgument,
+ "-version");
+
+ output = new OutputAnalyzer(pb.start());
+ String expectedErrorMsg =
+ String.format(
+ "The shared archive file's ObjectAlignmentInBytes of %d " +
+ "does not equal the current ObjectAlignmentInBytes of %d",
+ createAlignment,
+ loadAlignment);
+
+ output.shouldContain(expectedErrorMsg);
+ output.shouldHaveExitValue(1);
+ }
+}
diff --git a/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java
new file mode 100644
index 00000000000..e95bae3a790
--- /dev/null
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsSameObjectAlignment.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 CdsSameObjectAlignment
+ * @summary Testing CDS (class data sharing) using varying object alignment.
+ * Using same object alignment for each dump/load pair
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CdsSameObjectAlignment {
+ public static void main(String[] args) throws Exception {
+ String nativeWordSize = System.getProperty("sun.arch.data.model");
+ if (!Platform.is64bit()) {
+ System.out.println("ObjectAlignmentInBytes for CDS is only " +
+ "supported on 64bit platforms; this plaform is " +
+ nativeWordSize);
+ System.out.println("Skipping the test");
+ } else {
+ dumpAndLoadSharedArchive(8);
+ dumpAndLoadSharedArchive(16);
+ dumpAndLoadSharedArchive(32);
+ dumpAndLoadSharedArchive(64);
+ }
+ }
+
+ private static void
+ dumpAndLoadSharedArchive(int objectAlignmentInBytes) throws Exception {
+ String objectAlignmentArg = "-XX:ObjectAlignmentInBytes="
+ + objectAlignmentInBytes;
+ System.out.println("dumpAndLoadSharedArchive(): objectAlignmentInBytes = "
+ + objectAlignmentInBytes);
+
+ // create shared archive
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa",
+ "-Xshare:dump",
+ objectAlignmentArg);
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+
+ // run using the shared archive
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=./sample.jsa",
+ "-Xshare:on",
+ objectAlignmentArg,
+ "-version");
+
+ output = new OutputAnalyzer(pb.start());
+
+ try {
+ output.shouldContain("sharing");
+ output.shouldHaveExitValue(0);
+ } catch (RuntimeException e) {
+ // CDS uses absolute addresses for performance.
+ // It will try to reserve memory at a specific address;
+ // there is a chance such reservation will fail
+ // If it does, it is NOT considered a failure of the feature,
+ // rather a possible expected outcome, though not likely
+ output.shouldContain(
+ "Unable to reserve shared space at required address");
+ output.shouldHaveExitValue(1);
+ }
+ }
+}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
new file mode 100644
index 00000000000..cfc1a271c13
--- /dev/null
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Platform.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 com.oracle.java.testlibrary;
+
+public class Platform {
+ private static final String osName = System.getProperty("os.name");
+ private static final String dataModel = System.getProperty("sun.arch.data.model");
+ private static final String vmVersion = System.getProperty("java.vm.version");
+
+ public static boolean is64bit() {
+ return dataModel.equals("64");
+ }
+
+ public static boolean isSolaris() {
+ return osName.toLowerCase().startsWith("sunos");
+ }
+
+ public static boolean isWindows() {
+ return osName.toLowerCase().startsWith("win");
+ }
+
+ public static boolean isOSX() {
+ return osName.toLowerCase().startsWith("mac");
+ }
+
+ public static boolean isLinux() {
+ return osName.toLowerCase().startsWith("linux");
+ }
+
+ public static String getOsName() {
+ return osName;
+ }
+
+ public static boolean isDebugBuild() {
+ return vmVersion.toLowerCase().contains("debug");
+ }
+
+ public static String getVMVersion() {
+ return vmVersion;
+ }
+}
diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java
index 42203d17ff0..6e0fdae6564 100644
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java
@@ -112,10 +112,8 @@ public final class ProcessTools {
* @return String[] with platform specific arguments, empty if there are none
*/
public static String[] getPlatformSpecificVMArgs() {
- String osName = System.getProperty("os.name");
- String dataModel = System.getProperty("sun.arch.data.model");
- if (osName.equals("SunOS") && dataModel.equals("64")) {
+ if (Platform.is64bit() && Platform.isSolaris()) {
return new String[] { "-d64" };
}
From 53448fdbed35ff03776aaddbacf930f1f1802d14 Mon Sep 17 00:00:00 2001
From: Calvin Cheung
Date: Thu, 13 Jun 2013 22:02:40 -0700
Subject: [PATCH 038/136] 8014431: cleanup warnings indicated by the
-Wunused-value compiler option on linux
Co-authored-by: Jeremy Manson
Reviewed-by: dholmes, coleenp
---
hotspot/make/linux/makefiles/gcc.make | 2 +-
.../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 2 +-
.../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 2 +-
hotspot/src/share/vm/c1/c1_IR.cpp | 6 ++--
hotspot/src/share/vm/ci/ciUtilities.hpp | 4 +--
.../share/vm/classfile/genericSignatures.cpp | 4 +--
hotspot/src/share/vm/classfile/verifier.hpp | 4 +--
hotspot/src/share/vm/code/dependencies.cpp | 2 +-
hotspot/src/share/vm/code/nmethod.cpp | 3 +-
.../src/share/vm/memory/cardTableModRefBS.cpp | 2 +-
hotspot/src/share/vm/memory/universe.cpp | 4 ++-
hotspot/src/share/vm/opto/memnode.cpp | 2 +-
hotspot/src/share/vm/prims/forte.cpp | 2 +-
.../src/share/vm/runtime/sharedRuntime.cpp | 2 +-
.../share/vm/services/diagnosticArgument.cpp | 2 +-
hotspot/src/share/vm/utilities/exceptions.hpp | 10 +++----
hotspot/src/share/vm/utilities/taskqueue.hpp | 30 +++++++++++++++----
17 files changed, 52 insertions(+), 31 deletions(-)
diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make
index 6ef416dfbec..0382b7a3bf5 100644
--- a/hotspot/make/linux/makefiles/gcc.make
+++ b/hotspot/make/linux/makefiles/gcc.make
@@ -214,7 +214,7 @@ ifeq ($(USE_CLANG), true)
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
endif
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value
ifeq ($(USE_CLANG),)
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index 7422ed39d24..f24c5fdb38d 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -83,7 +83,7 @@ class StubGenerator: public StubCodeGenerator {
private:
#ifdef PRODUCT
-#define inc_counter_np(counter) (0)
+#define inc_counter_np(counter) ((void)0)
#else
void inc_counter_np_(int& counter) {
__ incrementl(ExternalAddress((address)&counter));
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index fb9c1ddd4b9..7b8408d7131 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -81,7 +81,7 @@ class StubGenerator: public StubCodeGenerator {
private:
#ifdef PRODUCT
-#define inc_counter_np(counter) (0)
+#define inc_counter_np(counter) ((void)0)
#else
void inc_counter_np_(int& counter) {
// This can destroy rscratch1 if counter is far from the code cache
diff --git a/hotspot/src/share/vm/c1/c1_IR.cpp b/hotspot/src/share/vm/c1/c1_IR.cpp
index e9e73db0c06..13a7f790f6f 100644
--- a/hotspot/src/share/vm/c1/c1_IR.cpp
+++ b/hotspot/src/share/vm/c1/c1_IR.cpp
@@ -506,7 +506,7 @@ ComputeLinearScanOrder::ComputeLinearScanOrder(Compilation* c, BlockBegin* start
_loop_map(0, 0), // initialized later with correct size
_compilation(c)
{
- TRACE_LINEAR_SCAN(2, "***** computing linear-scan block order");
+ TRACE_LINEAR_SCAN(2, tty->print_cr("***** computing linear-scan block order"));
init_visited();
count_edges(start_block, NULL);
@@ -683,7 +683,7 @@ void ComputeLinearScanOrder::clear_non_natural_loops(BlockBegin* start_block) {
}
void ComputeLinearScanOrder::assign_loop_depth(BlockBegin* start_block) {
- TRACE_LINEAR_SCAN(3, "----- computing loop-depth and weight");
+ TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing loop-depth and weight"));
init_visited();
assert(_work_list.is_empty(), "work list must be empty before processing");
@@ -868,7 +868,7 @@ void ComputeLinearScanOrder::append_block(BlockBegin* cur) {
}
void ComputeLinearScanOrder::compute_order(BlockBegin* start_block) {
- TRACE_LINEAR_SCAN(3, "----- computing final block order");
+ TRACE_LINEAR_SCAN(3, tty->print_cr("----- computing final block order"));
// the start block is always the first block in the linear scan order
_linear_scan_order = new BlockList(_num_blocks);
diff --git a/hotspot/src/share/vm/ci/ciUtilities.hpp b/hotspot/src/share/vm/ci/ciUtilities.hpp
index 1a075bf6e98..2032a8f35e1 100644
--- a/hotspot/src/share/vm/ci/ciUtilities.hpp
+++ b/hotspot/src/share/vm/ci/ciUtilities.hpp
@@ -96,7 +96,7 @@
CLEAR_PENDING_EXCEPTION; \
return (result); \
} \
- (0
+ (void)(0
#define KILL_COMPILE_ON_ANY \
THREAD); \
@@ -104,7 +104,7 @@
fatal("unhandled ci exception"); \
CLEAR_PENDING_EXCEPTION; \
} \
-(0
+(void)(0
inline const char* bool_to_str(bool b) {
diff --git a/hotspot/src/share/vm/classfile/genericSignatures.cpp b/hotspot/src/share/vm/classfile/genericSignatures.cpp
index 33fbca051b7..3bbce2f8ce7 100644
--- a/hotspot/src/share/vm/classfile/genericSignatures.cpp
+++ b/hotspot/src/share/vm/classfile/genericSignatures.cpp
@@ -124,7 +124,7 @@ class DescriptorStream : public ResourceObj {
fatal(STREAM->parse_error()); \
} \
return NULL; \
- } 0
+ } (void)0
#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR()
#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR()
@@ -133,7 +133,7 @@ class DescriptorStream : public ResourceObj {
#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR()
#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR()
-#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); (0
+#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); ((void)0
#ifndef PRODUCT
void Identifier::print_on(outputStream* str) const {
diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp
index 34a1e0b3aff..9da0ac34a84 100644
--- a/hotspot/src/share/vm/classfile/verifier.hpp
+++ b/hotspot/src/share/vm/classfile/verifier.hpp
@@ -86,9 +86,9 @@ class StackMapTable;
// These macros are used similarly to CHECK macros but also check
// the status of the verifier and return if that has an error.
#define CHECK_VERIFY(verifier) \
- CHECK); if ((verifier)->has_error()) return; (0
+ CHECK); if ((verifier)->has_error()) return; ((void)0
#define CHECK_VERIFY_(verifier, result) \
- CHECK_(result)); if ((verifier)->has_error()) return (result); (0
+ CHECK_(result)); if ((verifier)->has_error()) return (result); ((void)0
class TypeOrigin VALUE_OBJ_CLASS_SPEC {
private:
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
index b790c3597d4..4db37819ea5 100644
--- a/hotspot/src/share/vm/code/dependencies.cpp
+++ b/hotspot/src/share/vm/code/dependencies.cpp
@@ -989,7 +989,7 @@ Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes,
assert(changes.involves_context(context_type), "irrelevant dependency");
Klass* new_type = changes.new_type();
- count_find_witness_calls();
+ (void)count_find_witness_calls();
NOT_PRODUCT(deps_find_witness_singles++);
// Current thread must be in VM (not native mode, as in CI):
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 53f8cd07be8..41eb628fb46 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -2615,7 +2615,8 @@ void nmethod::print_relocations() {
relocation_begin()-1+ip[1]);
for (; ip < index_end; ip++)
tty->print_cr(" (%d ?)", ip[0]);
- tty->print_cr(" @" INTPTR_FORMAT ": index_size=%d", ip, *ip++);
+ tty->print_cr(" @" INTPTR_FORMAT ": index_size=%d", ip, *ip);
+ ip++;
tty->print_cr("reloc_end @" INTPTR_FORMAT ":", ip);
}
}
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
index 39f717ba0c6..82336503eb4 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
@@ -412,7 +412,7 @@ void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
}
// Touch the last card of the covered region to show that it
// is committed (or SEGV).
- debug_only(*byte_for(_covered[ind].last());)
+ debug_only((void) (*byte_for(_covered[ind].last()));)
debug_only(verify_guard();)
}
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index e98ef0c77ad..2b3576d6784 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -529,7 +529,9 @@ void Universe::reinitialize_vtable_of(KlassHandle k_h, TRAPS) {
if (vt) vt->initialize_vtable(false, CHECK);
if (ko->oop_is_instance()) {
InstanceKlass* ik = (InstanceKlass*)ko;
- for (KlassHandle s_h(THREAD, ik->subklass()); s_h() != NULL; s_h = (THREAD, s_h()->next_sibling())) {
+ for (KlassHandle s_h(THREAD, ik->subklass());
+ s_h() != NULL;
+ s_h = KlassHandle(THREAD, s_h()->next_sibling())) {
reinitialize_vtable_of(s_h, CHECK);
}
}
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index fc59cebdc55..8139383b3a9 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -4384,7 +4384,7 @@ static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) {
}
}
#else // !ASSERT
-#define verify_memory_slice(m,i,n) (0) // PRODUCT version is no-op
+#define verify_memory_slice(m,i,n) (void)(0) // PRODUCT version is no-op
#endif
diff --git a/hotspot/src/share/vm/prims/forte.cpp b/hotspot/src/share/vm/prims/forte.cpp
index 737dcecd0e1..43da7494417 100644
--- a/hotspot/src/share/vm/prims/forte.cpp
+++ b/hotspot/src/share/vm/prims/forte.cpp
@@ -619,7 +619,7 @@ void collector_func_load(char* name,
void* null_argument_3);
#pragma weak collector_func_load
#define collector_func_load(x0,x1,x2,x3,x4,x5,x6) \
- ( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),0 : 0 )
+ ( collector_func_load ? collector_func_load(x0,x1,x2,x3,x4,x5,x6),(void)0 : (void)0 )
#endif // __APPLE__
#endif // !_WINDOWS
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index fe55e8b0e6b..c9f37f4e2df 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -2731,7 +2731,7 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver,
// ResourceObject, so do not put any ResourceMarks in here.
char *s = sig->as_C_string();
int len = (int)strlen(s);
- *s++; len--; // Skip opening paren
+ s++; len--; // Skip opening paren
char *t = s+len;
while( *(--t) != ')' ) ; // Find close paren
diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp
index e3e14053270..0a1c20d8a2c 100644
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp
@@ -247,7 +247,7 @@ template <> void DCmdArgument::init_value(TRAPS) {
} else {
_value._time = 0;
_value._nanotime = 0;
- strcmp(_value._unit, "ns");
+ strcpy(_value._unit, "ns");
}
}
diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp
index 089cd3e0811..32c6f35d8a5 100644
--- a/hotspot/src/share/vm/utilities/exceptions.hpp
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp
@@ -194,15 +194,15 @@ class Exceptions {
#define HAS_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->has_pending_exception())
#define CLEAR_PENDING_EXCEPTION (((ThreadShadow*)THREAD)->clear_pending_exception())
-#define CHECK THREAD); if (HAS_PENDING_EXCEPTION) return ; (0
-#define CHECK_(result) THREAD); if (HAS_PENDING_EXCEPTION) return result; (0
+#define CHECK THREAD); if (HAS_PENDING_EXCEPTION) return ; (void)(0
+#define CHECK_(result) THREAD); if (HAS_PENDING_EXCEPTION) return result; (void)(0
#define CHECK_0 CHECK_(0)
#define CHECK_NH CHECK_(Handle())
#define CHECK_NULL CHECK_(NULL)
#define CHECK_false CHECK_(false)
-#define CHECK_AND_CLEAR THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return; } (0
-#define CHECK_AND_CLEAR_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (0
+#define CHECK_AND_CLEAR THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return; } (void)(0
+#define CHECK_AND_CLEAR_(result) THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (void)(0
#define CHECK_AND_CLEAR_0 CHECK_AND_CLEAR_(0)
#define CHECK_AND_CLEAR_NH CHECK_AND_CLEAR_(Handle())
#define CHECK_AND_CLEAR_NULL CHECK_AND_CLEAR_(NULL)
@@ -282,7 +282,7 @@ class Exceptions {
CLEAR_PENDING_EXCEPTION; \
ex->print(); \
ShouldNotReachHere(); \
- } (0
+ } (void)(0
// ExceptionMark is a stack-allocated helper class for local exception handling.
// It is used with the EXCEPTION_MARK macro.
diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp
index 980b7e973e0..aea96c8581c 100644
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp
@@ -340,8 +340,12 @@ bool GenericTaskQueue::push_slow(E t, uint dirty_n_elems) {
if (dirty_n_elems == N - 1) {
// Actually means 0, so do the push.
uint localBot = _bottom;
- // g++ complains if the volatile result of the assignment is unused.
- const_cast(_elems[localBot] = t);
+ // g++ complains if the volatile result of the assignment is
+ // unused, so we cast the volatile away. We cannot cast directly
+ // to void, because gcc treats that as not using the result of the
+ // assignment. However, casting to E& means that we trigger an
+ // unused-value warning. So, we cast the E& to void.
+ (void)const_cast(_elems[localBot] = t);
OrderAccess::release_store(&_bottom, increment_index(localBot));
TASKQUEUE_STATS_ONLY(stats.record_push());
return true;
@@ -397,7 +401,12 @@ bool GenericTaskQueue::pop_global(E& t) {
return false;
}
- const_cast(t = _elems[oldAge.top()]);
+ // g++ complains if the volatile result of the assignment is
+ // unused, so we cast the volatile away. We cannot cast directly
+ // to void, because gcc treats that as not using the result of the
+ // assignment. However, casting to E& means that we trigger an
+ // unused-value warning. So, we cast the E& to void.
+ (void) const_cast(t = _elems[oldAge.top()]);
Age newAge(oldAge);
newAge.increment();
Age resAge = _age.cmpxchg(newAge, oldAge);
@@ -640,8 +649,12 @@ GenericTaskQueue::push(E t) {
uint dirty_n_elems = dirty_size(localBot, top);
assert(dirty_n_elems < N, "n_elems out of range.");
if (dirty_n_elems < max_elems()) {
- // g++ complains if the volatile result of the assignment is unused.
- const_cast(_elems[localBot] = t);
+ // g++ complains if the volatile result of the assignment is
+ // unused, so we cast the volatile away. We cannot cast directly
+ // to void, because gcc treats that as not using the result of the
+ // assignment. However, casting to E& means that we trigger an
+ // unused-value warning. So, we cast the E& to void.
+ (void) const_cast(_elems[localBot] = t);
OrderAccess::release_store(&_bottom, increment_index(localBot));
TASKQUEUE_STATS_ONLY(stats.record_push());
return true;
@@ -665,7 +678,12 @@ GenericTaskQueue::pop_local(E& t) {
// This is necessary to prevent any read below from being reordered
// before the store just above.
OrderAccess::fence();
- const_cast(t = _elems[localBot]);
+ // g++ complains if the volatile result of the assignment is
+ // unused, so we cast the volatile away. We cannot cast directly
+ // to void, because gcc treats that as not using the result of the
+ // assignment. However, casting to E& means that we trigger an
+ // unused-value warning. So, we cast the E& to void.
+ (void) const_cast(t = _elems[localBot]);
// This is a second read of "age"; the "size()" above is the first.
// If there's still at least one element in the queue, based on the
// "_bottom" and "age" we've read, then there can be no interference with
From 737454c74456935c936da0bf0cf1641cfb385d08 Mon Sep 17 00:00:00 2001
From: Zhengyu Gu
Date: Fri, 14 Jun 2013 09:18:42 -0400
Subject: [PATCH 039/136] 8011968: Kitchensink crashed with SIGSEGV in
MemBaseline::baseline
Simple fix to add NULL pointer check that can cause segv
Reviewed-by: coleenp, ctornqvi
---
hotspot/src/share/vm/services/memBaseline.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/services/memBaseline.cpp b/hotspot/src/share/vm/services/memBaseline.cpp
index c2d04106c8b..21eb8b5d422 100644
--- a/hotspot/src/share/vm/services/memBaseline.cpp
+++ b/hotspot/src/share/vm/services/memBaseline.cpp
@@ -130,7 +130,7 @@ bool MemBaseline::baseline_malloc_summary(const MemPointerArray* malloc_records)
if (malloc_ptr->is_arena_record()) {
// see if arena memory record present
MemPointerRecord* next_malloc_ptr = (MemPointerRecordEx*)malloc_itr.peek_next();
- if (next_malloc_ptr->is_arena_memory_record()) {
+ if (next_malloc_ptr != NULL && next_malloc_ptr->is_arena_memory_record()) {
assert(next_malloc_ptr->is_memory_record_of_arena(malloc_ptr),
"Arena records do not match");
size = next_malloc_ptr->size();
From be6e7457559430f987ffcbe8874dbb439f9ec0b7 Mon Sep 17 00:00:00 2001
From: Ron Durbin
Date: Fri, 14 Jun 2013 07:46:22 -0700
Subject: [PATCH 040/136] 7178026: os::close can restart ::close but that is
not a restartable syscall
Removed restart macros from all os:close calls on Solaris, Linux, MacOS X platforms.
Reviewed-by: dcubed, dholmes
---
hotspot/src/os/bsd/dtrace/jvm_dtrace.c | 4 +---
hotspot/src/os/bsd/vm/attachListener_bsd.cpp | 15 ++++++---------
hotspot/src/os/bsd/vm/os_bsd.inline.hpp | 4 ++--
hotspot/src/os/bsd/vm/perfMemory_bsd.cpp | 12 +++++-------
hotspot/src/os/linux/vm/attachListener_linux.cpp | 15 ++++++---------
hotspot/src/os/linux/vm/perfMemory_linux.cpp | 14 +++++---------
hotspot/src/os/solaris/dtrace/jvm_dtrace.c | 4 +---
.../src/os/solaris/vm/attachListener_solaris.cpp | 6 +++---
hotspot/src/os/solaris/vm/os_solaris.cpp | 4 ++--
hotspot/src/os/solaris/vm/perfMemory_solaris.cpp | 14 +++++---------
10 files changed, 36 insertions(+), 56 deletions(-)
diff --git a/hotspot/src/os/bsd/dtrace/jvm_dtrace.c b/hotspot/src/os/bsd/dtrace/jvm_dtrace.c
index fd0c4333cba..6cdad788572 100644
--- a/hotspot/src/os/bsd/dtrace/jvm_dtrace.c
+++ b/hotspot/src/os/bsd/dtrace/jvm_dtrace.c
@@ -122,9 +122,7 @@ static int file_open(const char* path, int flag) {
}
static int file_close(int fd) {
- int ret;
- RESTARTABLE(close(fd), ret);
- return ret;
+ return close(fd);
}
static int file_read(int fd, char* buf, int len) {
diff --git a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp
index 81fba25efd8..ee4feb8d046 100644
--- a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp
@@ -199,7 +199,7 @@ int BsdAttachListener::init() {
::unlink(initial_path);
int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
if (res == -1) {
- RESTARTABLE(::close(listener), res);
+ ::close(listener);
return -1;
}
@@ -217,7 +217,7 @@ int BsdAttachListener::init() {
}
}
if (res == -1) {
- RESTARTABLE(::close(listener), res);
+ ::close(listener);
::unlink(initial_path);
return -1;
}
@@ -345,24 +345,21 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
uid_t puid;
gid_t pgid;
if (::getpeereid(s, &puid, &pgid) != 0) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
}
uid_t euid = geteuid();
gid_t egid = getegid();
if (puid != euid || pgid != egid) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
}
// peer credential look okay so we read the request
BsdAttachOperation* op = read_request(s);
if (op == NULL) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
} else {
return op;
@@ -413,7 +410,7 @@ void BsdAttachOperation::complete(jint result, bufferedStream* st) {
}
// done
- RESTARTABLE(::close(this->socket()), rc);
+ ::close(this->socket());
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
index 33ebec9fffc..cf8453332eb 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
@@ -178,11 +178,11 @@ inline size_t os::write(int fd, const void *buf, unsigned int nBytes) {
}
inline int os::close(int fd) {
- RESTARTABLE_RETURN_INT(::close(fd));
+ return ::close(fd);
}
inline int os::socket_close(int fd) {
- RESTARTABLE_RETURN_INT(::close(fd));
+ return ::close(fd);
}
inline int os::socket(int domain, int type, int protocol) {
diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
index 5d82c4d988b..89af13f86ce 100644
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
@@ -120,7 +120,7 @@ static void save_memory_to_file(char* addr, size_t size) {
addr += result;
}
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
if (PrintMiscellaneous && Verbose) {
if (result == OS_ERR) {
warning("Could not close %s: %s\n", destfile, strerror(errno));
@@ -632,7 +632,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
if (PrintMiscellaneous && Verbose) {
warning("could not set shared memory file size: %s\n", strerror(errno));
}
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
return -1;
}
@@ -656,7 +656,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
if (result != -1) {
return fd;
} else {
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
return -1;
}
}
@@ -734,9 +734,7 @@ static char* mmap_create_shared(size_t size) {
mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- // attempt to close the file - restart it if it was interrupted,
- // but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
@@ -909,7 +907,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
// attempt to close the file - restart if it gets interrupted,
// but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
diff --git a/hotspot/src/os/linux/vm/attachListener_linux.cpp b/hotspot/src/os/linux/vm/attachListener_linux.cpp
index 5b9c7294995..035d298a36c 100644
--- a/hotspot/src/os/linux/vm/attachListener_linux.cpp
+++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp
@@ -199,7 +199,7 @@ int LinuxAttachListener::init() {
::unlink(initial_path);
int res = ::bind(listener, (struct sockaddr*)&addr, sizeof(addr));
if (res == -1) {
- RESTARTABLE(::close(listener), res);
+ ::close(listener);
return -1;
}
@@ -212,7 +212,7 @@ int LinuxAttachListener::init() {
}
}
if (res == -1) {
- RESTARTABLE(::close(listener), res);
+ ::close(listener);
::unlink(initial_path);
return -1;
}
@@ -340,24 +340,21 @@ LinuxAttachOperation* LinuxAttachListener::dequeue() {
struct ucred cred_info;
socklen_t optlen = sizeof(cred_info);
if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void*)&cred_info, &optlen) == -1) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
}
uid_t euid = geteuid();
gid_t egid = getegid();
if (cred_info.uid != euid || cred_info.gid != egid) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
}
// peer credential look okay so we read the request
LinuxAttachOperation* op = read_request(s);
if (op == NULL) {
- int res;
- RESTARTABLE(::close(s), res);
+ ::close(s);
continue;
} else {
return op;
@@ -408,7 +405,7 @@ void LinuxAttachOperation::complete(jint result, bufferedStream* st) {
}
// done
- RESTARTABLE(::close(this->socket()), rc);
+ ::close(this->socket());
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
index 91b5f26c681..6287a429e8e 100644
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
@@ -120,7 +120,7 @@ static void save_memory_to_file(char* addr, size_t size) {
addr += result;
}
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
if (PrintMiscellaneous && Verbose) {
if (result == OS_ERR) {
warning("Could not close %s: %s\n", destfile, strerror(errno));
@@ -632,7 +632,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
if (PrintMiscellaneous && Verbose) {
warning("could not set shared memory file size: %s\n", strerror(errno));
}
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
return -1;
}
@@ -656,7 +656,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
if (result != -1) {
return fd;
} else {
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
return -1;
}
}
@@ -734,9 +734,7 @@ static char* mmap_create_shared(size_t size) {
mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- // attempt to close the file - restart it if it was interrupted,
- // but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
@@ -907,9 +905,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
- // attempt to close the file - restart if it gets interrupted,
- // but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
diff --git a/hotspot/src/os/solaris/dtrace/jvm_dtrace.c b/hotspot/src/os/solaris/dtrace/jvm_dtrace.c
index fd0c4333cba..6cdad788572 100644
--- a/hotspot/src/os/solaris/dtrace/jvm_dtrace.c
+++ b/hotspot/src/os/solaris/dtrace/jvm_dtrace.c
@@ -122,9 +122,7 @@ static int file_open(const char* path, int flag) {
}
static int file_close(int fd) {
- int ret;
- RESTARTABLE(close(fd), ret);
- return ret;
+ return close(fd);
}
static int file_read(int fd, char* buf, int len) {
diff --git a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
index f90538efe77..9cc66876268 100644
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
@@ -392,7 +392,7 @@ int SolarisAttachListener::create_door() {
return -1;
}
assert(fd >= 0, "bad file descriptor");
- RESTARTABLE(::close(fd), res);
+ ::close(fd);
// attach the door descriptor to the file
if ((res = ::fattach(dd, initial_path)) == -1) {
@@ -410,7 +410,7 @@ int SolarisAttachListener::create_door() {
// rename file so that clients can attach
if (dd >= 0) {
if (::rename(initial_path, door_path) == -1) {
- RESTARTABLE(::close(dd), res);
+ ::close(dd);
::fdetach(initial_path);
dd = -1;
}
@@ -549,7 +549,7 @@ void SolarisAttachOperation::complete(jint res, bufferedStream* st) {
}
// close socket and we're done
- RESTARTABLE(::close(this->socket()), rc);
+ ::close(this->socket());
// were we externally suspended while we were waiting?
thread->check_and_wait_while_suspended();
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index 73e9f064a78..dfd07d615e4 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -6679,11 +6679,11 @@ size_t os::write(int fd, const void *buf, unsigned int nBytes) {
}
int os::close(int fd) {
- RESTARTABLE_RETURN_INT(::close(fd));
+ return ::close(fd);
}
int os::socket_close(int fd) {
- RESTARTABLE_RETURN_INT(::close(fd));
+ return ::close(fd);
}
int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
diff --git a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
index 4da5f19aef0..bc11eb4ccdf 100644
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
@@ -122,7 +122,7 @@ static void save_memory_to_file(char* addr, size_t size) {
addr += result;
}
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
if (PrintMiscellaneous && Verbose) {
if (result == OS_ERR) {
warning("Could not close %s: %s\n", destfile, strerror(errno));
@@ -437,7 +437,7 @@ static char* get_user_name(int vmid, TRAPS) {
addr+=result;
}
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
// get the user name for the effective user id of the process
char* user_name = get_user_name(psinfo.pr_euid);
@@ -669,7 +669,7 @@ static int create_sharedmem_resources(const char* dirname, const char* filename,
if (PrintMiscellaneous && Verbose) {
warning("could not set shared memory file size: %s\n", strerror(errno));
}
- RESTARTABLE(::close(fd), result);
+ ::close(fd);
return -1;
}
@@ -749,9 +749,7 @@ static char* mmap_create_shared(size_t size) {
mapAddress = (char*)::mmap((char*)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- // attempt to close the file - restart it if it was interrupted,
- // but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
@@ -922,9 +920,7 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
mapAddress = (char*)::mmap((char*)0, size, mmap_prot, MAP_SHARED, fd, 0);
- // attempt to close the file - restart if it gets interrupted,
- // but ignore other failures
- RESTARTABLE(::close(fd), result);
+ result = ::close(fd);
assert(result != OS_ERR, "could not close file");
if (mapAddress == MAP_FAILED) {
From f0d506b4b5edcf5d3ae0295b01452e73822bc192 Mon Sep 17 00:00:00 2001
From: Serguei Spitsyn
Date: Fri, 14 Jun 2013 15:17:10 -0700
Subject: [PATCH 041/136] 6493116: JVMTI Doc: GetOwnedMonitorStackDepthInfo has
a typo in monitor_info_ptr parameter description
A typo in the parameter spelling, a bound update missed when the parameter was renamed
Reviewed-by: sla, minqi
---
hotspot/src/share/vm/prims/jvmti.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/prims/jvmti.xml b/hotspot/src/share/vm/prims/jvmti.xml
index dbd6735aa73..c23a7b5e1c3 100644
--- a/hotspot/src/share/vm/prims/jvmti.xml
+++ b/hotspot/src/share/vm/prims/jvmti.xml
@@ -1897,7 +1897,7 @@ jvmtiEnv *jvmti;
-
+
jvmtiMonitorStackDepthInfo
From 08f43d437909b5d0d48d69ea52bf54c6d2e872eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?=
Date: Sat, 15 Jun 2013 13:17:36 +0200
Subject: [PATCH 042/136] 8016105: Add complementary RETURN_NULL allocation
macros in allocation.hpp
Reviewed-by: sla, rbackman
---
hotspot/src/share/vm/memory/allocation.hpp | 43 ++++++++++++++++------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index 65df6ee052d..92d59a44585 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -635,8 +635,15 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
#define NEW_RESOURCE_ARRAY_IN_THREAD(thread, type, size)\
(type*) resource_allocate_bytes(thread, (size) * sizeof(type))
+#define NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(thread, type, size)\
+ (type*) resource_allocate_bytes(thread, (size) * sizeof(type), AllocFailStrategy::RETURN_NULL)
+
#define REALLOC_RESOURCE_ARRAY(type, old, old_size, new_size)\
- (type*) resource_reallocate_bytes((char*)(old), (old_size) * sizeof(type), (new_size) * sizeof(type) )
+ (type*) resource_reallocate_bytes((char*)(old), (old_size) * sizeof(type), (new_size) * sizeof(type))
+
+#define REALLOC_RESOURCE_ARRAY_RETURN_NULL(type, old, old_size, new_size)\
+ (type*) resource_reallocate_bytes((char*)(old), (old_size) * sizeof(type),\
+ (new_size) * sizeof(type), AllocFailStrategy::RETURN_NULL)
#define FREE_RESOURCE_ARRAY(type, old, size)\
resource_free_bytes((char*)(old), (size) * sizeof(type))
@@ -647,28 +654,40 @@ class ResourceObj ALLOCATION_SUPER_CLASS_SPEC {
#define NEW_RESOURCE_OBJ(type)\
NEW_RESOURCE_ARRAY(type, 1)
-#define NEW_C_HEAP_ARRAY(type, size, memflags)\
- (type*) (AllocateHeap((size) * sizeof(type), memflags))
+#define NEW_RESOURCE_OBJ_RETURN_NULL(type)\
+ NEW_RESOURCE_ARRAY_RETURN_NULL(type, 1)
-#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
- (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
-
-#define FREE_C_HEAP_ARRAY(type, old, memflags) \
- FreeHeap((char*)(old), memflags)
+#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail)\
+ (type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
(type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
-#define REALLOC_C_HEAP_ARRAY2(type, old, size, memflags, pc)\
- (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, pc))
+#define NEW_C_HEAP_ARRAY(type, size, memflags)\
+ (type*) (AllocateHeap((size) * sizeof(type), memflags))
-#define NEW_C_HEAP_ARRAY3(type, size, memflags, pc, allocfail) \
- (type*) AllocateHeap(size * sizeof(type), memflags, pc, allocfail)
+#define NEW_C_HEAP_ARRAY2_RETURN_NULL(type, size, memflags, pc)\
+ NEW_C_HEAP_ARRAY3(type, size, memflags, pc, AllocFailStrategy::RETURN_NULL)
+
+#define NEW_C_HEAP_ARRAY_RETURN_NULL(type, size, memflags)\
+ NEW_C_HEAP_ARRAY3(type, size, memflags, (address)0, AllocFailStrategy::RETURN_NULL)
+
+#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
+ (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
+
+#define REALLOC_C_HEAP_ARRAY_RETURN_NULL(type, old, size, memflags)\
+ (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, AllocFailStrategy::RETURN_NULL))
+
+#define FREE_C_HEAP_ARRAY(type, old, memflags) \
+ FreeHeap((char*)(old), memflags)
// allocate type in heap without calling ctor
#define NEW_C_HEAP_OBJ(type, memflags)\
NEW_C_HEAP_ARRAY(type, 1, memflags)
+#define NEW_C_HEAP_OBJ_RETURN_NULL(type, memflags)\
+ NEW_C_HEAP_ARRAY_RETURN_NULL(type, 1, memflags)
+
// deallocate obj of type in heap without calling dtor
#define FREE_C_HEAP_OBJ(objname, memflags)\
FreeHeap((char*)objname, memflags);
From 87505d60f6bb01dabe73c7b905398e150e966211 Mon Sep 17 00:00:00 2001
From: Zhengyu Gu
Date: Mon, 10 Jun 2013 10:45:19 -0400
Subject: [PATCH 043/136] 8013917: Kitchensink crashed with SIGSEGV in
BaselineReporter::diff_callsites
Simple fix when memory allocation site is gone, NMT should report 0 memory size, instead old memory size.
Reviewed-by: dcubed, ctornqvi
---
hotspot/src/share/vm/services/memReporter.cpp | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/hotspot/src/share/vm/services/memReporter.cpp b/hotspot/src/share/vm/services/memReporter.cpp
index 0311675f349..573d9e03c14 100644
--- a/hotspot/src/share/vm/services/memReporter.cpp
+++ b/hotspot/src/share/vm/services/memReporter.cpp
@@ -190,17 +190,18 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
if (prev_malloc_callsite == NULL ||
cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
+ // this is a new callsite
_outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
amount_in_current_scale(cur_malloc_callsite->amount()),
cur_malloc_callsite->count(),
diff_in_current_scale(cur_malloc_callsite->amount(), 0),
diff(cur_malloc_callsite->count(), 0));
cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
- } else if (prev_malloc_callsite == NULL ||
+ } else if (cur_malloc_callsite == NULL ||
cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
- _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
- amount_in_current_scale(prev_malloc_callsite->amount()),
- prev_malloc_callsite->count(),
+ // this callsite is already gone
+ _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
+ amount_in_current_scale(0), 0,
diff_in_current_scale(0, prev_malloc_callsite->amount()),
diff(0, prev_malloc_callsite->count()));
prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
@@ -222,6 +223,7 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
VMCallsitePointer* prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.current();
while (cur_vm_callsite != NULL || prev_vm_callsite != NULL) {
if (prev_vm_callsite == NULL || cur_vm_callsite->addr() < prev_vm_callsite->addr()) {
+ // this is a new callsite
_outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
amount_in_current_scale(cur_vm_callsite->reserved_amount()),
amount_in_current_scale(cur_vm_callsite->committed_amount()),
@@ -229,9 +231,10 @@ void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline&
diff_in_current_scale(cur_vm_callsite->committed_amount(), 0));
cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next();
} else if (cur_vm_callsite == NULL || cur_vm_callsite->addr() > prev_vm_callsite->addr()) {
+ // this callsite is already gone
_outputer.diff_virtual_memory_callsite(prev_vm_callsite->addr(),
- amount_in_current_scale(prev_vm_callsite->reserved_amount()),
- amount_in_current_scale(prev_vm_callsite->committed_amount()),
+ amount_in_current_scale(0),
+ amount_in_current_scale(0),
diff_in_current_scale(0, prev_vm_callsite->reserved_amount()),
diff_in_current_scale(0, prev_vm_callsite->committed_amount()));
prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
From 80407ef47d2d8f4ce540c8c84002fb9224d83c83 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Mon, 10 Jun 2013 15:57:32 +0100
Subject: [PATCH 044/136] 8013576: Add stat support to LambdaToMethod
LambdaToMethod should emit info to help diagnose/test lambda metafactory problems
Reviewed-by: jjg, vromero
---
.../sun/tools/javac/comp/LambdaToMethod.java | 20 ++
.../tools/javac/resources/compiler.properties | 17 ++
.../javac/diags/examples/LambdaStat.java | 29 +++
.../tools/javac/diags/examples/MrefStat.java | 31 +++
.../javac/diags/examples/MrefStat.java.rej | 34 ++++
.../tools/javac/diags/examples/MrefStat1.java | 34 ++++
.../javac/diags/examples/MrefStat1.java.rej | 37 ++++
.../javac/lambda/TestLambdaToMethodStats.java | 192 ++++++++++++++++++
8 files changed, 394 insertions(+)
create mode 100644 langtools/test/tools/javac/diags/examples/LambdaStat.java
create mode 100644 langtools/test/tools/javac/diags/examples/MrefStat.java
create mode 100644 langtools/test/tools/javac/diags/examples/MrefStat.java.rej
create mode 100644 langtools/test/tools/javac/diags/examples/MrefStat1.java
create mode 100644 langtools/test/tools/javac/diags/examples/MrefStat1.java.rej
create mode 100644 langtools/test/tools/javac/lambda/TestLambdaToMethodStats.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
index a8ce9494776..9acfdba9c88 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
@@ -68,6 +68,8 @@ import static com.sun.tools.javac.tree.JCTree.Tag.*;
*/
public class LambdaToMethod extends TreeTranslator {
+ private JCDiagnostic.Factory diags;
+ private Log log;
private Lower lower;
private Names names;
private Symtab syms;
@@ -89,6 +91,9 @@ public class LambdaToMethod extends TreeTranslator {
/** info about the current class being processed */
private KlassInfo kInfo;
+ /** dump statistics about lambda code generation */
+ private boolean dumpLambdaToMethodStats;
+
/** Flag for alternate metafactories indicating the lambda object is intended to be serializable */
public static final int FLAG_SERIALIZABLE = 1 << 0;
@@ -146,6 +151,8 @@ public class LambdaToMethod extends TreeTranslator {
}
private LambdaToMethod(Context context) {
+ diags = JCDiagnostic.Factory.instance(context);
+ log = Log.instance(context);
lower = Lower.instance(context);
names = Names.instance(context);
syms = Symtab.instance(context);
@@ -154,6 +161,8 @@ public class LambdaToMethod extends TreeTranslator {
types = Types.instance(context);
transTypes = TransTypes.instance(context);
analyzer = new LambdaAnalyzerPreprocessor();
+ Options options = Options.instance(context);
+ dumpLambdaToMethodStats = options.isSet("dumpLambdaToMethodStats");
}
//
@@ -1101,7 +1110,9 @@ public class LambdaToMethod extends TreeTranslator {
Map prevSerializableLambdaCount =
serializableLambdaCounts;
Map prevClinits = clinits;
+ DiagnosticSource prevSource = log.currentSource();
try {
+ log.useSource(tree.sym.sourcefile);
serializableLambdaCounts = new HashMap();
prevClinits = new HashMap();
if (tree.sym.owner.kind == MTH) {
@@ -1126,6 +1137,7 @@ public class LambdaToMethod extends TreeTranslator {
super.visitClassDef(tree);
}
finally {
+ log.useSource(prevSource.getFile());
frameStack = prevStack;
serializableLambdaCounts = prevSerializableLambdaCount;
clinits = prevClinits;
@@ -1685,6 +1697,9 @@ public class LambdaToMethod extends TreeTranslator {
}
Name name = isSerializable() ? serializedLambdaName(owner) : lambdaName();
this.translatedSym = makeSyntheticMethod(0, name, null, owner.enclClass());
+ if (dumpLambdaToMethodStats) {
+ log.note(tree, "lambda.stat", needsAltMetafactory(), translatedSym);
+ }
}
/**
@@ -1841,6 +1856,11 @@ public class LambdaToMethod extends TreeTranslator {
lambdaName().append(names.fromString("$bridge")), null,
owner.enclClass())
: null;
+ if (dumpLambdaToMethodStats) {
+ String key = bridgeSym == null ?
+ "mref.stat" : "mref.stat.1";
+ log.note(tree, key, needsAltMetafactory(), bridgeSym);
+ }
}
/**
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 192780ab956..9c2161e5d10 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -1163,6 +1163,23 @@ compiler.note.compressed.diags=\
compiler.note.potential.lambda.found=\
This anonymous inner class creation can be turned into a lambda expression.
+# 0: boolean, 1: symbol
+compiler.note.lambda.stat=\
+ Translating lambda expression\n\
+ alternate metafactory = {0}\n\
+ synthetic method = {1}
+
+# 0: boolean, 1: unused
+compiler.note.mref.stat=\
+ Translating method reference\n\
+ alternate metafactory = {0}\n\
+
+# 0: boolean, 1: symbol
+compiler.note.mref.stat.1=\
+ Translating method reference\n\
+ alternate metafactory = {0}\n\
+ bridge method = {1}
+
compiler.note.note=\
Note:\u0020
diff --git a/langtools/test/tools/javac/diags/examples/LambdaStat.java b/langtools/test/tools/javac/diags/examples/LambdaStat.java
new file mode 100644
index 00000000000..2eb894a54dd
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/LambdaStat.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.note.lambda.stat
+// options: -XDdumpLambdaToMethodStats
+
+class LambdaStat {
+ Runnable r = ()->{};
+}
diff --git a/langtools/test/tools/javac/diags/examples/MrefStat.java b/langtools/test/tools/javac/diags/examples/MrefStat.java
new file mode 100644
index 00000000000..d87e66546fa
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/MrefStat.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.note.mref.stat
+// options: -XDdumpLambdaToMethodStats
+
+class MrefStat {
+ Runnable r = MrefStat::m;
+
+ static void m() { }
+}
diff --git a/langtools/test/tools/javac/diags/examples/MrefStat.java.rej b/langtools/test/tools/javac/diags/examples/MrefStat.java.rej
new file mode 100644
index 00000000000..f5286e5a2d2
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/MrefStat.java.rej
@@ -0,0 +1,34 @@
+--- MrefStat.java
++++ MrefStat.java
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++// key: compiler.note.mref.stat
++// options: -XDdumpLambdaToMethodStats
++
++class MrefStat {
++ Runnable r = MrefStat::m;
++
++ static void m() { }
++}
diff --git a/langtools/test/tools/javac/diags/examples/MrefStat1.java b/langtools/test/tools/javac/diags/examples/MrefStat1.java
new file mode 100644
index 00000000000..6318e3c755f
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/MrefStat1.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.note.mref.stat.1
+// options: -XDdumpLambdaToMethodStats
+
+class MrefStat1 {
+
+ void m() { }
+
+ static class Sub extends MrefStat1 {
+ Runnable r = super::m;
+ }
+}
diff --git a/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej b/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej
new file mode 100644
index 00000000000..b247270db53
--- /dev/null
+++ b/langtools/test/tools/javac/diags/examples/MrefStat1.java.rej
@@ -0,0 +1,37 @@
+--- MrefStat1.java
++++ MrefStat1.java
+@@ -0,0 +1,34 @@
++/*
++ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation.
++ *
++ * This code is distributed in the hope that it will be useful, but WITHOUT
++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++// key: compiler.note.mref.stat.1
++// options: -XDdumpLambdaToMethodStats
++
++class MrefStat1 {
++
++ void m() { }
++
++ static class Sub extends MrefStat1 {
++ Runnable r = super::m;
++ }
++}
diff --git a/langtools/test/tools/javac/lambda/TestLambdaToMethodStats.java b/langtools/test/tools/javac/lambda/TestLambdaToMethodStats.java
new file mode 100644
index 00000000000..7a1d06a0982
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TestLambdaToMethodStats.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8013576
+ * @summary Add stat support to LambdaToMethod
+ * @library ../lib
+ * @build JavacTestingAbstractThreadedTest
+ * @run main/othervm TestLambdaToMethodStats
+ */
+
+// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
+// see JDK-8006746
+
+import java.net.URI;
+import java.util.Arrays;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.api.ClientCodeWrapper;
+import com.sun.tools.javac.util.JCDiagnostic;
+
+public class TestLambdaToMethodStats
+ extends JavacTestingAbstractThreadedTest
+ implements Runnable {
+
+ enum ExprKind {
+ LAMBDA("()->null"),
+ MREF1("this::g"),
+ MREF2("this::h");
+
+ String exprStr;
+
+ ExprKind(String exprStr) {
+ this.exprStr = exprStr;
+ }
+ }
+
+ enum TargetKind {
+ IMPLICIT(""),
+ SERIALIZABLE("(A & java.io.Serializable)");
+
+ String targetStr;
+
+ TargetKind(String targetStr) {
+ this.targetStr = targetStr;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+ for (ExprKind ek : ExprKind.values()) {
+ for (TargetKind tk : TargetKind.values()) {
+ pool.execute(new TestLambdaToMethodStats(ek, tk));
+ }
+ }
+
+ checkAfterExec(true);
+ }
+
+ ExprKind ek;
+ TargetKind tk;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+
+ TestLambdaToMethodStats(ExprKind ek, TargetKind tk) {
+ this.ek = ek;
+ this.tk = tk;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "interface A {\n" +
+ " Object o();\n" +
+ "}\n" +
+ "class Test {\n" +
+ " A a = #C#E;\n" +
+ " Object g() { return null; }\n" +
+ " Object h(Object... o) { return null; }\n" +
+ "}";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#E", ek.exprStr)
+ .replaceAll("#C", tk.targetStr);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ public void run() {
+ JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
+ Arrays.asList("-XDdumpLambdaToMethodStats"),
+ null, Arrays.asList(source));
+ try {
+ ct.generate();
+ } catch (Throwable ex) {
+ throw new
+ AssertionError("Error thron when analyzing the following source:\n" +
+ source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ checkCount.incrementAndGet();
+
+ boolean error = diagChecker.lambda !=
+ (ek == ExprKind.LAMBDA);
+
+ error |= diagChecker.bridge !=
+ (ek == ExprKind.MREF2);
+
+ error |= diagChecker.altMetafactory !=
+ (tk == TargetKind.SERIALIZABLE);
+
+ if (error) {
+ throw new AssertionError("Bad stat diagnostic found for source\n" +
+ "lambda = " + diagChecker.lambda + "\n" +
+ "bridge = " + diagChecker.bridge + "\n" +
+ "altMF = " + diagChecker.altMetafactory + "\n" +
+ source.source);
+ }
+ }
+
+ static class DiagnosticChecker
+ implements javax.tools.DiagnosticListener {
+
+ boolean altMetafactory;
+ boolean bridge;
+ boolean lambda;
+
+ public void report(Diagnostic extends JavaFileObject> diagnostic) {
+ try {
+ if (diagnostic.getKind() == Diagnostic.Kind.NOTE) {
+ switch (diagnostic.getCode()) {
+ case "compiler.note.lambda.stat":
+ lambda = true;
+ break;
+ case "compiler.note.mref.stat":
+ lambda = false;
+ bridge = false;
+ break;
+ case "compiler.note.mref.stat.1":
+ lambda = false;
+ bridge = true;
+ break;
+ default:
+ throw new AssertionError("unexpected note: " + diagnostic.getCode());
+ }
+ ClientCodeWrapper.DiagnosticSourceUnwrapper dsu =
+ (ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic;
+ altMetafactory = (Boolean)dsu.d.getArgs()[0];
+ }
+ } catch (RuntimeException t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+ }
+}
From e8efa342063ef081e7602f5ce4ad3969602c084f Mon Sep 17 00:00:00 2001
From: Alan Bateman
Date: Mon, 10 Jun 2013 17:15:42 +0100
Subject: [PATCH 045/136] 8016218: Warnings building corba repo due to missing
hashCode methods
Reviewed-by: chegar, coffeys, dfuchs
---
.../javax/rmi/CORBA/StubDelegateImpl.java | 8 +++++
.../sun/corba/se/impl/orb/ParserTable.java | 31 +++++++++++++++++++
.../corba/se/impl/orbutil/RepIdDelegator.java | 14 +++++++--
.../sun/rmi/rmic/iiop/CompoundType.java | 5 +++
4 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/StubDelegateImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/StubDelegateImpl.java
index 9b87ee1b8f2..6af71ee77cb 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/StubDelegateImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/StubDelegateImpl.java
@@ -147,6 +147,14 @@ public class StubDelegateImpl implements javax.rmi.CORBA.StubDelegate
return ior.equals( other.ior ) ;
}
+ public int hashCode() {
+ if (ior == null) {
+ return 0;
+ } else {
+ return ior.hashCode();
+ }
+ }
+
/**
* Returns a string representation of this stub. Returns the same string
* for all stubs that represent the same remote object.
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
index 550c4a7f304..b571391db16 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orb/ParserTable.java
@@ -455,6 +455,10 @@ public class ParserTable {
return other instanceof TestBadServerIdHandler ;
}
+ public int hashCode() {
+ return 1;
+ }
+
public void handle( ObjectKey objectKey )
{
}
@@ -518,6 +522,10 @@ public class ParserTable {
return other instanceof TestLegacyORBSocketFactory ;
}
+ public int hashCode() {
+ return 1;
+ }
+
public ServerSocket createServerSocket( String type, int port )
{
return null ;
@@ -543,6 +551,10 @@ public class ParserTable {
return other instanceof TestORBSocketFactory ;
}
+ public int hashCode() {
+ return 1;
+ }
+
public void setORB(ORB orb)
{
}
@@ -572,6 +584,10 @@ public class ParserTable {
return other instanceof TestIORToSocketInfo;
}
+ public int hashCode() {
+ return 1;
+ }
+
public List getSocketInfo(IOR ior)
{
return null;
@@ -608,6 +624,10 @@ public class ParserTable {
return other instanceof TestContactInfoListFactory;
}
+ public int hashCode() {
+ return 1;
+ }
+
public void setORB(ORB orb) { }
public CorbaContactInfoList create( IOR ior ) { return null; }
@@ -865,6 +885,10 @@ public class ParserTable {
return other instanceof TestORBInitializer1 ;
}
+ public int hashCode() {
+ return 1;
+ }
+
public void pre_init( ORBInitInfo info )
{
}
@@ -882,6 +906,10 @@ public class ParserTable {
return other instanceof TestORBInitializer2 ;
}
+ public int hashCode() {
+ return 1;
+ }
+
public void pre_init( ORBInitInfo info )
{
}
@@ -950,6 +978,8 @@ public class ParserTable {
{
return other instanceof TestAcceptor1 ;
}
+
+ public int hashCode() { return 1; }
public boolean initialize() { return true; }
public boolean initialized() { return true; }
public String getConnectionCacheType() { return "FOO"; }
@@ -981,6 +1011,7 @@ public class ParserTable {
{
return other instanceof TestAcceptor2 ;
}
+ public int hashCode() { return 1; }
public boolean initialize() { return true; }
public boolean initialized() { return true; }
public String getConnectionCacheType() { return "FOO"; }
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator.java b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator.java
index 7fb16589162..c2bc23cacac 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator.java
@@ -151,7 +151,9 @@ public final class RepIdDelegator
}
// Constructor used for factory/utility cases
- public RepIdDelegator() {}
+ public RepIdDelegator() {
+ this(null);
+ }
// Constructor used by getIdFromString. All non-static
// RepositoryId methods will use the provided delegate.
@@ -159,7 +161,7 @@ public final class RepIdDelegator
this.delegate = _delegate;
}
- private RepositoryId delegate;
+ private final RepositoryId delegate;
public String toString() {
if (delegate != null)
@@ -174,4 +176,12 @@ public final class RepIdDelegator
else
return super.equals(obj);
}
+
+ public int hashCode() {
+ if (delegate != null) {
+ return delegate.hashCode();
+ } else {
+ return super.hashCode();
+ }
+ }
}
diff --git a/corba/src/share/classes/sun/rmi/rmic/iiop/CompoundType.java b/corba/src/share/classes/sun/rmi/rmic/iiop/CompoundType.java
index 2c55bf72148..eba506daf73 100644
--- a/corba/src/share/classes/sun/rmi/rmic/iiop/CompoundType.java
+++ b/corba/src/share/classes/sun/rmi/rmic/iiop/CompoundType.java
@@ -32,6 +32,7 @@
package sun.rmi.rmic.iiop;
+import java.util.Arrays;
import java.util.Vector;
import sun.tools.java.Identifier;
import sun.tools.java.ClassNotFound;
@@ -1851,6 +1852,10 @@ public abstract class CompoundType extends Type {
return false;
}
+ public int hashCode() {
+ return getName().hashCode() ^ Arrays.hashCode(arguments);
+ }
+
/**
* Return a new Method object that is a legal combination of
* this method object and another one.
From b914f8d6be4aa9cb1e6f8b892b6cd127fd298aee Mon Sep 17 00:00:00 2001
From: Joe Wang
Date: Mon, 10 Jun 2013 14:42:57 -0700
Subject: [PATCH 046/136] 8016153: Property
http://javax.xml.XMLConstants/property/accessExternalDTD is not recognized
Reviewed-by: lancea, dfuchs
---
.../apache/xalan/internal/xsltc/compiler/Parser.java | 12 ++++++++++--
.../org/apache/xalan/internal/xsltc/trax/Util.java | 10 ++++++++--
.../jaxp/validation/ValidatorHandlerImpl.java | 11 +++++++----
.../apache/xml/internal/utils/XMLReaderManager.java | 7 ++++++-
4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
index 9669bf734ad..3c186a1172b 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java
@@ -52,6 +52,7 @@ import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.AttributesImpl;
@@ -476,8 +477,15 @@ public class Parser implements Constants, ContentHandler {
factory.setNamespaceAware(true);
}
final SAXParser parser = factory.newSAXParser();
- parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
- _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
+ try {
+ parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
+ } catch (SAXNotRecognizedException e) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.WARNING_MSG,
+ parser.getClass().getName() + ": " + e.getMessage());
+ reportError(WARNING, err);
+ }
+
final XMLReader reader = parser.getXMLReader();
return(parse(reader, input));
}
diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
index bef160df947..25c45c04be9 100644
--- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
+++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java
@@ -105,8 +105,6 @@ public final class Util {
if (reader == null) {
try {
reader= XMLReaderFactory.createXMLReader();
- reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
- xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
} catch (Exception e ) {
try {
@@ -138,6 +136,14 @@ public final class Util {
reader.setFeature
("http://xml.org/sax/features/namespace-prefixes",false);
+ try {
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
+ } catch (SAXNotRecognizedException e) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": "
+ + e.getMessage());
+ }
+
xsltc.setXMLReader(reader);
}catch (SAXNotRecognizedException snre ) {
throw new TransformerConfigurationException
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
index e53118b2d4f..3f493517209 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java
@@ -675,8 +675,6 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements
spf.setNamespaceAware(true);
try {
reader = spf.newSAXParser().getXMLReader();
- reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
- fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
// If this is a Xerces SAX parser, set the security manager if there is one
if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) {
SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER);
@@ -687,8 +685,13 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements
// Ignore the exception if the security manager cannot be set.
catch (SAXException exc) {}
}
- reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
- fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
+ try {
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD,
+ fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD));
+ } catch (SAXException exc) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": " +
+ exc.getMessage());
+ }
}
} catch( Exception e ) {
// this is impossible, but better safe than sorry
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
index 8f79f869cb2..28002037272 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java
@@ -136,11 +136,16 @@ public class XMLReaderManager {
try {
reader.setFeature(NAMESPACES_FEATURE, true);
reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false);
- reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
} catch (SAXException se) {
// Try to carry on if we've got a parser that
// doesn't know about namespace prefixes.
}
+ try {
+ reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
+ } catch (SAXException se) {
+ System.err.println("Warning: " + reader.getClass().getName() + ": "
+ + se.getMessage());
+ }
} catch (ParserConfigurationException ex) {
throw new SAXException(ex);
} catch (FactoryConfigurationError ex1) {
From 83aedc7fdd6cf07b283d74e1c7b50f6e87ee1005 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Tue, 11 Jun 2013 13:09:43 +0530
Subject: [PATCH 047/136] 8015357: a = []; a[0x7fffffff]=1; a.sort()[0] should
evaluate to 1 instead of undefined
Reviewed-by: hannesw, lagergren
---
nashorn/test/script/basic/JDK-8015357.js | 37 ++++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 nashorn/test/script/basic/JDK-8015357.js
diff --git a/nashorn/test/script/basic/JDK-8015357.js b/nashorn/test/script/basic/JDK-8015357.js
new file mode 100644
index 00000000000..b6c94537d98
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015357.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015357: a = []; a[0x7fffffff]=1; a.sort()[0] should evaluate to 1 instead of undefined
+ *
+ * @test
+ * @run
+ */
+
+var a = [];
+a[0x7fffffff]=1;
+
+if (a.sort()[0] != 1) {
+ fail("a.sort()[0] != 1");
+}
+
From 4836bfbcf1f5fea4f4ec63f388aa2b2d39b8400f Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 11 Jun 2013 09:35:58 +0100
Subject: [PATCH 048/136] 8008547: javac, warning message: use of ''_'' as an
identifier might not be supported in future releases, should be more
especific
Reviewed-by: jjg
---
.../classes/com/sun/tools/javac/resources/compiler.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index 9c2161e5d10..2487b7bef92 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -2204,7 +2204,7 @@ compiler.warn.assert.as.identifier=\
compiler.warn.underscore.as.identifier=\
''_'' used as an identifier\n\
- (use of ''_'' as an identifier might not be supported in future releases)
+ (use of ''_'' as an identifier might not be supported in releases after Java SE 8)
compiler.err.enum.as.identifier=\
as of release 5, ''enum'' is a keyword, and may not be used as an identifier\n\
From 3596018eb7ee920b7cf0c835737f30f663d9c0b6 Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 11 Jun 2013 09:59:34 +0100
Subject: [PATCH 049/136] 8007907: javap, method com.sun.tools.javap.Main.run
returns 0 even in case of class not found error
Reviewed-by: jjg
---
.../com/sun/tools/javap/JavapTask.java | 52 ++++++-------
.../javac/constDebug/ConstDebugTest.java | 21 +++---
.../8006334/JavapTaskCtorFailWithNPE.java | 3 +-
.../JavapReturns0AfterClassNotFoundTest.java | 75 +++++++++++++++++++
langtools/test/tools/javap/T4777949.java | 6 +-
langtools/test/tools/javap/T7190862.java | 3 +-
6 files changed, 117 insertions(+), 43 deletions(-)
create mode 100644 langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java
diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
index 2b499a831cd..77f9c3c8991 100644
--- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
+++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
@@ -452,8 +452,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
}
try {
- boolean ok = run();
- return ok ? EXIT_OK : EXIT_ERROR;
+ return run();
} finally {
if (defaultFileManager != null) {
try {
@@ -569,12 +568,13 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
}
public Boolean call() {
- return run();
+ return run() == 0;
}
- public boolean run() {
- if (classes == null || classes.size() == 0)
- return false;
+ public int run() {
+ if (classes == null || classes.isEmpty()) {
+ return EXIT_ERROR;
+ }
context.put(PrintWriter.class, log);
ClassWriter classWriter = ClassWriter.instance(context);
@@ -583,54 +583,55 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
attributeFactory.setCompat(options.compat);
- boolean ok = true;
+ int result = EXIT_OK;
for (String className: classes) {
- JavaFileObject fo;
try {
- writeClass(classWriter, className);
+ result = writeClass(classWriter, className);
} catch (ConstantPoolException e) {
reportError("err.bad.constant.pool", className, e.getLocalizedMessage());
- ok = false;
+ result = EXIT_ERROR;
} catch (EOFException e) {
reportError("err.end.of.file", className);
- ok = false;
+ result = EXIT_ERROR;
} catch (FileNotFoundException e) {
reportError("err.file.not.found", e.getLocalizedMessage());
- ok = false;
+ result = EXIT_ERROR;
} catch (IOException e) {
//e.printStackTrace();
Object msg = e.getLocalizedMessage();
- if (msg == null)
+ if (msg == null) {
msg = e;
+ }
reportError("err.ioerror", className, msg);
- ok = false;
+ result = EXIT_ERROR;
} catch (Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
pw.close();
reportError("err.crash", t.toString(), sw.toString());
- ok = false;
+ result = EXIT_ABNORMAL;
}
}
- return ok;
+ return result;
}
- protected boolean writeClass(ClassWriter classWriter, String className)
+ protected int writeClass(ClassWriter classWriter, String className)
throws IOException, ConstantPoolException {
JavaFileObject fo = open(className);
if (fo == null) {
reportError("err.class.not.found", className);
- return false;
+ return EXIT_ERROR;
}
ClassFileInfo cfInfo = read(fo);
if (!className.endsWith(".class")) {
String cfName = cfInfo.cf.getName();
- if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", ".")))
+ if (!cfName.replaceAll("[/$]", ".").equals(className.replaceAll("[/$]", "."))) {
reportWarning("warn.unexpected.class", className, cfName.replace('/', '.'));
+ }
}
write(cfInfo);
@@ -640,7 +641,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
if (a instanceof InnerClasses_attribute) {
InnerClasses_attribute inners = (InnerClasses_attribute) a;
try {
- boolean ok = true;
+ int result = EXIT_OK;
for (int i = 0; i < inners.classes.length; i++) {
int outerIndex = inners.classes[i].outer_class_info_index;
ConstantPool.CONSTANT_Class_info outerClassInfo = cf.constant_pool.getClassInfo(outerIndex);
@@ -651,21 +652,22 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
String innerClassName = innerClassInfo.getName();
classWriter.println("// inner class " + innerClassName.replaceAll("[/$]", "."));
classWriter.println();
- ok = ok & writeClass(classWriter, innerClassName);
+ result = writeClass(classWriter, innerClassName);
+ if (result != EXIT_OK) return result;
}
}
- return ok;
+ return result;
} catch (ConstantPoolException e) {
reportError("err.bad.innerclasses.attribute", className);
- return false;
+ return EXIT_ERROR;
}
} else if (a != null) {
reportError("err.bad.innerclasses.attribute", className);
- return false;
+ return EXIT_ERROR;
}
}
- return true;
+ return EXIT_OK;
}
protected JavaFileObject open(String className) throws IOException {
diff --git a/langtools/test/tools/javac/constDebug/ConstDebugTest.java b/langtools/test/tools/javac/constDebug/ConstDebugTest.java
index 6939d8f3836..20a4bf513cf 100644
--- a/langtools/test/tools/javac/constDebug/ConstDebugTest.java
+++ b/langtools/test/tools/javac/constDebug/ConstDebugTest.java
@@ -25,26 +25,25 @@
* @test
* @bug 4645152 4785453
* @summary javac compiler incorrectly inserts when -g is specified
- * @library /tools/javac/lib
- * @build ToolBox
* @run compile -g ConstDebugTest.java
* @run main ConstDebugTest
*/
+import java.nio.file.Paths;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Method;
-//original test: test/tools/javac/constDebug/ConstDebug.sh
public class ConstDebugTest {
public static final long l = 12;
public static void main(String args[]) throws Exception {
-// "${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -g -d . -classpath .${PS}${TESTSRC} $1.java 2> ${TMP1}
-// if "${TESTJAVA}${FS}bin${FS}javap" $1.class | grep clinit; then fail
- ToolBox.JavaToolArgs javapArgs =
- new ToolBox.JavaToolArgs().setAllArgs("-v",
- "-classpath", System.getProperty("test.classes"), "ConstDebugTest.class");
- if (ToolBox.javap(javapArgs).contains("clinit")) {
- throw new AssertionError(
- "javac should not create a method for ConstDebugTest class");
+ ClassFile classFile = ClassFile.read(Paths.get(System.getProperty("test.classes"),
+ ConstDebugTest.class.getSimpleName() + ".class"));
+ for (Method method: classFile.methods) {
+ if (method.getName(classFile.constant_pool).equals("")) {
+ throw new AssertionError(
+ "javac should not create a method for ConstDebugTest class");
+ }
}
}
diff --git a/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java b/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java
index 1ba5f9a106b..84e4f737ef6 100644
--- a/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java
+++ b/langtools/test/tools/javap/8006334/JavapTaskCtorFailWithNPE.java
@@ -66,8 +66,7 @@ public class JavapTaskCtorFailWithNPE {
JavaFileManager fm = JavapFileManager.create(dc, pw);
JavapTask t = new JavapTask(pw, fm, dc, null,
Arrays.asList(classToCheck.getPath()));
- boolean ok = t.run();
- if (!ok)
+ if (t.run() != 0)
throw new Error("javap failed unexpectedly");
List> diags = dc.getDiagnostics();
diff --git a/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java b/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java
new file mode 100644
index 00000000000..06e94963faf
--- /dev/null
+++ b/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 8007907
+ * @summary javap, method com.sun.tools.javap.Main.run returns 0 even in case
+ * of class not found error
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class JavapReturns0AfterClassNotFoundTest {
+
+ static final String fileNotFoundErrorMsg =
+ "Error: class not found: Unexisting.class";
+ static final String exitCodeClassNotFoundAssertionMsg =
+ "Javap's exit code for class not found should be 1";
+ static final String classNotFoundMsgAssertionMsg =
+ "Javap's error message for class not found is incorrect";
+
+ public static void main(String args[]) throws Exception {
+ new JavapReturns0AfterClassNotFoundTest().run();
+ }
+
+ void run() throws IOException {
+ check(exitCodeClassNotFoundAssertionMsg, classNotFoundMsgAssertionMsg,
+ fileNotFoundErrorMsg, "-v", "Unexisting.class");
+ }
+
+ void check(String exitCodeAssertionMsg, String errMsgAssertionMsg,
+ String expectedErrMsg, String... params) {
+ int result;
+ StringWriter s;
+ String out;
+ try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+ result = com.sun.tools.javap.Main.run(params, pw);
+ //no line separator, no problem
+ out = s.toString().trim();
+ }
+ if (result != 1) {
+ System.out.println("actual exit code " + result);
+ throw new AssertionError(exitCodeAssertionMsg);
+ }
+
+ if (!out.equals(expectedErrMsg)) {
+ System.out.println("actual " + out);
+ System.out.println("expected " + expectedErrMsg);
+ throw new AssertionError(errMsgAssertionMsg);
+ }
+ }
+
+}
diff --git a/langtools/test/tools/javap/T4777949.java b/langtools/test/tools/javap/T4777949.java
index 4dcc551b341..af81b2b4f53 100644
--- a/langtools/test/tools/javap/T4777949.java
+++ b/langtools/test/tools/javap/T4777949.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -87,11 +87,11 @@ public class T4777949 {
PrintWriter pw = new PrintWriter(sw);
JavaFileManager fm = JavapFileManager.create(dc, pw);
JavapTask t = new JavapTask(pw, fm, dc, args, classes);
- boolean ok = t.run();
+ int ok = t.run();
List> diags = dc.getDiagnostics();
- if (!ok)
+ if (ok != 0)
error("javap failed unexpectedly");
System.err.println("args=" + args + " classes=" + classes + "\n"
diff --git a/langtools/test/tools/javap/T7190862.java b/langtools/test/tools/javap/T7190862.java
index b7b57daa2f7..8a40ac481c7 100644
--- a/langtools/test/tools/javap/T7190862.java
+++ b/langtools/test/tools/javap/T7190862.java
@@ -96,8 +96,7 @@ public class T7190862 {
PrintWriter pw = new PrintWriter(sw);
JavaFileManager fm = JavapFileManager.create(dc, pw);
JavapTask t = new JavapTask(pw, fm, dc, args, classes);
- boolean ok = t.run();
- if (!ok)
+ if (t.run() != 0)
throw new Error("javap failed unexpectedly");
List> diags = dc.getDiagnostics();
From 1963dde59aaeeee562e50711b19cc2fae9d8061e Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Tue, 11 Jun 2013 14:14:31 +0400
Subject: [PATCH 050/136] 8012569: TEST_BUG:
java/awt/GraphicsDevice/CheckDisplayModes.java fails
Reviewed-by: anthony, serb
---
jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
index bc8d8a50be6..719ee9b43a7 100644
--- a/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
+++ b/jdk/test/java/awt/GraphicsDevice/CheckDisplayModes.java
@@ -37,6 +37,10 @@ public class CheckDisplayModes {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice graphicDevice = ge.getDefaultScreenDevice();
+ if (!graphicDevice.isDisplayChangeSupported()) {
+ System.err.println("Display mode change is not supported on this host. Test is considered passed.");
+ return;
+ }
DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
checkDisplayMode(defaultDisplayMode);
graphicDevice.setDisplayMode(defaultDisplayMode);
From 1df3335d0d24c321fa6451b0a5a7f633114d0359 Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Tue, 11 Jun 2013 14:20:37 +0400
Subject: [PATCH 051/136] 7184908: TEST_BUG: [macosx]
closed/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java fails
Reviewed-by: alexsch, serb
---
.../swing/plaf/gtk/4928019/bug4928019.java | 244 ++++++++++++++++++
1 file changed, 244 insertions(+)
create mode 100644 jdk/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java
diff --git a/jdk/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java b/jdk/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java
new file mode 100644
index 00000000000..60761c00ea7
--- /dev/null
+++ b/jdk/test/com/sun/java/swing/plaf/gtk/4928019/bug4928019.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 4928019
+ * @summary Makes sure all the basic classes can be created with GTK.
+ * @author Scott Violet
+ */
+
+import javax.swing.*;
+import javax.swing.plaf.basic.*;
+
+public class bug4928019 {
+ public static void main(String[] args) throws Throwable {
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+ } catch (UnsupportedLookAndFeelException ex) {
+ System.err.println("GTKLookAndFeel is not supported on this platform." +
+ " Test is considered passed.");
+ return;
+ } catch (ClassNotFoundException ex) {
+ System.err.println("GTKLookAndFeel class is not found." +
+ " Test is considered passed.");
+ return;
+ }
+ new JButton() {
+ public void updateUI() {
+ setUI(new BasicButtonUI());
+ }
+ };
+ new JCheckBox() {
+ public void updateUI() {
+ setUI(new BasicCheckBoxUI());
+ }
+ };
+ new JCheckBoxMenuItem() {
+ public void updateUI() {
+ setUI(new BasicCheckBoxMenuItemUI());
+ }
+ };
+ new JColorChooser() {
+ public void updateUI() {
+ setUI(new BasicColorChooserUI());
+ }
+ };
+ new JComboBox() {
+ public void updateUI() {
+ setUI(new BasicComboBoxUI());
+ }
+ };
+ new JDesktopPane() {
+ public void updateUI() {
+ setUI(new BasicDesktopPaneUI());
+ }
+ };
+ new JEditorPane() {
+ public void updateUI() {
+ setUI(new BasicEditorPaneUI());
+ }
+ };
+ new JFileChooser() {
+ public void updateUI() {
+ setUI(new BasicFileChooserUI(null));
+ }
+ };
+ new JFormattedTextField() {
+ public void updateUI() {
+ setUI(new BasicFormattedTextFieldUI());
+ }
+ };
+ new JInternalFrame() {
+ public void updateUI() {
+ setUI(new BasicInternalFrameUI(null));
+ }
+ };
+ new JLabel() {
+ public void updateUI() {
+ setUI(new BasicLabelUI());
+ }
+ };
+ new JList() {
+ public void updateUI() {
+ setUI(new BasicListUI());
+ }
+ };
+ new JMenuBar() {
+ public void updateUI() {
+ setUI(new BasicMenuBarUI());
+ }
+ };
+ new JMenuItem() {
+ public void updateUI() {
+ setUI(new BasicMenuItemUI());
+ }
+ };
+ new JMenu() {
+ public void updateUI() {
+ setUI(new BasicMenuUI());
+ }
+ };
+ new JOptionPane() {
+ public void updateUI() {
+ setUI(new BasicOptionPaneUI());
+ }
+ };
+ new JPanel() {
+ public void updateUI() {
+ setUI(new BasicPanelUI());
+ }
+ };
+ new JPasswordField() {
+ public void updateUI() {
+ setUI(new BasicPasswordFieldUI());
+ }
+ };
+ new JPopupMenu() {
+ public void updateUI() {
+ setUI(new BasicPopupMenuUI());
+ }
+ };
+ new JProgressBar() {
+ public void updateUI() {
+ setUI(new BasicProgressBarUI());
+ }
+ };
+ new JRadioButton() {
+ public void updateUI() {
+ setUI(new BasicRadioButtonUI());
+ }
+ };
+ new JRadioButtonMenuItem() {
+ public void updateUI() {
+ setUI(new BasicRadioButtonMenuItemUI());
+ }
+ };
+ new JRootPane() {
+ public void updateUI() {
+ setUI(new BasicRootPaneUI());
+ }
+ };
+ new JScrollBar() {
+ public void updateUI() {
+ setUI(new BasicScrollBarUI());
+ }
+ };
+ new JScrollPane() {
+ public void updateUI() {
+ setUI(new BasicScrollPaneUI());
+ }
+ };
+ new JSeparator() {
+ public void updateUI() {
+ setUI(new BasicSeparatorUI());
+ }
+ };
+ new JSlider() {
+ public void updateUI() {
+ setUI(new BasicSliderUI(null));
+ }
+ };
+ new JSpinner() {
+ public void updateUI() {
+ setUI(new BasicSpinnerUI());
+ }
+ };
+ new JSplitPane() {
+ public void updateUI() {
+ setUI(new BasicSplitPaneUI());
+ }
+ };
+ new JTabbedPane() {
+ public void updateUI() {
+ setUI(new BasicTabbedPaneUI());
+ }
+ };
+ new JTable() {
+ public void updateUI() {
+ setUI(new BasicTableUI());
+ }
+ };
+ new JTextArea() {
+ public void updateUI() {
+ setUI(new BasicTextAreaUI());
+ }
+ };
+ new JTextField() {
+ public void updateUI() {
+ setUI(new BasicTextFieldUI());
+ }
+ };
+ new JTextPane() {
+ public void updateUI() {
+ setUI(new BasicTextPaneUI());
+ }
+ };
+ new JToggleButton() {
+ public void updateUI() {
+ setUI(new BasicToggleButtonUI());
+ }
+ };
+ new JToolBar() {
+ public void updateUI() {
+ setUI(new BasicToolBarUI());
+ }
+ };
+ new JToolTip() {
+ public void updateUI() {
+ setUI(new BasicToolTipUI());
+ }
+ };
+ new JTree() {
+ public void updateUI() {
+ setUI(new BasicTreeUI());
+ }
+ };
+ new JViewport() {
+ public void updateUI() {
+ setUI(new BasicViewportUI());
+ }
+ };
+ System.out.println("DONE");
+ }
+}
From 857a99a9e72dea0c388fd4b04441538f97bb9f4c Mon Sep 17 00:00:00 2001
From: Sergey Malenkov
Date: Tue, 11 Jun 2013 16:02:22 +0400
Subject: [PATCH 052/136] 8015336: BasicComboBoxEditor throws
NullPointerException
Reviewed-by: alexsch
---
.../swing/plaf/basic/BasicComboBoxEditor.java | 3 ++
.../BasicComboBoxEditor/Test8015336.java | 41 +++++++++++++++++++
2 files changed, 44 insertions(+)
create mode 100644 jdk/test/javax/swing/plaf/basic/BasicComboBoxEditor/Test8015336.java
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java
index 1b741db47f6..c902252f4dc 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java
@@ -73,6 +73,9 @@ public class BasicComboBoxEditor implements ComboBoxEditor,FocusListener {
if ( anObject != null ) {
text = anObject.toString();
+ if (text == null) {
+ text = "";
+ }
oldValue = anObject;
} else {
text = "";
diff --git a/jdk/test/javax/swing/plaf/basic/BasicComboBoxEditor/Test8015336.java b/jdk/test/javax/swing/plaf/basic/BasicComboBoxEditor/Test8015336.java
new file mode 100644
index 00000000000..742fc99091a
--- /dev/null
+++ b/jdk/test/javax/swing/plaf/basic/BasicComboBoxEditor/Test8015336.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please 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 javax.swing.JComboBox;
+
+/*
+ * @test
+ * @bug 8015336
+ * @summary No NPE for BasicComboBoxEditor.setItem(null)
+ * @author Sergey Malenkov
+ */
+public class Test8015336 {
+ public static void main(String[] args) throws Exception {
+ new JComboBox().getEditor().setItem(new Test8015336());
+ }
+
+ @Override
+ public String toString() {
+ return null;
+ }
+}
From 3352552f34ae2f1079263bd1e28481cfbcc9165e Mon Sep 17 00:00:00 2001
From: Alexander Scherbatiy
Date: Tue, 11 Jun 2013 16:30:34 +0400
Subject: [PATCH 053/136] 8009984: [parfait] Buffer overrun at
jdk/src/macosx/native/com/apple/laf/AquaFileView.m
Reviewed-by: serb, art
---
jdk/src/macosx/native/com/apple/laf/AquaFileView.m | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/jdk/src/macosx/native/com/apple/laf/AquaFileView.m b/jdk/src/macosx/native/com/apple/laf/AquaFileView.m
index 8f33cc5da8c..65fcc72abd3 100644
--- a/jdk/src/macosx/native/com/apple/laf/AquaFileView.m
+++ b/jdk/src/macosx/native/com/apple/laf/AquaFileView.m
@@ -187,13 +187,13 @@ JNIEXPORT jstring JNICALL Java_com_apple_laf_AquaFileView_getNativePathForResolv
JNF_COCOA_ENTER(env);
UInt8 pathCString[MAXPATHLEN + 1];
- size_t pathSize = sizeof(pathCString);
+ size_t maxPathLen = sizeof(pathCString) - 1;
jbyte *byteArray = (*env)->GetByteArrayElements(env, pathToAlias, NULL);
jsize length = (*env)->GetArrayLength(env, pathToAlias);
- if (length > pathSize) {
- length = pathSize;
+ if (length > maxPathLen) {
+ length = maxPathLen;
}
strncpy((char *)pathCString, (char *)byteArray, length);
// make sure it's null terminated
From 526f21a95ed73009d6545c4f482ecd5a3adfd092 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Tue, 11 Jun 2013 17:50:10 +0200
Subject: [PATCH 054/136] 8015379: PropertyMap.addProperty() is slow
Reviewed-by: attila, jlaskey
---
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
index 077218d3f4f..b7248166696 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
@@ -95,7 +95,6 @@ public final class PropertyMap implements Iterable, PropertyListener {
*/
private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum) {
this.properties = properties;
- this.hashCode = computeHashCode();
this.fieldCount = fieldCount;
this.fieldMaximum = fieldMaximum;
@@ -125,7 +124,6 @@ public final class PropertyMap implements Iterable, PropertyListener {
this.spillLength = propertyMap.spillLength;
this.fieldCount = propertyMap.fieldCount;
this.fieldMaximum = propertyMap.fieldMaximum;
- this.hashCode = computeHashCode();
if (Context.DEBUG) {
count++;
@@ -610,6 +608,9 @@ public final class PropertyMap implements Iterable, PropertyListener {
@Override
public int hashCode() {
+ if (hashCode == 0 && !properties.isEmpty()) {
+ hashCode = computeHashCode();
+ }
return hashCode;
}
From f2a70d73109f438078ae59671e89eab1463ce933 Mon Sep 17 00:00:00 2001
From: Christian Thalinger
Date: Tue, 11 Jun 2013 11:13:09 -0700
Subject: [PATCH 055/136] 8003268: SharedRuntime::generate_native_wrapper
doesn't save all registers across runtime tracing calls for JNI critical
native methods
Reviewed-by: kvn
---
.../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 41 ++++++++++++-------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
index db20c1f2388..cbe960556dc 100644
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
@@ -1429,6 +1429,8 @@ static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType
assert(!length_arg.first()->is_Register() || length_arg.first()->as_Register() != tmp_reg,
"possible collision");
+ __ block_comment("unpack_array_argument {");
+
// Pass the length, ptr pair
Label is_null, done;
VMRegPair tmp;
@@ -1453,6 +1455,8 @@ static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType
move_ptr(masm, tmp, body_arg);
move32_64(masm, tmp, length_arg);
__ bind(done);
+
+ __ block_comment("} unpack_array_argument");
}
@@ -2170,27 +2174,34 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
}
}
- // point c_arg at the first arg that is already loaded in case we
- // need to spill before we call out
- int c_arg = total_c_args - total_in_args;
+ int c_arg;
// Pre-load a static method's oop into r14. Used both by locking code and
// the normal JNI call code.
- if (method->is_static() && !is_critical_native) {
+ if (!is_critical_native) {
+ // point c_arg at the first arg that is already loaded in case we
+ // need to spill before we call out
+ c_arg = total_c_args - total_in_args;
- // load oop into a register
- __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
+ if (method->is_static()) {
- // Now handlize the static class mirror it's known not-null.
- __ movptr(Address(rsp, klass_offset), oop_handle_reg);
- map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
+ // load oop into a register
+ __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror()));
- // Now get the handle
- __ lea(oop_handle_reg, Address(rsp, klass_offset));
- // store the klass handle as second argument
- __ movptr(c_rarg1, oop_handle_reg);
- // and protect the arg if we must spill
- c_arg--;
+ // Now handlize the static class mirror it's known not-null.
+ __ movptr(Address(rsp, klass_offset), oop_handle_reg);
+ map->set_oop(VMRegImpl::stack2reg(klass_slot_offset));
+
+ // Now get the handle
+ __ lea(oop_handle_reg, Address(rsp, klass_offset));
+ // store the klass handle as second argument
+ __ movptr(c_rarg1, oop_handle_reg);
+ // and protect the arg if we must spill
+ c_arg--;
+ }
+ } else {
+ // For JNI critical methods we need to save all registers in save_args.
+ c_arg = 0;
}
// Change state to native (we save the return address in the thread, since it might not
From 219121826ed2a746d2ef5108b40a6f9746f4758b Mon Sep 17 00:00:00 2001
From: David Chase
Date: Tue, 11 Jun 2013 16:34:34 -0400
Subject: [PATCH 056/136] 8014959: assert(Compile::current()->live_nodes() <
(uint)MaxNodeLimit) failed: Live Node limit exceeded limit
Insert extra checks and bailouts for too many nodes
Reviewed-by: kvn
---
hotspot/src/share/vm/opto/c2_globals.hpp | 6 +++---
hotspot/src/share/vm/opto/chaitin.cpp | 5 ++++-
hotspot/src/share/vm/opto/coalesce.cpp | 4 +++-
hotspot/src/share/vm/opto/matcher.cpp | 4 +++-
4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index 49ed1e8bcf0..2e212995f3e 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -406,10 +406,10 @@
develop(intx, WarmCallMaxSize, 999999, \
"size of the largest inlinable method") \
\
- product(intx, MaxNodeLimit, 65000, \
+ product(intx, MaxNodeLimit, 80000, \
"Maximum number of nodes") \
\
- product(intx, NodeLimitFudgeFactor, 1000, \
+ product(intx, NodeLimitFudgeFactor, 2000, \
"Fudge Factor for certain optimizations") \
\
product(bool, UseJumpTables, true, \
diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp
index 9d69b0f3b71..53ffc573284 100644
--- a/hotspot/src/share/vm/opto/chaitin.cpp
+++ b/hotspot/src/share/vm/opto/chaitin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -435,6 +435,9 @@ void PhaseChaitin::Register_Allocate() {
// Insert un-coalesced copies. Visit all Phis. Where inputs to a Phi do
// not match the Phi itself, insert a copy.
coalesce.insert_copies(_matcher);
+ if (C->failing()) {
+ return;
+ }
}
// After aggressive coalesce, attempt a first cut at coloring.
diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp
index 74618fb410c..60c88dc12ba 100644
--- a/hotspot/src/share/vm/opto/coalesce.cpp
+++ b/hotspot/src/share/vm/opto/coalesce.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -240,6 +240,8 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
_unique = C->unique();
for( uint i=0; i<_phc._cfg._num_blocks; i++ ) {
+ C->check_node_count(NodeLimitFudgeFactor, "out of nodes in coalesce");
+ if (C->failing()) return;
Block *b = _phc._cfg._blocks[i];
uint cnt = b->num_preds(); // Number of inputs to the Phi
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 91b4448c9bc..c2084df52c9 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -985,6 +985,8 @@ Node *Matcher::xform( Node *n, int max_stack ) {
mstack.push(n, Visit, NULL, -1); // set NULL as parent to indicate root
while (mstack.is_nonempty()) {
+ C->check_node_count(NodeLimitFudgeFactor, "too many nodes matching instructions");
+ if (C->failing()) return NULL;
n = mstack.node(); // Leave node on stack
Node_State nstate = mstack.state();
if (nstate == Visit) {
From 861f05be2fe6c0b7d97ef03fa748cce2f3ea59c6 Mon Sep 17 00:00:00 2001
From: Anton Tarasov
Date: Wed, 12 Jun 2013 16:18:04 +0400
Subject: [PATCH 057/136] 8015454:
java/awt/Focus/TypeAhead/TestFocusFreeze.java hangs with jdk8 since b56
Reviewed-by: anthony
---
.../java/awt/DefaultKeyboardFocusManager.java | 15 +++++++++++----
.../java/awt/Focus/TypeAhead/TestFocusFreeze.java | 1 +
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
index f4199881989..7676f5b068a 100644
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
+++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
@@ -285,10 +285,17 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
TimedWindowEvent we = (TimedWindowEvent)e;
long time = we.getWhen();
synchronized (this) {
- for (KeyEvent ke: enqueuedKeyEvents) {
- if (time >= ke.getWhen()) {
- SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
- return true;
+ KeyEvent ke = enqueuedKeyEvents.isEmpty() ? null : enqueuedKeyEvents.getFirst();
+ if (ke != null && time >= ke.getWhen()) {
+ TypeAheadMarker marker = typeAheadMarkers.getFirst();
+ if (marker != null) {
+ Window toplevel = marker.untilFocused.getContainingWindow();
+ // Check that the component awaiting focus belongs to
+ // the current focused window. See 8015454.
+ if (toplevel != null && toplevel.isFocused()) {
+ SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
+ return true;
+ }
}
}
}
diff --git a/jdk/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java b/jdk/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java
index a22551bec2c..2edcf9db98a 100644
--- a/jdk/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java
+++ b/jdk/test/java/awt/Focus/TypeAhead/TestFocusFreeze.java
@@ -132,6 +132,7 @@ class TestKFM extends DefaultKeyboardFocusManager {
}
protected synchronized void enqueueKeyEvents(long after, Component untilFocused) {
super.enqueueKeyEvents(after, untilFocused);
+ robot.delay(1);
robot.keyPress(KeyEvent.VK_SPACE);
robot.delay(50);
robot.keyRelease(KeyEvent.VK_SPACE);
From 55c80a79543e21bc67852edf7a9fdfafcb7ae2c0 Mon Sep 17 00:00:00 2001
From: Miroslav Kos
Date: Wed, 12 Jun 2013 14:47:09 +0100
Subject: [PATCH 058/136] 8013021: Rebase 8005432 & 8003542 against the latest
jdk8/jaxws 8003542: Improve processing of MTOM attachments 8005432: Update
access to JAX-WS
Reviewed-by: mullan
---
.../databinding/DatabindingModeFeature.java | 4 +-
.../databinding/ExternalMetadataFeature.java | 6 +
.../message/BaseDistributedPropertySet.java | 1 +
.../impl/encoding/StreamDecoderImpl.java | 1 +
.../jaxws_databinding/package-info.java | 1 -
.../internal/jxc/MessageBundle.properties | 4 +-
.../internal/jxc/MessageBundle_de.properties | 4 +-
.../internal/jxc/MessageBundle_es.properties | 4 +-
.../internal/jxc/MessageBundle_fr.properties | 4 +-
.../internal/jxc/MessageBundle_it.properties | 4 +-
.../internal/jxc/MessageBundle_ja.properties | 4 +-
.../internal/jxc/MessageBundle_ko.properties | 4 +-
.../jxc/MessageBundle_pt_BR.properties | 4 +-
.../jxc/MessageBundle_zh_CN.properties | 4 +-
.../jxc/MessageBundle_zh_TW.properties | 4 +-
.../internal/jxc/gen/config/Classes.java | 130 +++++-----
.../tools/internal/jxc/gen/config/Config.java | 128 +++++-----
.../tools/internal/jxc/gen/config/Schema.java | 160 ++++++------
.../sun/tools/internal/ws/version.properties | 6 +-
.../internal/xjc/MessageBundle.properties | 12 +-
.../internal/xjc/MessageBundle_de.properties | 12 +-
.../internal/xjc/MessageBundle_es.properties | 12 +-
.../internal/xjc/MessageBundle_fr.properties | 12 +-
.../internal/xjc/MessageBundle_it.properties | 12 +-
.../internal/xjc/MessageBundle_ja.properties | 12 +-
.../internal/xjc/MessageBundle_ko.properties | 12 +-
.../xjc/MessageBundle_pt_BR.properties | 12 +-
.../xjc/MessageBundle_zh_CN.properties | 12 +-
.../xjc/MessageBundle_zh_TW.properties | 12 +-
.../bind/v2/model/impl/ModelBuilder.java | 13 +-
.../bind/v2/runtime/JAXBContextImpl.java | 15 +-
.../bind/v2/schemagen/XmlSchemaGenerator.java | 8 +-
.../fastinfoset/CommonResourceBundle.java | 7 +-
.../sun/xml/internal/fastinfoset/Decoder.java | 14 +-
.../algorithm/BASE64EncodingAlgorithm.java | 4 +-
.../algorithm/BooleanEncodingAlgorithm.java | 4 +-
.../algorithm/BuiltInEncodingAlgorithm.java | 6 +-
.../algorithm/FloatEncodingAlgorithm.java | 2 +-
.../HexadecimalEncodingAlgorithm.java | 4 +-
.../fastinfoset/dom/DOMDocumentParser.java | 6 +-
.../resources/ResourceBundle.properties | 2 +-
.../fastinfoset/sax/AttributesHolder.java | 2 +-
.../fastinfoset/sax/SAXDocumentParser.java | 6 +-
.../fastinfoset/stax/StAXDocumentParser.java | 13 +-
.../stax/events/StartElementEvent.java | 14 +-
.../stax/factory/StAXOutputFactory.java | 57 +++--
.../fastinfoset/tools/SAXEventSerializer.java | 22 +-
.../tools/TransformInputOutput.java | 4 +-
.../internal/org/jvnet/mimepull/DataHead.java | 4 +-
.../org/jvnet/mimepull/MemoryData.java | 17 +-
.../org/jvnet/mimepull/TempFiles.java | 144 +++++++++++
.../ws/api/databinding/DatabindingConfig.java | 36 +--
.../ws/api/message/saaj/SAAJFactory.java | 10 +-
.../sun/xml/internal/ws/api/pipe/Fiber.java | 5 +-
.../api/streaming/XMLStreamWriterFactory.java | 34 ++-
.../ws/assembler/MetroConfigLoader.java | 37 ++-
.../internal/ws/assembler/TubeCreator.java | 24 +-
.../internal/ws/client/MonitorRootClient.java | 10 +-
.../xml/internal/ws/client/SEIPortInfo.java | 30 ++-
.../internal/ws/client/WSServiceDelegate.java | 59 +++--
.../ws/client/dispatch/DispatchImpl.java | 4 +-
.../xml/internal/ws/client/sei/SEIStub.java | 4 +-
.../ws/client/sei/SyncMethodHandler.java | 46 ++--
.../ws/db/DatabindingFactoryImpl.java | 34 +--
.../xml/internal/ws/db/DatabindingImpl.java | 228 ++++++++++--------
.../xml/internal/ws/encoding/MtomCodec.java | 42 +++-
.../ws/message/stream/StreamMessage.java | 33 ++-
.../xml/internal/ws/model/RuntimeModeler.java | 19 +-
.../ws/model/WrapperBeanGenerator.java | 22 +-
.../ws/model/wsdl/WSDLBoundOperationImpl.java | 17 +-
.../ws/model/wsdl/WSDLOperationImpl.java | 4 +-
.../ws/resources/DispatchMessages.java | 12 +
.../internal/ws/resources/dispatch.properties | 3 +-
.../internal/ws/server/EndpointFactory.java | 28 +--
.../xml/internal/ws/spi/db/BindingInfo.java | 11 +-
.../ws/spi/db/JAXBWrapperAccessor.java | 12 +-
.../ws/transport/http/HttpAdapter.java | 121 ++++++----
.../xml/internal/ws/util/version.properties | 6 +-
.../javax/xml/soap/FactoryFinder.java | 62 ++---
.../javax/xml/soap/MessageFactory.java | 18 +-
.../javax/xml/soap/SAAJMetaFactory.java | 4 +-
.../javax/xml/soap/SOAPConnectionFactory.java | 4 +-
.../javax/xml/soap/SOAPFactory.java | 8 +-
83 files changed, 1159 insertions(+), 793 deletions(-)
create mode 100644 jaxws/src/share/jaxws_classes/com/sun/xml/internal/org/jvnet/mimepull/TempFiles.java
diff --git a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/DatabindingModeFeature.java b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/DatabindingModeFeature.java
index c4cf116b0e0..5acb939ebec 100644
--- a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/DatabindingModeFeature.java
+++ b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/DatabindingModeFeature.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@ import java.util.Map;
import javax.xml.ws.WebServiceFeature;
-public class DatabindingModeFeature extends WebServiceFeature {
+public class DatabindingModeFeature extends WebServiceFeature implements com.sun.xml.internal.ws.api.ServiceSharedFeatureMarker {
/**
* Constant value identifying the DatabindingFeature
*/
diff --git a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/ExternalMetadataFeature.java b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/ExternalMetadataFeature.java
index d0c0d87a7fb..ff182cd86af 100644
--- a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/ExternalMetadataFeature.java
+++ b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/databinding/ExternalMetadataFeature.java
@@ -52,6 +52,7 @@ public class ExternalMetadataFeature extends WebServiceFeature {
private List resourceNames;
private List files;
+ private MetadataReader reader;
private ExternalMetadataFeature() {
}
@@ -88,6 +89,7 @@ public class ExternalMetadataFeature extends WebServiceFeature {
}
public MetadataReader getMetadataReader(ClassLoader classLoader, boolean disableSecureXmlProcessing) {
+ if (reader != null && enabled) return reader;
return enabled ? new ExternalMetadataReader(files, resourceNames, classLoader, true, disableSecureXmlProcessing) : null;
}
@@ -153,5 +155,9 @@ public class ExternalMetadataFeature extends WebServiceFeature {
return this;
}
+ public Builder setReader( MetadataReader r ) {
+ o.reader = r;
+ return this;
+ }
}
}
diff --git a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/message/BaseDistributedPropertySet.java b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/message/BaseDistributedPropertySet.java
index ab53f0574c1..e4ea2c19ea8 100644
--- a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/message/BaseDistributedPropertySet.java
+++ b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/api/message/BaseDistributedPropertySet.java
@@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package com.oracle.webservices.internal.api.message;
import com.sun.istack.internal.NotNull;
diff --git a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/impl/encoding/StreamDecoderImpl.java b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/impl/encoding/StreamDecoderImpl.java
index 28b3502cfdb..0ab6a2ea7a1 100644
--- a/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/impl/encoding/StreamDecoderImpl.java
+++ b/jaxws/src/share/jaxws_classes/com/oracle/webservices/internal/impl/encoding/StreamDecoderImpl.java
@@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+
package com.oracle.webservices.internal.impl.encoding;
import java.io.IOException;
diff --git a/jaxws/src/share/jaxws_classes/com/oracle/xmlns/internal/webservices/jaxws_databinding/package-info.java b/jaxws/src/share/jaxws_classes/com/oracle/xmlns/internal/webservices/jaxws_databinding/package-info.java
index 457f7e76b38..e91a138d49f 100644
--- a/jaxws/src/share/jaxws_classes/com/oracle/xmlns/internal/webservices/jaxws_databinding/package-info.java
+++ b/jaxws/src/share/jaxws_classes/com/oracle/xmlns/internal/webservices/jaxws_databinding/package-info.java
@@ -23,7 +23,6 @@
* questions.
*/
-
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.6-SNAPSHOT
// See http://java.sun.com/xml/jaxb
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle.properties
index b68f941bda4..c1805f1ff17 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle.properties
@@ -30,10 +30,10 @@ BASEDIR_DOESNT_EXIST = \
Non-existent directory: {0}
VERSION = \
- schemagen 2.2.7-b63
+ schemagen 2.2.8-b01
FULLVERSION = \
- schemagen full version "2.2.7-b63"
+ schemagen full version "2.2.8-b01"
USAGE = \
Usage: schemagen [-options ...] \n\
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_de.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_de.properties
index 77b472d313c..971c1709e2e 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_de.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_de.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = Nicht erkanntes {0} in Zeile {1} Spalte {2}
BASEDIR_DOESNT_EXIST = Nicht vorhandenes Verzeichnis: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = schemagen vollst\u00E4ndige Version "2.2.7-b63"
+FULLVERSION = schemagen vollst\u00E4ndige Version "2.2.8-b01"
USAGE = Verwendung: schemagen [-options ...] \nOptionen: \n\\ \\ \\ \\ -d : Gibt an, wo die von Prozessor und javac generierten Klassendateien gespeichert werden sollen\n\\ \\ \\ \\ -cp : Gibt an, wo die vom Benutzer angegebenen Dateien gespeichert sind\n\\ \\ \\ \\ -classpath : Gibt an, wo die vom Benutzer angegebenen Dateien gespeichert sind\n\\ \\ \\ \\ -encoding : Gibt die Codierung f\u00FCr die Annotationsverarbeitung/den javac-Aufruf an \n\\ \\ \\ \\ -episode : Generiert Episodendatei f\u00FCr separate Kompilierung\n\\ \\ \\ \\ -version : Zeigt Versionsinformation an\n\\ \\ \\ \\ -fullversion : Zeigt vollst\u00E4ndige Versionsinformationen an\n\\ \\ \\ \\ -help : Zeigt diese Verwendungsmeldung an
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_es.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_es.properties
index 4281c08073f..030047264b7 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_es.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_es.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = Aparece un {0} inesperado en la l\u00EDnea {1} y la colu
BASEDIR_DOESNT_EXIST = Directorio no existente: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = versi\u00F3n completa de schemagen "2.2.7-b63"
+FULLVERSION = versi\u00F3n completa de schemagen "2.2.8-b01"
USAGE = Sintaxis: schemagen [-options ...] \nOpciones: \n\\ \\ \\ \\ -d : especifique d\u00F3nde se colocan los archivos de clase generados por javac y el procesador\n\\ \\ \\ \\ -cp : especifique d\u00F3nde se encuentran los archivos especificados por el usuario\n\\ \\ \\ \\ -encoding : especifique la codificaci\u00F3n que se va a utilizar para el procesamiento de anotaciones/llamada de javac\n\\ \\ \\ \\ -episode : genera un archivo de episodio para una compilaci\u00F3n diferente\n\\ \\ \\ \\ -version : muestra la informaci\u00F3n de la versi\u00F3n\n\\ \\ \\ \\ -fullversion : muestra la informaci\u00F3n completa de la versi\u00F3n\n\\ \\ \\ \\ -help : muestra este mensaje de sintaxis
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_fr.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_fr.properties
index e72bfd541b2..b3107ee4418 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_fr.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_fr.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = Un \u00E9l\u00E9ment {0} inattendu appara\u00EEt \u00E0
BASEDIR_DOESNT_EXIST = R\u00E9pertoire {0} inexistant
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = version compl\u00E8te de schemagen "2.2.7-b63"
+FULLVERSION = version compl\u00E8te de schemagen "2.2.8-b01"
USAGE = Syntaxe : schemagen [-options ...] \nOptions : \n\ \ \ \ -d : indiquez o\u00F9 placer les fichiers de classe g\u00E9n\u00E9r\u00E9s par le processeur et le compilateur javac\n\ \ \ \ -cp : indiquez o\u00F9 trouver les fichiers sp\u00E9cifi\u00E9s par l'utilisateur\n\ \ \ \ -classpath : indiquez o\u00F9 trouver les fichiers sp\u00E9cifi\u00E9s par l'utilisateur\n\ \ \ \ -encoding : indiquez l'encodage \u00E0 utiliser pour l'appel de javac/traitement de l'annotation \n\ \ \ \ -episode : g\u00E9n\u00E9rez un fichier d'\u00E9pisode pour la compilation s\u00E9par\u00E9e\n\ \ \ \ -version : affichez les informations de version\n\ \ \ \ -fullversion : affichez les informations compl\u00E8tes de version\n\ \ \ \ -help : affichez ce message de syntaxe
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_it.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_it.properties
index 25a9f06a15d..0aa7cf4c807 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_it.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_it.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = {0} imprevisto visualizzato sulla riga {1} colonna {2}
BASEDIR_DOESNT_EXIST = Directory non esistente: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = versione completa schemagen "2.2.7-b63"
+FULLVERSION = versione completa schemagen "2.2.8-b01"
USAGE = Uso: schemagen [-options ...] \nOpzioni: \n\ \ \ \ -d : specifica dove posizionare il processore e i file della classe generata javac\n\ \ \ \ -cp : specifica dove trovare i file specificati dall'utente\n\ \ \ \ -classpath : specifica dove trovare i file specificati dall'utente\n\ \ \ \ -encoding : specifica la codifica da usare per l'elaborazione dell'annotazione/richiamo javac \n\ \ \ \ -episode : genera il file di episodio per la compilazione separata\n\ \ \ \ -version : visualizza le informazioni sulla versione\n\ \ \ \ -fullversion : visualizza le informazioni sulla versione completa\n\ \ \ \ -help : visualizza questo messaggio sull'uso
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ja.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ja.properties
index 42dcb00216a..b8889bb6e22 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ja.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ja.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = \u4E88\u671F\u3057\u306A\u3044{0}\u304C\u884C{1}\u3001\u
BASEDIR_DOESNT_EXIST = \u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u304C\u5B58\u5728\u3057\u307E\u305B\u3093: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = schemagen\u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3"2.2.7-b63"
+FULLVERSION = schemagen\u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3"2.2.8-b01"
USAGE = \u4F7F\u7528\u65B9\u6CD5: schemagen [-options ...] \n\u30AA\u30D7\u30B7\u30E7\u30F3: \n\ \ \ \ -d : \u30D7\u30ED\u30BB\u30C3\u30B5\u304A\u3088\u3073javac\u304C\u751F\u6210\u3057\u305F\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u7F6E\u304F\u4F4D\u7F6E\u3092\u6307\u5B9A\u3057\u307E\u3059\n\ \ \ \ -cp : \u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u4F4D\u7F6E\u3092\u6307\u5B9A\u3057\u307E\u3059\n\ \ \ \ -classpath : \u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3059\u308B\u4F4D\u7F6E\u3092\u6307\u5B9A\u3057\u307E\u3059\n\ \ \ \ -encoding : \u6CE8\u91C8\u51E6\u7406/javac\u547C\u51FA\u3057\u306B\u4F7F\u7528\u3059\u308B\u30A8\u30F3\u30B3\u30FC\u30C7\u30A3\u30F3\u30B0\u3092\u6307\u5B9A\u3057\u307E\u3059\n\ \ \ \ -episode : \u30B3\u30F3\u30D1\u30A4\u30EB\u3054\u3068\u306B\u30A8\u30D4\u30BD\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u751F\u6210\u3057\u307E\u3059\n\ \ \ \ -version : \u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3057\u307E\u3059\n\ \ \ \ -fullversion : \u30D5\u30EB\u30FB\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u8868\u793A\u3057\u307E\u3059\n\ \ \ \ -help : \u3053\u306E\u4F7F\u7528\u4F8B\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u8868\u793A\u3057\u307E\u3059
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ko.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ko.properties
index 8bc7bf0b1c4..b89650bd0ff 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ko.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_ko.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = \uC608\uC0C1\uCE58 \uC54A\uC740 {0}\uC774(\uAC00) {1}\uD
BASEDIR_DOESNT_EXIST = \uC874\uC7AC\uD558\uC9C0 \uC54A\uB294 \uB514\uB809\uD1A0\uB9AC: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = schemagen \uC815\uC2DD \uBC84\uC804 "2.2.7-b63"
+FULLVERSION = schemagen \uC815\uC2DD \uBC84\uC804 "2.2.8-b01"
USAGE = \uC0AC\uC6A9\uBC95: schemagen [-options ...] \n\uC635\uC158: \n\ \ \ \ -d : \uD504\uB85C\uC138\uC11C \uBC0F javac\uC5D0\uC11C \uC0DD\uC131\uD55C \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uBC30\uCE58\uD560 \uC704\uCE58\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4.\n\ \ \ \ -cp : \uC0AC\uC6A9\uC790\uAC00 \uC9C0\uC815\uD55C \uD30C\uC77C\uC744 \uCC3E\uC744 \uC704\uCE58\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4.\n\ \ \ \ -classpath : \uC0AC\uC6A9\uC790\uAC00 \uC9C0\uC815\uD55C \uD30C\uC77C\uC744 \uCC3E\uC744 \uC704\uCE58\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4.\n\ \ \ \ -encoding : \uC8FC\uC11D \uCC98\uB9AC/javac \uD638\uCD9C\uC5D0 \uC0AC\uC6A9\uD560 \uC778\uCF54\uB529\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4. \n\ \ \ \ -episode : \uBCC4\uB3C4 \uCEF4\uD30C\uC77C\uC744 \uC704\uD574 episode \uD30C\uC77C\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n\ \ \ \ -version : \uBC84\uC804 \uC815\uBCF4\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n\ \ \ \ -fullversion : \uC815\uC2DD \uBC84\uC804 \uC815\uBCF4\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.\n\ \ \ \ -help : \uC774 \uC0AC\uC6A9\uBC95 \uBA54\uC2DC\uC9C0\uB97C \uD45C\uC2DC\uD569\uB2C8\uB2E4.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_pt_BR.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_pt_BR.properties
index e6339ca7ec2..fc9f8afbc11 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_pt_BR.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_pt_BR.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = {0} inesperado aparece na linha {1} coluna {2}
BASEDIR_DOESNT_EXIST = Diret\u00F3rio n\u00E3o existente: {0}
-VERSION = gera\u00E7\u00E3o do esquema 2.2.7-b63
+VERSION = gera\u00E7\u00E3o do esquema 2.2.8-b01
-FULLVERSION = vers\u00E3o completa da gera\u00E7\u00E3o do esquema "2.2.7-b63"
+FULLVERSION = vers\u00E3o completa da gera\u00E7\u00E3o do esquema "2.2.8-b01"
USAGE = Uso: gera\u00E7\u00E3o do esquema [-options ...] \nOp\u00E7\u00F5es: \n\\ \\ \\ \\ -d : especificar onde colocar o processador e os arquivos da classe gerados por javac\n\\ \\ \\ \\ -cp : especificar onde localizar arquivos especificados pelo usu\u00E1rio\n\\ \\ \\ \\ -classpath : especificar onde localizar os arquivos especificados pelo usu\u00E1rio\n\\ \\ \\ \\ -encoding : especificar codifica\u00E7\u00E3o a ser usada para processamento de anota\u00E7\u00E3o/chamada javac \n\\ \\ \\ \\ -episode : gerar arquivo do epis\u00F3dio para compila\u00E7\u00E3o separada\n\\ \\ \\ \\ -version : exibir informa\u00E7\u00F5es da vers\u00E3o\n\\ \\ \\ \\ -fullversion : exibir informa\u00E7\u00F5es da vers\u00E3o completa\n\\ \\ \\ \\ -help : exibir esta mensagem de uso
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_CN.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_CN.properties
index c059a4fd23a..4493b23dd18 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_CN.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_CN.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = \u5728\u7B2C {1} \u884C, \u7B2C {2} \u5217\u51FA\u73B0\u
BASEDIR_DOESNT_EXIST = \u4E0D\u5B58\u5728\u7684\u76EE\u5F55: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = schemagen \u5B8C\u6574\u7248\u672C "2.2.7-b63"
+FULLVERSION = schemagen \u5B8C\u6574\u7248\u672C "2.2.8-b01"
USAGE = \u7528\u6CD5: schemagen [-options ...] \n\u9009\u9879: \n\ \ \ \ -d : \u6307\u5B9A\u653E\u7F6E\u5904\u7406\u7A0B\u5E8F\u548C javac \u751F\u6210\u7684\u7C7B\u6587\u4EF6\u7684\u4F4D\u7F6E\n\ \ \ \ -cp : \u6307\u5B9A\u67E5\u627E\u7528\u6237\u6307\u5B9A\u6587\u4EF6\u7684\u4F4D\u7F6E\n\ \ \ \ -classpath : \u6307\u5B9A\u67E5\u627E\u7528\u6237\u6307\u5B9A\u6587\u4EF6\u7684\u4F4D\u7F6E\n\ \ \ \ -encoding : \u6307\u5B9A\u7528\u4E8E\u6CE8\u91CA\u5904\u7406/javac \u8C03\u7528\u7684\u7F16\u7801\n\ \ \ \ -episode : \u751F\u6210\u7247\u6BB5\u6587\u4EF6\u4EE5\u4F9B\u5355\u72EC\u7F16\u8BD1\n\ \ \ \ -version : \u663E\u793A\u7248\u672C\u4FE1\u606F\n\ \ \ \ -fullversion : \u663E\u793A\u5B8C\u6574\u7684\u7248\u672C\u4FE1\u606F\n\ \ \ \ -help : \u663E\u793A\u6B64\u7528\u6CD5\u6D88\u606F
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_TW.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_TW.properties
index 1e73e423250..45748f11a28 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_TW.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/MessageBundle_zh_TW.properties
@@ -27,8 +27,8 @@ UNEXPECTED_NGCC_TOKEN = \u672A\u9810\u671F\u7684 {0} \u986F\u793A\u65BC\u884C {1
BASEDIR_DOESNT_EXIST = \u4E0D\u5B58\u5728\u7684\u76EE\u9304: {0}
-VERSION = schemagen 2.2.7-b63
+VERSION = schemagen 2.2.8-b01
-FULLVERSION = schemagen \u5B8C\u6574\u7248\u672C "2.2.7-b63"
+FULLVERSION = schemagen \u5B8C\u6574\u7248\u672C "2.2.8-b01"
USAGE = \u7528\u6CD5: schemagen [-options ...] \n\u9078\u9805: \n\\ \\ \\ \\ -d : \u6307\u5B9A\u8655\u7406\u5668\u4EE5\u53CA javac \u7522\u751F\u7684\u985E\u5225\u6A94\u6848\u653E\u7F6E\u4F4D\u7F6E\n\\ \\ \\ \\ -cp : \u6307\u5B9A\u8981\u5C0B\u627E\u4F7F\u7528\u8005\u6307\u5B9A\u6A94\u6848\u7684\u4F4D\u7F6E\n\\ \\ \\ \\ -classpath : \u6307\u5B9A\u8981\u5C0B\u627E\u4F7F\u7528\u8005\u6307\u5B9A\u6A94\u6848\u7684\u4F4D\u7F6E\n\\ \\ \\ \\ -encoding : \u6307\u5B9A\u8981\u7528\u65BC\u8A3B\u89E3\u8655\u7406/javac \u547C\u53EB\u7684\u7DE8\u78BC \n\\ \\ \\ \\ -episode : \u7522\u751F\u7368\u7ACB\u7DE8\u8B6F\u7684\u4E8B\u4EF6 (episode) \u6A94\u6848\n\\ \\ \\ \\ -version : \u986F\u793A\u7248\u672C\u8CC7\u8A0A\n\\ \\ \\ \\ -fullversion : \u986F\u793A\u5B8C\u6574\u7248\u672C\u8CC7\u8A0A\n\\ \\ \\ \\ -help : \u986F\u793A\u6B64\u7528\u6CD5\u8A0A\u606F
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Classes.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Classes.java
index b95cf71ad2b..60968c00c56 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Classes.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Classes.java
@@ -78,11 +78,6 @@ public class Classes extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 0:
- {
- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- break;
case 4:
{
$_ngcc_current_state = 3;
@@ -112,6 +107,11 @@ public class Classes extends NGCCHandler {
}
}
break;
+ case 0:
+ {
+ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ break;
case 12:
{
if(($__uri.equals("") && $__local.equals("classes"))) {
@@ -137,33 +137,6 @@ public class Classes extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 8:
- {
- if(($__uri.equals("") && $__local.equals("includes"))) {
- $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
- $_ngcc_current_state = 2;
- }
- else {
- unexpectedLeaveElement($__qname);
- }
- }
- break;
- case 1:
- {
- if(($__uri.equals("") && $__local.equals("classes"))) {
- $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
- $_ngcc_current_state = 0;
- }
- else {
- unexpectedLeaveElement($__qname);
- }
- }
- break;
- case 0:
- {
- revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
case 4:
{
$_ngcc_current_state = 3;
@@ -181,12 +154,39 @@ public class Classes extends NGCCHandler {
}
}
break;
+ case 1:
+ {
+ if(($__uri.equals("") && $__local.equals("classes"))) {
+ $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
+ $_ngcc_current_state = 0;
+ }
+ else {
+ unexpectedLeaveElement($__qname);
+ }
+ }
+ break;
+ case 8:
+ {
+ if(($__uri.equals("") && $__local.equals("includes"))) {
+ $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
+ $_ngcc_current_state = 2;
+ }
+ else {
+ unexpectedLeaveElement($__qname);
+ }
+ }
+ break;
case 2:
{
$_ngcc_current_state = 1;
$runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
}
break;
+ case 0:
+ {
+ revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
default:
{
unexpectedLeaveElement($__qname);
@@ -201,11 +201,6 @@ public class Classes extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 0:
- {
- revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
case 4:
{
$_ngcc_current_state = 3;
@@ -218,6 +213,11 @@ public class Classes extends NGCCHandler {
$runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname);
}
break;
+ case 0:
+ {
+ revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
default:
{
unexpectedEnterAttribute($__qname);
@@ -232,11 +232,6 @@ public class Classes extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 0:
- {
- revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
case 4:
{
$_ngcc_current_state = 3;
@@ -249,6 +244,11 @@ public class Classes extends NGCCHandler {
$runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname);
}
break;
+ case 0:
+ {
+ revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
default:
{
unexpectedLeaveAttribute($__qname);
@@ -260,25 +260,6 @@ public class Classes extends NGCCHandler {
public void text(String $value) throws SAXException {
int $ai;
switch($_ngcc_current_state) {
- case 9:
- {
- include_content = $value;
- $_ngcc_current_state = 8;
- action2();
- }
- break;
- case 8:
- {
- include_content = $value;
- $_ngcc_current_state = 8;
- action2();
- }
- break;
- case 0:
- {
- revertToParentFromText(this, super._cookie, $value);
- }
- break;
case 4:
{
exclude_content = $value;
@@ -293,6 +274,20 @@ public class Classes extends NGCCHandler {
action0();
}
break;
+ case 9:
+ {
+ include_content = $value;
+ $_ngcc_current_state = 8;
+ action2();
+ }
+ break;
+ case 10:
+ {
+ __text = $value;
+ $_ngcc_current_state = 9;
+ action3();
+ }
+ break;
case 6:
{
__text = $value;
@@ -300,17 +295,22 @@ public class Classes extends NGCCHandler {
action1();
}
break;
+ case 8:
+ {
+ include_content = $value;
+ $_ngcc_current_state = 8;
+ action2();
+ }
+ break;
case 2:
{
$_ngcc_current_state = 1;
$runtime.sendText(super._cookie, $value);
}
break;
- case 10:
+ case 0:
{
- __text = $value;
- $_ngcc_current_state = 9;
- action3();
+ revertToParentFromText(this, super._cookie, $value);
}
break;
}
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Config.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Config.java
index 7777f955275..f806a817416 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Config.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Config.java
@@ -74,31 +74,16 @@ public class Config extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 1:
+ case 2:
{
if(($__uri.equals("") && $__local.equals("schema"))) {
- NGCCHandler h = new Schema(this, super._source, $runtime, 31, baseDir);
+ NGCCHandler h = new Schema(this, super._source, $runtime, 16, baseDir);
spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs);
}
else {
- unexpectedEnterElement($__qname);
- }
- }
- break;
- case 0:
- {
- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- break;
- case 7:
- {
- if(($ai = $runtime.getAttributeIndex("","baseDir"))>=0) {
- $runtime.consumeAttribute($ai);
+ $_ngcc_current_state = 1;
$runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
}
- else {
- unexpectedEnterElement($__qname);
- }
}
break;
case 8:
@@ -112,22 +97,10 @@ public class Config extends NGCCHandler {
}
}
break;
- case 2:
- {
- if(($__uri.equals("") && $__local.equals("schema"))) {
- NGCCHandler h = new Schema(this, super._source, $runtime, 32, baseDir);
- spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs);
- }
- else {
- $_ngcc_current_state = 1;
- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- }
- break;
case 4:
{
if(($__uri.equals("") && $__local.equals("classes"))) {
- NGCCHandler h = new Classes(this, super._source, $runtime, 34);
+ NGCCHandler h = new Classes(this, super._source, $runtime, 18);
spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs);
}
else {
@@ -135,6 +108,33 @@ public class Config extends NGCCHandler {
}
}
break;
+ case 0:
+ {
+ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ break;
+ case 1:
+ {
+ if(($__uri.equals("") && $__local.equals("schema"))) {
+ NGCCHandler h = new Schema(this, super._source, $runtime, 15, baseDir);
+ spawnChildFromEnterElement(h, $__uri, $__local, $__qname, $attrs);
+ }
+ else {
+ unexpectedEnterElement($__qname);
+ }
+ }
+ break;
+ case 7:
+ {
+ if(($ai = $runtime.getAttributeIndex("","baseDir"))>=0) {
+ $runtime.consumeAttribute($ai);
+ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ else {
+ unexpectedEnterElement($__qname);
+ }
+ }
+ break;
default:
{
unexpectedEnterElement($__qname);
@@ -149,6 +149,17 @@ public class Config extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
+ case 2:
+ {
+ $_ngcc_current_state = 1;
+ $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
+ case 0:
+ {
+ revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
case 1:
{
if(($__uri.equals("") && $__local.equals("config"))) {
@@ -160,11 +171,6 @@ public class Config extends NGCCHandler {
}
}
break;
- case 0:
- {
- revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
case 7:
{
if(($ai = $runtime.getAttributeIndex("","baseDir"))>=0) {
@@ -176,12 +182,6 @@ public class Config extends NGCCHandler {
}
}
break;
- case 2:
- {
- $_ngcc_current_state = 1;
- $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
- }
- break;
default:
{
unexpectedLeaveElement($__qname);
@@ -196,6 +196,12 @@ public class Config extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
+ case 2:
+ {
+ $_ngcc_current_state = 1;
+ $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
case 0:
{
revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname);
@@ -211,12 +217,6 @@ public class Config extends NGCCHandler {
}
}
break;
- case 2:
- {
- $_ngcc_current_state = 1;
- $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname);
- }
- break;
default:
{
unexpectedEnterAttribute($__qname);
@@ -231,11 +231,6 @@ public class Config extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 0:
- {
- revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
case 2:
{
$_ngcc_current_state = 1;
@@ -252,6 +247,11 @@ public class Config extends NGCCHandler {
}
}
break;
+ case 0:
+ {
+ revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
default:
{
unexpectedLeaveAttribute($__qname);
@@ -263,9 +263,10 @@ public class Config extends NGCCHandler {
public void text(String $value) throws SAXException {
int $ai;
switch($_ngcc_current_state) {
- case 0:
+ case 2:
{
- revertToParentFromText(this, super._cookie, $value);
+ $_ngcc_current_state = 1;
+ $runtime.sendText(super._cookie, $value);
}
break;
case 6:
@@ -275,6 +276,11 @@ public class Config extends NGCCHandler {
action1();
}
break;
+ case 0:
+ {
+ revertToParentFromText(this, super._cookie, $value);
+ }
+ break;
case 7:
{
if(($ai = $runtime.getAttributeIndex("","baseDir"))>=0) {
@@ -283,31 +289,25 @@ public class Config extends NGCCHandler {
}
}
break;
- case 2:
- {
- $_ngcc_current_state = 1;
- $runtime.sendText(super._cookie, $value);
- }
- break;
}
}
public void onChildCompleted(Object result, int cookie, boolean needAttCheck)throws SAXException {
switch(cookie) {
- case 31:
+ case 16:
{
this._schema = ((Schema)result);
action0();
$_ngcc_current_state = 1;
}
break;
- case 34:
+ case 18:
{
this.classes = ((Classes)result);
$_ngcc_current_state = 2;
}
break;
- case 32:
+ case 15:
{
this._schema = ((Schema)result);
action0();
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Schema.java b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Schema.java
index 489de1c9ffc..18de25f4a88 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Schema.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/jxc/gen/config/Schema.java
@@ -67,6 +67,23 @@ public class Schema extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
+ case 0:
+ {
+ revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ break;
+ case 6:
+ {
+ if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) {
+ $runtime.consumeAttribute($ai);
+ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ else {
+ $_ngcc_current_state = 2;
+ $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
+ }
+ }
+ break;
case 2:
{
if(($ai = $runtime.getAttributeIndex("","location"))>=0) {
@@ -90,23 +107,6 @@ public class Schema extends NGCCHandler {
}
}
break;
- case 0:
- {
- revertToParentFromEnterElement(this, super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- break;
- case 6:
- {
- if(($ai = $runtime.getAttributeIndex("","namespace"))>=0) {
- $runtime.consumeAttribute($ai);
- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- else {
- $_ngcc_current_state = 2;
- $runtime.sendEnterElement(super._cookie, $__uri, $__local, $__qname, $attrs);
- }
- }
- break;
default:
{
unexpectedEnterElement($__qname);
@@ -121,29 +121,6 @@ public class Schema extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 1:
- {
- if(($__uri.equals("") && $__local.equals("schema"))) {
- $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
- $_ngcc_current_state = 0;
- }
- else {
- unexpectedLeaveElement($__qname);
- }
- }
- break;
- case 2:
- {
- if(($ai = $runtime.getAttributeIndex("","location"))>=0) {
- $runtime.consumeAttribute($ai);
- $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
- }
- else {
- $_ngcc_current_state = 1;
- $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
- }
- }
- break;
case 0:
{
revertToParentFromLeaveElement(this, super._cookie, $__uri, $__local, $__qname);
@@ -161,6 +138,29 @@ public class Schema extends NGCCHandler {
}
}
break;
+ case 2:
+ {
+ if(($ai = $runtime.getAttributeIndex("","location"))>=0) {
+ $runtime.consumeAttribute($ai);
+ $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
+ }
+ else {
+ $_ngcc_current_state = 1;
+ $runtime.sendLeaveElement(super._cookie, $__uri, $__local, $__qname);
+ }
+ }
+ break;
+ case 1:
+ {
+ if(($__uri.equals("") && $__local.equals("schema"))) {
+ $runtime.onLeaveElementConsumed($__uri, $__local, $__qname);
+ $_ngcc_current_state = 0;
+ }
+ else {
+ unexpectedLeaveElement($__qname);
+ }
+ }
+ break;
default:
{
unexpectedLeaveElement($__qname);
@@ -175,17 +175,6 @@ public class Schema extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 2:
- {
- if(($__uri.equals("") && $__local.equals("location"))) {
- $_ngcc_current_state = 4;
- }
- else {
- $_ngcc_current_state = 1;
- $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname);
- }
- }
- break;
case 0:
{
revertToParentFromEnterAttribute(this, super._cookie, $__uri, $__local, $__qname);
@@ -202,6 +191,17 @@ public class Schema extends NGCCHandler {
}
}
break;
+ case 2:
+ {
+ if(($__uri.equals("") && $__local.equals("location"))) {
+ $_ngcc_current_state = 4;
+ }
+ else {
+ $_ngcc_current_state = 1;
+ $runtime.sendEnterAttribute(super._cookie, $__uri, $__local, $__qname);
+ }
+ }
+ break;
default:
{
unexpectedEnterAttribute($__qname);
@@ -216,10 +216,9 @@ public class Schema extends NGCCHandler {
$localName = $__local;
$qname = $__qname;
switch($_ngcc_current_state) {
- case 2:
+ case 0:
{
- $_ngcc_current_state = 1;
- $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname);
+ revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
}
break;
case 7:
@@ -232,6 +231,12 @@ public class Schema extends NGCCHandler {
}
}
break;
+ case 6:
+ {
+ $_ngcc_current_state = 2;
+ $runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname);
+ }
+ break;
case 3:
{
if(($__uri.equals("") && $__local.equals("location"))) {
@@ -242,14 +247,9 @@ public class Schema extends NGCCHandler {
}
}
break;
- case 0:
+ case 2:
{
- revertToParentFromLeaveAttribute(this, super._cookie, $__uri, $__local, $__qname);
- }
- break;
- case 6:
- {
- $_ngcc_current_state = 2;
+ $_ngcc_current_state = 1;
$runtime.sendLeaveAttribute(super._cookie, $__uri, $__local, $__qname);
}
break;
@@ -264,25 +264,6 @@ public class Schema extends NGCCHandler {
public void text(String $value) throws SAXException {
int $ai;
switch($_ngcc_current_state) {
- case 2:
- {
- if(($ai = $runtime.getAttributeIndex("","location"))>=0) {
- $runtime.consumeAttribute($ai);
- $runtime.sendText(super._cookie, $value);
- }
- else {
- $_ngcc_current_state = 1;
- $runtime.sendText(super._cookie, $value);
- }
- }
- break;
- case 4:
- {
- loc = $value;
- $_ngcc_current_state = 3;
- action0();
- }
- break;
case 8:
{
namespace = $value;
@@ -306,6 +287,25 @@ public class Schema extends NGCCHandler {
}
}
break;
+ case 4:
+ {
+ loc = $value;
+ $_ngcc_current_state = 3;
+ action0();
+ }
+ break;
+ case 2:
+ {
+ if(($ai = $runtime.getAttributeIndex("","location"))>=0) {
+ $runtime.consumeAttribute($ai);
+ $runtime.sendText(super._cookie, $value);
+ }
+ else {
+ $_ngcc_current_state = 1;
+ $runtime.sendText(super._cookie, $value);
+ }
+ }
+ break;
}
}
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/version.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/version.properties
index 0917dd67ad6..5d7ed24b883 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/version.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/ws/version.properties
@@ -23,7 +23,7 @@
# questions.
#
-build-id=2.2.9-b13941
-build-version=JAX-WS RI 2.2.9-b13941
+build-id=2.2.9-b14027
+build-version=JAX-WS RI 2.2.9-b14027
major-version=2.2.9
-svn-revision=unknown
+svn-revision=14027
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle.properties
index 73dc95b47ad..4e64ca0c717 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle.properties
@@ -171,23 +171,23 @@ Driver.CompilingSchema = \
Driver.FailedToGenerateCode = \
Failed to produce code.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
Driver.FilePrologComment = \
- This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7-b63 \n\
+ This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b01 \n\
See http://java.sun.com/xml/jaxb \n\
Any modifications to this file will be lost upon recompilation of the source schema. \n\
Generated on: {0} \n
Driver.Version = \
- xjc 2.2.7-b63
+ xjc 2.2.8-b01
Driver.FullVersion = \
- xjc full version "2.2.7-b63-b19"
+ xjc full version "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_de.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_de.properties
index f83aa74cd97..3fee895ed99 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_de.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_de.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = Ein Schema wird kompiliert ...
Driver.FailedToGenerateCode = Code konnte nicht erzeugt werden.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7-b63 generiert \nSiehe http://java.sun.com/xml/jaxb \n\u00c4nderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. \nGeneriert: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b01 generiert \nSiehe http://java.sun.com/xml/jaxb \n\u00c4nderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. \nGeneriert: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = xjc vollst\u00e4ndige Version "2.2.7-b63-b19"
+Driver.FullVersion = xjc vollst\u00e4ndige Version "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_es.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_es.properties
index 104d93590a9..ee3e09df36a 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_es.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_es.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = Compilando un esquema...
Driver.FailedToGenerateCode = Fallo al producir c\u00f3digo.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = Este archivo ha sido generado por la arquitectura JavaTM para la implantaci\u00f3n de la referencia de enlace (JAXB) XML v2.2.7-b63 \nVisite http://java.sun.com/xml/jaxb \nTodas las modificaciones realizadas en este archivo se perder\u00e1n si se vuelve a compilar el esquema de origen. \nGenerado el: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = Este archivo ha sido generado por la arquitectura JavaTM para la implantaci\u00f3n de la referencia de enlace (JAXB) XML v2.2.8-b01 \nVisite http://java.sun.com/xml/jaxb \nTodas las modificaciones realizadas en este archivo se perder\u00e1n si se vuelve a compilar el esquema de origen. \nGenerado el: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = versi\u00f3n completa de xjc "2.2.7-b63-b19"
+Driver.FullVersion = versi\u00f3n completa de xjc "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_fr.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_fr.properties
index c992d94b4ea..d5a8fbbacbf 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_fr.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_fr.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = compilation d'un sch\u00e9ma...
Driver.FailedToGenerateCode = Echec de la production du code.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = Ce fichier a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 par l''impl\u00e9mentation de r\u00e9f\u00e9rence JavaTM Architecture for XML Binding (JAXB), v2.2.7-b63 \nVoir http://java.sun.com/xml/jaxb \nToute modification apport\u00e9e \u00e0 ce fichier sera perdue lors de la recompilation du sch\u00e9ma source. \nG\u00e9n\u00e9r\u00e9 le : {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = Ce fichier a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 par l''impl\u00e9mentation de r\u00e9f\u00e9rence JavaTM Architecture for XML Binding (JAXB), v2.2.8-b01 \nVoir http://java.sun.com/xml/jaxb \nToute modification apport\u00e9e \u00e0 ce fichier sera perdue lors de la recompilation du sch\u00e9ma source. \nG\u00e9n\u00e9r\u00e9 le : {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = version compl\u00e8te xjc "2.2.7-b63-b19"
+Driver.FullVersion = version compl\u00e8te xjc "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_it.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_it.properties
index 1edbcb844f5..33441891015 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_it.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_it.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = compilazione di uno schema in corso...
Driver.FailedToGenerateCode = Produzione del codice non riuscita.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = Questo file \u00e8 stato generato dall''architettura JavaTM per XML Binding (JAXB) Reference Implementation, v2.2.7-b63 \nVedere http://java.sun.com/xml/jaxb \nQualsiasi modifica a questo file andr\u00e0 persa durante la ricompilazione dello schema di origine. \nGenerato il: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = Questo file \u00e8 stato generato dall''architettura JavaTM per XML Binding (JAXB) Reference Implementation, v2.2.8-b01 \nVedere http://java.sun.com/xml/jaxb \nQualsiasi modifica a questo file andr\u00e0 persa durante la ricompilazione dello schema di origine. \nGenerato il: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = versione completa xjc "2.2.7-b63-b19"
+Driver.FullVersion = versione completa xjc "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ja.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ja.properties
index bf99b6b05f6..edd5c648e7c 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ja.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ja.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = \u30b9\u30ad\u30fc\u30de\u306e\u30b3\u30f3\u30d1\u30a4\
Driver.FailedToGenerateCode = \u30b3\u30fc\u30c9\u306e\u751f\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = \u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u3001JavaTM Architecture for XML Binding(JAXB) Reference Implementation\u3001v2.2.7-b63\u306b\u3088\u3063\u3066\u751f\u6210\u3055\u308c\u307e\u3057\u305f \nhttp://java.sun.com/xml/jaxb \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044 \n\u30bd\u30fc\u30b9\u30fb\u30b9\u30ad\u30fc\u30de\u306e\u518d\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u5909\u66f4\u306f\u5931\u308f\u308c\u307e\u3059\u3002 \n\u751f\u6210\u65e5: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = \u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u3001JavaTM Architecture for XML Binding(JAXB) Reference Implementation\u3001v2.2.8-b01\u306b\u3088\u3063\u3066\u751f\u6210\u3055\u308c\u307e\u3057\u305f \nhttp://java.sun.com/xml/jaxb \u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044 \n\u30bd\u30fc\u30b9\u30fb\u30b9\u30ad\u30fc\u30de\u306e\u518d\u30b3\u30f3\u30d1\u30a4\u30eb\u6642\u306b\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306e\u5909\u66f4\u306f\u5931\u308f\u308c\u307e\u3059\u3002 \n\u751f\u6210\u65e5: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = xjc\u30d5\u30eb\u30fb\u30d0\u30fc\u30b8\u30e7\u30f3"2.2.7-b63-b19"
+Driver.FullVersion = xjc\u30d5\u30eb\u30fb\u30d0\u30fc\u30b8\u30e7\u30f3"2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ko.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ko.properties
index b0ed1684017..d493f5bd054 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ko.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_ko.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = \uc2a4\ud0a4\ub9c8\ub97c \ucef4\ud30c\uc77c\ud558\ub294
Driver.FailedToGenerateCode = \ucf54\ub4dc \uc0dd\uc131\uc744 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = \uc774 \ud30c\uc77c\uc740 JAXB(JavaTM Architecture for XML Binding) \ucc38\uc870 \uad6c\ud604 2.2.7-b63 \ubc84\uc804\uc744 \ud1b5\ud574 \uc0dd\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \nhttp://java.sun.com/xml/jaxb \ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. \n\uc774 \ud30c\uc77c\uc744 \uc218\uc815\ud558\uba74 \uc18c\uc2a4 \uc2a4\ud0a4\ub9c8\ub97c \uc7ac\ucef4\ud30c\uc77c\ud560 \ub54c \uc218\uc815 \uc0ac\ud56d\uc774 \uc190\uc2e4\ub429\ub2c8\ub2e4. \n\uc0dd\uc131 \ub0a0\uc9dc: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = \uc774 \ud30c\uc77c\uc740 JAXB(JavaTM Architecture for XML Binding) \ucc38\uc870 \uad6c\ud604 2.2.8-b01 \ubc84\uc804\uc744 \ud1b5\ud574 \uc0dd\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \nhttp://java.sun.com/xml/jaxb \ub97c \ucc38\uc870\ud558\uc2ed\uc2dc\uc624. \n\uc774 \ud30c\uc77c\uc744 \uc218\uc815\ud558\uba74 \uc18c\uc2a4 \uc2a4\ud0a4\ub9c8\ub97c \uc7ac\ucef4\ud30c\uc77c\ud560 \ub54c \uc218\uc815 \uc0ac\ud56d\uc774 \uc190\uc2e4\ub429\ub2c8\ub2e4. \n\uc0dd\uc131 \ub0a0\uc9dc: {0} \n
-Driver.Version = XJC 2.2.7-b63
+Driver.Version = XJC 2.2.8-b01
-Driver.FullVersion = XJC \uc815\uc2dd \ubc84\uc804 "2.2.7-b63-b19"
+Driver.FullVersion = XJC \uc815\uc2dd \ubc84\uc804 "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_pt_BR.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_pt_BR.properties
index 54a4a21a496..3ac7a0bf2c3 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_pt_BR.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_pt_BR.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = compilando um esquema...
Driver.FailedToGenerateCode = Falha ao produzir o c\u00f3digo.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = Este arquivo foi gerado pela Arquitetura JavaTM para Implementa\u00e7\u00e3o de Refer\u00eancia (JAXB) de Bind XML, v2.2.7-b63 \nConsulte http://java.sun.com/xml/jaxb \nTodas as modifica\u00e7\u00f5es neste arquivo ser\u00e3o perdidas ap\u00f3s a recompila\u00e7\u00e3o do esquema de origem. \nGerado em: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = Este arquivo foi gerado pela Arquitetura JavaTM para Implementa\u00e7\u00e3o de Refer\u00eancia (JAXB) de Bind XML, v2.2.8-b01 \nConsulte http://java.sun.com/xml/jaxb \nTodas as modifica\u00e7\u00f5es neste arquivo ser\u00e3o perdidas ap\u00f3s a recompila\u00e7\u00e3o do esquema de origem. \nGerado em: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = vers\u00e3o completa de xjc "2.2.7-b63-b19"
+Driver.FullVersion = vers\u00e3o completa de xjc "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_CN.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_CN.properties
index d9636417969..610bb1e3cc7 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_CN.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_CN.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = \u6b63\u5728\u7f16\u8bd1\u6a21\u5f0f...
Driver.FailedToGenerateCode = \u65e0\u6cd5\u751f\u6210\u4ee3\u7801\u3002
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = \u6b64\u6587\u4ef6\u662f\u7531 JavaTM Architecture for XML Binding (JAXB) \u5f15\u7528\u5b9e\u73b0 v2.2.7-b63 \u751f\u6210\u7684\n\u8bf7\u8bbf\u95ee http://java.sun.com/xml/jaxb \n\u5728\u91cd\u65b0\u7f16\u8bd1\u6e90\u6a21\u5f0f\u65f6, \u5bf9\u6b64\u6587\u4ef6\u7684\u6240\u6709\u4fee\u6539\u90fd\u5c06\u4e22\u5931\u3002\n\u751f\u6210\u65f6\u95f4: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = \u6b64\u6587\u4ef6\u662f\u7531 JavaTM Architecture for XML Binding (JAXB) \u5f15\u7528\u5b9e\u73b0 v2.2.8-b01 \u751f\u6210\u7684\n\u8bf7\u8bbf\u95ee http://java.sun.com/xml/jaxb \n\u5728\u91cd\u65b0\u7f16\u8bd1\u6e90\u6a21\u5f0f\u65f6, \u5bf9\u6b64\u6587\u4ef6\u7684\u6240\u6709\u4fee\u6539\u90fd\u5c06\u4e22\u5931\u3002\n\u751f\u6210\u65f6\u95f4: {0} \n
-Driver.Version = xjc 2.2.7-b63
+Driver.Version = xjc 2.2.8-b01
-Driver.FullVersion = xjc \u5b8c\u6574\u7248\u672c "2.2.7-b63-b19"
+Driver.FullVersion = xjc \u5b8c\u6574\u7248\u672c "2.2.8-b01-b28"
-Driver.BuildID = 2.2.7-b63
+Driver.BuildID = 2.2.8-b01
# for JDK integration - include version in source zip
-jaxb.jdk.version=2.2.7-b63
+jaxb.jdk.version=2.2.8-b01
# see java.text.SimpleDateFormat for format syntax
# DO NOT LOCALIZE, Format should not be changed, English locale is used to transform this string into a real date.
diff --git a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_TW.properties b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_TW.properties
index e32b9cea11d..3ed7786c9ec 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_TW.properties
+++ b/jaxws/src/share/jaxws_classes/com/sun/tools/internal/xjc/MessageBundle_zh_TW.properties
@@ -96,17 +96,17 @@ Driver.CompilingSchema = \u6b63\u5728\u7de8\u8b6f\u7db1\u8981...
Driver.FailedToGenerateCode = \u7121\u6cd5\u7522\u751f\u7a0b\u5f0f\u78bc.
-# DO NOT localize the 2.2.7-b63 string - it is a token for an ant
-Driver.FilePrologComment = \u6b64\u6a94\u6848\u662f\u7531 JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7-b63 \u6240\u7522\u751f \n\u8acb\u53c3\u95b1 http://java.sun.com/xml/jaxb \n\u4e00\u65e6\u91cd\u65b0\u7de8\u8b6f\u4f86\u6e90\u7db1\u8981, \u5c0d\u6b64\u6a94\u6848\u6240\u505a\u7684\u4efb\u4f55\u4fee\u6539\u90fd\u5c07\u6703\u907a\u5931. \n\u7522\u751f\u6642\u9593: {0} \n
+# DO NOT localize the 2.2.8-b01 string - it is a token for an ant
+Driver.FilePrologComment = \u6b64\u6a94\u6848\u662f\u7531 JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b01 \u6240\u7522\u751f \n\u8acb\u53c3\u95b1