提交 ddc87f95 编写于 作者: A andrew

Merge

...@@ -1289,6 +1289,11 @@ ce42ae95d4d671f74246091f89bd101d5bcbfd91 jdk8u242-b01 ...@@ -1289,6 +1289,11 @@ ce42ae95d4d671f74246091f89bd101d5bcbfd91 jdk8u242-b01
775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02 775e2bf92114e41365cc6baf1480c818454256a4 jdk8u242-b02
ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03 ee19c358e3b8deeda2f64d660a0870df7b1abd49 jdk8u242-b03
20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04 20258ba5a788da55485c0648bcc073f8ad2c26ef jdk8u242-b04
2c1e9fab6964647f4eeffe55fe5592da6399a3ce jdk8u242-b05
81ddc1072b923330f84c0ace3124226f63877582 jdk8u242-b06
8b80409d5840142a27e274d33948f483a6406a50 jdk8u242-b07
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-b08
7c9f6b5f8d119dc1ba3c5536595ce3ae7414599d jdk8u242-ga
8c0733543544bbcd32c4404630d764d280299056 jdk8u252-b00 8c0733543544bbcd32c4404630d764d280299056 jdk8u252-b00
a67e9c6edcdd73cb860a16990f0905e102c282d7 jdk8u252-b01 a67e9c6edcdd73cb860a16990f0905e102c282d7 jdk8u252-b01
5bd3b8c0555292a967ea3b4c39a220d0c2cf40ad jdk8u252-b02 5bd3b8c0555292a967ea3b4c39a220d0c2cf40ad jdk8u252-b02
...@@ -1334,11 +1334,13 @@ SUCH DAMAGE. ...@@ -1334,11 +1334,13 @@ SUCH DAMAGE.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
%% This notice is provided with respect to Joni v1.1.9, which may be %% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8. included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE --- --- begin of LICENSE ---
Copyright (c) 2017 JRuby Team
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
......
...@@ -286,35 +286,35 @@ void VM_Version::initialize() { ...@@ -286,35 +286,35 @@ void VM_Version::initialize() {
// SPARC T4 and above should have support for AES instructions // SPARC T4 and above should have support for AES instructions
if (has_aes()) { if (has_aes()) {
if (UseVIS > 2) { // AES intrinsics use MOVxTOd/MOVdTOx which are VIS3
if (FLAG_IS_DEFAULT(UseAES)) { if (FLAG_IS_DEFAULT(UseAES)) {
FLAG_SET_DEFAULT(UseAES, true); FLAG_SET_DEFAULT(UseAES, true);
} }
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) { if (!UseAES) {
FLAG_SET_DEFAULT(UseAESIntrinsics, true); if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
} }
// we disable both the AES flags if either of them is disabled on the command line
if (!UseAES || !UseAESIntrinsics) {
FLAG_SET_DEFAULT(UseAES, false);
FLAG_SET_DEFAULT(UseAESIntrinsics, false); FLAG_SET_DEFAULT(UseAESIntrinsics, false);
} else {
// The AES intrinsic stubs require AES instruction support (of course)
// but also require VIS3 mode or higher for instructions it use.
if (UseVIS > 2) {
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
FLAG_SET_DEFAULT(UseAESIntrinsics, true);
} }
} else { } else {
if (UseAES || UseAESIntrinsics) { if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("SPARC AES intrinsics require VIS3 instruction support. Intrinsics will be disabled."); warning("SPARC AES intrinsics require VIS3 instructions. Intrinsics will be disabled.");
if (UseAES) {
FLAG_SET_DEFAULT(UseAES, false);
} }
if (UseAESIntrinsics) {
FLAG_SET_DEFAULT(UseAESIntrinsics, false); FLAG_SET_DEFAULT(UseAESIntrinsics, false);
} }
} }
}
} else if (UseAES || UseAESIntrinsics) { } else if (UseAES || UseAESIntrinsics) {
if (UseAES && !FLAG_IS_DEFAULT(UseAES)) {
warning("AES instructions are not available on this CPU"); warning("AES instructions are not available on this CPU");
if (UseAES) {
FLAG_SET_DEFAULT(UseAES, false); FLAG_SET_DEFAULT(UseAES, false);
} }
if (UseAESIntrinsics) { if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("AES intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseAESIntrinsics, false); FLAG_SET_DEFAULT(UseAESIntrinsics, false);
} }
} }
......
...@@ -553,13 +553,37 @@ void VM_Version::get_processor_features() { ...@@ -553,13 +553,37 @@ void VM_Version::get_processor_features() {
// Use AES instructions if available. // Use AES instructions if available.
if (supports_aes()) { if (supports_aes()) {
if (FLAG_IS_DEFAULT(UseAES)) { if (FLAG_IS_DEFAULT(UseAES)) {
UseAES = true; FLAG_SET_DEFAULT(UseAES, true);
} }
} else if (UseAES) { if (!UseAES) {
if (!FLAG_IS_DEFAULT(UseAES)) if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("AES intrinsics require UseAES flag to be enabled. Intrinsics will be disabled.");
}
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
} else {
if (UseSSE > 2) {
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
FLAG_SET_DEFAULT(UseAESIntrinsics, true);
}
} else {
// The AES intrinsic stubs require AES instruction support (of course)
// but also require sse3 mode or higher for instructions it use.
if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("X86 AES intrinsics require SSE3 instructions or higher. Intrinsics will be disabled.");
}
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
}
} else if (UseAES || UseAESIntrinsics) {
if (UseAES && !FLAG_IS_DEFAULT(UseAES)) {
warning("AES instructions are not available on this CPU"); warning("AES instructions are not available on this CPU");
FLAG_SET_DEFAULT(UseAES, false); FLAG_SET_DEFAULT(UseAES, false);
} }
if (UseAESIntrinsics && !FLAG_IS_DEFAULT(UseAESIntrinsics)) {
warning("AES intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
}
// Use CLMUL instructions if available. // Use CLMUL instructions if available.
if (supports_clmul()) { if (supports_clmul()) {
...@@ -582,18 +606,6 @@ void VM_Version::get_processor_features() { ...@@ -582,18 +606,6 @@ void VM_Version::get_processor_features() {
FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); FLAG_SET_DEFAULT(UseCRC32Intrinsics, false);
} }
// The AES intrinsic stubs require AES instruction support (of course)
// but also require sse3 mode for instructions it use.
if (UseAES && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
UseAESIntrinsics = true;
}
} else if (UseAESIntrinsics) {
if (!FLAG_IS_DEFAULT(UseAESIntrinsics))
warning("AES intrinsics are not available on this CPU");
FLAG_SET_DEFAULT(UseAESIntrinsics, false);
}
// GHASH/GCM intrinsics // GHASH/GCM intrinsics
if (UseCLMUL && (UseSSE > 2)) { if (UseCLMUL && (UseSSE > 2)) {
if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) { if (FLAG_IS_DEFAULT(UseGHASHIntrinsics)) {
......
...@@ -161,6 +161,8 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, ...@@ -161,6 +161,8 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
} }
_dictionary->set_par_lock(&_parDictionaryAllocLock); _dictionary->set_par_lock(&_parDictionaryAllocLock);
} }
_used_stable = 0;
} }
// Like CompactibleSpace forward() but always calls cross_threshold() to // Like CompactibleSpace forward() but always calls cross_threshold() to
...@@ -377,6 +379,14 @@ size_t CompactibleFreeListSpace::used() const { ...@@ -377,6 +379,14 @@ size_t CompactibleFreeListSpace::used() const {
return capacity() - free(); return capacity() - free();
} }
size_t CompactibleFreeListSpace::used_stable() const {
return _used_stable;
}
void CompactibleFreeListSpace::recalculate_used_stable() {
_used_stable = used();
}
size_t CompactibleFreeListSpace::free() const { size_t CompactibleFreeListSpace::free() const {
// "MT-safe, but not MT-precise"(TM), if you will: i.e. // "MT-safe, but not MT-precise"(TM), if you will: i.e.
// if you do this while the structures are in flux you // if you do this while the structures are in flux you
...@@ -1218,6 +1228,13 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) { ...@@ -1218,6 +1228,13 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) {
debug_only(fc->mangleAllocated(size)); debug_only(fc->mangleAllocated(size));
} }
// During GC we do not need to recalculate the stable used value for
// every allocation in old gen. It is done once at the end of GC instead
// for performance reasons.
if (!Universe::heap()->is_gc_active()) {
recalculate_used_stable();
}
return res; return res;
} }
......
...@@ -148,6 +148,9 @@ class CompactibleFreeListSpace: public CompactibleSpace { ...@@ -148,6 +148,9 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Used to keep track of limit of sweep for the space // Used to keep track of limit of sweep for the space
HeapWord* _sweep_limit; HeapWord* _sweep_limit;
// Stable value of used().
size_t _used_stable;
// Support for compacting cms // Support for compacting cms
HeapWord* cross_threshold(HeapWord* start, HeapWord* end); HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top); HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
...@@ -343,6 +346,17 @@ class CompactibleFreeListSpace: public CompactibleSpace { ...@@ -343,6 +346,17 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// which overestimates the region by returning the entire // which overestimates the region by returning the entire
// committed region (this is safe, but inefficient). // committed region (this is safe, but inefficient).
// Returns monotonically increasing stable used space bytes for CMS.
// This is required for jstat and other memory monitoring tools
// that might otherwise see inconsistent used space values during a garbage
// collection, promotion or allocation into compactibleFreeListSpace.
// The value returned by this function might be smaller than the
// actual value.
size_t used_stable() const;
// Recalculate and cache the current stable used() value. Only to be called
// in places where we can be sure that the result is stable.
void recalculate_used_stable();
// Returns a subregion of the space containing all the objects in // Returns a subregion of the space containing all the objects in
// the space. // the space.
MemRegion used_region() const { MemRegion used_region() const {
......
...@@ -869,6 +869,10 @@ ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const { ...@@ -869,6 +869,10 @@ ConcurrentMarkSweepGeneration::unsafe_max_alloc_nogc() const {
return _cmsSpace->max_alloc_in_words() * HeapWordSize; return _cmsSpace->max_alloc_in_words() * HeapWordSize;
} }
size_t ConcurrentMarkSweepGeneration::used_stable() const {
return cmsSpace()->used_stable();
}
size_t ConcurrentMarkSweepGeneration::max_available() const { size_t ConcurrentMarkSweepGeneration::max_available() const {
return free() + _virtual_space.uncommitted_size(); return free() + _virtual_space.uncommitted_size();
} }
...@@ -1955,6 +1959,8 @@ void CMSCollector::compute_new_size() { ...@@ -1955,6 +1959,8 @@ void CMSCollector::compute_new_size() {
FreelistLocker z(this); FreelistLocker z(this);
MetaspaceGC::compute_new_size(); MetaspaceGC::compute_new_size();
_cmsGen->compute_new_size_free_list(); _cmsGen->compute_new_size_free_list();
// recalculate CMS used space after CMS collection
_cmsGen->cmsSpace()->recalculate_used_stable();
} }
// A work method used by foreground collection to determine // A work method used by foreground collection to determine
...@@ -2768,6 +2774,7 @@ void ConcurrentMarkSweepGeneration::gc_prologue(bool full) { ...@@ -2768,6 +2774,7 @@ void ConcurrentMarkSweepGeneration::gc_prologue(bool full) {
_capacity_at_prologue = capacity(); _capacity_at_prologue = capacity();
_used_at_prologue = used(); _used_at_prologue = used();
_cmsSpace->recalculate_used_stable();
// Delegate to CMScollector which knows how to coordinate between // Delegate to CMScollector which knows how to coordinate between
// this and any other CMS generations that it is responsible for // this and any other CMS generations that it is responsible for
...@@ -2837,6 +2844,7 @@ void CMSCollector::gc_epilogue(bool full) { ...@@ -2837,6 +2844,7 @@ void CMSCollector::gc_epilogue(bool full) {
_eden_chunk_index = 0; _eden_chunk_index = 0;
size_t cms_used = _cmsGen->cmsSpace()->used(); size_t cms_used = _cmsGen->cmsSpace()->used();
_cmsGen->cmsSpace()->recalculate_used_stable();
// update performance counters - this uses a special version of // update performance counters - this uses a special version of
// update_counters() that allows the utilization to be passed as a // update_counters() that allows the utilization to be passed as a
...@@ -3672,6 +3680,7 @@ void CMSCollector::checkpointRootsInitial(bool asynch) { ...@@ -3672,6 +3680,7 @@ void CMSCollector::checkpointRootsInitial(bool asynch) {
_collectorState = Marking; _collectorState = Marking;
} }
SpecializationStats::print(); SpecializationStats::print();
_cmsGen->cmsSpace()->recalculate_used_stable();
} }
void CMSCollector::checkpointRootsInitialWork(bool asynch) { void CMSCollector::checkpointRootsInitialWork(bool asynch) {
...@@ -5066,10 +5075,12 @@ void CMSCollector::checkpointRootsFinal(bool asynch, ...@@ -5066,10 +5075,12 @@ void CMSCollector::checkpointRootsFinal(bool asynch,
Mutex::_no_safepoint_check_flag); Mutex::_no_safepoint_check_flag);
assert(!init_mark_was_synchronous, "but that's impossible!"); assert(!init_mark_was_synchronous, "but that's impossible!");
checkpointRootsFinalWork(asynch, clear_all_soft_refs, false); checkpointRootsFinalWork(asynch, clear_all_soft_refs, false);
_cmsGen->cmsSpace()->recalculate_used_stable();
} else { } else {
// already have all the locks // already have all the locks
checkpointRootsFinalWork(asynch, clear_all_soft_refs, checkpointRootsFinalWork(asynch, clear_all_soft_refs,
init_mark_was_synchronous); init_mark_was_synchronous);
_cmsGen->cmsSpace()->recalculate_used_stable();
} }
verify_work_stacks_empty(); verify_work_stacks_empty();
verify_overflow_empty(); verify_overflow_empty();
...@@ -6368,6 +6379,10 @@ void CMSCollector::sweep(bool asynch) { ...@@ -6368,6 +6379,10 @@ void CMSCollector::sweep(bool asynch) {
// Update heap occupancy information which is used as // Update heap occupancy information which is used as
// input to soft ref clearing policy at the next gc. // input to soft ref clearing policy at the next gc.
Universe::update_heap_info_at_gc(); Universe::update_heap_info_at_gc();
// recalculate CMS used space after CMS collection
_cmsGen->cmsSpace()->recalculate_used_stable();
_collectorState = Resizing; _collectorState = Resizing;
} }
} else { } else {
...@@ -6467,6 +6482,7 @@ void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level, ...@@ -6467,6 +6482,7 @@ void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level,
// Gather statistics on the young generation collection. // Gather statistics on the young generation collection.
collector()->stats().record_gc0_end(used()); collector()->stats().record_gc0_end(used());
} }
_cmsSpace->recalculate_used_stable();
} }
CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() { CMSAdaptiveSizePolicy* ConcurrentMarkSweepGeneration::size_policy() {
......
...@@ -1190,6 +1190,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration { ...@@ -1190,6 +1190,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
double occupancy() const { return ((double)used())/((double)capacity()); } double occupancy() const { return ((double)used())/((double)capacity()); }
size_t contiguous_available() const; size_t contiguous_available() const;
size_t unsafe_max_alloc_nogc() const; size_t unsafe_max_alloc_nogc() const;
size_t used_stable() const;
// over-rides // over-rides
MemRegion used_region() const; MemRegion used_region() const;
......
...@@ -63,7 +63,7 @@ class GSpaceCounters: public CHeapObj<mtGC> { ...@@ -63,7 +63,7 @@ class GSpaceCounters: public CHeapObj<mtGC> {
} }
inline void update_used() { inline void update_used() {
_used->set_value(_gen->used()); _used->set_value(_gen->used_stable());
} }
// special version of update_used() to allow the used value to be // special version of update_used() to allow the used value to be
...@@ -107,7 +107,7 @@ class GenerationUsedHelper : public PerfLongSampleHelper { ...@@ -107,7 +107,7 @@ class GenerationUsedHelper : public PerfLongSampleHelper {
GenerationUsedHelper(Generation* g) : _gen(g) { } GenerationUsedHelper(Generation* g) : _gen(g) { }
inline jlong take_sample() { inline jlong take_sample() {
return _gen->used(); return _gen->used_stable();
} }
}; };
......
...@@ -68,6 +68,12 @@ GenerationSpec* Generation::spec() { ...@@ -68,6 +68,12 @@ GenerationSpec* Generation::spec() {
return gch->_gen_specs[level()]; return gch->_gen_specs[level()];
} }
// This is for CMS. It returns stable monotonic used space size.
// Remove this when CMS is removed.
size_t Generation::used_stable() const {
return used();
}
size_t Generation::max_capacity() const { size_t Generation::max_capacity() const {
return reserved().byte_size(); return reserved().byte_size();
} }
......
...@@ -168,6 +168,7 @@ class Generation: public CHeapObj<mtGC> { ...@@ -168,6 +168,7 @@ class Generation: public CHeapObj<mtGC> {
virtual size_t capacity() const = 0; // The maximum number of object bytes the virtual size_t capacity() const = 0; // The maximum number of object bytes the
// generation can currently hold. // generation can currently hold.
virtual size_t used() const = 0; // The number of used bytes in the gen. virtual size_t used() const = 0; // The number of used bytes in the gen.
virtual size_t used_stable() const; // The number of used bytes for memory monitoring tools.
virtual size_t free() const = 0; // The number of free bytes in the gen. virtual size_t free() const = 0; // The number of free bytes in the gen.
// Support for java.lang.Runtime.maxMemory(); see CollectedHeap. // Support for java.lang.Runtime.maxMemory(); see CollectedHeap.
......
...@@ -294,6 +294,7 @@ InstanceKlass::InstanceKlass(int vtable_len, ...@@ -294,6 +294,7 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_has_unloaded_dependent(false); set_has_unloaded_dependent(false);
set_init_state(InstanceKlass::allocated); set_init_state(InstanceKlass::allocated);
set_init_thread(NULL); set_init_thread(NULL);
set_init_state(allocated);
set_reference_type(rt); set_reference_type(rt);
set_oop_map_cache(NULL); set_oop_map_cache(NULL);
set_jni_ids(NULL); set_jni_ids(NULL);
...@@ -978,11 +979,13 @@ void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle ...@@ -978,11 +979,13 @@ void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle
oop init_lock = this_oop->init_lock(); oop init_lock = this_oop->init_lock();
if (init_lock != NULL) { if (init_lock != NULL) {
ObjectLocker ol(init_lock, THREAD); ObjectLocker ol(init_lock, THREAD);
this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
this_oop->set_init_state(state); this_oop->set_init_state(state);
this_oop->fence_and_clear_init_lock(); this_oop->fence_and_clear_init_lock();
ol.notify_all(CHECK); ol.notify_all(CHECK);
} else { } else {
assert(init_lock != NULL, "The initialization state should never be set twice"); assert(init_lock != NULL, "The initialization state should never be set twice");
this_oop->set_init_thread(NULL); // reset _init_thread before changing _init_state
this_oop->set_init_state(state); this_oop->set_init_state(state);
} }
} }
...@@ -3602,6 +3605,7 @@ void InstanceKlass::set_init_state(ClassState state) { ...@@ -3602,6 +3605,7 @@ void InstanceKlass::set_init_state(ClassState state) {
bool good_state = is_shared() ? (_init_state <= state) bool good_state = is_shared() ? (_init_state <= state)
: (_init_state < state); : (_init_state < state);
assert(good_state || state == allocated, "illegal state transition"); assert(good_state || state == allocated, "illegal state transition");
assert(_init_thread == NULL, "should be cleared before state change");
_init_state = (u1)state; _init_state = (u1)state;
} }
#endif #endif
......
...@@ -241,7 +241,7 @@ class InstanceKlass: public Klass { ...@@ -241,7 +241,7 @@ class InstanceKlass: public Klass {
u2 _misc_flags; u2 _misc_flags;
u2 _minor_version; // minor version number of class file u2 _minor_version; // minor version number of class file
u2 _major_version; // major version number of class file u2 _major_version; // major version number of class file
Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization) Thread* _init_thread; // Pointer to current thread doing initialization (to handle recursive initialization)
int _vtable_len; // length of Java vtable (in words) int _vtable_len; // length of Java vtable (in words)
int _itable_len; // length of Java itable (in words) int _itable_len; // length of Java itable (in words)
OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily) OopMapCache* volatile _oop_map_cache; // OopMapCache for all methods in the klass (allocated lazily)
......
...@@ -289,22 +289,25 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper ...@@ -289,22 +289,25 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
InstanceKlass* superk = initialsuper; InstanceKlass* superk = initialsuper;
while (superk != NULL && superk->super() != NULL) { while (superk != NULL && superk->super() != NULL) {
InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); klassVtable* ssVtable = (superk->super())->vtable();
klassVtable* ssVtable = supersuperklass->vtable();
if (vtable_index < ssVtable->length()) { if (vtable_index < ssVtable->length()) {
Method* super_method = ssVtable->method_at(vtable_index); Method* super_method = ssVtable->method_at(vtable_index);
// get the class holding the matching method
// make sure you use that class for is_override
InstanceKlass* supermethodholder = super_method->method_holder();
#ifndef PRODUCT #ifndef PRODUCT
Symbol* name= target_method()->name(); Symbol* name= target_method()->name();
Symbol* signature = target_method()->signature(); Symbol* signature = target_method()->signature();
assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch");
#endif #endif
if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) {
if (supermethodholder->is_override(super_method, target_loader, target_classname, THREAD)) {
#ifndef PRODUCT #ifndef PRODUCT
if (PrintVtables && Verbose) { if (PrintVtables && Verbose) {
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
char* sig = target_method()->name_and_sig_as_C_string(); char* sig = target_method()->name_and_sig_as_C_string();
tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ",
supersuperklass->internal_name(), supermethodholder->internal_name(),
_klass->internal_name(), sig, vtable_index); _klass->internal_name(), sig, vtable_index);
super_method->access_flags().print_on(tty); super_method->access_flags().print_on(tty);
if (super_method->is_default_method()) { if (super_method->is_default_method()) {
...@@ -656,7 +659,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method, ...@@ -656,7 +659,7 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
// search through the super class hierarchy to see if we need // search through the super class hierarchy to see if we need
// a new entry // a new entry
ResourceMark rm; ResourceMark rm(THREAD);
Symbol* name = target_method()->name(); Symbol* name = target_method()->name();
Symbol* signature = target_method()->signature(); Symbol* signature = target_method()->signature();
Klass* k = super; Klass* k = super;
......
...@@ -198,7 +198,7 @@ public: ...@@ -198,7 +198,7 @@ public:
bool support_usage_threshold); bool support_usage_threshold);
MemoryUsage get_memory_usage(); MemoryUsage get_memory_usage();
size_t used_in_bytes() { return _space->used(); } size_t used_in_bytes() { return _space->used_stable(); }
}; };
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
......
...@@ -22,9 +22,10 @@ ...@@ -22,9 +22,10 @@
*/ */
import sun.hotspot.WhiteBox; import sun.hotspot.WhiteBox;
import sun.misc.Unsafe;
import sun.misc.IOUtils; import sun.misc.IOUtils;
import sun.misc.Unsafe;
import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
...@@ -108,7 +109,13 @@ public class TestAnonymousClassUnloading { ...@@ -108,7 +109,13 @@ public class TestAnonymousClassUnloading {
// (1) Load an anonymous version of this class using the corresponding Unsafe method // (1) Load an anonymous version of this class using the corresponding Unsafe method
URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class"); URL classUrl = TestAnonymousClassUnloading.class.getResource("TestAnonymousClassUnloading.class");
URLConnection connection = classUrl.openConnection(); URLConnection connection = classUrl.openConnection();
byte[] classBytes = IOUtils.readFully(connection.getInputStream(), connection.getContentLength(), true);
int length = connection.getContentLength();
byte[] classBytes = IOUtils.readAllBytes(connection.getInputStream());
if (length != -1 && classBytes.length != length) {
throw new IOException("Expected:" + length + ", actual: " + classBytes.length);
}
Class<?> anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null); Class<?> anonymousClass = UNSAFE.defineAnonymousClass(TestAnonymousClassUnloading.class, classBytes, null);
// (2) Make sure all paths of doWork are profiled and compiled // (2) Make sure all paths of doWork are profiled and compiled
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
* *
*/ */
import sun.misc.IOUtils;
public class VictimClassLoader extends ClassLoader { public class VictimClassLoader extends ClassLoader {
public static long counter = 0; public static long counter = 0;
...@@ -72,8 +74,10 @@ public class VictimClassLoader extends ClassLoader { ...@@ -72,8 +74,10 @@ public class VictimClassLoader extends ClassLoader {
} }
static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException { static byte[] readFully(java.io.InputStream in, int len) throws java.io.IOException {
// Warning here: byte[] b = IOUtils.readAllBytes(in);
return sun.misc.IOUtils.readFully(in, len, true); if (len != -1 && b.length != len)
throw new java.io.IOException("Expected:" + len + ", actual:" + b.length);
return b;
} }
public void finalize() { public void finalize() {
......
#!/bin/sh
#
# Copyright (c) 2019, Red Hat, Inc. All rights reserved.
#
# 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 test.sh
## @bug 8178870
## @summary test instrumentation.retransformClasses
## @run shell test.sh
if [ "${TESTSRC}" = "" ]
then
TESTSRC=${PWD}
echo "TESTSRC not set. Using "${TESTSRC}" as default"
fi
echo "TESTSRC=${TESTSRC}"
## Adding common setup Variables for running shell tests.
. ${TESTSRC}/../../test_env.sh
LIB_SRC=${TESTSRC}/../../testlibrary/
# set platform-dependent variables
OS=`uname -s`
echo "Testing on " $OS
case "$OS" in
Linux)
cc_cmd=`which gcc`
if [ "x$cc_cmd" == "x" ]; then
echo "WARNING: gcc not found. Cannot execute test." 2>&1
exit 0;
fi
;;
Solaris)
cc_cmd=`which cc`
if [ "x$cc_cmd" == "x" ]; then
echo "WARNING: cc not found. Cannot execute test." 2>&1
exit 0;
fi
;;
*)
echo "Test passed. Only on Linux and Solaris"
exit 0;
;;
esac
THIS_DIR=.
cp ${TESTSRC}/RedefineDoubleDelete.java ${THIS_DIR}
mkdir -p ${THIS_DIR}/classes
${TESTJAVA}/bin/javac -sourcepath ${LIB_SRC} -d ${THIS_DIR}/classes ${LIB_SRC}RedefineClassHelper.java
${TESTJAVA}/bin/javac -cp .:${THIS_DIR}/classes:${TESTJAVA}/lib/tools.jar -d ${THIS_DIR} RedefineDoubleDelete.java
$cc_cmd -fPIC -shared -o ${THIS_DIR}${FS}libRedefineDoubleDelete.so \
-I${TESTJAVA}/include -I${TESTJAVA}/include/linux \
${TESTSRC}/libRedefineDoubleDelete.c
LD_LIBRARY_PATH=${THIS_DIR}
echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
# Install redefineagent.jar
${TESTJAVA}/bin${FS}java -cp ${THIS_DIR}/classes RedefineClassHelper
echo
echo ${TESTJAVA}/bin/java -agentlib:RedefineDoubleDelete RedefineDoubleDelete
${TESTJAVA}/bin/java -cp .:${THIS_DIR}${FS}classes -javaagent:redefineagent.jar -agentlib:RedefineDoubleDelete RedefineDoubleDelete
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册