mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-11-26 22:00:25 +00:00
Merge
This commit is contained in:
commit
a8c5f1e59a
@ -527,8 +527,8 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
fi
|
||||
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fcheck-new"
|
||||
TOOLCHAIN_CFLAGS_JDK="-pipe"
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fcheck-new -fstack-protector"
|
||||
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!)
|
||||
|
||||
CXXSTD_CXXFLAG="-std=gnu++98"
|
||||
|
@ -56,7 +56,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBNET, \
|
||||
LIBS_solaris := -lnsl -lsocket $(LIBDL), \
|
||||
LIBS_aix := $(LIBDL),\
|
||||
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, \
|
||||
))
|
||||
|
||||
|
@ -9936,6 +9936,7 @@ instruct vmuladdadd4S2I_reg(vecD dst, vecD src1, vecD src2) %{
|
||||
__ evpdpwssd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector_len);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
ins_cost(10);
|
||||
%}
|
||||
|
||||
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);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
ins_cost(10);
|
||||
%}
|
||||
|
||||
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);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
ins_cost(10);
|
||||
%}
|
||||
|
||||
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);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
ins_cost(10);
|
||||
%}
|
||||
|
||||
// --------------------------------- PopCount --------------------------------------
|
||||
|
@ -168,9 +168,12 @@ void ciMethodData::load_extra_data() {
|
||||
// in the prepare_metadata call above) as we translate the copy:
|
||||
// update the copy as we go.
|
||||
int tag = dp_src->tag();
|
||||
if (tag != DataLayout::arg_info_data_tag) {
|
||||
memcpy(dp_dst, dp_src, ((intptr_t)MethodData::next_extra(dp_src)) - ((intptr_t)dp_src));
|
||||
size_t entry_size = DataLayout::header_size_in_bytes();
|
||||
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) {
|
||||
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
|
||||
|
||||
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 */);
|
||||
|
||||
if (!is_internal()) {
|
||||
|
@ -561,11 +561,6 @@ void ClassLoaderDataGraph::clean_module_and_package_info() {
|
||||
|
||||
ClassLoaderData* data = _head;
|
||||
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
|
||||
// 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
|
||||
|
@ -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
|
||||
void Dictionary::classes_do(void f(InstanceKlass*)) {
|
||||
for (int index = 0; index < table_size(); index++) {
|
||||
|
@ -74,9 +74,6 @@ public:
|
||||
|
||||
void unlink();
|
||||
|
||||
// Unload classes whose defining loaders are unloaded
|
||||
void do_unloading();
|
||||
|
||||
// Protection domains
|
||||
InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
|
||||
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);
|
||||
|
||||
// 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) {
|
||||
// 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
|
||||
// during compilations.
|
||||
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);
|
||||
if (sd_check == NULL) {
|
||||
dictionary->add_klass(d_hash, name, k);
|
||||
|
||||
notice_modification();
|
||||
}
|
||||
#ifdef ASSERT
|
||||
|
@ -50,7 +50,6 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym
|
||||
Klass* this_class = SystemDictionary::resolve_or_fail(
|
||||
name, Handle(THREAD, klass->class_loader()),
|
||||
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
||||
klass->class_loader_data()->record_dependency(this_class);
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
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(
|
||||
from_name, Handle(THREAD, klass->class_loader()),
|
||||
Handle(THREAD, klass->protection_domain()), true, CHECK_false);
|
||||
klass->class_loader_data()->record_dependency(from_class);
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
Verifier::trace_class_resolution(from_class, klass);
|
||||
}
|
||||
|
@ -2015,7 +2015,6 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
|
||||
true, THREAD);
|
||||
|
||||
if (kls != NULL) {
|
||||
current_class()->class_loader_data()->record_dependency(kls);
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
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.
|
||||
if (log_is_enabled(Debug, class, resolve)){
|
||||
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) {
|
||||
assert(invoke_code != Bytecodes::_invokevirtual &&
|
||||
invoke_code != Bytecodes::_invokeinterface, "");
|
||||
bool do_resolve = true;
|
||||
// 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
|
||||
// is executed.
|
||||
if (invoke_code != Bytecodes::_invokespecial || !sender_is_interface ||
|
||||
method->name() == vmSymbols::object_initializer_name()) {
|
||||
if (invoke_code == Bytecodes::_invokespecial && sender_is_interface &&
|
||||
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);
|
||||
}
|
||||
} 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
|
||||
// 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
|
||||
// updated by PhaseIdealLoop::update_skeleton_predicate()).
|
||||
// updated by PhaseIdealLoop::clone_skeleton_predicate()).
|
||||
ProjNode* PhaseIdealLoop::insert_skeleton_predicate(IfNode* iff, IdealLoopTree *loop,
|
||||
ProjNode* proj, ProjNode *predicate_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,
|
||||
// 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.
|
||||
void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* castii, IdealLoopTree* outer_loop,
|
||||
LoopNode* outer_main_head, uint dd_main_head) {
|
||||
void PhaseIdealLoop::duplicate_predicates_helper(Node* predicate, Node* start, Node* end,
|
||||
IdealLoopTree* outer_loop, LoopNode* outer_main_head,
|
||||
uint dd_main_head) {
|
||||
if (predicate != NULL) {
|
||||
IfNode* iff = predicate->in(0)->as_If();
|
||||
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)
|
||||
break;
|
||||
if (iff->in(1)->Opcode() == Op_Opaque4) {
|
||||
assert(skeleton_predicate_has_opaque(iff), "unexpected");
|
||||
// Clone the predicate twice and initialize one with the initial
|
||||
// value of the loop induction variable. Leave the other predicate
|
||||
// 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);
|
||||
Node* value = new Opaque1Node(C, castii);
|
||||
register_new_node(value, current_proj);
|
||||
prev_proj = update_skeleton_predicate(iff, value, 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);
|
||||
assert(skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()) == (start->Opcode() == Op_Opaque1), "");
|
||||
prev_proj = clone_skeleton_predicate(iff, end, 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
|
||||
_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,
|
||||
Node* current_proj, IdealLoopTree* outer_loop, Node* prev_proj) {
|
||||
bool clone = (outer_loop != NULL); // Clone the predicate?
|
||||
static bool skeleton_follow_inputs(Node* n, int op) {
|
||||
return (n->is_Bool() ||
|
||||
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);
|
||||
to_clone.push(iff->in(1), 1);
|
||||
uint current = C->unique();
|
||||
@ -1118,28 +1158,11 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
||||
uint i = to_clone.index();
|
||||
Node* m = n->in(i);
|
||||
int op = m->Opcode();
|
||||
if (m->is_Bool() ||
|
||||
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) {
|
||||
if (skeleton_follow_inputs(m, op)) {
|
||||
to_clone.push(m, 1);
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
n = n->clone();
|
||||
}
|
||||
@ -1161,20 +1184,17 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
||||
}
|
||||
Node* next = to_clone.node();
|
||||
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) {
|
||||
next = next->clone();
|
||||
register_new_node(next, current_proj);
|
||||
to_clone.set_node(next);
|
||||
}
|
||||
assert(next->in(j) != cur, "input should have been cloned");
|
||||
next->set_req(j, cur);
|
||||
}
|
||||
}
|
||||
} while (result == NULL);
|
||||
if (!clone) {
|
||||
return NULL;
|
||||
}
|
||||
assert(result->_idx >= current, "new node expected");
|
||||
|
||||
Node* proj = predicate->clone();
|
||||
@ -1197,8 +1217,9 @@ Node* PhaseIdealLoop::update_skeleton_predicate(Node* iff, Node* value, Node* pr
|
||||
return proj;
|
||||
}
|
||||
|
||||
void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* castii, IdealLoopTree* outer_loop,
|
||||
LoopNode* outer_main_head, uint dd_main_head) {
|
||||
void PhaseIdealLoop::duplicate_predicates(CountedLoopNode* pre_head, Node* start, Node* end,
|
||||
IdealLoopTree* outer_loop, LoopNode* outer_main_head,
|
||||
uint dd_main_head) {
|
||||
if (UseLoopPredicate) {
|
||||
Node* entry = pre_head->in(LoopNode::EntryControl);
|
||||
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);
|
||||
duplicate_predicates_helper(predicate, castii, 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(predicate, start, end, 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:
|
||||
Node* castii = cast_incr_before_loop( pre_incr, min_taken, main_head );
|
||||
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).
|
||||
// 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));
|
||||
}
|
||||
|
||||
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--------------------------------------
|
||||
// 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 &&
|
||||
(!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity");
|
||||
|
||||
if (UseLoopPredicate) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
update_skeleton_predicates(ctrl, loop_head, init, stride_con);
|
||||
|
||||
// Adjust loop limit to keep valid iterations number after unroll.
|
||||
// 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.
|
||||
Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
||||
Node* predicate_proj, int scale_con, Node* offset,
|
||||
Node* limit, jint stride_con) {
|
||||
Node* limit, jint stride_con, Node* value) {
|
||||
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));
|
||||
register_new_node(opaque_bol, predicate_proj);
|
||||
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 );
|
||||
// (0-offset)/scale could be outside of loop iterations range.
|
||||
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 {
|
||||
if (PrintOpto) {
|
||||
tty->print_cr("missed RCE opportunity");
|
||||
|
@ -747,12 +747,14 @@ private:
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
Node* update_skeleton_predicate(Node* iff, Node* value, Node* predicate = NULL, Node* uncommon_proj = NULL,
|
||||
Node* current_proj = NULL, IdealLoopTree* outer_loop = NULL, Node* prev_proj = NULL);
|
||||
Node* clone_skeleton_predicate(Node* iff, Node* value, Node* predicate, Node* uncommon_proj,
|
||||
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);
|
||||
|
||||
public:
|
||||
@ -1128,7 +1130,7 @@ public:
|
||||
Deoptimization::DeoptReason reason);
|
||||
Node* add_range_check_predicate(IdealLoopTree* loop, CountedLoopNode* cl,
|
||||
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
|
||||
void collect_potentially_useful_predicates(IdealLoopTree *loop, Unique_Node_List &predicate_opaque1);
|
||||
@ -1304,6 +1306,14 @@ private:
|
||||
bool identical_backtoback_ifs(Node *n);
|
||||
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;
|
||||
public:
|
||||
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));
|
||||
_igvn.replace_node(n, 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( C->live_nodes() > 35000 ) return n; // Method too big
|
||||
if (must_throttle_split_if()) return n;
|
||||
|
||||
// Split 'n' through the merge point if it is profitable
|
||||
Node *phi = split_thru_phi( n, n_blk, policy );
|
||||
@ -1143,9 +1148,10 @@ bool PhaseIdealLoop::identical_backtoback_ifs(Node *n) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PhaseIdealLoop::can_split_if(Node *n_ctrl) {
|
||||
if (C->live_nodes() > 35000) {
|
||||
return false; // Method too big
|
||||
|
||||
bool PhaseIdealLoop::can_split_if(Node* n_ctrl) {
|
||||
if (must_throttle_split_if()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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,
|
||||
// using basic block level info.
|
||||
void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
|
||||
Node *n = C->root();
|
||||
visited.set(n->_idx); // first, mark node as visited
|
||||
Node* root = C->root();
|
||||
visited.set(root->_idx); // first, mark root as visited
|
||||
// Do pre-visit work for root
|
||||
n = split_if_with_blocks_pre( n );
|
||||
uint cnt = n->outcnt();
|
||||
uint i = 0;
|
||||
Node* n = split_if_with_blocks_pre(root);
|
||||
uint cnt = n->outcnt();
|
||||
uint i = 0;
|
||||
|
||||
while (true) {
|
||||
// Visit all children
|
||||
if (i < cnt) {
|
||||
@ -1475,7 +1482,7 @@ void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack
|
||||
++i;
|
||||
if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
|
||||
// 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.
|
||||
n = use; // Process all children of current use.
|
||||
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.
|
||||
if (cnt != 0 && !n->is_Con()) {
|
||||
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()) {
|
||||
// Finished all nodes on stack.
|
||||
|
@ -1401,3 +1401,12 @@ const Type* FmaFNode::Value(PhaseGVN* phase) const {
|
||||
return TypeF::make(fma(f1, f2, f3));
|
||||
#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.
|
||||
// Semantics: I_OUT = S1 * S2 + S3 * S4
|
||||
class MulAddS2INode : public Node {
|
||||
virtual uint hash() const;
|
||||
public:
|
||||
MulAddS2INode(Node* in1, Node *in2, Node *in3, Node* in4) : Node(0, in1, in2, in3, in4) {}
|
||||
virtual int Opcode() const;
|
||||
|
@ -1445,7 +1445,7 @@ void SuperWord::order_def_uses(Node_List* p) {
|
||||
Node* t1 = s1->fast_out(i);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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())) {
|
||||
// Further analysis relies on operands position matching.
|
||||
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 {
|
||||
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);
|
||||
return true;
|
||||
|
@ -873,7 +873,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
|
||||
if (result != NULL) {
|
||||
oop mirror = JNIHandles::resolve_non_null(result);
|
||||
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) {
|
||||
|
@ -1376,6 +1376,14 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
|
||||
}
|
||||
#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:
|
||||
// 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
|
||||
|
@ -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.
|
||||
*
|
||||
* 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 java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Immutable, arbitrary-precision signed decimal numbers. A
|
||||
@ -424,9 +425,14 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
||||
* @since 1.5
|
||||
*/
|
||||
public BigDecimal(char[] in, int offset, int len, MathContext mc) {
|
||||
// protect against huge length.
|
||||
if (offset + len > in.length || offset < 0)
|
||||
throw new NumberFormatException("Bad offset or len arguments for char[] input.");
|
||||
// protect against huge length, negative values, and integer overflow
|
||||
try {
|
||||
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
|
||||
// incoming strings end up here; it uses explicit (inline)
|
||||
// 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) {
|
||||
if (val.length == 0) {
|
||||
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) {
|
||||
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) {
|
||||
if (signum < -1 || signum > 1) {
|
||||
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
|
||||
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);
|
||||
|
||||
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++) {
|
||||
int[] magnitude = new int[1];
|
||||
magnitude[0] = i;
|
||||
@ -1562,6 +1564,18 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
* @return {@code this * 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)
|
||||
return ZERO;
|
||||
|
||||
@ -1589,6 +1603,63 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
if ((xlen < TOOM_COOK_THRESHOLD) && (ylen < TOOM_COOK_THRESHOLD)) {
|
||||
return multiplyKaratsuba(this, val);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
@ -1674,7 +1745,7 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
int ystart = ylen - 1;
|
||||
|
||||
if (z == null || z.length < (xlen+ ylen))
|
||||
z = new int[xlen+ylen];
|
||||
z = new int[xlen+ylen];
|
||||
|
||||
long carry = 0;
|
||||
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;
|
||||
|
||||
v0 = a0.multiply(b0);
|
||||
v0 = a0.multiply(b0, true);
|
||||
da1 = a2.add(a0);
|
||||
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);
|
||||
db1 = db1.add(b1);
|
||||
v1 = da1.multiply(db1);
|
||||
v1 = da1.multiply(db1, true);
|
||||
v2 = da1.add(a2).shiftLeft(1).subtract(a0).multiply(
|
||||
db1.add(b2).shiftLeft(1).subtract(b0));
|
||||
vinf = a2.multiply(b2);
|
||||
db1.add(b2).shiftLeft(1).subtract(b0), true);
|
||||
vinf = a2.multiply(b2, true);
|
||||
|
||||
// The algorithm requires two divisions by 2 and one by 3.
|
||||
// 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>}
|
||||
*/
|
||||
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) {
|
||||
return ZERO;
|
||||
}
|
||||
@ -1995,6 +2077,15 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
if (len < TOOM_COOK_SQUARE_THRESHOLD) {
|
||||
return squareKaratsuba();
|
||||
} else {
|
||||
//
|
||||
// For a discussion of overflow detection see multiply()
|
||||
//
|
||||
if (!isRecursion) {
|
||||
if (bitLength(mag, mag.length) > 16L*MAX_MAG_LENGTH) {
|
||||
reportOverflow();
|
||||
}
|
||||
}
|
||||
|
||||
return squareToomCook3();
|
||||
}
|
||||
}
|
||||
@ -2146,13 +2237,13 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
a0 = getToomSlice(k, r, 2, len);
|
||||
BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1;
|
||||
|
||||
v0 = a0.square();
|
||||
v0 = a0.square(true);
|
||||
da1 = a2.add(a0);
|
||||
vm1 = da1.subtract(a1).square();
|
||||
vm1 = da1.subtract(a1).square(true);
|
||||
da1 = da1.add(a1);
|
||||
v1 = da1.square();
|
||||
vinf = a2.square();
|
||||
v2 = da1.add(a2).shiftLeft(1).subtract(a0).square();
|
||||
v1 = da1.square(true);
|
||||
vinf = a2.square(true);
|
||||
v2 = da1.add(a2).shiftLeft(1).subtract(a0).square(true);
|
||||
|
||||
// The algorithm requires two divisions by 2 and one by 3.
|
||||
// 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
|
||||
// powers of two will be multiplied back at the end.
|
||||
int powersOfTwo = partToSquare.getLowestSetBit();
|
||||
long bitsToShift = (long)powersOfTwo * exponent;
|
||||
if (bitsToShift > Integer.MAX_VALUE) {
|
||||
long bitsToShiftLong = (long)powersOfTwo * exponent;
|
||||
if (bitsToShiftLong > Integer.MAX_VALUE) {
|
||||
reportOverflow();
|
||||
}
|
||||
int bitsToShift = (int)bitsToShiftLong;
|
||||
|
||||
int remainingBits;
|
||||
|
||||
@ -2336,9 +2428,9 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
remainingBits = partToSquare.bitLength();
|
||||
if (remainingBits == 1) { // Nothing left but +/- 1?
|
||||
if (signum < 0 && (exponent&1) == 1) {
|
||||
return NEGATIVE_ONE.shiftLeft(powersOfTwo*exponent);
|
||||
return NEGATIVE_ONE.shiftLeft(bitsToShift);
|
||||
} else {
|
||||
return ONE.shiftLeft(powersOfTwo*exponent);
|
||||
return ONE.shiftLeft(bitsToShift);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2383,13 +2475,16 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
||||
if (bitsToShift + scaleFactor <= 62) { // Fits in long?
|
||||
return valueOf((result << bitsToShift) * newSign);
|
||||
} else {
|
||||
return valueOf(result*newSign).shiftLeft((int) bitsToShift);
|
||||
return valueOf(result*newSign).shiftLeft(bitsToShift);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return valueOf(result*newSign);
|
||||
}
|
||||
} else {
|
||||
if ((long)bitLength() * exponent / Integer.SIZE > MAX_MAG_LENGTH) {
|
||||
reportOverflow();
|
||||
}
|
||||
|
||||
// Large number algorithm. This is basically identical to
|
||||
// the algorithm above, but calls multiply() and square()
|
||||
// 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,
|
||||
// by shifting left)
|
||||
if (powersOfTwo > 0) {
|
||||
answer = answer.shiftLeft(powersOfTwo*exponent);
|
||||
answer = answer.shiftLeft(bitsToShift);
|
||||
}
|
||||
|
||||
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++)
|
||||
pow2 = (mag[i] == 0);
|
||||
|
||||
n = (pow2 ? magBitLength -1 : magBitLength);
|
||||
n = (pow2 ? magBitLength - 1 : magBitLength);
|
||||
} else {
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
if ((src == null) ||(len < 0) || (offset < 0)
|
||||
|| ((len + offset) > src.length)) {
|
||||
|| (len > (src.length - offset))) {
|
||||
throw new IllegalArgumentException("Invalid buffer arguments");
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,7 @@ import java.net.URL;
|
||||
* credentials without prompting) should only be tried with trusted sites.
|
||||
*/
|
||||
public abstract class NTLMAuthenticationCallback {
|
||||
private static volatile NTLMAuthenticationCallback callback =
|
||||
new DefaultNTLMAuthenticationCallback();
|
||||
private static volatile NTLMAuthenticationCallback callback;
|
||||
|
||||
public static void setNTLMAuthenticationCallback(
|
||||
NTLMAuthenticationCallback callback) {
|
||||
@ -50,10 +49,5 @@ public abstract class NTLMAuthenticationCallback {
|
||||
* transparent Authentication.
|
||||
*/
|
||||
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
|
||||
int c = Math.min(icount, TRANSFER_SIZE);
|
||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(c);
|
||||
ByteBuffer bb = ByteBuffer.allocate(c);
|
||||
long tw = 0; // Total bytes written
|
||||
long pos = position;
|
||||
try {
|
||||
Util.erase(bb);
|
||||
while (tw < icount) {
|
||||
bb.limit(Math.min((int)(icount - tw), TRANSFER_SIZE));
|
||||
int nr = read(bb, pos);
|
||||
@ -649,8 +648,6 @@ public class FileChannelImpl
|
||||
if (tw > 0)
|
||||
return tw;
|
||||
throw x;
|
||||
} finally {
|
||||
Util.releaseTemporaryDirectBuffer(bb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,11 +731,10 @@ public class FileChannelImpl
|
||||
{
|
||||
// Untrusted target: Use a newly-erased buffer
|
||||
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 pos = position;
|
||||
try {
|
||||
Util.erase(bb);
|
||||
while (tw < count) {
|
||||
bb.limit((int)Math.min((count - tw), (long)TRANSFER_SIZE));
|
||||
// ## Bug: Will block reading src if this channel
|
||||
@ -759,8 +755,6 @@ public class FileChannelImpl
|
||||
if (tw > 0)
|
||||
return tw;
|
||||
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.
|
||||
# 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
|
||||
#
|
||||
#
|
||||
# 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
|
||||
* transparent Authentication.
|
||||
* transparent Authentication. Shouldn't be called since
|
||||
* capability not supported on Unix
|
||||
*/
|
||||
public static boolean isTrustedSite(URL url) {
|
||||
return NTLMAuthCallback.isTrustedSite(url);
|
||||
if (NTLMAuthCallback != null)
|
||||
return NTLMAuthCallback.isTrustedSite(url);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void init0() {
|
||||
|
@ -584,6 +584,8 @@ static void initLoopbackRoutes() {
|
||||
|
||||
if (loRoutesTemp == 0) {
|
||||
free(loRoutes);
|
||||
loRoutes = NULL;
|
||||
nRoutes = 0;
|
||||
fclose (f);
|
||||
return;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import java.net.UnknownHostException;
|
||||
import java.net.URL;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import sun.net.NetProperties;
|
||||
import sun.net.www.HeaderParser;
|
||||
import sun.net.www.protocol.http.AuthenticationInfo;
|
||||
import sun.net.www.protocol.http.AuthScheme;
|
||||
@ -56,11 +57,33 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
||||
private static final String defaultDomain;
|
||||
/* Whether cache is enabled for NTLM */
|
||||
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 {
|
||||
Properties props = GetPropertyAction.privilegedGetProperties();
|
||||
defaultDomain = props.getProperty("http.auth.ntlm.domain", "domain");
|
||||
String ntlmCacheProp = props.getProperty("jdk.ntlm.cache", "true");
|
||||
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() {
|
||||
@ -166,9 +189,21 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
||||
* transparent Authentication.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -218,5 +253,4 @@ public class NTLMAuthentication extends AuthenticationInfo {
|
||||
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
|
||||
curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
|
||||
} 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);
|
||||
@ -316,7 +316,7 @@ int enumInterfaces(JNIEnv *env, netif **netifPP)
|
||||
free(curr);
|
||||
return -1;
|
||||
} else {
|
||||
curr->displayName[wlen*(sizeof(wchar_t))] = '\0';
|
||||
((wchar_t *)curr->displayName)[wlen] = L'\0';
|
||||
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.
|
||||
*
|
||||
* 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);
|
||||
struct iovec *iovp = (struct iovec *)address;
|
||||
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
||||
if (bufs == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
/* copy iovec into WSABUF */
|
||||
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);
|
||||
struct iovec *iovp = (struct iovec *)address;
|
||||
WSABUF *bufs = malloc(len * sizeof(WSABUF));
|
||||
if (bufs == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return IOS_THROWN;
|
||||
}
|
||||
|
||||
/* copy iovec into WSABUF */
|
||||
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.
|
||||
*
|
||||
* 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 */
|
||||
if (bytesToRead > WAKEUP_SOCKET_BUF_SIZE) {
|
||||
char* buf = (char*)malloc(bytesToRead);
|
||||
if (buf == NULL) {
|
||||
JNU_ThrowOutOfMemoryError(env, NULL);
|
||||
return;
|
||||
}
|
||||
recv(scinFd, buf, bytesToRead, 0);
|
||||
free(buf);
|
||||
} else {
|
||||
|
@ -394,6 +394,7 @@ public class Robot {
|
||||
* @return Color of the pixel
|
||||
*/
|
||||
public synchronized Color getPixelColor(int x, int y) {
|
||||
checkScreenCaptureAllowed();
|
||||
AffineTransform tx = GraphicsEnvironment.
|
||||
getLocalGraphicsEnvironment().getDefaultScreenDevice().
|
||||
getDefaultConfiguration().getDefaultTransform();
|
||||
|
@ -406,6 +406,9 @@ alloc_sarray (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION rowsperchunk, currow, i;
|
||||
long ltemp;
|
||||
|
||||
if (samplesperrow == 0) {
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
}
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
((long) samplesperrow * SIZEOF(JSAMPLE));
|
||||
@ -454,6 +457,10 @@ alloc_barray (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION rowsperchunk, currow, i;
|
||||
long ltemp;
|
||||
|
||||
if (blocksperrow == 0) {
|
||||
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
|
||||
}
|
||||
|
||||
/* Calculate max # of rows allowed in one allocation chunk */
|
||||
ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
|
||||
((long) blocksperrow * SIZEOF(JBLOCK));
|
||||
|
@ -1535,10 +1535,16 @@ void AllocateDataSet(cmsIT8* it8)
|
||||
t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
|
||||
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->Data == NULL) {
|
||||
if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* 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;
|
||||
char *stock_id_str = NULL;
|
||||
char *detail_str = NULL;
|
||||
jboolean result = JNI_FALSE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!init_method(env, this) ) {
|
||||
free(stock_id_str);
|
||||
if (detail_str != NULL) {
|
||||
free(detail_str);
|
||||
}
|
||||
return JNI_FALSE;
|
||||
if (init_method(env, this)) {
|
||||
result = gtk->get_icon_data(env, widget_type, stock_id_str,
|
||||
icon_size, text_direction, detail_str,
|
||||
icon_upcall_method, this);
|
||||
}
|
||||
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. */
|
||||
free(stock_id_str);
|
||||
if (detail_str != NULL)
|
||||
{
|
||||
free(detail_str);
|
||||
}
|
||||
free(detail_str);
|
||||
|
||||
return result;
|
||||
#else /* HEADLESS */
|
||||
return JNI_FALSE;
|
||||
|
@ -962,9 +962,10 @@ Java_sun_print_Win32PrintService_getDefaultSettings(JNIEnv *env,
|
||||
if (!present) {
|
||||
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
|
||||
|
@ -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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -50,6 +51,10 @@ char* basePath(const char* path) {
|
||||
} else {
|
||||
int len = last - path;
|
||||
char* str = (char*)malloc(len+1);
|
||||
if (str == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
if (len > 0) {
|
||||
memcpy(str, path, len);
|
||||
}
|
||||
@ -80,6 +85,10 @@ static char* normalizePath(const char* pathname, int len, int off) {
|
||||
if (n == 0) return strdup("/");
|
||||
|
||||
sb = (char*)malloc(strlen(pathname)+1);
|
||||
if (sb == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
sbLen = 0;
|
||||
|
||||
if (off > 0) {
|
||||
@ -128,6 +137,10 @@ char* resolve(const char* parent, const char* child) {
|
||||
len = parentEnd + cn - childStart;
|
||||
if (child[0] == slash) {
|
||||
theChars = (char*)malloc(len+1);
|
||||
if (theChars == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
if (parentEnd > 0)
|
||||
memcpy(theChars, parent, parentEnd);
|
||||
if (cn > 0)
|
||||
@ -135,6 +148,10 @@ char* resolve(const char* parent, const char* child) {
|
||||
theChars[len] = '\0';
|
||||
} else {
|
||||
theChars = (char*)malloc(len+2);
|
||||
if (theChars == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
if (parentEnd > 0)
|
||||
memcpy(theChars, parent, parentEnd);
|
||||
theChars[parentEnd] = slash;
|
||||
@ -150,10 +167,13 @@ char* fromURIPath(const char* path) {
|
||||
if (len > 1 && path[len-1] == slash) {
|
||||
// "/foo/" --> "/foo", but "/" --> "/"
|
||||
char* str = (char*)malloc(len);
|
||||
if (str != NULL) {
|
||||
memcpy(str, path, len-1);
|
||||
str[len-1] = '\0';
|
||||
if (str == NULL)
|
||||
{
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(str, path, len-1);
|
||||
str[len-1] = '\0';
|
||||
return str;
|
||||
} else {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,6 +23,7 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
@ -66,6 +67,10 @@ char* basePath(const char* path) {
|
||||
} else {
|
||||
int len = (int)(last - path);
|
||||
char* str = (char*)malloc(len+1);
|
||||
if (str == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
if (len > 0) {
|
||||
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 */
|
||||
|
||||
sb = (char*)malloc(len+1);
|
||||
if (sb == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
sbLen = 0;
|
||||
|
||||
if (off == 0) {
|
||||
@ -261,11 +270,19 @@ char* resolve(const char* parent, const char* child) {
|
||||
|
||||
if (child[childStart] == slash) {
|
||||
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+parentEnd, child+childStart, (cn-childStart));
|
||||
theChars[len] = '\0';
|
||||
} else {
|
||||
theChars = (char*)malloc(len+2);
|
||||
if (theChars == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(theChars, parent, parentEnd);
|
||||
theChars[parentEnd] = slash;
|
||||
memcpy(theChars+parentEnd+1, child+childStart, (cn-childStart));
|
||||
@ -320,10 +337,12 @@ char* fromURIPath(const char* path) {
|
||||
return (char*)path;
|
||||
} else {
|
||||
char* p = (char*)malloc(len+1);
|
||||
if (p != NULL) {
|
||||
memcpy(p, path+start, len);
|
||||
p[len] = '\0';
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "OOM error in native tmp buffer allocation");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(p, path+start, len);
|
||||
p[len] = '\0';
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ BOOL native_debug = 0;
|
||||
|
||||
BOOL PackageConnectLookup(PHANDLE,PULONG);
|
||||
|
||||
NTSTATUS ConstructTicketRequest(UNICODE_STRING DomainName,
|
||||
NTSTATUS ConstructTicketRequest(JNIEnv *env,
|
||||
UNICODE_STRING DomainName,
|
||||
PKERB_RETRIEVE_TKT_REQUEST *outRequest,
|
||||
ULONG *outSize);
|
||||
|
||||
@ -104,6 +105,8 @@ jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey);
|
||||
jobject BuildTicketFlags(JNIEnv *env, PULONG flags);
|
||||
jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime);
|
||||
|
||||
void ThrowOOME(JNIEnv *env, const char *szMessage);
|
||||
|
||||
/*
|
||||
* Class: sun_security_krb5_KrbCreds
|
||||
* Method: JNI_OnLoad
|
||||
@ -497,7 +500,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
|
||||
}
|
||||
|
||||
// use domain to request Ticket
|
||||
Status = ConstructTicketRequest(msticket->TargetDomainName,
|
||||
Status = ConstructTicketRequest(env, msticket->TargetDomainName,
|
||||
&pTicketRequest, &requestSize);
|
||||
if (!LSA_SUCCESS(Status)) {
|
||||
ShowNTError("ConstructTicketRequest status", Status);
|
||||
@ -691,7 +694,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
ConstructTicketRequest(UNICODE_STRING DomainName,
|
||||
ConstructTicketRequest(JNIEnv *env, UNICODE_STRING DomainName,
|
||||
PKERB_RETRIEVE_TKT_REQUEST *outRequest, ULONG *outSize)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
@ -738,8 +741,10 @@ ConstructTicketRequest(UNICODE_STRING DomainName,
|
||||
|
||||
pTicketRequest = (PKERB_RETRIEVE_TKT_REQUEST)
|
||||
LocalAlloc(LMEM_ZEROINIT, RequestSize);
|
||||
if (!pTicketRequest)
|
||||
if (!pTicketRequest) {
|
||||
ThrowOOME(env, "Can't allocate memory for ticket");
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
//
|
||||
// Concatenate the target prefix with the previous response's
|
||||
@ -896,7 +901,7 @@ jobject BuildTicket(JNIEnv *env, PUCHAR encodedTicket, ULONG encodedTicketSize)
|
||||
jbyteArray ary;
|
||||
|
||||
ary = (*env)->NewByteArray(env,encodedTicketSize);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
if (ary == NULL) {
|
||||
return (jobject) NULL;
|
||||
}
|
||||
|
||||
@ -942,6 +947,10 @@ jobject BuildPrincipal(JNIEnv *env, PKERB_EXTERNAL_NAME principalName,
|
||||
|
||||
realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT,
|
||||
((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));
|
||||
|
||||
if (native_debug) {
|
||||
@ -1016,6 +1025,9 @@ jobject BuildEncryptionKey(JNIEnv *env, PKERB_CRYPTO_KEY cryptoKey) {
|
||||
}
|
||||
|
||||
ary = (*env)->NewByteArray(env,cryptoKey->Length);
|
||||
if (ary == NULL) {
|
||||
return (jobject) NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, cryptoKey->Length,
|
||||
(jbyte *)cryptoKey->Value);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
@ -1038,6 +1050,9 @@ jobject BuildTicketFlags(JNIEnv *env, PULONG flags) {
|
||||
ULONG nlflags = htonl(*flags);
|
||||
|
||||
ary = (*env)->NewByteArray(env, sizeof(*flags));
|
||||
if (ary == NULL) {
|
||||
return (jobject) NULL;
|
||||
}
|
||||
(*env)->SetByteArrayRegion(env, ary, (jsize) 0, sizeof(*flags),
|
||||
(jbyte *)&nlflags);
|
||||
if ((*env)->ExceptionOccurred(env)) {
|
||||
@ -1090,3 +1105,10 @@ jobject BuildKerberosTime(JNIEnv *env, PLARGE_INTEGER kerbtime) {
|
||||
}
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,6 +32,7 @@
|
||||
#include "AccessBridgePackages.h" // for debugging only
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
#include <new>
|
||||
|
||||
DEBUG_CODE(extern HWND theDialogWindow);
|
||||
extern "C" {
|
||||
@ -46,6 +47,9 @@ AccessBridgeQueueElement::AccessBridgeQueueElement(char *buf, int size) {
|
||||
next = (AccessBridgeQueueElement *) 0;
|
||||
previous = (AccessBridgeQueueElement *) 0;
|
||||
buffer = (char *) malloc(bufsize);
|
||||
if (buffer == NULL) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
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.
|
||||
@ -75,18 +75,20 @@
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
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;
|
||||
CK_C_GetFunctionList C_GetFunctionList;
|
||||
CK_RV rv;
|
||||
CK_RV rv = CK_ASSERT_OK;
|
||||
ModuleData *moduleData;
|
||||
jobject globalPKCS11ImplementationReference;
|
||||
LPVOID lpMsgBuf;
|
||||
char *exceptionMessage;
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
char *exceptionMessage = NULL;
|
||||
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);
|
||||
|
||||
|
||||
@ -106,21 +108,24 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
0,
|
||||
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);
|
||||
strcat(exceptionMessage, libraryNameStr);
|
||||
throwIOException(env, (LPTSTR) exceptionMessage);
|
||||
/* Free the buffer. */
|
||||
free(exceptionMessage);
|
||||
LocalFree(lpMsgBuf);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get function pointer to C_GetFunctionList
|
||||
*/
|
||||
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);
|
||||
if (C_GetFunctionList == NULL) {
|
||||
FormatMessage(
|
||||
@ -135,24 +140,37 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
NULL
|
||||
);
|
||||
throwIOException(env, (LPTSTR) lpMsgBuf);
|
||||
/* Free the buffer. */
|
||||
LocalFree( lpMsgBuf );
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get function pointers to all PKCS #11 functions
|
||||
*/
|
||||
moduleData = (ModuleData *) malloc(sizeof(ModuleData));
|
||||
if (moduleData == NULL) {
|
||||
throwOutOfMemoryError(env, 0);
|
||||
goto cleanup;
|
||||
}
|
||||
moduleData->hModule = hModule;
|
||||
moduleData->applicationMutexHandler = NULL;
|
||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
|
||||
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
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; }
|
||||
}
|
||||
|
||||
|
@ -754,7 +754,8 @@ abstract class CKeyStore extends KeyStoreSpi {
|
||||
new KeyEntry(alias, null, certChain));
|
||||
} catch (Throwable e) {
|
||||
// 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));
|
||||
} catch (Throwable e) {
|
||||
// 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);
|
||||
} catch (CertificateException e) {
|
||||
// Ignore the exception and skip this certificate
|
||||
// TODO - throw CertificateException?
|
||||
} catch (Throwable te) {
|
||||
// If e is thrown, remember to deal with it in
|
||||
// native code.
|
||||
}
|
||||
catch (Throwable te)
|
||||
{
|
||||
// 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
|
||||
jobject jArrayList =
|
||||
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++)
|
||||
{
|
||||
@ -582,6 +591,9 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
|
||||
|
||||
// Allocate and populate byte array
|
||||
jbyteArray byteArray = env->NewByteArray(cbCertEncoded);
|
||||
if (byteArray == NULL) {
|
||||
__leave;
|
||||
}
|
||||
env->SetByteArrayRegion(byteArray, 0, cbCertEncoded,
|
||||
(jbyte*) pbCertEncoded);
|
||||
|
||||
@ -590,49 +602,67 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC
|
||||
env->CallVoidMethod(obj, mGenCert, byteArray, jArrayList);
|
||||
}
|
||||
|
||||
PP("%s: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
|
||||
if (bHasNoPrivateKey)
|
||||
// Usually pszNameString should be non-NULL. It's either
|
||||
// the friendly name or an element from the subject name
|
||||
// or SAN.
|
||||
if (pszNameString)
|
||||
{
|
||||
// Generate certificate chain and store into cert chain
|
||||
// collection
|
||||
env->CallVoidMethod(obj, mGenCertChain,
|
||||
env->NewStringUTF(pszNameString),
|
||||
jArrayList);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
PP("%s: %s", pszNameString, pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
|
||||
if (bHasNoPrivateKey)
|
||||
{
|
||||
// Generate certificate chain and store into cert chain
|
||||
// collection
|
||||
jstring name = env->NewStringUTF(pszNameString);
|
||||
if (name == NULL) {
|
||||
__leave;
|
||||
}
|
||||
} 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)) {
|
||||
env->CallVoidMethod(obj, mGenCertChain,
|
||||
name,
|
||||
jArrayList);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
jstring name = env->NewStringUTF(pszNameString);
|
||||
if (name == NULL) {
|
||||
__leave;
|
||||
}
|
||||
env->CallVoidMethod(obj, mGenKeyAndCertChain,
|
||||
0,
|
||||
env->NewStringUTF(pszNameString),
|
||||
(jlong) hCryptProv, 0,
|
||||
dwPublicKeyLength, jArrayList);
|
||||
1,
|
||||
name,
|
||||
(jlong) hCryptProv, (jlong) hUserKey,
|
||||
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
|
||||
jbyteArray temp = env->NewByteArray(dwBufLen);
|
||||
if (temp == NULL) {
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Copy data from native buffer
|
||||
env->SetByteArrayRegion(temp, 0, dwBufLen, pSignedHashBuffer);
|
||||
@ -900,6 +933,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signCngHash
|
||||
|
||||
// Create new byte array
|
||||
jbyteArray temp = env->NewByteArray(jSignedHashSize);
|
||||
if (temp == NULL) {
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Copy data from native buffer
|
||||
env->SetByteArrayRegion(temp, 0, jSignedHashSize, pSignedHashBuffer);
|
||||
@ -1417,6 +1453,9 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_storeCertificate
|
||||
}
|
||||
|
||||
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
|
||||
if (jCertAliasChars == NULL) {
|
||||
__leave;
|
||||
}
|
||||
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
|
||||
pszCertAliasName[size] = 0; // append the string terminator
|
||||
|
||||
@ -1847,7 +1886,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CRSACipher_encryptDecrypt
|
||||
}
|
||||
|
||||
// Create new byte array
|
||||
result = env->NewByteArray(dwBufLen);
|
||||
if ((result = env->NewByteArray(dwBufLen)) == NULL) {
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Copy data from native buffer to Java buffer
|
||||
env->SetByteArrayRegion(result, 0, dwBufLen, (jbyte*) pData);
|
||||
@ -1910,7 +1951,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_getPublicKeyBlo
|
||||
}
|
||||
|
||||
// Create new byte array
|
||||
blob = env->NewByteArray(dwBlobLen);
|
||||
if ((blob = env->NewByteArray(dwBlobLen)) == NULL) {
|
||||
__leave;
|
||||
}
|
||||
|
||||
// Copy data from native buffer to Java buffer
|
||||
env->SetByteArrayRegion(blob, 0, dwBlobLen, (jbyte*) pbKeyBlob);
|
||||
@ -1939,6 +1982,13 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
||||
__try {
|
||||
|
||||
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) {
|
||||
__leave;
|
||||
}
|
||||
@ -1965,7 +2015,9 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
||||
exponentBytes[i] = ((BYTE*) &pRsaPubKey->pubexp)[j];
|
||||
}
|
||||
|
||||
exponent = env->NewByteArray(len);
|
||||
if ((exponent = env->NewByteArray(len)) == NULL) {
|
||||
__leave;
|
||||
}
|
||||
env->SetByteArrayRegion(exponent, 0, len, exponentBytes);
|
||||
}
|
||||
__finally
|
||||
@ -1995,6 +2047,13 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
||||
__try {
|
||||
|
||||
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) {
|
||||
__leave;
|
||||
}
|
||||
@ -2011,19 +2070,25 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CPublicKey_00024CRSAPublic
|
||||
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
|
||||
|
||||
int len = pRsaPubKey->bitlen / 8;
|
||||
if (len < 0 || len > length - headerLength) {
|
||||
ThrowExceptionWithMessage(env, KEY_EXCEPTION, "Invalid key length");
|
||||
__leave;
|
||||
}
|
||||
|
||||
modulusBytes = new (env) jbyte[len];
|
||||
if (modulusBytes == NULL) {
|
||||
__leave;
|
||||
}
|
||||
BYTE * pbModulus =
|
||||
(BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
|
||||
BYTE * pbModulus = (BYTE *) (keyBlob + headerLength);
|
||||
|
||||
// convert from little-endian while copying from blob
|
||||
for (int i = 0, j = len - 1; i < len; i++, j--) {
|
||||
modulusBytes[i] = pbModulus[j];
|
||||
}
|
||||
|
||||
modulus = env->NewByteArray(len);
|
||||
if ((modulus = env->NewByteArray(len)) == NULL) {
|
||||
__leave;
|
||||
}
|
||||
env->SetByteArrayRegion(modulus, 0, len, modulusBytes);
|
||||
}
|
||||
__finally
|
||||
@ -2240,7 +2305,9 @@ jbyteArray generateKeyBlob(
|
||||
}
|
||||
}
|
||||
|
||||
jBlob = env->NewByteArray(jBlobLength);
|
||||
if ((jBlob = env->NewByteArray(jBlobLength)) == NULL) {
|
||||
__leave;
|
||||
}
|
||||
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;
|
||||
|
||||
public void testLongExactOverflowSnippet(long input) {
|
||||
@ -138,4 +178,44 @@ public class IntegerExactExceptionTest extends GraalCompilerTest {
|
||||
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.IntegerExactArithmeticSplitNode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
@Ignore
|
||||
@RunWith(Parameterized.class)
|
||||
public class IntegerExactFoldTest extends GraalCompilerTest {
|
||||
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) {
|
||||
if (b.needsExplicitException()) {
|
||||
private static boolean createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) {
|
||||
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;
|
||||
AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind);
|
||||
IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op));
|
||||
split.setNext(b.add(new BeginNode()));
|
||||
} else {
|
||||
SpeculationLog log = b.getGraph().getSpeculationLog();
|
||||
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);
|
||||
}
|
||||
if (exceptionEdge != null) {
|
||||
IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op));
|
||||
split.setNext(b.add(new BeginNode()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,8 +585,7 @@ public class StandardGraphBuilderPlugins {
|
||||
@Override
|
||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
||||
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT);
|
||||
return true;
|
||||
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT);
|
||||
}
|
||||
});
|
||||
|
||||
@ -601,33 +593,29 @@ public class StandardGraphBuilderPlugins {
|
||||
@Override
|
||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) {
|
||||
ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1));
|
||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT);
|
||||
return true;
|
||||
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT);
|
||||
}
|
||||
});
|
||||
|
||||
r.register2("addExact", type, type, new InvocationPlugin() {
|
||||
@Override
|
||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT);
|
||||
return true;
|
||||
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT);
|
||||
}
|
||||
});
|
||||
|
||||
r.register2("subtractExact", type, type, new InvocationPlugin() {
|
||||
@Override
|
||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT);
|
||||
return true;
|
||||
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT);
|
||||
}
|
||||
});
|
||||
|
||||
r.register2("multiplyExact", type, type, new InvocationPlugin() {
|
||||
@Override
|
||||
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
|
||||
createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT);
|
||||
return true;
|
||||
}
|
||||
return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.DocPaths;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Writes a file that tries to redirect to an alternate page.
|
||||
* 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.
|
||||
*
|
||||
* 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.DocumentationTool;
|
||||
|
||||
import com.sun.tools.javac.code.Flags;
|
||||
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import jdk.javadoc.doclet.Reporter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
@ -276,6 +278,12 @@ public class Extern {
|
||||
ModuleElement moduleElement = utils.containingModule(packageElement);
|
||||
Map<String, Item> pkgMap = packageItems.get(utils.getModuleName(moduleElement));
|
||||
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;
|
||||
}
|
||||
@ -420,12 +428,25 @@ public class Extern {
|
||||
path), null);
|
||||
}
|
||||
} else if (moduleName == null) {
|
||||
throw new Fault(resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage",
|
||||
path), null);
|
||||
// suppress the error message in the case of automatic modules
|
||||
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) {
|
||||
try {
|
||||
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/loopopts/PeelingZeroTripCount.java 8216135 generic-all
|
||||
|
||||
#############################################################################
|
||||
|
||||
# :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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6362557
|
||||
* @bug 6362557 8200698
|
||||
* @summary Some tests of add(BigDecimal, mc)
|
||||
* @author Joseph D. Darcy
|
||||
*/
|
||||
@ -290,12 +290,35 @@ public class AddTests {
|
||||
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[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += extremaTests();
|
||||
failures += roundingGradationTests();
|
||||
failures += precisionConsistencyTest();
|
||||
failures += arithmeticExceptionTest();
|
||||
|
||||
if (failures > 0) {
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,20 +23,48 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4259453
|
||||
* @summary Test string constructor of BigDecimal
|
||||
* @bug 4259453 8200698
|
||||
* @summary Test constructors of BigDecimal
|
||||
* @library ..
|
||||
* @run testng Constructor
|
||||
*/
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class Constructor {
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean nfe = false;
|
||||
@Test(expectedExceptions=NumberFormatException.class)
|
||||
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 {
|
||||
BigDecimal bd = new BigDecimal("1.2e");
|
||||
} catch (NumberFormatException e) {
|
||||
nfe = true;
|
||||
BigDecimal bd = new BigDecimal(new char[5], Integer.MAX_VALUE - 5,
|
||||
6, null);
|
||||
} 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",
|
||||
"kind": "ERROR",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user