6995781: Native Memory Tracking (Phase 1)

7151532: DCmd for hotspot native memory tracking

Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd

Reviewed-by: acorn, coleenp, fparain
This commit is contained in:
Zhengyu Gu 2012-06-28 17:03:16 -04:00
parent 8e42425c92
commit a39b17624a
315 changed files with 7245 additions and 1477 deletions

View file

@ -40,7 +40,7 @@
class BasicHashtableEntry : public CHeapObj {
template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
friend class VMStructs;
private:
unsigned int _hash; // 32-bit hash for item
@ -52,7 +52,7 @@ private:
// shared entries will not change. New entries will always be
// unshared and since pointers are align, bit 0 will always remain 0
// with no extra effort.
BasicHashtableEntry* _next;
BasicHashtableEntry<F>* _next;
// Windows IA64 compiler requires subclasses to be able to access these
protected:
@ -69,19 +69,19 @@ public:
void set_hash(unsigned int hash) { _hash = hash; }
unsigned int* hash_addr() { return &_hash; }
static BasicHashtableEntry* make_ptr(BasicHashtableEntry* p) {
static BasicHashtableEntry<F>* make_ptr(BasicHashtableEntry<F>* p) {
return (BasicHashtableEntry*)((intptr_t)p & -2);
}
BasicHashtableEntry* next() const {
BasicHashtableEntry<F>* next() const {
return make_ptr(_next);
}
void set_next(BasicHashtableEntry* next) {
void set_next(BasicHashtableEntry<F>* next) {
_next = next;
}
BasicHashtableEntry** next_addr() {
BasicHashtableEntry<F>** next_addr() {
return &_next;
}
@ -90,13 +90,13 @@ public:
}
void set_shared() {
_next = (BasicHashtableEntry*)((intptr_t)_next | 1);
_next = (BasicHashtableEntry<F>*)((intptr_t)_next | 1);
}
};
template <class T> class HashtableEntry : public BasicHashtableEntry {
template <class T, MEMFLAGS F> class HashtableEntry : public BasicHashtableEntry<F> {
friend class VMStructs;
private:
T _literal; // ref to item in table.
@ -108,20 +108,20 @@ public:
void set_literal(T s) { _literal = s; }
HashtableEntry* next() const {
return (HashtableEntry*)BasicHashtableEntry::next();
return (HashtableEntry*)BasicHashtableEntry<F>::next();
}
HashtableEntry** next_addr() {
return (HashtableEntry**)BasicHashtableEntry::next_addr();
return (HashtableEntry**)BasicHashtableEntry<F>::next_addr();
}
};
class HashtableBucket : public CHeapObj {
template <MEMFLAGS F> class HashtableBucket : public CHeapObj<F> {
friend class VMStructs;
private:
// Instance variable
BasicHashtableEntry* _entry;
BasicHashtableEntry<F>* _entry;
public:
// Accessing
@ -129,21 +129,21 @@ public:
// The following methods use order access methods to avoid race
// conditions in multiprocessor systems.
BasicHashtableEntry* get_entry() const;
void set_entry(BasicHashtableEntry* l);
BasicHashtableEntry<F>* get_entry() const;
void set_entry(BasicHashtableEntry<F>* l);
// The following method is not MT-safe and must be done under lock.
BasicHashtableEntry** entry_addr() { return &_entry; }
BasicHashtableEntry<F>** entry_addr() { return &_entry; }
};
class BasicHashtable : public CHeapObj {
template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
friend class VMStructs;
public:
BasicHashtable(int table_size, int entry_size);
BasicHashtable(int table_size, int entry_size,
HashtableBucket* buckets, int number_of_entries);
HashtableBucket<F>* buckets, int number_of_entries);
// Sharing support.
void copy_buckets(char** top, char* end);
@ -162,8 +162,8 @@ public:
private:
// Instance variables
int _table_size;
HashtableBucket* _buckets;
BasicHashtableEntry* _free_list;
HashtableBucket<F>* _buckets;
BasicHashtableEntry<F>* _free_list;
char* _first_free_entry;
char* _end_block;
int _entry_size;
@ -188,20 +188,20 @@ protected:
int entry_size() const { return _entry_size; }
// The following method is MT-safe and may be used with caution.
BasicHashtableEntry* bucket(int i);
BasicHashtableEntry<F>* bucket(int i);
// The following method is not MT-safe and must be done under lock.
BasicHashtableEntry** bucket_addr(int i) { return _buckets[i].entry_addr(); }
BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
// Table entry management
BasicHashtableEntry* new_entry(unsigned int hashValue);
BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
// Check that the table is unbalanced
bool check_rehash_table(int count);
// Used when moving the entry to another table
// Clean up links, but do not add to free_list
void unlink_entry(BasicHashtableEntry* entry) {
void unlink_entry(BasicHashtableEntry<F>* entry) {
entry->set_next(NULL);
--_number_of_entries;
}
@ -221,11 +221,11 @@ protected:
public:
int table_size() { return _table_size; }
void set_entry(int index, BasicHashtableEntry* entry);
void set_entry(int index, BasicHashtableEntry<F>* entry);
void add_entry(int index, BasicHashtableEntry* entry);
void add_entry(int index, BasicHashtableEntry<F>* entry);
void free_entry(BasicHashtableEntry* entry);
void free_entry(BasicHashtableEntry<F>* entry);
int number_of_entries() { return _number_of_entries; }
@ -233,16 +233,16 @@ public:
};
template <class T> class Hashtable : public BasicHashtable {
template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
friend class VMStructs;
public:
Hashtable(int table_size, int entry_size)
: BasicHashtable(table_size, entry_size) { }
: BasicHashtable<F>(table_size, entry_size) { }
Hashtable(int table_size, int entry_size,
HashtableBucket* buckets, int number_of_entries)
: BasicHashtable(table_size, entry_size, buckets, number_of_entries) { }
HashtableBucket<F>* buckets, int number_of_entries)
: BasicHashtable<F>(table_size, entry_size, buckets, number_of_entries) { }
// Debugging
void print() PRODUCT_RETURN;
@ -264,35 +264,35 @@ protected:
}
// Table entry management
HashtableEntry<T>* new_entry(unsigned int hashValue, T obj);
HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
// The following method is MT-safe and may be used with caution.
HashtableEntry<T>* bucket(int i) {
return (HashtableEntry<T>*)BasicHashtable::bucket(i);
HashtableEntry<T, F>* bucket(int i) {
return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
}
// The following method is not MT-safe and must be done under lock.
HashtableEntry<T>** bucket_addr(int i) {
return (HashtableEntry<T>**)BasicHashtable::bucket_addr(i);
HashtableEntry<T, F>** bucket_addr(int i) {
return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
}
// Function to move these elements into the new table.
void move_to(Hashtable<T>* new_table);
void move_to(Hashtable<T, F>* new_table);
virtual unsigned int new_hash(T) { ShouldNotReachHere(); return 0; } // should be overridden
};
// Verions of hashtable where two handles are used to compute the index.
template <class T> class TwoOopHashtable : public Hashtable<T> {
template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
friend class VMStructs;
protected:
TwoOopHashtable(int table_size, int entry_size)
: Hashtable<T>(table_size, entry_size) {}
: Hashtable<T, F>(table_size, entry_size) {}
TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t,
TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
int number_of_entries)
: Hashtable<T>(table_size, entry_size, t, number_of_entries) {}
: Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
public:
unsigned int compute_hash(Symbol* name, Handle loader) {