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
f5902d3841b82cac6e7716a20c24e8e916fb14a8 jdk-9+129
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"
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])
if test "x$JVM_ARG_OK" = "xtrue"; then
AC_MSG_RESULT([yes])

View File

@ -5095,7 +5095,7 @@ VS_SDK_PLATFORM_NAME_2013=
#CUSTOM_AUTOCONF_INCLUDE
# 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 "Command: $JAVA -Xpatch:foo=bar -version" >&5
OUTPUT=`$JAVA -Xpatch:foo=bar -version 2>&1`
$ECHO "Check if jvm arg is ok: --patch-module foo=bar" >&5
$ECHO "Command: $JAVA --patch-module foo=bar -version" >&5
OUTPUT=`$JAVA --patch-module foo=bar -version 2>&1`
FOUND_WARN=`$ECHO "$OUTPUT" | $GREP -i warn`
FOUND_VERSION=`$ECHO $OUTPUT | $GREP " version \""`
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
else
$ECHO "Arg failed:" >&5

View File

@ -585,7 +585,7 @@ INTERIM_OVERRIDE_MODULES := java.compiler jdk.compiler \
jdk.jdeps jdk.javadoc jdk.rmic
ifeq ($(BOOT_JDK_MODULAR), true)
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)
JAVAC_MAIN_CLASS = -m jdk.compiler/com.sun.tools.javac.Main
JAVADOC_MAIN_CLASS = -m jdk.javadoc/jdk.javadoc.internal.tool.Main

View File

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

View File

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

View File

@ -533,3 +533,4 @@ adc8c84b7cf8c540d920182f78a2bc982366432a jdk-9+126
22bf6db9767b1b3a1994cbf32eb3331f31ae2093 jdk-9+128
e96b34b76d863ed1fa04e0eeb3f297ac17b490fd jdk-9+129
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)) {
return false;
}
if (s.getParameterCount(false) != parameterTypes.length) {
return false;
}
for (int i = 0; i < s.getParameterCount(false); ++i) {
if (!s.getParameterType(i, CLASS).equals(parameterTypes[i])) {
return false;

View File

@ -57,7 +57,7 @@ public final class Services {
if (jvmci != requestorModule) {
for (String pkg : jvmci.getPackages()) {
// 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.
if (!jvmci.isExported(pkg, requestorModule)) {
jvmci.addExports(pkg, requestorModule);

View File

@ -140,7 +140,7 @@ PerfCounter* ClassLoader::_unsafe_defineClassCallCounter = NULL;
PerfCounter* ClassLoader::_isUnsyncloadClass = 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;
ClassPathEntry* ClassLoader::_jrt_entry = NULL;
ClassPathEntry* ClassLoader::_first_append_entry = NULL;
@ -685,27 +685,27 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
}
#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
// loaded is defined to a module that has been specified to -Xpatch.
void ClassLoader::setup_xpatch_entries() {
// loaded is defined to a module that has been specified to --patch-module.
void ClassLoader::setup_patch_mod_entries() {
Thread* THREAD = Thread::current();
GrowableArray<ModuleXPatchPath*>* xpatch_args = Arguments::get_xpatchprefix();
int num_of_entries = xpatch_args->length();
GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
int num_of_entries = patch_mod_args->length();
assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with -Xpatch");
assert(!UseSharedSpaces, "UseSharedSpaces not supported with -Xpatch");
assert(!DumpSharedSpaces, "DumpSharedSpaces not supported with --patch-module");
assert(!UseSharedSpaces, "UseSharedSpaces not supported with --patch-module");
// Set up the boot loader's _xpatch_entries list
_xpatch_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
// Set up the boot loader's _patch_mod_entries list
_patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
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);
assert(module_sym != NULL, "Failed to obtain Symbol for module name");
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 end = 0;
// 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
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;
tty->print("[bootclasspath= ");
// Print -Xpatch module/path specifications first
if (_xpatch_entries != NULL) {
print_module_entry_table(_xpatch_entries);
// Print --patch-module module/path specifications first
if (_patch_mod_entries != NULL) {
print_module_entry_table(_patch_mod_entries);
}
// [jimage | exploded modules build]
@ -1341,7 +1341,7 @@ const char* ClassLoader::file_name_for_class_name(const char* class_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,
const char* const class_name, const char* const file_name, TRAPS) {
ClassFileStream* stream = NULL;
@ -1366,7 +1366,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
int num_of_entries = module_list->length();
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++) {
ModuleClassPathList* module_cpl = module_list->at(i);
Symbol* module_cpl_name = module_cpl->module_name();
@ -1378,7 +1378,7 @@ ClassFileStream* ClassLoader::search_module_entries(const GrowableArray<ModuleCl
while (e != NULL) {
stream = e->open_stream(file_name, CHECK_NULL);
// 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) {
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:
// - [jimage] + [_first_append_entry to _last_append_entry] (all path entries).
// No -Xpatch entries or exploded module builds are included since CDS
// is not supported if -Xpatch or exploded module builds are used.
// No --patch-module entries or exploded module builds are included since CDS
// is not supported if --patch-module or exploded module builds are used.
//
// If search_append_only is true, boot loader visibility boundaries are
// set to be _first_append_entry to the end. This includes:
// [-Xbootclasspath/a]; [jvmti appended entries]
//
// 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:
// [-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
// be true at the same time.
assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true");
// Load Attempt #1: -Xpatch
// Determine the class' defining module. If it appears in the _xpatch_entries,
// Load Attempt #1: --patch-module
// 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.
// 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
// 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.
if (_xpatch_entries != NULL && !search_append_only && !DumpSharedSpaces) {
stream = search_module_entries(_xpatch_entries, class_name, file_name, CHECK_NULL);
if (_patch_mod_entries != NULL && !search_append_only && !DumpSharedSpaces) {
stream = search_module_entries(_patch_mod_entries, class_name, file_name, CHECK_NULL);
}
// Load Attempt #2: [jimage | exploded build]
@ -1650,11 +1650,11 @@ void ClassLoader::classLoader_init2(TRAPS) {
// Create the moduleEntry for java.base
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
// to use fast_compare on module names instead of a string compare.
if (Arguments::get_xpatchprefix() != NULL) {
setup_xpatch_entries();
if (Arguments::get_patch_mod_prefix() != NULL) {
setup_patch_mod_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
// 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.
class ModuleClassPathList : public CHeapObj<mtClass> {
private:
@ -213,8 +213,8 @@ class ClassLoader: AllStatic {
static PerfCounter* _load_instance_class_failCounter;
// The boot class path consists of 3 ordered pieces:
// 1. the module/path pairs specified to -Xpatch
// -Xpatch:<module>=<file>(<pathsep><file>)*
// 1. the module/path pairs specified to --patch-module
// --patch-module=<module>=<file>(<pathsep><file>)*
// 2. the base piece
// [jimage | build with exploded modules]
// 3. boot loader append path
@ -223,8 +223,8 @@ class ClassLoader: AllStatic {
// The boot loader must obey this order when attempting
// to load a class.
// 1. Contains the module/path pairs specified to -Xpatch
static GrowableArray<ModuleClassPathList*>* _xpatch_entries;
// 1. Contains the module/path pairs specified to --patch-module
static GrowableArray<ModuleClassPathList*>* _patch_mod_entries;
// 2. the base piece
// Contains the ClassPathEntry of the modular java runtime image.
@ -256,11 +256,11 @@ class ClassLoader: AllStatic {
// Initialization:
// - 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
static void setup_bootstrap_search_path();
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 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
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,
const char* const class_name,
const char* const file_name, TRAPS);

View File

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

View File

@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/modules.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
@ -224,6 +226,7 @@ JvmtiEnv::GetNamedModule(jobject class_loader, const char* package_name, jobject
return JVMTI_ERROR_NONE;
} /* end GetNamedModule */
//
// Class functions
//
@ -3465,28 +3468,35 @@ jvmtiError
JvmtiEnv::GetSystemProperties(jint* count_ptr, char*** property_ptr) {
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);
if (err != JVMTI_ERROR_NONE) {
return err;
}
int i = 0 ;
for (SystemProperty* p = Arguments::system_properties(); p != NULL && i < *count_ptr; p = p->next(), i++) {
const char *key = p->key();
char **tmp_value = *property_ptr+i;
err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
if (err == JVMTI_ERROR_NONE) {
strcpy(*tmp_value, key);
} else {
// clean up previously allocated memory.
for (int j=0; j<i; j++) {
Deallocate((unsigned char*)*property_ptr+j);
int readable_count = 0;
// Loop through the system properties until all the readable properties are found.
for (SystemProperty* p = Arguments::system_properties(); p != NULL && readable_count < *count_ptr; p = p->next()) {
if (p->is_readable()) {
const char *key = p->key();
char **tmp_value = *property_ptr+readable_count;
readable_count++;
err = allocate((strlen(key)+1) * sizeof(char), (unsigned char**)tmp_value);
if (err == JVMTI_ERROR_NONE) {
strcpy(*tmp_value, key);
} 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;
} /* end GetSystemProperties */
@ -3498,7 +3508,8 @@ JvmtiEnv::GetSystemProperty(const char* property, char** value_ptr) {
jvmtiError err = JVMTI_ERROR_NONE;
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) {
err = JVMTI_ERROR_NOT_AVAILABLE;
} else {

View File

@ -110,7 +110,7 @@ SystemProperty *Arguments::_java_home = NULL;
SystemProperty *Arguments::_java_class_path = 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;
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.
void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
// 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);
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.name", VM_Version::vm_name(), false));
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);
}
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* key;
const char* value = "";
@ -1228,7 +1252,9 @@ bool Arguments::add_property(const char* prop) {
// private and are processed in process_sun_java_launcher_properties();
// the sun.java.launcher property is passed on to the java application
} 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 {
if (strcmp(key, "sun.java.command") == 0) {
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
PropertyList_unique_add(&_system_properties, key, value);
PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
}
if (key != prop) {
@ -1260,9 +1286,9 @@ bool Arguments::add_property(const char* prop) {
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) {
const char* key = "jdk.launcher.addmods";
const char* key = "jdk.module.addmods";
const char* old_value = Arguments::get_property(key);
size_t buf_len = strlen(key) + strlen(module_name) + 2;
if (old_value != NULL) {
@ -1277,7 +1303,7 @@ bool Arguments::append_to_addmods_property(const char* module_name) {
} else {
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);
return added;
}
@ -1287,14 +1313,14 @@ void Arguments::check_unsupported_dumping_properties() {
assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
const char* unsupported_properties[5] = { "jdk.module.main",
"jdk.module.path",
"jdk.upgrade.module.path",
"jdk.launcher.addmods",
"jdk.launcher.limitmods" };
"jdk.module.upgrade.path",
"jdk.module.addmods",
"jdk.module.limitmods" };
const char* unsupported_options[5] = { "-m",
"-modulepath",
"-upgrademodulepath",
"-addmods",
"-limitmods" };
"--module-path",
"--upgrade-module-path",
"--add-modules",
"--limit-modules" };
SystemProperty* sp = system_properties();
while (sp != NULL) {
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.
// This may not be the final mode; mode may change later in onload phase.
PropertyList_unique_add(&_system_properties, "java.vm.info",
VM_Version::vm_info_string(), false);
VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
UseInterpreter = true;
UseCompiler = true;
@ -2516,6 +2542,41 @@ bool Arguments::parse_uintx(const char* value,
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,
julong* long_arg,
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,
const JavaVMInitArgs *java_options_args,
const JavaVMInitArgs *cmd_line_args) {
bool xpatch_javabase = false;
bool patch_mod_javabase = false;
// Save default settings for some mode flags
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
// 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) {
return result;
}
// 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) {
return result;
}
// Parse args structure generated from the _JAVA_OPTIONS environment
// 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) {
return result;
}
@ -2617,7 +2678,35 @@ bool valid_jdwp_agent(char *name, bool is_path) {
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
const char* tail;
@ -2701,6 +2790,34 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
#endif // !INCLUDE_JVMTI
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
} else if (match_option(option, "-agentlib:", &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);
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)) {
return JNI_ENOMEM;
@ -3012,33 +3136,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
return JNI_ERR;
#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
} else if (match_option(option, "-Xint")) {
set_mode_flags(_int);
@ -3298,25 +3395,25 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_
return JNI_OK;
}
void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
// For java.base check for duplicate -Xpatch options being specified on the command line.
void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
// 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
// will be checked during module system initialization. The module system initialization
// will throw an ExceptionInInitializerError if this situation occurs.
if (strcmp(module_name, "java.base") == 0) {
if (*xpatch_javabase) {
vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
if (*patch_mod_javabase) {
vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
} else {
*xpatch_javabase = true;
*patch_mod_javabase = true;
}
}
// Create GrowableArray lazily, only if -Xpatch has been specified
if (_xpatchprefix == NULL) {
_xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
// Create GrowableArray lazily, only if --patch-module has been specified
if (_patch_mod_prefix == NULL) {
_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)
@ -3441,6 +3538,15 @@ jint Arguments::finalize_vm_init_args() {
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.
// java_compiler() true means set to "NONE" or empty.
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() {
if (DumpSharedSpaces) {
if (Arguments::get_xpatchprefix() != NULL) {
if (Arguments::get_patch_mod_prefix() != NULL) {
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) {
@ -4180,6 +4286,11 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
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.
UNSUPPORTED_OPTION(UseLargePages);
#endif
@ -4404,6 +4515,18 @@ int Arguments::PropertyList_count(SystemProperty* pl) {
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) {
assert(key != NULL, "just checking");
SystemProperty* prop;
@ -4413,6 +4536,27 @@ const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* ke
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) {
int count = 0;
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)
return;
SystemProperty* new_p = new SystemProperty(k, v, true);
SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
PropertyList_add(plist, new_p);
}
@ -4470,7 +4615,9 @@ void Arguments::PropertyList_add(SystemProperty *element) {
}
// 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)
return;
@ -4478,16 +4625,16 @@ void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, c
SystemProperty* prop;
for (prop = *plist; prop != NULL; prop = prop->next()) {
if (strcmp(k, prop->key()) == 0) {
if (append) {
if (append == AppendProperty) {
prop->append_value(v);
} else {
prop->set_writeable_value(v);
prop->set_value(v);
}
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

View File

@ -43,7 +43,7 @@ extern "C" {
// PathString is used as:
// - 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.
class PathString : public CHeapObj<mtArguments> {
protected:
@ -107,13 +107,13 @@ class PathString : public CHeapObj<mtArguments> {
}
};
// ModuleXPatchPath records the module/path pair as specified to -Xpatch.
class ModuleXPatchPath : public CHeapObj<mtInternal> {
// ModulePatchPath records the module/path pair as specified to --patch-module.
class ModulePatchPath : public CHeapObj<mtInternal> {
private:
char* _module_name;
PathString* _path;
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");
size_t len = strlen(module_name) + 1;
_module_name = AllocateHeap(len, mtInternal);
@ -121,7 +121,7 @@ public:
_path = new PathString(path);
}
~ModuleXPatchPath() {
~ModulePatchPath() {
if (_module_name != NULL) {
FreeHeap(_module_name);
_module_name = NULL;
@ -158,6 +158,10 @@ class SystemProperty : public PathString {
SystemProperty* next() const { return _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
// via an external interface if it is a writeable property.
// The internal, non-writeable property jdk.boot.class.path.append
@ -325,6 +329,21 @@ class Arguments : AllStatic {
arg_in_range = 0
};
enum PropertyAppendable {
AppendProperty,
AddProperty
};
enum PropertyWriteable {
WriteableProperty,
UnwriteableProperty
};
enum PropertyInternal {
InternalProperty,
ExternalProperty
};
private:
// 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 *_jdk_boot_class_path_append;
// -Xpatch:module=<file>(<pathsep><file>)*
// --patch-module=module=<file>(<pathsep><file>)*
// Each element contains the associated module name, path
// string pair as specified to -Xpatch.
static GrowableArray<ModuleXPatchPath*>* _xpatchprefix;
// string pair as specified to --patch-module.
static GrowableArray<ModulePatchPath*>* _patch_mod_prefix;
// The constructed value of the system class path after
// argument processing and JVMTI OnLoad additions via
// calls to AddToBootstrapClassLoaderSearch. This is the
// final form before ClassLoader::setup_bootstrap_search().
// Note: since -Xpatch is a module name/path pair, the system
// boot class path string no longer contains the "prefix" to
// the boot class path base piece as it did when
// Note: since --patch-module is a module name/path pair, the
// system boot class path string no longer contains the "prefix"
// to the boot class path base piece as it did when
// -Xbootclasspath/p was supported.
static PathString *_system_boot_class_path;
@ -462,7 +481,13 @@ class Arguments : AllStatic {
static vfprintf_hook_t _vfprintf_hook;
// 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
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,
const JavaVMInitArgs *java_options_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 bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
@ -708,16 +733,20 @@ class Arguments : AllStatic {
// Property List manipulation
static void PropertyList_add(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_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, jboolean append);
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,
PropertyAppendable append, PropertyWriteable writeable,
PropertyInternal internal);
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_readable_count(SystemProperty* pl);
static const char* PropertyList_get_key_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.
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); }
@ -725,7 +754,7 @@ class Arguments : AllStatic {
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
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) {
// During start up, set by os::set_boot_path()
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);
}
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_jdk_boot_class_path_append() { return _jdk_boot_class_path_append->value(); }
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.
outputStream *text = xs->text();
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");
text->print_raw(p->key());
text->put('=');
assert(p->value() != NULL, "p->value() is NULL");
text->print_raw_cr(p->value());
if (p->is_readable()) {
// Print in two stages to avoid problems with long
// keys/values.
text->print_raw(p->key());
text->put('=');
assert(p->value() != NULL, "p->value() is NULL");
text->print_raw_cr(p->value());
}
}
xs->tail("properties");
}

View File

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

View File

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

View File

@ -88,7 +88,7 @@ public class TestMaxMinHeapFreeRatioFlags {
(useXmaxf ? "-Xmaxf" + maxRatio / 100.0 : "-XX:MaxHeapFreeRatio=" + maxRatio),
"-Xmx" + MAX_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:MaxNewSize=" + MAX_NEW_SIZE,
"-XX:" + (shrinkHeapInSteps ? '+' : '-') + "ShrinkHeapInSteps",
@ -120,7 +120,7 @@ public class TestMaxMinHeapFreeRatioFlags {
Collections.addAll(vmOptions,
(useXminf ? "-Xminf" + minRatio / 100.0 : "-XX:MinHeapFreeRatio=" + minRatio),
(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"
);
ProcessBuilder procBuilder = ProcessTools.createJavaProcessBuilder(vmOptions.toArray(new String[vmOptions.size()]));

View File

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

View File

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

View File

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

View File

@ -48,7 +48,7 @@ public class BootstrapRedefine {
"-Xmodule: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())
.shouldContain("Incompatible definition of java.lang.Object")
.shouldHaveExitValue(1);

View File

@ -27,7 +27,7 @@ import java.io.File;
* @test
* @build 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 BootClassPathAppendProp
*/

View File

@ -56,7 +56,7 @@ public class CreateCoredumpOnCrash {
public static OutputAnalyzer runTest(String option) throws Exception {
return new OutputAnalyzer(
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());
}
}

View File

@ -48,7 +48,7 @@ public class ProblematicFrameTest {
public static void main(String[] args) throws Exception {
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());
output.shouldNotContain("Exception in thread");
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,
// 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
// enabled.
// using --limit-modules. Verify the behavior is the same at runtime when CDS
// 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
// loaded from the archive at runtime.
public static void testBootAppendExcludedModuleClass() throws Exception {
@ -174,7 +174,7 @@ public class BootAppendTests {
"-XX:+TraceClassLoading",
"-cp", appJar,
"-Xbootclasspath/a:" + bootAppendJar,
"-limitmods", "java.base",
"--limit-modules=java.base",
"-Xshare:" + mode,
APP_CLASS,
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
// name as a class defined in boot modules, the class is loaded
// from -Xbootclasspath/a when the boot module is excluded using
// -limitmods. Verify the behavior is the same at runtime when CDS is
// enabled.
// --limit-modules. Verify the behavior is the same at runtime
// when CDS is enabled.
//
// The org.omg.CORBA.Context is a boot module class. The class
// on -Xbootclasspath/a that has the same fully-qualified name
@ -206,7 +206,7 @@ public class BootAppendTests {
"-XX:+TraceClassLoading",
"-cp", appJar,
"-Xbootclasspath/a:" + bootAppendJar,
"-limitmods", "java.base",
"--limit-modules=java.base",
"-Xshare:" + mode,
APP_CLASS,
BOOT_APPEND_DUPLICATE_MODULE_CLASS_NAME);

View File

@ -89,10 +89,11 @@ public class SASymbolTableTest {
long pid = p.getPid();
System.out.println("Attaching agent " + pid);
ProcessBuilder tool = ProcessTools.createJavaProcessBuilder(
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED",
"-XaddExports:jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED",
"--add-modules=jdk.hotspot.agent",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
"--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.memory=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",
Long.toString(pid));
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.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,7 @@ public class RangeCheck {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
true,
"-Xmx32m",
"-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED",
"--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
"-XX:-TransmitErrorReport",
"-XX:-CreateCoredumpOnCrash",
"-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);
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");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
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(
SRC_DIR.resolve("jdk.translet"),
MODS_DIR.resolve("jdk.translet"),
"-XaddExports:jdk.test/test=jdk.translet",
"-mp", MODS_DIR.toString());
"--add-exports=jdk.test/test=jdk.translet",
"-p", MODS_DIR.toString());
if (!compiled) {
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
// runs without error.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-mp", MODS_DIR.toString(),
"-p", MODS_DIR.toString(),
"-m", "jdk.test/test.Main");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("failed: 0")

View File

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

View File

@ -23,17 +23,17 @@
/*
* @test
* @summary Make sure -Xpatch works with multiple directories.
* @summary Make sure --patch-module works with multiple directories.
* @modules java.base/jdk.internal.misc
* @library /testlibrary
* @compile Xpatch2DirsMain.java
* @run main Xpatch2Dirs
* @compile PatchModule2DirsMain.java
* @run main PatchModule2Dirs
*/
import jdk.test.lib.*;
import java.io.File;
public class Xpatch2Dirs {
public class PatchModule2Dirs {
public static void main(String[] args) throws Exception {
String source1 = "package javax.naming.spi; " +
@ -58,9 +58,9 @@ public class Xpatch2Dirs {
"mods2/java.desktop");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.naming=mods/java.naming",
"-Xpatch:java.desktop=mods2/java.desktop",
"Xpatch2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
"--patch-module=java.naming=mods/java.naming",
"--patch-module=java.desktop=mods2/java.desktop",
"PatchModule2DirsMain", "javax.naming.spi.NamingManager", "java.beans.Encoder");
OutputAnalyzer oa = new OutputAnalyzer(pb.start());
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.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,9 +21,9 @@
* questions.
*/
// This loads the class affected by the -Xpatch option. For the test to pass
// it must load both classes from the -Xpatch directory, not the jimage file.
public class Xpatch2DirsMain {
// This loads the class affected by the --patch-module option. For the test to pass
// it must load both classes from the --patch-module directory, not the jimage file.
public class PatchModule2DirsMain {
public static void main(String[] args) throws Exception {
Class.forName(args[0]);
Class.forName(args[1]);

View File

@ -25,22 +25,22 @@
* @test
* @library /testlibrary
* @modules java.base/jdk.internal.misc
* @run main XpatchCDS
* @run main PatchModuleCDS
*/
import java.io.File;
import jdk.test.lib.*;
public class XpatchCDS {
public class PatchModuleCDS {
public static void main(String args[]) throws Throwable {
System.out.println("Test that -Xpatch and -Xshare:dump are incompatibable");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming", "-Xshare:dump");
System.out.println("Test that --patch-module and -Xshare:dump are incompatibable");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming", "-Xshare:dump");
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");
String filename = "Xpatch.jsa";
System.out.println("Test that --patch-module and -Xshare:on are incompatibable");
String filename = "patch_module.jsa";
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename,
@ -52,10 +52,10 @@ public class XpatchCDS {
"-XX:+UnlockDiagnosticVMOptions",
"-XX:SharedArchiveFile=" + filename,
"-Xshare:on",
"-Xpatch:java.naming=mods/java.naming",
"--patch-module=java.naming=mods/java.naming",
"-version");
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);
}

View File

@ -23,23 +23,23 @@
/*
* @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
* @library /testlibrary
*/
import jdk.test.lib.*;
public class XpatchDupJavaBase {
public class PatchModuleDupJavaBase {
// 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 {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.base=javabase_dir",
"-Xpatch:java.base=javabase_dir",
"--patch-module=java.base=javabase_dir",
"--patch-module=java.base=javabase_dir",
"-version");
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);
}
}

View File

@ -23,26 +23,25 @@
/*
* @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
* @library /testlibrary
*/
import jdk.test.lib.*;
public class XpatchDupModule {
public class PatchModuleDupModule {
// 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 {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-Xpatch:module1=module1_dir",
"-Xpatch:module1=module1_dir",
"--patch-module=module1=module1_dir",
"--patch-module=module1=module1_dir",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("java.lang.ExceptionInInitializerError");
output.shouldHaveExitValue(1);
}
}

View File

@ -24,16 +24,16 @@
/*
* @test
* @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
* @library /testlibrary
* @compile XpatchMain.java
* @run main XpatchJavaBase
* @compile PatchModuleMain.java
* @run main PatchModuleJavaBase
*/
import jdk.test.lib.*;
public class XpatchJavaBase {
public class PatchModuleJavaBase {
public static void main(String[] args) throws Exception {
String source = "package java.lang; " +
@ -47,8 +47,8 @@ public class XpatchJavaBase {
InMemoryJavaCompiler.compile("java.lang.NewClass", source, "-Xmodule:java.base"),
"mods/java.base");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.base=mods/java.base",
"XpatchMain", "java.lang.NewClass");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.base=mods/java.base",
"PatchModuleMain", "java.lang.NewClass");
new OutputAnalyzer(pb.start())
.shouldContain("I pass!")

View File

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

View File

@ -24,16 +24,16 @@
/*
* @test
* @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
* @library /testlibrary
* @compile XpatchMain.java
* @run main XpatchTest
* @compile PatchModuleMain.java
* @run main PatchModuleTest
*/
import jdk.test.lib.*;
public class XpatchTest {
public class PatchModuleTest {
public static void main(String[] args) throws Exception {
String source = "package javax.naming.spi; " +
@ -47,8 +47,8 @@ public class XpatchTest {
InMemoryJavaCompiler.compile("javax.naming.spi.NamingManager", source, "-Xmodule:java.naming"),
"mods/java.naming");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=mods/java.naming",
"XpatchMain", "javax.naming.spi.NamingManager");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=mods/java.naming",
"PatchModuleMain", "javax.naming.spi.NamingManager");
new OutputAnalyzer(pb.start())
.shouldContain("I pass!")

View File

@ -23,18 +23,18 @@
/*
* @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
* @modules java.base/jdk.internal.misc
* jdk.jartool/sun.tools.jar
* @build BasicJarBuilder
* @compile XpatchMain.java
* @run main XpatchTestJar
* @compile PatchModuleMain.java
* @run main PatchModuleTestJar
*/
import jdk.test.lib.*;
public class XpatchTestJar {
public class PatchModuleTestJar {
private static String moduleJar;
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"),
System.getProperty("test.classes"));
// Supply -Xpatch with the name of the jar file for the module java.naming.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xpatch:java.naming=" + moduleJar,
"XpatchMain", "javax.naming.spi.NamingManager");
// Supply --patch-module with the name of the jar file for the module java.naming.
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("--patch-module=java.naming=" + moduleJar,
"PatchModuleMain", "javax.naming.spi.NamingManager");
new OutputAnalyzer(pb.start())
.shouldContain("I pass!")

View File

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

View File

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

View File

@ -23,13 +23,13 @@
/*
* @test
* @summary Ensure that a newly introduced java.base package placed within the -Xpatch directory
* is considered part of the boot loader's visibility boundary
* @summary Ensure that a newly introduced java.base package placed within the --patch-module
* directory is considered part of the boot loader's visibility boundary
* @requires !(os.family == "windows")
* @library /testlibrary
* @modules java.base/jdk.internal.misc
* java.management
* @run main/othervm XpatchVisibility
* @run main/othervm PatchModuleVisibility
*/
import java.io.File;
@ -38,7 +38,7 @@ import java.nio.file.Paths;
import jdk.test.lib.*;
public class XpatchVisibility {
public class PatchModuleVisibility {
public static void main(String[] args) throws Throwable {
@ -55,19 +55,19 @@ public class XpatchVisibility {
"public class Vis2_A {" +
" public static void main(String args[]) throws Exception {" +
// 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 {" +
" p2.Vis2_B b = new p2.Vis2_B();" +
" 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\");" +
" }" +
" b.m();" +
" } catch (Throwable e) {" +
" throw new RuntimeException(\"XpatchVisibility FAILED - test " +
" throw new RuntimeException(\"PatchModuleVisibility FAILED - test " +
"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"));
new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(
"-Xpatch:java.base=mods2/java.base",
"-XaddExports:java.base/p2=ALL-UNNAMED",
"--patch-module=java.base=mods2/java.base",
"--add-exports=java.base/p2=ALL-UNNAMED",
"Vis2_A")
.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
// 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:
// [-Xpatch]; exploded build | "modules" jimage
// [--patch-module]; exploded build | "modules" jimage
//
// Since the class is located on the boot loader's append path via
// -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.
*
* 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
* 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.
*/

View File

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

View File

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

View File

@ -87,7 +87,7 @@ public class JMapHProfLargeHeapTest {
String expectedFormat) throws Exception, IOException,
InterruptedException, FileNotFoundException {
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);
Process largeHeapProc = procBuilder.start();

View File

@ -58,10 +58,10 @@ cleantmp:
ctw.jar: filelist wb.jar
@mkdir -p $(OUTPUT_DIR)
$(JAVAC) -XaddExports:java.base/jdk.internal.jimage=ALL-UNNAMED \
-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED \
-XaddExports:java.base/jdk.internal.reflect=ALL-UNNAMED \
-sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
$(JAVAC) --add-exports java.base/jdk.internal.jimage=ALL-UNNAMED \
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED \
--add-exports java.base/jdk.internal.reflect=ALL-UNNAMED \
-sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist
$(JAR) --create --file=$@ --main-class $(MAIN_CLASS) -C $(OUTPUT_DIR) .
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.
#
# 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)
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
$(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)
@rm -f $@
@ -109,7 +109,7 @@ INIT: $(DIST_DIR)
$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
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:
@rm -rf $(TESTBASE_DIR)

View File

@ -373,3 +373,4 @@ bdc3c0b737efbf899709eb3121ce760dcfb51151 jdk-9+127
8a7681a9d70640ac7fbf05c28f53c1d51d8d00a1 jdk-9+128
74241304e87b0d463391a8ecab40979b5af86dc2 jdk-9+129
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.4=Invalid quantifier. A min quantity must be <= a max quantity.
parser.quantifier.5=Invalid quantifier. A quantity value overflow.
null
null

View File

@ -23,4 +23,7 @@ modules=java.xml
groups=TEST.groups
# 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 {
JAXPPolicyManager.teardownPolicyManager();
} 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 java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.net.SocketTimeoutException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
@ -52,7 +50,7 @@ import org.xml.sax.SAXParseException;
/*
* @test
* @bug 8158084 8162438 8162442
* @bug 8158084 8162438 8162442 8163535
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport2
* @run testng/othervm catalog.CatalogSupport2
@ -97,7 +95,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/*
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
xml, MyHandler handler, String expected) throws Exception {
testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -106,7 +104,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/*
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,
String xml, MyHandler handler, String expected) throws Exception {
testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -124,7 +122,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
/*
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,
String xml, MyHandler handler, String expected) throws Exception {
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -141,7 +139,7 @@ public class CatalogSupport2 extends CatalogSupportBase {
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,
Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
String catalog1, String catalog2)

View File

@ -27,10 +27,8 @@ import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.net.SocketTimeoutException;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
@ -51,7 +49,7 @@ import org.xml.sax.SAXParseException;
/*
* @test
* @bug 8158084 8162438 8162442
* @bug 8158084 8162438 8162442 8163535
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport3
* @run testng/othervm catalog.CatalogSupport3
@ -93,7 +91,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/*
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 xml, MyHandler handler, String expected) throws Exception {
testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -102,7 +100,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/*
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,
String xml, MyHandler handler, String expected) throws Exception {
testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
@ -120,7 +118,7 @@ public class CatalogSupport3 extends CatalogSupportBase {
/*
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,
String xml, MyHandler handler, String expected) throws Exception {
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
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,
Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
String catalog1, String catalog2)

View File

@ -32,11 +32,10 @@ import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
@ -69,6 +68,7 @@ public class Bug6773084Test {
private static final ExecutorService EXEC = Executors.newCachedThreadPool();
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 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++) {
EXEC.execute(new XMLValiddator(files[i], i));
EXEC.execute(new XMLValiddator(dbf.newDocumentBuilder().parse(files[i]), i));
}
runWithAllPerm(() -> EXEC.shutdown());
EXEC.awaitTermination(TIMEOUT, TimeUnit.SECONDS);
}
private static class XMLValiddator implements Runnable {
private File file;
private Document document;
private int index;
public XMLValiddator(File file, int index) {
this.file = file;
public XMLValiddator(Document document, int index) {
this.document = document;
this.index = index;
}
@ -117,23 +120,14 @@ public class Bug6773084Test {
BARRIER.await();
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.setErrorHandler(new ErrorHandlerImpl());
validator.validate(new DOMSource(document));
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
Assert.fail("Test failed.");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (InterruptedException e) {

View File

@ -373,3 +373,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
9446c534f0222b4eecfd9d9e25ab37c4fd4400a5 jdk-9+128
47699aa2e69ec2702542dc73eb01de3bfb61aea0 jdk-9+129
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
$(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

View File

@ -36,12 +36,12 @@ $(eval $(call SetupJavaCompilation,BUILD_JIGSAW_TOOLS, \
INCLUDES := build/tools/deps \
build/tools/jigsaw, \
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) \
build.tools.jigsaw.GenGraphs
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

View File

@ -38,7 +38,7 @@ BUILD_TOOLS_JDK := $(call SetupJavaCompilationCompileTarget, \
################################################################################
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
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.
ifeq ($(BOOT_JDK_MODULAR), true)
COMPILENIMBUS_ADD_MODS := -addmods java.xml.bind
COMPILENIMBUS_ADD_MODS := --add-modules java.xml.bind
endif
TOOL_GENERATENIMBUS = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \

View File

@ -203,7 +203,7 @@ TARGETS += $(DEF_POLICY_DST)
################################################################################
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
CACERTS_DST := $(LIB_DST_DIR)/security/cacerts

View File

@ -63,11 +63,11 @@ $(eval $(call SetupJavaCompilation,BUILD_BREAKITERATOR_LD, \
ifeq ($(BOOT_JDK_MODULAR), true)
BREAK_ITERATOR_BOOTCLASSPATH := \
-Xpatch:java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
-Xpatch:jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
-XaddExports:java.base/sun.text=ALL-UNNAMED \
-XaddExports:java.base/sun.text.resources=ALL-UNNAMED \
-XaddExports:jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
--patch-module java.base=$(BREAK_ITERATOR_CLASSES)/java.base \
--patch-module jdk.localedata=$(BREAK_ITERATOR_CLASSES)/jdk.localedata \
--add-exports java.base/sun.text=ALL-UNNAMED \
--add-exports java.base/sun.text.resources=ALL-UNNAMED \
--add-exports jdk.localedata/sun.text.resources.ext=ALL-UNNAMED \
#
else
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
$(eval $(call SetupBuildLauncher, appletviewer, \
MAIN_CLASS := sun.applet.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
LIBS_unix := $(X_LIBS), \
))
endif

View File

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

View File

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

View File

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

View File

@ -27,6 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
JAVA_ARGS := -addmods ALL-DEFAULT, \
JAVA_ARGS := --add-modules ALL-DEFAULT, \
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.*;
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 {
int i=0;
@ -61,13 +61,13 @@ public class ModuleSummary {
while (i < args.length && args[i].startsWith("-")) {
String arg = args[i++];
switch (arg) {
case "-mp":
case "--module-path":
modpath = Paths.get(args[i++]);
break;
case "-o":
outfile = Paths.get(args[i++]);
break;
case "-root":
case "--root":
roots.add(args[i++]);
default:
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.
*
* 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;
/**
* Standard constructor, creates a new HmacCore instance using the
* specified MessageDigest object.
* Standard constructor, creates a new HmacCore instance instantiating
* 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.blockLen = bl;
this.k_ipad = new byte[blockLen];
@ -64,14 +91,6 @@ abstract class HmacCore extends MacSpi implements Cloneable {
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.
*

View File

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

View File

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

View File

@ -644,23 +644,20 @@ public final class System {
* <code>getProperties</code> operation, it may choose to permit the
* {@link #getProperty(String)} operation.
*
* @implNote In addition to the standard system properties, the {@code
* java} launcher may create the Java Virtual Machine with system
* properties that have the following keys:
* @implNote In addition to the standard system properties, the system
* properties may include the following keys:
* <table summary="Shows property keys and associated values">
* <tr><th>Key</th>
* <th>Description of Associated Value</th></tr>
* <tr><td>{@code jdk.module.path}</td>
* <td>Application module path</td></tr>
* <tr><td>{@code jdk.upgrade.module.path}</td>
* <td>The application module path</td></tr>
* <tr><td>{@code jdk.module.upgrade.path}</td>
* <td>The upgrade module path</td></tr>
* <tr><td>{@code jdk.module.main}</td>
* <td>The module name of the initial/main module</td></tr>
* <tr><td>{@code jdk.module.main.class}</td>
* <td>The main class name of the initial module</td></tr>
* </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
* @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;
}
/**
* @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) {
static String speciesInternalClassName(String 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.

View File

@ -186,7 +186,7 @@ class DirectMethodHandle extends MethodHandle {
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 doesAlloc = (which == LF_NEWINVSPECIAL);
String linkerName, lambdaName;
@ -248,20 +248,6 @@ class DirectMethodHandle extends MethodHandle {
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) {
if (name.function == NF_internalMemberName ||
name.function == NF_internalMemberNameEnsureInit ||
@ -273,7 +259,7 @@ class DirectMethodHandle extends MethodHandle {
}
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...
lform.compileToBytecode();
}
@ -515,7 +501,7 @@ class DirectMethodHandle extends MethodHandle {
// Enumerate the different field kinds using Wrapper,
// with an extra case added for checked references.
private static final int
FT_LAST_WRAPPER = Wrapper.values().length-1,
FT_LAST_WRAPPER = Wrapper.COUNT-1,
FT_UNCHECKED_REF = Wrapper.OBJECT.ordinal(),
FT_CHECKED_REF = FT_LAST_WRAPPER+1,
FT_LIMIT = FT_LAST_WRAPPER+2;
@ -576,25 +562,36 @@ class DirectMethodHandle extends MethodHandle {
return lform;
}
private static final Wrapper[] ALL_WRAPPERS = Wrapper.values();
private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
boolean isGetter = (formOp & 1) == (AF_GETFIELD & 1);
boolean isStatic = (formOp >= AF_GETSTATIC);
boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
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();
assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
String tname = fw.primitiveSimpleName();
String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
if (isVolatile) ctname += "Volatile";
String getOrPut = (isGetter ? "get" : "put");
String linkerName = (getOrPut + ctname); // getObject, putIntVolatile, etc.
// getObject, putIntVolatile, etc.
StringBuilder nameBuilder = new StringBuilder();
if (isGetter) {
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;
if (isGetter)
linkerType = MethodType.methodType(ft, Object.class, long.class);
else
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 {
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
} catch (ReflectiveOperationException ex) {
@ -649,11 +646,16 @@ class DirectMethodHandle extends MethodHandle {
if (needsCast && isGetter)
names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
for (Name n : names) assert(n != null);
String fieldOrStatic = (isStatic ? "Static" : "Field");
String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging
if (needsCast) lambdaName += "Cast";
if (needsInit) lambdaName += "Init";
return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
// add some detail to the lambdaForm debugname,
// significant only for debugging
if (isStatic) {
nameBuilder.append("Static");
} 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.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import static java.lang.invoke.LambdaForm.*;
@ -68,9 +68,10 @@ class InvokerBytecodeGenerator {
private static final String LFN_SIG = "L" + LFN + ";";
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 CLASS_PREFIX = LF + "$";
/** Name of its super class*/
private static final String INVOKER_SUPER_NAME = OBJ;
static final String INVOKER_SUPER_NAME = OBJ;
/** Name of new class */
private final String className;
@ -96,15 +97,15 @@ class InvokerBytecodeGenerator {
/** Main constructor; other constructors delegate to this one. */
private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
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);
invokerName = invokerName.substring(p+1);
invokerName = invokerName.substring(p + 1);
}
if (DUMP_CLASS_FILES) {
className = makeDumpableClassName(className);
}
this.className = LF + "$" + className;
this.className = CLASS_PREFIX + className;
this.sourceFile = "LambdaForm$" + className;
this.lambdaForm = lambdaForm;
this.invokerName = invokerName;
@ -124,7 +125,7 @@ class InvokerBytecodeGenerator {
}
/** 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,
className, form.debugName, invokerType);
// Create an array to map name indexes to locals indexes.
@ -201,38 +202,34 @@ class InvokerBytecodeGenerator {
class CpPatch {
final int index;
final String placeholder;
final Object value;
CpPatch(int index, String placeholder, Object value) {
CpPatch(int index, Object value) {
this.index = index;
this.placeholder = placeholder;
this.value = value;
}
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 cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>"; // debugging aid
if (cpPatches.containsKey(cpPlaceholder)) {
throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
}
if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + debugString(arg) + ">>";
// TODO check if arg is already in the constant pool
// insert placeholder in CP and remember the patch
int index = cw.newConst((Object) cpPlaceholder); // TODO check if already in the constant pool
cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
int index = cw.newConst((Object) cpPlaceholder);
cpPatches.add(new CpPatch(index, arg));
return cpPlaceholder;
}
Object[] cpPatches(byte[] classFile) {
int size = getConstantPoolSize(classFile);
Object[] res = new Object[size];
for (CpPatch p : cpPatches.values()) {
for (CpPatch p : cpPatches) {
if (p.index >= size)
throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
res[p.index] = p.value;
@ -655,35 +652,11 @@ class InvokerBytecodeGenerator {
return classFile;
}
/*
* 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) {
void setClassWriter(ClassWriter cw) {
this.cw = cw;
}
private void addMethod() {
void addMethod() {
methodPrologue();
// Suppress this method in backtraces displayed to the user.
@ -765,7 +738,7 @@ class InvokerBytecodeGenerator {
continue;
case IDENTITY:
assert(name.arguments.length == 1);
emitPushArguments(name);
emitPushArguments(name, 0);
continue;
case ZERO:
assert(name.arguments.length == 0);
@ -819,7 +792,7 @@ class InvokerBytecodeGenerator {
assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
assert elementType != null;
emitPushArguments(name);
emitPushArguments(name, 0);
if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
Wrapper w = Wrapper.forPrimitiveType(elementType);
arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
@ -848,7 +821,7 @@ class InvokerBytecodeGenerator {
}
// push arguments
emitPushArguments(name);
emitPushArguments(name, 0);
// invocation
MethodType type = name.function.methodType();
@ -947,7 +920,7 @@ class InvokerBytecodeGenerator {
assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
// push arguments
emitPushArguments(name);
emitPushArguments(name, 0);
// invocation
if (member.isMethod()) {
@ -1468,13 +1441,10 @@ class InvokerBytecodeGenerator {
}
}
private void emitPushArguments(Name args) {
emitPushArguments(args, 0);
}
private void emitPushArguments(Name args, int start) {
MethodType type = args.function.methodType();
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 TYPE_LIMIT = ALL_TYPES.length;
private final char btChar;
private final Class<?> btClass;
private final Wrapper btWrapper;
final char btChar;
final Class<?> btClass;
final Wrapper btWrapper;
private BasicType(char btChar, Class<?> btClass, Wrapper wrapper) {
this.btChar = btChar;
@ -1366,10 +1366,11 @@ class LambdaForm {
}
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;
for (Class<?> pt : type.parameterList()) {
sig[sigp++] = basicTypeChar(pt);
while (sigp < params) {
sig[sigp] = basicTypeChar(type.parameterType(sigp++));
}
sig[sigp++] = '_';
sig[sigp++] = basicTypeChar(type.returnType());
@ -1407,7 +1408,7 @@ class LambdaForm {
static final class Name {
final BasicType type;
private short index;
@Stable short index;
final NamedFunction function;
final Object constraint; // additional type information, if not null
@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.
* 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.
* 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 byte[] fullBytes;
private enum Kind {
NO_KIND, // necessary because ordinal must be greater than zero
BIND_ARG, ADD_ARG, DUP_ARG,
SPREAD_ARGS,
FILTER_ARG, FILTER_RETURN, FILTER_RETURN_TO_ZERO,
COLLECT_ARGS, COLLECT_ARGS_TO_VOID, COLLECT_ARGS_TO_ARRAY,
FOLD_ARGS, FOLD_ARGS_TO_VOID,
PERMUTE_ARGS,
LOCAL_TYPES
//maybe add more for guard with test, catch exception, pointwise type conversions
}
// maybe add more for guard with test, catch exception, pointwise type conversions
private static final byte
BIND_ARG = 1,
ADD_ARG = 2,
DUP_ARG = 3,
SPREAD_ARGS = 4,
FILTER_ARG = 5,
FILTER_RETURN = 6,
FILTER_RETURN_TO_ZERO = 7,
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 int
@ -131,20 +136,6 @@ class LambdaFormEditor {
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) {
super(result);
this.packedBytes = packedBytes;
@ -162,44 +153,39 @@ class LambdaFormEditor {
assert((b & 0xFF) == b); // incoming value must fit in *unsigned* byte
return (byte)b;
}
private static byte bval(Kind k) {
return bval(k.ordinal());
}
static Transform of(Kind k, int b1) {
static Transform of(byte k, int b1) {
byte b0 = bval(k);
if (inRange(b0 | b1))
return new Transform(packedBytes(b0, b1));
else
return new Transform(fullBytes(b0, b1));
}
static Transform of(Kind k, int b1, int b2) {
byte b0 = (byte) k.ordinal();
static Transform of(byte b0, int b1, int b2) {
if (inRange(b0 | b1 | b2))
return new Transform(packedBytes(b0, b1, b2));
else
return new Transform(fullBytes(b0, b1, b2));
}
static Transform of(Kind k, int b1, int b2, int b3) {
byte b0 = (byte) k.ordinal();
static Transform of(byte b0, int b1, int b2, int b3) {
if (inRange(b0 | b1 | b2 | b3))
return new Transform(packedBytes(b0, b1, b2, b3));
else
return new Transform(fullBytes(b0, b1, b2, b3));
}
private static final byte[] NO_BYTES = {};
static Transform of(Kind k, int... b123) {
return ofBothArrays(k, b123, NO_BYTES);
static Transform of(byte kind, int... b123) {
return ofBothArrays(kind, b123, NO_BYTES);
}
static Transform of(Kind k, int b1, byte[] b234) {
return ofBothArrays(k, new int[]{ b1 }, b234);
static Transform of(byte kind, int b1, byte[] b234) {
return ofBothArrays(kind, new int[]{ b1 }, b234);
}
static Transform of(Kind k, int b1, int b2, byte[] b345) {
return ofBothArrays(k, new int[]{ b1, b2 }, b345);
static Transform of(byte kind, int b1, int b2, byte[] 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];
int i = 0;
fullBytes[i++] = bval(k);
fullBytes[i++] = bval(kind);
for (int bv : b123) {
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.
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);
if (form != null) {
assert(form.parameterConstraint(0) == newSpeciesData(lambdaForm.parameterType(pos)));
@ -484,7 +470,7 @@ class LambdaFormEditor {
}
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);
if (form != null) {
assert(form.arity == lambdaForm.arity+1);
@ -501,7 +487,7 @@ class LambdaFormEditor {
}
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);
if (form != null) {
assert(form.arity == lambdaForm.arity-1);
@ -530,7 +516,7 @@ class LambdaFormEditor {
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);
if (form != null) {
assert(form.arity == lambdaForm.arity - arrayLength + 1);
@ -569,9 +555,9 @@ class LambdaFormEditor {
return filterArgumentForm(pos, basicType(collectorType.parameterType(0)));
}
byte[] newTypes = BasicType.basicTypesOrd(collectorType.parameterArray());
Transform.Kind kind = (dropResult
? Transform.Kind.COLLECT_ARGS_TO_VOID
: Transform.Kind.COLLECT_ARGS);
byte kind = (dropResult
? Transform.COLLECT_ARGS_TO_VOID
: Transform.COLLECT_ARGS);
if (dropResult && collectorArity == 0) pos = 1; // pure side effect
Transform key = Transform.of(kind, pos, collectorArity, newTypes);
LambdaForm form = getInCache(key);
@ -598,7 +584,7 @@ class LambdaFormEditor {
argTypeKey = TYPE_LIMIT + Wrapper.forPrimitiveType(elementType).ordinal();
}
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);
LambdaForm form = getInCache(key);
if (form != null) {
@ -634,7 +620,7 @@ class LambdaFormEditor {
}
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);
if (form != null) {
assert(form.arity == lambdaForm.arity);
@ -710,7 +696,7 @@ class LambdaFormEditor {
}
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());
LambdaForm form = getInCache(key);
if (form != null) {
@ -762,11 +748,11 @@ class LambdaFormEditor {
LambdaForm foldArgumentsForm(int foldPos, boolean dropResult, MethodType combinerType) {
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);
LambdaForm form = getInCache(key);
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;
}
form = makeArgumentCombinationForm(foldPos, combinerType, true, dropResult);
@ -786,7 +772,7 @@ class LambdaFormEditor {
}
assert(skip + reorder.length == lambdaForm.arity);
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);
if (form != null) {
assert(form.arity == skip+inTypes) : form;
@ -855,7 +841,7 @@ class LambdaFormEditor {
int[] desc = BasicType.basicTypeOrds(localTypes);
desc = Arrays.copyOf(desc, desc.length + 1);
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);
if (form != null) {
return form;

View File

@ -25,8 +25,6 @@
package java.lang.invoke;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.VerifyAccess;
@ -37,7 +35,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Module;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@ -81,7 +78,7 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
private int flags; // modifier bits; see reflect.Modifier
//@Injected JVM_Method* vmtarget;
//@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.
* 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;
}
private void initResolved(boolean isResolved) {
void initResolved(boolean isResolved) {
assert(this.resolution == null); // not initialized yet!
if (!isResolved)
this.resolution = this;
@ -1002,7 +999,9 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
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
// one signature might correspond to several types.
// So if matchType is a Class or MethodType, refilter the results.
@ -1150,27 +1149,4 @@ import static java.lang.invoke.MethodHandleStatics.newInternalError;
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;
import jdk.internal.misc.JavaLangInvokeAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.org.objectweb.asm.AnnotationVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
@ -38,12 +40,11 @@ import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
import java.lang.reflect.Array;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
@ -57,19 +58,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* @author jrose
*/
/*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:
@ -649,7 +637,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
MethodType srcType = targetType // (a..., [b...])=>r
.dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
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... ]
// 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();
if (arity > 1) {
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 makePairwiseConvert(NF_throwException.resolvedHandle(), type, false, true);
@ -1710,6 +1698,39 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
} catch (ReflectiveOperationException 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(). */

View File

@ -53,6 +53,7 @@ import java.util.Properties;
static final boolean PROFILE_GWT;
static final int CUSTOMIZE_THRESHOLD;
static final boolean VAR_HANDLE_GUARDS;
static final int MAX_ARITY;
static {
Properties props = GetPropertyAction.privilegedGetProperties();
@ -79,6 +80,10 @@ import java.util.Properties;
VAR_HANDLE_GUARDS = Boolean.parseBoolean(
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) {
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 static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
// See IMPL_LOOKUP below.
@ -3115,7 +3115,7 @@ assert((int)twice.invokeExact(21) == 42);
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) {
MethodType mtype = methodType(ptype, ptype);
LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
@ -3133,7 +3133,7 @@ assert((int)twice.invokeExact(21) == 42);
assert(btw == Wrapper.OBJECT);
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) {
MethodType mtype = methodType(rtype);
LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
@ -3268,12 +3268,11 @@ assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
*/
public static
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) {
Object[] a = types.toArray();
return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
private static List<Class<?>> copyTypes(Object[] array) {
return Arrays.asList(Arrays.copyOf(array, array.length, Class[].class));
}
private static
@ -3352,13 +3351,13 @@ assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
*/
public static
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 static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, List<Class<?>> newTypes, int pos,
boolean nullOnFailure) {
newTypes = copyTypes(newTypes);
newTypes = copyTypes(newTypes.toArray());
List<Class<?>> oldTypes = target.type().parameterList();
int match = oldTypes.size();
if (skip != 0) {
@ -3900,10 +3899,14 @@ assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
int foldVals = rtype == void.class ? 0 : 1;
int afterInsertPos = foldPos + foldVals;
boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
if (ok && !(combinerType.parameterList()
.equals(targetType.parameterList().subList(afterInsertPos,
afterInsertPos + foldArgs))))
ok = false;
if (ok) {
for (int i = 0; i < foldArgs; i++) {
if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
ok = false;
break;
}
}
}
if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
ok = false;
if (!ok)

View File

@ -539,10 +539,10 @@ class MethodType implements java.io.Serializable {
return res;
} else {
// insert after (if need be), then before
if (pos < parameterList().size() - 1) {
res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size()));
if (pos < ptypes.length - 1) {
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) {
Object cnst = constants[constC++];
el.add(new RecipeElement(cnst));
}
if (c == TAG_ARG) {
} else if (c == TAG_ARG) {
el.add(new RecipeElement(argC++));
}
} else {
// Not a special characters, this is a constant embedded into
// Not a special character, this is a constant embedded into
// the recipe itself.
acc.append(c);
}
@ -322,31 +321,31 @@ public final class StringConcatFactory {
private static final class RecipeElement {
private final Object value;
private final int argPos;
private final Tag tag;
private final char tag;
public RecipeElement(Object cnst) {
this.value = Objects.requireNonNull(cnst);
this.argPos = -1;
this.tag = Tag.CONST;
this.tag = TAG_CONST;
}
public RecipeElement(int arg) {
this.value = null;
this.argPos = arg;
this.tag = Tag.ARG;
this.tag = TAG_ARG;
}
public Object getValue() {
assert (tag == Tag.CONST);
assert (tag == TAG_CONST);
return value;
}
public int getArgPos() {
assert (tag == Tag.ARG);
assert (tag == TAG_ARG);
return argPos;
}
public Tag getTag() {
public char getTag() {
return tag;
}
@ -357,22 +356,18 @@ public final class StringConcatFactory {
RecipeElement that = (RecipeElement) o;
if (tag != that.tag) return false;
if (tag == Tag.CONST && (!value.equals(that.value))) return false;
if (tag == Tag.ARG && (argPos != that.argPos)) return false;
if (this.tag != that.tag) return false;
if (this.tag == TAG_CONST && (!value.equals(that.value))) return false;
if (this.tag == TAG_ARG && (argPos != that.argPos)) return false;
return true;
}
@Override
public int hashCode() {
return tag.hashCode();
return (int)tag;
}
}
private enum Tag {
CONST, ARG
}
/**
* Facilitates the creation of optimized String concatenation methods, that
* 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
*/
private static MethodType adaptType(MethodType args) {
Class<?>[] ptypes = args.parameterArray();
boolean changed = false;
for (int i = 0; i < ptypes.length; i++) {
Class<?> ptype = ptypes[i];
Class<?>[] ptypes = null;
for (int i = 0; i < args.parameterCount(); i++) {
Class<?> ptype = args.parameterType(i);
if (!ptype.isPrimitive() &&
ptype != String.class &&
ptype != Object.class) { // truncate to Object
if (ptypes == null) {
ptypes = args.parameterArray();
}
ptypes[i] = Object.class;
changed = true;
}
// else other primitives or String or Object (unchanged)
}
return changed
return (ptypes != null)
? MethodType.methodType(args.returnType(), ptypes)
: args;
}
@ -881,11 +877,10 @@ public final class StringConcatFactory {
int off = 0;
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
// Guaranteed non-null, no null check required.
break;
}
case ARG: {
case TAG_ARG:
// 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
// with "null" constant. Note, we omit Objects here, because we don't call
@ -902,7 +897,6 @@ public final class StringConcatFactory {
}
off += getParameterSize(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
@ -926,12 +920,11 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object cnst = el.getValue();
len += cnst.toString().length();
break;
}
case ARG: {
case TAG_ARG:
/*
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
@ -953,7 +946,6 @@ public final class StringConcatFactory {
}
off += getParameterSize(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
@ -988,22 +980,21 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) {
String desc;
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object cnst = el.getValue();
mv.visitLdcInsn(cnst);
desc = getSBAppendDesc(cnst.getClass());
break;
}
case ARG: {
case TAG_ARG:
Class<?> cl = arr[el.getArgPos()];
mv.visitVarInsn(getLoadOpcode(cl), off);
off += getParameterSize(cl);
desc = getSBAppendDesc(cl);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
mv.visitMethodInsn(
INVOKEVIRTUAL,
"java/lang/StringBuilder",
@ -1271,7 +1262,6 @@ public final class StringConcatFactory {
}
}
List<Class<?>> ptypesList = Arrays.asList(ptypes);
MethodHandle[] lengthers = new MethodHandle[pc];
// Figure out lengths: constants' lengths can be deduced on the spot.
@ -1280,14 +1270,13 @@ public final class StringConcatFactory {
int initial = 0;
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object cnst = el.getValue();
initial += cnst.toString().length();
break;
}
case ARG: {
case TAG_ARG:
final int i = el.getArgPos();
Class<?> type = ptypesList.get(i);
Class<?> type = ptypes[i];
if (type.isPrimitive()) {
MethodHandle est = MethodHandles.constant(int.class, estimateSize(type));
est = MethodHandles.dropArguments(est, 0, type);
@ -1296,14 +1285,13 @@ public final class StringConcatFactory {
lengthers[i] = STRING_LENGTH;
}
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
}
// 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
// reverse as well.
@ -1312,23 +1300,21 @@ public final class StringConcatFactory {
RecipeElement el = elements.get(i);
MethodHandle appender;
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object constant = el.getValue();
MethodHandle mh = appender(adaptToStringBuilder(constant.getClass()));
appender = MethodHandles.insertArguments(mh, 1, constant);
break;
}
case ARG: {
case TAG_ARG:
int ac = el.getArgPos();
appender = appender(ptypesList.get(ac));
appender = appender(ptypes[ac]);
// Insert dummy arguments to match the prefix in the signature.
// The actual appender argument will be the ac-ith argument.
if (ac != 0) {
appender = MethodHandles.dropArguments(appender, 1, ptypesList.subList(0, ac));
appender = MethodHandles.dropArguments(appender, 1, Arrays.copyOf(ptypes, ac));
}
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
@ -1500,7 +1486,6 @@ public final class StringConcatFactory {
ptypes[i] = filter.type().returnType();
}
}
List<Class<?>> ptypesList = Arrays.asList(ptypes);
// 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,
@ -1522,16 +1507,14 @@ public final class StringConcatFactory {
for (RecipeElement el : recipe.getElements()) {
MethodHandle prepender;
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object cnst = el.getValue();
prepender = MethodHandles.insertArguments(prepender(cnst.getClass()), 3, cnst);
break;
}
case ARG: {
case TAG_ARG:
int pos = el.getArgPos();
prepender = selectArgument(prepender(ptypesList.get(pos)), 3, ptypesList, pos);
prepender = selectArgument(prepender(ptypes[pos]), 3, ptypes, pos);
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
@ -1554,7 +1537,7 @@ public final class StringConcatFactory {
}
// 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);
// Start combining length and coder mixers.
@ -1574,22 +1557,21 @@ public final class StringConcatFactory {
int initialLen = 0; // initial length, in characters
for (RecipeElement el : recipe.getElements()) {
switch (el.getTag()) {
case CONST: {
case TAG_CONST:
Object constant = el.getValue();
String s = constant.toString();
initialCoder = (byte) coderMixer(String.class).invoke(initialCoder, s);
initialLen += s.length();
break;
}
case ARG: {
case TAG_ARG:
int ac = el.getArgPos();
Class<?> argClass = ptypesList.get(ac);
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypesList, ac);
Class<?> argClass = ptypes[ac];
MethodHandle lm = selectArgument(lengthMixer(argClass), 1, ptypes, ac);
lm = MethodHandles.dropArguments(lm, 0, 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); // (**)
// Read this bottom up:
@ -1607,7 +1589,6 @@ public final class StringConcatFactory {
// 1. The mh shape here is ("old-index", "old-coder", <args>)
break;
}
default:
throw new StringConcatException("Unhandled tag: " + el.getTag());
}
@ -1636,14 +1617,14 @@ public final class StringConcatFactory {
}
// 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) {
return MethodHandles.dropArguments(mh, prefix + 1, ptypes.subList(1, ptypes.size()));
} else if (pos == ptypes.size() - 1) {
return MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, ptypes.size() - 1));
return MethodHandles.dropArguments(mh, prefix + 1, Arrays.copyOfRange(ptypes, 1, ptypes.length));
} else if (pos == ptypes.length - 1) {
return MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, ptypes.length - 1));
} else { // 0 < pos < ptypes.size() - 1
MethodHandle t = MethodHandles.dropArguments(mh, prefix, ptypes.subList(0, pos));
return MethodHandles.dropArguments(t, prefix + 1 + pos, ptypes.subList(pos + 1, ptypes.size()));
MethodHandle t = MethodHandles.dropArguments(mh, prefix, Arrays.copyOf(ptypes, pos));
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> LENGTH_MIXERS;
private static final ConcurrentMap<Class<?>, MethodHandle> CODER_MIXERS;
private static final Class<?> STRING_HELPER;
private static final byte INITIAL_CODER;
static final Class<?> STRING_HELPER;
static {
try {
@ -1805,7 +1786,7 @@ public final class StringConcatFactory {
/* ------------------------------- 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 {
return lookup.findStatic(refc, name, MethodType.methodType(rtype, ptypes));
} 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 {
return lookup.findVirtual(refc, name, MethodType.methodType(rtype, ptypes));
} 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 {
return lookup.findConstructor(refc, MethodType.methodType(void.class, ptypes));
} 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) {
return 11; // "-2147483648"
} 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 == Byte.TYPE || c == Short.TYPE) {
return int.class;

View File

@ -38,7 +38,7 @@ class TypeConvertingMethodAdapter extends MethodVisitor {
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 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.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@ -54,7 +53,8 @@ final class VarForm {
List<Class<?>> l = new ArrayList<>();
if (receiver != null)
l.add(receiver);
l.addAll(Arrays.asList(intermediate));
for (Class<?> c : intermediate)
l.add(c);
// (Receiver, <Intermediates>)Value
methodType_table[VarHandle.AccessType.GET.ordinal()] =

View File

@ -1057,57 +1057,11 @@ public abstract class VarHandle {
Object addAndGet(Object... args);
enum AccessType {
GET(Object.class) {
@Override
MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate) {
Class<?>[] ps = allocateParameters(0, receiver, intermediate);
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);
}
};
GET(Object.class),
SET(void.class),
COMPARE_AND_SWAP(boolean.class),
COMPARE_AND_EXCHANGE(Object.class),
GET_AND_UPDATE(Object.class);
final Class<?> returnType;
final boolean isMonomorphicInReturnType;
@ -1117,8 +1071,41 @@ public abstract class VarHandle {
isMonomorphicInReturnType = returnType != Object.class;
}
abstract MethodType accessModeType(Class<?> receiver, Class<?> value,
Class<?>... intermediate);
MethodType accessModeType(Class<?> receiver, Class<?> value,
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,
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() {
return patched;

View File

@ -68,7 +68,7 @@ class ModuleReferences {
/**
* 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,
URI uri,

View File

@ -178,7 +178,7 @@ class SystemModuleFinder implements ModuleFinder {
ModuleReference mref =
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);
return mref;

View File

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

View File

@ -263,6 +263,47 @@ public class StampedLock implements java.io.Serializable {
* is theoretically possible, so we additionally add a
* 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
* (normally on the same cache line). This usually works well for
* 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 */
private static final int NCPU = Runtime.getRuntime().availableProcessors();
/** Maximum number of retries before enqueuing on acquisition */
private static final int SPINS = (NCPU > 1) ? 1 << 6 : 0;
/** Maximum number of retries before enqueuing on acquisition; at least 1 */
private static final int SPINS = (NCPU > 1) ? 1 << 6 : 1;
/** Maximum number of retries before blocking at head on acquisition */
private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 0;
/** Maximum number of tries before blocking at head on acquisition */
private static final int HEAD_SPINS = (NCPU > 1) ? 1 << 10 : 1;
/** 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 */
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) &&
(w = c.thread) != null) // help release
LockSupport.unpark(w);
if (Thread.interrupted()) {
if (interruptible)
return cancelWaiter(node, p, true);
wasInterrupted = true;
}
if (h == (pp = p.prev) || h == p || pp == null) {
long m, s, ns;
do {
@ -1264,11 +1310,6 @@ public class StampedLock implements java.io.Serializable {
LockSupport.parkNanos(this, time);
}
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;
import java.lang.invoke.MethodType;
import java.util.Map;
public interface JavaLangInvokeAccess {
/**
* Create a new MemberName instance
* Create a new MemberName instance. Used by {@see StackFrameInfo}.
*/
Object newMemberName();
/**
* Returns the name for the given MemberName
* Returns the name for the given MemberName. Used by {@see StackFrameInfo}.
*/
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);
/**
* 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