7195867: NPG: SAJDI tests fail with sun.jvm.hotspot.types.WrongTypeException: No suitable match for type
Summary: Need to restore the vtable in metadata when we restore the type from the shared archive.
Reviewed-by: acorn, jcoomes, jmasa, jrose
/*
* Copyright (c) 2002, 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_HEAPINSPECTION_HPP
#define SHARE_VM_MEMORY_HEAPINSPECTION_HPP
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#ifndef SERVICES_KERNEL
// HeapInspection
// KlassInfoTable is a bucket hash table that
// maps Klass*s to extra information:
// instance count and instance word size.
//
// A KlassInfoBucket is the head of a link list
// of KlassInfoEntry's
//
// KlassInfoHisto is a growable array of pointers
// to KlassInfoEntry's and is used to sort
// the entries.
class KlassInfoEntry: public CHeapObj<mtInternal> {
private:
KlassInfoEntry* _next;
Klass* _klass;
long _instance_count;
size_t _instance_words;
public:
KlassInfoEntry(Klass* k, KlassInfoEntry* next) :
_klass(k), _instance_count(0), _instance_words(0), _next(next)
{}
KlassInfoEntry* next() { return _next; }
bool is_equal(Klass* k) { return k == _klass; }
Klass* klass() { return _klass; }
long count() { return _instance_count; }
void set_count(long ct) { _instance_count = ct; }
size_t words() { return _instance_words; }
void set_words(size_t wds) { _instance_words = wds; }
int compare(KlassInfoEntry* e1, KlassInfoEntry* e2);
void print_on(outputStream* st) const;
};
class KlassInfoClosure: public StackObj {
public:
// Called for each KlassInfoEntry.
virtual void do_cinfo(KlassInfoEntry* cie) = 0;
};
class KlassInfoBucket: public CHeapObj<mtInternal> {
private:
KlassInfoEntry* _list;
KlassInfoEntry* list() { return _list; }
void set_list(KlassInfoEntry* l) { _list = l; }
public:
KlassInfoEntry* lookup(Klass* const k);
void initialize() { _list = NULL; }
void empty();
void iterate(KlassInfoClosure* cic);
};
class KlassInfoTable: public StackObj {
private:
int _size;
// An aligned reference address (typically the least
// address in the perm gen) used for hashing klass
// objects.
HeapWord* _ref;
KlassInfoBucket* _buckets;
uint hash(Klass* p);
KlassInfoEntry* lookup(Klass* const k);
public:
// Table size
enum {
cit_size = 20011
};
KlassInfoTable(int size, HeapWord* ref);
~KlassInfoTable();
bool record_instance(const oop obj);
void iterate(KlassInfoClosure* cic);
bool allocation_failed() { return _buckets == NULL; }
};
class KlassInfoHisto : public StackObj {
private:
GrowableArray<KlassInfoEntry*>* _elements;
GrowableArray<KlassInfoEntry*>* elements() const { return _elements; }
const char* _title;
const char* title() const { return _title; }
static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2);
void print_elements(outputStream* st) const;
public:
enum {
histo_initial_size = 1000
};
KlassInfoHisto(const char* title,
int estimatedCount);
~KlassInfoHisto();
void add(KlassInfoEntry* cie);
void print_on(outputStream* st) const;
void sort();
};
#endif // SERVICES_KERNEL
class HeapInspection : public AllStatic {
public:
static void heap_inspection(outputStream* st, bool need_prologue) KERNEL_RETURN;
static void find_instances_at_safepoint(Klass* k, GrowableArray<oop>* result) KERNEL_RETURN;
};
#endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP