diff --git a/make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java b/make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java index 630d3a390d18a..426d0bb10ede1 100644 --- a/make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java +++ b/make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, 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 @@ -273,7 +273,7 @@ private void outputFile(Path dstFile, String version, // link version-region-rules out.writeShort(builtZones.size()); for (Map.Entry entry : builtZones.entrySet()) { - int regionIndex = Arrays.binarySearch(regionArray, entry.getKey()); + int regionIndex = findRegionIndex(regionArray, entry.getKey()); int rulesIndex = rulesList.indexOf(entry.getValue()); out.writeShort(regionIndex); out.writeShort(rulesIndex); @@ -281,8 +281,8 @@ private void outputFile(Path dstFile, String version, // alias-region out.writeShort(links.size()); for (Map.Entry entry : links.entrySet()) { - int aliasIndex = Arrays.binarySearch(regionArray, entry.getKey()); - int regionIndex = Arrays.binarySearch(regionArray, entry.getValue()); + int aliasIndex = findRegionIndex(regionArray, entry.getKey()); + int regionIndex = findRegionIndex(regionArray, entry.getValue()); out.writeShort(aliasIndex); out.writeShort(regionIndex); } @@ -294,6 +294,14 @@ private void outputFile(Path dstFile, String version, } } + private static int findRegionIndex(String[] regionArray, String region) { + int index = Arrays.binarySearch(regionArray, region); + if (index < 0) { + throw new IllegalArgumentException("Unknown region: " + region); + } + return index; + } + /** Whether to output verbose messages. */ private boolean verbose; diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 1b02108b00f94..52996f4c4a503 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -2234,7 +2234,7 @@ void SharedRuntime::generate_deopt_blob() { int reexecute_offset = __ pc() - start; #if INCLUDE_JVMCI && !defined(COMPILER1) - if (EnableJVMCI && UseJVMCICompiler) { + if (UseJVMCICompiler) { // JVMCI does not use this kind of deoptimization __ should_not_reach_here(); } diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 612b7bf898c08..ca9abfa3719b4 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -6598,7 +6598,7 @@ instruct encodeP_not_null_Ex(iRegNdst dst, iRegPsrc src) %{ instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{ match(Set dst (EncodeP src)); predicate(CompressedOops::shift() != 0 && - CompressedOops::base() ==0); + CompressedOops::base() == nullptr); format %{ "SRDI $dst, $src, #3 \t// encodeP, $src != nullptr" %} size(4); @@ -6695,7 +6695,7 @@ instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ predicate((n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant) && CompressedOops::shift() != 0 && - CompressedOops::base() != 0); + CompressedOops::base() != nullptr); ins_cost(4 * DEFAULT_COST); // Should be more expensive than decodeN_Disjoint_isel_Ex. effect(TEMP crx); @@ -6707,7 +6707,7 @@ instruct decodeN_Ex(iRegPdst dst, iRegNsrc src, flagsReg crx) %{ instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{ match(Set dst (DecodeN src)); predicate(CompressedOops::shift() != 0 && - CompressedOops::base() == 0); + CompressedOops::base() == nullptr); format %{ "SLDI $dst, $src, #3 \t// DecodeN (zerobased)" %} size(4); @@ -6825,7 +6825,7 @@ instruct decodeN_notNull_addBase_Ex(iRegPdst dst, iRegNsrc src) %{ predicate((n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant) && CompressedOops::shift() != 0 && - CompressedOops::base() != 0); + CompressedOops::base() != nullptr); ins_cost(2 * DEFAULT_COST); format %{ "DecodeN $dst, $src \t// $src != nullptr, postalloc expanded" %} diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index 879fd92272279..27da26d404cc0 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -2110,7 +2110,7 @@ void SharedRuntime::generate_deopt_blob() { int reexecute_offset = __ pc() - start; #if INCLUDE_JVMCI && !defined(COMPILER1) - if (EnableJVMCI && UseJVMCICompiler) { + if (UseJVMCICompiler) { // JVMCI does not use this kind of deoptimization __ should_not_reach_here(); } diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index 4de1a4e7b7f35..1bc9484215005 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -4628,7 +4628,7 @@ instruct encodeP(iRegN dst, iRegP src, flagsReg cr) %{ match(Set dst (EncodeP src)); effect(KILL cr); predicate((n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull) && - (CompressedOops::base() == 0 || + (CompressedOops::base() == nullptr || CompressedOops::base_disjoint() || !ExpandLoadingBaseEncode)); ins_cost(MEMORY_REF_COST+3 * DEFAULT_COST); @@ -4651,7 +4651,7 @@ instruct encodeP_NN(iRegN dst, iRegP src, flagsReg cr) %{ match(Set dst (EncodeP src)); effect(KILL cr); predicate((n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull) && - (CompressedOops::base() == 0 || + (CompressedOops::base() == nullptr || CompressedOops::base_disjoint() || !ExpandLoadingBaseEncode_NN)); ins_cost(MEMORY_REF_COST+3 * DEFAULT_COST); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index 4bd91f640fca7..174e2e0277903 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -2674,7 +2674,7 @@ void SharedRuntime::generate_deopt_blob() { int reexecute_offset = __ pc() - start; #if INCLUDE_JVMCI && !defined(COMPILER1) - if (EnableJVMCI && UseJVMCICompiler) { + if (UseJVMCICompiler) { // JVMCI does not use this kind of deoptimization __ should_not_reach_here(); } diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index f8d24295a12e5..694a179d7ee6c 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -508,7 +508,9 @@ InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); } - InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL); + ResourceMark rm; + char * source_path = os::strdup_check_oom(ClassLoader::uri_to_path(_source)); + InstanceKlass* k = UnregisteredClasses::load_class(class_name, source_path, CHECK_NULL); if (k->local_interfaces()->length() != _interfaces->length()) { print_specified_interfaces(); print_actual_interfaces(k); diff --git a/src/hotspot/share/cds/classListWriter.cpp b/src/hotspot/share/cds/classListWriter.cpp index 78cd092445b70..1b9f589f1c5e5 100644 --- a/src/hotspot/share/cds/classListWriter.cpp +++ b/src/hotspot/share/cds/classListWriter.cpp @@ -174,6 +174,8 @@ void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stre } } + // NB: the string following "source: " is not really a proper file name, but rather + // a truncated URI referring to a file. It must be decoded after reading. #ifdef _WINDOWS // "file:/C:/dir/foo.jar" -> "C:/dir/foo.jar" stream->print(" source: %s", cfs->source() + 6); diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index c935541d7cf0a..78613ae4b36c4 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -581,7 +581,7 @@ int FileMapInfo::get_module_shared_path_index(Symbol* location) { // skip_uri_protocol was also called during dump time -- see ClassLoaderExt::process_module_table() ResourceMark rm; - const char* file = ClassLoader::skip_uri_protocol(location->as_C_string()); + const char* file = ClassLoader::uri_to_path(location->as_C_string()); for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) { SharedClassPathEntry* ent = shared_path(i); if (!ent->is_non_existent()) { diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 5309fcd20a8be..487d69a6f4fc9 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -81,6 +81,9 @@ #include "utilities/ostream.hpp" #include "utilities/utf8.hpp" +#include +#include + // Entry point in java.dll for path canonicalization typedef int (*canonicalize_fn_t)(const char *orig, char *out, int len); @@ -1209,7 +1212,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, PackageEntry* pkg_entry, bo } #if INCLUDE_CDS -char* ClassLoader::skip_uri_protocol(char* source) { +static const char* skip_uri_protocol(const char* source) { if (strncmp(source, "file:", 5) == 0) { // file: protocol path could start with file:/ or file:/// // locate the char after all the forward slashes @@ -1228,6 +1231,47 @@ char* ClassLoader::skip_uri_protocol(char* source) { return source; } +static char decode_percent_encoded(const char *str, size_t& index) { + if (str[index] == '%' + && isxdigit(str[index + 1]) + && isxdigit(str[index + 2])) { + char hex[3]; + hex[0] = str[index + 1]; + hex[1] = str[index + 2]; + hex[2] = '\0'; + index += 2; + return (char) strtol(hex, NULL, 16); + } + return str[index]; +} + +char* ClassLoader::uri_to_path(const char* uri) { + const size_t len = strlen(uri) + 1; + char* path = NEW_RESOURCE_ARRAY(char, len); + + uri = skip_uri_protocol(uri); + + if (strncmp(uri, "//", 2) == 0) { + // Skip the empty "authority" part + uri += 2; + } + +#ifdef _WINDOWS + if (uri[0] == '/') { + // Absolute path name on Windows does not begin with a slash + uri += 1; + } +#endif + + size_t path_index = 0; + for (size_t i = 0; i < strlen(uri); ++i) { + char decoded = decode_percent_encoded(uri, i); + path[path_index++] = decoded; + } + path[path_index] = '\0'; + return path; +} + // Record the shared classpath index and loader type for classes loaded // by the builtin loaders at dump time. void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, @@ -1261,7 +1305,7 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, // Save the path from the file: protocol or the module name from the jrt: protocol // if no protocol prefix is found, path is the same as stream->source(). This path // must be valid since the class has been successfully parsed. - char* path = skip_uri_protocol(src); + const char* path = ClassLoader::uri_to_path(src); assert(path != nullptr, "sanity"); for (int i = 0; i < FileMapInfo::get_number_of_shared_paths(); i++) { SharedClassPathEntry* ent = FileMapInfo::shared_path(i); diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index af625082ddabf..e44059b724769 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -382,7 +382,7 @@ class ClassLoader: AllStatic { // entries during shared classpath setup time. static int num_module_path_entries(); static void exit_with_path_failure(const char* error, const char* message); - static char* skip_uri_protocol(char* source); + static char* uri_to_path(const char* uri); static void record_result(JavaThread* current, InstanceKlass* ik, const ClassFileStream* stream, bool redefined); #endif diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp index 3cd7dd7cd3ba6..997f9d76676fa 100644 --- a/src/hotspot/share/classfile/classLoaderExt.cpp +++ b/src/hotspot/share/classfile/classLoaderExt.cpp @@ -100,12 +100,10 @@ void ClassLoaderExt::process_module_table(JavaThread* current, ModuleEntryTable* ModulePathsGatherer(JavaThread* current, GrowableArray* module_paths) : _current(current), _module_paths(module_paths) {} void do_module(ModuleEntry* m) { - char* path = m->location()->as_C_string(); - if (strncmp(path, "file:", 5) == 0) { - path = ClassLoader::skip_uri_protocol(path); - char* path_copy = NEW_RESOURCE_ARRAY(char, strlen(path) + 1); - strcpy(path_copy, path); - _module_paths->append(path_copy); + char* uri = m->location()->as_C_string(); + if (strncmp(uri, "file:", 5) == 0) { + char* path = ClassLoader::uri_to_path(uri); + _module_paths->append(path); } } }; diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index b6ef682ae0965..0ad36cd21dbf3 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -3052,9 +3052,10 @@ void java_lang_ClassFrameInfo::serialize_offsets(SerializeClosure* f) { static int get_flags(const methodHandle& m) { int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); - if (m->is_initializer()) { + if (m->is_object_initializer()) { flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR; } else { + // Note: Static initializers can be here. Record them as plain methods. flags |= java_lang_invoke_MemberName::MN_IS_METHOD; } if (m->caller_sensitive()) { diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index bcddddc0c7c78..7b307a0b8a37c 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1069,7 +1069,7 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta } Klass *found = resolve_with_circularity_detection(klass->name(), super_type->name(), - class_loader, protection_domain, is_superclass, CHECK_0); + class_loader, protection_domain, is_superclass, CHECK_false); if (found == super_type) { return true; } else { @@ -1088,16 +1088,21 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle // If unexpected superclass or interfaces are found, we cannot // load from the shared archive. - if (ik->super() != nullptr && - !check_shared_class_super_type(ik, InstanceKlass::cast(ik->super()), - class_loader, protection_domain, true, THREAD)) { - return false; + if (ik->super() != nullptr) { + bool check_super = check_shared_class_super_type(ik, InstanceKlass::cast(ik->super()), + class_loader, protection_domain, true, + CHECK_false); + if (!check_super) { + return false; + } } Array* interfaces = ik->local_interfaces(); int num_interfaces = interfaces->length(); for (int index = 0; index < num_interfaces; index++) { - if (!check_shared_class_super_type(ik, interfaces->at(index), class_loader, protection_domain, false, THREAD)) { + bool check_interface = check_shared_class_super_type(ik, interfaces->at(index), class_loader, protection_domain, false, + CHECK_false); + if (!check_interface) { return false; } } @@ -1153,7 +1158,8 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik, return nullptr; } - if (!check_shared_class_super_types(ik, class_loader, protection_domain, THREAD)) { + bool check = check_shared_class_super_types(ik, class_loader, protection_domain, CHECK_NULL); + if (!check) { ik->set_shared_loading_failed(); return nullptr; } diff --git a/src/hotspot/share/compiler/oopMap.inline.hpp b/src/hotspot/share/compiler/oopMap.inline.hpp index f2a3b3ba834df..05ef53f823142 100644 --- a/src/hotspot/share/compiler/oopMap.inline.hpp +++ b/src/hotspot/share/compiler/oopMap.inline.hpp @@ -66,12 +66,10 @@ void OopMapDo::iterate_oops_do(const frame continue; #ifndef COMPILER2 - COMPILER1_PRESENT(ShouldNotReachHere();) #if INCLUDE_JVMCI - if (UseJVMCICompiler) { - ShouldNotReachHere(); - } + if (!EnableJVMCI) #endif + ShouldNotReachHere(); #endif // !COMPILER2 address loc = fr->oopmapreg_to_location(omv.reg(), reg_map); diff --git a/src/hotspot/share/gc/shared/oopStorageSet.cpp b/src/hotspot/share/gc/shared/oopStorageSet.cpp index c6947590d96fb..e3a9fccbad3dc 100644 --- a/src/hotspot/share/gc/shared/oopStorageSet.cpp +++ b/src/hotspot/share/gc/shared/oopStorageSet.cpp @@ -86,7 +86,9 @@ bool OopStorageSet::print_containing(const void* addr, outputStream* st) { if (addr != nullptr) { const void* aligned_addr = align_down(addr, alignof(oop)); for (OopStorage* storage : Range()) { - if (storage->print_containing((oop*) aligned_addr, st)) { + // Check for null for extra safety: might get here while handling error + // before storage initialization. + if ((storage != nullptr) && storage->print_containing((oop*) aligned_addr, st)) { if (aligned_addr != addr) { st->print_cr(" (unaligned)"); } else { diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp index 36740560dd23f..2ae38044df0ff 100644 --- a/src/hotspot/share/jvmci/jvmci_globals.cpp +++ b/src/hotspot/share/jvmci/jvmci_globals.cpp @@ -26,6 +26,7 @@ #include "compiler/compilerDefinitions.hpp" #include "gc/shared/gcConfig.hpp" #include "jvm.h" +#include "jvmci/jvmci.hpp" #include "jvmci/jvmci_globals.hpp" #include "logging/log.hpp" #include "runtime/arguments.hpp" @@ -90,8 +91,7 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() { if (EnableJVMCI) { if (FLAG_IS_DEFAULT(UseJVMCINativeLibrary) && !UseJVMCINativeLibrary) { - char path[JVM_MAXPATHLEN]; - if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) { + if (JVMCI::shared_library_exists()) { // If a JVMCI native library is present, // we enable UseJVMCINativeLibrary by default. FLAG_SET_DEFAULT(UseJVMCINativeLibrary, true); diff --git a/src/hotspot/share/jvmci/jvmci_globals.hpp b/src/hotspot/share/jvmci/jvmci_globals.hpp index 30f2e6c2c73e0..d6f9ddd6739d4 100644 --- a/src/hotspot/share/jvmci/jvmci_globals.hpp +++ b/src/hotspot/share/jvmci/jvmci_globals.hpp @@ -45,7 +45,7 @@ class fileStream; constraint) \ \ product(bool, EnableJVMCI, false, EXPERIMENTAL, \ - "Enable JVMCI") \ + "Enable JVMCI. Defaults to true if UseJVMCICompiler is true.") \ \ product(bool, UseGraalJIT, false, EXPERIMENTAL, \ "Select the Graal JVMCI compiler. This is an alias for: " \ @@ -140,8 +140,8 @@ class fileStream; product(bool, UseJVMCINativeLibrary, false, EXPERIMENTAL, \ "Execute JVMCI Java code from a shared library (\"libjvmci\") " \ "instead of loading it from class files and executing it " \ - "on the HotSpot heap. Defaults to true if EnableJVMCI is " \ - "true and a JVMCI native library is available.") \ + "on the HotSpot heap. Defaults to true if UseJVMCICompiler or " \ + "EnableJVMCI is true and a JVMCI native library is available.") \ \ product(double, JVMCINativeLibraryThreadFraction, 0.33, EXPERIMENTAL, \ "The fraction of compiler threads used by libjvmci. " \ diff --git a/src/hotspot/share/oops/compressedOops.cpp b/src/hotspot/share/oops/compressedOops.cpp index 98a4438383a79..ec41dd8521918 100644 --- a/src/hotspot/share/oops/compressedOops.cpp +++ b/src/hotspot/share/oops/compressedOops.cpp @@ -61,7 +61,7 @@ void CompressedOops::initialize(const ReservedHeapSpace& heap_space) { } if ((uint64_t)heap_space.end() <= OopEncodingHeapMax) { // Did reserve heap below 32Gb. Can use base == 0; - set_base(0); + set_base(nullptr); } else { set_base((address)heap_space.compressed_oop_base()); } @@ -115,7 +115,7 @@ CompressedOops::Mode CompressedOops::mode() { return DisjointBaseNarrowOop; } - if (base() != 0) { + if (base() != nullptr) { return HeapBasedNarrowOop; } @@ -166,7 +166,7 @@ void CompressedOops::print_mode(outputStream* st) { st->print(", Compressed Oops mode: %s", mode_to_string(mode())); - if (base() != 0) { + if (base() != nullptr) { st->print(": " PTR_FORMAT, p2i(base())); } diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 1f115c783e6d7..a869e9821a0b2 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -444,9 +444,11 @@ JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID meth methodHandle m (THREAD, Method::resolve_jmethod_id(method_id)); assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match"); oop reflection_method; - if (m->is_initializer()) { + if (m->is_object_initializer()) { reflection_method = Reflection::new_constructor(m, CHECK_NULL); } else { + // Note: Static initializers can theoretically be here, if JNI users manage + // to get their jmethodID. Record them as plain methods. reflection_method = Reflection::new_method(m, false, CHECK_NULL); } ret = JNIHandles::make_local(THREAD, reflection_method); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index bf9874956bae2..a246c2c50d674 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1826,14 +1826,6 @@ JVM_ENTRY(jobjectArray, JVM_GetRecordComponents(JNIEnv* env, jclass ofClass)) } JVM_END -static bool select_method(const methodHandle& method, bool want_constructor) { - if (want_constructor) { - return (method->is_initializer() && !method->is_static()); - } else { - return (!method->is_initializer() && !method->is_overpass()); - } -} - static jobjectArray get_class_declared_methods_helper( JNIEnv *env, jclass ofClass, jboolean publicOnly, @@ -1866,14 +1858,22 @@ static jobjectArray get_class_declared_methods_helper( GrowableArray* idnums = new GrowableArray(methods_length); int num_methods = 0; + // Select methods matching the criteria. for (int i = 0; i < methods_length; i++) { - methodHandle method(THREAD, methods->at(i)); - if (select_method(method, want_constructor)) { - if (!publicOnly || method->is_public()) { - idnums->push(method->method_idnum()); - ++num_methods; - } + Method* method = methods->at(i); + if (want_constructor && !method->is_object_initializer()) { + continue; + } + if (!want_constructor && + (method->is_object_initializer() || method->is_static_initializer() || + method->is_overpass())) { + continue; } + if (publicOnly && !method->is_public()) { + continue; + } + idnums->push(method->method_idnum()); + ++num_methods; } // Allocate result @@ -2175,10 +2175,11 @@ static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bo THROW_MSG_NULL(vmSymbols::java_lang_RuntimeException(), "Unable to look up method in target class"); } oop method; - if (!m->is_initializer() || m->is_static()) { - method = Reflection::new_method(m, true, CHECK_NULL); - } else { + if (m->is_object_initializer()) { method = Reflection::new_constructor(m, CHECK_NULL); + } else { + // new_method accepts as Method here + method = Reflection::new_method(m, true, CHECK_NULL); } return JNIHandles::make_local(THREAD, method); } diff --git a/src/hotspot/share/prims/methodHandles.cpp b/src/hotspot/share/prims/methodHandles.cpp index 4f33055d6a3fe..498da559cf526 100644 --- a/src/hotspot/share/prims/methodHandles.cpp +++ b/src/hotspot/share/prims/methodHandles.cpp @@ -313,8 +313,9 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { case CallInfo::direct_call: vmindex = Method::nonvirtual_vtable_index; if (m->is_static()) { + assert(!m->is_static_initializer(), "Cannot be static initializer"); flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); - } else if (m->is_initializer()) { + } else if (m->is_object_initializer()) { flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); } else { // "special" reflects that this is a direct call, not that it diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 7961e56598f25..2006f340450e5 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -447,7 +447,7 @@ bool Deoptimization::deoptimize_objects_internal(JavaThread* thread, GrowableArr RegisterMap map(chunk->at(0)->register_map()); bool deoptimized_objects = false; - bool const jvmci_enabled = JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false); + bool const jvmci_enabled = JVMCI_ONLY(EnableJVMCI) NOT_JVMCI(false); // Reallocate the non-escaping objects and restore their fields. if (jvmci_enabled COMPILER2_PRESENT(|| (DoEscapeAnalysis && EliminateAllocations) diff --git a/src/hotspot/share/runtime/escapeBarrier.hpp b/src/hotspot/share/runtime/escapeBarrier.hpp index df32deef98639..454e0b555e118 100644 --- a/src/hotspot/share/runtime/escapeBarrier.hpp +++ b/src/hotspot/share/runtime/escapeBarrier.hpp @@ -71,7 +71,7 @@ class EscapeBarrier : StackObj { // Revert ea based optimizations for given deoptee thread EscapeBarrier(bool barrier_active, JavaThread* calling_thread, JavaThread* deoptee_thread) : _calling_thread(calling_thread), _deoptee_thread(deoptee_thread), - _barrier_active(barrier_active && (JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false) + _barrier_active(barrier_active && (JVMCI_ONLY(EnableJVMCI) NOT_JVMCI(false) COMPILER2_PRESENT(|| DoEscapeAnalysis))) { if (_barrier_active) sync_and_suspend_one(); @@ -80,7 +80,7 @@ class EscapeBarrier : StackObj { // Revert ea based optimizations for all java threads EscapeBarrier(bool barrier_active, JavaThread* calling_thread) : _calling_thread(calling_thread), _deoptee_thread(nullptr), - _barrier_active(barrier_active && (JVMCI_ONLY(UseJVMCICompiler) NOT_JVMCI(false) + _barrier_active(barrier_active && (JVMCI_ONLY(EnableJVMCI) NOT_JVMCI(false) COMPILER2_PRESENT(|| DoEscapeAnalysis))) { if (_barrier_active) sync_and_suspend_all(); diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index ab3d82ad7e2a4..15172b7f4c3d8 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -766,10 +766,10 @@ static Handle new_type(Symbol* signature, Klass* k, TRAPS) { } oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) { - // Allow sun.reflect.ConstantPool to refer to methods as java.lang.reflect.Methods. - assert(!method()->is_initializer() || - (for_constant_pool_access && method()->is_static()), - "should call new_constructor instead"); + // Allow jdk.internal.reflect.ConstantPool to refer to methods as java.lang.reflect.Methods. + assert(!method()->is_object_initializer() && + (for_constant_pool_access || !method()->is_static_initializer()), + "Should not be the initializer"); InstanceKlass* holder = method->method_holder(); int slot = method->method_idnum(); @@ -817,7 +817,7 @@ oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_ac oop Reflection::new_constructor(const methodHandle& method, TRAPS) { - assert(method()->is_initializer(), "should call new_method instead"); + assert(method()->is_object_initializer(), "Should be the initializer"); InstanceKlass* holder = method->method_holder(); int slot = method->method_idnum(); diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index d9b38133f9944..6ca7f42e038f5 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -651,7 +651,7 @@ void SharedRuntime::throw_and_post_jvmti_exception(JavaThread* current, Handle h } #if INCLUDE_JVMCI - if (EnableJVMCI && UseJVMCICompiler) { + if (EnableJVMCI) { vframeStream vfst(current, true); methodHandle method = methodHandle(current, vfst.method()); int bci = vfst.bci(); diff --git a/src/java.base/macosx/native/libjli/java_md_macosx.m b/src/java.base/macosx/native/libjli/java_md_macosx.m index c5e7ba580a503..d8742aa1204d5 100644 --- a/src/java.base/macosx/native/libjli/java_md_macosx.m +++ b/src/java.base/macosx/native/libjli/java_md_macosx.m @@ -297,6 +297,7 @@ static void ParkEventLoop() { static void MacOSXStartup(int argc, char *argv[]) { // Thread already started? static jboolean started = false; + int rc; if (started) { return; } @@ -309,12 +310,14 @@ static void MacOSXStartup(int argc, char *argv[]) { // Fire up the main thread pthread_t main_thr; - if (pthread_create(&main_thr, NULL, &apple_main, &args) != 0) { - JLI_ReportErrorMessageSys("Could not create main thread: %s\n", strerror(errno)); + rc = pthread_create(&main_thr, NULL, &apple_main, &args); + if (rc != 0) { + JLI_ReportErrorMessageSys("Could not create main thread, return code: %s\n", rc); exit(1); } - if (pthread_detach(main_thr)) { - JLI_ReportErrorMessageSys("pthread_detach() failed: %s\n", strerror(errno)); + rc = pthread_detach(main_thr); + if (rc != 0) { + JLI_ReportErrorMessage("pthread_detach() failed, return code: %s\n", rc); exit(1); } diff --git a/src/java.base/share/classes/java/io/BufferedInputStream.java b/src/java.base/share/classes/java/io/BufferedInputStream.java index cfc2a3d2c75b9..c401873ce12e4 100644 --- a/src/java.base/share/classes/java/io/BufferedInputStream.java +++ b/src/java.base/share/classes/java/io/BufferedInputStream.java @@ -50,6 +50,11 @@ * reread before new bytes are taken from * the contained input stream. * + * @apiNote + * Once wrapped in a {@code BufferedInputStream}, the underlying + * {@code InputStream} should not be used directly nor wrapped with + * another stream. + * * @author Arthur van Hoff * @since 1.0 */ diff --git a/src/java.base/share/classes/java/io/BufferedOutputStream.java b/src/java.base/share/classes/java/io/BufferedOutputStream.java index ecc1e8a8a4845..687f0c91bc4f7 100644 --- a/src/java.base/share/classes/java/io/BufferedOutputStream.java +++ b/src/java.base/share/classes/java/io/BufferedOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, 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 @@ -35,6 +35,11 @@ * output stream without necessarily causing a call to the underlying * system for each byte written. * + * @apiNote + * Once wrapped in a {@code BufferedOutputStream}, the underlying + * {@code OutputStream} should not be used directly nor wrapped with + * another stream. + * * @author Arthur van Hoff * @since 1.0 */ diff --git a/src/java.base/share/classes/java/io/BufferedReader.java b/src/java.base/share/classes/java/io/BufferedReader.java index 2cd027c8bd8a2..c2f6b89e08622 100644 --- a/src/java.base/share/classes/java/io/BufferedReader.java +++ b/src/java.base/share/classes/java/io/BufferedReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, 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 @@ -43,8 +43,9 @@ * *

In general, each read request made of a Reader causes a corresponding * read request to be made of the underlying character or byte stream. It is - * therefore advisable to wrap a BufferedReader around any Reader whose read() - * operations may be costly, such as FileReaders and InputStreamReaders. For + * therefore advisable to wrap a {@code BufferedReader} around any + * {@code Reader} whose {@code read()} operations may be costly, such as + * {@code FileReader}s and {@code InputStreamReader}s. For * example, * * {@snippet lang=java : @@ -52,12 +53,18 @@ * } * * will buffer the input from the specified file. Without buffering, each - * invocation of read() or readLine() could cause bytes to be read from the - * file, converted into characters, and then returned, which can be very - * inefficient. + * invocation of {@code read()} or {@code readLine()} could cause bytes to be + * read from the file, converted into characters, and then returned, which can + * be very inefficient. * - *

Programs that use DataInputStreams for textual input can be localized by - * replacing each DataInputStream with an appropriate BufferedReader. + *

Programs that use {@code DataInputStream}s for textual input can be + * localized by replacing each {@code DataInputStream} with an appropriate + * {@code BufferedReader}. + * + * @apiNote + * Once wrapped in a {@code BufferedReader}, the underlying + * {@code Reader} should not be used directly nor wrapped with + * another reader. * * @see FileReader * @see InputStreamReader diff --git a/src/java.base/share/classes/java/io/BufferedWriter.java b/src/java.base/share/classes/java/io/BufferedWriter.java index 4904f7180724a..17862a265ae82 100644 --- a/src/java.base/share/classes/java/io/BufferedWriter.java +++ b/src/java.base/share/classes/java/io/BufferedWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, 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 @@ -37,25 +37,31 @@ *

The buffer size may be specified, or the default size may be accepted. * The default is large enough for most purposes. * - *

A newLine() method is provided, which uses the platform's own notion of - * line separator as defined by the system property {@code line.separator}. - * Not all platforms use the newline character ('\n') to terminate lines. - * Calling this method to terminate each output line is therefore preferred to - * writing a newline character directly. + *

A {@code newLine()} method is provided, which uses the platform's own + * notion of line separator as defined by the system property + * {@linkplain System#lineSeparator() line.separator}. Not all platforms use the newline character ('\n') + * to terminate lines. Calling this method to terminate each output line is + * therefore preferred to writing a newline character directly. * - *

In general, a Writer sends its output immediately to the underlying - * character or byte stream. Unless prompt output is required, it is advisable - * to wrap a BufferedWriter around any Writer whose write() operations may be - * costly, such as FileWriters and OutputStreamWriters. For example, + *

In general, a {@code Writer} sends its output immediately to the + * underlying character or byte stream. Unless prompt output is required, it + * is advisable to wrap a {@code BufferedWriter} around any {@code Writer} whose + * {@code write()} operations may be costly, such as {@code FileWriter}s and + * {@code OutputStreamWriter}s. For example, * * {@snippet lang=java : * PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out"))); * } * - * will buffer the PrintWriter's output to the file. Without buffering, each - * invocation of a print() method would cause characters to be converted into - * bytes that would then be written immediately to the file, which can be very - * inefficient. + * will buffer the {@code PrintWriter}'s output to the file. Without buffering, + * each invocation of a {@code print()} method would cause characters to be + * converted into bytes that would then be written immediately to the file, + * which can be very inefficient. + * + * @apiNote + * Once wrapped in a {@code BufferedWriter}, the underlying + * {@code Writer} should not be used directly nor wrapped with + * another writer. * * @see PrintWriter * @see FileWriter diff --git a/src/java.base/share/classes/java/lang/Double.java b/src/java.base/share/classes/java/lang/Double.java index 9b11964d9e6fa..e789a6777175e 100644 --- a/src/java.base/share/classes/java/lang/Double.java +++ b/src/java.base/share/classes/java/lang/Double.java @@ -148,7 +148,7 @@ * relations that can be defined over floating-point values: * *

- *
numerical equality ({@code ==} + *
{@index "numerical equality"} ({@code ==} * operator): (Not an equivalence relation)
*
Two floating-point values represent the same extended real * number. The extended real numbers are the real numbers augmented @@ -158,7 +158,7 @@ * number and is not equal to any value, including itself. *
* - *
bit-wise equivalence:
+ *
{@index "bit-wise equivalence"}:
*
The bits of the two floating-point values are the same. This * equivalence relation for {@code double} values {@code a} and {@code * b} is implemented by the expression @@ -168,7 +168,7 @@ * is distinguished from every other bit pattern encoding a NaN. *
* - *
representation equivalence:
+ *
{@index "representation equivalence"}:
*
The two floating-point values represent the same IEEE 754 * datum. In particular, for {@linkplain #isFinite(double) * finite} values, the sign, {@linkplain Math#getExponent(double) diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java index 7a65046181f00..fccdd697c7238 100644 --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, 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 @@ -63,8 +63,9 @@ *

Implementation note: The implementations of the "bit twiddling" * methods (such as {@link #highestOneBit(int) highestOneBit} and * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are - * based on material from Henry S. Warren, Jr.'s Hacker's - * Delight, (Addison Wesley, 2002). + * based on material from Henry S. Warren, Jr.'s Hacker's + * Delight, (Addison Wesley, 2002) and Hacker's + * Delight, Second Edition, (Pearson Education, 2013). * * @author Lee Boynton * @author Arthur van Hoff @@ -1736,7 +1737,7 @@ public static int reverse(int i) { * compress(expand(x, m), m) == x & compress(m, m) * } *

- * The Sheep And Goats (SAG) operation (see Hacker's Delight, section 7.7) + * The Sheep And Goats (SAG) operation (see Hacker's Delight, Second Edition, section 7.7) * can be implemented as follows: * {@snippet lang="java" : * int compressLeft(int i, int mask) { diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java index ee9533b29eb53..ff34da232f9ab 100644 --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, 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 @@ -63,8 +63,9 @@ *

Implementation note: The implementations of the "bit twiddling" * methods (such as {@link #highestOneBit(long) highestOneBit} and * {@link #numberOfTrailingZeros(long) numberOfTrailingZeros}) are - * based on material from Henry S. Warren, Jr.'s Hacker's - * Delight, (Addison Wesley, 2002). + * based on material from Henry S. Warren, Jr.'s Hacker's + * Delight, (Addison Wesley, 2002) and Hacker's + * Delight, Second Edition, (Pearson Education, 2013). * * @author Lee Boynton * @author Arthur van Hoff @@ -1749,7 +1750,7 @@ public static long reverse(long i) { * compress(expand(x, m), m) == x & compress(m, m) * } *

- * The Sheep And Goats (SAG) operation (see Hacker's Delight, section 7.7) + * The Sheep And Goats (SAG) operation (see Hacker's Delight, Second Edition, section 7.7) * can be implemented as follows: * {@snippet lang="java" : * long compressLeft(long i, long mask) { diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index d9813df57a4f0..7909f05304268 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -109,7 +109,7 @@ public Object() {} /** * Indicates whether some other object is "equal to" this one. *

- * The {@code equals} method implements an equivalence relation + * The {@code equals} method implements an {@index "equivalence relation"} * on non-null object references: *

    *
  • It is reflexive: for any non-null reference value diff --git a/src/java.base/unix/native/libjli/java_md_common.c b/src/java.base/unix/native/libjli/java_md_common.c index 511519ae362ff..453d605f71082 100644 --- a/src/java.base/unix/native/libjli/java_md_common.c +++ b/src/java.base/unix/native/libjli/java_md_common.c @@ -243,13 +243,7 @@ JLI_ReportErrorMessage(const char* fmt, ...) { JNIEXPORT void JNICALL JLI_ReportErrorMessageSys(const char* fmt, ...) { va_list vl; - char *emsg; - - /* - * TODO: its safer to use strerror_r but is not available on - * Solaris 8. Until then.... - */ - emsg = strerror(errno); + char *emsg = strerror(errno); if (emsg != NULL) { fprintf(stderr, "%s\n", emsg); } diff --git a/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m b/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m index 66e0c362318d7..e74f8ee50fb04 100644 --- a/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m +++ b/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m @@ -271,11 +271,13 @@ static int isInAquaSession() { SplashCreateThread(Splash * splash) { pthread_t thr; pthread_attr_t attr; - int rc; int rslt = pthread_attr_init(&attr); if (rslt != 0) return; - rc = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); + rslt = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); + if (rslt != 0) { + fprintf(stderr, "Could not create SplashScreen thread, error number:%d\n", rslt); + } pthread_attr_destroy(&attr); } diff --git a/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c b/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c index 5a008d10a482c..e89d813fff460 100644 --- a/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c +++ b/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c @@ -741,7 +741,10 @@ SplashCreateThread(Splash * splash) { int rslt = pthread_attr_init(&attr); if (rslt != 0) return; - pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); + rslt = pthread_create(&thr, &attr, SplashScreenThread, (void *) splash); + if (rslt != 0) { + fprintf(stderr, "Could not create SplashScreen thread, error number:%d\n", rslt); + } pthread_attr_destroy(&attr); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java index a531a987f0d40..0ec72e4ae1cf3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, 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 @@ -870,10 +870,12 @@ private List getFiles(ModulePackage modpkg, private ModuleSymbol findModuleOfPackageName(String packageName) { Name pack = names.fromString(packageName); - for (ModuleSymbol msym : modules.allModules()) { - PackageSymbol p = syms.getPackage(msym, pack); - if (p != null && !p.members().isEmpty()) { - return msym; + if (modules.modulesInitialized()) { + for (ModuleSymbol msym : modules.allModules()) { + PackageSymbol p = syms.getPackage(msym, pack); + if (p != null && !p.members().isEmpty()) { + return msym; + } } } return null; diff --git a/test/hotspot/jtreg/TEST.ROOT b/test/hotspot/jtreg/TEST.ROOT index 74540b6ad45dc..5ed0227068cf6 100644 --- a/test/hotspot/jtreg/TEST.ROOT +++ b/test/hotspot/jtreg/TEST.ROOT @@ -81,7 +81,7 @@ requires.properties= \ vm.jvmti \ vm.graal.enabled \ jdk.hasLibgraal \ - vm.libgraal.enabled \ + vm.libgraal.jit \ vm.compiler1.enabled \ vm.compiler2.enabled \ vm.musl \ diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 101cbe76afdda..4ab4ba68692c1 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -435,6 +435,7 @@ hotspot_cds_only = \ hotspot_appcds_dynamic = \ runtime/cds/appcds/ \ -runtime/cds/appcds/cacheObject \ + -runtime/cds/appcds/complexURI \ -runtime/cds/appcds/customLoader \ -runtime/cds/appcds/dynamicArchive \ -runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java \ diff --git a/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java index fcf48a7a2d775..01b051af8e550 100644 --- a/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java +++ b/test/hotspot/jtreg/runtime/Unsafe/InternalErrorTest.java @@ -147,7 +147,8 @@ public static void test(MappedByteBuffer buffer, Unsafe unsafe, long mapAddr, lo break; case 1: // testing Unsafe.copySwapMemory, trying to access next page after truncation. - unsafe.copySwapMemory(null, mapAddr + pageSize, new byte[4000], 16, 2000, 2); + int destOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET; + unsafe.copySwapMemory(null, mapAddr + pageSize, new byte[4000], destOffset, 2000, 2); break; case 2: // testing Unsafe.copySwapMemory, trying to access next page after truncation. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java new file mode 100644 index 0000000000000..409e37e10a164 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/ComplexURITest.java @@ -0,0 +1,167 @@ +/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024 JetBrains s.r.o. + * 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. + */ + +/* + * @test + * @summary Verifies that CDS works with jar located in directories + * with names that need escaping + * @bug 8339460 + * @requires vm.cds + * @requires vm.cds.custom.loaders + * @requires vm.flagless + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile mypackage/Main.java mypackage/Another.java + * @run main/othervm ComplexURITest + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Platform; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; + +public class ComplexURITest { + final static String moduleName = "mymodule"; + + public static void main(String[] args) throws Exception { + System.setProperty("test.noclasspath", "true"); + String jarFile = JarBuilder.build(moduleName, "mypackage/Main", "mypackage/Another"); + + Path subDir = Path.of(".", "dir with space"); + Files.createDirectory(subDir); + Path newJarFilePath = subDir.resolve(moduleName + ".jar"); + Files.move(Path.of(jarFile), newJarFilePath); + jarFile = newJarFilePath.toString(); + + final String listFileName = "test-classlist.txt"; + final String staticArchiveName = "test-static.jsa"; + final String dynamicArchiveName = "test-dynamic.jsa"; + + // Verify static archive creation and use + File fileList = new File(listFileName); + delete(fileList.toPath()); + File staticArchive = new File(staticArchiveName); + delete(staticArchive.toPath()); + + createClassList(jarFile, listFileName); + if (!fileList.exists()) { + throw new RuntimeException("No class list created at " + fileList); + } + + createArchive(jarFile, listFileName, staticArchiveName); + if (!staticArchive.exists()) { + throw new RuntimeException("No shared classes archive created at " + staticArchive); + } + + useArchive(jarFile, staticArchiveName); + + // Verify dynamic archive creation and use + File dynamicArchive = new File(dynamicArchiveName); + delete(dynamicArchive.toPath()); + + createDynamicArchive(jarFile, dynamicArchiveName); + if (!dynamicArchive.exists()) { + throw new RuntimeException("No dynamic archive created at " + dynamicArchive); + } + + testDynamicArchive(jarFile, dynamicArchiveName); + } + + private static void delete(Path path) throws Exception { + if (Files.exists(path)) { + if (Platform.isWindows()) { + Files.setAttribute(path, "dos:readonly", false); + } + Files.delete(path); + } + } + + private static void createClassList(String jarFile, String list) throws Exception { + String[] launchArgs = { + "-XX:DumpLoadedClassList=" + list, + "--module-path", + jarFile, + "--module", + moduleName + "/mypackage.Main"}; + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "create-list"); + output.shouldHaveExitValue(0); + } + + private static void createArchive(String jarFile, String list, String archive) throws Exception { + String[] launchArgs = { + "-Xshare:dump", + "-XX:SharedClassListFile=" + list, + "-XX:SharedArchiveFile=" + archive, + "--module-path", + jarFile, + "--module", + moduleName + "/mypackage.Main"}; + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "dump-archive"); + output.shouldHaveExitValue(0); + } + + private static void useArchive(String jarFile, String archive) throws Exception { + String[] launchArgs = { + "-Xshare:on", + "-XX:SharedArchiveFile=" + archive, + "--module-path", + jarFile, + "--module", + moduleName + "/mypackage.Main"}; + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "use-archive"); + output.shouldHaveExitValue(0); + } + + private static void createDynamicArchive(String jarFile, String archive) throws Exception { + String[] launchArgs = { + "-XX:ArchiveClassesAtExit=" + archive, + "--module-path", + jarFile, + "--module", + moduleName + "/mypackage.Main"}; + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "dynamic-archive"); + output.shouldHaveExitValue(0); + } + + private static void testDynamicArchive(String jarFile, String archive) throws Exception { + String[] launchArgs = { + "-XX:SharedArchiveFile=" + archive, + "-XX:+PrintSharedArchiveAndExit", + "--module-path", + jarFile, + "--module", + moduleName + "/mypackage.Main"}; + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(launchArgs); + OutputAnalyzer output = TestCommon.executeAndLog(pb, "dynamic-archive"); + output.shouldHaveExitValue(0); + output.shouldContain("archive is valid"); + output.shouldContain(": mypackage.Main app_loader"); + output.shouldContain(": mypackage.Another unregistered_loader"); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java new file mode 100644 index 0000000000000..106dfd4904c7d --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Another.java @@ -0,0 +1,27 @@ +/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024 JetBrains s.r.o. + * 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. + */ + +package mypackage; + +public class Another { +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java new file mode 100644 index 0000000000000..fdb79e895d240 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/complexURI/mypackage/Main.java @@ -0,0 +1,37 @@ +/* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024 JetBrains s.r.o. + * 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. + */ + +package mypackage; + +import java.net.URL; +import java.net.URLClassLoader; + +public class Main { + public static void main(String[] args) throws Exception { + URL url1 = Main.class.getProtectionDomain().getCodeSource().getLocation(); + System.out.println("Will load Another from " + url1); + ClassLoader cl = URLClassLoader.newInstance(new URL[] { url1 }, null); + var anotherClass = cl.loadClass("mypackage.Another"); + System.out.println("Class " + anotherClass + " loaded successfully"); + } +} diff --git a/test/jdk/java/awt/Component/ComponentEventTest.java b/test/jdk/java/awt/Component/ComponentEventTest.java new file mode 100644 index 0000000000000..bfbfed336a017 --- /dev/null +++ b/test/jdk/java/awt/Component/ComponentEventTest.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2024, 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. + */ + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.List; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Scrollbar; +import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + +import jdk.test.lib.Platform; + +/* + * @test + * @key headful + * @bug 8333403 + * @summary Test performs various operations to check components events are triggered properly. + * @library /test/lib + * @build jdk.test.lib.Platform + * @run main ComponentEventTest + */ +public class ComponentEventTest { + + private static final int DELAY = 500; + + private static Frame frame; + private static Robot robot; + + private static Component[] components; + + private static volatile Point centerPoint; + + private static volatile boolean componentHidden; + private static volatile boolean componentShown; + private static volatile boolean componentMoved; + private static volatile boolean componentResized; + + private static final ComponentListener componentListener = + new ComponentListener() { + + @Override + public void componentShown(ComponentEvent e) { + System.out.println("ComponentShown: " + e.getSource()); + componentShown = true; + } + + @Override + public void componentResized(ComponentEvent e) { + System.out.println("ComponentResized: " + e.getSource()); + componentResized = true; + } + + @Override + public void componentMoved(ComponentEvent e) { + System.out.println("ComponentMoved: " + e.getSource()); + componentMoved = true; + } + + @Override + public void componentHidden(ComponentEvent e) { + System.out.println("ComponentHidden: " + e.getSource()); + componentHidden = true; + } + }; + + private static void initializeGUI() { + frame = new Frame("Component Event Test"); + frame.setLayout(new FlowLayout()); + + Panel panel = new Panel(); + Button button = new Button("Button"); + Label label = new Label("Label"); + List list = new List(); + list.add("One"); + list.add("Two"); + list.add("Three"); + Choice choice = new Choice(); + choice.add("Red"); + choice.add("Orange"); + choice.add("Yellow"); + Checkbox checkbox = new Checkbox("Checkbox"); + Scrollbar scrollbar = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); + TextField textfield = new TextField(15); + TextArea textarea = new TextArea(5, 15); + + components = new Component[] { panel, button, label, list, choice, + checkbox, scrollbar, textfield, textarea, frame }; + + for (int i = 0; i < components.length - 1; i++) { + components[i].addComponentListener(componentListener); + frame.add(components[i]); + } + frame.addComponentListener(componentListener); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + + EventQueue.invokeAndWait(ComponentEventTest::initializeGUI); + robot.waitForIdle(); + robot.delay(DELAY); + + doTest(); + + System.out.println("Test PASSED"); + } finally { + EventQueue.invokeAndWait(ComponentEventTest::disposeFrame); + } + } + + private static void doTest() + throws InvocationTargetException, InterruptedException { + // Click the frame to ensure it gains focus + clickFrame(); + + robot.delay(DELAY); + + for (int i = 0; i < components.length; i++) { + for (boolean state : new boolean[] { true, false }) { + doTest(components[i], state); + } + } + + robot.delay(DELAY); + + System.out.println("Iconify frame"); + resetValues(); + testIconifyFrame(); + + System.out.println("Deiconify frame"); + resetValues(); + testDeiconifyFrame(); + } + + private static void clickFrame() + throws InvocationTargetException, InterruptedException { + EventQueue.invokeAndWait(() -> { + Point location = frame.getLocationOnScreen(); + Dimension size = frame.getSize(); + centerPoint = new Point(location.x + size.width / 2, + location.y + size.height / 2); + }); + + robot.mouseMove(centerPoint.x, centerPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + private static void testIconifyFrame() + throws InvocationTargetException, InterruptedException { + EventQueue.invokeAndWait(() -> frame.setExtendedState(Frame.ICONIFIED)); + + robot.waitForIdle(); + robot.delay(DELAY); + if (componentShown || componentHidden || componentMoved + || componentResized) { + throw new RuntimeException( + "ComponentEvent triggered when frame is iconified"); + } + } + + private static void testDeiconifyFrame() + throws InvocationTargetException, InterruptedException { + EventQueue.invokeAndWait(() -> frame.setExtendedState(Frame.NORMAL)); + + robot.waitForIdle(); + robot.delay(DELAY); + + /* + * Because of the different behavior between MS Windows and other OS, we + * receive native events WM_SIZE and WM_MOVE on Windows when the frame + * state changes from iconified to normal. AWT sends these events to + * components when it receives the events from the native system. See + * JDK-6754618 for more information. + */ + + if (componentShown || componentHidden) { + throw new RuntimeException( + "FAIL: componentShown or componentHidden triggered " + + "when frame set to normal"); + } + + if (Platform.isWindows() && (!componentMoved || !componentResized)) { + throw new RuntimeException( + "FAIL: componentMoved or componentResized wasn't triggered " + + "when frame set to normal"); + } + if (!Platform.isWindows() && (componentMoved || componentResized)) { + throw new RuntimeException( + "FAIL: componentMoved or componentResized triggered " + + "when frame set to normal"); + } + } + + private static void doTest(final Component currentComponent, boolean enable) + throws InvocationTargetException, InterruptedException { + + System.out.println("Component " + currentComponent); + System.out.println(" enabled " + enable); + + EventQueue.invokeAndWait(() -> { + currentComponent.setEnabled(enable); + revalidateFrame(); + }); + + robot.delay(DELAY); + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setVisible(false); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (!componentHidden) { + throw new RuntimeException("FAIL: ComponentHidden not triggered for" + + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setVisible(false); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (componentHidden) { + throw new RuntimeException("FAIL: ComponentHidden triggered when " + + "setVisible(false) called for a hidden " + + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setVisible(true); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (!componentShown) { + throw new RuntimeException("FAIL: ComponentShown not triggered for " + + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setVisible(true); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (componentShown) { + throw new RuntimeException("FAIL: ComponentShown triggered when " + + "setVisible(true) called for a shown " + + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setLocation(currentComponent.getLocation().x + 1, + currentComponent.getLocation().y); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (!componentMoved) { + throw new RuntimeException("FAIL: ComponentMoved not triggered for " + + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setSize(currentComponent.getSize().width + 1, + currentComponent.getSize().height); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (!componentResized) { + throw new RuntimeException("FAIL: ComponentResized not triggered " + + "when size increases for " + currentComponent.getClass()); + } + + resetValues(); + EventQueue.invokeAndWait(() -> { + currentComponent.setSize(currentComponent.getSize().width - 1, + currentComponent.getSize().height); + revalidateFrame(); + }); + + robot.delay(DELAY); + if (!componentResized) { + throw new RuntimeException("FAIL: ComponentResized not triggered " + + "when size decreases for " + currentComponent.getClass()); + } + + System.out.println("\n"); + } + + private static void revalidateFrame() { + frame.invalidate(); + frame.validate(); + } + + private static void resetValues() { + componentShown = false; + componentHidden = false; + componentMoved = false; + componentResized = false; + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + } + } +} diff --git a/test/jdk/javax/net/ssl/DTLS/TEST.properties b/test/jdk/javax/net/ssl/DTLS/TEST.properties index ceb6c8c9c42c7..a50cba09c0f81 100644 --- a/test/jdk/javax/net/ssl/DTLS/TEST.properties +++ b/test/jdk/javax/net/ssl/DTLS/TEST.properties @@ -6,3 +6,4 @@ modules = \ java.security.jgss/sun.security.krb5.internal:+open \ java.security.jgss/sun.security.krb5.internal.ktab \ java.base/sun.security.util +maxOutputSize = 2500000 diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 5aa703c5b26c2..539a1f23208c3 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -128,8 +128,7 @@ public Map call() { map.put("vm.graal.enabled", this::isGraalEnabled); // jdk.hasLibgraal is true if the libgraal shared library file is present map.put("jdk.hasLibgraal", this::hasLibgraal); - // vm.libgraal.enabled is true if libgraal is used as JIT - map.put("vm.libgraal.enabled", this::isLibgraalEnabled); + map.put("vm.libgraal.jit", this::isLibgraalJIT); map.put("vm.compiler1.enabled", this::isCompiler1Enabled); map.put("vm.compiler2.enabled", this::isCompiler2Enabled); map.put("docker.support", this::dockerSupport); @@ -560,8 +559,8 @@ protected String hasLibgraal() { * * @return true if libgraal is used as JIT compiler. */ - protected String isLibgraalEnabled() { - return "" + Compiler.isLibgraalEnabled(); + protected String isLibgraalJIT() { + return "" + Compiler.isLibgraalJIT(); } /** diff --git a/test/langtools/jdk/javadoc/tool/subpackageNoModules/SubpackageNoModules.java b/test/langtools/jdk/javadoc/tool/subpackageNoModules/SubpackageNoModules.java new file mode 100644 index 0000000000000..164ec1f19e494 --- /dev/null +++ b/test/langtools/jdk/javadoc/tool/subpackageNoModules/SubpackageNoModules.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, 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. + */ + +/* + * @test + * @bug 8325090 + * @summary javadoc fails when -subpackages option is used with non-modular -source + * @modules jdk.javadoc/jdk.javadoc.internal.api + * jdk.javadoc/jdk.javadoc.internal.tool + * @library /tools/lib + * @build toolbox.TestRunner toolbox.ToolBox + * @run main SubpackageNoModules + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import toolbox.*; +import toolbox.Task.Expect; + +public class SubpackageNoModules extends TestRunner { + + final ToolBox tb = new ToolBox(); + + public SubpackageNoModules() { + super(System.err); + } + + public static void main(String[] args) throws Exception { + SubpackageNoModules t = new SubpackageNoModules(); + t.runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + @Test + public void testSubpackageNoModules(Path base) throws Exception { + Files.createDirectories(base); + tb.writeFile(base.resolve("pkg/A.java"), "package pkg;\npublic class A {}\n"); + + Path outDir = base.resolve("out"); + Files.createDirectory(outDir); + // Combine -subpackages option with -source release that doesn't support modules + new JavadocTask(tb) + .outdir(outDir) + .sourcepath(base) + .options("-source", "8", + "-subpackages", "pkg") + .run(Expect.SUCCESS); + // Check for presence of generated docs + if (!Files.isRegularFile(outDir.resolve("pkg/A.html"))) { + error("File not found: " + outDir.resolve("pkg/A.html")); + } + } +} diff --git a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java index acd91eac8c785..904e4e78cad1f 100644 --- a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java +++ b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java @@ -41,6 +41,8 @@ import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; import java.util.ArrayList; @@ -93,13 +95,15 @@ public class BasicAnnoTests extends JavacTestingAbstractProcessor { private static final Map> nameToAnnotation = Map.ofEntries(new NameToAnnotationEntry("java.lang.Override", Override.class), new NameToAnnotationEntry("java.lang.annotation.Repeatable", Repeatable.class), + new NameToAnnotationEntry("java.lang.annotation.Retention", Target.class), new NameToAnnotationEntry("java.lang.annotation.Target", Target.class), new NameToAnnotationEntry("BasicAnnoTests.Test", BasicAnnoTests.Test.class), new NameToAnnotationEntry("BasicAnnoTests.Tests",BasicAnnoTests.Tests.class), new NameToAnnotationEntry("BasicAnnoTests.TA", BasicAnnoTests.TA.class), new NameToAnnotationEntry("BasicAnnoTests.TB", BasicAnnoTests.TB.class), new NameToAnnotationEntry("BasicAnnoTests.TC", BasicAnnoTests.TC.class), - new NameToAnnotationEntry("BasicAnnoTests.TCs", BasicAnnoTests.TCs.class)); + new NameToAnnotationEntry("BasicAnnoTests.TCs", BasicAnnoTests.TCs.class), + new NameToAnnotationEntry("BasicAnnoTests.TD", BasicAnnoTests.TD.class)); static class NameToAnnotationEntry extends AbstractMap.SimpleEntry> { public NameToAnnotationEntry(String key, Class entry) { @@ -520,6 +524,12 @@ R scan(Iterable iter, P p) { TC[] value(); } + @Target(ElementType.TYPE_USE) + @Retention(RetentionPolicy.RUNTIME) + public @interface TD { + int value(); + } + // Test cases // TODO: add more cases for arrays @@ -657,6 +667,10 @@ public class Inner6 {} @Test(posn=1, annoType=TA.class, expect="23") public Set<@TA(23) ? super Object> f9; + @Test(posn=0, annoType=TA.class, expect="1") + @Test(posn=0, annoType=TD.class, expect="2") + public @TA(1) @TD(2) int f10; + // Test type use annotations on uses of type variables @Test(posn=6, annoType = TA.class, expect = "25") @Test(posn=6, annoType = TB.class, expect = "26") diff --git a/test/lib/jdk/test/whitebox/code/Compiler.java b/test/lib/jdk/test/whitebox/code/Compiler.java index 2f8447700d57d..69d79ab9d7104 100644 --- a/test/lib/jdk/test/whitebox/code/Compiler.java +++ b/test/lib/jdk/test/whitebox/code/Compiler.java @@ -91,12 +91,12 @@ public static boolean isGraalEnabled() { /** * Check if libgraal is used as JIT compiler. * - * libraal is enabled if isGraalEnabled is true and: + * libraal JIT is enabled if isGraalEnabled is true and: * - UseJVMCINativeLibrary flag is true * * @return true if libgraal is used as JIT compiler. */ - public static boolean isLibgraalEnabled() { + public static boolean isLibgraalJIT() { if (!isGraalEnabled()) { return false; }