Skip to content
Permalink
Browse files
8277998: runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraint…
…sTest.java#custom-cl-zgc failed "assert(ZAddress::is_marked(addr)) failed: Should be marked"

Reviewed-by: iklam, minqi
  • Loading branch information
calvinccheung committed Dec 8, 2021
1 parent 37921e3 commit e4852c6f0aa25e7d40c577d507aedc7916ee8d50
Showing 4 changed files with 38 additions and 8 deletions.
@@ -354,6 +354,9 @@ class VM_PopulateDynamicDumpSharedSpace: public VM_GC_Sync_Operation {

_builder.doit();
}
~VM_PopulateDynamicDumpSharedSpace() {
LambdaFormInvokers::cleanup_regenerated_classes();
}
};

void DynamicArchive::check_for_dynamic_dump() {
@@ -39,17 +39,19 @@
#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"
#include "runtime/mutexLocker.hpp"

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));
}

@@ -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,13 +38,16 @@ 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);
static void dump_static_archive_invokers();
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
@@ -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();

1 comment on commit e4852c6

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on e4852c6 Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.