Merge
This commit is contained in:
commit
a8c5f1e59a
@ -527,8 +527,8 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fcheck-new"
|
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fcheck-new -fstack-protector"
|
||||||
TOOLCHAIN_CFLAGS_JDK="-pipe"
|
TOOLCHAIN_CFLAGS_JDK="-pipe -fstack-protector"
|
||||||
TOOLCHAIN_CFLAGS_JDK_CONLY="-fno-strict-aliasing" # technically NOT for CXX (but since this gives *worse* performance, use no-strict-aliasing everywhere!)
|
TOOLCHAIN_CFLAGS_JDK_CONLY="-fno-strict-aliasing" # technically NOT for CXX (but since this gives *worse* performance, use no-strict-aliasing everywhere!)
|
||||||
|
|
||||||
CXXSTD_CXXFLAG="-std=gnu++98"
|
CXXSTD_CXXFLAG="-std=gnu++98"
|
||||||
|
@ -56,7 +56,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBNET, \
|
|||||||
LIBS_solaris := -lnsl -lsocket $(LIBDL), \
|
LIBS_solaris := -lnsl -lsocket $(LIBDL), \
|
||||||
LIBS_aix := $(LIBDL),\
|
LIBS_aix := $(LIBDL),\
|
||||||
LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
|
LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
|
||||||
delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
|
urlmon.lib delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
|
||||||
LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
|
LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -9936,6 +9936,7 @@ instruct vmuladdadd4S2I_reg(vecD dst, vecD src1, vecD src2) %{
|
|||||||
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
|
ins_cost(10);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vmuladdadd8S4I_reg(vecX dst, vecX src1, vecX src2) %{
|
instruct vmuladdadd8S4I_reg(vecX dst, vecX src1, vecX src2) %{
|
||||||
@ -9947,6 +9948,7 @@ instruct vmuladdadd8S4I_reg(vecX dst, vecX src1, vecX src2) %{
|
|||||||
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
|
ins_cost(10);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vmuladdadd16S8I_reg(vecY dst, vecY src1, vecY src2) %{
|
instruct vmuladdadd16S8I_reg(vecY dst, vecY src1, vecY src2) %{
|
||||||
@ -9958,6 +9960,7 @@ instruct vmuladdadd16S8I_reg(vecY dst, vecY src1, vecY src2) %{
|
|||||||
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
|
ins_cost(10);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct vmuladdadd32S16I_reg(vecZ dst, vecZ src1, vecZ src2) %{
|
instruct vmuladdadd32S16I_reg(vecZ dst, vecZ src1, vecZ src2) %{
|
||||||
@ -9969,6 +9972,7 @@ instruct vmuladdadd32S16I_reg(vecZ dst, vecZ src1, vecZ src2) %{
|
|||||||
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
||||||
%}
|
%}
|
||||||
ins_pipe( pipe_slow );
|
ins_pipe( pipe_slow );
|
||||||
|
ins_cost(10);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// --------------------------------- PopCount --------------------------------------
|
// --------------------------------- PopCount --------------------------------------
|
||||||
|
@ -168,9 +168,12 @@ void ciMethodData::load_extra_data() {
|
|||||||
// in the prepare_metadata call above) as we translate the copy:
|
// in the prepare_metadata call above) as we translate the copy:
|
||||||
// update the copy as we go.
|
// update the copy as we go.
|
||||||
int tag = dp_src->tag();
|
int tag = dp_src->tag();
|
||||||
if (tag != DataLayout::arg_info_data_tag) {
|
size_t entry_size = DataLayout::header_size_in_bytes();
|
||||||
memcpy(dp_dst, dp_src, ((intptr_t)MethodData::next_extra(dp_src)) - ((intptr_t)dp_src));
|
if (tag != DataLayout::no_tag) {
|
||||||
|
ProfileData* src_data = dp_src->data_in();
|
||||||
|
entry_size = src_data->size_in_bytes();
|
||||||
}
|
}
|
||||||
|
memcpy(dp_dst, dp_src, entry_size);
|
||||||
|
|
||||||
switch(tag) {
|
switch(tag) {
|
||||||
case DataLayout::speculative_trap_data_tag: {
|
case DataLayout::speculative_trap_data_tag: {
|
||||||
|
@ -4486,33 +4486,6 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach super classes and interface classes to class loader data
|
|
||||||
static void record_defined_class_dependencies(const InstanceKlass* defined_klass,
|
|
||||||
TRAPS) {
|
|
||||||
assert(defined_klass != NULL, "invariant");
|
|
||||||
|
|
||||||
ClassLoaderData* const defining_loader_data = defined_klass->class_loader_data();
|
|
||||||
if (defining_loader_data->is_the_null_class_loader_data()) {
|
|
||||||
// Dependencies to null class loader data are implicit.
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// add super class dependency
|
|
||||||
Klass* const super = defined_klass->super();
|
|
||||||
if (super != NULL) {
|
|
||||||
defining_loader_data->record_dependency(super);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add super interface dependencies
|
|
||||||
const Array<InstanceKlass*>* const local_interfaces = defined_klass->local_interfaces();
|
|
||||||
if (local_interfaces != NULL) {
|
|
||||||
const int length = local_interfaces->length();
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
defining_loader_data->record_dependency(local_interfaces->at(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// utility methods for appending an array with check for duplicates
|
// utility methods for appending an array with check for duplicates
|
||||||
|
|
||||||
static void append_interfaces(GrowableArray<InstanceKlass*>* result,
|
static void append_interfaces(GrowableArray<InstanceKlass*>* result,
|
||||||
@ -5719,9 +5692,6 @@ void ClassFileParser::fill_instance_klass(InstanceKlass* ik, bool changed_by_loa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the loader_data graph.
|
|
||||||
record_defined_class_dependencies(ik, CHECK);
|
|
||||||
|
|
||||||
ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
|
ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
|
||||||
|
|
||||||
if (!is_internal()) {
|
if (!is_internal()) {
|
||||||
|
@ -561,11 +561,6 @@ void ClassLoaderDataGraph::clean_module_and_package_info() {
|
|||||||
|
|
||||||
ClassLoaderData* data = _head;
|
ClassLoaderData* data = _head;
|
||||||
while (data != NULL) {
|
while (data != NULL) {
|
||||||
// Remove entries in the dictionary of live class loader that have
|
|
||||||
// initiated loading classes in a dead class loader.
|
|
||||||
if (data->dictionary() != NULL) {
|
|
||||||
data->dictionary()->do_unloading();
|
|
||||||
}
|
|
||||||
// Walk a ModuleEntry's reads, and a PackageEntry's exports
|
// Walk a ModuleEntry's reads, and a PackageEntry's exports
|
||||||
// lists to determine if there are modules on those lists that are now
|
// lists to determine if there are modules on those lists that are now
|
||||||
// dead and should be removed. A module's life cycle is equivalent
|
// dead and should be removed. A module's life cycle is equivalent
|
||||||
|
@ -233,40 +233,6 @@ void Dictionary::clean_cached_protection_domains(DictionaryEntry* probe) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Dictionary::do_unloading() {
|
|
||||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
|
||||||
|
|
||||||
// The NULL class loader doesn't initiate loading classes from other class loaders
|
|
||||||
if (loader_data() == ClassLoaderData::the_null_class_loader_data()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove unloaded entries and classes from this dictionary
|
|
||||||
DictionaryEntry* probe = NULL;
|
|
||||||
for (int index = 0; index < table_size(); index++) {
|
|
||||||
for (DictionaryEntry** p = bucket_addr(index); *p != NULL; ) {
|
|
||||||
probe = *p;
|
|
||||||
InstanceKlass* ik = probe->instance_klass();
|
|
||||||
ClassLoaderData* k_def_class_loader_data = ik->class_loader_data();
|
|
||||||
|
|
||||||
// If the klass that this loader initiated is dead,
|
|
||||||
// (determined by checking the defining class loader)
|
|
||||||
// remove this entry.
|
|
||||||
if (k_def_class_loader_data->is_unloading()) {
|
|
||||||
assert(k_def_class_loader_data != loader_data(),
|
|
||||||
"cannot have live defining loader and unreachable klass");
|
|
||||||
*p = probe->next();
|
|
||||||
free_entry(probe);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Clean pd_set
|
|
||||||
clean_cached_protection_domains(probe);
|
|
||||||
p = probe->next_addr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just the classes from defining class loaders
|
// Just the classes from defining class loaders
|
||||||
void Dictionary::classes_do(void f(InstanceKlass*)) {
|
void Dictionary::classes_do(void f(InstanceKlass*)) {
|
||||||
for (int index = 0; index < table_size(); index++) {
|
for (int index = 0; index < table_size(); index++) {
|
||||||
|
@ -74,9 +74,6 @@ public:
|
|||||||
|
|
||||||
void unlink();
|
void unlink();
|
||||||
|
|
||||||
// Unload classes whose defining loaders are unloaded
|
|
||||||
void do_unloading();
|
|
||||||
|
|
||||||
// Protection domains
|
// Protection domains
|
||||||
InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
|
InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
|
||||||
bool is_valid_protection_domain(unsigned int hash,
|
bool is_valid_protection_domain(unsigned int hash,
|
||||||
|
@ -860,8 +860,15 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
|
|||||||
check_constraints(d_hash, k, class_loader, false, THREAD);
|
check_constraints(d_hash, k, class_loader, false, THREAD);
|
||||||
|
|
||||||
// Need to check for a PENDING_EXCEPTION again; check_constraints
|
// Need to check for a PENDING_EXCEPTION again; check_constraints
|
||||||
// can throw and doesn't use the CHECK macro.
|
// can throw but we may have to remove entry from the placeholder table below.
|
||||||
if (!HAS_PENDING_EXCEPTION) {
|
if (!HAS_PENDING_EXCEPTION) {
|
||||||
|
// Record dependency for non-parent delegation.
|
||||||
|
// This recording keeps the defining class loader of the klass (k) found
|
||||||
|
// from being unloaded while the initiating class loader is loaded
|
||||||
|
// even if the reference to the defining class loader is dropped
|
||||||
|
// before references to the initiating class loader.
|
||||||
|
loader_data->record_dependency(k);
|
||||||
|
|
||||||
{ // Grabbing the Compile_lock prevents systemDictionary updates
|
{ // Grabbing the Compile_lock prevents systemDictionary updates
|
||||||
// during compilations.
|
// during compilations.
|
||||||
MutexLocker mu(Compile_lock, THREAD);
|
MutexLocker mu(Compile_lock, THREAD);
|
||||||
@ -2179,6 +2186,7 @@ void SystemDictionary::update_dictionary(unsigned int d_hash,
|
|||||||
InstanceKlass* sd_check = find_class(d_hash, name, dictionary);
|
InstanceKlass* sd_check = find_class(d_hash, name, dictionary);
|
||||||
if (sd_check == NULL) {
|
if (sd_check == NULL) {
|
||||||
dictionary->add_klass(d_hash, name, k);
|
dictionary->add_klass(d_hash, name, k);
|
||||||
|
|
||||||
notice_modification();
|
notice_modification();
|
||||||
}
|
}
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -50,7 +50,6 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym
|
|||||||
Klass* this_class = SystemDictionary::resolve_or_fail(
|
Klass* this_class = SystemDictionary::resolve_or_fail(
|
||||||
name, Handle(THREAD, klass->class_loader()),
|
name, Handle(THREAD, klass->class_loader()),
|
||||||
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
||||||
klass->class_loader_data()->record_dependency(this_class);
|
|
||||||
if (log_is_enabled(Debug, class, resolve)) {
|
if (log_is_enabled(Debug, class, resolve)) {
|
||||||
Verifier::trace_class_resolution(this_class, klass);
|
Verifier::trace_class_resolution(this_class, klass);
|
||||||
}
|
}
|
||||||
@ -68,7 +67,6 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym
|
|||||||
Klass* from_class = SystemDictionary::resolve_or_fail(
|
Klass* from_class = SystemDictionary::resolve_or_fail(
|
||||||
from_name, Handle(THREAD, klass->class_loader()),
|
from_name, Handle(THREAD, klass->class_loader()),
|
||||||
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
||||||
klass->class_loader_data()->record_dependency(from_class);
|
|
||||||
if (log_is_enabled(Debug, class, resolve)) {
|
if (log_is_enabled(Debug, class, resolve)) {
|
||||||
Verifier::trace_class_resolution(from_class, klass);
|
Verifier::trace_class_resolution(from_class, klass);
|
||||||
}
|
}
|
||||||
|
@ -2015,7 +2015,6 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
|
|||||||
true, THREAD);
|
true, THREAD);
|
||||||
|
|
||||||
if (kls != NULL) {
|
if (kls != NULL) {
|
||||||
current_class()->class_loader_data()->record_dependency(kls);
|
|
||||||
if (log_is_enabled(Debug, class, resolve)) {
|
if (log_is_enabled(Debug, class, resolve)) {
|
||||||
Verifier::trace_class_resolution(kls, current_class());
|
Verifier::trace_class_resolution(kls, current_class());
|
||||||
}
|
}
|
||||||
|
@ -504,10 +504,6 @@ Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int which,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make this class loader depend upon the class loader owning the class reference
|
|
||||||
ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data();
|
|
||||||
this_key->record_dependency(k);
|
|
||||||
|
|
||||||
// logging for class+resolve.
|
// logging for class+resolve.
|
||||||
if (log_is_enabled(Debug, class, resolve)){
|
if (log_is_enabled(Debug, class, resolve)){
|
||||||
trace_class_resolution(this_cp, k);
|
trace_class_resolution(this_cp, k);
|
||||||
|
@ -253,11 +253,21 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co
|
|||||||
if (byte_no == 1) {
|
if (byte_no == 1) {
|
||||||
assert(invoke_code != Bytecodes::_invokevirtual &&
|
assert(invoke_code != Bytecodes::_invokevirtual &&
|
||||||
invoke_code != Bytecodes::_invokeinterface, "");
|
invoke_code != Bytecodes::_invokeinterface, "");
|
||||||
|
bool do_resolve = true;
|
||||||
// Don't mark invokespecial to method as resolved if sender is an interface. The receiver
|
// Don't mark invokespecial to method as resolved if sender is an interface. The receiver
|
||||||
// has to be checked that it is a subclass of the current class every time this bytecode
|
// has to be checked that it is a subclass of the current class every time this bytecode
|
||||||
// is executed.
|
// is executed.
|
||||||
if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface ||
|
if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
|
||||||
method->name() == vmSymbols::object_initializer_name()) {
|
method->name() != vmSymbols::object_initializer_name()) {
|
||||||
|
do_resolve = false;
|
||||||
|
}
|
||||||
|
// Don't mark invokestatic to method as resolved if the holder class has not yet completed
|
||||||
|
// initialization. An invokestatic must only proceed if the class is initialized, but if
|
||||||
|
// we resolve it before then that class initialization check is skipped.
|
||||||
|
if (invoke_code == Bytecodes::_invokestatic && !method->method_holder()->is_initialized()) {
|
||||||
|
do_resolve = false;
|
||||||
|
}
|
||||||
|
if (do_resolve) {
|
||||||
set_bytecode_1(invoke_code);
|
set_bytecode_1(invoke_code);
|
||||||
}
|
}
|
||||||
} else if (byte_no == 2) {
|
} else if (byte_no == 2) {
|
||||||
|
@ -1308,7 +1308,7 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree *loop, ProjNode*
|
|||||||
// range checks between the pre and main loop to validate the value
|
// range checks between the pre and main loop to validate the value
|
||||||
// of the main loop induction variable. Make a copy of the predicates
|
// of the main loop induction variable. Make a copy of the predicates
|
||||||
// here with an opaque node as a place holder for the value (will be
|
// here with an opaque node as a place holder for the value (will be
|
||||||
// updated by PhaseIdealLoop::update_skeleton_predicate()).
|
// updated by PhaseIdealLoop::clone_skeleton_predicate()).
|
||||||
ProjNode* PhaseIdealLoop::insert_skeleton_predicate(IfNode* iff, IdealLoopTree *loop,
|
ProjNode* PhaseIdealLoop::insert_skeleton_predicate(IfNode* iff, IdealLoopTree *loop,
|
||||||
ProjNode* proj, ProjNode *predicate_proj,
|
ProjNode* proj, ProjNode *predicate_proj,
|
||||||
ProjNode* upper_bound_proj,
|
ProjNode* upper_bound_proj,
|
||||||
|
@ -1067,8 +1067,9 @@ Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop)
|
|||||||
// CastII/ConvI2L nodes cause some data paths to die. For consistency,
|
// CastII/ConvI2L nodes cause some data paths to die. For consistency,
|
||||||
// the control paths must die too but the range checks were removed by
|
// the control paths must die too but the range checks were removed by
|
||||||
// predication. The range checks that we add here guarantee that they do.
|
// predication. The range checks that we add here guarantee that they do.
|
||||||
void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* castii, IdealLoopTree* outer_loop,
|
void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* start, Node* end,
|
||||||
LoopNode* outer_main_head, uint dd_main_head) {
|
IdealLoopTree* outer_loop, LoopNode* outer_main_head,
|
||||||
|
uint dd_main_head) {
|
||||||
if (predicate != NULL) {
|
if (predicate != NULL) {
|
||||||
IfNode* iff = predicate->in(0)->as_If();
|
IfNode* iff = predicate->in(0)->as_If();
|
||||||
ProjNode* uncommon_proj = iff->proj_out(1 - predicate->as_Proj()->_con);
|
ProjNode* uncommon_proj = iff->proj_out(1 - predicate->as_Proj()->_con);
|
||||||
@ -1084,13 +1085,14 @@ void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* castii,
|
|||||||
if (uncommon_proj->unique_ctrl_out() != rgn)
|
if (uncommon_proj->unique_ctrl_out() != rgn)
|
||||||
break;
|
break;
|
||||||
if (iff->in(1)->Opcode() == Op_Opaque4) {
|
if (iff->in(1)->Opcode() == Op_Opaque4) {
|
||||||
|
assert(skeleton_predicate_has_opaque(iff), "unexpected");
|
||||||
// Clone the predicate twice and initialize one with the initial
|
// Clone the predicate twice and initialize one with the initial
|
||||||
// value of the loop induction variable. Leave the other predicate
|
// value of the loop induction variable. Leave the other predicate
|
||||||
// to be initialized when increasing the stride during loop unrolling.
|
// to be initialized when increasing the stride during loop unrolling.
|
||||||
prev_proj = update_skeleton_predicate(iff, castii, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
|
prev_proj = clone_skeleton_predicate(iff, start, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
|
||||||
Node* value = new Opaque1Node(C, castii);
|
assert(skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()) == (start->Opcode() == Op_Opaque1), "");
|
||||||
register_new_node(value, current_proj);
|
prev_proj = clone_skeleton_predicate(iff, end, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
|
||||||
prev_proj = update_skeleton_predicate(iff, value, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
|
assert(skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()) == (end->Opcode() == Op_Opaque1), "");
|
||||||
// Remove the skeleton predicate from the pre-loop
|
// Remove the skeleton predicate from the pre-loop
|
||||||
_igvn.replace_input_of(iff, 1, _igvn.intcon(1));
|
_igvn.replace_input_of(iff, 1, _igvn.intcon(1));
|
||||||
}
|
}
|
||||||
@ -1101,9 +1103,47 @@ void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* castii,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* predicate, Node* uncommon_proj,
|
static bool skeleton_follow_inputs(Node* n, int op) {
|
||||||
Node* current_proj, IdealLoopTree* outer_loop, Node* prev_proj) {
|
return (n->is_Bool() ||
|
||||||
bool clone = (outer_loop != NULL); // Clone the predicate?
|
n->is_Cmp() ||
|
||||||
|
op == Op_AndL ||
|
||||||
|
op == Op_OrL ||
|
||||||
|
op == Op_RShiftL ||
|
||||||
|
op == Op_LShiftL ||
|
||||||
|
op == Op_AddL ||
|
||||||
|
op == Op_AddI ||
|
||||||
|
op == Op_MulL ||
|
||||||
|
op == Op_MulI ||
|
||||||
|
op == Op_SubL ||
|
||||||
|
op == Op_SubI ||
|
||||||
|
op == Op_ConvI2L);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhaseIdealLoop::skeleton_predicate_has_opaque(IfNode* iff) {
|
||||||
|
ResourceMark rm;
|
||||||
|
Unique_Node_List wq;
|
||||||
|
wq.push(iff->in(1)->in(1));
|
||||||
|
for (uint i = 0; i < wq.size(); i++) {
|
||||||
|
Node* n = wq.at(i);
|
||||||
|
int op = n->Opcode();
|
||||||
|
if (skeleton_follow_inputs(n, op)) {
|
||||||
|
for (uint j = 1; j < n->req(); j++) {
|
||||||
|
Node* m = n->in(j);
|
||||||
|
if (m != NULL) {
|
||||||
|
wq.push(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (op == Op_Opaque1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* PhaseIdealLoop::clone_skeleton_predicate(Node* iff, Node* value, Node* predicate, Node* uncommon_proj,
|
||||||
|
Node* current_proj, IdealLoopTree* outer_loop, Node* prev_proj) {
|
||||||
Node_Stack to_clone(2);
|
Node_Stack to_clone(2);
|
||||||
to_clone.push(iff->in(1), 1);
|
to_clone.push(iff->in(1), 1);
|
||||||
uint current = C->unique();
|
uint current = C->unique();
|
||||||
@ -1118,28 +1158,11 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
|||||||
uint i = to_clone.index();
|
uint i = to_clone.index();
|
||||||
Node* m = n->in(i);
|
Node* m = n->in(i);
|
||||||
int op = m->Opcode();
|
int op = m->Opcode();
|
||||||
if (m->is_Bool() ||
|
if (skeleton_follow_inputs(m, op)) {
|
||||||
m->is_Cmp() ||
|
|
||||||
op == Op_AndL ||
|
|
||||||
op == Op_OrL ||
|
|
||||||
op == Op_RShiftL ||
|
|
||||||
op == Op_LShiftL ||
|
|
||||||
op == Op_AddL ||
|
|
||||||
op == Op_AddI ||
|
|
||||||
op == Op_MulL ||
|
|
||||||
op == Op_MulI ||
|
|
||||||
op == Op_SubL ||
|
|
||||||
op == Op_SubI ||
|
|
||||||
op == Op_ConvI2L) {
|
|
||||||
to_clone.push(m, 1);
|
to_clone.push(m, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (op == Op_Opaque1) {
|
if (op == Op_Opaque1) {
|
||||||
if (!clone) {
|
|
||||||
// Update the input of the Opaque1Node and exit
|
|
||||||
_igvn.replace_input_of(m, 1, value);
|
|
||||||
return prev_proj;
|
|
||||||
}
|
|
||||||
if (n->_idx < current) {
|
if (n->_idx < current) {
|
||||||
n = n->clone();
|
n = n->clone();
|
||||||
}
|
}
|
||||||
@ -1161,20 +1184,17 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
|||||||
}
|
}
|
||||||
Node* next = to_clone.node();
|
Node* next = to_clone.node();
|
||||||
j = to_clone.index();
|
j = to_clone.index();
|
||||||
if (clone && cur->_idx >= current) {
|
if (next->in(j) != cur) {
|
||||||
|
assert(cur->_idx >= current || next->in(j)->Opcode() == Op_Opaque1, "new node or Opaque1 being replaced");
|
||||||
if (next->_idx < current) {
|
if (next->_idx < current) {
|
||||||
next = next->clone();
|
next = next->clone();
|
||||||
register_new_node(next, current_proj);
|
register_new_node(next, current_proj);
|
||||||
to_clone.set_node(next);
|
to_clone.set_node(next);
|
||||||
}
|
}
|
||||||
assert(next->in(j) != cur, "input should have been cloned");
|
|
||||||
next->set_req(j, cur);
|
next->set_req(j, cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (result == NULL);
|
} while (result == NULL);
|
||||||
if (!clone) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
assert(result->_idx >= current, "new node expected");
|
assert(result->_idx >= current, "new node expected");
|
||||||
|
|
||||||
Node* proj = predicate->clone();
|
Node* proj = predicate->clone();
|
||||||
@ -1197,8 +1217,9 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
|||||||
return proj;
|
return proj;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* castii, IdealLoopTree* outer_loop,
|
void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* start, Node* end,
|
||||||
LoopNode* outer_main_head, uint dd_main_head) {
|
IdealLoopTree* outer_loop, LoopNode* outer_main_head,
|
||||||
|
uint dd_main_head) {
|
||||||
if (UseLoopPredicate) {
|
if (UseLoopPredicate) {
|
||||||
Node* entry = pre_head->in(LoopNode::EntryControl);
|
Node* entry = pre_head->in(LoopNode::EntryControl);
|
||||||
Node* predicate = NULL;
|
Node* predicate = NULL;
|
||||||
@ -1214,8 +1235,8 @@ void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* casti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
duplicate_predicates_helper(predicate, castii, outer_loop, outer_main_head, dd_main_head);
|
duplicate_predicates_helper(predicate, start, end, outer_loop, outer_main_head, dd_main_head);
|
||||||
duplicate_predicates_helper(profile_predicate, castii, outer_loop, outer_main_head, dd_main_head);
|
duplicate_predicates_helper(profile_predicate, start, end, outer_loop, outer_main_head, dd_main_head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1362,7 +1383,9 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
|
|||||||
// CastII for the main loop:
|
// CastII for the main loop:
|
||||||
Node* castii = cast_incr_before_loop( pre_incr, min_taken, main_head );
|
Node* castii = cast_incr_before_loop( pre_incr, min_taken, main_head );
|
||||||
assert(castii != NULL, "no castII inserted");
|
assert(castii != NULL, "no castII inserted");
|
||||||
duplicate_predicates(pre_head, castii, outer_loop, outer_main_head, dd_main_head);
|
Node* opaque_castii = new Opaque1Node(C, castii);
|
||||||
|
register_new_node(opaque_castii, outer_main_head->in(LoopNode::EntryControl));
|
||||||
|
duplicate_predicates(pre_head, castii, opaque_castii, outer_loop, outer_main_head, dd_main_head);
|
||||||
|
|
||||||
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
|
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
|
||||||
// RCE and alignment may change this later.
|
// RCE and alignment may change this later.
|
||||||
@ -1641,6 +1664,49 @@ bool IdealLoopTree::is_invariant(Node* n) const {
|
|||||||
return !is_member(_phase->get_loop(n_c));
|
return !is_member(_phase->get_loop(n_c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhaseIdealLoop::update_skeleton_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con) {
|
||||||
|
// Search for skeleton predicates and update them according to the new stride
|
||||||
|
Node* entry = ctrl;
|
||||||
|
Node* prev_proj = ctrl;
|
||||||
|
LoopNode* outer_loop_head = loop_head->skip_strip_mined();
|
||||||
|
IdealLoopTree* outer_loop = get_loop(outer_loop_head);
|
||||||
|
while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
|
||||||
|
IfNode* iff = entry->in(0)->as_If();
|
||||||
|
ProjNode* proj = iff->proj_out(1 - entry->as_Proj()->_con);
|
||||||
|
if (proj->unique_ctrl_out()->Opcode() != Op_Halt) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (iff->in(1)->Opcode() == Op_Opaque4) {
|
||||||
|
// Look for predicate with an Opaque1 node that can be used as a template
|
||||||
|
if (!skeleton_predicate_has_opaque(iff)) {
|
||||||
|
// No Opaque1 node? It's either the check for the first value
|
||||||
|
// of the first iteration or the check for the last value of
|
||||||
|
// the first iteration of an unrolled loop. We can't
|
||||||
|
// tell. Kill it in any case.
|
||||||
|
_igvn.replace_input_of(iff, 1, iff->in(1)->in(2));
|
||||||
|
} else {
|
||||||
|
// Add back the predicate for the value at the beginning of the first entry
|
||||||
|
prev_proj = clone_skeleton_predicate(iff, init, entry, proj, ctrl, outer_loop, prev_proj);
|
||||||
|
assert(!skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "unexpected");
|
||||||
|
// Compute the value of the loop induction variable at the end of the
|
||||||
|
// first iteration of the unrolled loop: init + new_stride_con - init_inc
|
||||||
|
int init_inc = stride_con/loop_head->unrolled_count();
|
||||||
|
assert(init_inc != 0, "invalid loop increment");
|
||||||
|
int new_stride_con = stride_con * 2;
|
||||||
|
Node* max_value = _igvn.intcon(new_stride_con - init_inc);
|
||||||
|
max_value = new AddINode(init, max_value);
|
||||||
|
register_new_node(max_value, get_ctrl(iff->in(1)));
|
||||||
|
prev_proj = clone_skeleton_predicate(iff, max_value, entry, proj, ctrl, outer_loop, prev_proj);
|
||||||
|
assert(!skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "unexpected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entry = entry->in(0)->in(0);
|
||||||
|
}
|
||||||
|
if (prev_proj != ctrl) {
|
||||||
|
_igvn.replace_input_of(outer_loop_head, LoopNode::EntryControl, prev_proj);
|
||||||
|
set_idom(outer_loop_head, prev_proj, dom_depth(outer_loop_head));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------do_unroll--------------------------------------
|
//------------------------------do_unroll--------------------------------------
|
||||||
// Unroll the loop body one step - make each trip do 2 iterations.
|
// Unroll the loop body one step - make each trip do 2 iterations.
|
||||||
@ -1706,29 +1772,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
|
|||||||
assert(old_trip_count > 1 &&
|
assert(old_trip_count > 1 &&
|
||||||
(!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity");
|
(!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity");
|
||||||
|
|
||||||
if (UseLoopPredicate) {
|
update_skeleton_predicates(ctrl, loop_head, init, stride_con);
|
||||||
// Search for skeleton predicates and update them according to the new stride
|
|
||||||
Node* entry = ctrl;
|
|
||||||
while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
|
|
||||||
IfNode* iff = entry->in(0)->as_If();
|
|
||||||
ProjNode* proj = iff->proj_out(1 - entry->as_Proj()->_con);
|
|
||||||
if (proj->unique_ctrl_out()->Opcode() != Op_Halt) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (iff->in(1)->Opcode() == Op_Opaque4) {
|
|
||||||
// Compute the value of the loop induction variable at the end of the
|
|
||||||
// first iteration of the unrolled loop: init + new_stride_con - init_inc
|
|
||||||
int init_inc = stride_con/loop_head->unrolled_count();
|
|
||||||
assert(init_inc != 0, "invalid loop increment");
|
|
||||||
int new_stride_con = stride_con * 2;
|
|
||||||
Node* max_value = _igvn.intcon(new_stride_con - init_inc);
|
|
||||||
max_value = new AddINode(init, max_value);
|
|
||||||
register_new_node(max_value, get_ctrl(iff->in(1)));
|
|
||||||
update_skeleton_predicate(iff, max_value);
|
|
||||||
}
|
|
||||||
entry = entry->in(0)->in(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust loop limit to keep valid iterations number after unroll.
|
// Adjust loop limit to keep valid iterations number after unroll.
|
||||||
// Use (limit - stride) instead of (((limit - init)/stride) & (-2))*stride
|
// Use (limit - stride) instead of (((limit - init)/stride) & (-2))*stride
|
||||||
@ -2296,9 +2340,9 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale,
|
|||||||
// eliminated by iteration splitting.
|
// eliminated by iteration splitting.
|
||||||
Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
||||||
Node* predicate_proj, int scale_con, Node* offset,
|
Node* predicate_proj, int scale_con, Node* offset,
|
||||||
Node* limit, jint stride_con) {
|
Node* limit, jint stride_con, Node* value) {
|
||||||
bool overflow = false;
|
bool overflow = false;
|
||||||
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, cl->init_trip(), NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow);
|
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow);
|
||||||
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
|
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
|
||||||
register_new_node(opaque_bol, predicate_proj);
|
register_new_node(opaque_bol, predicate_proj);
|
||||||
IfNode* new_iff = NULL;
|
IfNode* new_iff = NULL;
|
||||||
@ -2497,7 +2541,23 @@ int PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
|||||||
add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
|
add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
|
||||||
// (0-offset)/scale could be outside of loop iterations range.
|
// (0-offset)/scale could be outside of loop iterations range.
|
||||||
conditional_rc = true;
|
conditional_rc = true;
|
||||||
predicate_proj = add_range_check_predicate(loop, cl, predicate_proj, scale_con, offset, limit, stride_con);
|
Node* init = cl->init_trip();
|
||||||
|
Node* opaque_init = new Opaque1Node(C, init);
|
||||||
|
register_new_node(opaque_init, predicate_proj);
|
||||||
|
// template predicate so it can be updated on next unrolling
|
||||||
|
predicate_proj = add_range_check_predicate(loop, cl, predicate_proj, scale_con, offset, limit, stride_con, opaque_init);
|
||||||
|
assert(skeleton_predicate_has_opaque(predicate_proj->in(0)->as_If()), "unexpected");
|
||||||
|
// predicate on first value of first iteration
|
||||||
|
predicate_proj = add_range_check_predicate(loop, cl, predicate_proj, scale_con, offset, limit, stride_con, init);
|
||||||
|
assert(!skeleton_predicate_has_opaque(predicate_proj->in(0)->as_If()), "unexpected");
|
||||||
|
int init_inc = stride_con/cl->unrolled_count();
|
||||||
|
assert(init_inc != 0, "invalid loop increment");
|
||||||
|
Node* max_value = _igvn.intcon(stride_con - init_inc);
|
||||||
|
max_value = new AddINode(init, max_value);
|
||||||
|
register_new_node(max_value, predicate_proj);
|
||||||
|
// predicate on last value of first iteration (in case unrolling has already happened)
|
||||||
|
predicate_proj = add_range_check_predicate(loop, cl, predicate_proj, scale_con, offset, limit, stride_con, max_value);
|
||||||
|
assert(!skeleton_predicate_has_opaque(predicate_proj->in(0)->as_If()), "unexpected");
|
||||||
} else {
|
} else {
|
||||||
if (PrintOpto) {
|
if (PrintOpto) {
|
||||||
tty->print_cr("missed RCE opportunity");
|
tty->print_cr("missed RCE opportunity");
|
||||||
|
@ -747,12 +747,14 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node* cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
|
Node* cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop);
|
||||||
void duplicate_predicates_helper(Node* predicate, Node* castii, IdealLoopTree* outer_loop,
|
void duplicate_predicates_helper(Node* predicate, Node* start, Node* end, IdealLoopTree* outer_loop,
|
||||||
LoopNode* outer_main_head, uint dd_main_head);
|
LoopNode* outer_main_head, uint dd_main_head);
|
||||||
void duplicate_predicates(CountedLoopNode* pre_head, Node* castii, IdealLoopTree* outer_loop,
|
void duplicate_predicates(CountedLoopNode* pre_head, Node* start, Node* end, IdealLoopTree* outer_loop,
|
||||||
LoopNode* outer_main_head, uint dd_main_head);
|
LoopNode* outer_main_head, uint dd_main_head);
|
||||||
Node* update_skeleton_predicate(Node* iff, Node* value, Node* predicate = NULL, Node* uncommon_proj = NULL,
|
Node* clone_skeleton_predicate(Node* iff, Node* value, Node* predicate, Node* uncommon_proj,
|
||||||
Node* current_proj = NULL, IdealLoopTree* outer_loop = NULL, Node* prev_proj = NULL);
|
Node* current_proj, IdealLoopTree* outer_loop, Node* prev_proj);
|
||||||
|
bool skeleton_predicate_has_opaque(IfNode* iff);
|
||||||
|
void update_skeleton_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con);
|
||||||
void insert_loop_limit_check(ProjNode* limit_check_proj, Node* cmp_limit, Node* bol);
|
void insert_loop_limit_check(ProjNode* limit_check_proj, Node* cmp_limit, Node* bol);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1128,7 +1130,7 @@ public:
|
|||||||
Deoptimization::DeoptReason reason);
|
Deoptimization::DeoptReason reason);
|
||||||
Node* add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
Node* add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
||||||
Node* predicate_proj, int scale_con, Node* offset,
|
Node* predicate_proj, int scale_con, Node* offset,
|
||||||
Node* limit, jint stride_con);
|
Node* limit, jint stride_con, Node* value);
|
||||||
|
|
||||||
// Helper function to collect predicate for eliminating the useless ones
|
// Helper function to collect predicate for eliminating the useless ones
|
||||||
void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
|
void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
|
||||||
@ -1304,6 +1306,14 @@ private:
|
|||||||
bool identical_backtoback_ifs(Node *n);
|
bool identical_backtoback_ifs(Node *n);
|
||||||
bool can_split_if(Node *n_ctrl);
|
bool can_split_if(Node *n_ctrl);
|
||||||
|
|
||||||
|
// Determine if a method is too big for a/another round of split-if, based on
|
||||||
|
// a magic (approximate) ratio derived from the equally magic constant 35000,
|
||||||
|
// previously used for this purpose (but without relating to the node limit).
|
||||||
|
bool must_throttle_split_if() {
|
||||||
|
uint threshold = C->max_node_limit() * 2 / 5;
|
||||||
|
return C->live_nodes() > threshold;
|
||||||
|
}
|
||||||
|
|
||||||
bool _created_loop_node;
|
bool _created_loop_node;
|
||||||
public:
|
public:
|
||||||
void set_created_loop_node() { _created_loop_node = true; }
|
void set_created_loop_node() { _created_loop_node = true; }
|
||||||
|
@ -532,6 +532,12 @@ Node *PhaseIdealLoop::convert_add_to_muladd(Node* n) {
|
|||||||
register_new_node(nn, get_ctrl(n));
|
register_new_node(nn, get_ctrl(n));
|
||||||
_igvn.replace_node(n, nn);
|
_igvn.replace_node(n, nn);
|
||||||
return nn;
|
return nn;
|
||||||
|
} else if ((adr1->in(AddPNode::Base) == adr4->in(AddPNode::Base)) &&
|
||||||
|
(adr2->in(AddPNode::Base) == adr3->in(AddPNode::Base))) {
|
||||||
|
nn = new MulAddS2INode(mul_in1, mul_in2, mul_in4, mul_in3);
|
||||||
|
register_new_node(nn, get_ctrl(n));
|
||||||
|
_igvn.replace_node(n, nn);
|
||||||
|
return nn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1024,8 +1030,7 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use same limit as split_if_with_blocks_post
|
if (must_throttle_split_if()) return n;
|
||||||
if( C->live_nodes() > 35000 ) return n; // Method too big
|
|
||||||
|
|
||||||
// Split 'n' through the merge point if it is profitable
|
// Split 'n' through the merge point if it is profitable
|
||||||
Node *phi = split_thru_phi( n, n_blk, policy );
|
Node *phi = split_thru_phi( n, n_blk, policy );
|
||||||
@ -1143,9 +1148,10 @@ bool PhaseIdealLoop::identical_backtoback_ifs(Node *n) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhaseIdealLoop::can_split_if(Node *n_ctrl) {
|
|
||||||
if (C->live_nodes() > 35000) {
|
bool PhaseIdealLoop::can_split_if(Node* n_ctrl) {
|
||||||
return false; // Method too big
|
if (must_throttle_split_if()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not do 'split-if' if irreducible loops are present.
|
// Do not do 'split-if' if irreducible loops are present.
|
||||||
@ -1462,12 +1468,13 @@ void PhaseIdealLoop::split_if_with_blocks_post(Node *n, bool last_round) {
|
|||||||
// Check for aggressive application of 'split-if' optimization,
|
// Check for aggressive application of 'split-if' optimization,
|
||||||
// using basic block level info.
|
// using basic block level info.
|
||||||
void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
|
void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
|
||||||
Node *n = C->root();
|
Node* root = C->root();
|
||||||
visited.set(n->_idx); // first, mark node as visited
|
visited.set(root->_idx); // first, mark root as visited
|
||||||
// Do pre-visit work for root
|
// Do pre-visit work for root
|
||||||
n = split_if_with_blocks_pre( n );
|
Node* n = split_if_with_blocks_pre(root);
|
||||||
uint cnt = n->outcnt();
|
uint cnt = n->outcnt();
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Visit all children
|
// Visit all children
|
||||||
if (i < cnt) {
|
if (i < cnt) {
|
||||||
@ -1475,7 +1482,7 @@ void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack
|
|||||||
++i;
|
++i;
|
||||||
if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
|
if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
|
||||||
// Now do pre-visit work for this use
|
// Now do pre-visit work for this use
|
||||||
use = split_if_with_blocks_pre( use );
|
use = split_if_with_blocks_pre(use);
|
||||||
nstack.push(n, i); // Save parent and next use's index.
|
nstack.push(n, i); // Save parent and next use's index.
|
||||||
n = use; // Process all children of current use.
|
n = use; // Process all children of current use.
|
||||||
cnt = use->outcnt();
|
cnt = use->outcnt();
|
||||||
@ -1486,7 +1493,10 @@ void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack
|
|||||||
// All of n's children have been processed, complete post-processing.
|
// All of n's children have been processed, complete post-processing.
|
||||||
if (cnt != 0 && !n->is_Con()) {
|
if (cnt != 0 && !n->is_Con()) {
|
||||||
assert(has_node(n), "no dead nodes");
|
assert(has_node(n), "no dead nodes");
|
||||||
split_if_with_blocks_post( n, last_round );
|
split_if_with_blocks_post(n, last_round);
|
||||||
|
}
|
||||||
|
if (must_throttle_split_if()) {
|
||||||
|
nstack.clear();
|
||||||
}
|
}
|
||||||
if (nstack.is_empty()) {
|
if (nstack.is_empty()) {
|
||||||
// Finished all nodes on stack.
|
// Finished all nodes on stack.
|
||||||
|
@ -1401,3 +1401,12 @@ const Type* FmaFNode::Value(PhaseGVN* phase) const {
|
|||||||
return TypeF::make(fma(f1, f2, f3));
|
return TypeF::make(fma(f1, f2, f3));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//------------------------------hash-------------------------------------------
|
||||||
|
// Hash function for MulAddS2INode. Operation is commutative with commutative pairs.
|
||||||
|
// The hash function must return the same value when edge swapping is performed.
|
||||||
|
uint MulAddS2INode::hash() const {
|
||||||
|
return (uintptr_t)in(1) + (uintptr_t)in(2) + (uintptr_t)in(3) + (uintptr_t)in(4) + Opcode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -289,6 +289,7 @@ public:
|
|||||||
// Multiply shorts into integers and add them.
|
// Multiply shorts into integers and add them.
|
||||||
// Semantics: I_OUT = S1 * S2 + S3 * S4
|
// Semantics: I_OUT = S1 * S2 + S3 * S4
|
||||||
class MulAddS2INode : public Node {
|
class MulAddS2INode : public Node {
|
||||||
|
virtual uint hash() const;
|
||||||
public:
|
public:
|
||||||
MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(0, in1, in2, in3, in4) {}
|
MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(0, in1, in2, in3, in4) {}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
|
@ -1445,7 +1445,7 @@ void SuperWord::order_def_uses(Node_List* p) {
|
|||||||
Node* t1 = s1->fast_out(i);
|
Node* t1 = s1->fast_out(i);
|
||||||
|
|
||||||
// Only allow operand swap on commuting operations
|
// Only allow operand swap on commuting operations
|
||||||
if (!t1->is_Add() && !t1->is_Mul()) {
|
if (!t1->is_Add() && !t1->is_Mul() && !VectorNode::is_muladds2i(t1)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1500,9 +1500,23 @@ bool SuperWord::opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2) {
|
|||||||
if ((i1 == (3-i2)) && (u2->is_Add() || u2->is_Mul())) {
|
if ((i1 == (3-i2)) && (u2->is_Add() || u2->is_Mul())) {
|
||||||
// Further analysis relies on operands position matching.
|
// Further analysis relies on operands position matching.
|
||||||
u2->swap_edges(i1, i2);
|
u2->swap_edges(i1, i2);
|
||||||
|
} else if (VectorNode::is_muladds2i(u2) && u1 != u2) {
|
||||||
|
if (i1 == 5 - i2) { // ((i1 == 3 && i2 == 2) || (i1 == 2 && i2 == 3) || (i1 == 1 && i2 == 4) || (i1 == 4 && i2 == 1))
|
||||||
|
u2->swap_edges(1, 2);
|
||||||
|
u2->swap_edges(3, 4);
|
||||||
|
}
|
||||||
|
if (i1 == 3 - i2 || i1 == 7 - i2) { // ((i1 == 1 && i2 == 2) || (i1 == 2 && i2 == 1) || (i1 == 3 && i2 == 4) || (i1 == 4 && i2 == 3))
|
||||||
|
u2->swap_edges(2, 3);
|
||||||
|
u2->swap_edges(1, 4);
|
||||||
|
}
|
||||||
|
return false; // Just swap the edges, the muladds2i nodes get packed in follow_use_defs
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (i1 == i2 && VectorNode::is_muladds2i(u2) && u1 != u2) {
|
||||||
|
u2->swap_edges(1, 3);
|
||||||
|
u2->swap_edges(2, 4);
|
||||||
|
return false; // Just swap the edges, the muladds2i nodes get packed in follow_use_defs
|
||||||
}
|
}
|
||||||
} while (i1 < ct);
|
} while (i1 < ct);
|
||||||
return true;
|
return true;
|
||||||
|
@ -873,7 +873,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
|
|||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
oop mirror = JNIHandles::resolve_non_null(result);
|
oop mirror = JNIHandles::resolve_non_null(result);
|
||||||
Klass* to_class = java_lang_Class::as_Klass(mirror);
|
Klass* to_class = java_lang_Class::as_Klass(mirror);
|
||||||
ClassLoaderData::class_loader_data(h_loader())->record_dependency(to_class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
|
||||||
|
@ -1376,6 +1376,14 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Do not patch call site for static call when the class is not
|
||||||
|
// fully initialized.
|
||||||
|
if (invoke_code == Bytecodes::_invokestatic &&
|
||||||
|
!callee_method->method_holder()->is_initialized()) {
|
||||||
|
assert(callee_method->method_holder()->is_linked(), "must be");
|
||||||
|
return callee_method;
|
||||||
|
}
|
||||||
|
|
||||||
// JSR 292 key invariant:
|
// JSR 292 key invariant:
|
||||||
// If the resolved method is a MethodHandle invoke target, the call
|
// If the resolved method is a MethodHandle invoke target, the call
|
||||||
// site must be a MethodHandle call site, because the lambda form might tail-call
|
// site must be a MethodHandle call site, because the lambda form might tail-call
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -31,6 +31,7 @@ package java.math;
|
|||||||
|
|
||||||
import static java.math.BigInteger.LONG_MASK;
|
import static java.math.BigInteger.LONG_MASK;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable, arbitrary-precision signed decimal numbers. A
|
* Immutable, arbitrary-precision signed decimal numbers. A
|
||||||
@ -424,9 +425,14 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public BigDecimal(char[] in, int offset, int len, MathContext mc) {
|
public BigDecimal(char[] in, int offset, int len, MathContext mc) {
|
||||||
// protect against huge length.
|
// protect against huge length, negative values, and integer overflow
|
||||||
if (offset + len > in.length || offset < 0)
|
try {
|
||||||
throw new NumberFormatException("Bad offset or len arguments for char[] input.");
|
Objects.checkFromIndexSize(offset, len, in.length);
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
throw new NumberFormatException
|
||||||
|
("Bad offset or len arguments for char[] input.");
|
||||||
|
}
|
||||||
|
|
||||||
// This is the primary string to BigDecimal constructor; all
|
// This is the primary string to BigDecimal constructor; all
|
||||||
// incoming strings end up here; it uses explicit (inline)
|
// incoming strings end up here; it uses explicit (inline)
|
||||||
// parsing for speed and generates at most one intermediate
|
// parsing for speed and generates at most one intermediate
|
||||||
|
@ -307,10 +307,8 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
public BigInteger(byte[] val, int off, int len) {
|
public BigInteger(byte[] val, int off, int len) {
|
||||||
if (val.length == 0) {
|
if (val.length == 0) {
|
||||||
throw new NumberFormatException("Zero length BigInteger");
|
throw new NumberFormatException("Zero length BigInteger");
|
||||||
} else if ((off < 0) || (off >= val.length) || (len < 0) ||
|
|
||||||
(len > val.length - off)) { // 0 <= off < val.length
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
}
|
||||||
|
Objects.checkFromIndexSize(off, len, val.length);
|
||||||
|
|
||||||
if (val[off] < 0) {
|
if (val[off] < 0) {
|
||||||
mag = makePositive(val, off, len);
|
mag = makePositive(val, off, len);
|
||||||
@ -395,12 +393,8 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
public BigInteger(int signum, byte[] magnitude, int off, int len) {
|
public BigInteger(int signum, byte[] magnitude, int off, int len) {
|
||||||
if (signum < -1 || signum > 1) {
|
if (signum < -1 || signum > 1) {
|
||||||
throw(new NumberFormatException("Invalid signum value"));
|
throw(new NumberFormatException("Invalid signum value"));
|
||||||
} else if ((off < 0) || (len < 0) ||
|
|
||||||
(len > 0 &&
|
|
||||||
((off >= magnitude.length) ||
|
|
||||||
(len > magnitude.length - off)))) { // 0 <= off < magnitude.length
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
}
|
||||||
|
Objects.checkFromIndexSize(off, len, magnitude.length);
|
||||||
|
|
||||||
// stripLeadingZeroBytes() returns a zero length array if len == 0
|
// stripLeadingZeroBytes() returns a zero length array if len == 0
|
||||||
this.mag = stripLeadingZeroBytes(magnitude, off, len);
|
this.mag = stripLeadingZeroBytes(magnitude, off, len);
|
||||||
@ -1239,6 +1233,14 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
private static final double LOG_TWO = Math.log(2.0);
|
private static final double LOG_TWO = Math.log(2.0);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
assert 0 < KARATSUBA_THRESHOLD
|
||||||
|
&& KARATSUBA_THRESHOLD < TOOM_COOK_THRESHOLD
|
||||||
|
&& TOOM_COOK_THRESHOLD < Integer.MAX_VALUE
|
||||||
|
&& 0 < KARATSUBA_SQUARE_THRESHOLD
|
||||||
|
&& KARATSUBA_SQUARE_THRESHOLD < TOOM_COOK_SQUARE_THRESHOLD
|
||||||
|
&& TOOM_COOK_SQUARE_THRESHOLD < Integer.MAX_VALUE :
|
||||||
|
"Algorithm thresholds are inconsistent";
|
||||||
|
|
||||||
for (int i = 1; i <= MAX_CONSTANT; i++) {
|
for (int i = 1; i <= MAX_CONSTANT; i++) {
|
||||||
int[] magnitude = new int[1];
|
int[] magnitude = new int[1];
|
||||||
magnitude[0] = i;
|
magnitude[0] = i;
|
||||||
@ -1562,6 +1564,18 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
* @return {@code this * val}
|
* @return {@code this * val}
|
||||||
*/
|
*/
|
||||||
public BigInteger multiply(BigInteger val) {
|
public BigInteger multiply(BigInteger val) {
|
||||||
|
return multiply(val, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a BigInteger whose value is {@code (this * val)}. If
|
||||||
|
* the invocation is recursive certain overflow checks are skipped.
|
||||||
|
*
|
||||||
|
* @param val value to be multiplied by this BigInteger.
|
||||||
|
* @param isRecursion whether this is a recursive invocation
|
||||||
|
* @return {@code this * val}
|
||||||
|
*/
|
||||||
|
private BigInteger multiply(BigInteger val, boolean isRecursion) {
|
||||||
if (val.signum == 0 || signum == 0)
|
if (val.signum == 0 || signum == 0)
|
||||||
return ZERO;
|
return ZERO;
|
||||||
|
|
||||||
@ -1589,6 +1603,63 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
if ((xlen < TOOM_COOK_THRESHOLD) && (ylen < TOOM_COOK_THRESHOLD)) {
|
if ((xlen < TOOM_COOK_THRESHOLD) && (ylen < TOOM_COOK_THRESHOLD)) {
|
||||||
return multiplyKaratsuba(this, val);
|
return multiplyKaratsuba(this, val);
|
||||||
} else {
|
} else {
|
||||||
|
//
|
||||||
|
// In "Hacker's Delight" section 2-13, p.33, it is explained
|
||||||
|
// that if x and y are unsigned 32-bit quantities and m and n
|
||||||
|
// are their respective numbers of leading zeros within 32 bits,
|
||||||
|
// then the number of leading zeros within their product as a
|
||||||
|
// 64-bit unsigned quantity is either m + n or m + n + 1. If
|
||||||
|
// their product is not to overflow, it cannot exceed 32 bits,
|
||||||
|
// and so the number of leading zeros of the product within 64
|
||||||
|
// bits must be at least 32, i.e., the leftmost set bit is at
|
||||||
|
// zero-relative position 31 or less.
|
||||||
|
//
|
||||||
|
// From the above there are three cases:
|
||||||
|
//
|
||||||
|
// m + n leftmost set bit condition
|
||||||
|
// ----- ---------------- ---------
|
||||||
|
// >= 32 x <= 64 - 32 = 32 no overflow
|
||||||
|
// == 31 x >= 64 - 32 = 32 possible overflow
|
||||||
|
// <= 30 x >= 64 - 31 = 33 definite overflow
|
||||||
|
//
|
||||||
|
// The "possible overflow" condition cannot be detected by
|
||||||
|
// examning data lengths alone and requires further calculation.
|
||||||
|
//
|
||||||
|
// By analogy, if 'this' and 'val' have m and n as their
|
||||||
|
// respective numbers of leading zeros within 32*MAX_MAG_LENGTH
|
||||||
|
// bits, then:
|
||||||
|
//
|
||||||
|
// m + n >= 32*MAX_MAG_LENGTH no overflow
|
||||||
|
// m + n == 32*MAX_MAG_LENGTH - 1 possible overflow
|
||||||
|
// m + n <= 32*MAX_MAG_LENGTH - 2 definite overflow
|
||||||
|
//
|
||||||
|
// Note however that if the number of ints in the result
|
||||||
|
// were to be MAX_MAG_LENGTH and mag[0] < 0, then there would
|
||||||
|
// be overflow. As a result the leftmost bit (of mag[0]) cannot
|
||||||
|
// be used and the constraints must be adjusted by one bit to:
|
||||||
|
//
|
||||||
|
// m + n > 32*MAX_MAG_LENGTH no overflow
|
||||||
|
// m + n == 32*MAX_MAG_LENGTH possible overflow
|
||||||
|
// m + n < 32*MAX_MAG_LENGTH definite overflow
|
||||||
|
//
|
||||||
|
// The foregoing leading zero-based discussion is for clarity
|
||||||
|
// only. The actual calculations use the estimated bit length
|
||||||
|
// of the product as this is more natural to the internal
|
||||||
|
// array representation of the magnitude which has no leading
|
||||||
|
// zero elements.
|
||||||
|
//
|
||||||
|
if (!isRecursion) {
|
||||||
|
// The bitLength() instance method is not used here as we
|
||||||
|
// are only considering the magnitudes as non-negative. The
|
||||||
|
// Toom-Cook multiplication algorithm determines the sign
|
||||||
|
// at its end from the two signum values.
|
||||||
|
if (bitLength(mag, mag.length) +
|
||||||
|
bitLength(val.mag, val.mag.length) >
|
||||||
|
32L*MAX_MAG_LENGTH) {
|
||||||
|
reportOverflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return multiplyToomCook3(this, val);
|
return multiplyToomCook3(this, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1674,7 +1745,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
int ystart = ylen - 1;
|
int ystart = ylen - 1;
|
||||||
|
|
||||||
if (z == null || z.length < (xlen+ ylen))
|
if (z == null || z.length < (xlen+ ylen))
|
||||||
z = new int[xlen+ylen];
|
z = new int[xlen+ylen];
|
||||||
|
|
||||||
long carry = 0;
|
long carry = 0;
|
||||||
for (int j=ystart, k=ystart+1+xstart; j >= 0; j--, k--) {
|
for (int j=ystart, k=ystart+1+xstart; j >= 0; j--, k--) {
|
||||||
@ -1808,16 +1879,16 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
|
|
||||||
BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1, db1;
|
BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1, db1;
|
||||||
|
|
||||||
v0 = a0.multiply(b0);
|
v0 = a0.multiply(b0, true);
|
||||||
da1 = a2.add(a0);
|
da1 = a2.add(a0);
|
||||||
db1 = b2.add(b0);
|
db1 = b2.add(b0);
|
||||||
vm1 = da1.subtract(a1).multiply(db1.subtract(b1));
|
vm1 = da1.subtract(a1).multiply(db1.subtract(b1), true);
|
||||||
da1 = da1.add(a1);
|
da1 = da1.add(a1);
|
||||||
db1 = db1.add(b1);
|
db1 = db1.add(b1);
|
||||||
v1 = da1.multiply(db1);
|
v1 = da1.multiply(db1, true);
|
||||||
v2 = da1.add(a2).shiftLeft(1).subtract(a0).multiply(
|
v2 = da1.add(a2).shiftLeft(1).subtract(a0).multiply(
|
||||||
db1.add(b2).shiftLeft(1).subtract(b0));
|
db1.add(b2).shiftLeft(1).subtract(b0), true);
|
||||||
vinf = a2.multiply(b2);
|
vinf = a2.multiply(b2, true);
|
||||||
|
|
||||||
// The algorithm requires two divisions by 2 and one by 3.
|
// The algorithm requires two divisions by 2 and one by 3.
|
||||||
// All divisions are known to be exact, that is, they do not produce
|
// All divisions are known to be exact, that is, they do not produce
|
||||||
@ -1983,6 +2054,17 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
* @return {@code this<sup>2</sup>}
|
* @return {@code this<sup>2</sup>}
|
||||||
*/
|
*/
|
||||||
private BigInteger square() {
|
private BigInteger square() {
|
||||||
|
return square(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a BigInteger whose value is {@code (this<sup>2</sup>)}. If
|
||||||
|
* the invocation is recursive certain overflow checks are skipped.
|
||||||
|
*
|
||||||
|
* @param isRecursion whether this is a recursive invocation
|
||||||
|
* @return {@code this<sup>2</sup>}
|
||||||
|
*/
|
||||||
|
private BigInteger square(boolean isRecursion) {
|
||||||
if (signum == 0) {
|
if (signum == 0) {
|
||||||
return ZERO;
|
return ZERO;
|
||||||
}
|
}
|
||||||
@ -1995,6 +2077,15 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
if (len < TOOM_COOK_SQUARE_THRESHOLD) {
|
if (len < TOOM_COOK_SQUARE_THRESHOLD) {
|
||||||
return squareKaratsuba();
|
return squareKaratsuba();
|
||||||
} else {
|
} else {
|
||||||
|
//
|
||||||
|
// For a discussion of overflow detection see multiply()
|
||||||
|
//
|
||||||
|
if (!isRecursion) {
|
||||||
|
if (bitLength(mag, mag.length) > 16L*MAX_MAG_LENGTH) {
|
||||||
|
reportOverflow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return squareToomCook3();
|
return squareToomCook3();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2146,13 +2237,13 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
a0 = getToomSlice(k, r, 2, len);
|
a0 = getToomSlice(k, r, 2, len);
|
||||||
BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1;
|
BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1;
|
||||||
|
|
||||||
v0 = a0.square();
|
v0 = a0.square(true);
|
||||||
da1 = a2.add(a0);
|
da1 = a2.add(a0);
|
||||||
vm1 = da1.subtract(a1).square();
|
vm1 = da1.subtract(a1).square(true);
|
||||||
da1 = da1.add(a1);
|
da1 = da1.add(a1);
|
||||||
v1 = da1.square();
|
v1 = da1.square(true);
|
||||||
vinf = a2.square();
|
vinf = a2.square(true);
|
||||||
v2 = da1.add(a2).shiftLeft(1).subtract(a0).square();
|
v2 = da1.add(a2).shiftLeft(1).subtract(a0).square(true);
|
||||||
|
|
||||||
// The algorithm requires two divisions by 2 and one by 3.
|
// The algorithm requires two divisions by 2 and one by 3.
|
||||||
// All divisions are known to be exact, that is, they do not produce
|
// All divisions are known to be exact, that is, they do not produce
|
||||||
@ -2323,10 +2414,11 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
// The remaining part can then be exponentiated faster. The
|
// The remaining part can then be exponentiated faster. The
|
||||||
// powers of two will be multiplied back at the end.
|
// powers of two will be multiplied back at the end.
|
||||||
int powersOfTwo = partToSquare.getLowestSetBit();
|
int powersOfTwo = partToSquare.getLowestSetBit();
|
||||||
long bitsToShift = (long)powersOfTwo * exponent;
|
long bitsToShiftLong = (long)powersOfTwo * exponent;
|
||||||
if (bitsToShift > Integer.MAX_VALUE) {
|
if (bitsToShiftLong > Integer.MAX_VALUE) {
|
||||||
reportOverflow();
|
reportOverflow();
|
||||||
}
|
}
|
||||||
|
int bitsToShift = (int)bitsToShiftLong;
|
||||||
|
|
||||||
int remainingBits;
|
int remainingBits;
|
||||||
|
|
||||||
@ -2336,9 +2428,9 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
remainingBits = partToSquare.bitLength();
|
remainingBits = partToSquare.bitLength();
|
||||||
if (remainingBits == 1) { // Nothing left but +/- 1?
|
if (remainingBits == 1) { // Nothing left but +/- 1?
|
||||||
if (signum < 0 && (exponent&1) == 1) {
|
if (signum < 0 && (exponent&1) == 1) {
|
||||||
return NEGATIVE_ONE.shiftLeft(powersOfTwo*exponent);
|
return NEGATIVE_ONE.shiftLeft(bitsToShift);
|
||||||
} else {
|
} else {
|
||||||
return ONE.shiftLeft(powersOfTwo*exponent);
|
return ONE.shiftLeft(bitsToShift);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2383,13 +2475,16 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
if (bitsToShift + scaleFactor <= 62) { // Fits in long?
|
if (bitsToShift + scaleFactor <= 62) { // Fits in long?
|
||||||
return valueOf((result << bitsToShift) * newSign);
|
return valueOf((result << bitsToShift) * newSign);
|
||||||
} else {
|
} else {
|
||||||
return valueOf(result*newSign).shiftLeft((int) bitsToShift);
|
return valueOf(result*newSign).shiftLeft(bitsToShift);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return valueOf(result*newSign);
|
return valueOf(result*newSign);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if ((long)bitLength() * exponent / Integer.SIZE > MAX_MAG_LENGTH) {
|
||||||
|
reportOverflow();
|
||||||
|
}
|
||||||
|
|
||||||
// Large number algorithm. This is basically identical to
|
// Large number algorithm. This is basically identical to
|
||||||
// the algorithm above, but calls multiply() and square()
|
// the algorithm above, but calls multiply() and square()
|
||||||
// which may use more efficient algorithms for large numbers.
|
// which may use more efficient algorithms for large numbers.
|
||||||
@ -2409,7 +2504,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
// Multiply back the (exponentiated) powers of two (quickly,
|
// Multiply back the (exponentiated) powers of two (quickly,
|
||||||
// by shifting left)
|
// by shifting left)
|
||||||
if (powersOfTwo > 0) {
|
if (powersOfTwo > 0) {
|
||||||
answer = answer.shiftLeft(powersOfTwo*exponent);
|
answer = answer.shiftLeft(bitsToShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signum < 0 && (exponent&1) == 1) {
|
if (signum < 0 && (exponent&1) == 1) {
|
||||||
@ -3584,7 +3679,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
for (int i=1; i< len && pow2; i++)
|
for (int i=1; i< len && pow2; i++)
|
||||||
pow2 = (mag[i] == 0);
|
pow2 = (mag[i] == 0);
|
||||||
|
|
||||||
n = (pow2 ? magBitLength -1 : magBitLength);
|
n = (pow2 ? magBitLength - 1 : magBitLength);
|
||||||
} else {
|
} else {
|
||||||
n = magBitLength;
|
n = magBitLength;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -120,7 +120,7 @@ public class GCMParameterSpec implements AlgorithmParameterSpec {
|
|||||||
|
|
||||||
// Input sanity check
|
// Input sanity check
|
||||||
if ((src == null) ||(len < 0) || (offset < 0)
|
if ((src == null) ||(len < 0) || (offset < 0)
|
||||||
|| ((len + offset) > src.length)) {
|
|| (len > (src.length - offset))) {
|
||||||
throw new IllegalArgumentException("Invalid buffer arguments");
|
throw new IllegalArgumentException("Invalid buffer arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,7 @@ import java.net.URL;
|
|||||||
* credentials without prompting) should only be tried with trusted sites.
|
* credentials without prompting) should only be tried with trusted sites.
|
||||||
*/
|
*/
|
||||||
public abstract class NTLMAuthenticationCallback {
|
public abstract class NTLMAuthenticationCallback {
|
||||||
private static volatile NTLMAuthenticationCallback callback =
|
private static volatile NTLMAuthenticationCallback callback;
|
||||||
new DefaultNTLMAuthenticationCallback();
|
|
||||||
|
|
||||||
public static void setNTLMAuthenticationCallback(
|
public static void setNTLMAuthenticationCallback(
|
||||||
NTLMAuthenticationCallback callback) {
|
NTLMAuthenticationCallback callback) {
|
||||||
@ -50,10 +49,5 @@ public abstract class NTLMAuthenticationCallback {
|
|||||||
* transparent Authentication.
|
* transparent Authentication.
|
||||||
*/
|
*/
|
||||||
public abstract boolean isTrustedSite(URL url);
|
public abstract boolean isTrustedSite(URL url);
|
||||||
|
|
||||||
static class DefaultNTLMAuthenticationCallback extends NTLMAuthenticationCallback {
|
|
||||||
@Override
|
|
||||||
public boolean isTrustedSite(URL url) { return true; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -624,11 +624,10 @@ public class FileChannelImpl
|
|||||||
{
|
{
|
||||||
// Untrusted target: Use a newly-erased buffer
|
// Untrusted target: Use a newly-erased buffer
|
||||||
int c = Math.min(icount, TRANSFER_SIZE);
|
int c = Math.min(icount, TRANSFER_SIZE);
|
||||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(c);
|
ByteBuffer bb = ByteBuffer.allocate(c);
|
||||||
long tw = 0; // Total bytes written
|
long tw = 0; // Total bytes written
|
||||||
long pos = position;
|
long pos = position;
|
||||||
try {
|
try {
|
||||||
Util.erase(bb);
|
|
||||||
while (tw < icount) {
|
while (tw < icount) {
|
||||||
bb.limit(Math.min((int)(icount - tw), TRANSFER_SIZE));
|
bb.limit(Math.min((int)(icount - tw), TRANSFER_SIZE));
|
||||||
int nr = read(bb, pos);
|
int nr = read(bb, pos);
|
||||||
@ -649,8 +648,6 @@ public class FileChannelImpl
|
|||||||
if (tw > 0)
|
if (tw > 0)
|
||||||
return tw;
|
return tw;
|
||||||
throw x;
|
throw x;
|
||||||
} finally {
|
|
||||||
Util.releaseTemporaryDirectBuffer(bb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,11 +731,10 @@ public class FileChannelImpl
|
|||||||
{
|
{
|
||||||
// Untrusted target: Use a newly-erased buffer
|
// Untrusted target: Use a newly-erased buffer
|
||||||
int c = (int)Math.min(count, TRANSFER_SIZE);
|
int c = (int)Math.min(count, TRANSFER_SIZE);
|
||||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(c);
|
ByteBuffer bb = ByteBuffer.allocate(c);
|
||||||
long tw = 0; // Total bytes written
|
long tw = 0; // Total bytes written
|
||||||
long pos = position;
|
long pos = position;
|
||||||
try {
|
try {
|
||||||
Util.erase(bb);
|
|
||||||
while (tw < count) {
|
while (tw < count) {
|
||||||
bb.limit((int)Math.min((count - tw), (long)TRANSFER_SIZE));
|
bb.limit((int)Math.min((count - tw), (long)TRANSFER_SIZE));
|
||||||
// ## Bug: Will block reading src if this channel
|
// ## Bug: Will block reading src if this channel
|
||||||
@ -759,8 +755,6 @@ public class FileChannelImpl
|
|||||||
if (tw > 0)
|
if (tw > 0)
|
||||||
return tw;
|
return tw;
|
||||||
throw x;
|
throw x;
|
||||||
} finally {
|
|
||||||
Util.releaseTemporaryDirectBuffer(bb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
############################################################
|
############################################################
|
||||||
# Default Networking Configuration File
|
# Default Networking Configuration File
|
||||||
#
|
#
|
||||||
# This file may contain default values for the networking system properties.
|
# This file may contain default values for the networking system properties.
|
||||||
# These values are only used when the system properties are not specified
|
# These values are only used when the system properties are not specified
|
||||||
@ -110,3 +110,23 @@ jdk.http.auth.tunneling.disabledSchemes=Basic
|
|||||||
#
|
#
|
||||||
# jdk.httpclient.allowRestrictedHeaders=host
|
# jdk.httpclient.allowRestrictedHeaders=host
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Transparent NTLM HTTP authentication mode on Windows. Transparent authentication
|
||||||
|
# can be used for the NTLM scheme, where the security credentials based on the
|
||||||
|
# currently logged in user's name and password can be obtained directly from the
|
||||||
|
# operating system, without prompting the user. This property has three possible
|
||||||
|
# values which regulate the behavior as shown below. Other unrecognized values
|
||||||
|
# are handled the same as 'disabled'. Note, that NTLM is not considered to be a
|
||||||
|
# strongly secure authentication scheme and care should be taken before enabling
|
||||||
|
# this mechanism.
|
||||||
|
#
|
||||||
|
# Transparent authentication never used.
|
||||||
|
#jdk.http.ntlm.transparentAuth=disabled
|
||||||
|
#
|
||||||
|
# Enabled for all hosts.
|
||||||
|
#jdk.http.ntlm.transparentAuth=allHosts
|
||||||
|
#
|
||||||
|
# Enabled for hosts that are trusted in Windows Internet settings
|
||||||
|
#jdk.http.ntlm.transparentAuth=trustedHosts
|
||||||
|
#
|
||||||
|
jdk.http.ntlm.transparentAuth=disabled
|
||||||
|
@ -93,10 +93,13 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the given site is trusted, i.e. we can try
|
* Returns true if the given site is trusted, i.e. we can try
|
||||||
* transparent Authentication.
|
* transparent Authentication. Shouldn't be called since
|
||||||
|
* capability not supported on Unix
|
||||||
*/
|
*/
|
||||||
public static boolean isTrustedSite(URL url) {
|
public static boolean isTrustedSite(URL url) {
|
||||||
return NTLMAuthCallback.isTrustedSite(url);
|
if (NTLMAuthCallback != null)
|
||||||
|
return NTLMAuthCallback.isTrustedSite(url);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init0() {
|
private void init0() {
|
||||||
|
@ -584,6 +584,8 @@ static void initLoopbackRoutes() {
|
|||||||
|
|
||||||
if (loRoutesTemp == 0) {
|
if (loRoutesTemp == 0) {
|
||||||
free(loRoutes);
|
free(loRoutes);
|
||||||
|
loRoutes = NULL;
|
||||||
|
nRoutes = 0;
|
||||||
fclose (f);
|
fclose (f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import java.net.UnknownHostException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import sun.net.NetProperties;
|
||||||
import sun.net.www.HeaderParser;
|
import sun.net.www.HeaderParser;
|
||||||
import sun.net.www.protocol.http.AuthenticationInfo;
|
import sun.net.www.protocol.http.AuthenticationInfo;
|
||||||
import sun.net.www.protocol.http.AuthScheme;
|
import sun.net.www.protocol.http.AuthScheme;
|
||||||
@ -56,11 +57,33 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
|||||||
private static final String defaultDomain;
|
private static final String defaultDomain;
|
||||||
/* Whether cache is enabled for NTLM */
|
/* Whether cache is enabled for NTLM */
|
||||||
private static final boolean ntlmCache;
|
private static final boolean ntlmCache;
|
||||||
|
|
||||||
|
enum TransparentAuth {
|
||||||
|
DISABLED, // disable for all hosts (default)
|
||||||
|
TRUSTED_HOSTS, // use Windows trusted hosts settings
|
||||||
|
ALL_HOSTS // attempt for all hosts
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final TransparentAuth authMode;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Properties props = GetPropertyAction.privilegedGetProperties();
|
Properties props = GetPropertyAction.privilegedGetProperties();
|
||||||
defaultDomain = props.getProperty("http.auth.ntlm.domain", "domain");
|
defaultDomain = props.getProperty("http.auth.ntlm.domain", "domain");
|
||||||
String ntlmCacheProp = props.getProperty("jdk.ntlm.cache", "true");
|
String ntlmCacheProp = props.getProperty("jdk.ntlm.cache", "true");
|
||||||
ntlmCache = Boolean.parseBoolean(ntlmCacheProp);
|
ntlmCache = Boolean.parseBoolean(ntlmCacheProp);
|
||||||
|
String modeProp = java.security.AccessController.doPrivileged(
|
||||||
|
new java.security.PrivilegedAction<String>() {
|
||||||
|
public String run() {
|
||||||
|
return NetProperties.get("jdk.http.ntlm.transparentAuth");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ("trustedHosts".equalsIgnoreCase(modeProp))
|
||||||
|
authMode = TransparentAuth.TRUSTED_HOSTS;
|
||||||
|
else if ("allHosts".equalsIgnoreCase(modeProp))
|
||||||
|
authMode = TransparentAuth.ALL_HOSTS;
|
||||||
|
else
|
||||||
|
authMode = TransparentAuth.DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init0() {
|
private void init0() {
|
||||||
@ -166,9 +189,21 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
|||||||
* transparent Authentication.
|
* transparent Authentication.
|
||||||
*/
|
*/
|
||||||
public static boolean isTrustedSite(URL url) {
|
public static boolean isTrustedSite(URL url) {
|
||||||
return NTLMAuthCallback.isTrustedSite(url);
|
if (NTLMAuthCallback != null)
|
||||||
|
return NTLMAuthCallback.isTrustedSite(url);
|
||||||
|
|
||||||
|
switch (authMode) {
|
||||||
|
case TRUSTED_HOSTS:
|
||||||
|
return isTrustedSite(url.toString());
|
||||||
|
case ALL_HOSTS:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static native boolean isTrustedSite(String url);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not supported. Must use the setHeaders() method
|
* Not supported. Must use the setHeaders() method
|
||||||
*/
|
*/
|
||||||
@ -218,5 +253,4 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
106
src/java.base/windows/native/libnet/NTLMAuthentication.c
Normal file
106
src/java.base/windows/native/libnet/NTLMAuthentication.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "jni_util.h"
|
||||||
|
#include <urlmon.h>
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL Java_sun_net_www_protocol_http_ntlm_NTLMAuthentication_isTrustedSite(JNIEnv *env, jclass clazz, jstring url )
|
||||||
|
{
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
DWORD dwZone;
|
||||||
|
DWORD pPolicy = 0;
|
||||||
|
IInternetSecurityManager *spSecurityManager;
|
||||||
|
jboolean ret;
|
||||||
|
|
||||||
|
// Create IInternetSecurityManager
|
||||||
|
hr = CoInternetCreateSecurityManager(NULL, &spSecurityManager, (DWORD)0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LPCWSTR bstrURL = (LPCWSTR)((*env)->GetStringChars(env, url, NULL));
|
||||||
|
if (bstrURL == NULL) {
|
||||||
|
if (!(*env)->ExceptionCheck(env))
|
||||||
|
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||||
|
spSecurityManager->lpVtbl->Release(spSecurityManager);
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determines the policy for the URLACTION_CREDENTIALS_USE action and display
|
||||||
|
// a user interface, if the policy indicates that the user should be queried
|
||||||
|
hr = spSecurityManager->lpVtbl->ProcessUrlAction(
|
||||||
|
spSecurityManager,
|
||||||
|
bstrURL,
|
||||||
|
URLACTION_CREDENTIALS_USE,
|
||||||
|
(LPBYTE)&pPolicy,
|
||||||
|
sizeof(DWORD), 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ret = JNI_FALSE;
|
||||||
|
goto cleanupAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If these two User Authentication Logon options is selected
|
||||||
|
// Anonymous logon
|
||||||
|
// Prompt for user name and password
|
||||||
|
if (pPolicy == URLPOLICY_CREDENTIALS_ANONYMOUS_ONLY ||
|
||||||
|
pPolicy == URLPOLICY_CREDENTIALS_MUST_PROMPT_USER) {
|
||||||
|
ret = JNI_FALSE;
|
||||||
|
goto cleanupAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option "Automatic logon with current user name and password" is selected
|
||||||
|
if (pPolicy == URLPOLICY_CREDENTIALS_SILENT_LOGON_OK) {
|
||||||
|
ret = JNI_TRUE;
|
||||||
|
goto cleanupAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Option "Automatic logon only in intranet zone" is selected
|
||||||
|
if (pPolicy == URLPOLICY_CREDENTIALS_CONDITIONAL_PROMPT) {
|
||||||
|
|
||||||
|
// Gets the zone index from the specified URL
|
||||||
|
hr = spSecurityManager->lpVtbl->MapUrlToZone(
|
||||||
|
spSecurityManager, bstrURL, &dwZone, 0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
ret = JNI_FALSE;
|
||||||
|
goto cleanupAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the URL is in Local or Intranet zone
|
||||||
|
if (dwZone == URLZONE_INTRANET || dwZone == URLZONE_LOCAL_MACHINE) {
|
||||||
|
ret = JNI_TRUE;
|
||||||
|
goto cleanupAndReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = JNI_FALSE;
|
||||||
|
|
||||||
|
cleanupAndReturn:
|
||||||
|
(*env)->ReleaseStringChars(env, url, bstrURL);
|
||||||
|
spSecurityManager->lpVtbl->Release(spSecurityManager);
|
||||||
|
return ret;
|
||||||
|
}
|
@ -273,7 +273,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
|
|||||||
// But in rare case it fails, we allow 'char' to be displayed
|
// But in rare case it fails, we allow 'char' to be displayed
|
||||||
curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
|
curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
|
||||||
} else {
|
} else {
|
||||||
curr->displayName = (wchar_t *)malloc(wlen*(sizeof(wchar_t))+1);
|
curr->displayName = (wchar_t *)malloc((wlen+1)*sizeof(wchar_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
curr->name = (char *)malloc(strlen(dev_name) + 1);
|
curr->name = (char *)malloc(strlen(dev_name) + 1);
|
||||||
@ -316,7 +316,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
|
|||||||
free(curr);
|
free(curr);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
curr->displayName[wlen*(sizeof(wchar_t))] = '\0';
|
((wchar_t *)curr->displayName)[wlen] = L'\0';
|
||||||
curr->dNameIsUnicode = TRUE;
|
curr->dNameIsUnicode = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -95,6 +95,10 @@ Java_sun_nio_ch_DatagramDispatcher_readv0(JNIEnv *env, jclass clazz,
|
|||||||
jint fd = fdval(env, fdo);
|
jint fd = fdval(env, fdo);
|
||||||
struct iovec *iovp = (struct iovec *)address;
|
struct iovec *iovp = (struct iovec *)address;
|
||||||
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
||||||
|
if (bufs == NULL) {
|
||||||
|
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||||
|
return IOS_THROWN;
|
||||||
|
}
|
||||||
|
|
||||||
/* copy iovec into WSABUF */
|
/* copy iovec into WSABUF */
|
||||||
for(i=0; i<len; i++) {
|
for(i=0; i<len; i++) {
|
||||||
@ -182,6 +186,10 @@ Java_sun_nio_ch_DatagramDispatcher_writev0(JNIEnv *env, jclass clazz,
|
|||||||
jint fd = fdval(env, fdo);
|
jint fd = fdval(env, fdo);
|
||||||
struct iovec *iovp = (struct iovec *)address;
|
struct iovec *iovp = (struct iovec *)address;
|
||||||
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
||||||
|
if (bufs == NULL) {
|
||||||
|
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||||
|
return IOS_THROWN;
|
||||||
|
}
|
||||||
|
|
||||||
/* copy iovec into WSABUF */
|
/* copy iovec into WSABUF */
|
||||||
for(i=0; i<len; i++) {
|
for(i=0; i<len; i++) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -219,6 +219,10 @@ Java_sun_nio_ch_WindowsSelectorImpl_resetWakeupSocket0(JNIEnv *env, jclass this,
|
|||||||
/* Prepare corresponding buffer if needed, and then read */
|
/* Prepare corresponding buffer if needed, and then read */
|
||||||
if (bytesToRead > WAKEUP_SOCKET_BUF_SIZE) {
|
if (bytesToRead > WAKEUP_SOCKET_BUF_SIZE) {
|
||||||
char* buf = (char*)malloc(bytesToRead);
|
char* buf = (char*)malloc(bytesToRead);
|
||||||
|
if (buf == NULL) {
|
||||||
|
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
recv(scinFd, buf, bytesToRead, 0);
|
recv(scinFd, buf, bytesToRead, 0);
|
||||||
free(buf);
|
free(buf);
|
||||||
} else {
|
} else {
|
||||||
|
@ -394,6 +394,7 @@ public class Robot {
|
|||||||
* @return Color of the pixel
|
* @return Color of the pixel
|
||||||
*/
|
*/
|
||||||
public synchronized Color getPixelColor(int x, int y) {
|
public synchronized Color getPixelColor(int x, int y) {
|
||||||
|
checkScreenCaptureAllowed();
|
||||||
AffineTransform tx = GraphicsEnvironment.
|
AffineTransform tx = GraphicsEnvironment.
|
||||||
getLocalGraphicsEnvironment().getDefaultScreenDevice().
|
getLocalGraphicsEnvironment().getDefaultScreenDevice().
|
||||||
getDefaultConfiguration().getDefaultTransform();
|
getDefaultConfiguration().getDefaultTransform();
|
||||||
|
@ -406,6 +406,9 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
|
|||||||
JDIMENSION rowsperchunk, currow, i;
|
JDIMENSION rowsperchunk, currow, i;
|
||||||
long ltemp;
|
long ltemp;
|
||||||
|
|
||||||
|
if (samplesperrow == 0) {
|
||||||
|
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||||
|
}
|
||||||
/* Calculate max # of rows allowed in one allocation chunk */
|
/* Calculate max # of rows allowed in one allocation chunk */
|
||||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||||
((long) samplesperrow * SIZEOF(JSAMPLE));
|
((long) samplesperrow * SIZEOF(JSAMPLE));
|
||||||
@ -454,6 +457,10 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
|
|||||||
JDIMENSION rowsperchunk, currow, i;
|
JDIMENSION rowsperchunk, currow, i;
|
||||||
long ltemp;
|
long ltemp;
|
||||||
|
|
||||||
|
if (blocksperrow == 0) {
|
||||||
|
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate max # of rows allowed in one allocation chunk */
|
/* Calculate max # of rows allowed in one allocation chunk */
|
||||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||||
((long) blocksperrow * SIZEOF(JBLOCK));
|
((long) blocksperrow * SIZEOF(JBLOCK));
|
||||||
|
@ -1535,10 +1535,16 @@ void AllocateDataSet(cmsIT8* it8)
|
|||||||
t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
|
t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
|
||||||
t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
|
t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
|
||||||
|
|
||||||
t-> Data = (char**)AllocChunk (it8, ((cmsUInt32Number) t->nSamples + 1) * ((cmsUInt32Number) t->nPatches + 1) *sizeof (char*));
|
if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
|
||||||
if (t->Data == NULL) {
|
{
|
||||||
|
SynError(it8, "AllocateDataSet: too much data");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
|
||||||
|
if (t->Data == NULL) {
|
||||||
|
|
||||||
SynError(it8, "AllocateDataSet: Unable to allocate data array");
|
SynError(it8, "AllocateDataSet: Unable to allocate data array");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -161,6 +161,7 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
|
|||||||
int len;
|
int len;
|
||||||
char *stock_id_str = NULL;
|
char *stock_id_str = NULL;
|
||||||
char *detail_str = NULL;
|
char *detail_str = NULL;
|
||||||
|
jboolean result = JNI_FALSE;
|
||||||
|
|
||||||
if (stock_id == NULL)
|
if (stock_id == NULL)
|
||||||
{
|
{
|
||||||
@ -190,23 +191,15 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon(JNIEnv *env, jobject this,
|
|||||||
(*env)->GetStringUTFRegion(env, detail, 0, len, detail_str);
|
(*env)->GetStringUTFRegion(env, detail, 0, len, detail_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init_method(env, this) ) {
|
if (init_method(env, this)) {
|
||||||
free(stock_id_str);
|
result = gtk->get_icon_data(env, widget_type, stock_id_str,
|
||||||
if (detail_str != NULL) {
|
icon_size, text_direction, detail_str,
|
||||||
free(detail_str);
|
icon_upcall_method, this);
|
||||||
}
|
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
}
|
||||||
jboolean result = gtk->get_icon_data(env, widget_type, stock_id_str,
|
|
||||||
icon_size, text_direction, detail_str,
|
|
||||||
icon_upcall_method, this);
|
|
||||||
|
|
||||||
/* Release the strings we've allocated. */
|
/* Release the strings we've allocated. */
|
||||||
free(stock_id_str);
|
free(stock_id_str);
|
||||||
if (detail_str != NULL)
|
free(detail_str);
|
||||||
{
|
|
||||||
free(detail_str);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
#else /* HEADLESS */
|
#else /* HEADLESS */
|
||||||
return JNI_FALSE;
|
return JNI_FALSE;
|
||||||
|
@ -962,9 +962,10 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env,
|
|||||||
if (!present) {
|
if (!present) {
|
||||||
defIndices[0] = papers[0];
|
defIndices[0] = papers[0];
|
||||||
}
|
}
|
||||||
if (papers != NULL) {
|
}
|
||||||
free((char*)papers);
|
// If DeviceCapabilities fails, then also free paper allocation
|
||||||
}
|
if (papers != NULL) {
|
||||||
|
free((char*)papers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RESTORE_CONTROLWORD
|
RESTORE_CONTROLWORD
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,6 +23,7 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -50,6 +51,10 @@ char* basePath(const char* path) {
|
|||||||
} else {
|
} else {
|
||||||
int len = last - path;
|
int len = last - path;
|
||||||
char* str = (char*)malloc(len+1);
|
char* str = (char*)malloc(len+1);
|
||||||
|
if (str == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
memcpy(str, path, len);
|
memcpy(str, path, len);
|
||||||
}
|
}
|
||||||
@ -80,6 +85,10 @@ static char* normalizePath(const char* pathname, int len, int off) {
|
|||||||
if (n == 0) return strdup("/");
|
if (n == 0) return strdup("/");
|
||||||
|
|
||||||
sb = (char*)malloc(strlen(pathname)+1);
|
sb = (char*)malloc(strlen(pathname)+1);
|
||||||
|
if (sb == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
sbLen = 0;
|
sbLen = 0;
|
||||||
|
|
||||||
if (off > 0) {
|
if (off > 0) {
|
||||||
@ -128,6 +137,10 @@ char* resolve(const char* parent, const char* child) {
|
|||||||
len = parentEnd + cn - childStart;
|
len = parentEnd + cn - childStart;
|
||||||
if (child[0] == slash) {
|
if (child[0] == slash) {
|
||||||
theChars = (char*)malloc(len+1);
|
theChars = (char*)malloc(len+1);
|
||||||
|
if (theChars == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (parentEnd > 0)
|
if (parentEnd > 0)
|
||||||
memcpy(theChars, parent, parentEnd);
|
memcpy(theChars, parent, parentEnd);
|
||||||
if (cn > 0)
|
if (cn > 0)
|
||||||
@ -135,6 +148,10 @@ char* resolve(const char* parent, const char* child) {
|
|||||||
theChars[len] = '\0';
|
theChars[len] = '\0';
|
||||||
} else {
|
} else {
|
||||||
theChars = (char*)malloc(len+2);
|
theChars = (char*)malloc(len+2);
|
||||||
|
if (theChars == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (parentEnd > 0)
|
if (parentEnd > 0)
|
||||||
memcpy(theChars, parent, parentEnd);
|
memcpy(theChars, parent, parentEnd);
|
||||||
theChars[parentEnd] = slash;
|
theChars[parentEnd] = slash;
|
||||||
@ -150,10 +167,13 @@ char* fromURIPath(const char* path) {
|
|||||||
if (len > 1 && path[len-1] == slash) {
|
if (len > 1 && path[len-1] == slash) {
|
||||||
// "/foo/" --> "/foo", but "/" --> "/"
|
// "/foo/" --> "/foo", but "/" --> "/"
|
||||||
char* str = (char*)malloc(len);
|
char* str = (char*)malloc(len);
|
||||||
if (str != NULL) {
|
if (str == NULL)
|
||||||
memcpy(str, path, len-1);
|
{
|
||||||
str[len-1] = '\0';
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memcpy(str, path, len-1);
|
||||||
|
str[len-1] = '\0';
|
||||||
return str;
|
return str;
|
||||||
} else {
|
} else {
|
||||||
return (char*)path;
|
return (char*)path;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,6 +23,7 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -66,6 +67,10 @@ char* basePath(const char* path) {
|
|||||||
} else {
|
} else {
|
||||||
int len = (int)(last - path);
|
int len = (int)(last - path);
|
||||||
char* str = (char*)malloc(len+1);
|
char* str = (char*)malloc(len+1);
|
||||||
|
if (str == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
memcpy(str, path, len);
|
memcpy(str, path, len);
|
||||||
}
|
}
|
||||||
@ -135,6 +140,10 @@ static char* normalizePath(const char* path, int len, int off) {
|
|||||||
if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
|
if (off < 3) off = 0; /* Avoid fencepost cases with UNC pathnames */
|
||||||
|
|
||||||
sb = (char*)malloc(len+1);
|
sb = (char*)malloc(len+1);
|
||||||
|
if (sb == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
sbLen = 0;
|
sbLen = 0;
|
||||||
|
|
||||||
if (off == 0) {
|
if (off == 0) {
|
||||||
@ -261,11 +270,19 @@ char* resolve(const char* parent, const char* child) {
|
|||||||
|
|
||||||
if (child[childStart] == slash) {
|
if (child[childStart] == slash) {
|
||||||
theChars = (char*)malloc(len+1);
|
theChars = (char*)malloc(len+1);
|
||||||
|
if (theChars == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
memcpy(theChars, parent, parentEnd);
|
memcpy(theChars, parent, parentEnd);
|
||||||
memcpy(theChars+parentEnd, child+childStart, (cn-childStart));
|
memcpy(theChars+parentEnd, child+childStart, (cn-childStart));
|
||||||
theChars[len] = '\0';
|
theChars[len] = '\0';
|
||||||
} else {
|
} else {
|
||||||
theChars = (char*)malloc(len+2);
|
theChars = (char*)malloc(len+2);
|
||||||
|
if (theChars == NULL) {
|
||||||
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
memcpy(theChars, parent, parentEnd);
|
memcpy(theChars, parent, parentEnd);
|
||||||
theChars[parentEnd] = slash;
|
theChars[parentEnd] = slash;
|
||||||
memcpy(theChars+parentEnd+1, child+childStart, (cn-childStart));
|
memcpy(theChars+parentEnd+1, child+childStart, (cn-childStart));
|
||||||
@ -320,10 +337,12 @@ char* fromURIPath(const char* path) {
|
|||||||
return (char*)path;
|
return (char*)path;
|
||||||
} else {
|
} else {
|
||||||
char* p = (char*)malloc(len+1);
|
char* p = (char*)malloc(len+1);
|
||||||
if (p != NULL) {
|
if (p == NULL) {
|
||||||
memcpy(p, path+start, len);
|
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||||
p[len] = '\0';
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memcpy(p, path+start, len);
|
||||||
|
p[len] = '\0';
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,8 @@ BOOL native_debug = 0;
|
|||||||
|
|
||||||
BOOL PackageConnectLookup(PHANDLE,PULONG);
|
BOOL PackageConnectLookup(PHANDLE,PULONG);
|
||||||
|
|
||||||
NTSTATUS ConstructTicketRequest(UNICODE_STRING DomainName,
|
NTSTATUS ConstructTicketRequest(JNIEnv *env,
|
||||||
|
UNICODE_STRING DomainName,
|
||||||
PKERB_RETRIEVE_TKT_REQUEST *outRequest,
|
PKERB_RETRIEVE_TKT_REQUEST *outRequest,
|
||||||
ULONG *outSize);
|
ULONG *outSize);
|
||||||
|
|
||||||
@ -104,6 +105,8 @@ jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey);
|
|||||||
jobject BuildTicketFlags(JNIEnv *env, PULONG flags);
|
jobject BuildTicketFlags(JNIEnv *env, PULONG flags);
|
||||||
jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime);
|
jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime);
|
||||||
|
|
||||||
|
void ThrowOOME(JNIEnv *env, const char *szMessage);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: sun_security_krb5_KrbCreds
|
* Class: sun_security_krb5_KrbCreds
|
||||||
* Method: JNI_OnLoad
|
* Method: JNI_OnLoad
|
||||||
@ -497,7 +500,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use domain to request Ticket
|
// use domain to request Ticket
|
||||||
Status = ConstructTicketRequest(msticket->TargetDomainName,
|
Status = ConstructTicketRequest(env, msticket->TargetDomainName,
|
||||||
&pTicketRequest, &requestSize);
|
&pTicketRequest, &requestSize);
|
||||||
if (!LSA_SUCCESS(Status)) {
|
if (!LSA_SUCCESS(Status)) {
|
||||||
ShowNTError("ConstructTicketRequest status", Status);
|
ShowNTError("ConstructTicketRequest status", Status);
|
||||||
@ -691,7 +694,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
|
|||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
ConstructTicketRequest(UNICODE_STRING DomainName,
|
ConstructTicketRequest(JNIEnv *env, UNICODE_STRING DomainName,
|
||||||
PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize)
|
PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
@ -738,8 +741,10 @@ ConstructTicketRequest(UNICODE_STRING DomainName,
|
|||||||
|
|
||||||
pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
|
pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
|
||||||
LocalAlloc(LMEM_ZEROINIT, RequestSize);
|
LocalAlloc(LMEM_ZEROINIT, RequestSize);
|
||||||
if (!pTicketRequest)
|
if (!pTicketRequest) {
|
||||||
|
ThrowOOME(env, "Can't allocate memory for ticket");
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Concatenate the target prefix with the previous response's
|
// Concatenate the target prefix with the previous response's
|
||||||
@ -896,7 +901,7 @@ jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize)
|
|||||||
jbyteArray ary;
|
jbyteArray ary;
|
||||||
|
|
||||||
ary = (*env)->NewByteArray(env,encodedTicketSize);
|
ary = (*env)->NewByteArray(env,encodedTicketSize);
|
||||||
if ((*env)->ExceptionOccurred(env)) {
|
if (ary == NULL) {
|
||||||
return (jobject) NULL;
|
return (jobject) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,6 +947,10 @@ jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName,
|
|||||||
|
|
||||||
realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
|
realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
|
||||||
((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL)));
|
((domainName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL)));
|
||||||
|
if (realm == NULL) {
|
||||||
|
ThrowOOME(env, "Can't allocate memory for realm");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR));
|
wcsncpy(realm, domainName.Buffer, domainName.Length/sizeof(WCHAR));
|
||||||
|
|
||||||
if (native_debug) {
|
if (native_debug) {
|
||||||
@ -1016,6 +1025,9 @@ jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ary = (*env)->NewByteArray(env,cryptoKey->Length);
|
ary = (*env)->NewByteArray(env,cryptoKey->Length);
|
||||||
|
if (ary == NULL) {
|
||||||
|
return (jobject) NULL;
|
||||||
|
}
|
||||||
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
|
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
|
||||||
(jbyte *)cryptoKey->Value);
|
(jbyte *)cryptoKey->Value);
|
||||||
if ((*env)->ExceptionOccurred(env)) {
|
if ((*env)->ExceptionOccurred(env)) {
|
||||||
@ -1038,6 +1050,9 @@ jobject BuildTicketFlags(JNIEnv *env, PULONG flags) {
|
|||||||
ULONG nlflags = htonl(*flags);
|
ULONG nlflags = htonl(*flags);
|
||||||
|
|
||||||
ary = (*env)->NewByteArray(env, sizeof(*flags));
|
ary = (*env)->NewByteArray(env, sizeof(*flags));
|
||||||
|
if (ary == NULL) {
|
||||||
|
return (jobject) NULL;
|
||||||
|
}
|
||||||
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
|
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
|
||||||
(jbyte *)&nlflags);
|
(jbyte *)&nlflags);
|
||||||
if ((*env)->ExceptionOccurred(env)) {
|
if ((*env)->ExceptionOccurred(env)) {
|
||||||
@ -1090,3 +1105,10 @@ jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) {
|
|||||||
}
|
}
|
||||||
return kerberosTime;
|
return kerberosTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThrowOOME(JNIEnv *env, const char *szMessage) {
|
||||||
|
jclass exceptionClazz = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
|
||||||
|
if (exceptionClazz != NULL) {
|
||||||
|
(*env)->ThrowNew(env, exceptionClazz, szMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -32,6 +32,7 @@
|
|||||||
#include "AccessBridgePackages.h" // for debugging only
|
#include "AccessBridgePackages.h" // for debugging only
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
DEBUG_CODE(extern HWND theDialogWindow);
|
DEBUG_CODE(extern HWND theDialogWindow);
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -46,6 +47,9 @@ AccessBridgeQueueElement::AccessBridgeQueueElement(char *buf, int size) {
|
|||||||
next = (AccessBridgeQueueElement *) 0;
|
next = (AccessBridgeQueueElement *) 0;
|
||||||
previous = (AccessBridgeQueueElement *) 0;
|
previous = (AccessBridgeQueueElement *) 0;
|
||||||
buffer = (char *) malloc(bufsize);
|
buffer = (char *) malloc(bufsize);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
memcpy(buffer, buf, bufsize);
|
memcpy(buffer, buf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
|
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
|
||||||
@ -75,18 +75,20 @@
|
|||||||
* Signature: (Ljava/lang/String;)V
|
* Signature: (Ljava/lang/String;)V
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||||
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
|
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath,
|
||||||
|
jstring jGetFunctionList)
|
||||||
{
|
{
|
||||||
HINSTANCE hModule;
|
HINSTANCE hModule;
|
||||||
CK_C_GetFunctionList C_GetFunctionList;
|
CK_C_GetFunctionList C_GetFunctionList;
|
||||||
CK_RV rv;
|
CK_RV rv = CK_ASSERT_OK;
|
||||||
ModuleData *moduleData;
|
ModuleData *moduleData;
|
||||||
jobject globalPKCS11ImplementationReference;
|
jobject globalPKCS11ImplementationReference;
|
||||||
LPVOID lpMsgBuf;
|
LPVOID lpMsgBuf = NULL;
|
||||||
char *exceptionMessage;
|
char *exceptionMessage = NULL;
|
||||||
const char *getFunctionListStr;
|
const char *getFunctionListStr;
|
||||||
|
|
||||||
const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
|
const char *libraryNameStr = (*env)->GetStringUTFChars(env,
|
||||||
|
jPkcs11ModulePath, 0);
|
||||||
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
|
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
|
||||||
|
|
||||||
|
|
||||||
@ -106,21 +108,24 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
|||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
exceptionMessage = (char *) malloc(sizeof(char) * (strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1));
|
exceptionMessage = (char *) malloc(sizeof(char) *
|
||||||
|
(strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1));
|
||||||
|
if (exceptionMessage == NULL) {
|
||||||
|
throwOutOfMemoryError(env, 0);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
strcpy(exceptionMessage, (LPTSTR) lpMsgBuf);
|
strcpy(exceptionMessage, (LPTSTR) lpMsgBuf);
|
||||||
strcat(exceptionMessage, libraryNameStr);
|
strcat(exceptionMessage, libraryNameStr);
|
||||||
throwIOException(env, (LPTSTR) exceptionMessage);
|
throwIOException(env, (LPTSTR) exceptionMessage);
|
||||||
/* Free the buffer. */
|
goto cleanup;
|
||||||
free(exceptionMessage);
|
|
||||||
LocalFree(lpMsgBuf);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get function pointer to C_GetFunctionList
|
* Get function pointer to C_GetFunctionList
|
||||||
*/
|
*/
|
||||||
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
|
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
|
||||||
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, getFunctionListStr);
|
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule,
|
||||||
|
getFunctionListStr);
|
||||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
|
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
|
||||||
if (C_GetFunctionList == NULL) {
|
if (C_GetFunctionList == NULL) {
|
||||||
FormatMessage(
|
FormatMessage(
|
||||||
@ -135,24 +140,37 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
throwIOException(env, (LPTSTR) lpMsgBuf);
|
throwIOException(env, (LPTSTR) lpMsgBuf);
|
||||||
/* Free the buffer. */
|
goto cleanup;
|
||||||
LocalFree( lpMsgBuf );
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get function pointers to all PKCS #11 functions
|
* Get function pointers to all PKCS #11 functions
|
||||||
*/
|
*/
|
||||||
moduleData = (ModuleData *) malloc(sizeof(ModuleData));
|
moduleData = (ModuleData *) malloc(sizeof(ModuleData));
|
||||||
|
if (moduleData == NULL) {
|
||||||
|
throwOutOfMemoryError(env, 0);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
moduleData->hModule = hModule;
|
moduleData->hModule = hModule;
|
||||||
moduleData->applicationMutexHandler = NULL;
|
moduleData->applicationMutexHandler = NULL;
|
||||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||||
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
|
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
|
||||||
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
|
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
|
||||||
|
|
||||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
|
||||||
TRACE0("FINISHED\n");
|
TRACE0("FINISHED\n");
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
/* Free up allocated buffers we no longer need */
|
||||||
|
if (lpMsgBuf != NULL) {
|
||||||
|
LocalFree( lpMsgBuf );
|
||||||
|
}
|
||||||
|
if (libraryNameStr != NULL) {
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||||
|
}
|
||||||
|
if (exceptionMessage != NULL) {
|
||||||
|
free(exceptionMessage);
|
||||||
|
}
|
||||||
|
|
||||||
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,7 +754,8 @@ abstract class CKeyStore extends KeyStoreSpi {
|
|||||||
new KeyEntry(alias, null, certChain));
|
new KeyEntry(alias, null, certChain));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Ignore the exception and skip this entry
|
// Ignore the exception and skip this entry
|
||||||
// TODO - throw CertificateException?
|
// If e is thrown, remember to deal with it in
|
||||||
|
// native code.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +782,8 @@ abstract class CKeyStore extends KeyStoreSpi {
|
|||||||
certChain));
|
certChain));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// Ignore the exception and skip this entry
|
// Ignore the exception and skip this entry
|
||||||
// TODO - throw CertificateException?
|
// If e is thrown, remember to deal with it in
|
||||||
|
// native code.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,10 +811,14 @@ abstract class CKeyStore extends KeyStoreSpi {
|
|||||||
certCollection.addAll(c);
|
certCollection.addAll(c);
|
||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
// Ignore the exception and skip this certificate
|
// Ignore the exception and skip this certificate
|
||||||
// TODO - throw CertificateException?
|
// If e is thrown, remember to deal with it in
|
||||||
} catch (Throwable te) {
|
// native code.
|
||||||
|
}
|
||||||
|
catch (Throwable te)
|
||||||
|
{
|
||||||
// Ignore the exception and skip this certificate
|
// Ignore the exception and skip this certificate
|
||||||
// TODO - throw CertificateException?
|
// If e is thrown, remember to deal with it in
|
||||||
|
// native code.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,6 +544,15 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
|
|||||||
// Create ArrayList to store certs in each chain
|
// Create ArrayList to store certs in each chain
|
||||||
jobject jArrayList =
|
jobject jArrayList =
|
||||||
env->NewObject(clazzArrayList, mNewArrayList);
|
env->NewObject(clazzArrayList, mNewArrayList);
|
||||||
|
if (jArrayList == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the previous allocated name
|
||||||
|
if (pszNameString) {
|
||||||
|
delete [] pszNameString;
|
||||||
|
pszNameString = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int j=0; j < rgpChain->cElement; j++)
|
for (unsigned int j=0; j < rgpChain->cElement; j++)
|
||||||
{
|
{
|
||||||
@ -582,6 +591,9 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
|
|||||||
|
|
||||||
// Allocate and populate byte array
|
// Allocate and populate byte array
|
||||||
jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
|
jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
|
||||||
|
if (byteArray == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
|
env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
|
||||||
(jbyte*) pbCertEncoded);
|
(jbyte*) pbCertEncoded);
|
||||||
|
|
||||||
@ -590,49 +602,67 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
|
|||||||
env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
|
env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
|
||||||
}
|
}
|
||||||
|
|
||||||
PP("%s: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
|
// Usually pszNameString should be non-NULL. It's either
|
||||||
if (bHasNoPrivateKey)
|
// the friendly name or an element from the subject name
|
||||||
|
// or SAN.
|
||||||
|
if (pszNameString)
|
||||||
{
|
{
|
||||||
// Generate certificate chain and store into cert chain
|
PP("%s: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
|
||||||
// collection
|
if (bHasNoPrivateKey)
|
||||||
env->CallVoidMethod(obj, mGenCertChain,
|
{
|
||||||
env->NewStringUTF(pszNameString),
|
// Generate certificate chain and store into cert chain
|
||||||
jArrayList);
|
// collection
|
||||||
}
|
jstring name = env->NewStringUTF(pszNameString);
|
||||||
else
|
if (name == NULL) {
|
||||||
{
|
__leave;
|
||||||
if (hUserKey) {
|
|
||||||
// Only accept RSA for CAPI
|
|
||||||
DWORD dwData = CALG_RSA_KEYX;
|
|
||||||
DWORD dwSize = sizeof(DWORD);
|
|
||||||
::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, //deprecated
|
|
||||||
&dwSize, NULL);
|
|
||||||
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
|
|
||||||
{
|
|
||||||
// Generate RSA certificate chain and store into cert
|
|
||||||
// chain collection
|
|
||||||
env->CallVoidMethod(obj, mGenKeyAndCertChain,
|
|
||||||
1,
|
|
||||||
env->NewStringUTF(pszNameString),
|
|
||||||
(jlong) hCryptProv, (jlong) hUserKey,
|
|
||||||
dwPublicKeyLength, jArrayList);
|
|
||||||
}
|
}
|
||||||
} else {
|
env->CallVoidMethod(obj, mGenCertChain,
|
||||||
// Only accept EC for CNG
|
name,
|
||||||
BYTE buffer[32];
|
jArrayList);
|
||||||
DWORD len = 0;
|
}
|
||||||
if (::NCryptGetProperty(
|
else
|
||||||
hCryptProv, NCRYPT_ALGORITHM_PROPERTY,
|
{
|
||||||
(PBYTE)buffer, 32, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) {
|
if (hUserKey) {
|
||||||
if (buffer[0] == 'E' && buffer[2] == 'C'
|
// Only accept RSA for CAPI
|
||||||
&& (dwPublicKeyLength == 256
|
DWORD dwData = CALG_RSA_KEYX;
|
||||||
|| dwPublicKeyLength == 384
|
DWORD dwSize = sizeof(DWORD);
|
||||||
|| dwPublicKeyLength == 521)) {
|
::CryptGetKeyParam(hUserKey, KP_ALGID, (BYTE*)&dwData, //deprecated
|
||||||
|
&dwSize, NULL);
|
||||||
|
if ((dwData & ALG_TYPE_RSA) == ALG_TYPE_RSA)
|
||||||
|
{
|
||||||
|
// Generate RSA certificate chain and store into cert
|
||||||
|
// chain collection
|
||||||
|
jstring name = env->NewStringUTF(pszNameString);
|
||||||
|
if (name == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
env->CallVoidMethod(obj, mGenKeyAndCertChain,
|
env->CallVoidMethod(obj, mGenKeyAndCertChain,
|
||||||
0,
|
1,
|
||||||
env->NewStringUTF(pszNameString),
|
name,
|
||||||
(jlong) hCryptProv, 0,
|
(jlong) hCryptProv, (jlong) hUserKey,
|
||||||
dwPublicKeyLength, jArrayList);
|
dwPublicKeyLength, jArrayList);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Only accept EC for CNG
|
||||||
|
BYTE buffer[32];
|
||||||
|
DWORD len = 0;
|
||||||
|
if (::NCryptGetProperty(
|
||||||
|
hCryptProv, NCRYPT_ALGORITHM_PROPERTY,
|
||||||
|
(PBYTE)buffer, 32, &len, NCRYPT_SILENT_FLAG) == ERROR_SUCCESS) {
|
||||||
|
if (buffer[0] == 'E' && buffer[2] == 'C'
|
||||||
|
&& (dwPublicKeyLength == 256
|
||||||
|
|| dwPublicKeyLength == 384
|
||||||
|
|| dwPublicKeyLength == 521)) {
|
||||||
|
jstring name = env->NewStringUTF(pszNameString);
|
||||||
|
if (name == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
env->CallVoidMethod(obj, mGenKeyAndCertChain,
|
||||||
|
0,
|
||||||
|
name,
|
||||||
|
(jlong) hCryptProv, 0,
|
||||||
|
dwPublicKeyLength, jArrayList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -782,6 +812,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash
|
|||||||
|
|
||||||
// Create new byte array
|
// Create new byte array
|
||||||
jbyteArray temp = env->NewByteArray(dwBufLen);
|
jbyteArray temp = env->NewByteArray(dwBufLen);
|
||||||
|
if (temp == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from native buffer
|
// Copy data from native buffer
|
||||||
env->SetByteArrayRegion(temp, 0, dwBufLen, pSignedHashBuffer);
|
env->SetByteArrayRegion(temp, 0, dwBufLen, pSignedHashBuffer);
|
||||||
@ -900,6 +933,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signCngHash
|
|||||||
|
|
||||||
// Create new byte array
|
// Create new byte array
|
||||||
jbyteArray temp = env->NewByteArray(jSignedHashSize);
|
jbyteArray temp = env->NewByteArray(jSignedHashSize);
|
||||||
|
if (temp == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from native buffer
|
// Copy data from native buffer
|
||||||
env->SetByteArrayRegion(temp, 0, jSignedHashSize, pSignedHashBuffer);
|
env->SetByteArrayRegion(temp, 0, jSignedHashSize, pSignedHashBuffer);
|
||||||
@ -1417,6 +1453,9 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_storeCertificate
|
|||||||
}
|
}
|
||||||
|
|
||||||
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
|
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
|
||||||
|
if (jCertAliasChars == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
|
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
|
||||||
pszCertAliasName[size] = 0; // append the string terminator
|
pszCertAliasName[size] = 0; // append the string terminator
|
||||||
|
|
||||||
@ -1847,7 +1886,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_encryptDecrypt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new byte array
|
// Create new byte array
|
||||||
result = env->NewByteArray(dwBufLen);
|
if ((result = env->NewByteArray(dwBufLen)) == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from native buffer to Java buffer
|
// Copy data from native buffer to Java buffer
|
||||||
env->SetByteArrayRegion(result, 0, dwBufLen, (jbyte*) pData);
|
env->SetByteArrayRegion(result, 0, dwBufLen, (jbyte*) pData);
|
||||||
@ -1910,7 +1951,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_getPublicKeyBlo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new byte array
|
// Create new byte array
|
||||||
blob = env->NewByteArray(dwBlobLen);
|
if ((blob = env->NewByteArray(dwBlobLen)) == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from native buffer to Java buffer
|
// Copy data from native buffer to Java buffer
|
||||||
env->SetByteArrayRegion(blob, 0, dwBlobLen, (jbyte*) pbKeyBlob);
|
env->SetByteArrayRegion(blob, 0, dwBlobLen, (jbyte*) pbKeyBlob);
|
||||||
@ -1939,6 +1982,13 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
|||||||
__try {
|
__try {
|
||||||
|
|
||||||
jsize length = env->GetArrayLength(jKeyBlob);
|
jsize length = env->GetArrayLength(jKeyBlob);
|
||||||
|
jsize headerLength = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
|
||||||
|
|
||||||
|
if (length < headerLength) {
|
||||||
|
ThrowExceptionWithMessage(env, KEY_EXCEPTION, "Invalid BLOB");
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
|
if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
@ -1965,7 +2015,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
|||||||
exponentBytes[i] = ((BYTE*) &pRsaPubKey->pubexp)[j];
|
exponentBytes[i] = ((BYTE*) &pRsaPubKey->pubexp)[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
exponent = env->NewByteArray(len);
|
if ((exponent = env->NewByteArray(len)) == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
env->SetByteArrayRegion(exponent, 0, len, exponentBytes);
|
env->SetByteArrayRegion(exponent, 0, len, exponentBytes);
|
||||||
}
|
}
|
||||||
__finally
|
__finally
|
||||||
@ -1995,6 +2047,13 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
|||||||
__try {
|
__try {
|
||||||
|
|
||||||
jsize length = env->GetArrayLength(jKeyBlob);
|
jsize length = env->GetArrayLength(jKeyBlob);
|
||||||
|
jsize headerLength = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY);
|
||||||
|
|
||||||
|
if (length < headerLength) {
|
||||||
|
ThrowExceptionWithMessage(env, KEY_EXCEPTION, "Invalid BLOB");
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
|
if ((keyBlob = env->GetByteArrayElements(jKeyBlob, 0)) == NULL) {
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
@ -2011,19 +2070,25 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
|||||||
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
|
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
|
||||||
|
|
||||||
int len = pRsaPubKey->bitlen / 8;
|
int len = pRsaPubKey->bitlen / 8;
|
||||||
|
if (len < 0 || len > length - headerLength) {
|
||||||
|
ThrowExceptionWithMessage(env, KEY_EXCEPTION, "Invalid key length");
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
|
|
||||||
modulusBytes = new (env) jbyte[len];
|
modulusBytes = new (env) jbyte[len];
|
||||||
if (modulusBytes == NULL) {
|
if (modulusBytes == NULL) {
|
||||||
__leave;
|
__leave;
|
||||||
}
|
}
|
||||||
BYTE * pbModulus =
|
BYTE * pbModulus = (BYTE *) (keyBlob + headerLength);
|
||||||
(BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
|
|
||||||
|
|
||||||
// convert from little-endian while copying from blob
|
// convert from little-endian while copying from blob
|
||||||
for (int i = 0, j = len - 1; i < len; i++, j--) {
|
for (int i = 0, j = len - 1; i < len; i++, j--) {
|
||||||
modulusBytes[i] = pbModulus[j];
|
modulusBytes[i] = pbModulus[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
modulus = env->NewByteArray(len);
|
if ((modulus = env->NewByteArray(len)) == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
env->SetByteArrayRegion(modulus, 0, len, modulusBytes);
|
env->SetByteArrayRegion(modulus, 0, len, modulusBytes);
|
||||||
}
|
}
|
||||||
__finally
|
__finally
|
||||||
@ -2240,7 +2305,9 @@ jbyteArray generateKeyBlob(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jBlob = env->NewByteArray(jBlobLength);
|
if ((jBlob = env->NewByteArray(jBlobLength)) == NULL) {
|
||||||
|
__leave;
|
||||||
|
}
|
||||||
env->SetByteArrayRegion(jBlob, 0, jBlobLength, jBlobBytes);
|
env->SetByteArrayRegion(jBlob, 0, jBlobLength, jBlobBytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,46 @@ public class IntegerExactExceptionTest extends GraalCompilerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIntegerExactOverflowWithoutUse1(int input) {
|
||||||
|
Math.addExact(intCounter, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIntegerExactOverflowWithoutUse2(int input, boolean cond) {
|
||||||
|
if (cond) {
|
||||||
|
Math.addExact(intCounter, input);
|
||||||
|
} else {
|
||||||
|
intCounter = Math.addExact(intCounter, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegerExactWithoutUse1() throws InvalidInstalledCodeException {
|
||||||
|
ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutUse1");
|
||||||
|
InstalledCode code = getCode(method);
|
||||||
|
|
||||||
|
boolean gotException = false;
|
||||||
|
try {
|
||||||
|
code.executeVarargs(this, Integer.MAX_VALUE);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
gotException = true;
|
||||||
|
}
|
||||||
|
assertTrue(gotException);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegerExactWithoutUse2() throws InvalidInstalledCodeException {
|
||||||
|
ResolvedJavaMethod method = getResolvedJavaMethod("testIntegerExactOverflowWithoutUse2");
|
||||||
|
InstalledCode code = getCode(method);
|
||||||
|
|
||||||
|
boolean gotException = false;
|
||||||
|
try {
|
||||||
|
code.executeVarargs(this, Integer.MAX_VALUE, true);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
gotException = true;
|
||||||
|
}
|
||||||
|
assertTrue(gotException);
|
||||||
|
}
|
||||||
|
|
||||||
static long longCounter = 10;
|
static long longCounter = 10;
|
||||||
|
|
||||||
public void testLongExactOverflowSnippet(long input) {
|
public void testLongExactOverflowSnippet(long input) {
|
||||||
@ -138,4 +178,44 @@ public class IntegerExactExceptionTest extends GraalCompilerTest {
|
|||||||
assertTrue(code.isValid());
|
assertTrue(code.isValid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testLongExactOverflowWithoutUse1(long input) {
|
||||||
|
Math.addExact(longCounter, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLongExactOverflowWithoutUse2(long input, boolean cond) {
|
||||||
|
if (cond) {
|
||||||
|
Math.addExact(longCounter, input);
|
||||||
|
} else {
|
||||||
|
longCounter = Math.addExact(longCounter, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongExactWithoutUse1() throws InvalidInstalledCodeException {
|
||||||
|
ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowWithoutUse1");
|
||||||
|
InstalledCode code = getCode(method);
|
||||||
|
|
||||||
|
boolean gotException = false;
|
||||||
|
try {
|
||||||
|
code.executeVarargs(this, Long.MAX_VALUE);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
gotException = true;
|
||||||
|
}
|
||||||
|
assertTrue(gotException);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongExactWithoutUse2() throws InvalidInstalledCodeException {
|
||||||
|
ResolvedJavaMethod method = getResolvedJavaMethod("testLongExactOverflowWithoutUse2");
|
||||||
|
InstalledCode code = getCode(method);
|
||||||
|
|
||||||
|
boolean gotException = false;
|
||||||
|
try {
|
||||||
|
code.executeVarargs(this, Long.MAX_VALUE, true);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
gotException = true;
|
||||||
|
}
|
||||||
|
assertTrue(gotException);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +50,13 @@ import org.graalvm.compiler.phases.tiers.PhaseContext;
|
|||||||
import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticNode;
|
import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticNode;
|
||||||
import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticSplitNode;
|
import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticSplitNode;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
import org.junit.runners.Parameterized.Parameters;
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class IntegerExactFoldTest extends GraalCompilerTest {
|
public class IntegerExactFoldTest extends GraalCompilerTest {
|
||||||
private final long lowerBoundA;
|
private final long lowerBoundA;
|
||||||
|
@ -559,26 +559,19 @@ public class StandardGraphBuilderPlugins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) {
|
private static boolean createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) {
|
||||||
if (b.needsExplicitException()) {
|
if (x.isConstant() && y.isConstant()) {
|
||||||
|
b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW;
|
BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW;
|
||||||
AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind);
|
AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind);
|
||||||
IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op));
|
if (exceptionEdge != null) {
|
||||||
split.setNext(b.add(new BeginNode()));
|
IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op));
|
||||||
} else {
|
split.setNext(b.add(new BeginNode()));
|
||||||
SpeculationLog log = b.getGraph().getSpeculationLog();
|
return true;
|
||||||
if (log == null || (x.isConstant() && y.isConstant())) {
|
|
||||||
b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op));
|
|
||||||
} else {
|
|
||||||
SpeculationReason speculation = new IntegerExactOpSpeculation(b.getMethod(), op);
|
|
||||||
if (log.maySpeculate(speculation)) {
|
|
||||||
b.addPush(kind, createIntegerExactArithmeticNode(x, y, speculation, op));
|
|
||||||
} else {
|
|
||||||
BeginNode begin = b.add(new BeginNode());
|
|
||||||
IntegerExactArithmeticNode node = (IntegerExactArithmeticNode) b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op));
|
|
||||||
node.setAnchor(begin);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,8 +585,7 @@ public class StandardGraphBuilderPlugins {
|
|||||||
@Override
|
@Override
|
||||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
||||||
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
||||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT);
|
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -601,33 +593,29 @@ public class StandardGraphBuilderPlugins {
|
|||||||
@Override
|
@Override
|
||||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
||||||
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
||||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT);
|
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
r.register2("addExact", type, type, new InvocationPlugin() {
|
r.register2("addExact", type, type, new InvocationPlugin() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT);
|
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
r.register2("subtractExact", type, type, new InvocationPlugin() {
|
r.register2("subtractExact", type, type, new InvocationPlugin() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT);
|
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
r.register2("multiplyExact", type, type, new InvocationPlugin() {
|
r.register2("multiplyExact", type, type, new InvocationPlugin() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT);
|
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT);
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -40,6 +40,8 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
|||||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes a file that tries to redirect to an alternate page.
|
* Writes a file that tries to redirect to an alternate page.
|
||||||
* The redirect uses JavaScript, if enabled, falling back on
|
* The redirect uses JavaScript, if enabled, falling back on
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -45,6 +45,8 @@ import javax.tools.Diagnostic;
|
|||||||
import javax.tools.Diagnostic.Kind;
|
import javax.tools.Diagnostic.Kind;
|
||||||
import javax.tools.DocumentationTool;
|
import javax.tools.DocumentationTool;
|
||||||
|
|
||||||
|
import com.sun.tools.javac.code.Flags;
|
||||||
|
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||||
import jdk.javadoc.doclet.Reporter;
|
import jdk.javadoc.doclet.Reporter;
|
||||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||||
@ -276,6 +278,12 @@ public class Extern {
|
|||||||
ModuleElement moduleElement = utils.containingModule(packageElement);
|
ModuleElement moduleElement = utils.containingModule(packageElement);
|
||||||
Map<String, Item> pkgMap = packageItems.get(utils.getModuleName(moduleElement));
|
Map<String, Item> pkgMap = packageItems.get(utils.getModuleName(moduleElement));
|
||||||
item = (pkgMap != null) ? pkgMap.get(utils.getPackageName(packageElement)) : null;
|
item = (pkgMap != null) ? pkgMap.get(utils.getPackageName(packageElement)) : null;
|
||||||
|
if (item == null && isAutomaticModule(moduleElement)) {
|
||||||
|
pkgMap = packageItems.get(utils.getModuleName(null));
|
||||||
|
if (pkgMap != null) {
|
||||||
|
item = pkgMap.get(utils.getPackageName(packageElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -420,12 +428,25 @@ public class Extern {
|
|||||||
path), null);
|
path), null);
|
||||||
}
|
}
|
||||||
} else if (moduleName == null) {
|
} else if (moduleName == null) {
|
||||||
throw new Fault(resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage",
|
// suppress the error message in the case of automatic modules
|
||||||
path), null);
|
if (!isAutomaticModule(me)) {
|
||||||
|
throw new Fault(resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage",
|
||||||
|
path), null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following should be replaced by a new method such as Elements.isAutomaticModule
|
||||||
|
private boolean isAutomaticModule(ModuleElement me) {
|
||||||
|
if (me == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
ModuleSymbol msym = (ModuleSymbol) me;
|
||||||
|
return (msym.flags() & Flags.AUTOMATIC_MODULE) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUrl (String urlCandidate) {
|
public boolean isUrl (String urlCandidate) {
|
||||||
try {
|
try {
|
||||||
new URL(urlCandidate);
|
new URL(urlCandidate);
|
||||||
|
@ -61,8 +61,6 @@ compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
|
|||||||
|
|
||||||
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
|
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
|
||||||
|
|
||||||
compiler/loopopts/PeelingZeroTripCount.java 8216135 generic-all
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
# :hotspot_gc
|
# :hotspot_gc
|
||||||
|
65
test/hotspot/jtreg/compiler/loopopts/Test8210392.java
Normal file
65
test/hotspot/jtreg/compiler/loopopts/Test8210392.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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 8210392
|
||||||
|
* @summary C2 Assert failure: Live node limit exceeded
|
||||||
|
*
|
||||||
|
* @run main/othervm compiler.loopopts.Test8210392
|
||||||
|
*/
|
||||||
|
|
||||||
|
package compiler.loopopts;
|
||||||
|
|
||||||
|
public class Test8210392 {
|
||||||
|
public static int ival = 17;
|
||||||
|
|
||||||
|
public static int intFn() {
|
||||||
|
int v = 0, k = 0;
|
||||||
|
for (int i = 17; i < 311; i += 3) {
|
||||||
|
v = Test8210392.ival;
|
||||||
|
int j = 1;
|
||||||
|
do {
|
||||||
|
v *= i;
|
||||||
|
v += j * v;
|
||||||
|
while (++k < 1)
|
||||||
|
;
|
||||||
|
} while (++j < 13);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mainTest() {
|
||||||
|
for (int i = 0; i < 30000; i++) {
|
||||||
|
Test8210392.ival = intFn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] _args) {
|
||||||
|
Test8210392 tc = new Test8210392();
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
tc.mainTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 ConstantPoolDependsTest
|
||||||
|
* @bug 8210094
|
||||||
|
* @summary Create ClassLoader dependency from initiating loader to class loader through constant pool reference
|
||||||
|
* @requires vm.opt.final.ClassUnloading
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.compiler
|
||||||
|
* @library /runtime/testlibrary /test/lib
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @compile p2/c2.java MyDiffClassLoader.java
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -Xlog:class+unload -XX:+WhiteBoxAPI ConstantPoolDependsTest
|
||||||
|
*/
|
||||||
|
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
|
||||||
|
public class ConstantPoolDependsTest {
|
||||||
|
public static WhiteBox wb = WhiteBox.getWhiteBox();
|
||||||
|
public static final String MY_TEST = "ConstantPoolDependsTest$c1c";
|
||||||
|
|
||||||
|
public static class c1c {
|
||||||
|
private void test() throws Exception {
|
||||||
|
// ConstantPool.klass_at_impl loads through constant pool and creates dependency
|
||||||
|
p2.c2 c2_obj = new p2.c2();
|
||||||
|
c2_obj.method2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public c1c () throws Exception {
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test() throws Throwable {
|
||||||
|
|
||||||
|
// now use the same loader to load class MyTest
|
||||||
|
Class MyTest_class = new MyDiffClassLoader(MY_TEST).loadClass(MY_TEST);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Call MyTest to load p2.c2 twice and call p2.c2.method2
|
||||||
|
MyTest_class.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Test FAILED if NoSuchMethodException is thrown");
|
||||||
|
}
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive(MY_TEST), "should not be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive("p2.c2"), "should not be unloaded");
|
||||||
|
// Unless MyTest_class is referenced here, the compiler can unload it.
|
||||||
|
System.out.println("Should not unload anything before here because " + MyTest_class + " is still alive.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should unload
|
||||||
|
System.gc();
|
||||||
|
System.out.println("Should unload p2.c2 just now");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive(MY_TEST), "should be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive("p2.c2"), "should be unloaded");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 DictionaryDependsTest
|
||||||
|
* @bug 8210094
|
||||||
|
* @summary Create ClassLoader dependency from initiating loader to class loader through reflection
|
||||||
|
* @requires vm.opt.final.ClassUnloading
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.compiler
|
||||||
|
* @library /runtime/testlibrary /test/lib
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @compile p2/c2.java MyDiffClassLoader.java
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -Xlog:class+unload -XX:+WhiteBoxAPI DictionaryDependsTest
|
||||||
|
*/
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class DictionaryDependsTest {
|
||||||
|
public static WhiteBox wb = WhiteBox.getWhiteBox();
|
||||||
|
public static final String MY_TEST = "DictionaryDependsTest$c1r";
|
||||||
|
|
||||||
|
static public class c1r {
|
||||||
|
|
||||||
|
private void test() throws Exception {
|
||||||
|
// forName loads through reflection and doesn't create dependency
|
||||||
|
Class<?> x = Class.forName("p2.c2", true, c1r.class.getClassLoader());
|
||||||
|
Method m = x.getMethod("method2");
|
||||||
|
java.lang.Object t = x.newInstance();
|
||||||
|
m.invoke(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public c1r () throws Exception {
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should unload p2.c2
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should unload p2.c2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() throws Throwable {
|
||||||
|
|
||||||
|
// now use the same loader to load class MyTest
|
||||||
|
Class MyTest_class = new MyDiffClassLoader(MY_TEST).loadClass(MY_TEST);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Call MyTest to load p2.c2 twice and call p2.c2.method2
|
||||||
|
MyTest_class.newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Not expected NSME");
|
||||||
|
throw new RuntimeException("Not expecting NSME");
|
||||||
|
}
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive(MY_TEST), "should not be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive("p2.c2"), "should not be unloaded");
|
||||||
|
// Unless MyTest_class is referenced here, the compiler can unload it.
|
||||||
|
System.out.println("Should not unload anything before here because " + MyTest_class + " is still alive.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
DictionaryDependsTest d = new DictionaryDependsTest();
|
||||||
|
d.test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
System.out.println("Should unload MyTest and p2.c2 just now");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive(MY_TEST), "should be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive("p2.c2"), "should be unloaded");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import jdk.test.lib.compiler.InMemoryJavaCompiler;
|
||||||
|
|
||||||
|
public class MyDiffClassLoader extends ClassLoader {
|
||||||
|
|
||||||
|
public String loaderName;
|
||||||
|
public static boolean switchClassData = false;
|
||||||
|
|
||||||
|
MyDiffClassLoader(String name) {
|
||||||
|
this.loaderName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class loadClass(String name) throws ClassNotFoundException {
|
||||||
|
if (!name.contains("c1r") &&
|
||||||
|
!name.contains("c1c") &&
|
||||||
|
!name.contains("c1s") &&
|
||||||
|
!name.equals("p2.c2")) {
|
||||||
|
return super.loadClass(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// new loader loads p2.c2
|
||||||
|
if (name.equals("p2.c2") && !loaderName.equals("C2Loader")) {
|
||||||
|
Class<?> c = new MyDiffClassLoader("C2Loader").loadClass(name);
|
||||||
|
switchClassData = true;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] data = switchClassData ? getNewClassData(name) : getClassData(name);
|
||||||
|
System.out.println("name is " + name);
|
||||||
|
return defineClass(name, data, 0, data.length);
|
||||||
|
}
|
||||||
|
byte[] getClassData(String name) {
|
||||||
|
try {
|
||||||
|
String TempName = name.replaceAll("\\.", "/");
|
||||||
|
String currentDir = System.getProperty("test.classes");
|
||||||
|
String filename = currentDir + File.separator + TempName + ".class";
|
||||||
|
FileInputStream fis = new FileInputStream(filename);
|
||||||
|
byte[] b = new byte[5000];
|
||||||
|
int cnt = fis.read(b, 0, 5000);
|
||||||
|
byte[] c = new byte[cnt];
|
||||||
|
for (int i=0; i<cnt; i++) c[i] = b[i];
|
||||||
|
return c;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return p2.c2 with everything removed
|
||||||
|
byte[] getNewClassData(String name) {
|
||||||
|
return InMemoryJavaCompiler.compile("p2.c2", "package p2; public class c2 { }");
|
||||||
|
}
|
||||||
|
}
|
82
test/hotspot/jtreg/runtime/ClassUnload/SuperDependsTest.java
Normal file
82
test/hotspot/jtreg/runtime/ClassUnload/SuperDependsTest.java
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 SuperDependsTest
|
||||||
|
* @bug 8210094
|
||||||
|
* @summary Create ClassLoader dependency from initiating loader to class loader through subclassing
|
||||||
|
* @requires vm.opt.final.ClassUnloading
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.compiler
|
||||||
|
* @library /runtime/testlibrary /test/lib
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @compile p2/c2.java MyDiffClassLoader.java
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -Xlog:class+unload -XX:+WhiteBoxAPI SuperDependsTest
|
||||||
|
*/
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
import p2.*;
|
||||||
|
|
||||||
|
public class SuperDependsTest {
|
||||||
|
public static WhiteBox wb = WhiteBox.getWhiteBox();
|
||||||
|
public static final String MY_TEST = "SuperDependsTest$c1s";
|
||||||
|
|
||||||
|
|
||||||
|
// p2.c2 loads through super class and creates dependency
|
||||||
|
public static class c1s extends p2.c2 {
|
||||||
|
|
||||||
|
private void test() throws Exception {
|
||||||
|
method2();
|
||||||
|
}
|
||||||
|
|
||||||
|
public c1s () throws Exception {
|
||||||
|
test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() throws Throwable {
|
||||||
|
|
||||||
|
// now use the same loader to load class MyTest
|
||||||
|
Class MyTest_class = new MyDiffClassLoader(MY_TEST).loadClass(MY_TEST);
|
||||||
|
|
||||||
|
// Call MyTest to load p2.c2 twice and call p2.c2.method2
|
||||||
|
MyTest_class.newInstance();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive(MY_TEST), "should not be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(!wb.isClassAlive("p2.c2"), "should not be unloaded");
|
||||||
|
// Unless MyTest_class is referenced here, the compiler can unload it.
|
||||||
|
System.out.println("Should not unload anything before here because " + MyTest_class + " is still alive.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
SuperDependsTest d = new SuperDependsTest();
|
||||||
|
d.test();
|
||||||
|
ClassUnloadCommon.triggerUnloading(); // should not unload anything
|
||||||
|
System.out.println("Should unload MyTest and p2.c2 just now");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive(MY_TEST), "should be unloaded");
|
||||||
|
ClassUnloadCommon.failIf(wb.isClassAlive("p2.c2"), "should be unloaded");
|
||||||
|
}
|
||||||
|
}
|
28
test/hotspot/jtreg/runtime/ClassUnload/p2/c2.java
Normal file
28
test/hotspot/jtreg/runtime/ClassUnload/p2/c2.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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.
|
||||||
|
*/
|
||||||
|
package p2;
|
||||||
|
|
||||||
|
public class c2 {
|
||||||
|
int i;
|
||||||
|
public void method2() { i = 5; System.out.println("c2 method2 called"); }
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6362557
|
* @bug 6362557 8200698
|
||||||
* @summary Some tests of add(BigDecimal, mc)
|
* @summary Some tests of add(BigDecimal, mc)
|
||||||
* @author Joseph D. Darcy
|
* @author Joseph D. Darcy
|
||||||
*/
|
*/
|
||||||
@ -290,12 +290,35 @@ public class AddTests {
|
|||||||
return failures;
|
return failures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int arithmeticExceptionTest() {
|
||||||
|
int failures = 0;
|
||||||
|
BigDecimal x;
|
||||||
|
try {
|
||||||
|
//
|
||||||
|
// The string representation "1e2147483647", which is equivalent
|
||||||
|
// to 10^Integer.MAX_VALUE, is used to create an augend with an
|
||||||
|
// unscaled value of 1 and a scale of -Integer.MAX_VALUE. The
|
||||||
|
// addend "1" has an unscaled value of 1 with a scale of 0. The
|
||||||
|
// addition is performed exactly and is specified to have a
|
||||||
|
// preferred scale of max(-Integer.MAX_VALUE, 0). As the scale
|
||||||
|
// of the result is 0, a value with Integer.MAX_VALUE + 1 digits
|
||||||
|
// would need to be created. Therefore the next statement is
|
||||||
|
// expected to overflow with an ArithmeticException.
|
||||||
|
//
|
||||||
|
x = new BigDecimal("1e2147483647").add(new BigDecimal(1));
|
||||||
|
failures++;
|
||||||
|
} catch (ArithmeticException ae) {
|
||||||
|
}
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String argv[]) {
|
public static void main(String argv[]) {
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
|
|
||||||
failures += extremaTests();
|
failures += extremaTests();
|
||||||
failures += roundingGradationTests();
|
failures += roundingGradationTests();
|
||||||
failures += precisionConsistencyTest();
|
failures += precisionConsistencyTest();
|
||||||
|
failures += arithmeticExceptionTest();
|
||||||
|
|
||||||
if (failures > 0) {
|
if (failures > 0) {
|
||||||
throw new RuntimeException("Incurred " + failures +
|
throw new RuntimeException("Incurred " + failures +
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -23,20 +23,48 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 4259453
|
* @bug 4259453 8200698
|
||||||
* @summary Test string constructor of BigDecimal
|
* @summary Test constructors of BigDecimal
|
||||||
|
* @library ..
|
||||||
|
* @run testng Constructor
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
public class Constructor {
|
public class Constructor {
|
||||||
public static void main(String[] args) throws Exception {
|
@Test(expectedExceptions=NumberFormatException.class)
|
||||||
boolean nfe = false;
|
public void stringConstructor() {
|
||||||
|
BigDecimal bd = new BigDecimal("1.2e");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=NumberFormatException.class)
|
||||||
|
public void charArrayConstructorNegativeOffset() {
|
||||||
|
BigDecimal bd = new BigDecimal(new char[5], -1, 4, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=NumberFormatException.class)
|
||||||
|
public void charArrayConstructorNegativeLength() {
|
||||||
|
BigDecimal bd = new BigDecimal(new char[5], 0, -1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=NumberFormatException.class)
|
||||||
|
public void charArrayConstructorIntegerOverflow() {
|
||||||
try {
|
try {
|
||||||
BigDecimal bd = new BigDecimal("1.2e");
|
BigDecimal bd = new BigDecimal(new char[5], Integer.MAX_VALUE - 5,
|
||||||
} catch (NumberFormatException e) {
|
6, null);
|
||||||
nfe = true;
|
} catch (NumberFormatException nfe) {
|
||||||
|
if (nfe.getCause() instanceof IndexOutOfBoundsException) {
|
||||||
|
throw new RuntimeException
|
||||||
|
("NumberFormatException should not have a cause");
|
||||||
|
} else {
|
||||||
|
throw nfe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!nfe)
|
}
|
||||||
throw new Exception("Didn't throw NumberFormatException");
|
|
||||||
|
@Test(expectedExceptions=NumberFormatException.class)
|
||||||
|
public void charArrayConstructorIndexOutOfBounds() {
|
||||||
|
BigDecimal bd = new BigDecimal(new char[5], 1, 5, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
192
test/jdk/java/math/BigInteger/LargeValueExceptions.java
Normal file
192
test/jdk/java/math/BigInteger/LargeValueExceptions.java
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 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 8200698
|
||||||
|
* @summary Tests that exceptions are thrown for ops which would overflow
|
||||||
|
* @requires os.maxMemory >= 4g
|
||||||
|
* @run testng/othervm -Xmx4g LargeValueExceptions
|
||||||
|
*/
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import static java.math.BigInteger.ONE;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The intent of this test is to probe the boundaries between overflow and
|
||||||
|
// non-overflow, principally for multiplication and squaring, specifically
|
||||||
|
// the largest values which should not overflow and the smallest values which
|
||||||
|
// should. The transition values used are not necessarily at the exact
|
||||||
|
// boundaries but should be "close." Quite a few different values were used
|
||||||
|
// experimentally before settling on the ones in this test. For multiplication
|
||||||
|
// and squaring all cases are exercised: definite overflow and non-overflow
|
||||||
|
// which can be detected "up front," and "indefinite" overflow, i.e., overflow
|
||||||
|
// which cannot be detected up front so further calculations are required.
|
||||||
|
//
|
||||||
|
// Testing negative values is unnecessary. For both multiplication and squaring
|
||||||
|
// the paths lead to the Toom-Cook algorithm where the signum is used only to
|
||||||
|
// determine the sign of the result and not in the intermediate calculations.
|
||||||
|
// This is also true for exponentiation.
|
||||||
|
//
|
||||||
|
// @Test annotations with optional element "enabled" set to "false" should
|
||||||
|
// succeed when "enabled" is set to "true" but they take too to run in the
|
||||||
|
// course of the typical regression test execution scenario.
|
||||||
|
//
|
||||||
|
public class LargeValueExceptions {
|
||||||
|
// BigInteger.MAX_MAG_LENGTH
|
||||||
|
private static final int MAX_INTS = 1 << 26;
|
||||||
|
|
||||||
|
// Number of bits corresponding to MAX_INTS
|
||||||
|
private static final long MAX_BITS = (0xffffffffL & MAX_INTS) << 5L;
|
||||||
|
|
||||||
|
// Half BigInteger.MAX_MAG_LENGTH
|
||||||
|
private static final int MAX_INTS_HALF = MAX_INTS / 2;
|
||||||
|
|
||||||
|
// --- squaring ---
|
||||||
|
|
||||||
|
// Largest no overflow determined by examining data lengths alone.
|
||||||
|
@Test(enabled=false)
|
||||||
|
public void squareNoOverflow() {
|
||||||
|
BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1).subtract(ONE);
|
||||||
|
BigInteger y = x.multiply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smallest no overflow determined by extra calculations.
|
||||||
|
@Test(enabled=false)
|
||||||
|
public void squareIndefiniteOverflowSuccess() {
|
||||||
|
BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1);
|
||||||
|
BigInteger y = x.multiply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Largest overflow detected by extra calculations.
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class,enabled=false)
|
||||||
|
public void squareIndefiniteOverflowFailure() {
|
||||||
|
BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE);
|
||||||
|
BigInteger y = x.multiply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smallest overflow detected by examining data lengths alone.
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class)
|
||||||
|
public void squareDefiniteOverflow() {
|
||||||
|
BigInteger x = ONE.shiftLeft(16*MAX_INTS);
|
||||||
|
BigInteger y = x.multiply(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- multiplication ---
|
||||||
|
|
||||||
|
// Largest no overflow determined by examining data lengths alone.
|
||||||
|
@Test(enabled=false)
|
||||||
|
public void multiplyNoOverflow() {
|
||||||
|
final int halfMaxBits = MAX_INTS_HALF << 5;
|
||||||
|
|
||||||
|
BigInteger x = ONE.shiftLeft(halfMaxBits).subtract(ONE);
|
||||||
|
BigInteger y = ONE.shiftLeft(halfMaxBits - 1).subtract(ONE);
|
||||||
|
BigInteger z = x.multiply(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smallest no overflow determined by extra calculations.
|
||||||
|
@Test(enabled=false)
|
||||||
|
public void multiplyIndefiniteOverflowSuccess() {
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
|
||||||
|
long m = MAX_BITS - x.bitLength();
|
||||||
|
|
||||||
|
BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2) - 1);
|
||||||
|
long n = MAX_BITS - y.bitLength();
|
||||||
|
|
||||||
|
if (m + n != MAX_BITS) {
|
||||||
|
throw new RuntimeException("Unexpected leading zero sum");
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger z = x.multiply(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Largest overflow detected by extra calculations.
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class,enabled=false)
|
||||||
|
public void multiplyIndefiniteOverflowFailure() {
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
|
||||||
|
long m = MAX_BITS - x.bitLength();
|
||||||
|
|
||||||
|
BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE);
|
||||||
|
long n = MAX_BITS - y.bitLength();
|
||||||
|
|
||||||
|
if (m + n != MAX_BITS) {
|
||||||
|
throw new RuntimeException("Unexpected leading zero sum");
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInteger z = x.multiply(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smallest overflow detected by examining data lengths alone.
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class)
|
||||||
|
public void multiplyDefiniteOverflow() {
|
||||||
|
// multiply by 4 as MAX_INTS_HALF refers to ints
|
||||||
|
byte[] xmag = new byte[4*MAX_INTS_HALF];
|
||||||
|
xmag[0] = (byte)0xff;
|
||||||
|
BigInteger x = new BigInteger(1, xmag);
|
||||||
|
|
||||||
|
byte[] ymag = new byte[4*MAX_INTS_HALF + 1];
|
||||||
|
ymag[0] = (byte)0xff;
|
||||||
|
BigInteger y = new BigInteger(1, ymag);
|
||||||
|
|
||||||
|
BigInteger z = x.multiply(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- exponentiation ---
|
||||||
|
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class)
|
||||||
|
public void powOverflow() {
|
||||||
|
BigInteger.TEN.pow(Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class)
|
||||||
|
public void powOverflow1() {
|
||||||
|
int shift = 20;
|
||||||
|
int exponent = 1 << shift;
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent));
|
||||||
|
BigInteger y = x.pow(exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class)
|
||||||
|
public void powOverflow2() {
|
||||||
|
int shift = 20;
|
||||||
|
int exponent = 1 << shift;
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE);
|
||||||
|
BigInteger y = x.pow(exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions=ArithmeticException.class,enabled=false)
|
||||||
|
public void powOverflow3() {
|
||||||
|
int shift = 20;
|
||||||
|
int exponent = 1 << shift;
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE);
|
||||||
|
BigInteger y = x.pow(exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled=false)
|
||||||
|
public void powOverflow4() {
|
||||||
|
int shift = 20;
|
||||||
|
int exponent = 1 << shift;
|
||||||
|
BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent - 1)).add(ONE);
|
||||||
|
BigInteger y = x.pow(exponent);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 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 8212233
|
||||||
|
* @summary The code being documented uses modules but the packages defined in $URL are in the unnamed module.
|
||||||
|
* @library /tools/lib ../lib
|
||||||
|
* @modules
|
||||||
|
* jdk.javadoc/jdk.javadoc.internal.tool
|
||||||
|
* jdk.compiler/com.sun.tools.javac.api
|
||||||
|
* jdk.compiler/com.sun.tools.javac.main
|
||||||
|
* @build JavadocTester toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder toolbox.ToolBox
|
||||||
|
* @run main TestLinkOptionWithAutomaticModule
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import toolbox.JarTask;
|
||||||
|
import toolbox.JavacTask;
|
||||||
|
import toolbox.ModuleBuilder;
|
||||||
|
import toolbox.ToolBox;
|
||||||
|
|
||||||
|
public class TestLinkOptionWithAutomaticModule extends JavadocTester {
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
TestLinkOptionWithAutomaticModule tester = new TestLinkOptionWithAutomaticModule();
|
||||||
|
tester.runTests(m -> new Object[]{ Path.of(m.getName()) });
|
||||||
|
}
|
||||||
|
|
||||||
|
final ToolBox tb = new ToolBox();
|
||||||
|
private Path libJar;
|
||||||
|
private Path libAPI;
|
||||||
|
|
||||||
|
TestLinkOptionWithAutomaticModule() throws IOException {
|
||||||
|
initLib();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initLib() throws IOException {
|
||||||
|
// create library: write source, compile it, jar it
|
||||||
|
Path lib = Path.of("lib");
|
||||||
|
Path libSrc = lib.resolve("src");
|
||||||
|
tb.writeJavaFiles(libSrc, "package lib; public class LibClass { }");
|
||||||
|
Path libClasses = Files.createDirectories(lib.resolve("classes"));
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.outdir(libClasses)
|
||||||
|
.files(tb.findJavaFiles(libSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll();
|
||||||
|
|
||||||
|
libJar = lib.resolve("MyLib.jar");
|
||||||
|
new JarTask(tb, libJar)
|
||||||
|
.baseDir(libClasses)
|
||||||
|
.files(".")
|
||||||
|
.run();
|
||||||
|
|
||||||
|
libAPI = lib.resolve("api");
|
||||||
|
javadoc("-d", libAPI.toString(),
|
||||||
|
"-sourcepath", libSrc.toString(),
|
||||||
|
"lib");
|
||||||
|
checkExit(Exit.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinkUnnamedToAutomaticModule(Path base) throws IOException {
|
||||||
|
|
||||||
|
// create API referring to library
|
||||||
|
Path src = base.resolve("src");
|
||||||
|
tb.writeJavaFiles(src, "package p; public class MyClass extends lib.LibClass { }");
|
||||||
|
|
||||||
|
// run javadoc with library as automatic module
|
||||||
|
Path api = base.resolve("api");
|
||||||
|
javadoc("-d", api.toString(),
|
||||||
|
"-sourcepath", src.toString(),
|
||||||
|
"--add-modules", "MyLib",
|
||||||
|
"--module-path", libJar.toString(),
|
||||||
|
"-linkoffline", "http://myWebsite", libAPI.toAbsolutePath().toString(),
|
||||||
|
"p");
|
||||||
|
checkExit(Exit.OK);
|
||||||
|
checkOutput("p/MyClass.html", true,
|
||||||
|
"extends <a href=\"http://myWebsite/lib/LibClass.html?is-external=true\" "
|
||||||
|
+ "title=\"class or interface in lib\" class=\"externalLink\">LibClass</a>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinkNamedToAutomaticModule(Path base) throws IOException {
|
||||||
|
|
||||||
|
// create API referring to library
|
||||||
|
Path src = base.resolve("src");
|
||||||
|
new ModuleBuilder(tb, "my.module")
|
||||||
|
.exports("p")
|
||||||
|
.requires("MyLib")
|
||||||
|
.classes("package p; public class MyClass extends lib.LibClass { }")
|
||||||
|
.write(src);
|
||||||
|
|
||||||
|
// run javadoc with library as automatic module
|
||||||
|
Path api = base.resolve("api");
|
||||||
|
javadoc("-d", api.toString(),
|
||||||
|
"--module-source-path", src.toString(),
|
||||||
|
"--module-path", libJar.toString(),
|
||||||
|
"-linkoffline", "http://myWebsite", libAPI.toAbsolutePath().toString(),
|
||||||
|
"--module", "my.module");
|
||||||
|
checkExit(Exit.OK);
|
||||||
|
checkOutput("my.module/p/MyClass.html", true,
|
||||||
|
"extends <a href=\"http://myWebsite/lib/LibClass.html?is-external=true\" "
|
||||||
|
+ "title=\"class or interface in lib\" class=\"externalLink\">LibClass</a>");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLinkNamedToUnnamedModule(Path base) throws IOException {
|
||||||
|
|
||||||
|
// create API referring to library
|
||||||
|
Path src = base.resolve("src");
|
||||||
|
new ModuleBuilder(tb, "my.module")
|
||||||
|
.exports("p")
|
||||||
|
.classes("package p; public class MyClass extends lib.LibClass { }")
|
||||||
|
.write(src);
|
||||||
|
|
||||||
|
// run javadoc with library as unnamed module
|
||||||
|
Path api = base.resolve("api");
|
||||||
|
javadoc("-d", api.toString(),
|
||||||
|
"--module-source-path", src.toString(),
|
||||||
|
"--add-reads", "my.module=ALL-UNNAMED",
|
||||||
|
"--class-path", libJar.toString(),
|
||||||
|
"-linkoffline", "http://myWebsite", libAPI.toAbsolutePath().toString(),
|
||||||
|
"--module", "my.module");
|
||||||
|
checkExit(Exit.OK);
|
||||||
|
checkOutput("my.module/p/MyClass.html", true,
|
||||||
|
"extends <a href=\"http://myWebsite/lib/LibClass.html?is-external=true\" "
|
||||||
|
+ "title=\"class or interface in lib\" class=\"externalLink\">LibClass</a>");
|
||||||
|
}
|
||||||
|
}
|
@ -80,7 +80,7 @@
|
|||||||
"columnNumber": "15",
|
"columnNumber": "15",
|
||||||
"kind": "ERROR",
|
"kind": "ERROR",
|
||||||
"position": "15",
|
"position": "15",
|
||||||
"message": "test.js:1:15 Unclosed group near index 9\n([a-z])+(\n ^\n /([a-z])+(/;\n ^",
|
"message": "test.js:1:15 Unclosed group near index 9\n([a-z])+(\n /([a-z])+(/;\n ^",
|
||||||
"lineNumber": "1"
|
"lineNumber": "1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user