Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions src/hotspot/share/cds/aotMapLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ void AOTMapLogger::log_as_hex(address base, address top, address requested_base,
}

#if INCLUDE_CDS_JAVA_HEAP
// FakeOop (and subclasses FakeMirror, FakeString, FakeObjArray, FakeTypeArray) are used to traverse
// FakeOop (and subclasses FakeMirror, FakeString, FakeRefArray, FakeFlatArray, FakeTypeArray) are used to traverse
// and print the (image of) heap objects stored in the AOT cache. These objects are different than regular oops:
// - They do not reside inside the range of the heap.
// - For +UseCompressedOops: pointers may use a different narrowOop encoding: see FakeOop::read_oop_at(narrowOop*)
Expand Down Expand Up @@ -530,7 +530,8 @@ class AOTMapLogger::FakeOop {
FakeOop(OopDataIterator* iter, OopData data) : _iter(iter), _data(data) {}

FakeMirror as_mirror();
FakeObjArray as_obj_array();
FakeRefArray as_ref_array();
FakeFlatArray as_flat_array();
FakeString as_string();
FakeTypeArray as_type_array();

Expand Down Expand Up @@ -618,25 +619,42 @@ class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
}
}; // AOTMapLogger::FakeMirror

class AOTMapLogger::FakeObjArray : public AOTMapLogger::FakeOop {
objArrayOop raw_objArrayOop() {
return (objArrayOop)raw_oop();
class AOTMapLogger::FakeRefArray : public AOTMapLogger::FakeOop {
refArrayOop raw_refArrayOop() {
return (refArrayOop)raw_oop();
}

public:
FakeObjArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
FakeRefArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}

int length() {
return raw_objArrayOop()->length();
return raw_refArrayOop()->length();
}
FakeOop obj_at(int i) {
if (UseCompressedOops) {
return read_oop_at(raw_objArrayOop()->obj_at_addr<narrowOop>(i));
return read_oop_at(raw_refArrayOop()->obj_at_addr<narrowOop>(i));
} else {
return read_oop_at(raw_objArrayOop()->obj_at_addr<oop>(i));
return read_oop_at(raw_refArrayOop()->obj_at_addr<oop>(i));
}
}
}; // AOTMapLogger::FakeObjArray
}; // AOTMapLogger::FakeRefArray

class AOTMapLogger::FakeFlatArray : public AOTMapLogger::FakeOop {
flatArrayOop raw_flatArrayOop() {
return (flatArrayOop)raw_oop();
}

public:
FakeFlatArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}

int length() {
return raw_flatArrayOop()->length();
}
void print_elements_on(outputStream* st) {
FlatArrayKlass::cast(real_klass())->oop_print_elements_on(raw_flatArrayOop(), st);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

AOTMapLogger::FakeRefArray has an FakeOop obj_at(int i) method for reading the elements. Do we need an equivalent for FakeFlatArray?

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we get away without having it due to the implementation of FlatArrayKlass::oop_print_on?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought it was nicer to have the printing logic in the flatArrayOop.cpp file rather than in some AOT file, so it's more like typeArrayOop. The refArray case wants to save the oops it finds for something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Although I suppose this won't work if the flatArrayKlass has oops (something about read_oop_at())

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This code is weird. I don't know this code.

}; // AOTMapLogger::FakeRefArray

class AOTMapLogger::FakeString : public AOTMapLogger::FakeOop {
public:
Expand Down Expand Up @@ -676,9 +694,14 @@ AOTMapLogger::FakeMirror AOTMapLogger::FakeOop::as_mirror() {
return FakeMirror(_iter, _data);
}

AOTMapLogger::FakeObjArray AOTMapLogger::FakeOop::as_obj_array() {
precond(real_klass()->is_objArray_klass());
return FakeObjArray(_iter, _data);
AOTMapLogger::FakeRefArray AOTMapLogger::FakeOop::as_ref_array() {
precond(real_klass()->is_refArray_klass());
return FakeRefArray(_iter, _data);
}

AOTMapLogger::FakeFlatArray AOTMapLogger::FakeOop::as_flat_array() {
precond(real_klass()->is_flatArray_klass());
return FakeFlatArray(_iter, _data);
}

AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
Expand Down Expand Up @@ -923,8 +946,10 @@ void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {

if (real_klass->is_typeArray_klass()) {
fake_oop.as_type_array().print_elements_on(st);
} else if (real_klass->is_objArray_klass()) {
FakeObjArray fake_obj_array = fake_oop.as_obj_array();
} else if (real_klass->is_flatArray_klass()) {
fake_oop.as_flat_array().print_elements_on(st);
} else if (real_klass->is_refArray_klass()) {
FakeRefArray fake_obj_array = fake_oop.as_ref_array();
bool is_logging_root_segment = fake_oop.is_root_segment();

for (int i = 0; i < fake_obj_array.length(); i++) {
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/cds/aotMapLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class AOTMapLogger : AllStatic {
// FakeOop and subtypes
class FakeOop;
class FakeMirror;
class FakeObjArray;
class FakeRefArray;
class FakeFlatArray;
class FakeString;
class FakeTypeArray;

Expand Down
6 changes: 4 additions & 2 deletions src/hotspot/share/cds/aotMappedHeapWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ HeapWord* AOTMappedHeapWriter::init_filler_array_at_buffer_top(int array_length,
if (UseCompactObjectHeaders) {
oopDesc::release_set_mark(mem, markWord::prototype().set_narrow_klass(nk));
} else {
assert(!EnableValhalla || Universe::objectArrayKlass()->prototype_header() == markWord::prototype(), "should be the same");
oopDesc::set_mark(mem, markWord::prototype());
cast_to_oop(mem)->set_narrow_klass(nk);
}
Expand Down Expand Up @@ -642,7 +643,8 @@ void AOTMappedHeapWriter::update_header_for_requested_obj(oop requested_obj, oop

oop fake_oop = cast_to_oop(buffered_addr);
if (UseCompactObjectHeaders) {
fake_oop->set_mark(markWord::prototype().set_narrow_klass(nk));
markWord prototype_header = src_klass->prototype_header().set_narrow_klass(nk);
fake_oop->set_mark(prototype_header);
} else {
fake_oop->set_narrow_klass(nk);
}
Expand All @@ -655,7 +657,7 @@ void AOTMappedHeapWriter::update_header_for_requested_obj(oop requested_obj, oop
if (!src_obj->fast_no_hash_check() && (!(EnableValhalla && src_obj->mark().is_inline_type()))) {
intptr_t src_hash = src_obj->identity_hash();
if (UseCompactObjectHeaders) {
fake_oop->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
fake_oop->set_mark(fake_oop->mark().copy_set_hash(src_hash));
} else if (EnableValhalla) {
fake_oop->set_mark(src_klass->prototype_header().copy_set_hash(src_hash));
} else {
Expand Down
5 changes: 0 additions & 5 deletions src/hotspot/share/cds/aotMetaspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1353,11 +1353,6 @@ bool AOTMetaspace::try_link_class(JavaThread* current, InstanceKlass* ik) {
}

void VM_PopulateDumpSharedSpace::dump_java_heap_objects() {
if (CDSConfig::is_valhalla_preview()) {
log_info(cds)("Archived java heap is not yet supported with Valhalla preview");
return;
}

if (CDSConfig::is_dumping_heap()) {
HeapShared::write_heap(&_mapped_heap_info, &_streamed_heap_info);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/cds/aotStreamedHeapWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,14 +390,14 @@ void AOTStreamedHeapWriter::update_header_for_buffered_addr(address buffered_add
assert(UseCompressedClassPointers, "Archived heap only supported for compressed klasses");
narrowKlass nk = ArchiveBuilder::current()->get_requested_narrow_klass(src_klass);

markWord mw = markWord::prototype();
markWord mw = Arguments::enable_preview() ? src_klass->prototype_header() : markWord::prototype();
oopDesc* fake_oop = (oopDesc*)buffered_addr;

// We need to retain the identity_hash, because it may have been used by some hashtables
// in the shared heap. This also has the side effect of pre-initializing the
// identity_hash for all shared objects, so they are less likely to be written
// into during run time, increasing the potential of memory sharing.
if (src_obj != nullptr) {
if (src_obj != nullptr && !src_klass->is_inline_klass()) {
intptr_t src_hash = src_obj->identity_hash();
mw = mw.copy_set_hash(src_hash);
}
Expand Down
6 changes: 1 addition & 5 deletions src/hotspot/share/cds/cdsConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void CDSConfig::ergo_init_classic_archive_paths() {
}

void CDSConfig::check_internal_module_property(const char* key, const char* value) {
if (Arguments::is_incompatible_cds_internal_module_property(key) && !Arguments::patching_migrated_classes(key, value)) {
if (Arguments::is_incompatible_cds_internal_module_property(key)) {
stop_using_optimized_module_handling();
aot_log_info(aot)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
}
Expand Down Expand Up @@ -975,10 +975,6 @@ bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() {
}

bool CDSConfig::is_dumping_heap() {
if (is_valhalla_preview()) {
// Not working yet -- e.g., HeapShared::oop_hash() needs to be implemented for value oops
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see an implementation of HeapShared::oop_hash() for value oops in this PR. Can you point me at it or is this comment outdated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is something that doesn't work that for some reason I didn't run into on Friday.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It wasn't the oop_hash() reason that something didn't work, it was the wrong prototype header.

return false;
}
if (!(is_dumping_classic_static_archive() || is_dumping_final_static_archive())
|| are_vm_options_incompatible_with_dumping_heap()
|| _disable_heap_dumping) {
Expand Down
6 changes: 0 additions & 6 deletions src/hotspot/share/cds/heapShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2261,12 +2261,6 @@ void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
ArchivableStaticFieldInfo* info = &fields[i];
const char* klass_name = info->klass_name;

if (CDSConfig::is_valhalla_preview() && strcmp(klass_name, "jdk/internal/module/ArchivedModuleGraph") == 0) {
// FIXME -- ArchivedModuleGraph doesn't work when java.base is patched with valhalla classes.
i++;
continue;
}

start_recording_subgraph(info->klass, klass_name, is_full_module_graph);

// If you have specified consecutive fields of the same klass in
Expand Down
10 changes: 9 additions & 1 deletion src/hotspot/share/classfile/systemDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,15 @@ ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool cre
bool created = false;
ClassLoaderData* cld = ClassLoaderDataGraph::find_or_create(class_loader, created);
if (created && Arguments::enable_preview()) {
add_migrated_value_classes(cld);
if (CDSConfig::is_using_aot_linked_classes() && java_system_loader() == nullptr) {
// We are inside AOTLinkedClassBulkLoader::preload_classes().
//
// AOTLinkedClassBulkLoader will automatically initiate the loading of all archived
// public classes from the boot loader into platform/system loaders, so there's
// no need to call add_migrated_value_classes().
} else {
add_migrated_value_classes(cld);
}
}
return cld;
}
Expand Down
33 changes: 18 additions & 15 deletions src/hotspot/share/oops/flatArrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,25 +403,11 @@ void FlatArrayKlass::print_value_on(outputStream* st) const {
st->print("[]");
}


#ifndef PRODUCT
void FlatArrayKlass::oop_print_on(oop obj, outputStream* st) {
ArrayKlass::oop_print_on(obj, st);
flatArrayOop va = flatArrayOop(obj);
InlineKlass* vk = element_klass();
int print_len = MIN2(va->length(), MaxElementPrintSize);
for(int index = 0; index < print_len; index++) {
int off = (address) va->value_at_addr(index, layout_helper()) - cast_from_oop<address>(obj);
st->print_cr(" - Index %3d offset %3d: ", index, off);
oop obj = cast_to_oop((address)va->value_at_addr(index, layout_helper()) - vk->payload_offset());
FieldPrinter print_field(st, obj);
vk->do_nonstatic_fields(&print_field);
st->cr();
}
int remaining = va->length() - print_len;
if (remaining > 0) {
st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
}
oop_print_elements_on(va, st);
}
#endif //PRODUCT

Expand All @@ -445,6 +431,23 @@ void FlatArrayKlass::oop_print_value_on(oop obj, outputStream* st) {
}
}

void FlatArrayKlass::oop_print_elements_on(flatArrayOop fa, outputStream* st) {
InlineKlass* vk = element_klass();
int print_len = MIN2(fa->length(), MaxElementPrintSize);
for(int index = 0; index < print_len; index++) {
int off = (address) fa->value_at_addr(index, layout_helper()) - cast_from_oop<address>(fa);
st->print_cr(" - Index %3d offset %3d: ", index, off);
oop obj = cast_to_oop((address)fa->value_at_addr(index, layout_helper()) - vk->payload_offset());
FieldPrinter print_field(st, obj);
vk->do_nonstatic_fields(&print_field);
st->cr();
}
int remaining = fa->length() - print_len;
if (remaining > 0) {
st->print_cr(" - <%d more elements, increase MaxElementPrintSize to print>", remaining);
}
}

// Verification
class VerifyElementClosure: public BasicOopIterateClosure {
public:
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/oops/flatArrayKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class FlatArrayKlass : public ObjArrayKlass {
#ifndef PRODUCT
void oop_print_on(oop obj, outputStream* st);
#endif
void oop_print_elements_on(flatArrayOop fa, outputStream* st);

// Verification
void verify_on(outputStream* st);
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/oops/objArrayOop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class objArrayOopDesc : public arrayOopDesc {
friend class Continuation;
template <typename T>
friend class RawOopWriter;
friend class AOTMapLogger;

template <class T> T* obj_at_addr(int index) const;

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/oops/refArrayOop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class refArrayOopDesc : public arrayOopDesc {
friend class Continuation;
template <typename T>
friend class RawOopWriter;
friend class AOTMapLogger;

template <class T> T* obj_at_addr(int index) const;

Expand Down
14 changes: 1 addition & 13 deletions src/hotspot/share/runtime/arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,18 +364,6 @@ bool Arguments::internal_module_property_helper(const char* property, bool check
return false;
}

bool Arguments::patching_migrated_classes(const char* property, const char* value) {
if (strncmp(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) == 0) {
const char* property_suffix = property + MODULE_PROPERTY_PREFIX_LEN;
if (matches_property_suffix(property_suffix, PATCH, PATCH_LEN)) {
if (strcmp(value, "java.base-valueclasses.jar")) {
return true;
}
}
}
return false;
}

// Process java launcher properties.
void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
// See if sun.java.launcher is defined.
Expand Down Expand Up @@ -2092,7 +2080,7 @@ int Arguments::process_patch_mod_option(const char* patch_mod_tail) {
// Temporary system property to disable preview patching and enable the new preview mode
// feature for testing/development. Once the preview mode feature is finished, the value
// will be always 'true' and this code, and all related dead-code can be removed.
#define DISABLE_PREVIEW_PATCHING_DEFAULT false
#define DISABLE_PREVIEW_PATCHING_DEFAULT true

bool Arguments::disable_preview_patching() {
const char* prop = get_property("DISABLE_PREVIEW_PATCHING");
Expand Down
1 change: 0 additions & 1 deletion src/hotspot/share/runtime/arguments.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ class Arguments : AllStatic {

static bool is_internal_module_property(const char* option);
static bool is_incompatible_cds_internal_module_property(const char* property);
static bool patching_migrated_classes(const char* property, const char* value);

// Miscellaneous System property value getter and setters.
static void set_dll_dir(const char *value) { _sun_boot_library_path->set_value(value); }
Expand Down
14 changes: 14 additions & 0 deletions src/hotspot/share/runtime/sharedRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2928,6 +2928,19 @@ void CompiledEntrySignature::compute_calling_conventions(bool init) {
GrowableArray<Method*>* supers = get_supers();
for (int i = 0; i < supers->length(); ++i) {
Method* super_method = supers->at(i);
if (AOTCodeCache::is_using_adapter() && super_method->adapter()->get_sig_cc() == nullptr) {
// Calling conventions have to be regenerated at runtime and are accessed through method adapters,
// which are archived in the AOT code cache. If the adapters are not regenerated, the
// calling conventions should be regenerated here.
CompiledEntrySignature ces(super_method);
ces.compute_calling_conventions();
if (ces.has_scalarized_args()) {
// Save a C heap allocated version of the scalarized signature and store it in the adapter
GrowableArray<SigEntry>* heap_sig = new (mtInternal) GrowableArray<SigEntry>(ces.sig_cc()->length(), mtInternal);
heap_sig->appendAll(ces.sig_cc());
super_method->adapter()->set_sig_cc(heap_sig);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand (yet) why the scalarized versions aren't already archived as part of the existing adapter archiving. Getting them saved/restored in the archive seems like the best approach, with this being a work around until that's sorted

Copy link
Contributor

Choose a reason for hiding this comment

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

We explicitly null out the _sig_cc from the archived adapters in AdapterHandlerEntry::remove_unshareable_info as _sig_cc is a new Valhalla thing. It's possible for it to be added to the AOTCache, but we just haven't done the work to save / restore the arrays of SigEntries.

Opened https://bugs.openjdk.org/browse/JDK-8373348 a reminder to update the AOTCache support later

}
}
if (super_method->is_scalarized_arg(arg_num)) {
scalar_super = true;
} else {
Expand Down Expand Up @@ -3382,6 +3395,7 @@ void AdapterHandlerEntry::remove_unshareable_info() {
#endif // ASSERT
_adapter_blob = nullptr;
_linked = false;
_sig_cc = nullptr;
}

class CopyAdapterTableToArchive : StackObj {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public boolean isPreviewModeEnabled() {
// Temporary system property to disable preview patching and enable the new preview mode
// feature for testing/development. Once the preview mode feature is finished, the value
// will be always 'true' and this code, and all related dead-code can be removed.
private static final boolean DISABLE_PREVIEW_PATCHING_DEFAULT = false;
private static final boolean DISABLE_PREVIEW_PATCHING_DEFAULT = true;
private static final boolean DISABLE_PREVIEW_PATCHING = Boolean.parseBoolean(
System.getProperty(
"DISABLE_PREVIEW_PATCHING",
Expand Down
14 changes: 7 additions & 7 deletions test/hotspot/jtreg/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ runtime/cds/TestDefaultArchiveLoading.java#coops_nocoh 8366774
runtime/cds/TestDefaultArchiveLoading.java#nocoops_nocoh 8366774 generic-all

# Valhalla + AOT
runtime/cds/appcds/aotCache/HelloAOTCache.java 8369043 generic-aarch64
runtime/cds/appcds/aotCode/AOTCodeFlags.java 8369043 generic-aarch64
runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java#aot 8367408 generic-all
runtime/cds/appcds/resolvedConstants/ResolvedConstants.java#aot 8371456 generic-all
runtime/cds/appcds/resolvedConstants/ResolvedConstants.java#static 8371456 generic-all
runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java 8372265 generic-all
runtime/cds/appcds/dynamicArchive/HelloDynamicInlineClass.java 8372265 generic-all
# runtime/cds/appcds/aotCache/HelloAOTCache.java 8369043 generic-aarch64
# runtime/cds/appcds/aotCode/AOTCodeFlags.java 8369043 generic-aarch64
# runtime/cds/appcds/methodHandles/MethodHandlesGeneralTest.java#aot 8367408 generic-all
# runtime/cds/appcds/resolvedConstants/ResolvedConstants.java#aot 8371456 generic-all
# runtime/cds/appcds/resolvedConstants/ResolvedConstants.java#static 8371456 generic-all
# runtime/cds/appcds/dynamicArchive/DynamicArchiveRelocationTest.java 8372265 generic-all
# runtime/cds/appcds/dynamicArchive/HelloDynamicInlineClass.java 8372265 generic-all
#############################################################################

# :hotspot_serviceability
Expand Down
4 changes: 4 additions & 0 deletions test/lib/jdk/test/lib/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ public static String[] getTestJavaOpts() {
List<String> opts = new ArrayList<String>();
Collections.addAll(opts, safeSplitString(VM_OPTIONS));
Collections.addAll(opts, safeSplitString(JAVA_OPTIONS));
String preview = System.getProperty("test.enable.preview", "");
if (preview.equals("true")) {
Collections.addAll(opts, "--enable-preview");
}
return opts.toArray(new String[0]);
}

Expand Down
Loading