提交 bfd974a3 编写于 作者: V vladidan

Merge

......@@ -921,6 +921,8 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
HINSTANCE dbghelp;
EXCEPTION_POINTERS ep;
MINIDUMP_EXCEPTION_INFORMATION mei;
MINIDUMP_EXCEPTION_INFORMATION* pmei;
HANDLE hProcess = GetCurrentProcess();
DWORD processId = GetCurrentProcessId();
HANDLE dumpFile;
......@@ -971,17 +973,22 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
VMError::report_coredump_status("Failed to create file for dumping", false);
return;
}
if (exceptionRecord != NULL && contextRecord != NULL) {
ep.ContextRecord = (PCONTEXT) contextRecord;
ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;
ep.ContextRecord = (PCONTEXT) contextRecord;
ep.ExceptionRecord = (PEXCEPTION_RECORD) exceptionRecord;
mei.ThreadId = GetCurrentThreadId();
mei.ExceptionPointers = &ep;
pmei = &mei;
} else {
pmei = NULL;
}
mei.ThreadId = GetCurrentThreadId();
mei.ExceptionPointers = &ep;
// Older versions of dbghelp.dll (the one shipped with Win2003 for example) may not support all
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, &mei, NULL, NULL) == false &&
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, &mei, NULL, NULL) == false) {
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
} else {
VMError::report_coredump_status(buffer, true);
......
......@@ -2196,11 +2196,12 @@ typeArrayHandle ClassFileParser::sort_methods(objArrayHandle methods,
TRAPS) {
typeArrayHandle nullHandle;
int length = methods()->length();
// If JVMTI original method ordering is enabled we have to
// If JVMTI original method ordering or sharing is enabled we have to
// remember the original class file ordering.
// We temporarily use the vtable_index field in the methodOop to store the
// class file index, so we can read in after calling qsort.
if (JvmtiExport::can_maintain_original_method_order()) {
// Put the method ordering in the shared archive.
if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
for (int index = 0; index < length; index++) {
methodOop m = methodOop(methods->obj_at(index));
assert(!m->valid_vtable_index(), "vtable index should not be set");
......@@ -2214,8 +2215,9 @@ typeArrayHandle ClassFileParser::sort_methods(objArrayHandle methods,
methods_parameter_annotations(),
methods_default_annotations());
// If JVMTI original method ordering is enabled construct int array remembering the original ordering
if (JvmtiExport::can_maintain_original_method_order()) {
// If JVMTI original method ordering or sharing is enabled construct int
// array remembering the original ordering
if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
typeArrayOop new_ordering = oopFactory::new_permanent_intArray(length, CHECK_(nullHandle));
typeArrayHandle method_ordering(THREAD, new_ordering);
for (int index = 0; index < length; index++) {
......
......@@ -1255,6 +1255,16 @@ instanceKlassHandle SystemDictionary::load_shared_class(
methodHandle m(THREAD, methodOop(methods->obj_at(index2)));
m()->link_method(m, CHECK_(nh));
}
if (JvmtiExport::has_redefined_a_class()) {
// Reinitialize vtable because RedefineClasses may have changed some
// entries in this vtable for super classes so the CDS vtable might
// point to old or obsolete entries. RedefineClasses doesn't fix up
// vtables in the shared system dictionary, only the main one.
// It also redefines the itable too so fix that too.
ResourceMark rm(THREAD);
ik->vtable()->initialize_vtable(false, CHECK_(nh));
ik->itable()->initialize_itable(false, CHECK_(nh));
}
}
if (TraceClassLoading) {
......
......@@ -623,24 +623,48 @@ public:
}
};
// Itable indices are calculated based on methods array order
// (see klassItable::compute_itable_index()). Must reinitialize
// Vtable and Itable indices are calculated based on methods array
// order (see klassItable::compute_itable_index()). Must reinitialize
// after ALL methods of ALL classes have been reordered.
// We assume that since checkconstraints is false, this method
// cannot throw an exception. An exception here would be
// problematic since this is the VMThread, not a JavaThread.
class ReinitializeItables: public ObjectClosure {
class ReinitializeTables: public ObjectClosure {
private:
Thread* _thread;
public:
ReinitializeItables(Thread* thread) : _thread(thread) {}
ReinitializeTables(Thread* thread) : _thread(thread) {}
// Initialize super vtable first, check if already initialized to avoid
// quadradic behavior. The vtable is cleared in remove_unshareable_info.
void reinitialize_vtables(klassOop k) {
if (k->blueprint()->oop_is_instanceKlass()) {
instanceKlass* ik = instanceKlass::cast(k);
if (ik->vtable()->is_initialized()) return;
if (ik->super() != NULL) {
reinitialize_vtables(ik->super());
}
ik->vtable()->initialize_vtable(false, _thread);
}
}
void do_object(oop obj) {
if (obj->blueprint()->oop_is_instanceKlass()) {
instanceKlass* ik = instanceKlass::cast((klassOop)obj);
ResourceMark rm(_thread);
ik->itable()->initialize_itable(false, _thread);
reinitialize_vtables((klassOop)obj);
#ifdef ASSERT
ik->vtable()->verify(tty, true);
#endif // ASSERT
} else if (obj->blueprint()->oop_is_arrayKlass()) {
// The vtable for array klasses are that of its super class,
// ie. java.lang.Object.
arrayKlass* ak = arrayKlass::cast((klassOop)obj);
if (ak->vtable()->is_initialized()) return;
ak->vtable()->initialize_vtable(false, _thread);
}
}
};
......@@ -1205,9 +1229,9 @@ public:
gen->ro_space()->object_iterate(&sort);
gen->rw_space()->object_iterate(&sort);
ReinitializeItables reinit_itables(THREAD);
gen->ro_space()->object_iterate(&reinit_itables);
gen->rw_space()->object_iterate(&reinit_itables);
ReinitializeTables reinit_tables(THREAD);
gen->ro_space()->object_iterate(&reinit_tables);
gen->rw_space()->object_iterate(&reinit_tables);
tty->print_cr("done. ");
tty->cr();
......
......@@ -690,7 +690,8 @@ void instanceKlassKlass::oop_verify_on(oop obj, outputStream* st) {
guarantee(method_ordering->is_perm(), "should be in permspace");
guarantee(method_ordering->is_typeArray(), "should be type array");
int length = method_ordering->length();
if (JvmtiExport::can_maintain_original_method_order()) {
if (JvmtiExport::can_maintain_original_method_order() ||
(UseSharedSpaces && length != 0)) {
guarantee(length == methods->length(), "invalid method ordering length");
jlong sum = 0;
for (j = 0; j < length; j++) {
......
......@@ -453,6 +453,14 @@ void Klass::remove_unshareable_info() {
ik->unlink_class();
}
}
// Clear the Java vtable if the oop has one.
// The vtable isn't shareable because it's in the wrong order wrt the methods
// once the method names get moved and resorted.
klassVtable* vt = vtable();
if (vt != NULL) {
assert(oop_is_instance() || oop_is_array(), "nothing else has vtable");
vt->clear_vtable();
}
set_subklass(NULL);
set_next_sibling(NULL);
}
......
......@@ -645,6 +645,15 @@ void klassVtable::adjust_method_entries(methodOop* old_methods, methodOop* new_m
}
}
// CDS/RedefineClasses support - clear vtables so they can be reinitialized
void klassVtable::clear_vtable() {
for (int i = 0; i < _length; i++) table()[i].clear();
}
bool klassVtable::is_initialized() {
return _length == 0 || table()[0].method() != NULL;
}
// Garbage collection
void klassVtable::oop_follow_contents() {
......
......@@ -75,7 +75,15 @@ class klassVtable : public ResourceObj {
void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass
// conputes vtable length (in words) and the number of miranda methods
// CDS/RedefineClasses support - clear vtables so they can be reinitialized
// at dump time. Clearing gives us an easy way to tell if the vtable has
// already been reinitialized at dump time (see dump.cpp). Vtables can
// be initialized at run time by RedefineClasses so dumping the right order
// is necessary.
void clear_vtable();
bool is_initialized();
// computes vtable length (in words) and the number of miranda methods
static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods,
klassOop super, objArrayOop methods,
AccessFlags class_flags, Handle classloader,
......
......@@ -525,7 +525,7 @@ JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) {
ObjectLocker ol(loader, THREAD);
// need the path as java.lang.String
Handle path = java_lang_String::create_from_str(segment, THREAD);
Handle path = java_lang_String::create_from_platform_dependent_str(segment, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
return JVMTI_ERROR_INTERNAL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册