8229278: Improve hs_err location printing to assume less about GC internals

Reviewed-by: stefank, kbarrett
This commit is contained in:
Erik Österlund 2019-08-28 11:19:09 +02:00
parent 2750569c00
commit 855f16ef50
23 changed files with 243 additions and 127 deletions

View file

@ -26,6 +26,7 @@
#include "gc/epsilon/epsilonMemoryPool.hpp" #include "gc/epsilon/epsilonMemoryPool.hpp"
#include "gc/epsilon/epsilonThreadLocalData.hpp" #include "gc/epsilon/epsilonThreadLocalData.hpp"
#include "gc/shared/gcArguments.hpp" #include "gc/shared/gcArguments.hpp"
#include "gc/shared/locationPrinter.inline.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
@ -305,6 +306,10 @@ void EpsilonHeap::print_on(outputStream *st) const {
MetaspaceUtils::print_on(st); MetaspaceUtils::print_on(st);
} }
bool EpsilonHeap::print_location(outputStream* st, void* addr) const {
return BlockLocationPrinter<EpsilonHeap>::print_location(st, addr);
}
void EpsilonHeap::print_tracing_info() const { void EpsilonHeap::print_tracing_info() const {
print_heap_info(used()); print_heap_info(used());
print_metaspace_info(); print_metaspace_info();

View file

@ -114,8 +114,8 @@ public:
virtual void unpin_object(JavaThread* thread, oop obj) { } virtual void unpin_object(JavaThread* thread, oop obj) { }
// No support for block parsing. // No support for block parsing.
virtual HeapWord* block_start(const void* addr) const { return NULL; } HeapWord* block_start(const void* addr) const { return NULL; }
virtual bool block_is_obj(const HeapWord* addr) const { return false; } bool block_is_obj(const HeapWord* addr) const { return false; }
// No GC threads // No GC threads
virtual void print_gc_threads_on(outputStream* st) const {} virtual void print_gc_threads_on(outputStream* st) const {}
@ -138,6 +138,7 @@ public:
virtual void print_on(outputStream* st) const; virtual void print_on(outputStream* st) const;
virtual void print_tracing_info() const; virtual void print_tracing_info() const;
virtual bool print_location(outputStream* st, void* addr) const;
private: private:
void print_heap_info(size_t used) const; void print_heap_info(size_t used) const;

View file

@ -74,6 +74,7 @@
#include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/generationSpec.hpp" #include "gc/shared/generationSpec.hpp"
#include "gc/shared/isGCActiveMark.hpp" #include "gc/shared/isGCActiveMark.hpp"
#include "gc/shared/locationPrinter.inline.hpp"
#include "gc/shared/oopStorageParState.hpp" #include "gc/shared/oopStorageParState.hpp"
#include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp"
#include "gc/shared/suspendibleThreadSet.hpp" #include "gc/shared/suspendibleThreadSet.hpp"
@ -2490,6 +2491,10 @@ void G1CollectedHeap::print_all_rsets() {
} }
#endif // PRODUCT #endif // PRODUCT
bool G1CollectedHeap::print_location(outputStream* st, void* addr) const {
return BlockLocationPrinter<G1CollectedHeap>::print_location(st, addr);
}
G1HeapSummary G1CollectedHeap::create_g1_heap_summary() { G1HeapSummary G1CollectedHeap::create_g1_heap_summary() {
size_t eden_used_bytes = _eden.used_bytes(); size_t eden_used_bytes = _eden.used_bytes();

View file

@ -1211,11 +1211,11 @@ public:
// address "addr". We say "blocks" instead of "object" since some heaps // address "addr". We say "blocks" instead of "object" since some heaps
// may not pack objects densely; a chunk may either be an object or a // may not pack objects densely; a chunk may either be an object or a
// non-object. // non-object.
virtual HeapWord* block_start(const void* addr) const; HeapWord* block_start(const void* addr) const;
// Requires "addr" to be the start of a block, and returns "TRUE" iff // Requires "addr" to be the start of a block, and returns "TRUE" iff
// the block is an object. // the block is an object.
virtual bool block_is_obj(const HeapWord* addr) const; bool block_is_obj(const HeapWord* addr) const;
// Section on thread-local allocation buffers (TLABs) // Section on thread-local allocation buffers (TLABs)
// See CollectedHeap for semantics. // See CollectedHeap for semantics.
@ -1428,6 +1428,9 @@ public:
void print_cset_rsets() PRODUCT_RETURN; void print_cset_rsets() PRODUCT_RETURN;
void print_all_rsets() PRODUCT_RETURN; void print_all_rsets() PRODUCT_RETURN;
// Used to print information about locations in the hs_err file.
virtual bool print_location(outputStream* st, void* addr) const;
size_t pending_card_num(); size_t pending_card_num();
}; };

View file

@ -41,6 +41,7 @@
#include "gc/shared/gcLocker.hpp" #include "gc/shared/gcLocker.hpp"
#include "gc/shared/gcWhen.hpp" #include "gc/shared/gcWhen.hpp"
#include "gc/shared/genArguments.hpp" #include "gc/shared/genArguments.hpp"
#include "gc/shared/locationPrinter.inline.hpp"
#include "gc/shared/scavengableNMethods.hpp" #include "gc/shared/scavengableNMethods.hpp"
#include "logging/log.hpp" #include "logging/log.hpp"
#include "memory/metaspaceCounters.hpp" #include "memory/metaspaceCounters.hpp"
@ -584,6 +585,10 @@ PSHeapSummary ParallelScavengeHeap::create_ps_heap_summary() {
return PSHeapSummary(heap_summary, used(), old_summary, old_space, young_summary, eden_space, from_space, to_space); return PSHeapSummary(heap_summary, used(), old_summary, old_space, young_summary, eden_space, from_space, to_space);
} }
bool ParallelScavengeHeap::print_location(outputStream* st, void* addr) const {
return BlockLocationPrinter<ParallelScavengeHeap>::print_location(st, addr);
}
void ParallelScavengeHeap::print_on(outputStream* st) const { void ParallelScavengeHeap::print_on(outputStream* st) const {
young_gen()->print_on(st); young_gen()->print_on(st);
old_gen()->print_on(st); old_gen()->print_on(st);

View file

@ -228,6 +228,9 @@ class ParallelScavengeHeap : public CollectedHeap {
PreGenGCValues get_pre_gc_values() const; PreGenGCValues get_pre_gc_values() const;
void print_heap_change(const PreGenGCValues& pre_gc_values) const; void print_heap_change(const PreGenGCValues& pre_gc_values) const;
// Used to print information about locations in the hs_err file.
virtual bool print_location(outputStream* st, void* addr) const;
void verify(VerifyOption option /* ignored */); void verify(VerifyOption option /* ignored */);
// Resize the young generation. The reserved space for the // Resize the young generation. The reserved space for the

View file

@ -402,28 +402,6 @@ class CollectedHeap : public CHeapObj<mtInternal> {
// over live objects. // over live objects.
virtual void safe_object_iterate(ObjectClosure* cl) = 0; virtual void safe_object_iterate(ObjectClosure* cl) = 0;
// NOTE! There is no requirement that a collector implement these
// functions.
//
// A CollectedHeap is divided into a dense sequence of "blocks"; that is,
// each address in the (reserved) heap is a member of exactly
// one block. The defining characteristic of a block is that it is
// possible to find its size, and thus to progress forward to the next
// block. (Blocks may be of different sizes.) Thus, blocks may
// represent Java objects, or they might be free blocks in a
// free-list-based heap (or subheap), as long as the two kinds are
// distinguishable and the size of each is determinable.
// Returns the address of the start of the "block" that contains the
// address "addr". We say "blocks" instead of "object" since some heaps
// may not pack objects densely; a chunk may either be an object or a
// non-object.
virtual HeapWord* block_start(const void* addr) const = 0;
// Requires "addr" to be the start of a block, and returns "TRUE" iff
// the block is an object.
virtual bool block_is_obj(const HeapWord* addr) const = 0;
// Returns the longest time (in ms) that has elapsed since the last // Returns the longest time (in ms) that has elapsed since the last
// time that any part of the heap was examined by a garbage collection. // time that any part of the heap was examined by a garbage collection.
virtual jlong millis_since_last_gc() = 0; virtual jlong millis_since_last_gc() = 0;
@ -461,6 +439,9 @@ class CollectedHeap : public CHeapObj<mtInternal> {
virtual void print_on_error(outputStream* st) const; virtual void print_on_error(outputStream* st) const;
// Used to print information about locations in the hs_err file.
virtual bool print_location(outputStream* st, void* addr) const = 0;
// Print all GC threads (other than the VM thread) // Print all GC threads (other than the VM thread)
// used by this heap. // used by this heap.
virtual void print_gc_threads_on(outputStream* st) const = 0; virtual void print_gc_threads_on(outputStream* st) const = 0;

View file

@ -47,6 +47,7 @@
#include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/generationSpec.hpp" #include "gc/shared/generationSpec.hpp"
#include "gc/shared/locationPrinter.inline.hpp"
#include "gc/shared/oopStorageParState.inline.hpp" #include "gc/shared/oopStorageParState.inline.hpp"
#include "gc/shared/scavengableNMethods.hpp" #include "gc/shared/scavengableNMethods.hpp"
#include "gc/shared/space.hpp" #include "gc/shared/space.hpp"
@ -1260,6 +1261,10 @@ void GenCollectedHeap::gc_threads_do(ThreadClosure* tc) const {
void GenCollectedHeap::print_gc_threads_on(outputStream* st) const { void GenCollectedHeap::print_gc_threads_on(outputStream* st) const {
} }
bool GenCollectedHeap::print_location(outputStream* st, void* addr) const {
return BlockLocationPrinter<GenCollectedHeap>::print_location(st, addr);
}
void GenCollectedHeap::print_tracing_info() const { void GenCollectedHeap::print_tracing_info() const {
if (log_is_enabled(Debug, gc, heap, exit)) { if (log_is_enabled(Debug, gc, heap, exit)) {
LogStreamHandle(Debug, gc, heap, exit) lsh; LogStreamHandle(Debug, gc, heap, exit) lsh;

View file

@ -260,13 +260,13 @@ public:
// address "addr". We say "blocks" instead of "object" since some heaps // address "addr". We say "blocks" instead of "object" since some heaps
// may not pack objects densely; a chunk may either be an object or a // may not pack objects densely; a chunk may either be an object or a
// non-object. // non-object.
virtual HeapWord* block_start(const void* addr) const; HeapWord* block_start(const void* addr) const;
// Requires "addr" to be the start of a block, and returns "TRUE" iff // Requires "addr" to be the start of a block, and returns "TRUE" iff
// the block is an object. Assumes (and verifies in non-product // the block is an object. Assumes (and verifies in non-product
// builds) that addr is in the allocated part of the heap and is // builds) that addr is in the allocated part of the heap and is
// the start of a chunk. // the start of a chunk.
virtual bool block_is_obj(const HeapWord* addr) const; bool block_is_obj(const HeapWord* addr) const;
// Section on TLAB's. // Section on TLAB's.
virtual bool supports_tlab_allocation() const; virtual bool supports_tlab_allocation() const;
@ -332,6 +332,9 @@ public:
virtual void gc_threads_do(ThreadClosure* tc) const; virtual void gc_threads_do(ThreadClosure* tc) const;
virtual void print_tracing_info() const; virtual void print_tracing_info() const;
// Used to print information about locations in the hs_err file.
virtual bool print_location(outputStream* st, void* addr) const;
void print_heap_change(size_t young_prev_used, size_t old_prev_used) const; void print_heap_change(size_t young_prev_used, size_t old_prev_used) const;
// The functions below are helper functions that a subclass of // The functions below are helper functions that a subclass of

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* 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/shared/collectedHeap.hpp"
#include "gc/shared/locationPrinter.hpp"
#include "memory/universe.hpp"
#include "runtime/os.hpp"
#include "oops/klass.hpp"
bool LocationPrinter::is_valid_obj(void* obj) {
if (!is_object_aligned(obj)) {
return false;
}
if (obj < (void*)os::min_page_size()) {
return false;
}
// We need at least the mark and the klass word in the committed region.
if (!os::is_readable_range(obj, (HeapWord*)obj + oopDesc::header_size())) {
return false;
}
if (!Universe::heap()->is_in(obj)) {
return false;
}
Klass* k = (Klass*)oopDesc::load_klass_raw((oopDesc*)obj);
return Klass::is_valid(k);
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* 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_GC_SHARED_LOCATIONPRINTER_HPP
#define SHARE_GC_SHARED_LOCATIONPRINTER_HPP
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "utilities/globalDefinitions.hpp"
class outputStream;
class LocationPrinter : AllStatic {
public:
static bool is_valid_obj(void* addr);
};
template <typename CollectedHeapT>
class BlockLocationPrinter : public LocationPrinter {
static oop base_oop_or_null(void* addr);
public:
static bool print_location(outputStream* st, void* addr);
};
#endif // SHARE_GC_SHARED_LOCATIONPRINTER_HPP

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* 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_GC_SHARED_LOCATIONPRINTER_INLINE_HPP
#define SHARE_GC_SHARED_LOCATIONPRINTER_INLINE_HPP
#include "gc/shared/locationPrinter.hpp"
#include "oops/compressedOops.inline.hpp"
#include "oops/oopsHierarchy.hpp"
template <typename CollectedHeapT>
oop BlockLocationPrinter<CollectedHeapT>::base_oop_or_null(void* addr) {
if (is_valid_obj(addr)) {
// We were just given an oop directly.
return oop(addr);
}
// Try to find addr using block_start.
HeapWord* p = CollectedHeapT::heap()->block_start(addr);
if (p != NULL && CollectedHeapT::heap()->block_is_obj(p)) {
if (!is_valid_obj(p)) {
return NULL;
}
return oop(p);
}
return NULL;
}
template <typename CollectedHeapT>
bool BlockLocationPrinter<CollectedHeapT>::print_location(outputStream* st, void* addr) {
// Check if addr points into Java heap.
if (CollectedHeapT::heap()->is_in(addr)) {
oop o = base_oop_or_null(addr);
if (o != NULL) {
if ((void*)o == addr) {
st->print(INTPTR_FORMAT " is an oop: ", p2i(addr));
} else {
st->print(INTPTR_FORMAT " is pointing into object: " , p2i(addr));
}
o->print_on(st);
return true;
}
} else if (CollectedHeapT::heap()->is_in_reserved(addr)) {
st->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", p2i(addr));
return true;
}
// Compressed oop needs to be decoded first.
#ifdef _LP64
if (UseCompressedOops && ((uintptr_t)addr &~ (uintptr_t)max_juint) == 0) {
narrowOop narrow_oop = (narrowOop)(uintptr_t)addr;
oop o = CompressedOops::decode_raw(narrow_oop);
if (is_valid_obj((address)o)) {
st->print(UINT32_FORMAT " is a compressed pointer to object: ", narrow_oop);
o->print_on(st);
return true;
}
}
#endif
return false;
}
#endif // SHARE_GC_SHARED_LOCATIONPRINTER_INLINE_HPP

View file

@ -28,6 +28,7 @@
#include "gc/shared/gcArguments.hpp" #include "gc/shared/gcArguments.hpp"
#include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/locationPrinter.inline.hpp"
#include "gc/shared/memAllocator.hpp" #include "gc/shared/memAllocator.hpp"
#include "gc/shared/plab.hpp" #include "gc/shared/plab.hpp"
@ -1133,6 +1134,10 @@ bool ShenandoahHeap::block_is_obj(const HeapWord* addr) const {
return sp->block_is_obj(addr); return sp->block_is_obj(addr);
} }
bool ShenandoahHeap::print_location(outputStream* st, void* addr) const {
return BlockLocationPrinter<ShenandoahHeap>::print_location(st, addr);
}
jlong ShenandoahHeap::millis_since_last_gc() { jlong ShenandoahHeap::millis_since_last_gc() {
double v = heuristics()->time_since_last_gc() * 1000; double v = heuristics()->time_since_last_gc() * 1000;
assert(0 <= v && v <= max_jlong, "value should fit: %f", v); assert(0 <= v && v <= max_jlong, "value should fit: %f", v);

View file

@ -536,6 +536,7 @@ public:
// Used for parsing heap during error printing // Used for parsing heap during error printing
HeapWord* block_start(const void* addr) const; HeapWord* block_start(const void* addr) const;
bool block_is_obj(const HeapWord* addr) const; bool block_is_obj(const HeapWord* addr) const;
bool print_location(outputStream* st, void* addr) const;
// Used for native heap walkers: heap dumpers, mostly // Used for native heap walkers: heap dumpers, mostly
void object_iterate(ObjectClosure* cl); void object_iterate(ObjectClosure* cl);

View file

@ -23,6 +23,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/locationPrinter.hpp"
#include "gc/shared/suspendibleThreadSet.hpp" #include "gc/shared/suspendibleThreadSet.hpp"
#include "gc/z/zCollectedHeap.hpp" #include "gc/z/zCollectedHeap.hpp"
#include "gc/z/zGlobals.hpp" #include "gc/z/zGlobals.hpp"
@ -249,14 +250,6 @@ void ZCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
_heap.object_iterate(cl, true /* visit_weaks */); _heap.object_iterate(cl, true /* visit_weaks */);
} }
HeapWord* ZCollectedHeap::block_start(const void* addr) const {
return (HeapWord*)_heap.block_start((uintptr_t)addr);
}
bool ZCollectedHeap::block_is_obj(const HeapWord* addr) const {
return _heap.block_is_obj((uintptr_t)addr);
}
void ZCollectedHeap::register_nmethod(nmethod* nm) { void ZCollectedHeap::register_nmethod(nmethod* nm) {
ZNMethod::register_nmethod(nm); ZNMethod::register_nmethod(nm);
} }
@ -356,6 +349,16 @@ void ZCollectedHeap::print_tracing_info() const {
// Does nothing // Does nothing
} }
bool ZCollectedHeap::print_location(outputStream* st, void* addr) const {
if (LocationPrinter::is_valid_obj(addr)) {
st->print(INTPTR_FORMAT " is a %s oop: ", p2i(addr),
ZAddress::is_good(reinterpret_cast<uintptr_t>(addr)) ? "good" : "bad");
cast_to_oop(addr)->print_on(st);
return true;
}
return false;
}
void ZCollectedHeap::verify(VerifyOption option /* ignored */) { void ZCollectedHeap::verify(VerifyOption option /* ignored */) {
_heap.verify(); _heap.verify();
} }

View file

@ -100,9 +100,6 @@ public:
virtual void object_iterate(ObjectClosure* cl); virtual void object_iterate(ObjectClosure* cl);
virtual void safe_object_iterate(ObjectClosure* cl); virtual void safe_object_iterate(ObjectClosure* cl);
virtual HeapWord* block_start(const void* addr) const;
virtual bool block_is_obj(const HeapWord* addr) const;
virtual void register_nmethod(nmethod* nm); virtual void register_nmethod(nmethod* nm);
virtual void unregister_nmethod(nmethod* nm); virtual void unregister_nmethod(nmethod* nm);
virtual void flush_nmethod(nmethod* nm); virtual void flush_nmethod(nmethod* nm);
@ -124,6 +121,7 @@ public:
virtual void print_extended_on(outputStream* st) const; virtual void print_extended_on(outputStream* st) const;
virtual void print_gc_threads_on(outputStream* st) const; virtual void print_gc_threads_on(outputStream* st) const;
virtual void print_tracing_info() const; virtual void print_tracing_info() const;
virtual bool print_location(outputStream* st, void* addr) const;
virtual void prepare_for_verify(); virtual void prepare_for_verify();
virtual void verify(VerifyOption option /* ignored */); virtual void verify(VerifyOption option /* ignored */);

View file

@ -194,16 +194,6 @@ bool ZHeap::is_in(uintptr_t addr) const {
return false; return false;
} }
uintptr_t ZHeap::block_start(uintptr_t addr) const {
const ZPage* const page = _page_table.get(addr);
return page->block_start(addr);
}
bool ZHeap::block_is_obj(uintptr_t addr) const {
const ZPage* const page = _page_table.get(addr);
return page->block_is_obj(addr);
}
uint ZHeap::nconcurrent_worker_threads() const { uint ZHeap::nconcurrent_worker_threads() const {
return _workers.nconcurrent(); return _workers.nconcurrent();
} }

View file

@ -107,10 +107,6 @@ public:
bool is_in(uintptr_t addr) const; bool is_in(uintptr_t addr) const;
uint32_t hash_oop(oop obj) const; uint32_t hash_oop(oop obj) const;
// Block
uintptr_t block_start(uintptr_t addr) const;
bool block_is_obj(uintptr_t addr) const;
// Workers // Workers
uint nconcurrent_worker_threads() const; uint nconcurrent_worker_threads() const;
uint nconcurrent_no_boost_worker_threads() const; uint nconcurrent_no_boost_worker_threads() const;

View file

@ -90,9 +90,6 @@ public:
bool is_in(uintptr_t addr) const; bool is_in(uintptr_t addr) const;
uintptr_t block_start(uintptr_t addr) const;
bool block_is_obj(uintptr_t addr) const;
bool is_marked() const; bool is_marked() const;
bool is_object_live(uintptr_t addr) const; bool is_object_live(uintptr_t addr) const;
bool is_object_strongly_live(uintptr_t addr) const; bool is_object_strongly_live(uintptr_t addr) const;

View file

@ -177,18 +177,6 @@ inline bool ZPage::is_in(uintptr_t addr) const {
return offset >= start() && offset < top(); return offset >= start() && offset < top();
} }
inline uintptr_t ZPage::block_start(uintptr_t addr) const {
if (block_is_obj(addr)) {
return addr;
} else {
return ZAddress::good(top());
}
}
inline bool ZPage::block_is_obj(uintptr_t addr) const {
return ZAddress::offset(addr) < top();
}
inline bool ZPage::is_marked() const { inline bool ZPage::is_marked() const {
assert(is_relocatable(), "Invalid page state"); assert(is_relocatable(), "Invalid page state");
return _livemap.is_marked(); return _livemap.is_marked();

View file

@ -173,35 +173,6 @@ void* oopDesc::load_oop_raw(oop obj, int offset) {
} }
} }
bool oopDesc::is_valid(oop obj) {
if (!is_object_aligned(obj)) return false;
if ((size_t)(oopDesc*)obj < os::min_page_size()) return false;
// We need at least the mark and the klass word in the committed region.
if (!os::is_readable_range(obj, (oopDesc*)obj + 1)) return false;
if (!Universe::heap()->is_in(obj)) return false;
Klass* k = (Klass*)load_klass_raw(obj);
return Klass::is_valid(k);
}
oop oopDesc::oop_or_null(address addr) {
if (is_valid(oop(addr))) {
// We were just given an oop directly.
return oop(addr);
}
// Try to find addr using block_start.
HeapWord* p = Universe::heap()->block_start(addr);
if (p != NULL && Universe::heap()->block_is_obj(p)) {
if (!is_valid(oop(p))) return NULL;
return oop(p);
}
// If we can't find it it just may mean that heap wasn't parsable.
return NULL;
}
oop oopDesc::obj_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::oop_load_at(as_oop(), offset); } oop oopDesc::obj_field_acquire(int offset) const { return HeapAccess<MO_ACQUIRE>::oop_load_at(as_oop(), offset); }
void oopDesc::obj_field_put_raw(int offset, oop value) { RawAccess<>::oop_store_at(as_oop(), offset, value); } void oopDesc::obj_field_put_raw(int offset, oop value) { RawAccess<>::oop_store_at(as_oop(), offset, value); }

View file

@ -331,8 +331,6 @@ class oopDesc {
// for error reporting // for error reporting
static void* load_klass_raw(oop obj); static void* load_klass_raw(oop obj);
static void* load_oop_raw(oop obj, int offset); static void* load_oop_raw(oop obj, int offset);
static bool is_valid(oop obj);
static oop oop_or_null(address addr);
}; };
#endif // SHARE_OOPS_OOP_HPP #endif // SHARE_OOPS_OOP_HPP

View file

@ -1082,36 +1082,9 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
} }
// Check if addr points into Java heap. // Check if addr points into Java heap.
if (Universe::heap()->is_in(addr)) { if (Universe::heap()->print_location(st, addr)) {
oop o = oopDesc::oop_or_null(addr);
if (o != NULL) {
if ((HeapWord*)o == (HeapWord*)addr) {
st->print(INTPTR_FORMAT " is an oop: ", p2i(addr));
} else {
st->print(INTPTR_FORMAT " is pointing into object: " , p2i(addr));
}
ResourceMark rm;
o->print_on(st);
return; return;
} }
} else if (Universe::heap()->is_in_reserved(addr)) {
st->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", p2i(addr));
return;
}
// Compressed oop needs to be decoded first.
#ifdef _LP64
if (UseCompressedOops && ((uintptr_t)addr &~ (uintptr_t)max_juint) == 0) {
narrowOop narrow_oop = (narrowOop)(uintptr_t)addr;
oop o = CompressedOops::decode_raw(narrow_oop);
if (oopDesc::is_valid(o)) {
st->print(UINT32_FORMAT " is a compressed pointer to object: ", narrow_oop);
o->print_on(st);
return;
}
}
#endif
bool accessible = is_readable_pointer(addr); bool accessible = is_readable_pointer(addr);