8277998: runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java#custom-cl-zgc failed "assert(ZAddress::is_marked(addr)) failed: Should be marked"

Reviewed-by: iklam, minqi
This commit is contained in:
Calvin Cheung 2021-12-08 15:59:37 +00:00
parent 37921e3080
commit e4852c6f0a
4 changed files with 38 additions and 8 deletions

View File

@ -354,6 +354,9 @@ public:
_builder.doit();
}
~VM_PopulateDynamicDumpSharedSpace() {
LambdaFormInvokers::cleanup_regenerated_classes();
}
};
void DynamicArchive::check_for_dynamic_dump() {

View File

@ -39,10 +39,11 @@
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/klass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
@ -50,6 +51,7 @@
GrowableArrayCHeap<char*, mtClassShared>* LambdaFormInvokers::_lambdaform_lines = nullptr;
Array<Array<char>*>* LambdaFormInvokers::_static_archive_invokers = nullptr;
GrowableArrayCHeap<OopHandle, mtClassShared>* LambdaFormInvokers::_regenerated_mirrors = nullptr;
#define NUM_FILTER 4
static const char* filter[NUM_FILTER] = {"java.lang.invoke.Invokers$Holder",
@ -81,6 +83,25 @@ void LambdaFormInvokers::append(char* line) {
_lambdaform_lines->append(line);
}
// The regenerated Klass is not added to any class loader, so we need
// to keep its java_mirror alive to avoid class unloading.
void LambdaFormInvokers::add_regenerated_class(oop regenerated_class) {
if (_regenerated_mirrors == nullptr) {
_regenerated_mirrors = new GrowableArrayCHeap<OopHandle, mtClassShared>(150);
}
_regenerated_mirrors->append(OopHandle(Universe::vm_global(), regenerated_class));
}
void LambdaFormInvokers::cleanup_regenerated_classes() {
if (_regenerated_mirrors == nullptr) return;
for (int i = 0; i < _regenerated_mirrors->length(); i++) {
_regenerated_mirrors->at(i).release(Universe::vm_global());
}
delete _regenerated_mirrors;
_regenerated_mirrors = nullptr;
}
// convenient output
class PrintLambdaFormMessage {
public:
@ -155,12 +176,11 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
char *buf = NEW_RESOURCE_ARRAY(char, len);
memcpy(buf, (char*)h_bytes->byte_at_addr(0), len);
ClassFileStream st((u1*)buf, len, NULL, ClassFileStream::verify);
reload_class(class_name, st, CHECK);
regenerate_class(class_name, st, CHECK);
}
}
// class_handle - the class name, bytes_handle - the class bytes
void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS) {
Symbol* class_name = SymbolTable::new_symbol((const char*)name);
// the class must exist
Klass* klass = SystemDictionary::resolve_or_null(class_name, THREAD);
@ -180,6 +200,9 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
cl_info,
CHECK);
assert(result->java_mirror() != nullptr, "must be");
add_regenerated_class(result->java_mirror());
{
MutexLocker mu_r(THREAD, Compile_lock); // add_to_hierarchy asserts this.
SystemDictionary::add_to_hierarchy(result);
@ -191,7 +214,7 @@ void LambdaFormInvokers::reload_class(char* name, ClassFileStream& st, TRAPS) {
// exclude the existing class from dump
SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass));
SystemDictionaryShared::init_dumptime_info(result);
log_info(cds, lambda)("Replaced class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT,
name, p2i(klass), p2i(result));
}

View File

@ -25,6 +25,7 @@
#ifndef SHARE_CDS_LAMBDAFORMINVOKERS_HPP
#define SHARE_CDS_LAMBDAFORMINVOKERS_HPP
#include "memory/allStatic.hpp"
#include "oops/oopHandle.hpp"
#include "runtime/handles.hpp"
#include "utilities/growableArray.hpp"
@ -37,7 +38,9 @@ class LambdaFormInvokers : public AllStatic {
static GrowableArrayCHeap<char*, mtClassShared>* _lambdaform_lines;
// For storing LF form lines (LF_RESOLVE only) in read only table.
static Array<Array<char>*>* _static_archive_invokers;
static void reload_class(char* name, ClassFileStream& st, TRAPS);
static GrowableArrayCHeap<OopHandle, mtClassShared>* _regenerated_mirrors;
static void regenerate_class(char* name, ClassFileStream& st, TRAPS);
static void add_regenerated_class(oop regenerated_class);
public:
static void append(char* line);
static void append_filtered(char* line);
@ -45,5 +48,6 @@ class LambdaFormInvokers : public AllStatic {
static void read_static_archive_invokers();
static void regenerate_holder_classes(TRAPS);
static void serialize(SerializeClosure* soc);
static void cleanup_regenerated_classes();
};
#endif // SHARE_CDS_LAMBDAFORMINVOKERS_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, 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
@ -33,7 +33,7 @@
*/
public class DumpClassListWithLF extends ClassListFormatBase {
static final String REPLACE_OK = "Replaced class java/lang/invoke/DirectMethodHandle$Holder";
static final String REPLACE_OK = "Regenerated class java/lang/invoke/DirectMethodHandle$Holder";
public static void main(String[] args) throws Throwable {
String appJar = JarBuilder.getOrCreateHelloJar();