This commit is contained in:
J. Duke 2017-07-05 22:05:10 +02:00
commit 5aac6d6f96
369 changed files with 6507 additions and 3038 deletions

View File

@ -373,3 +373,4 @@ f80c841ae2545eaf9acd2724bccc305d98cefbe2 jdk-9+124
b30ae794d974d7dd3eb4e84203f70021823fa6c6 jdk-9+128 b30ae794d974d7dd3eb4e84203f70021823fa6c6 jdk-9+128
f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129 f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130 d94d54a3192fea79234c3ac55cd0b4052d45e954 jdk-9+130
8728756c2f70a79a90188f4019cfd6b9a275765c jdk-9+131

View File

@ -305,7 +305,7 @@ AC_DEFUN_ONCE([BOOTJDK_SETUP_BOOT_JDK],
BOOT_JDK_SOURCETARGET="-source 8 -target 8" BOOT_JDK_SOURCETARGET="-source 8 -target 8"
AC_SUBST(BOOT_JDK_SOURCETARGET) AC_SUBST(BOOT_JDK_SOURCETARGET)
ADD_JVM_ARG_IF_OK([-Xpatch:foo=bar], dummy, [$JAVA]) ADD_JVM_ARG_IF_OK([--patch-module foo=bar], dummy, [$JAVA])
AC_MSG_CHECKING([if Boot JDK supports modules]) AC_MSG_CHECKING([if Boot JDK supports modules])
if test "x$JVM_ARG_OK" = "xtrue"; then if test "x$JVM_ARG_OK" = "xtrue"; then
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])

View File

@ -5095,7 +5095,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE #CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks: # Do not change or remove the following line, it is needed for consistency checks:
DATE_WHEN_GENERATED=1470415803 DATE_WHEN_GENERATED=1470863189
############################################################################### ###############################################################################
# #
@ -30596,13 +30596,13 @@ $as_echo "$tool_specified" >&6; }
$ECHO "Check if jvm arg is ok: -Xpatch:foo=bar" >&5 $ECHO "Check if jvm arg is ok: --patch-module foo=bar" >&5
$ECHO "Command: $JAVA -Xpatch:foo=bar -version" >&5 $ECHO "Command: $JAVA --patch-module foo=bar -version" >&5
OUTPUT=`$JAVA -Xpatch:foo=bar -version 2>&1` OUTPUT=`$JAVA --patch-module foo=bar -version 2>&1`
FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn` FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""` FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then if test "x$FOUND_VERSION" != x && test "x$FOUND_WARN" = x; then
dummy="$dummy -Xpatch:foo=bar" dummy="$dummy --patch-module foo=bar"
JVM_ARG_OK=true JVM_ARG_OK=true
else else
$ECHO "Arg failed:" >&5 $ECHO "Arg failed:" >&5

View File

@ -585,7 +585,7 @@ INTERIM_OVERRIDE_MODULES := java.compiler jdk.compiler \
jdk.jdeps jdk.javadoc jdk.rmic jdk.jdeps jdk.javadoc jdk.rmic
ifeq ($(BOOT_JDK_MODULAR), true) ifeq ($(BOOT_JDK_MODULAR), true)
INTERIM_OVERRIDE_MODULES_ARGS = $(foreach m, $(INTERIM_OVERRIDE_MODULES), \ INTERIM_OVERRIDE_MODULES_ARGS = $(foreach m, $(INTERIM_OVERRIDE_MODULES), \
-Xpatch:$m=$(BUILDTOOLS_OUTPUTDIR)/override_modules/$m) --patch-module $m=$(BUILDTOOLS_OUTPUTDIR)/override_modules/$m)
INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS) INTERIM_LANGTOOLS_ARGS = $(INTERIM_OVERRIDE_MODULES_ARGS)
JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main
JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main

View File

@ -417,7 +417,7 @@ var getJibProfilesDependencies = function (input, common) {
jtreg: { jtreg: {
server: "javare", server: "javare",
revision: "4.2", revision: "4.2",
build_number: "b02", build_number: "b03",
checksum_file: "MD5_VALUES", checksum_file: "MD5_VALUES",
file: "jtreg_bin-4.2.zip", file: "jtreg_bin-4.2.zip",
environment_name: "JT_HOME" environment_name: "JT_HOME"

View File

@ -373,3 +373,4 @@ c7f5ba08fcd4b8416e62c21229f9a07c95498919 jdk-9+126
1f093d3f8cd99cd37c3b0af4cf5c3bffaa9c8b98 jdk-9+128 1f093d3f8cd99cd37c3b0af4cf5c3bffaa9c8b98 jdk-9+128
c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129 c3e83ccab3bb1733ae903d681879a33f85ed465c jdk-9+129
77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130 77f9692d5976ae155773dd3e07533616bb95bae1 jdk-9+130
f7e1d5337c2e550fe553df7a3886bbed80292ecd jdk-9+131

View File

@ -533,3 +533,4 @@ adc8c84b7cf8c540d920182f78a2bc982366432a jdk-9+126
22bf6db9767b1b3a1994cbf32eb3331f31ae2093 jdk-9+128 22bf6db9767b1b3a1994cbf32eb3331f31ae2093 jdk-9+128
e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129 e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130 7d54c7056328b6a2bf4877458b8f4d8cd870f93b jdk-9+130
943bf73b49c33c2d7cbd796f6a4ae3c7a00ae932 jdk-9+131

View File

@ -109,6 +109,9 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv
if (!s.getReturnType(CLASS).equals(resultType)) { if (!s.getReturnType(CLASS).equals(resultType)) {
return false; return false;
} }
if (s.getParameterCount(false) != parameterTypes.length) {
return false;
}
for (int i = 0; i < s.getParameterCount(false); ++i) { for (int i = 0; i < s.getParameterCount(false); ++i) {
if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) { if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) {
return false; return false;

View File

@ -57,7 +57,7 @@ public final class Services {
if (jvmci != requestorModule) { if (jvmci != requestorModule) {
for (String pkg : jvmci.getPackages()) { for (String pkg : jvmci.getPackages()) {
// Export all JVMCI packages dynamically instead // Export all JVMCI packages dynamically instead
// of requiring a long list of -XaddExports // of requiring a long list of --add-exports
// options on the JVM command line. // options on the JVM command line.
if (!jvmci.isExported(pkg, requestorModule)) { if (!jvmci.isExported(pkg, requestorModule)) {
jvmci.addExports(pkg, requestorModule); jvmci.addExports(pkg, requestorModule);

View File

@ -140,7 +140,7 @@ PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
PerfCounter* ClassLoader::_isUnsyncloadClass = NULL; PerfCounter* ClassLoader::_isUnsyncloadClass = NULL;
PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL; PerfCounter* ClassLoader::_load_instance_class_failCounter = NULL;
GrowableArray<ModuleClassPathList*>* ClassLoader::_xpatch_entries = NULL; GrowableArray<ModuleClassPathList*>* ClassLoader::_patch_mod_entries = NULL;
GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL; GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL;
ClassPathEntry* ClassLoader::_jrt_entry = NULL; ClassPathEntry* ClassLoader::_jrt_entry = NULL;
ClassPathEntry* ClassLoader::_first_append_entry = NULL; ClassPathEntry* ClassLoader::_first_append_entry = NULL;
@ -685,27 +685,27 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
} }
#endif #endif
// Construct the array of module/path pairs as specified to -Xpatch // Construct the array of module/path pairs as specified to --patch-module
// for the boot loader to search ahead of the jimage, if the class being // for the boot loader to search ahead of the jimage, if the class being
// loaded is defined to a module that has been specified to -Xpatch. // loaded is defined to a module that has been specified to --patch-module.
void ClassLoader::setup_xpatch_entries() { void ClassLoader::setup_patch_mod_entries() {
Thread* THREAD = Thread::current(); Thread* THREAD = Thread::current();
GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix(); GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
int num_of_entries = xpatch_args->length(); int num_of_entries = patch_mod_args->length();
assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with -Xpatch"); assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with --patch-module");
assert(!UseSharedSpaces, "UseSharedSpaces not supported with -Xpatch"); assert(!UseSharedSpaces, "UseSharedSpaces not supported with --patch-module");
// Set up the boot loader's _xpatch_entries list // Set up the boot loader's _patch_mod_entries list
_xpatch_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true); _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
for (int i = 0; i < num_of_entries; i++) { for (int i = 0; i < num_of_entries; i++) {
const char* module_name = (xpatch_args->at(i))->module_name(); const char* module_name = (patch_mod_args->at(i))->module_name();
Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK); Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
assert(module_sym != NULL, "Failed to obtain Symbol for module name"); assert(module_sym != NULL, "Failed to obtain Symbol for module name");
ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym); ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
char* class_path = (xpatch_args->at(i))->path_string(); char* class_path = (patch_mod_args->at(i))->path_string();
int len = (int)strlen(class_path); int len = (int)strlen(class_path);
int end = 0; int end = 0;
// Iterate over the module's class path entries // Iterate over the module's class path entries
@ -735,10 +735,10 @@ void ClassLoader::setup_xpatch_entries() {
} }
} }
// Record the module into the list of -Xpatch entries only if // Record the module into the list of --patch-module entries only if
// valid ClassPathEntrys have been created // valid ClassPathEntrys have been created
if (module_cpl->module_first_entry() != NULL) { if (module_cpl->module_first_entry() != NULL) {
_xpatch_entries->push(module_cpl); _patch_mod_entries->push(module_cpl);
} }
} }
} }
@ -1020,9 +1020,9 @@ void ClassLoader::print_bootclasspath() {
ClassPathEntry* e; ClassPathEntry* e;
tty->print("[bootclasspath= "); tty->print("[bootclasspath= ");
// Print -Xpatch module/path specifications first // Print --patch-module module/path specifications first
if (_xpatch_entries != NULL) { if (_patch_mod_entries != NULL) {
print_module_entry_table(_xpatch_entries); print_module_entry_table(_patch_mod_entries);
} }
// [jimage | exploded modules build] // [jimage | exploded modules build]
@ -1341,7 +1341,7 @@ const char* ClassLoader::file_name_for_class_name(const char* class_name,
return file_name; return file_name;
} }
// Search either the xpatch or exploded build entries for class // Search either the patch-module or exploded build entries for class
ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list, ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list,
const char* const class_name, const char* const file_name, TRAPS) { const char* const class_name, const char* const file_name, TRAPS) {
ClassFileStream* stream = NULL; ClassFileStream* stream = NULL;
@ -1366,7 +1366,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
int num_of_entries = module_list->length(); int num_of_entries = module_list->length();
const Symbol* class_module_name = mod_entry->name(); const Symbol* class_module_name = mod_entry->name();
// Loop through all the modules in either the xpatch or exploded entries looking for module // Loop through all the modules in either the patch-module or exploded entries looking for module
for (int i = 0; i < num_of_entries; i++) { for (int i = 0; i < num_of_entries; i++) {
ModuleClassPathList* module_cpl = module_list->at(i); ModuleClassPathList* module_cpl = module_list->at(i);
Symbol* module_cpl_name = module_cpl->module_name(); Symbol* module_cpl_name = module_cpl->module_name();
@ -1378,7 +1378,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
while (e != NULL) { while (e != NULL) {
stream = e->open_stream(file_name, CHECK_NULL); stream = e->open_stream(file_name, CHECK_NULL);
// No context.check is required since CDS is not supported // No context.check is required since CDS is not supported
// for an exploded modules build or if -Xpatch is specified. // for an exploded modules build or if --patch-module is specified.
if (NULL != stream) { if (NULL != stream) {
return stream; return stream;
} }
@ -1420,32 +1420,32 @@ instanceKlassHandle ClassLoader::load_class(Symbol* name, bool search_append_onl
// If DumpSharedSpaces is true boot loader visibility boundaries are set to: // If DumpSharedSpaces is true boot loader visibility boundaries are set to:
// - [jimage] + [_first_append_entry to _last_append_entry] (all path entries). // - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
// No -Xpatch entries or exploded module builds are included since CDS // No --patch-module entries or exploded module builds are included since CDS
// is not supported if -Xpatch or exploded module builds are used. // is not supported if --patch-module or exploded module builds are used.
// //
// If search_append_only is true, boot loader visibility boundaries are // If search_append_only is true, boot loader visibility boundaries are
// set to be _first_append_entry to the end. This includes: // set to be _first_append_entry to the end. This includes:
// [-Xbootclasspath/a]; [jvmti appended entries] // [-Xbootclasspath/a]; [jvmti appended entries]
// //
// If both DumpSharedSpaces and search_append_only are false, boot loader // If both DumpSharedSpaces and search_append_only are false, boot loader
// visibility boundaries are set to be the -Xpatch entries plus the base piece. // visibility boundaries are set to be the --patch-module entries plus the base piece.
// This would include: // This would include:
// [-Xpatch:<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build] // [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build]
// //
// DumpSharedSpaces and search_append_only are mutually exclusive and cannot // DumpSharedSpaces and search_append_only are mutually exclusive and cannot
// be true at the same time. // be true at the same time.
assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true"); assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
// Load Attempt #1: -Xpatch // Load Attempt #1: --patch-module
// Determine the class' defining module. If it appears in the _xpatch_entries, // Determine the class' defining module. If it appears in the _patch_mod_entries,
// attempt to load the class from those locations specific to the module. // attempt to load the class from those locations specific to the module.
// Specifications to -Xpatch can contain a partial number of classes // Specifications to --patch-module can contain a partial number of classes
// that are part of the overall module definition. So if a particular class is not // that are part of the overall module definition. So if a particular class is not
// found within its module specification, the search should continue to Load Attempt #2. // found within its module specification, the search should continue to Load Attempt #2.
// Note: The -Xpatch entries are never searched if the boot loader's // Note: The --patch-module entries are never searched if the boot loader's
// visibility boundary is limited to only searching the append entries. // visibility boundary is limited to only searching the append entries.
if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) { if (_patch_mod_entries != NULL && !search_append_only && !DumpSharedSpaces) {
stream = search_module_entries(_xpatch_entries, class_name, file_name, CHECK_NULL); stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
} }
// Load Attempt #2: [jimage | exploded build] // Load Attempt #2: [jimage | exploded build]
@ -1650,11 +1650,11 @@ void ClassLoader::classLoader_init2(TRAPS) {
// Create the moduleEntry for java.base // Create the moduleEntry for java.base
create_javabase(); create_javabase();
// Setup the list of module/path pairs for -Xpatch processing // Setup the list of module/path pairs for --patch-module processing
// This must be done after the SymbolTable is created in order // This must be done after the SymbolTable is created in order
// to use fast_compare on module names instead of a string compare. // to use fast_compare on module names instead of a string compare.
if (Arguments::get_xpatchprefix() != NULL) { if (Arguments::get_patch_mod_prefix() != NULL) {
setup_xpatch_entries(); setup_patch_mod_entries();
} }
// Setup the initial java.base/path pair for the exploded build entries. // Setup the initial java.base/path pair for the exploded build entries.

View File

@ -150,7 +150,7 @@ public:
// ModuleClassPathList contains a linked list of ClassPathEntry's // ModuleClassPathList contains a linked list of ClassPathEntry's
// that have been specified for a specific module. Currently, // that have been specified for a specific module. Currently,
// the only way to specify a module/path pair is via the -Xpatch // the only way to specify a module/path pair is via the --patch-module
// command line option. // command line option.
class ModuleClassPathList : public CHeapObj<mtClass> { class ModuleClassPathList : public CHeapObj<mtClass> {
private: private:
@ -213,8 +213,8 @@ class ClassLoader: AllStatic {
static PerfCounter* _load_instance_class_failCounter; static PerfCounter* _load_instance_class_failCounter;
// The boot class path consists of 3 ordered pieces: // The boot class path consists of 3 ordered pieces:
// 1. the module/path pairs specified to -Xpatch // 1. the module/path pairs specified to --patch-module
// -Xpatch:<module>=<file>(<pathsep><file>)* // --patch-module=<module>=<file>(<pathsep><file>)*
// 2. the base piece // 2. the base piece
// [jimage | build with exploded modules] // [jimage | build with exploded modules]
// 3. boot loader append path // 3. boot loader append path
@ -223,8 +223,8 @@ class ClassLoader: AllStatic {
// The boot loader must obey this order when attempting // The boot loader must obey this order when attempting
// to load a class. // to load a class.
// 1. Contains the module/path pairs specified to -Xpatch // 1. Contains the module/path pairs specified to --patch-module
static GrowableArray<ModuleClassPathList*>* _xpatch_entries; static GrowableArray<ModuleClassPathList*>* _patch_mod_entries;
// 2. the base piece // 2. the base piece
// Contains the ClassPathEntry of the modular java runtime image. // Contains the ClassPathEntry of the modular java runtime image.
@ -256,11 +256,11 @@ class ClassLoader: AllStatic {
// Initialization: // Initialization:
// - setup the boot loader's system class path // - setup the boot loader's system class path
// - setup the boot loader's xpatch entries, if present // - setup the boot loader's patch mod entries, if present
// - create the ModuleEntry for java.base // - create the ModuleEntry for java.base
static void setup_bootstrap_search_path(); static void setup_bootstrap_search_path();
static void setup_search_path(const char *class_path, bool setting_bootstrap); static void setup_search_path(const char *class_path, bool setting_bootstrap);
static void setup_xpatch_entries(); static void setup_patch_mod_entries();
static void create_javabase(); static void create_javabase();
static void load_zip_library(); static void load_zip_library();
@ -363,7 +363,7 @@ class ClassLoader: AllStatic {
// Add a module's exploded directory to the boot loader's exploded module build list // Add a module's exploded directory to the boot loader's exploded module build list
static void add_to_exploded_build_list(Symbol* module_name, TRAPS); static void add_to_exploded_build_list(Symbol* module_name, TRAPS);
// Attempt load of individual class from either the xpatch or exploded modules build lists // Attempt load of individual class from either the patched or exploded modules build lists
static ClassFileStream* search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list, static ClassFileStream* search_module_entries(const GrowableArray<ModuleClassPathList*>* const module_list,
const char* const class_name, const char* const class_name,
const char* const file_name, TRAPS); const char* const file_name, TRAPS);

View File

@ -911,8 +911,8 @@ bool FileMapInfo::FileMapHeader::validate() {
return false; return false;
} }
if (Arguments::get_xpatchprefix() != NULL) { if (Arguments::get_patch_mod_prefix() != NULL) {
FileMapInfo::fail_continue("The shared archive file cannot be used with -Xpatch."); FileMapInfo::fail_continue("The shared archive file cannot be used with --patch-module.");
return false; return false;
} }

View File

@ -24,6 +24,8 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "classfile/classLoaderExt.hpp" #include "classfile/classLoaderExt.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/modules.hpp" #include "classfile/modules.hpp"
#include "classfile/systemDictionary.hpp" #include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp" #include "classfile/vmSymbols.hpp"
@ -224,6 +226,7 @@ JvmtiEnv::GetNamedModule(jobject class_loader, const char* package_name, jobject
return JVMTI_ERROR_NONE; return JVMTI_ERROR_NONE;
} /* end GetNamedModule */ } /* end GetNamedModule */
// //
// Class functions // Class functions
// //
@ -3465,28 +3468,35 @@ jvmtiError
JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) { JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
jvmtiError err = JVMTI_ERROR_NONE; jvmtiError err = JVMTI_ERROR_NONE;
*count_ptr = Arguments::PropertyList_count(Arguments::system_properties()); // Get the number of readable properties.
*count_ptr = Arguments::PropertyList_readable_count(Arguments::system_properties());
// Allocate memory to hold the exact number of readable properties.
err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr); err = allocate(*count_ptr * sizeof(char *), (unsigned char **)property_ptr);
if (err != JVMTI_ERROR_NONE) { if (err != JVMTI_ERROR_NONE) {
return err; return err;
} }
int i = 0 ; int readable_count = 0;
for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) { // Loop through the system properties until all the readable properties are found.
const char *key = p->key(); for (SystemProperty* p = Arguments::system_properties(); p != NULL && readable_count < *count_ptr; p = p->next()) {
char **tmp_value = *property_ptr+i; if (p->is_readable()) {
err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value); const char *key = p->key();
if (err == JVMTI_ERROR_NONE) { char **tmp_value = *property_ptr+readable_count;
strcpy(*tmp_value, key); readable_count++;
} else { err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
// clean up previously allocated memory. if (err == JVMTI_ERROR_NONE) {
for (int j=0; j<i; j++) { strcpy(*tmp_value, key);
Deallocate((unsigned char*)*property_ptr+j); } else {
// clean up previously allocated memory.
for (int j=0; j<readable_count; j++) {
Deallocate((unsigned char*)*property_ptr+j);
}
Deallocate((unsigned char*)property_ptr);
break;
} }
Deallocate((unsigned char*)property_ptr);
break;
} }
} }
assert(err != JVMTI_ERROR_NONE || readable_count == *count_ptr, "Bad readable property count");
return err; return err;
} /* end GetSystemProperties */ } /* end GetSystemProperties */
@ -3498,7 +3508,8 @@ JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
jvmtiError err = JVMTI_ERROR_NONE; jvmtiError err = JVMTI_ERROR_NONE;
const char *value; const char *value;
value = Arguments::PropertyList_get_value(Arguments::system_properties(), property); // Return JVMTI_ERROR_NOT_AVAILABLE if property is not readable or doesn't exist.
value = Arguments::PropertyList_get_readable_value(Arguments::system_properties(), property);
if (value == NULL) { if (value == NULL) {
err = JVMTI_ERROR_NOT_AVAILABLE; err = JVMTI_ERROR_NOT_AVAILABLE;
} else { } else {

View File

@ -110,7 +110,7 @@ SystemProperty *Arguments::_java_home = NULL;
SystemProperty *Arguments::_java_class_path = NULL; SystemProperty *Arguments::_java_class_path = NULL;
SystemProperty *Arguments::_jdk_boot_class_path_append = NULL; SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL; GrowableArray<ModulePatchPath*> *Arguments::_patch_mod_prefix = NULL;
PathString *Arguments::_system_boot_class_path = NULL; PathString *Arguments::_system_boot_class_path = NULL;
bool Arguments::_has_jimage = false; bool Arguments::_has_jimage = false;
@ -161,6 +161,30 @@ static void logOption(const char* opt) {
} }
} }
bool needs_module_property_warning = false;
#define MODULE_PROPERTY_PREFIX "jdk.module"
#define MODULE_PROPERTY_PREFIX_LEN 10
#define MODULE_MAIN_PROPERTY "jdk.module.main"
#define MODULE_MAIN_PROPERTY_LEN 15
// Return TRUE if option matches property, or property=, or property..
static bool matches_property_prefix(const char* option, const char* property, size_t len) {
return (strncmp(option, property, len) == 0) &&
(option[len] == '=' || option[len] == '.' || option[len] == '\0');
}
// Return true if the property is either "jdk.module" or starts with "jdk.module.",
// but does not start with "jdk.module.main".
// Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
// are valid non-internal system properties.
// "property" should be passed without the leading "-D".
bool Arguments::is_internal_module_property(const char* property) {
assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
!matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
}
// Process java launcher properties. // Process java launcher properties.
void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) { void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
// See if sun.java.launcher, sun.java.launcher.is_altjvm or // See if sun.java.launcher, sun.java.launcher.is_altjvm or
@ -197,7 +221,7 @@ void Arguments::init_system_properties() {
_system_boot_class_path = new PathString(NULL); _system_boot_class_path = new PathString(NULL);
PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name", PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name",
"Java Virtual Machine Specification", false)); "Java Virtual Machine Specification", false));
PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(), false)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(), false));
PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false));
PropertyList_add(&_system_properties, new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true)); PropertyList_add(&_system_properties, new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true));
@ -1198,7 +1222,7 @@ const char* Arguments::get_property(const char* key) {
return PropertyList_get_value(system_properties(), key); return PropertyList_get_value(system_properties(), key);
} }
bool Arguments::add_property(const char* prop) { bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) {
const char* eq = strchr(prop, '='); const char* eq = strchr(prop, '=');
const char* key; const char* key;
const char* value = ""; const char* value = "";
@ -1228,7 +1252,9 @@ bool Arguments::add_property(const char* prop) {
// private and are processed in process_sun_java_launcher_properties(); // private and are processed in process_sun_java_launcher_properties();
// the sun.java.launcher property is passed on to the java application // the sun.java.launcher property is passed on to the java application
} else if (strcmp(key, "sun.boot.library.path") == 0) { } else if (strcmp(key, "sun.boot.library.path") == 0) {
PropertyList_unique_add(&_system_properties, key, value, true); // append is true, writable is true, internal is false
PropertyList_unique_add(&_system_properties, key, value, AppendProperty,
WriteableProperty, ExternalProperty);
} else { } else {
if (strcmp(key, "sun.java.command") == 0) { if (strcmp(key, "sun.java.command") == 0) {
char *old_java_command = _java_command; char *old_java_command = _java_command;
@ -1248,7 +1274,7 @@ bool Arguments::add_property(const char* prop) {
} }
// Create new property and add at the end of the list // Create new property and add at the end of the list
PropertyList_unique_add(&_system_properties, key, value); PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
} }
if (key != prop) { if (key != prop) {
@ -1260,9 +1286,9 @@ bool Arguments::add_property(const char* prop) {
return true; return true;
} }
// sets or adds a module name to the jdk.launcher.addmods property // sets or adds a module name to the jdk.module.addmods property
bool Arguments::append_to_addmods_property(const char* module_name) { bool Arguments::append_to_addmods_property(const char* module_name) {
const char* key = "jdk.launcher.addmods"; const char* key = "jdk.module.addmods";
const char* old_value = Arguments::get_property(key); const char* old_value = Arguments::get_property(key);
size_t buf_len = strlen(key) + strlen(module_name) + 2; size_t buf_len = strlen(key) + strlen(module_name) + 2;
if (old_value != NULL) { if (old_value != NULL) {
@ -1277,7 +1303,7 @@ bool Arguments::append_to_addmods_property(const char* module_name) {
} else { } else {
jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name); jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
} }
bool added = add_property(new_value); bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
FreeHeap(new_value); FreeHeap(new_value);
return added; return added;
} }
@ -1287,14 +1313,14 @@ void Arguments::check_unsupported_dumping_properties() {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
const char* unsupported_properties[5] = { "jdk.module.main", const char* unsupported_properties[5] = { "jdk.module.main",
"jdk.module.path", "jdk.module.path",
"jdk.upgrade.module.path", "jdk.module.upgrade.path",
"jdk.launcher.addmods", "jdk.module.addmods",
"jdk.launcher.limitmods" }; "jdk.module.limitmods" };
const char* unsupported_options[5] = { "-m", const char* unsupported_options[5] = { "-m",
"-modulepath", "--module-path",
"-upgrademodulepath", "--upgrade-module-path",
"-addmods", "--add-modules",
"-limitmods" }; "--limit-modules" };
SystemProperty* sp = system_properties(); SystemProperty* sp = system_properties();
while (sp != NULL) { while (sp != NULL) {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@ -1326,7 +1352,7 @@ void Arguments::set_mode_flags(Mode mode) {
// Ensure Agent_OnLoad has the correct initial values. // Ensure Agent_OnLoad has the correct initial values.
// This may not be the final mode; mode may change later in onload phase. // This may not be the final mode; mode may change later in onload phase.
PropertyList_unique_add(&_system_properties, "java.vm.info", PropertyList_unique_add(&_system_properties, "java.vm.info",
VM_Version::vm_info_string(), false); VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
UseInterpreter = true; UseInterpreter = true;
UseCompiler = true; UseCompiler = true;
@ -2516,6 +2542,41 @@ bool Arguments::parse_uintx(const char* value,
return false; return false;
} }
unsigned int addreads_count = 0;
unsigned int addexports_count = 0;
unsigned int patch_mod_count = 0;
const char* add_modules_value = NULL;
bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
char* property = AllocateHeap(prop_len, mtArguments);
int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
if (ret < 0 || ret >= (int)prop_len) {
FreeHeap(property);
return false;
}
bool added = add_property(property, UnwriteableProperty, internal);
FreeHeap(property);
return added;
}
bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) {
// Make sure count is < 1,000. Otherwise, memory allocation will be too small.
if (count < 1000) {
size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5;
char* property = AllocateHeap(prop_len, mtArguments);
int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value);
if (ret < 0 || ret >= (int)prop_len) {
FreeHeap(property);
return false;
}
bool added = add_property(property, UnwriteableProperty, InternalProperty);
FreeHeap(property);
return added;
}
return false;
}
Arguments::ArgsRange Arguments::parse_memory_size(const char* s, Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
julong* long_arg, julong* long_arg,
julong min_size) { julong min_size) {
@ -2528,7 +2589,7 @@ Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args) { const JavaVMInitArgs *cmd_line_args) {
bool xpatch_javabase = false; bool patch_mod_javabase = false;
// Save default settings for some mode flags // Save default settings for some mode flags
Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
@ -2545,20 +2606,20 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
// Parse args structure generated from JAVA_TOOL_OPTIONS environment // Parse args structure generated from JAVA_TOOL_OPTIONS environment
// variable (if present). // variable (if present).
jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR); jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
if (result != JNI_OK) { if (result != JNI_OK) {
return result; return result;
} }
// Parse args structure generated from the command line flags. // Parse args structure generated from the command line flags.
result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE); result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE);
if (result != JNI_OK) { if (result != JNI_OK) {
return result; return result;
} }
// Parse args structure generated from the _JAVA_OPTIONS environment // Parse args structure generated from the _JAVA_OPTIONS environment
// variable (if present) (mimics classic VM) // variable (if present) (mimics classic VM)
result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR); result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
if (result != JNI_OK) { if (result != JNI_OK) {
return result; return result;
} }
@ -2617,7 +2678,35 @@ bool valid_jdwp_agent(char *name, bool is_path) {
return false; return false;
} }
jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) { int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) {
// --patch-module=<module>=<file>(<pathsep><file>)*
assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value");
// Find the equal sign between the module name and the path specification
const char* module_equal = strchr(patch_mod_tail, '=');
if (module_equal == NULL) {
jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n");
return JNI_ERR;
} else {
// Pick out the module name
size_t module_len = module_equal - patch_mod_tail;
char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
if (module_name != NULL) {
memcpy(module_name, patch_mod_tail, module_len);
*(module_name + module_len) = '\0';
// The path piece begins one past the module_equal sign
add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase);
FREE_C_HEAP_ARRAY(char, module_name);
if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
return JNI_ENOMEM;
}
} else {
return JNI_ENOMEM;
}
}
return JNI_OK;
}
jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) {
// For match_option to return remaining or value part of option string // For match_option to return remaining or value part of option string
const char* tail; const char* tail;
@ -2701,6 +2790,34 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
#endif // !INCLUDE_JVMTI #endif // !INCLUDE_JVMTI
add_init_library(name, options); add_init_library(name, options);
} }
} else if (match_option(option, "--add-reads=", &tail)) {
if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) {
return JNI_ENOMEM;
}
} else if (match_option(option, "--add-exports=", &tail)) {
if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) {
return JNI_ENOMEM;
}
} else if (match_option(option, "--add-modules=", &tail)) {
add_modules_value = tail;
} else if (match_option(option, "--limit-modules=", &tail)) {
if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
return JNI_ENOMEM;
}
} else if (match_option(option, "--module-path=", &tail)) {
if (!create_property("jdk.module.path", tail, ExternalProperty)) {
return JNI_ENOMEM;
}
} else if (match_option(option, "--upgrade-module-path=", &tail)) {
if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) {
return JNI_ENOMEM;
}
} else if (match_option(option, "--patch-module=", &tail)) {
// --patch-module=<module>=<file>(<pathsep><file>)*
int res = process_patch_mod_option(tail, patch_mod_javabase);
if (res != JNI_OK) {
return res;
}
// -agentlib and -agentpath // -agentlib and -agentpath
} else if (match_option(option, "-agentlib:", &tail) || } else if (match_option(option, "-agentlib:", &tail) ||
(is_absolute_path = match_option(option, "-agentpath:", &tail))) { (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
@ -2992,6 +3109,13 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
"-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value); "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
return JNI_EINVAL; return JNI_EINVAL;
} }
// Check for module related properties. They must be set using the modules
// options. For example: use "--add-modules=java.sql", not
// "-Djdk.module.addmods=java.sql"
if (is_internal_module_property(option->optionString + 2)) {
needs_module_property_warning = true;
continue;
}
if (!add_property(tail)) { if (!add_property(tail)) {
return JNI_ENOMEM; return JNI_ENOMEM;
@ -3012,33 +3136,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
return JNI_ERR; return JNI_ERR;
#endif #endif
} }
if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
// -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
// The number, #, specified will be increasing with each -Xpatch
// specified on the command line.
// Pick up module name, following the -D property's equal sign.
const char* property_equal = strchr(tail, '=');
if (property_equal == NULL) {
jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
return JNI_ERR;
} else {
// Find the equal sign between the module name and the path specification
const char* module_equal = strchr(property_equal + 1, '=');
if (module_equal == NULL) {
jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
return JNI_ERR;
} else {
// Pick out the module name, in between the two equal signs
size_t module_len = module_equal - property_equal - 1;
char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
memcpy(module_name, property_equal + 1, module_len);
*(module_name + module_len) = '\0';
// The path piece begins one past the module_equal sign
Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
FREE_C_HEAP_ARRAY(char, module_name);
}
}
}
// -Xint // -Xint
} else if (match_option(option, "-Xint")) { } else if (match_option(option, "-Xint")) {
set_mode_flags(_int); set_mode_flags(_int);
@ -3298,25 +3395,25 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
return JNI_OK; return JNI_OK;
} }
void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) { void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
// For java.base check for duplicate -Xpatch options being specified on the command line. // For java.base check for duplicate --patch-module options being specified on the command line.
// This check is only required for java.base, all other duplicate module specifications // This check is only required for java.base, all other duplicate module specifications
// will be checked during module system initialization. The module system initialization // will be checked during module system initialization. The module system initialization
// will throw an ExceptionInInitializerError if this situation occurs. // will throw an ExceptionInInitializerError if this situation occurs.
if (strcmp(module_name, "java.base") == 0) { if (strcmp(module_name, "java.base") == 0) {
if (*xpatch_javabase) { if (*patch_mod_javabase) {
vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch"); vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
} else { } else {
*xpatch_javabase = true; *patch_mod_javabase = true;
} }
} }
// Create GrowableArray lazily, only if -Xpatch has been specified // Create GrowableArray lazily, only if --patch-module has been specified
if (_xpatchprefix == NULL) { if (_patch_mod_prefix == NULL) {
_xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true); _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true);
} }
_xpatchprefix->push(new ModuleXPatchPath(module_name, path)); _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
} }
// Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled) // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
@ -3441,6 +3538,15 @@ jint Arguments::finalize_vm_init_args() {
return JNI_ERR; return JNI_ERR;
} }
// Append the value of the last --add-modules option specified on the command line.
// This needs to be done here, to prevent overwriting possible values written
// to the jdk.module.addmods property by -javaagent and other options.
if (add_modules_value != NULL) {
if (!append_to_addmods_property(add_modules_value)) {
return JNI_ENOMEM;
}
}
// This must be done after all arguments have been processed. // This must be done after all arguments have been processed.
// java_compiler() true means set to "NONE" or empty. // java_compiler() true means set to "NONE" or empty.
if (java_compiler() && !xdebug_mode()) { if (java_compiler() && !xdebug_mode()) {
@ -3795,9 +3901,9 @@ jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_
void Arguments::set_shared_spaces_flags() { void Arguments::set_shared_spaces_flags() {
if (DumpSharedSpaces) { if (DumpSharedSpaces) {
if (Arguments::get_xpatchprefix() != NULL) { if (Arguments::get_patch_mod_prefix() != NULL) {
vm_exit_during_initialization( vm_exit_during_initialization(
"Cannot use the following option when dumping the shared archive", "-Xpatch"); "Cannot use the following option when dumping the shared archive: --patch-module");
} }
if (RequireSharedSpaces) { if (RequireSharedSpaces) {
@ -4180,6 +4286,11 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
hotspotrc, hotspotrc); hotspotrc, hotspotrc);
} }
if (needs_module_property_warning) {
warning("Ignoring system property options whose names start with '-Djdk.module'."
" They are reserved for internal use.");
}
#if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX. #if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
UNSUPPORTED_OPTION(UseLargePages); UNSUPPORTED_OPTION(UseLargePages);
#endif #endif
@ -4404,6 +4515,18 @@ int Arguments::PropertyList_count(SystemProperty* pl) {
return count; return count;
} }
// Return the number of readable properties.
int Arguments::PropertyList_readable_count(SystemProperty* pl) {
int count = 0;
while(pl != NULL) {
if (pl->is_readable()) {
count++;
}
pl = pl->next();
}
return count;
}
const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) { const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
assert(key != NULL, "just checking"); assert(key != NULL, "just checking");
SystemProperty* prop; SystemProperty* prop;
@ -4413,6 +4536,27 @@ const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* ke
return NULL; return NULL;
} }
// Return the value of the requested property provided that it is a readable property.
const char* Arguments::PropertyList_get_readable_value(SystemProperty *pl, const char* key) {
assert(key != NULL, "just checking");
SystemProperty* prop;
// Return the property value if the keys match and the property is not internal or
// it's the special internal property "jdk.boot.class.path.append".
for (prop = pl; prop != NULL; prop = prop->next()) {
if (strcmp(key, prop->key()) == 0) {
if (!prop->internal()) {
return prop->value();
} else if (strcmp(key, "jdk.boot.class.path.append") == 0) {
return prop->value();
} else {
// Property is internal and not jdk.boot.class.path.append so return NULL.
return NULL;
}
}
}
return NULL;
}
const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) { const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
int count = 0; int count = 0;
const char* ret_val = NULL; const char* ret_val = NULL;
@ -4457,11 +4601,12 @@ void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p)
} }
} }
void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) { void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v,
bool writeable, bool internal) {
if (plist == NULL) if (plist == NULL)
return; return;
SystemProperty* new_p = new SystemProperty(k, v, true); SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
PropertyList_add(plist, new_p); PropertyList_add(plist, new_p);
} }
@ -4470,7 +4615,9 @@ void Arguments::PropertyList_add(SystemProperty *element) {
} }
// This add maintains unique property key in the list. // This add maintains unique property key in the list.
void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) { void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
PropertyAppendable append, PropertyWriteable writeable,
PropertyInternal internal) {
if (plist == NULL) if (plist == NULL)
return; return;
@ -4478,16 +4625,16 @@ void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, c
SystemProperty* prop; SystemProperty* prop;
for (prop = *plist; prop != NULL; prop = prop->next()) { for (prop = *plist; prop != NULL; prop = prop->next()) {
if (strcmp(k, prop->key()) == 0) { if (strcmp(k, prop->key()) == 0) {
if (append) { if (append == AppendProperty) {
prop->append_value(v); prop->append_value(v);
} else { } else {
prop->set_writeable_value(v); prop->set_value(v);
} }
return; return;
} }
} }
PropertyList_add(plist, k, v); PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
} }
// Copies src into buf, replacing "%%" with "%" and "%p" with pid // Copies src into buf, replacing "%%" with "%" and "%p" with pid

View File

@ -43,7 +43,7 @@ extern "C" {
// PathString is used as: // PathString is used as:
// - the underlying value for a SystemProperty // - the underlying value for a SystemProperty
// - the path portion of an -Xpatch module/path pair // - the path portion of an --patch-module module/path pair
// - the string that represents the system boot class path, Arguments::_system_boot_class_path. // - the string that represents the system boot class path, Arguments::_system_boot_class_path.
class PathString : public CHeapObj<mtArguments> { class PathString : public CHeapObj<mtArguments> {
protected: protected:
@ -107,13 +107,13 @@ class PathString : public CHeapObj<mtArguments> {
} }
}; };
// ModuleXPatchPath records the module/path pair as specified to -Xpatch. // ModulePatchPath records the module/path pair as specified to --patch-module.
class ModuleXPatchPath : public CHeapObj<mtInternal> { class ModulePatchPath : public CHeapObj<mtInternal> {
private: private:
char* _module_name; char* _module_name;
PathString* _path; PathString* _path;
public: public:
ModuleXPatchPath(const char* module_name, const char* path) { ModulePatchPath(const char* module_name, const char* path) {
assert(module_name != NULL && path != NULL, "Invalid module name or path value"); assert(module_name != NULL && path != NULL, "Invalid module name or path value");
size_t len = strlen(module_name) + 1; size_t len = strlen(module_name) + 1;
_module_name = AllocateHeap(len, mtInternal); _module_name = AllocateHeap(len, mtInternal);
@ -121,7 +121,7 @@ public:
_path = new PathString(path); _path = new PathString(path);
} }
~ModuleXPatchPath() { ~ModulePatchPath() {
if (_module_name != NULL) { if (_module_name != NULL) {
FreeHeap(_module_name); FreeHeap(_module_name);
_module_name = NULL; _module_name = NULL;
@ -158,6 +158,10 @@ class SystemProperty : public PathString {
SystemProperty* next() const { return _next; } SystemProperty* next() const { return _next; }
void set_next(SystemProperty* next) { _next = next; } void set_next(SystemProperty* next) { _next = next; }
bool is_readable() const {
return !_internal || strcmp(_key, "jdk.boot.class.path.append") == 0;
}
// A system property should only have its value set // A system property should only have its value set
// via an external interface if it is a writeable property. // via an external interface if it is a writeable property.
// The internal, non-writeable property jdk.boot.class.path.append // The internal, non-writeable property jdk.boot.class.path.append
@ -325,6 +329,21 @@ class Arguments : AllStatic {
arg_in_range = 0 arg_in_range = 0
}; };
enum PropertyAppendable {
AppendProperty,
AddProperty
};
enum PropertyWriteable {
WriteableProperty,
UnwriteableProperty
};
enum PropertyInternal {
InternalProperty,
ExternalProperty
};
private: private:
// a pointer to the flags file name if it is specified // a pointer to the flags file name if it is specified
@ -348,18 +367,18 @@ class Arguments : AllStatic {
static SystemProperty *_java_class_path; static SystemProperty *_java_class_path;
static SystemProperty *_jdk_boot_class_path_append; static SystemProperty *_jdk_boot_class_path_append;
// -Xpatch:module=<file>(<pathsep><file>)* // --patch-module=module=<file>(<pathsep><file>)*
// Each element contains the associated module name, path // Each element contains the associated module name, path
// string pair as specified to -Xpatch. // string pair as specified to --patch-module.
static GrowableArray<ModuleXPatchPath*>* _xpatchprefix; static GrowableArray<ModulePatchPath*>* _patch_mod_prefix;
// The constructed value of the system class path after // The constructed value of the system class path after
// argument processing and JVMTI OnLoad additions via // argument processing and JVMTI OnLoad additions via
// calls to AddToBootstrapClassLoaderSearch. This is the // calls to AddToBootstrapClassLoaderSearch. This is the
// final form before ClassLoader::setup_bootstrap_search(). // final form before ClassLoader::setup_bootstrap_search().
// Note: since -Xpatch is a module name/path pair, the system // Note: since --patch-module is a module name/path pair, the
// boot class path string no longer contains the "prefix" to // system boot class path string no longer contains the "prefix"
// the boot class path base piece as it did when // to the boot class path base piece as it did when
// -Xbootclasspath/p was supported. // -Xbootclasspath/p was supported.
static PathString *_system_boot_class_path; static PathString *_system_boot_class_path;
@ -462,7 +481,13 @@ class Arguments : AllStatic {
static vfprintf_hook_t _vfprintf_hook; static vfprintf_hook_t _vfprintf_hook;
// System properties // System properties
static bool add_property(const char* prop); static bool add_property(const char* prop, PropertyWriteable writeable=WriteableProperty,
PropertyInternal internal=ExternalProperty);
static bool create_property(const char* prop_name, const char* prop_value, PropertyInternal internal);
static bool create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count);
static int process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase);
// Miscellaneous system property setter // Miscellaneous system property setter
static bool append_to_addmods_property(const char* module_name); static bool append_to_addmods_property(const char* module_name);
@ -500,7 +525,7 @@ class Arguments : AllStatic {
static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args); const JavaVMInitArgs *cmd_line_args);
static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin); static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin);
static jint finalize_vm_init_args(); static jint finalize_vm_init_args();
static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type); static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
@ -708,16 +733,20 @@ class Arguments : AllStatic {
// Property List manipulation // Property List manipulation
static void PropertyList_add(SystemProperty *element); static void PropertyList_add(SystemProperty *element);
static void PropertyList_add(SystemProperty** plist, SystemProperty *element); static void PropertyList_add(SystemProperty** plist, SystemProperty *element);
static void PropertyList_add(SystemProperty** plist, const char* k, const char* v); static void PropertyList_add(SystemProperty** plist, const char* k, const char* v, bool writeable, bool internal);
static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v) {
PropertyList_unique_add(plist, k, v, false); static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
} PropertyAppendable append, PropertyWriteable writeable,
static void PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append); PropertyInternal internal);
static const char* PropertyList_get_value(SystemProperty* plist, const char* key); static const char* PropertyList_get_value(SystemProperty* plist, const char* key);
static const char* PropertyList_get_readable_value(SystemProperty* plist, const char* key);
static int PropertyList_count(SystemProperty* pl); static int PropertyList_count(SystemProperty* pl);
static int PropertyList_readable_count(SystemProperty* pl);
static const char* PropertyList_get_key_at(SystemProperty* pl,int index); static const char* PropertyList_get_key_at(SystemProperty* pl,int index);
static char* PropertyList_get_value_at(SystemProperty* pl,int index); static char* PropertyList_get_value_at(SystemProperty* pl,int index);
static bool is_internal_module_property(const char* option);
// Miscellaneous System property value getter and setters. // Miscellaneous System property value getter and setters.
static void set_dll_dir(const char *value) { _sun_boot_library_path->set_value(value); } static void set_dll_dir(const char *value) { _sun_boot_library_path->set_value(value); }
static void set_java_home(const char *value) { _java_home->set_value(value); } static void set_java_home(const char *value) { _java_home->set_value(value); }
@ -725,7 +754,7 @@ class Arguments : AllStatic {
static void set_ext_dirs(char *value) { _ext_dirs = os::strdup_check_oom(value); } static void set_ext_dirs(char *value) { _ext_dirs = os::strdup_check_oom(value); }
// Set up the underlying pieces of the system boot class path // Set up the underlying pieces of the system boot class path
static void add_xpatchprefix(const char *module_name, const char *path, bool* xpatch_javabase); static void add_patch_mod_prefix(const char *module_name, const char *path, bool* patch_mod_javabase);
static void set_sysclasspath(const char *value, bool has_jimage) { static void set_sysclasspath(const char *value, bool has_jimage) {
// During start up, set by os::set_boot_path() // During start up, set by os::set_boot_path()
assert(get_sysclasspath() == NULL, "System boot class path previously set"); assert(get_sysclasspath() == NULL, "System boot class path previously set");
@ -737,7 +766,7 @@ class Arguments : AllStatic {
_jdk_boot_class_path_append->append_value(value); _jdk_boot_class_path_append->append_value(value);
} }
static GrowableArray<ModuleXPatchPath*>* get_xpatchprefix() { return _xpatchprefix; } static GrowableArray<ModulePatchPath*>* get_patch_mod_prefix() { return _patch_mod_prefix; }
static char* get_sysclasspath() { return _system_boot_class_path->value(); } static char* get_sysclasspath() { return _system_boot_class_path->value(); }
static char* get_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); } static char* get_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); }
static bool has_jimage() { return _has_jimage; } static bool has_jimage() { return _has_jimage; }

View File

@ -703,13 +703,15 @@ void defaultStream::start_log() {
// System properties don't generally contain newlines, so don't bother with unparsing. // System properties don't generally contain newlines, so don't bother with unparsing.
outputStream *text = xs->text(); outputStream *text = xs->text();
for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) {
// Print in two stages to avoid problems with long
// keys/values.
assert(p->key() != NULL, "p->key() is NULL"); assert(p->key() != NULL, "p->key() is NULL");
text->print_raw(p->key()); if (p->is_readable()) {
text->put('='); // Print in two stages to avoid problems with long
assert(p->value() != NULL, "p->value() is NULL"); // keys/values.
text->print_raw_cr(p->value()); text->print_raw(p->key());
text->put('=');
assert(p->value() != NULL, "p->value() is NULL");
text->print_raw_cr(p->value());
}
} }
xs->tail("properties"); xs->tail("properties");
} }

View File

@ -46,12 +46,12 @@ requires.properties= \
vm.gc.Parallel \ vm.gc.Parallel \
vm.gc.ConcMarkSweep vm.gc.ConcMarkSweep
# Tests using jtreg 4.2 b02 features # Tests using jtreg 4.2 b03 features
requiredVersion=4.2 b02 requiredVersion=4.2 b03
# Path to libraries in the topmost test directory. This is needed so @library # Path to libraries in the topmost test directory. This is needed so @library
# does not need ../../ notation to reach them # does not need ../../ notation to reach them
external.lib.roots = ../../ external.lib.roots = ../../
# Use new form of -Xpatch # Use new module options
useNewXpatch=true useNewOptions=true

View File

@ -40,7 +40,7 @@
* -XX:CompileCommand=dontinline,compiler.unsafe.UnsafeGetConstantField::checkGetAddress * -XX:CompileCommand=dontinline,compiler.unsafe.UnsafeGetConstantField::checkGetAddress
* -XX:CompileCommand=dontinline,*::test* * -XX:CompileCommand=dontinline,*::test*
* -XX:+UseUnalignedAccesses * -XX:+UseUnalignedAccesses
* -XaddReads:java.base=ALL-UNNAMED * --add-reads=java.base=ALL-UNNAMED
* compiler.unsafe.UnsafeGetConstantField * compiler.unsafe.UnsafeGetConstantField
* *
* @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions * @run main/bootclasspath/othervm -XX:+UnlockDiagnosticVMOptions
@ -50,7 +50,7 @@
* -XX:CompileCommand=dontinline,*::test* * -XX:CompileCommand=dontinline,*::test*
* -XX:CompileCommand=inline,*Unsafe::get* * -XX:CompileCommand=inline,*Unsafe::get*
* -XX:-UseUnalignedAccesses * -XX:-UseUnalignedAccesses
* -XaddReads:java.base=ALL-UNNAMED * --add-reads=java.base=ALL-UNNAMED
* compiler.unsafe.UnsafeGetConstantField * compiler.unsafe.UnsafeGetConstantField
*/ */

View File

@ -88,7 +88,7 @@ public class TestMaxMinHeapFreeRatioFlags {
(useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio), (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
"-Xmx" + MAX_HEAP_SIZE, "-Xmx" + MAX_HEAP_SIZE,
"-Xms" + HEAP_SIZE, "-Xms" + HEAP_SIZE,
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-XX:NewSize=" + NEW_SIZE, "-XX:NewSize=" + NEW_SIZE,
"-XX:MaxNewSize=" + MAX_NEW_SIZE, "-XX:MaxNewSize=" + MAX_NEW_SIZE,
"-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps", "-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps",
@ -120,7 +120,7 @@ public class TestMaxMinHeapFreeRatioFlags {
Collections.addAll(vmOptions, Collections.addAll(vmOptions,
(useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio), (useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
(useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio), (useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-version" "-version"
); );
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()])); ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));

View File

@ -74,7 +74,7 @@ public class TestSurvivorRatioFlag {
Collections.addAll(vmOptions, Collections.addAll(vmOptions,
"-Xbootclasspath/a:.", "-Xbootclasspath/a:.",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI", "-XX:+WhiteBoxAPI",
"-XX:GCLockerEdenExpansionPercent=0", "-XX:GCLockerEdenExpansionPercent=0",

View File

@ -132,7 +132,7 @@ public class TestTargetSurvivorRatioFlag {
LinkedList<String> vmOptions = new LinkedList<>(options); LinkedList<String> vmOptions = new LinkedList<>(options);
Collections.addAll(vmOptions, Collections.addAll(vmOptions,
"-Xbootclasspath/a:.", "-Xbootclasspath/a:.",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI", "-XX:+WhiteBoxAPI",
"-XX:+UseAdaptiveSizePolicy", "-XX:+UseAdaptiveSizePolicy",

View File

@ -53,7 +53,7 @@ public class TestShrinkAuxiliaryData {
"-Xlog:gc=debug", "-Xlog:gc=debug",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI", "-XX:+WhiteBoxAPI",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-Xbootclasspath/a:.", "-Xbootclasspath/a:.",
}; };

View File

@ -48,7 +48,7 @@ public class BootstrapRedefine {
"-Xmodule:java.base"), "-Xmodule:java.base"),
"mods/java.base"); "mods/java.base");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base", "-version"); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.base=mods/java.base", "-version");
new OutputAnalyzer(pb.start()) new OutputAnalyzer(pb.start())
.shouldContain("Incompatible definition of java.lang.Object") .shouldContain("Incompatible definition of java.lang.Object")
.shouldHaveExitValue(1); .shouldHaveExitValue(1);

View File

@ -27,7 +27,7 @@ import java.io.File;
* @test * @test
* @build BootClassPathAppendProp * @build BootClassPathAppendProp
* @run main/othervm -Xbootclasspath/a:/usr/lib -showversion -Xbootclasspath/a:/i/dont/exist BootClassPathAppendProp * @run main/othervm -Xbootclasspath/a:/usr/lib -showversion -Xbootclasspath/a:/i/dont/exist BootClassPathAppendProp
* @run main/othervm -Xpatch:/not/here -Xbootclasspath/a:/i/may/exist BootClassPathAppendProp * @run main/othervm --patch-module=no_module=/not/here -Xbootclasspath/a:/i/may/exist BootClassPathAppendProp
* @run main/othervm -Djdk.boot.class.path.append=newdir BootClassPathAppendProp * @run main/othervm -Djdk.boot.class.path.append=newdir BootClassPathAppendProp
* @run main/othervm BootClassPathAppendProp * @run main/othervm BootClassPathAppendProp
*/ */

View File

@ -56,7 +56,7 @@ public class CreateCoredumpOnCrash {
public static OutputAnalyzer runTest(String option) throws Exception { public static OutputAnalyzer runTest(String option) throws Exception {
return new OutputAnalyzer( return new OutputAnalyzer(
ProcessTools.createJavaProcessBuilder( ProcessTools.createJavaProcessBuilder(
"-Xmx64m", "-XX:-TransmitErrorReport", "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", option, Crasher.class.getName()) "-Xmx64m", "-XX:-TransmitErrorReport", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", option, Crasher.class.getName())
.start()); .start());
} }
} }

View File

@ -48,7 +48,7 @@ public class ProblematicFrameTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xmx64m", "-XX:-TransmitErrorReport", "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:-CreateCoredumpOnCrash", Crasher.class.getName()); "-Xmx64m", "-XX:-TransmitErrorReport", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:-CreateCoredumpOnCrash", Crasher.class.getName());
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Exception in thread"); output.shouldNotContain("Exception in thread");
output.shouldNotMatch("error occurred during error reporting \\(printing problematic frame\\)"); output.shouldNotMatch("error occurred during error reporting \\(printing problematic frame\\)");

View File

@ -160,10 +160,10 @@ public class BootAppendTests {
// Test #3: If a class on -Xbootclasspath/a is from a package defined in boot modules, // Test #3: If a class on -Xbootclasspath/a is from a package defined in boot modules,
// the class can be loaded from -Xbootclasspath/a when the module is excluded // the class can be loaded from -Xbootclasspath/a when the module is excluded
// using -limitmods. Verify the behavior is the same at runtime when CDS is // using --limit-modules. Verify the behavior is the same at runtime when CDS
// enabled. // is enabled.
// //
// The java.desktop module is excluded using -limitmods at runtime, // The java.desktop module is excluded using --limit-modules at runtime,
// javax.sound.sampled.MyClass is archived from -Xbootclasspath/a. It can be // javax.sound.sampled.MyClass is archived from -Xbootclasspath/a. It can be
// loaded from the archive at runtime. // loaded from the archive at runtime.
public static void testBootAppendExcludedModuleClass() throws Exception { public static void testBootAppendExcludedModuleClass() throws Exception {
@ -174,7 +174,7 @@ public class BootAppendTests {
"-XX:+TraceClassLoading", "-XX:+TraceClassLoading",
"-cp", appJar, "-cp", appJar,
"-Xbootclasspath/a:" + bootAppendJar, "-Xbootclasspath/a:" + bootAppendJar,
"-limitmods", "java.base", "--limit-modules=java.base",
"-Xshare:" + mode, "-Xshare:" + mode,
APP_CLASS, APP_CLASS,
BOOT_APPEND_MODULE_CLASS_NAME); BOOT_APPEND_MODULE_CLASS_NAME);
@ -191,8 +191,8 @@ public class BootAppendTests {
// Test #4: If a class on -Xbootclasspath/a has the same fully qualified // Test #4: If a class on -Xbootclasspath/a has the same fully qualified
// name as a class defined in boot modules, the class is loaded // name as a class defined in boot modules, the class is loaded
// from -Xbootclasspath/a when the boot module is excluded using // from -Xbootclasspath/a when the boot module is excluded using
// -limitmods. Verify the behavior is the same at runtime when CDS is // --limit-modules. Verify the behavior is the same at runtime
// enabled. // when CDS is enabled.
// //
// The org.omg.CORBA.Context is a boot module class. The class // The org.omg.CORBA.Context is a boot module class. The class
// on -Xbootclasspath/a that has the same fully-qualified name // on -Xbootclasspath/a that has the same fully-qualified name
@ -206,7 +206,7 @@ public class BootAppendTests {
"-XX:+TraceClassLoading", "-XX:+TraceClassLoading",
"-cp", appJar, "-cp", appJar,
"-Xbootclasspath/a:" + bootAppendJar, "-Xbootclasspath/a:" + bootAppendJar,
"-limitmods", "java.base", "--limit-modules=java.base",
"-Xshare:" + mode, "-Xshare:" + mode,
APP_CLASS, APP_CLASS,
BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME); BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);

View File

@ -89,10 +89,11 @@ public class SASymbolTableTest {
long pid = p.getPid(); long pid = p.getPid();
System.out.println("Attaching agent " + pid); System.out.println("Attaching agent " + pid);
ProcessBuilder tool = ProcessTools.createJavaProcessBuilder( ProcessBuilder tool = ProcessTools.createJavaProcessBuilder(
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", "--add-modules=jdk.hotspot.agent",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
"SASymbolTableTestAgent", "SASymbolTableTestAgent",
Long.toString(pid)); Long.toString(pid));
OutputAnalyzer output = ProcessTools.executeProcess(tool); OutputAnalyzer output = ProcessTools.executeProcess(tool);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ public class RangeCheck {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
true, true,
"-Xmx32m", "-Xmx32m",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-XX:-TransmitErrorReport", "-XX:-TransmitErrorReport",
"-XX:-CreateCoredumpOnCrash", "-XX:-CreateCoredumpOnCrash",
"-XX:-InlineUnsafeOps", // The compiler intrinsics doesn't have the assert "-XX:-InlineUnsafeOps", // The compiler intrinsics doesn't have the assert

View File

@ -98,7 +98,7 @@ public class GetSysPkgTest {
ClassFileInstaller.writeClassToDisk("GetSysPkg_package/GetSysClass", klassbuf); ClassFileInstaller.writeClassToDisk("GetSysPkg_package/GetSysClass", klassbuf);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:bl_dir", ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:bl_dir",
"-XaddExports:java.base/jdk.internal.loader=ALL-UNNAMED", "-cp", "." + File.pathSeparator + "--add-exports=java.base/jdk.internal.loader=ALL-UNNAMED", "-cp", "." + File.pathSeparator +
System.getProperty("test.classes"), "GetSysPkgTest", "do_tests"); System.getProperty("test.classes"), "GetSysPkgTest", "do_tests");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2016, 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 8136930
* @summary Test that the VM ignores explicitly specified module internal properties.
* @modules java.base/jdk.internal.misc
* @library /testlibrary
*/
import jdk.test.lib.*;
// Test that the VM ignores module related properties such as "jdk.module.addmods"
// and jdk.module.addreads.0" that can only be set using module options.
public class IgnoreModulePropertiesTest {
// Test that the specified property and its value are ignored. If the VM accepted
// the property and value then an exception would be thrown because the value is
// bogus for that property. But, since the property is ignored no exception is
// thrown.
public static void testProperty(String prop, String value) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-D" + prop + "=" + value, "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java version ");
output.shouldHaveExitValue(0);
// Ensure that the property and its value aren't available.
if (System.getProperty(prop) != null) {
throw new RuntimeException(
"Unexpected non-null value for property " + prop);
}
}
// For options of the form "option=value", check that an exception gets thrown for
// the illegal value and then check that its corresponding property is handled
// correctly.
public static void testOption(String option, String value,
String prop, String result) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
option + "=" + value, "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain(result);
testProperty(prop, value);
}
public static void main(String[] args) throws Exception {
testOption("--add-modules", "java.sqlx", "jdk.module.addmods", "java.lang.module.ResolutionException");
testOption("--limit-modules", "java.sqlx", "jdk.module.limitmods", "java.lang.module.ResolutionException");
testOption("--add-reads", "xyzz=yyzd", "jdk.module.addreads.0", "java.lang.RuntimeException");
testOption("--add-exports", "java.base/xyzz=yyzd", "jdk.module.addexports.0", "java.lang.RuntimeException");
testOption("--patch-module", "=d", "jdk.module.patch.0", "IllegalArgumentException");
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016, 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 8136930
* @summary Test that the VM only recognizes the last specified --add-modules
* and --list-modules options
* @modules java.base/jdk.internal.misc
* @library /testlibrary
*/
import jdk.test.lib.*;
// Test that the VM behaves correctly when processing module related options.
public class ModuleOptionsTest {
public static void main(String[] args) throws Exception {
// Test that last --add-modules is the only one recognized. No exception
// should be thrown.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"--add-modules=i_dont_exist", "--add-modules=java.base", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
// Test that last --limit-modules is the only one recognized. No exception
// should be thrown.
pb = ProcessTools.createJavaProcessBuilder(
"--limit-modules=i_dont_exist", "--limit-modules=java.base", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2016, 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 8162415
* @summary Test warnings for ignored properties.
* @modules java.base/jdk.internal.misc
* @library /testlibrary
*/
import jdk.test.lib.*;
// Test that the VM behaves correctly when processing command line module system properties.
public class ModuleOptionsWarn {
public static void main(String[] args) throws Exception {
// Test that a warning is issued for module related properties that get ignored.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+PrintWarnings", "-Djdk.module.ignored", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Ignoring system property option");
output.shouldHaveExitValue(0);
// Test that a warning can be suppressed for module related properties that get ignored.
pb = ProcessTools.createJavaProcessBuilder(
"-Djdk.module.ignored", "-XX:-PrintWarnings", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Ignoring system property option");
output.shouldHaveExitValue(0);
// Test that a warning is not issued for properties of the form "jdk.module.main"
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+PrintWarnings", "-Djdk.module.main.ignored", "-version");
output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Ignoring system property option");
output.shouldHaveExitValue(0);
}
}

View File

@ -62,8 +62,8 @@ public class ExportModuleStressTest {
compiled = CompilerUtils.compile( compiled = CompilerUtils.compile(
SRC_DIR.resolve("jdk.translet"), SRC_DIR.resolve("jdk.translet"),
MODS_DIR.resolve("jdk.translet"), MODS_DIR.resolve("jdk.translet"),
"-XaddExports:jdk.test/test=jdk.translet", "--add-exports=jdk.test/test=jdk.translet",
"-mp", MODS_DIR.toString()); "-p", MODS_DIR.toString());
if (!compiled) { if (!compiled) {
throw new RuntimeException("Test failed to compile module jdk.translet"); throw new RuntimeException("Test failed to compile module jdk.translet");
} }
@ -71,7 +71,7 @@ public class ExportModuleStressTest {
// Sanity check that the test, jdk.test/test/Main.java // Sanity check that the test, jdk.test/test/Main.java
// runs without error. // runs without error.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-mp", MODS_DIR.toString(), "-p", MODS_DIR.toString(),
"-m", "jdk.test/test.Main"); "-m", "jdk.test/test.Main");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("failed: 0") output.shouldContain("failed: 0")

View File

@ -62,8 +62,8 @@ public class ModuleStressGC {
compiled = CompilerUtils.compile( compiled = CompilerUtils.compile(
SRC_DIR.resolve("jdk.translet"), SRC_DIR.resolve("jdk.translet"),
MODS_DIR.resolve("jdk.translet"), MODS_DIR.resolve("jdk.translet"),
"-XaddExports:jdk.test/test=jdk.translet", "--add-exports=jdk.test/test=jdk.translet",
"-mp", MODS_DIR.toString()); "-p", MODS_DIR.toString());
if (!compiled) { if (!compiled) {
throw new RuntimeException("Test failed to compile module jdk.translet"); throw new RuntimeException("Test failed to compile module jdk.translet");
} }
@ -74,7 +74,7 @@ public class ModuleStressGC {
// GC safepoints. // GC safepoints.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xlog:modules=trace", "-Xlog:modules=trace",
"-mp", MODS_DIR.toString(), "-p", MODS_DIR.toString(),
"-m", "jdk.test/test.MainGC"); "-m", "jdk.test/test.MainGC");
OutputAnalyzer oa = new OutputAnalyzer(pb.start()); OutputAnalyzer oa = new OutputAnalyzer(pb.start());
oa.shouldContain("package test defined in module jdk.test, exports list being walked") oa.shouldContain("package test defined in module jdk.test, exports list being walked")

View File

@ -23,17 +23,17 @@
/* /*
* @test * @test
* @summary Make sure -Xpatch works with multiple directories. * @summary Make sure --patch-module works with multiple directories.
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
* @compile Xpatch2DirsMain.java * @compile PatchModule2DirsMain.java
* @run main Xpatch2Dirs * @run main PatchModule2Dirs
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
import java.io.File; import java.io.File;
public class Xpatch2Dirs { public class PatchModule2Dirs {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String source1 = "package javax.naming.spi; " + String source1 = "package javax.naming.spi; " +
@ -58,9 +58,9 @@ public class Xpatch2Dirs {
"mods2/java.desktop"); "mods2/java.desktop");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.naming=mods/java.naming", "--patch-module=java.naming=mods/java.naming",
"-Xpatch:java.desktop=mods2/java.desktop", "--patch-module=java.desktop=mods2/java.desktop",
"Xpatch2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder"); "PatchModule2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
OutputAnalyzer oa = new OutputAnalyzer(pb.start()); OutputAnalyzer oa = new OutputAnalyzer(pb.start());
oa.shouldContain("I pass one!"); oa.shouldContain("I pass one!");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -21,9 +21,9 @@
* questions. * questions.
*/ */
// This loads the class affected by the -Xpatch option. For the test to pass // This loads the class affected by the --patch-module option. For the test to pass
// it must load both classes from the -Xpatch directory, not the jimage file. // it must load both classes from the --patch-module directory, not the jimage file.
public class Xpatch2DirsMain { public class PatchModule2DirsMain {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Class.forName(args[0]); Class.forName(args[0]);
Class.forName(args[1]); Class.forName(args[1]);

View File

@ -25,22 +25,22 @@
* @test * @test
* @library /testlibrary * @library /testlibrary
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @run main XpatchCDS * @run main PatchModuleCDS
*/ */
import java.io.File; import java.io.File;
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchCDS { public class PatchModuleCDS {
public static void main(String args[]) throws Throwable { public static void main(String args[]) throws Throwable {
System.out.println("Test that -Xpatch and -Xshare:dump are incompatibable"); System.out.println("Test that --patch-module and -Xshare:dump are incompatibable");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", "-Xshare:dump"); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot use the following option when dumping the shared archive: -Xpatch"); output.shouldContain("Cannot use the following option when dumping the shared archive: --patch-module");
System.out.println("Test that -Xpatch and -Xshare:on are incompatibable"); System.out.println("Test that --patch-module and -Xshare:on are incompatibable");
String filename = "Xpatch.jsa"; String filename = "patch_module.jsa";
pb = ProcessTools.createJavaProcessBuilder( pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename, "-XX:SharedArchiveFile=" + filename,
@ -52,10 +52,10 @@ public class XpatchCDS {
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename, "-XX:SharedArchiveFile=" + filename,
"-Xshare:on", "-Xshare:on",
"-Xpatch:java.naming=mods/java.naming", "--patch-module=java.naming=mods/java.naming",
"-version"); "-version");
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("The shared archive file cannot be used with -Xpatch"); output.shouldContain("The shared archive file cannot be used with --patch-module");
output.shouldHaveExitValue(1); output.shouldHaveExitValue(1);
} }

View File

@ -23,23 +23,23 @@
/* /*
* @test * @test
* @summary VM exit initialization results if java.base is specificed more than once to Xpatch. * @summary VM exit initialization results if java.base is specificed more than once to --patch-module.
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchDupJavaBase { public class PatchModuleDupJavaBase {
// The VM should exit initialization if java.base is specified // The VM should exit initialization if java.base is specified
// more than once to -Xpatch. // more than once to --patch-module.
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.base=javabase_dir", "--patch-module=java.base=javabase_dir",
"-Xpatch:java.base=javabase_dir", "--patch-module=java.base=javabase_dir",
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("Cannot specify java.base more than once to -Xpatch"); output.shouldContain("Cannot specify java.base more than once to --patch-module");
output.shouldHaveExitValue(1); output.shouldHaveExitValue(1);
} }
} }

View File

@ -23,26 +23,25 @@
/* /*
* @test * @test
* @summary Module system initialization exception results if a module is specificed twice to Xpatch. * @summary Module system initialization exception results if a module is specificed twice to --patch-module.
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchDupModule { public class PatchModuleDupModule {
// The module system initialization should generate an ExceptionInInitializerError // The module system initialization should generate an ExceptionInInitializerError
// if -Xpatch is specified with the same module more than once. // if --patch-module is specified with the same module more than once.
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:module1=module1_dir", "--patch-module=module1=module1_dir",
"-Xpatch:module1=module1_dir", "--patch-module=module1=module1_dir",
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java.lang.ExceptionInInitializerError"); output.shouldContain("java.lang.ExceptionInInitializerError");
output.shouldHaveExitValue(1); output.shouldHaveExitValue(1);
} }
} }

View File

@ -24,16 +24,16 @@
/* /*
* @test * @test
* @bug 8130399 * @bug 8130399
* @summary Make sure -Xpatch works for java.base. * @summary Make sure --patch-module works for java.base.
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
* @compile XpatchMain.java * @compile PatchModuleMain.java
* @run main XpatchJavaBase * @run main PatchModuleJavaBase
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchJavaBase { public class PatchModuleJavaBase {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String source = "package java.lang; " + String source = "package java.lang; " +
@ -47,8 +47,8 @@ public class XpatchJavaBase {
InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"), InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
"mods/java.base"); "mods/java.base");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base", ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.base=mods/java.base",
"XpatchMain", "java.lang.NewClass"); "PatchModuleMain", "java.lang.NewClass");
new OutputAnalyzer(pb.start()) new OutputAnalyzer(pb.start())
.shouldContain("I pass!") .shouldContain("I pass!")

View File

@ -21,9 +21,9 @@
* questions. * questions.
*/ */
// This loads the class affected by the -Xpatch option. For the test to pass // This loads the class affected by the --patch-module option. For the test to pass
// it must load the class from the -Xpatch directory, not the jimage file. // it must load the class from the --patch-module directory, not the jimage file.
public class XpatchMain { public class PatchModuleMain {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Class.forName(args[0]); Class.forName(args[0]);
} }

View File

@ -24,16 +24,16 @@
/* /*
* @test * @test
* @bug 8130399 * @bug 8130399
* @summary Make sure -Xpatch works for modules besides java.base. * @summary Make sure --patch-module works for modules besides java.base.
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
* @compile XpatchMain.java * @compile PatchModuleMain.java
* @run main XpatchTest * @run main PatchModuleTest
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchTest { public class PatchModuleTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String source = "package javax.naming.spi; " + String source = "package javax.naming.spi; " +
@ -47,8 +47,8 @@ public class XpatchTest {
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"), InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
"mods/java.naming"); "mods/java.naming");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming",
"XpatchMain", "javax.naming.spi.NamingManager"); "PatchModuleMain", "javax.naming.spi.NamingManager");
new OutputAnalyzer(pb.start()) new OutputAnalyzer(pb.start())
.shouldContain("I pass!") .shouldContain("I pass!")

View File

@ -23,18 +23,18 @@
/* /*
* @test * @test
* @summary Make sure -Xpatch works when a jar file is specified for a module * @summary Make sure --patch-module works when a jar file is specified for a module
* @library /testlibrary * @library /testlibrary
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* jdk.jartool/sun.tools.jar * jdk.jartool/sun.tools.jar
* @build BasicJarBuilder * @build BasicJarBuilder
* @compile XpatchMain.java * @compile PatchModuleMain.java
* @run main XpatchTestJar * @run main PatchModuleTestJar
*/ */
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchTestJar { public class PatchModuleTestJar {
private static String moduleJar; private static String moduleJar;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -72,9 +72,9 @@ public class XpatchTestJar {
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"), InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
System.getProperty("test.classes")); System.getProperty("test.classes"));
// Supply -Xpatch with the name of the jar file for the module java.naming. // Supply --patch-module with the name of the jar file for the module java.naming.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + moduleJar, ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=" + moduleJar,
"XpatchMain", "javax.naming.spi.NamingManager"); "PatchModuleMain", "javax.naming.spi.NamingManager");
new OutputAnalyzer(pb.start()) new OutputAnalyzer(pb.start())
.shouldContain("I pass!") .shouldContain("I pass!")

View File

@ -23,20 +23,20 @@
/* /*
* @test * @test
* @summary Make sure -Xpatch works when a jar file and a directory is specified for a module * @summary Make sure --patch-module works when a jar file and a directory is specified for a module
* @library /testlibrary * @library /testlibrary
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* jdk.jartool/sun.tools.jar * jdk.jartool/sun.tools.jar
* @build BasicJarBuilder * @build BasicJarBuilder
* @compile Xpatch2DirsMain.java * @compile PatchModule2DirsMain.java
* @run main XpatchTestJarDir * @run main PatchModuleTestJarDir
*/ */
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchTestJarDir { public class PatchModuleTestJarDir {
private static String moduleJar; private static String moduleJar;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -88,12 +88,12 @@ public class XpatchTestJarDir {
(System.getProperty("test.classes") + "/mods/java.naming")); (System.getProperty("test.classes") + "/mods/java.naming"));
// Supply -Xpatch with the name of the jar file for the module java.naming. // Supply --patch-module with the name of the jar file for the module java.naming.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=" +
moduleJar + moduleJar +
File.pathSeparator + File.pathSeparator +
System.getProperty("test.classes") + "/mods/java.naming", System.getProperty("test.classes") + "/mods/java.naming",
"Xpatch2DirsMain", "PatchModule2DirsMain",
"javax.naming.spi.NamingManager1", "javax.naming.spi.NamingManager1",
"javax.naming.spi.NamingManager2"); "javax.naming.spi.NamingManager2");

View File

@ -25,17 +25,17 @@
* @test * @test
* @bug 8069469 * @bug 8069469
* @summary Make sure -Xlog:classload=info works properly with "modules" jimage, * @summary Make sure -Xlog:classload=info works properly with "modules" jimage,
-Xpatch, and with -Xbootclasspath/a --patch-module, and with -Xbootclasspath/a
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* @library /testlibrary * @library /testlibrary
* @compile XpatchMain.java * @compile PatchModuleMain.java
* @run main XpatchTraceCL * @run main PatchModuleTraceCL
*/ */
import java.io.File; import java.io.File;
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchTraceCL { public class PatchModuleTraceCL {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
String source = "package javax.naming.spi; " + String source = "package javax.naming.spi; " +
@ -45,39 +45,39 @@ public class XpatchTraceCL {
" } " + " } " +
"}"; "}";
// Test -Xlog:classload=info output for -Xpatch // Test -Xlog:classload=info output for --patch-module
ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager", ClassFileInstaller.writeClassToDisk("javax/naming/spi/NamingManager",
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"), InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
"mods/java.naming"); "mods/java.naming");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming",
"-Xlog:class+load=info", "XpatchMain", "javax.naming.spi.NamingManager"); "-Xlog:class+load=info", "PatchModuleMain", "javax.naming.spi.NamingManager");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
// "modules" jimage case. // "modules" jimage case.
output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base"); output.shouldContain("[class,load] java.lang.Thread source: jrt:/java.base");
// -Xpatch case. // --patch-module case.
output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming"); output.shouldContain("[class,load] javax.naming.spi.NamingManager source: mods/java.naming");
// -cp case. // -cp case.
output.shouldContain("[class,load] XpatchMain source: file"); output.shouldContain("[class,load] PatchModuleMain source: file");
// Test -Xlog:classload=info output for -Xbootclasspath/a // Test -Xlog:classload=info output for -Xbootclasspath/a
source = "package XpatchTraceCL_pkg; " + source = "package PatchModuleTraceCL_pkg; " +
"public class ItIsI { " + "public class ItIsI { " +
" static { " + " static { " +
" System.out.println(\"I also pass!\"); " + " System.out.println(\"I also pass!\"); " +
" } " + " } " +
"}"; "}";
ClassFileInstaller.writeClassToDisk("XpatchTraceCL_pkg/ItIsI", ClassFileInstaller.writeClassToDisk("PatchModuleTraceCL_pkg/ItIsI",
InMemoryJavaCompiler.compile("XpatchTraceCL_pkg.ItIsI", source), InMemoryJavaCompiler.compile("PatchModuleTraceCL_pkg.ItIsI", source),
"xbcp"); "xbcp");
pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp", pb = ProcessTools.createJavaProcessBuilder("-Xbootclasspath/a:xbcp",
"-Xlog:class+load=info", "XpatchMain", "XpatchTraceCL_pkg.ItIsI"); "-Xlog:class+load=info", "PatchModuleMain", "PatchModuleTraceCL_pkg.ItIsI");
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
// -Xbootclasspath/a case. // -Xbootclasspath/a case.
output.shouldContain("[class,load] XpatchTraceCL_pkg.ItIsI source: xbcp"); output.shouldContain("[class,load] PatchModuleTraceCL_pkg.ItIsI source: xbcp");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }
} }

View File

@ -23,13 +23,13 @@
/* /*
* @test * @test
* @summary Ensure that a newly introduced java.base package placed within the -Xpatch directory * @summary Ensure that a newly introduced java.base package placed within the --patch-module
* is considered part of the boot loader's visibility boundary * directory is considered part of the boot loader's visibility boundary
* @requires !(os.family == "windows") * @requires !(os.family == "windows")
* @library /testlibrary * @library /testlibrary
* @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.misc
* java.management * java.management
* @run main/othervm XpatchVisibility * @run main/othervm PatchModuleVisibility
*/ */
import java.io.File; import java.io.File;
@ -38,7 +38,7 @@ import java.nio.file.Paths;
import jdk.test.lib.*; import jdk.test.lib.*;
public class XpatchVisibility { public class PatchModuleVisibility {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
@ -55,19 +55,19 @@ public class XpatchVisibility {
"public class Vis2_A {" + "public class Vis2_A {" +
" public static void main(String args[]) throws Exception {" + " public static void main(String args[]) throws Exception {" +
// Try loading a class within a newly introduced java.base // Try loading a class within a newly introduced java.base
// package. Make sure the class can be found via -Xpatch. // package. Make sure the class can be found via --patch-module.
" try {" + " try {" +
" p2.Vis2_B b = new p2.Vis2_B();" + " p2.Vis2_B b = new p2.Vis2_B();" +
" if (b.getClass().getClassLoader() != null) {" + " if (b.getClass().getClassLoader() != null) {" +
" throw new RuntimeException(\"XpatchVisibility FAILED - class B " + " throw new RuntimeException(\"PatchModuleVisibility FAILED - class B " +
"should be loaded by boot class loader\\n\");" + "should be loaded by boot class loader\\n\");" +
" }" + " }" +
" b.m();" + " b.m();" +
" } catch (Throwable e) {" + " } catch (Throwable e) {" +
" throw new RuntimeException(\"XpatchVisibility FAILED - test " + " throw new RuntimeException(\"PatchModuleVisibility FAILED - test " +
"should not throw an error or exception\\n\");" + "should not throw an error or exception\\n\");" +
" }" + " }" +
" System.out.println(\"XpatchVisibility PASSED\\n\");" + " System.out.println(\"PatchModuleVisibility PASSED\\n\");" +
" }" + " }" +
"}"; "}";
@ -83,8 +83,8 @@ public class XpatchVisibility {
"p2" + File.separator + "Vis2_B.class")); "p2" + File.separator + "Vis2_B.class"));
new OutputAnalyzer(ProcessTools.createJavaProcessBuilder( new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.base=mods2/java.base", "--patch-module=java.base=mods2/java.base",
"-XaddExports:java.base/p2=ALL-UNNAMED", "--add-exports=java.base/p2=ALL-UNNAMED",
"Vis2_A") "Vis2_A")
.start()).shouldHaveExitValue(0); .start()).shouldHaveExitValue(0);
} }

View File

@ -50,7 +50,7 @@ public class XbootcpNoVisibility {
// Try loading a class within a named package in a module which has been defined // Try loading a class within a named package in a module which has been defined
// to the boot loader. In this situation, the class should only be attempted // to the boot loader. In this situation, the class should only be attempted
// to be loaded from the boot loader's module path which consists of: // to be loaded from the boot loader's module path which consists of:
// [-Xpatch]; exploded build | "modules" jimage // [--patch-module]; exploded build | "modules" jimage
// //
// Since the class is located on the boot loader's append path via // Since the class is located on the boot loader's append path via
// -Xbootclasspath/a specification, it should not be found. // -Xbootclasspath/a specification, it should not be found.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@ import java.lang.module.ModuleDescriptor;
/** /**
* A helper class intended to be injected into java.lang.reflect using the * A helper class intended to be injected into java.lang.reflect using the
* java -Xpatch option. The helper class provides access to package private * java --patch-module option. The helper class provides access to package private
* methods in java.lang.reflect.Module. * methods in java.lang.reflect.Module.
*/ */

View File

@ -113,9 +113,10 @@ public class TestInstanceKlassSize {
}; };
String[] toolArgs = { String[] toolArgs = {
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED", "--add-modules=jdk.hotspot.agent",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
"TestInstanceKlassSize", "TestInstanceKlassSize",
Long.toString(app.getPid()) Long.toString(app.getPid())
}; };

View File

@ -107,9 +107,10 @@ public class TestInstanceKlassSizeForInterface {
// Grab the pid from the current java process and pass it // Grab the pid from the current java process and pass it
String[] toolArgs = { String[] toolArgs = {
"-XX:+UnlockDiagnosticVMOptions", "-XX:+UnlockDiagnosticVMOptions",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED", "--add-modules=jdk.hotspot.agent",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.utilities=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
"TestInstanceKlassSizeForInterface", "TestInstanceKlassSizeForInterface",
Long.toString(ProcessTools.getProcessId()) Long.toString(ProcessTools.getProcessId())
}; };

View File

@ -87,7 +87,7 @@ public class JMapHProfLargeHeapTest {
String expectedFormat) throws Exception, IOException, String expectedFormat) throws Exception, IOException,
InterruptedException, FileNotFoundException { InterruptedException, FileNotFoundException {
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder( ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(
"-XaddExports:java.management/sun.management=ALL-UNNAMED", vmArgs, "JMapHProfLargeHeapProc", String.valueOf(heapSize)); "--add-exports=java.management/sun.management=ALL-UNNAMED", vmArgs, "JMapHProfLargeHeapProc", String.valueOf(heapSize));
procBuilder.redirectError(ProcessBuilder.Redirect.INHERIT); procBuilder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process largeHeapProc = procBuilder.start(); Process largeHeapProc = procBuilder.start();

View File

@ -58,10 +58,10 @@ cleantmp:
ctw.jar: filelist wb.jar ctw.jar: filelist wb.jar
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
$(JAVAC) -XaddExports:java.base/jdk.internal.jimage=ALL-UNNAMED \ $(JAVAC) --add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \
-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED \ --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
-XaddExports:java.base/jdk.internal.reflect=ALL-UNNAMED \ --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED \
-sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
$(JAR) --create --file=$@ --main-class $(MAIN_CLASS) -C $(OUTPUT_DIR) . $(JAR) --create --file=$@ --main-class $(MAIN_CLASS) -C $(OUTPUT_DIR) .
wb.jar: wb_filelist wb.jar: wb_filelist

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -95,10 +95,10 @@ manifest:
@echo 'Main-Class: jdk.test.lib.jittester.Automatic' >> $(MANIFEST) @echo 'Main-Class: jdk.test.lib.jittester.Automatic' >> $(MANIFEST)
compile_testlib: INIT compile_testlib: INIT
$(JAVAC) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR) $(JAVAC) -XDignore.symbol.file --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR)
COMPILE: INIT filelist compile_testlib COMPILE: INIT filelist compile_testlib
$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) @filelist $(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) @filelist
filelist: $(SRC_FILES) filelist: $(SRC_FILES)
@rm -f $@ @rm -f $@
@ -109,7 +109,7 @@ INIT: $(DIST_DIR)
$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi) $(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
install: clean_testbase testgroup testroot copytestlibrary JAR cleantmp install: clean_testbase testgroup testroot copytestlibrary JAR cleantmp
$(JAVA) -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -ea -jar $(DIST_JAR) $(APPLICATION_ARGS) $(JAVA) --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -ea -jar $(DIST_JAR) $(APPLICATION_ARGS)
clean_testbase: clean_testbase:
@rm -rf $(TESTBASE_DIR) @rm -rf $(TESTBASE_DIR)

View File

@ -373,3 +373,4 @@ bdc3c0b737efbf899709eb3121ce760dcfb51151 jdk-9+127
8a7681a9d70640ac7fbf05c28f53c1d51d8d00a1 jdk-9+128 8a7681a9d70640ac7fbf05c28f53c1d51d8d00a1 jdk-9+128
74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129 74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129
e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130 e66cdc2de6b02443911d386fc9217b0d824d0686 jdk-9+130
874082a9b565a7092a40bfa934a6e3e3c3455a60 jdk-9+131

View File

@ -37,5 +37,3 @@ parser.quantifier.2=Invalid quantifier. Invalid quantity or a '}' is missing.
parser.quantifier.3=Invalid quantifier. A digit or '}' is expected. parser.quantifier.3=Invalid quantifier. A digit or '}' is expected.
parser.quantifier.4=Invalid quantifier. A min quantity must be <= a max quantity. parser.quantifier.4=Invalid quantifier. A min quantity must be <= a max quantity.
parser.quantifier.5=Invalid quantifier. A quantity value overflow. parser.quantifier.5=Invalid quantifier. A quantity value overflow.
null
null

View File

@ -23,4 +23,7 @@ modules=java.xml
groups=TEST.groups groups=TEST.groups
# Minimum jtreg version # Minimum jtreg version
requiredVersion=4.2 b02 requiredVersion=4.2 b03
# Use new module options
useNewOptions=true

View File

@ -37,7 +37,7 @@ public class BasePolicy implements ITestListener {
try { try {
JAXPPolicyManager.teardownPolicyManager(); JAXPPolicyManager.teardownPolicyManager();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Failed to teardonw the policy manager", e); throw new RuntimeException("Failed to teardown the policy manager", e);
} }
} }

View File

@ -28,10 +28,8 @@ import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty; import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.net.SocketTimeoutException;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver; import javax.xml.transform.URIResolver;
@ -52,7 +50,7 @@ import org.xml.sax.SAXParseException;
/* /*
* @test * @test
* @bug 8158084 8162438 8162442 * @bug 8158084 8162438 8162442 8163535
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2 * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2
* @run testng/othervm catalog.CatalogSupport2 * @run testng/othervm catalog.CatalogSupport2
@ -97,7 +95,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on SAXParser. Verifies the Catalog support on SAXParser.
*/ */
@Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class) @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, String public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, String
xml, MyHandler handler, String expected) throws Exception { xml, MyHandler handler, String expected) throws Exception {
testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected); testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -106,7 +104,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on XMLReader. Verifies the Catalog support on XMLReader.
*/ */
@Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class) @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog, public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception { String xml, MyHandler handler, String expected) throws Exception {
testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected); testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -124,7 +122,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on DOM parser. Verifies the Catalog support on DOM parser.
*/ */
@Test(dataProvider = "data_DOMC", expectedExceptions = {FileNotFoundException.class, SocketTimeoutException.class}) @Test(dataProvider = "data_DOMC", expectedExceptions = IOException.class)
public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog, public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception { String xml, MyHandler handler, String expected) throws Exception {
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected); testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -141,7 +139,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
testValidation(setUseCatalog, useCatalog, catalog, xsd, resolver) ; testValidation(setUseCatalog, useCatalog, catalog, xsd, resolver) ;
} }
@Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, FileNotFoundException.class}) @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, IOException.class})
public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog, public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog,
Source source, LSResourceResolver resolver1, LSResourceResolver resolver2, Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
String catalog1, String catalog2) String catalog1, String catalog2)

View File

@ -27,10 +27,8 @@ import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty; import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.net.SocketTimeoutException;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver; import javax.xml.transform.URIResolver;
@ -51,7 +49,7 @@ import org.xml.sax.SAXParseException;
/* /*
* @test * @test
* @bug 8158084 8162438 8162442 * @bug 8158084 8162438 8162442 8163535
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3 * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3
* @run testng/othervm catalog.CatalogSupport3 * @run testng/othervm catalog.CatalogSupport3
@ -93,7 +91,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on SAXParser. Verifies the Catalog support on SAXParser.
*/ */
@Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class) @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception { String xml, MyHandler handler, String expected) throws Exception {
testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected); testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -102,7 +100,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on XMLReader. Verifies the Catalog support on XMLReader.
*/ */
@Test(dataProvider = "data_SAXC", expectedExceptions = FileNotFoundException.class) @Test(dataProvider = "data_SAXC", expectedExceptions = IOException.class)
public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog, public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception { String xml, MyHandler handler, String expected) throws Exception {
testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected); testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -120,7 +118,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/* /*
Verifies the Catalog support on DOM parser. Verifies the Catalog support on DOM parser.
*/ */
@Test(dataProvider = "data_DOMC", expectedExceptions = {FileNotFoundException.class, SocketTimeoutException.class}) @Test(dataProvider = "data_DOMC", expectedExceptions = IOException.class)
public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog, public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception { String xml, MyHandler handler, String expected) throws Exception {
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected); testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -141,7 +139,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
@bug 8158084 8162438 these tests also verifies the fix for 8162438 @bug 8158084 8162438 these tests also verifies the fix for 8162438
Verifies the Catalog support on the Schema Validator. Verifies the Catalog support on the Schema Validator.
*/ */
@Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, FileNotFoundException.class}) @Test(dataProvider = "data_ValidatorC", expectedExceptions = {SAXException.class, IOException.class})
public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog, public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog,
Source source, LSResourceResolver resolver1, LSResourceResolver resolver2, Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
String catalog1, String catalog2) String catalog1, String catalog2)

View File

@ -32,11 +32,10 @@ import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamSource;
@ -69,6 +68,7 @@ public class Bug6773084Test {
private static final ExecutorService EXEC = Executors.newCachedThreadPool(); private static final ExecutorService EXEC = Executors.newCachedThreadPool();
private static final CyclicBarrier BARRIER = new CyclicBarrier(NTHREADS); private static final CyclicBarrier BARRIER = new CyclicBarrier(NTHREADS);
private static final int TIMEOUT = 110;
public static final String IN_FOLDER = Bug6773084Test.class.getResource("Bug6773084In").getPath(); public static final String IN_FOLDER = Bug6773084Test.class.getResource("Bug6773084In").getPath();
public static final String XSD_PATH = Bug6773084Test.class.getResource("Bug6773084.xsd").getPath(); public static final String XSD_PATH = Bug6773084Test.class.getResource("Bug6773084.xsd").getPath();
@ -93,20 +93,23 @@ public class Bug6773084Test {
} }
}); });
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
for (int i = 0; i < files.length; i++) { for (int i = 0; i < files.length; i++) {
EXEC.execute(new XMLValiddator(files[i], i)); EXEC.execute(new XMLValiddator(dbf.newDocumentBuilder().parse(files[i]), i));
} }
runWithAllPerm(() -> EXEC.shutdown()); runWithAllPerm(() -> EXEC.shutdown());
EXEC.awaitTermination(TIMEOUT, TimeUnit.SECONDS);
} }
private static class XMLValiddator implements Runnable { private static class XMLValiddator implements Runnable {
private File file; private Document document;
private int index; private int index;
public XMLValiddator(File file, int index) { public XMLValiddator(Document document, int index) {
this.file = file; this.document = document;
this.index = index; this.index = index;
} }
@ -117,23 +120,14 @@ public class Bug6773084Test {
BARRIER.await(); BARRIER.await();
System.out.println("Validating...."); System.out.println("Validating....");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(file);
Validator validator = schema.newValidator(); Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandlerImpl()); validator.setErrorHandler(new ErrorHandlerImpl());
validator.validate(new DOMSource(document)); validator.validate(new DOMSource(document));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} catch (SAXException e) { } catch (SAXException e) {
e.printStackTrace(); e.printStackTrace();
Assert.fail("Test failed."); Assert.fail("Test failed.");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) { } catch (BrokenBarrierException e) {
e.printStackTrace(); e.printStackTrace();
} catch (InterruptedException e) { } catch (InterruptedException e) {

View File

@ -373,3 +373,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
9446c534f0222b4eecfd9d9e25ab37c4fd4400a5 jdk-9+128 9446c534f0222b4eecfd9d9e25ab37c4fd4400a5 jdk-9+128
47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129 47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129
6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130 6c827500e34587061af97ad6fef0e859280255c5 jdk-9+130
8c57f4c293bbc5609928308a6d91ba765760b5f9 jdk-9+131

View File

@ -42,6 +42,6 @@ $(GENGRAPHS_DIR)/technology-summary.html: $(TOOLS_MODULE_SRCDIR)/technology-summ
$(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/technology-summary.html $(GENGRAPHS_DIR)/module-summary.html: $(BUILD_JIGSAW_TOOLS) $(GENGRAPHS_DIR)/technology-summary.html
$(MKDIR) -p $(@D) $(MKDIR) -p $(@D)
$(TOOL_MODULESUMMARY) -o $@ -mp $(IMAGES_OUTPUTDIR)/jmods $(TOOL_MODULESUMMARY) -o $@ --module-path $(IMAGES_OUTPUTDIR)/jmods
all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html all: $(GENGRAPHS_DIR)/jdk.dot $(GENGRAPHS_DIR)/module-summary.html

View File

@ -36,12 +36,12 @@ $(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
INCLUDES := build/tools/deps \ INCLUDES := build/tools/deps \
build/tools/jigsaw, \ build/tools/jigsaw, \
BIN := $(TOOLS_CLASSES_DIR), \ BIN := $(TOOLS_CLASSES_DIR), \
ADD_JAVAC_FLAGS := -XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED )) ADD_JAVAC_FLAGS := --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED ))
TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \ TOOL_GENGRAPHS := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
build.tools.jigsaw.GenGraphs build.tools.jigsaw.GenGraphs
TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \ TOOL_MODULESUMMARY := $(BUILD_JAVA) -esa -ea -cp $(TOOLS_CLASSES_DIR) \
-XaddExports:jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \ --add-exports jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED \
build.tools.jigsaw.ModuleSummary build.tools.jigsaw.ModuleSummary

View File

@ -38,7 +38,7 @@ BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
################################################################################ ################################################################################
ifeq ($(BOOT_JDK_MODULAR), true) ifeq ($(BOOT_JDK_MODULAR), true)
COMPILEFONTCONFIG_ADD_EXPORTS := -XaddExports:java.desktop/sun.awt=ALL-UNNAMED COMPILEFONTCONFIG_ADD_EXPORTS := --add-exports java.desktop/sun.awt=ALL-UNNAMED
endif endif
TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ TOOL_COMPILEFONTCONFIG = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
@ -94,7 +94,7 @@ TOOL_SPP = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes build.too
# Nimbus is used somewhere in the swing build. # Nimbus is used somewhere in the swing build.
ifeq ($(BOOT_JDK_MODULAR), true) ifeq ($(BOOT_JDK_MODULAR), true)
COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind COMPILENIMBUS_ADD_MODS := --add-modules java.xml.bind
endif endif
TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \ TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \

View File

@ -203,7 +203,7 @@ TARGETS += $(DEF_POLICY_DST)
################################################################################ ################################################################################
ifeq ($(CACERTS_FILE), ) ifeq ($(CACERTS_FILE), )
CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/conf/security/cacerts CACERTS_FILE := $(JDK_TOPDIR)/src/java.base/share/lib/security/cacerts
endif endif
CACERTS_DST := $(LIB_DST_DIR)/security/cacerts CACERTS_DST := $(LIB_DST_DIR)/security/cacerts

View File

@ -63,11 +63,11 @@ $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
ifeq ($(BOOT_JDK_MODULAR), true) ifeq ($(BOOT_JDK_MODULAR), true)
BREAK_ITERATOR_BOOTCLASSPATH := \ BREAK_ITERATOR_BOOTCLASSPATH := \
-Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \ --patch-module java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
-Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \ --patch-module jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
-XaddExports:java.base/sun.text=ALL-UNNAMED \ --add-exports java.base/sun.text=ALL-UNNAMED \
-XaddExports:java.base/sun.text.resources=ALL-UNNAMED \ --add-exports java.base/sun.text.resources=ALL-UNNAMED \
-XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \ --add-exports jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
# #
else else
BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \ BREAK_ITERATOR_BOOTCLASSPATH := -Xbootclasspath/p:$(call PathList, \

View File

@ -31,7 +31,7 @@ $(eval $(call IncludeCustomExtension, jdk, launcher/Launcher-java.desktop.gmk))
ifndef BUILD_HEADLESS_ONLY ifndef BUILD_HEADLESS_ONLY
$(eval $(call SetupBuildLauncher, appletviewer, \ $(eval $(call SetupBuildLauncher, appletviewer, \
MAIN_CLASS := sun.applet.Main, \ MAIN_CLASS := sun.applet.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
LIBS_unix := $(X_LIBS), \ LIBS_unix := $(X_LIBS), \
)) ))
endif endif

View File

@ -27,5 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jrunscript, \ $(eval $(call SetupBuildLauncher, jrunscript, \
MAIN_CLASS := com.sun.tools.script.shell.Main, \ MAIN_CLASS := com.sun.tools.script.shell.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
)) ))

View File

@ -27,7 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javac, \ $(eval $(call SetupBuildLauncher, javac, \
MAIN_CLASS := com.sun.tools.javac.Main, \ MAIN_CLASS := com.sun.tools.javac.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
)) ))

View File

@ -27,7 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javadoc, \ $(eval $(call SetupBuildLauncher, javadoc, \
MAIN_CLASS := jdk.javadoc.internal.tool.Main, \ MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \
)) ))

View File

@ -32,7 +32,7 @@ $(eval $(call SetupBuildLauncher, jimage,\
$(eval $(call SetupBuildLauncher, jlink,\ $(eval $(call SetupBuildLauncher, jlink,\
MAIN_CLASS := jdk.tools.jlink.internal.Main, \ MAIN_CLASS := jdk.tools.jlink.internal.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES \ CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS \ -DEXPAND_CLASSPATH_WILDCARDS \
-DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \ -DNEVER_ACT_AS_SERVER_CLASS_MACHINE, \

View File

@ -27,6 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \ $(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \ MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \
CFLAGS := -DENABLE_ARG_FILES, \ CFLAGS := -DENABLE_ARG_FILES, \
)) ))

View File

@ -51,7 +51,7 @@ import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Selector.*;
import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*; import static build.tools.jigsaw.ModuleSummary.HtmlDocument.Division.*;
public class ModuleSummary { public class ModuleSummary {
private static final String USAGE = "Usage: ModuleSummary -mp <dir> -o <outfile> [-root mn]*"; private static final String USAGE = "Usage: ModuleSummary --module-path <dir> -o <outfile> [--root mn]*";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
int i=0; int i=0;
@ -61,13 +61,13 @@ public class ModuleSummary {
while (i < args.length && args[i].startsWith("-")) { while (i < args.length && args[i].startsWith("-")) {
String arg = args[i++]; String arg = args[i++];
switch (arg) { switch (arg) {
case "-mp": case "--module-path":
modpath = Paths.get(args[i++]); modpath = Paths.get(args[i++]);
break; break;
case "-o": case "-o":
outfile = Paths.get(args[i++]); outfile = Paths.get(args[i++]);
break; break;
case "-root": case "--root":
roots.add(args[i++]); roots.add(args[i++]);
default: default:
System.err.println(USAGE); System.err.println(USAGE);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -53,10 +53,37 @@ abstract class HmacCore extends MacSpi implements Cloneable {
private final int blockLen; private final int blockLen;
/** /**
* Standard constructor, creates a new HmacCore instance using the * Standard constructor, creates a new HmacCore instance instantiating
* specified MessageDigest object. * a MessageDigest of the specified name.
*/ */
HmacCore(MessageDigest md, int bl) { HmacCore(String digestAlgo, int bl) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance(digestAlgo);
if (!(md instanceof Cloneable)) {
// use SUN provider if the most preferred one does not support
// cloning
Provider sun = Security.getProvider("SUN");
if (sun != null) {
md = MessageDigest.getInstance(digestAlgo, sun);
} else {
String noCloneProv = md.getProvider().getName();
// if no Sun provider, use provider list
Provider[] provs = Security.getProviders();
for (Provider p : provs) {
try {
if (!p.getName().equals(noCloneProv)) {
MessageDigest md2 =
MessageDigest.getInstance(digestAlgo, p);
if (md2 instanceof Cloneable) {
md = md2;
break;
}
}
} catch (NoSuchAlgorithmException nsae) {
continue;
}
}
}
}
this.md = md; this.md = md;
this.blockLen = bl; this.blockLen = bl;
this.k_ipad = new byte[blockLen]; this.k_ipad = new byte[blockLen];
@ -64,14 +91,6 @@ abstract class HmacCore extends MacSpi implements Cloneable {
first = true; first = true;
} }
/**
* Standard constructor, creates a new HmacCore instance instantiating
* a MessageDigest of the specified name.
*/
HmacCore(String digestAlgorithm, int bl) throws NoSuchAlgorithmException {
this(MessageDigest.getInstance(digestAlgorithm), bl);
}
/** /**
* Returns the length of the HMAC in bytes. * Returns the length of the HMAC in bytes.
* *

View File

@ -131,8 +131,10 @@ public class CharArrayReader extends Reader {
if (pos >= count) { if (pos >= count) {
return -1; return -1;
} }
if (pos + len > count) {
len = count - pos; int avail = count - pos;
if (len > avail) {
len = avail;
} }
if (len <= 0) { if (len <= 0) {
return 0; return 0;
@ -158,8 +160,10 @@ public class CharArrayReader extends Reader {
public long skip(long n) throws IOException { public long skip(long n) throws IOException {
synchronized (lock) { synchronized (lock) {
ensureOpen(); ensureOpen();
if (pos + n > count) {
n = count - pos; long avail = count - pos;
if (n > avail) {
n = avail;
} }
if (n < 0) { if (n < 0) {
return 0; return 0;

View File

@ -118,8 +118,10 @@ class StringBufferInputStream extends InputStream {
if (pos >= count) { if (pos >= count) {
return -1; return -1;
} }
if (pos + len > count) {
len = count - pos; int avail = count - pos;
if (len > avail) {
len = avail;
} }
if (len <= 0) { if (len <= 0) {
return 0; return 0;

View File

@ -644,23 +644,20 @@ public final class System {
* <code>getProperties</code> operation, it may choose to permit the * <code>getProperties</code> operation, it may choose to permit the
* {@link #getProperty(String)} operation. * {@link #getProperty(String)} operation.
* *
* @implNote In addition to the standard system properties, the {@code * @implNote In addition to the standard system properties, the system
* java} launcher may create the Java Virtual Machine with system * properties may include the following keys:
* properties that have the following keys:
* <table summary="Shows property keys and associated values"> * <table summary="Shows property keys and associated values">
* <tr><th>Key</th> * <tr><th>Key</th>
* <th>Description of Associated Value</th></tr> * <th>Description of Associated Value</th></tr>
* <tr><td>{@code jdk.module.path}</td> * <tr><td>{@code jdk.module.path}</td>
* <td>Application module path</td></tr> * <td>The application module path</td></tr>
* <tr><td>{@code jdk.upgrade.module.path}</td> * <tr><td>{@code jdk.module.upgrade.path}</td>
* <td>The upgrade module path</td></tr> * <td>The upgrade module path</td></tr>
* <tr><td>{@code jdk.module.main}</td> * <tr><td>{@code jdk.module.main}</td>
* <td>The module name of the initial/main module</td></tr> * <td>The module name of the initial/main module</td></tr>
* <tr><td>{@code jdk.module.main.class}</td> * <tr><td>{@code jdk.module.main.class}</td>
* <td>The main class name of the initial module</td></tr> * <td>The main class name of the initial module</td></tr>
* </table> * </table>
* These properties may also be set by custom launchers that use the JNI
* invocation API to create the Java Virtual Machine.
* *
* @return the system properties * @return the system properties
* @exception SecurityException if a security manager exists and its * @exception SecurityException if a security manager exists and its

View File

@ -587,26 +587,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
return bmhClass; return bmhClass;
} }
/** static String speciesInternalClassName(String shortTypes) {
* @implNote this method is used by GenerateBMHClassesPlugin to enable
* ahead-of-time generation of BMH classes at link time. It does
* added validation since this string may be user provided.
*/
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new IllegalArgumentException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
String shortTypes = LambdaForm.shortenSignature(types);
final String className = speciesInternalClassName(shortTypes);
return Map.entry(className,
generateConcreteBMHClassBytes(shortTypes, types, className));
}
private static String speciesInternalClassName(String shortTypes) {
return SPECIES_PREFIX_PATH + shortTypes; return SPECIES_PREFIX_PATH + shortTypes;
} }
@ -865,7 +846,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
} }
} }
private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP; static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
/** /**
* All subclasses must provide such a value describing their type signature. * All subclasses must provide such a value describing their type signature.

View File

@ -186,7 +186,7 @@ class DirectMethodHandle extends MethodHandle {
return mtype.form().setCachedLambdaForm(which, lform); return mtype.form().setCachedLambdaForm(which, lform);
} }
private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
boolean needsInit = (which == LF_INVSTATIC_INIT); boolean needsInit = (which == LF_INVSTATIC_INIT);
boolean doesAlloc = (which == LF_NEWINVSPECIAL); boolean doesAlloc = (which == LF_NEWINVSPECIAL);
String linkerName, lambdaName; String linkerName, lambdaName;
@ -248,20 +248,6 @@ class DirectMethodHandle extends MethodHandle {
return lform; return lform;
} }
/*
* NOTE: This method acts as an API hook for use by the
* GenerateJLIClassesPlugin to generate a class wrapping DirectMethodHandle
* methods for an array of method types.
*/
static byte[] generateDMHClassBytes(String className, MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length];
for (int i = 0; i < forms.length; i++) {
forms[i] = makePreparedLambdaForm(methodTypes[i], types[i]);
methodTypes[i] = forms[i].methodType();
}
return InvokerBytecodeGenerator.generateCodeBytesForMultiple(className, forms, methodTypes);
}
static Object findDirectMethodHandle(Name name) { static Object findDirectMethodHandle(Name name) {
if (name.function == NF_internalMemberName || if (name.function == NF_internalMemberName ||
name.function == NF_internalMemberNameEnsureInit || name.function == NF_internalMemberNameEnsureInit ||
@ -273,7 +259,7 @@ class DirectMethodHandle extends MethodHandle {
} }
private static void maybeCompile(LambdaForm lform, MemberName m) { private static void maybeCompile(LambdaForm lform, MemberName m) {
if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class)) if (lform.vmentry == null && VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
// Help along bootstrapping... // Help along bootstrapping...
lform.compileToBytecode(); lform.compileToBytecode();
} }
@ -515,7 +501,7 @@ class DirectMethodHandle extends MethodHandle {
// Enumerate the different field kinds using Wrapper, // Enumerate the different field kinds using Wrapper,
// with an extra case added for checked references. // with an extra case added for checked references.
private static final int private static final int
FT_LAST_WRAPPER = Wrapper.values().length-1, FT_LAST_WRAPPER = Wrapper.COUNT-1,
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(), FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
FT_CHECKED_REF = FT_LAST_WRAPPER+1, FT_CHECKED_REF = FT_LAST_WRAPPER+1,
FT_LIMIT = FT_LAST_WRAPPER+2; FT_LIMIT = FT_LAST_WRAPPER+2;
@ -576,25 +562,36 @@ class DirectMethodHandle extends MethodHandle {
return lform; return lform;
} }
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) { private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1); boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
boolean isStatic = (formOp >= AF_GETSTATIC); boolean isStatic = (formOp >= AF_GETSTATIC);
boolean needsInit = (formOp >= AF_GETSTATIC_INIT); boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
boolean needsCast = (ftypeKind == FT_CHECKED_REF); boolean needsCast = (ftypeKind == FT_CHECKED_REF);
Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]); Wrapper fw = (needsCast ? Wrapper.OBJECT : ALL_WRAPPERS[ftypeKind]);
Class<?> ft = fw.primitiveType(); Class<?> ft = fw.primitiveType();
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind); assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
String tname = fw.primitiveSimpleName();
String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1); // getObject, putIntVolatile, etc.
if (isVolatile) ctname += "Volatile"; StringBuilder nameBuilder = new StringBuilder();
String getOrPut = (isGetter ? "get" : "put"); if (isGetter) {
String linkerName = (getOrPut + ctname); // getObject, putIntVolatile, etc. nameBuilder.append("get");
} else {
nameBuilder.append("put");
}
nameBuilder.append(fw.primitiveSimpleName());
nameBuilder.setCharAt(3, Character.toUpperCase(nameBuilder.charAt(3)));
if (isVolatile) {
nameBuilder.append("Volatile");
}
MethodType linkerType; MethodType linkerType;
if (isGetter) if (isGetter)
linkerType = MethodType.methodType(ft, Object.class, long.class); linkerType = MethodType.methodType(ft, Object.class, long.class);
else else
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft); linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual); MemberName linker = new MemberName(Unsafe.class, nameBuilder.toString(), linkerType, REF_invokeVirtual);
try { try {
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class); linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
@ -649,11 +646,16 @@ class DirectMethodHandle extends MethodHandle {
if (needsCast && isGetter) if (needsCast && isGetter)
names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
for (Name n : names) assert(n != null); for (Name n : names) assert(n != null);
String fieldOrStatic = (isStatic ? "Static" : "Field"); // add some detail to the lambdaForm debugname,
String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging // significant only for debugging
if (needsCast) lambdaName += "Cast"; if (isStatic) {
if (needsInit) lambdaName += "Init"; nameBuilder.append("Static");
return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } else {
nameBuilder.append("Field");
}
if (needsCast) nameBuilder.append("Cast");
if (needsInit) nameBuilder.append("Init");
return new LambdaForm(nameBuilder.toString(), ARG_LIMIT, names, RESULT);
} }
/** /**

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 java.lang.invoke;
import java.util.Map;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* Helper class to assist the GenerateJLIClassesPlugin to get access to
* generate classes ahead of time.
*/
class GenerateJLIClassesHelper {
static byte[] generateDMHClassBytes(String className,
MethodType[] methodTypes, int[] types) {
LambdaForm[] forms = new LambdaForm[methodTypes.length];
for (int i = 0; i < forms.length; i++) {
forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
types[i]);
methodTypes[i] = forms[i].methodType();
}
return generateCodeBytesForLFs(className, forms, methodTypes);
}
/*
* Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name.
*/
private static byte[] generateCodeBytesForLFs(String className,
LambdaForm[] forms, MethodType[] types) {
assert(forms.length == types.length);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
for (int i = 0; i < forms.length; i++) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, forms[i], types[i]);
g.setClassWriter(cw);
g.addMethod();
}
return cw.toByteArray();
}
static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
for (char c : types.toCharArray()) {
if ("LIJFD".indexOf(c) < 0) {
throw new IllegalArgumentException("All characters must "
+ "correspond to a basic field type: LIJFD");
}
}
String shortTypes = LambdaForm.shortenSignature(types);
final String className =
BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
return Map.entry(className,
BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
shortTypes, types, className));
}
}

View File

@ -40,8 +40,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Arrays; import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.LambdaForm.*;
@ -68,9 +68,10 @@ class InvokerBytecodeGenerator {
private static final String LFN_SIG = "L" + LFN + ";"; private static final String LFN_SIG = "L" + LFN + ";";
private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V";
private static final String CLASS_PREFIX = LF + "$";
/** Name of its super class*/ /** Name of its super class*/
private static final String INVOKER_SUPER_NAME = OBJ; static final String INVOKER_SUPER_NAME = OBJ;
/** Name of new class */ /** Name of new class */
private final String className; private final String className;
@ -96,15 +97,15 @@ class InvokerBytecodeGenerator {
/** Main constructor; other constructors delegate to this one. */ /** Main constructor; other constructors delegate to this one. */
private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize, private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
String className, String invokerName, MethodType invokerType) { String className, String invokerName, MethodType invokerType) {
if (invokerName.contains(".")) { int p = invokerName.indexOf('.');
int p = invokerName.indexOf('.'); if (p > -1) {
className = invokerName.substring(0, p); className = invokerName.substring(0, p);
invokerName = invokerName.substring(p+1); invokerName = invokerName.substring(p + 1);
} }
if (DUMP_CLASS_FILES) { if (DUMP_CLASS_FILES) {
className = makeDumpableClassName(className); className = makeDumpableClassName(className);
} }
this.className = LF + "$" + className; this.className = CLASS_PREFIX + className;
this.sourceFile = "LambdaForm$" + className; this.sourceFile = "LambdaForm$" + className;
this.lambdaForm = lambdaForm; this.lambdaForm = lambdaForm;
this.invokerName = invokerName; this.invokerName = invokerName;
@ -124,7 +125,7 @@ class InvokerBytecodeGenerator {
} }
/** For generating customized code for a single LambdaForm. */ /** For generating customized code for a single LambdaForm. */
private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) { InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
this(form, form.names.length, this(form, form.names.length,
className, form.debugName, invokerType); className, form.debugName, invokerType);
// Create an array to map name indexes to locals indexes. // Create an array to map name indexes to locals indexes.
@ -201,38 +202,34 @@ class InvokerBytecodeGenerator {
class CpPatch { class CpPatch {
final int index; final int index;
final String placeholder;
final Object value; final Object value;
CpPatch(int index, String placeholder, Object value) { CpPatch(int index, Object value) {
this.index = index; this.index = index;
this.placeholder = placeholder;
this.value = value; this.value = value;
} }
public String toString() { public String toString() {
return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value; return "CpPatch/index="+index+",value="+value;
} }
} }
Map<Object, CpPatch> cpPatches = new HashMap<>(); private final ArrayList<CpPatch> cpPatches = new ArrayList<>();
int cph = 0; // for counting constant placeholders private int cph = 0; // for counting constant placeholders
String constantPlaceholder(Object arg) { String constantPlaceholder(Object arg) {
String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++; String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>"; // debugging aid if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
if (cpPatches.containsKey(cpPlaceholder)) { // TODO check if arg is already in the constant pool
throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
}
// insert placeholder in CP and remember the patch // insert placeholder in CP and remember the patch
int index = cw.newConst((Object) cpPlaceholder); // TODO check if already in the constant pool int index = cw.newConst((Object) cpPlaceholder);
cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg)); cpPatches.add(new CpPatch(index, arg));
return cpPlaceholder; return cpPlaceholder;
} }
Object[] cpPatches(byte[] classFile) { Object[] cpPatches(byte[] classFile) {
int size = getConstantPoolSize(classFile); int size = getConstantPoolSize(classFile);
Object[] res = new Object[size]; Object[] res = new Object[size];
for (CpPatch p : cpPatches.values()) { for (CpPatch p : cpPatches) {
if (p.index >= size) if (p.index >= size)
throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20))); throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
res[p.index] = p.value; res[p.index] = p.value;
@ -655,35 +652,11 @@ class InvokerBytecodeGenerator {
return classFile; return classFile;
} }
/* void setClassWriter(ClassWriter cw) {
* NOTE: This is used from GenerateJLIClassesPlugin via
* DirectMethodHandle::generateDMHClassBytes.
*
* Generate customized code for a set of LambdaForms of specified types into
* a class with a specified name.
*/
static byte[] generateCodeBytesForMultiple(String className,
LambdaForm[] forms, MethodType[] types) {
assert(forms.length == types.length);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
className, null, INVOKER_SUPER_NAME, null);
cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
for (int i = 0; i < forms.length; i++) {
InvokerBytecodeGenerator g
= new InvokerBytecodeGenerator(className, forms[i], types[i]);
g.setClassWriter(cw);
g.addMethod();
}
return cw.toByteArray();
}
private void setClassWriter(ClassWriter cw) {
this.cw = cw; this.cw = cw;
} }
private void addMethod() { void addMethod() {
methodPrologue(); methodPrologue();
// Suppress this method in backtraces displayed to the user. // Suppress this method in backtraces displayed to the user.
@ -765,7 +738,7 @@ class InvokerBytecodeGenerator {
continue; continue;
case IDENTITY: case IDENTITY:
assert(name.arguments.length == 1); assert(name.arguments.length == 1);
emitPushArguments(name); emitPushArguments(name, 0);
continue; continue;
case ZERO: case ZERO:
assert(name.arguments.length == 0); assert(name.arguments.length == 0);
@ -819,7 +792,7 @@ class InvokerBytecodeGenerator {
assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH; assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
Class<?> elementType = name.function.methodType().parameterType(0).getComponentType(); Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
assert elementType != null; assert elementType != null;
emitPushArguments(name); emitPushArguments(name, 0);
if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) { if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
Wrapper w = Wrapper.forPrimitiveType(elementType); Wrapper w = Wrapper.forPrimitiveType(elementType);
arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode); arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
@ -848,7 +821,7 @@ class InvokerBytecodeGenerator {
} }
// push arguments // push arguments
emitPushArguments(name); emitPushArguments(name, 0);
// invocation // invocation
MethodType type = name.function.methodType(); MethodType type = name.function.methodType();
@ -947,7 +920,7 @@ class InvokerBytecodeGenerator {
assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual)); assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
// push arguments // push arguments
emitPushArguments(name); emitPushArguments(name, 0);
// invocation // invocation
if (member.isMethod()) { if (member.isMethod()) {
@ -1468,13 +1441,10 @@ class InvokerBytecodeGenerator {
} }
} }
private void emitPushArguments(Name args) {
emitPushArguments(args, 0);
}
private void emitPushArguments(Name args, int start) { private void emitPushArguments(Name args, int start) {
MethodType type = args.function.methodType();
for (int i = start; i < args.arguments.length; i++) { for (int i = start; i < args.arguments.length; i++) {
emitPushArgument(args, i); emitPushArgument(type.parameterType(i), args.arguments[i]);
} }
} }

View File

@ -149,9 +149,9 @@ class LambdaForm {
static final int ARG_TYPE_LIMIT = ARG_TYPES.length; static final int ARG_TYPE_LIMIT = ARG_TYPES.length;
static final int TYPE_LIMIT = ALL_TYPES.length; static final int TYPE_LIMIT = ALL_TYPES.length;
private final char btChar; final char btChar;
private final Class<?> btClass; final Class<?> btClass;
private final Wrapper btWrapper; final Wrapper btWrapper;
private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) { private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
this.btChar = btChar; this.btChar = btChar;
@ -1366,10 +1366,11 @@ class LambdaForm {
} }
public static String basicTypeSignature(MethodType type) { public static String basicTypeSignature(MethodType type) {
char[] sig = new char[type.parameterCount() + 2]; int params = type.parameterCount();
char[] sig = new char[params + 2];
int sigp = 0; int sigp = 0;
for (Class<?> pt : type.parameterList()) { while (sigp < params) {
sig[sigp++] = basicTypeChar(pt); sig[sigp] = basicTypeChar(type.parameterType(sigp++));
} }
sig[sigp++] = '_'; sig[sigp++] = '_';
sig[sigp++] = basicTypeChar(type.returnType()); sig[sigp++] = basicTypeChar(type.returnType());
@ -1407,7 +1408,7 @@ class LambdaForm {
static final class Name { static final class Name {
final BasicType type; final BasicType type;
private short index; @Stable short index;
final NamedFunction function; final NamedFunction function;
final Object constraint; // additional type information, if not null final Object constraint; // additional type information, if not null
@Stable final Object[] arguments; @Stable final Object[] arguments;

View File

@ -60,7 +60,7 @@ class LambdaFormEditor {
} }
/** A description of a cached transform, possibly associated with the result of the transform. /** A description of a cached transform, possibly associated with the result of the transform.
* The logical content is a sequence of byte values, starting with a Kind.ordinal value. * The logical content is a sequence of byte values, starting with a kind value.
* The sequence is unterminated, ending with an indefinite number of zero bytes. * The sequence is unterminated, ending with an indefinite number of zero bytes.
* Sequences that are simple (short enough and with small enough values) pack into a 64-bit long. * Sequences that are simple (short enough and with small enough values) pack into a 64-bit long.
*/ */
@ -68,17 +68,22 @@ class LambdaFormEditor {
final long packedBytes; final long packedBytes;
final byte[] fullBytes; final byte[] fullBytes;
private enum Kind { // maybe add more for guard with test, catch exception, pointwise type conversions
NO_KIND, // necessary because ordinal must be greater than zero private static final byte
BIND_ARG, ADD_ARG, DUP_ARG, BIND_ARG = 1,
SPREAD_ARGS, ADD_ARG = 2,
FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO, DUP_ARG = 3,
COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY, SPREAD_ARGS = 4,
FOLD_ARGS, FOLD_ARGS_TO_VOID, FILTER_ARG = 5,
PERMUTE_ARGS, FILTER_RETURN = 6,
LOCAL_TYPES FILTER_RETURN_TO_ZERO = 7,
//maybe add more for guard with test, catch exception, pointwise type conversions COLLECT_ARGS = 8,
} COLLECT_ARGS_TO_VOID = 9,
COLLECT_ARGS_TO_ARRAY = 10,
FOLD_ARGS = 11,
FOLD_ARGS_TO_VOID = 12,
PERMUTE_ARGS = 13,
LOCAL_TYPES = 14;
private static final boolean STRESS_TEST = false; // turn on to disable most packing private static final boolean STRESS_TEST = false; // turn on to disable most packing
private static final int private static final int
@ -131,20 +136,6 @@ class LambdaFormEditor {
return bytes; return bytes;
} }
private byte byteAt(int i) {
long pb = packedBytes;
if (pb == 0) {
if (i >= fullBytes.length) return 0;
return fullBytes[i];
}
assert(fullBytes == null);
if (i > PACKED_BYTE_MAX_LENGTH) return 0;
int pos = (i * PACKED_BYTE_SIZE);
return (byte)((pb >>> pos) & PACKED_BYTE_MASK);
}
Kind kind() { return Kind.values()[byteAt(0)]; }
private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) { private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) {
super(result); super(result);
this.packedBytes = packedBytes; this.packedBytes = packedBytes;
@ -162,44 +153,39 @@ class LambdaFormEditor {
assert((b & 0xFF) == b); // incoming value must fit in *unsigned* byte assert((b & 0xFF) == b); // incoming value must fit in *unsigned* byte
return (byte)b; return (byte)b;
} }
private static byte bval(Kind k) { static Transform of(byte k, int b1) {
return bval(k.ordinal());
}
static Transform of(Kind k, int b1) {
byte b0 = bval(k); byte b0 = bval(k);
if (inRange(b0 | b1)) if (inRange(b0 | b1))
return new Transform(packedBytes(b0, b1)); return new Transform(packedBytes(b0, b1));
else else
return new Transform(fullBytes(b0, b1)); return new Transform(fullBytes(b0, b1));
} }
static Transform of(Kind k, int b1, int b2) { static Transform of(byte b0, int b1, int b2) {
byte b0 = (byte) k.ordinal();
if (inRange(b0 | b1 | b2)) if (inRange(b0 | b1 | b2))
return new Transform(packedBytes(b0, b1, b2)); return new Transform(packedBytes(b0, b1, b2));
else else
return new Transform(fullBytes(b0, b1, b2)); return new Transform(fullBytes(b0, b1, b2));
} }
static Transform of(Kind k, int b1, int b2, int b3) { static Transform of(byte b0, int b1, int b2, int b3) {
byte b0 = (byte) k.ordinal();
if (inRange(b0 | b1 | b2 | b3)) if (inRange(b0 | b1 | b2 | b3))
return new Transform(packedBytes(b0, b1, b2, b3)); return new Transform(packedBytes(b0, b1, b2, b3));
else else
return new Transform(fullBytes(b0, b1, b2, b3)); return new Transform(fullBytes(b0, b1, b2, b3));
} }
private static final byte[] NO_BYTES = {}; private static final byte[] NO_BYTES = {};
static Transform of(Kind k, int... b123) { static Transform of(byte kind, int... b123) {
return ofBothArrays(k, b123, NO_BYTES); return ofBothArrays(kind, b123, NO_BYTES);
} }
static Transform of(Kind k, int b1, byte[] b234) { static Transform of(byte kind, int b1, byte[] b234) {
return ofBothArrays(k, new int[]{ b1 }, b234); return ofBothArrays(kind, new int[]{ b1 }, b234);
} }
static Transform of(Kind k, int b1, int b2, byte[] b345) { static Transform of(byte kind, int b1, int b2, byte[] b345) {
return ofBothArrays(k, new int[]{ b1, b2 }, b345); return ofBothArrays(kind, new int[]{ b1, b2 }, b345);
} }
private static Transform ofBothArrays(Kind k, int[] b123, byte[] b456) { private static Transform ofBothArrays(byte kind, int[] b123, byte[] b456) {
byte[] fullBytes = new byte[1 + b123.length + b456.length]; byte[] fullBytes = new byte[1 + b123.length + b456.length];
int i = 0; int i = 0;
fullBytes[i++] = bval(k); fullBytes[i++] = bval(kind);
for (int bv : b123) { for (int bv : b123) {
fullBytes[i++] = bval(bv); fullBytes[i++] = bval(bv);
} }
@ -449,7 +435,7 @@ class LambdaFormEditor {
// Each editing method can (potentially) cache the edited LF so that it can be reused later. // Each editing method can (potentially) cache the edited LF so that it can be reused later.
LambdaForm bindArgumentForm(int pos) { LambdaForm bindArgumentForm(int pos) {
Transform key = Transform.of(Transform.Kind.BIND_ARG, pos); Transform key = Transform.of(Transform.BIND_ARG, pos);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos))); assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
@ -484,7 +470,7 @@ class LambdaFormEditor {
} }
LambdaForm addArgumentForm(int pos, BasicType type) { LambdaForm addArgumentForm(int pos, BasicType type) {
Transform key = Transform.of(Transform.Kind.ADD_ARG, pos, type.ordinal()); Transform key = Transform.of(Transform.ADD_ARG, pos, type.ordinal());
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == lambdaForm.arity+1); assert(form.arity == lambdaForm.arity+1);
@ -501,7 +487,7 @@ class LambdaFormEditor {
} }
LambdaForm dupArgumentForm(int srcPos, int dstPos) { LambdaForm dupArgumentForm(int srcPos, int dstPos) {
Transform key = Transform.of(Transform.Kind.DUP_ARG, srcPos, dstPos); Transform key = Transform.of(Transform.DUP_ARG, srcPos, dstPos);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == lambdaForm.arity-1); assert(form.arity == lambdaForm.arity-1);
@ -530,7 +516,7 @@ class LambdaFormEditor {
elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal(); elementTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
} }
} }
Transform key = Transform.of(Transform.Kind.SPREAD_ARGS, pos, elementTypeKey, arrayLength); Transform key = Transform.of(Transform.SPREAD_ARGS, pos, elementTypeKey, arrayLength);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == lambdaForm.arity - arrayLength + 1); assert(form.arity == lambdaForm.arity - arrayLength + 1);
@ -569,9 +555,9 @@ class LambdaFormEditor {
return filterArgumentForm(pos, basicType(collectorType.parameterType(0))); return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
} }
byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray()); byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
Transform.Kind kind = (dropResult byte kind = (dropResult
? Transform.Kind.COLLECT_ARGS_TO_VOID ? Transform.COLLECT_ARGS_TO_VOID
: Transform.Kind.COLLECT_ARGS); : Transform.COLLECT_ARGS);
if (dropResult && collectorArity == 0) pos = 1; // pure side effect if (dropResult && collectorArity == 0) pos = 1; // pure side effect
Transform key = Transform.of(kind, pos, collectorArity, newTypes); Transform key = Transform.of(kind, pos, collectorArity, newTypes);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
@ -598,7 +584,7 @@ class LambdaFormEditor {
argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal(); argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
} }
assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType))); assert(collectorType.parameterList().equals(Collections.nCopies(collectorArity, elementType)));
Transform.Kind kind = Transform.Kind.COLLECT_ARGS_TO_ARRAY; byte kind = Transform.COLLECT_ARGS_TO_ARRAY;
Transform key = Transform.of(kind, pos, collectorArity, argTypeKey); Transform key = Transform.of(kind, pos, collectorArity, argTypeKey);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
@ -634,7 +620,7 @@ class LambdaFormEditor {
} }
LambdaForm filterArgumentForm(int pos, BasicType newType) { LambdaForm filterArgumentForm(int pos, BasicType newType) {
Transform key = Transform.of(Transform.Kind.FILTER_ARG, pos, newType.ordinal()); Transform key = Transform.of(Transform.FILTER_ARG, pos, newType.ordinal());
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == lambdaForm.arity); assert(form.arity == lambdaForm.arity);
@ -710,7 +696,7 @@ class LambdaFormEditor {
} }
LambdaForm filterReturnForm(BasicType newType, boolean constantZero) { LambdaForm filterReturnForm(BasicType newType, boolean constantZero) {
Transform.Kind kind = (constantZero ? Transform.Kind.FILTER_RETURN_TO_ZERO : Transform.Kind.FILTER_RETURN); byte kind = (constantZero ? Transform.FILTER_RETURN_TO_ZERO : Transform.FILTER_RETURN);
Transform key = Transform.of(kind, newType.ordinal()); Transform key = Transform.of(kind, newType.ordinal());
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
@ -762,11 +748,11 @@ class LambdaFormEditor {
LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) { LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
int combinerArity = combinerType.parameterCount(); int combinerArity = combinerType.parameterCount();
Transform.Kind kind = (dropResult ? Transform.Kind.FOLD_ARGS_TO_VOID : Transform.Kind.FOLD_ARGS); byte kind = (dropResult ? Transform.FOLD_ARGS_TO_VOID : Transform.FOLD_ARGS);
Transform key = Transform.of(kind, foldPos, combinerArity); Transform key = Transform.of(kind, foldPos, combinerArity);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == lambdaForm.arity - (kind == Transform.Kind.FOLD_ARGS ? 1 : 0)); assert(form.arity == lambdaForm.arity - (kind == Transform.FOLD_ARGS ? 1 : 0));
return form; return form;
} }
form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult); form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
@ -786,7 +772,7 @@ class LambdaFormEditor {
} }
assert(skip + reorder.length == lambdaForm.arity); assert(skip + reorder.length == lambdaForm.arity);
if (nullPerm) return lambdaForm; // do not bother to cache if (nullPerm) return lambdaForm; // do not bother to cache
Transform key = Transform.of(Transform.Kind.PERMUTE_ARGS, reorder); Transform key = Transform.of(Transform.PERMUTE_ARGS, reorder);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
assert(form.arity == skip+inTypes) : form; assert(form.arity == skip+inTypes) : form;
@ -855,7 +841,7 @@ class LambdaFormEditor {
int[] desc = BasicType.basicTypeOrds(localTypes); int[] desc = BasicType.basicTypeOrds(localTypes);
desc = Arrays.copyOf(desc, desc.length + 1); desc = Arrays.copyOf(desc, desc.length + 1);
desc[desc.length - 1] = pos; desc[desc.length - 1] = pos;
Transform key = Transform.of(Transform.Kind.LOCAL_TYPES, desc); Transform key = Transform.of(Transform.LOCAL_TYPES, desc);
LambdaForm form = getInCache(key); LambdaForm form = getInCache(key);
if (form != null) { if (form != null) {
return form; return form;

View File

@ -25,8 +25,6 @@
package java.lang.invoke; package java.lang.invoke;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import sun.invoke.util.BytecodeDescriptor; import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.VerifyAccess; import sun.invoke.util.VerifyAccess;
@ -37,7 +35,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Module; import java.lang.reflect.Module;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -81,7 +78,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
private int flags; // modifier bits; see reflect.Modifier private int flags; // modifier bits; see reflect.Modifier
//@Injected JVM_Method* vmtarget; //@Injected JVM_Method* vmtarget;
//@Injected int vmindex; //@Injected int vmindex;
private Object resolution; // if null, this guy is resolved Object resolution; // if null, this guy is resolved
/** Return the declaring class of this member. /** Return the declaring class of this member.
* In the case of a bare name and type, the declaring class will be null. * In the case of a bare name and type, the declaring class will be null.
@ -829,7 +826,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
return resolution == null; return resolution == null;
} }
private void initResolved(boolean isResolved) { void initResolved(boolean isResolved) {
assert(this.resolution == null); // not initialized yet! assert(this.resolution == null); // not initialized yet!
if (!isResolved) if (!isResolved)
this.resolution = this; this.resolution = this;
@ -1002,7 +999,9 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
Collections.addAll(result, buf0); Collections.addAll(result, buf0);
} }
} }
result.addAll(Arrays.asList(buf).subList(0, bufCount)); for (int i = 0; i < bufCount; i++) {
result.add(buf[i]);
}
// Signature matching is not the same as type matching, since // Signature matching is not the same as type matching, since
// one signature might correspond to several types. // one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results. // So if matchType is a Class or MethodType, refilter the results.
@ -1150,27 +1149,4 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
return buf; return buf;
} }
} }
static {
// StackFrameInfo stores Member and this provides the shared secrets
// for stack walker to access MemberName information.
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
@Override
public Object newMemberName() {
return new MemberName();
}
@Override
public String getName(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.getName();
}
@Override
public boolean isNative(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.isNative();
}
});
}
} }

View File

@ -25,6 +25,8 @@
package java.lang.invoke; package java.lang.invoke;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.org.objectweb.asm.AnnotationVisitor; import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.MethodVisitor;
@ -38,12 +40,11 @@ import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -57,19 +58,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* @author jrose * @author jrose
*/ */
/*non-public*/ abstract class MethodHandleImpl { /*non-public*/ abstract class MethodHandleImpl {
// Do not adjust this except for special platforms:
private static final int MAX_ARITY;
static {
final Object[] values = { 255 };
AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Void run() {
values[0] = Integer.getInteger(MethodHandleImpl.class.getName()+".MAX_ARITY", 255);
return null;
}
});
MAX_ARITY = (Integer) values[0];
}
/// Factory methods to create method handles: /// Factory methods to create method handles:
@ -649,7 +637,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
MethodType srcType = targetType // (a..., [b...])=>r MethodType srcType = targetType // (a..., [b...])=>r
.dropParameterTypes(collectArgPos, collectArgPos+collectValCount); .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
if (!retainOriginalArgs) { // (a..., b...)=>r if (!retainOriginalArgs) { // (a..., b...)=>r
srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList()); srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterArray());
} }
// in arglist: [0: ...keep1 | cpos: collect... | cpos+cacount: keep2... ] // in arglist: [0: ...keep1 | cpos: collect... | cpos+cacount: keep2... ]
// out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ] // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
@ -1094,7 +1082,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
int arity = type.parameterCount(); int arity = type.parameterCount();
if (arity > 1) { if (arity > 1) {
MethodHandle mh = throwException(type.dropParameterTypes(1, arity)); MethodHandle mh = throwException(type.dropParameterTypes(1, arity));
mh = MethodHandles.dropArguments(mh, 1, type.parameterList().subList(1, arity)); mh = MethodHandles.dropArguments(mh, 1, Arrays.copyOfRange(type.parameterArray(), 1, arity));
return mh; return mh;
} }
return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true); return makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
@ -1710,6 +1698,39 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw newInternalError(ex); throw newInternalError(ex);
} }
SharedSecrets.setJavaLangInvokeAccess(new JavaLangInvokeAccess() {
@Override
public Object newMemberName() {
return new MemberName();
}
@Override
public String getName(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.getName();
}
@Override
public boolean isNative(Object mname) {
MemberName memberName = (MemberName)mname;
return memberName.isNative();
}
@Override
public byte[] generateDMHClassBytes(String className,
MethodType[] methodTypes, int[] types) {
return GenerateJLIClassesHelper
.generateDMHClassBytes(className, methodTypes, types);
}
@Override
public Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types) {
return GenerateJLIClassesHelper
.generateConcreteBMHClassBytes(types);
}
});
} }
/** Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore(). */ /** Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore(). */

View File

@ -53,6 +53,7 @@ import java.util.Properties;
static final boolean PROFILE_GWT; static final boolean PROFILE_GWT;
static final int CUSTOMIZE_THRESHOLD; static final int CUSTOMIZE_THRESHOLD;
static final boolean VAR_HANDLE_GUARDS; static final boolean VAR_HANDLE_GUARDS;
static final int MAX_ARITY;
static { static {
Properties props = GetPropertyAction.privilegedGetProperties(); Properties props = GetPropertyAction.privilegedGetProperties();
@ -79,6 +80,10 @@ import java.util.Properties;
VAR_HANDLE_GUARDS = Boolean.parseBoolean( VAR_HANDLE_GUARDS = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true")); props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
// Do not adjust this except for special platforms:
MAX_ARITY = Integer.parseInt(
props.getProperty("java.lang.invoke.MethodHandleImpl.MAX_ARITY", "255"));
if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) { if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range"); throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
} }

View File

@ -77,7 +77,7 @@ public class MethodHandles {
private MethodHandles() { } // do not instantiate private MethodHandles() { } // do not instantiate
private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
// See IMPL_LOOKUP below. // See IMPL_LOOKUP below.
@ -3115,7 +3115,7 @@ assert((int)twice.invokeExact(21) == 42);
return dropArguments(zero(type.returnType()), 0, type.parameterList()); return dropArguments(zero(type.returnType()), 0, type.parameterList());
} }
private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.values().length]; private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
private static MethodHandle makeIdentity(Class<?> ptype) { private static MethodHandle makeIdentity(Class<?> ptype) {
MethodType mtype = methodType(ptype, ptype); MethodType mtype = methodType(ptype, ptype);
LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype)); LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
@ -3133,7 +3133,7 @@ assert((int)twice.invokeExact(21) == 42);
assert(btw == Wrapper.OBJECT); assert(btw == Wrapper.OBJECT);
return makeZero(rtype); return makeZero(rtype);
} }
private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.values().length]; private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
private static MethodHandle makeZero(Class<?> rtype) { private static MethodHandle makeZero(Class<?> rtype) {
MethodType mtype = methodType(rtype); MethodType mtype = methodType(rtype);
LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype)); LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
@ -3268,12 +3268,11 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
*/ */
public static public static
MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) { MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
return dropArguments0(target, pos, copyTypes(valueTypes)); return dropArguments0(target, pos, copyTypes(valueTypes.toArray()));
} }
private static List<Class<?>> copyTypes(List<Class<?>> types) { private static List<Class<?>> copyTypes(Object[] array) {
Object[] a = types.toArray(); return Arrays.asList(Arrays.copyOf(array, array.length, Class[].class));
return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
} }
private static private static
@ -3352,13 +3351,13 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
*/ */
public static public static
MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) { MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
return dropArguments(target, pos, Arrays.asList(valueTypes)); return dropArguments0(target, pos, copyTypes(valueTypes));
} }
// private version which allows caller some freedom with error handling // private version which allows caller some freedom with error handling
private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos, private static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
boolean nullOnFailure) { boolean nullOnFailure) {
newTypes = copyTypes(newTypes); newTypes = copyTypes(newTypes.toArray());
List<Class<?>> oldTypes = target.type().parameterList(); List<Class<?>> oldTypes = target.type().parameterList();
int match = oldTypes.size(); int match = oldTypes.size();
if (skip != 0) { if (skip != 0) {
@ -3900,10 +3899,14 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
int foldVals = rtype == void.class ? 0 : 1; int foldVals = rtype == void.class ? 0 : 1;
int afterInsertPos = foldPos + foldVals; int afterInsertPos = foldPos + foldVals;
boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs); boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
if (ok && !(combinerType.parameterList() if (ok) {
.equals(targetType.parameterList().subList(afterInsertPos, for (int i = 0; i < foldArgs; i++) {
afterInsertPos + foldArgs)))) if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
ok = false; ok = false;
break;
}
}
}
if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos)) if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
ok = false; ok = false;
if (!ok) if (!ok)

View File

@ -539,10 +539,10 @@ class MethodType implements java.io.Serializable {
return res; return res;
} else { } else {
// insert after (if need be), then before // insert after (if need be), then before
if (pos < parameterList().size() - 1) { if (pos < ptypes.length - 1) {
res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size())); res = res.insertParameterTypes(arrayLength, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
} }
return res.insertParameterTypes(0, parameterList().subList(0, pos)); return res.insertParameterTypes(0, Arrays.copyOf(ptypes, pos));
} }
} }

View File

@ -281,12 +281,11 @@ public final class StringConcatFactory {
if (c == TAG_CONST) { if (c == TAG_CONST) {
Object cnst = constants[constC++]; Object cnst = constants[constC++];
el.add(new RecipeElement(cnst)); el.add(new RecipeElement(cnst));
} } else if (c == TAG_ARG) {
if (c == TAG_ARG) {
el.add(new RecipeElement(argC++)); el.add(new RecipeElement(argC++));
} }
} else { } else {
// Not a special characters, this is a constant embedded into // Not a special character, this is a constant embedded into
// the recipe itself. // the recipe itself.
acc.append(c); acc.append(c);
} }
@ -322,31 +321,31 @@ public final class StringConcatFactory {
private static final class RecipeElement { private static final class RecipeElement {
private final Object value; private final Object value;
private final int argPos; private final int argPos;
private final Tag tag; private final char tag;
public RecipeElement(Object cnst) { public RecipeElement(Object cnst) {
this.value = Objects.requireNonNull(cnst); this.value = Objects.requireNonNull(cnst);
this.argPos = -1; this.argPos = -1;
this.tag = Tag.CONST; this.tag = TAG_CONST;
} }
public RecipeElement(int arg) { public RecipeElement(int arg) {
this.value = null; this.value = null;
this.argPos = arg; this.argPos = arg;
this.tag = Tag.ARG; this.tag = TAG_ARG;
} }
public Object getValue() { public Object getValue() {
assert (tag == Tag.CONST); assert (tag == TAG_CONST);
return value; return value;
} }
public int getArgPos() { public int getArgPos() {
assert (tag == Tag.ARG); assert (tag == TAG_ARG);
return argPos; return argPos;
} }
public Tag getTag() { public char getTag() {
return tag; return tag;
} }
@ -357,22 +356,18 @@ public final class StringConcatFactory {
RecipeElement that = (RecipeElement) o; RecipeElement that = (RecipeElement) o;
if (tag != that.tag) return false; if (this.tag != that.tag) return false;
if (tag == Tag.CONST && (!value.equals(that.value))) return false; if (this.tag == TAG_CONST && (!value.equals(that.value))) return false;
if (tag == Tag.ARG && (argPos != that.argPos)) return false; if (this.tag == TAG_ARG && (argPos != that.argPos)) return false;
return true; return true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return tag.hashCode(); return (int)tag;
} }
} }
private enum Tag {
CONST, ARG
}
/** /**
* Facilitates the creation of optimized String concatenation methods, that * Facilitates the creation of optimized String concatenation methods, that
* can be used to efficiently concatenate a known number of arguments of * can be used to efficiently concatenate a known number of arguments of
@ -649,19 +644,20 @@ public final class StringConcatFactory {
* @return argument types the strategy is going to use * @return argument types the strategy is going to use
*/ */
private static MethodType adaptType(MethodType args) { private static MethodType adaptType(MethodType args) {
Class<?>[] ptypes = args.parameterArray(); Class<?>[] ptypes = null;
boolean changed = false; for (int i = 0; i < args.parameterCount(); i++) {
for (int i = 0; i < ptypes.length; i++) { Class<?> ptype = args.parameterType(i);
Class<?> ptype = ptypes[i];
if (!ptype.isPrimitive() && if (!ptype.isPrimitive() &&
ptype != String.class && ptype != String.class &&
ptype != Object.class) { // truncate to Object ptype != Object.class) { // truncate to Object
if (ptypes == null) {
ptypes = args.parameterArray();
}
ptypes[i] = Object.class; ptypes[i] = Object.class;
changed = true;
} }
// else other primitives or String or Object (unchanged) // else other primitives or String or Object (unchanged)
} }
return changed return (ptypes != null)
? MethodType.methodType(args.returnType(), ptypes) ? MethodType.methodType(args.returnType(), ptypes)
: args; : args;
} }
@ -881,11 +877,10 @@ public final class StringConcatFactory {
int off = 0; int off = 0;
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
// Guaranteed non-null, no null check required. // Guaranteed non-null, no null check required.
break; break;
} case TAG_ARG:
case ARG: {
// Null-checks are needed only for String arguments, and when a previous stage // Null-checks are needed only for String arguments, and when a previous stage
// did not do implicit null-checks. If a String is null, we eagerly replace it // did not do implicit null-checks. If a String is null, we eagerly replace it
// with "null" constant. Note, we omit Objects here, because we don't call // with "null" constant. Note, we omit Objects here, because we don't call
@ -902,7 +897,6 @@ public final class StringConcatFactory {
} }
off += getParameterSize(cl); off += getParameterSize(cl);
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
@ -926,12 +920,11 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object cnst = el.getValue(); Object cnst = el.getValue();
len += cnst.toString().length(); len += cnst.toString().length();
break; break;
} case TAG_ARG:
case ARG: {
/* /*
If an argument is String, then we can call .length() on it. Sized/Exact modes have If an argument is String, then we can call .length() on it. Sized/Exact modes have
converted arguments for us. If an argument is primitive, we can provide a guess converted arguments for us. If an argument is primitive, we can provide a guess
@ -953,7 +946,6 @@ public final class StringConcatFactory {
} }
off += getParameterSize(cl); off += getParameterSize(cl);
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
@ -988,22 +980,21 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
String desc; String desc;
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object cnst = el.getValue(); Object cnst = el.getValue();
mv.visitLdcInsn(cnst); mv.visitLdcInsn(cnst);
desc = getSBAppendDesc(cnst.getClass()); desc = getSBAppendDesc(cnst.getClass());
break; break;
} case TAG_ARG:
case ARG: {
Class<?> cl = arr[el.getArgPos()]; Class<?> cl = arr[el.getArgPos()];
mv.visitVarInsn(getLoadOpcode(cl), off); mv.visitVarInsn(getLoadOpcode(cl), off);
off += getParameterSize(cl); off += getParameterSize(cl);
desc = getSBAppendDesc(cl); desc = getSBAppendDesc(cl);
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
mv.visitMethodInsn( mv.visitMethodInsn(
INVOKEVIRTUAL, INVOKEVIRTUAL,
"java/lang/StringBuilder", "java/lang/StringBuilder",
@ -1271,7 +1262,6 @@ public final class StringConcatFactory {
} }
} }
List<Class<?>> ptypesList = Arrays.asList(ptypes);
MethodHandle[] lengthers = new MethodHandle[pc]; MethodHandle[] lengthers = new MethodHandle[pc];
// Figure out lengths: constants' lengths can be deduced on the spot. // Figure out lengths: constants' lengths can be deduced on the spot.
@ -1280,14 +1270,13 @@ public final class StringConcatFactory {
int initial = 0; int initial = 0;
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object cnst = el.getValue(); Object cnst = el.getValue();
initial += cnst.toString().length(); initial += cnst.toString().length();
break; break;
} case TAG_ARG:
case ARG: {
final int i = el.getArgPos(); final int i = el.getArgPos();
Class<?> type = ptypesList.get(i); Class<?> type = ptypes[i];
if (type.isPrimitive()) { if (type.isPrimitive()) {
MethodHandle est = MethodHandles.constant(int.class, estimateSize(type)); MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
est = MethodHandles.dropArguments(est, 0, type); est = MethodHandles.dropArguments(est, 0, type);
@ -1296,14 +1285,13 @@ public final class StringConcatFactory {
lengthers[i] = STRING_LENGTH; lengthers[i] = STRING_LENGTH;
} }
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
} }
// Create (StringBuilder, <args>) shape for appending: // Create (StringBuilder, <args>) shape for appending:
MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypesList); MethodHandle builder = MethodHandles.dropArguments(MethodHandles.identity(StringBuilder.class), 1, ptypes);
// Compose append calls. This is done in reverse because the application order is // Compose append calls. This is done in reverse because the application order is
// reverse as well. // reverse as well.
@ -1312,23 +1300,21 @@ public final class StringConcatFactory {
RecipeElement el = elements.get(i); RecipeElement el = elements.get(i);
MethodHandle appender; MethodHandle appender;
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object constant = el.getValue(); Object constant = el.getValue();
MethodHandle mh = appender(adaptToStringBuilder(constant.getClass())); MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
appender = MethodHandles.insertArguments(mh, 1, constant); appender = MethodHandles.insertArguments(mh, 1, constant);
break; break;
} case TAG_ARG:
case ARG: {
int ac = el.getArgPos(); int ac = el.getArgPos();
appender = appender(ptypesList.get(ac)); appender = appender(ptypes[ac]);
// Insert dummy arguments to match the prefix in the signature. // Insert dummy arguments to match the prefix in the signature.
// The actual appender argument will be the ac-ith argument. // The actual appender argument will be the ac-ith argument.
if (ac != 0) { if (ac != 0) {
appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac)); appender = MethodHandles.dropArguments(appender, 1, Arrays.copyOf(ptypes, ac));
} }
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
@ -1500,7 +1486,6 @@ public final class StringConcatFactory {
ptypes[i] = filter.type().returnType(); ptypes[i] = filter.type().returnType();
} }
} }
List<Class<?>> ptypesList = Arrays.asList(ptypes);
// Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes" // Start building the combinator tree. The tree "starts" with (<parameters>)String, and "finishes"
// with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up, // with the (int, byte[], byte)String in String helper. The combinators are assembled bottom-up,
@ -1522,16 +1507,14 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
MethodHandle prepender; MethodHandle prepender;
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object cnst = el.getValue(); Object cnst = el.getValue();
prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst); prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
break; break;
} case TAG_ARG:
case ARG: {
int pos = el.getArgPos(); int pos = el.getArgPos();
prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos); prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
@ -1554,7 +1537,7 @@ public final class StringConcatFactory {
} }
// Fold in byte[] instantiation at argument 0. // Fold in byte[] instantiation at argument 0.
MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypesList); MethodHandle combiner = MethodHandles.dropArguments(NEW_ARRAY, 2, ptypes);
mh = MethodHandles.foldArguments(mh, combiner); mh = MethodHandles.foldArguments(mh, combiner);
// Start combining length and coder mixers. // Start combining length and coder mixers.
@ -1574,22 +1557,21 @@ public final class StringConcatFactory {
int initialLen = 0; // initial length, in characters int initialLen = 0; // initial length, in characters
for (RecipeElement el : recipe.getElements()) { for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) { switch (el.getTag()) {
case CONST: { case TAG_CONST:
Object constant = el.getValue(); Object constant = el.getValue();
String s = constant.toString(); String s = constant.toString();
initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s); initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
initialLen += s.length(); initialLen += s.length();
break; break;
} case TAG_ARG:
case ARG: {
int ac = el.getArgPos(); int ac = el.getArgPos();
Class<?> argClass = ptypesList.get(ac); Class<?> argClass = ptypes[ac];
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac); MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*) lm = MethodHandles.dropArguments(lm, 0, byte.class); // (*)
lm = MethodHandles.dropArguments(lm, 2, byte.class); lm = MethodHandles.dropArguments(lm, 2, byte.class);
MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypesList, ac); MethodHandle cm = selectArgument(coderMixer(argClass), 1, ptypes, ac);
cm = MethodHandles.dropArguments(cm, 0, int.class); // (**) cm = MethodHandles.dropArguments(cm, 0, int.class); // (**)
// Read this bottom up: // Read this bottom up:
@ -1607,7 +1589,6 @@ public final class StringConcatFactory {
// 1. The mh shape here is ("old-index", "old-coder", <args>) // 1. The mh shape here is ("old-index", "old-coder", <args>)
break; break;
}
default: default:
throw new StringConcatException("Unhandled tag: " + el.getTag()); throw new StringConcatException("Unhandled tag: " + el.getTag());
} }
@ -1636,14 +1617,14 @@ public final class StringConcatFactory {
} }
// Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R // Adapts: (...prefix..., parameter[pos])R -> (...prefix..., ...parameters...)R
private static MethodHandle selectArgument(MethodHandle mh, int prefix, List<Class<?>> ptypes, int pos) { private static MethodHandle selectArgument(MethodHandle mh, int prefix, Class<?>[] ptypes, int pos) {
if (pos == 0) { if (pos == 0) {
return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size())); return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
} else if (pos == ptypes.size() - 1) { } else if (pos == ptypes.length - 1) {
return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1)); return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
} else { // 0 < pos < ptypes.size() - 1 } else { // 0 < pos < ptypes.size() - 1
MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos)); MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size())); return MethodHandles.dropArguments(t, prefix + 1 + pos, Arrays.copyOfRange(ptypes, pos + 1, ptypes.length));
} }
} }
@ -1702,8 +1683,8 @@ public final class StringConcatFactory {
private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS; private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS;
private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS; private static final ConcurrentMap<Class<?>, MethodHandle> LENGTH_MIXERS;
private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS; private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
private static final Class<?> STRING_HELPER;
private static final byte INITIAL_CODER; private static final byte INITIAL_CODER;
static final Class<?> STRING_HELPER;
static { static {
try { try {
@ -1805,7 +1786,7 @@ public final class StringConcatFactory {
/* ------------------------------- Common utilities ------------------------------------ */ /* ------------------------------- Common utilities ------------------------------------ */
private static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) { static MethodHandle lookupStatic(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
try { try {
return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes)); return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) { } catch (NoSuchMethodException | IllegalAccessException e) {
@ -1813,7 +1794,7 @@ public final class StringConcatFactory {
} }
} }
private static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) { static MethodHandle lookupVirtual(Lookup lookup, Class<?> refc, String name, Class<?> rtype, Class<?>... ptypes) {
try { try {
return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes)); return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) { } catch (NoSuchMethodException | IllegalAccessException e) {
@ -1821,7 +1802,7 @@ public final class StringConcatFactory {
} }
} }
private static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) { static MethodHandle lookupConstructor(Lookup lookup, Class<?> refc, Class<?> ptypes) {
try { try {
return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes)); return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
} catch (NoSuchMethodException | IllegalAccessException e) { } catch (NoSuchMethodException | IllegalAccessException e) {
@ -1829,7 +1810,7 @@ public final class StringConcatFactory {
} }
} }
private static int estimateSize(Class<?> cl) { static int estimateSize(Class<?> cl) {
if (cl == Integer.TYPE) { if (cl == Integer.TYPE) {
return 11; // "-2147483648" return 11; // "-2147483648"
} else if (cl == Boolean.TYPE) { } else if (cl == Boolean.TYPE) {
@ -1851,7 +1832,7 @@ public final class StringConcatFactory {
} }
} }
private static Class<?> adaptToStringBuilder(Class<?> c) { static Class<?> adaptToStringBuilder(Class<?> c) {
if (c.isPrimitive()) { if (c.isPrimitive()) {
if (c == Byte.TYPE || c == Short.TYPE) { if (c == Byte.TYPE || c == Short.TYPE) {
return int.class; return int.class;

View File

@ -38,7 +38,7 @@ class TypeConvertingMethodAdapter extends MethodVisitor {
super(Opcodes.ASM5, mv); super(Opcodes.ASM5, mv);
} }
private static final int NUM_WRAPPERS = Wrapper.values().length; private static final int NUM_WRAPPERS = Wrapper.COUNT;
private static final String NAME_OBJECT = "java/lang/Object"; private static final String NAME_OBJECT = "java/lang/Object";
private static final String WRAPPER_PREFIX = "Ljava/lang/"; private static final String WRAPPER_PREFIX = "Ljava/lang/";

View File

@ -31,7 +31,6 @@ import java.lang.invoke.VarHandle.AccessMode;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -54,7 +53,8 @@ final class VarForm {
List<Class<?>> l = new ArrayList<>(); List<Class<?>> l = new ArrayList<>();
if (receiver != null) if (receiver != null)
l.add(receiver); l.add(receiver);
l.addAll(Arrays.asList(intermediate)); for (Class<?> c : intermediate)
l.add(c);
// (Receiver, <Intermediates>)Value // (Receiver, <Intermediates>)Value
methodType_table[VarHandle.AccessType.GET.ordinal()] = methodType_table[VarHandle.AccessType.GET.ordinal()] =

View File

@ -1057,57 +1057,11 @@ public abstract class VarHandle {
Object addAndGet(Object... args); Object addAndGet(Object... args);
enum AccessType { enum AccessType {
GET(Object.class) { GET(Object.class),
@Override SET(void.class),
MethodType accessModeType(Class<?> receiver, Class<?> value, COMPARE_AND_SWAP(boolean.class),
Class<?>... intermediate) { COMPARE_AND_EXCHANGE(Object.class),
Class<?>[] ps = allocateParameters(0, receiver, intermediate); GET_AND_UPDATE(Object.class);
fillParameters(ps, receiver, intermediate);
return MethodType.methodType(value, ps);
}
},
SET(void.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(1, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(void.class, ps);
}
},
COMPARE_AND_SWAP(boolean.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(2, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(boolean.class, ps);
}
},
COMPARE_AND_EXCHANGE(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(2, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(value, ps);
}
},
GET_AND_UPDATE(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(1, receiver, intermediate);
int i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(value, ps);
}
};
final Class<?> returnType; final Class<?> returnType;
final boolean isMonomorphicInReturnType; final boolean isMonomorphicInReturnType;
@ -1117,8 +1071,41 @@ public abstract class VarHandle {
isMonomorphicInReturnType = returnType != Object.class; isMonomorphicInReturnType = returnType != Object.class;
} }
abstract MethodType accessModeType(Class<?> receiver, Class<?> value, MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate); Class<?>... intermediate) {
Class<?>[] ps;
int i;
switch (this) {
case GET:
ps = allocateParameters(0, receiver, intermediate);
fillParameters(ps, receiver, intermediate);
return MethodType.methodType(value, ps);
case SET:
ps = allocateParameters(1, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(void.class, ps);
case COMPARE_AND_SWAP:
ps = allocateParameters(2, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(boolean.class, ps);
case COMPARE_AND_EXCHANGE:
ps = allocateParameters(2, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i++] = value;
ps[i] = value;
return MethodType.methodType(value, ps);
case GET_AND_UPDATE:
ps = allocateParameters(1, receiver, intermediate);
i = fillParameters(ps, receiver, intermediate);
ps[i] = value;
return MethodType.methodType(value, ps);
default:
throw new InternalError("Unknown AccessType");
}
}
private static Class<?>[] allocateParameters(int values, private static Class<?>[] allocateParameters(int values,
Class<?> receiver, Class<?>... intermediate) { Class<?> receiver, Class<?>... intermediate) {

View File

@ -169,7 +169,7 @@ public final class ModuleReference {
/** /**
* Returns {@code true} if this module has been patched via -Xpatch. * Returns {@code true} if this module has been patched via --patch-module.
*/ */
boolean isPatched() { boolean isPatched() {
return patched; return patched;

View File

@ -68,7 +68,7 @@ class ModuleReferences {
/** /**
* Creates a ModuleReference to a module or to patched module when * Creates a ModuleReference to a module or to patched module when
* creating modules for the boot Layer and -Xpatch is specified. * creating modules for the boot Layer and --patch-module is specified.
*/ */
private static ModuleReference newModule(ModuleDescriptor md, private static ModuleReference newModule(ModuleDescriptor md,
URI uri, URI uri,

View File

@ -178,7 +178,7 @@ class SystemModuleFinder implements ModuleFinder {
ModuleReference mref = ModuleReference mref =
new ModuleReference(md, uri, readerSupplier, hash); new ModuleReference(md, uri, readerSupplier, hash);
// may need a reference to a patched module if -Xpatch specified // may need a reference to a patched module if --patch-module specified
mref = ModulePatcher.interposeIfNeeded(mref); mref = ModulePatcher.interposeIfNeeded(mref);
return mref; return mref;

View File

@ -147,11 +147,7 @@ public class AtomicBoolean implements java.io.Serializable {
* @return the previous value * @return the previous value
*/ */
public final boolean getAndSet(boolean newValue) { public final boolean getAndSet(boolean newValue) {
boolean prev; return (int)VALUE.getAndSet(this, (newValue ? 1 : 0)) != 0;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
} }
/** /**

View File

@ -263,6 +263,47 @@ public class StampedLock implements java.io.Serializable {
* is theoretically possible, so we additionally add a * is theoretically possible, so we additionally add a
* storeStoreFence after lock acquisition CAS. * storeStoreFence after lock acquisition CAS.
* *
* ----------------------------------------------------------------
* Here's an informal proof that plain reads by _successful_
* readers see plain writes from preceding but not following
* writers (following Boehm and the C++ standard [atomics.fences]):
*
* Because of the total synchronization order of accesses to
* volatile long state containing the sequence number, writers and
* _successful_ readers can be globally sequenced.
*
* int x, y;
*
* Writer 1:
* inc sequence (odd - "locked")
* storeStoreFence();
* x = 1; y = 2;
* inc sequence (even - "unlocked")
*
* Successful Reader:
* read sequence (even)
* // must see writes from Writer 1 but not Writer 2
* r1 = x; r2 = y;
* acquireFence();
* read sequence (even - validated unchanged)
* // use r1 and r2
*
* Writer 2:
* inc sequence (odd - "locked")
* storeStoreFence();
* x = 3; y = 4;
* inc sequence (even - "unlocked")
*
* Visibility of writer 1's stores is normal - reader's initial
* read of state synchronizes with writer 1's final write to state.
* Lack of visibility of writer 2's plain writes is less obvious.
* If reader's read of x or y saw writer 2's write, then (assuming
* semantics of C++ fences) the storeStoreFence would "synchronize"
* with reader's acquireFence and reader's validation read must see
* writer 2's initial write to state and so validation must fail.
* But making this "proof" formal and rigorous is an open problem!
* ----------------------------------------------------------------
*
* The memory layout keeps lock state and queue pointers together * The memory layout keeps lock state and queue pointers together
* (normally on the same cache line). This usually works well for * (normally on the same cache line). This usually works well for
* read-mostly loads. In most other cases, the natural tendency of * read-mostly loads. In most other cases, the natural tendency of
@ -276,14 +317,14 @@ public class StampedLock implements java.io.Serializable {
/** Number of processors, for spin control */ /** Number of processors, for spin control */
private static final int NCPU = Runtime.getRuntime().availableProcessors(); private static final int NCPU = Runtime.getRuntime().availableProcessors();
/** Maximum number of retries before enqueuing on acquisition */ /** Maximum number of retries before enqueuing on acquisition; at least 1 */
private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0; private static final int SPINS = (NCPU > 1) ? 1 << 6 : 1;
/** Maximum number of retries before blocking at head on acquisition */ /** Maximum number of tries before blocking at head on acquisition */
private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0; private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 1;
/** Maximum number of retries before re-blocking */ /** Maximum number of retries before re-blocking */
private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 0; private static final int MAX_HEAD_SPINS = (NCPU > 1) ? 1 << 16 : 1;
/** The period for yielding when waiting for overflow spinlock */ /** The period for yielding when waiting for overflow spinlock */
private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1 private static final int OVERFLOW_YIELD_RATE = 7; // must be power 2 - 1
@ -1228,6 +1269,11 @@ public class StampedLock implements java.io.Serializable {
WCOWAIT.compareAndSet(h, c, c.cowait) && WCOWAIT.compareAndSet(h, c, c.cowait) &&
(w = c.thread) != null) // help release (w = c.thread) != null) // help release
LockSupport.unpark(w); LockSupport.unpark(w);
if (Thread.interrupted()) {
if (interruptible)
return cancelWaiter(node, p, true);
wasInterrupted = true;
}
if (h == (pp = p.prev) || h == p || pp == null) { if (h == (pp = p.prev) || h == p || pp == null) {
long m, s, ns; long m, s, ns;
do { do {
@ -1264,11 +1310,6 @@ public class StampedLock implements java.io.Serializable {
LockSupport.parkNanos(this, time); LockSupport.parkNanos(this, time);
} }
node.thread = null; node.thread = null;
if (Thread.interrupted()) {
if (interruptible)
return cancelWaiter(node, p, true);
wasInterrupted = true;
}
} }
} }
} }

View File

@ -25,19 +25,42 @@
package jdk.internal.misc; package jdk.internal.misc;
import java.lang.invoke.MethodType;
import java.util.Map;
public interface JavaLangInvokeAccess { public interface JavaLangInvokeAccess {
/** /**
* Create a new MemberName instance * Create a new MemberName instance. Used by {@see StackFrameInfo}.
*/ */
Object newMemberName(); Object newMemberName();
/** /**
* Returns the name for the given MemberName * Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
*/ */
String getName(Object mname); String getName(Object mname);
/** /**
* Returns {@code true} if the given MemberName is a native method * Returns {@code true} if the given MemberName is a native method. Used by
* {@see StackFrameInfo}.
*/ */
boolean isNative(Object mname); boolean isNative(Object mname);
/**
* Returns a {@code byte[]} containing the bytecode for a class implementing
* DirectMethodHandle of each pairwise combination of {@code MethodType} and
* an {@code int} representing method type. Used by
* GenerateJLIClassesPlugin to generate such a class during the jlink phase.
*/
byte[] generateDMHClassBytes(String className, MethodType[] methodTypes,
int[] types);
/**
* Returns a {@code byte[]} containing the bytecode for a BoundMethodHandle
* species class implementing the signature defined by {@code types}. Used
* by GenerateBMHClassesPlugin to enable generation of such classes during
* the jlink phase. Should do some added validation since this string may be
* user provided.
*/
Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
final String types);
} }

Some files were not shown because too many files have changed in this diff Show More