Skip to content
Permalink
Browse files
Merge
  • Loading branch information
prsadhuk committed Mar 3, 2020
2 parents 65bf618 + c42de93 commit 26a7b0dddd562ba4b45b6a504f020e54606bcc44
Showing with 1,008 additions and 298 deletions.
  1. +2 −1 make/test/JtregNativeHotspot.gmk
  2. +18 −43 src/hotspot/share/classfile/systemDictionary.cpp
  3. +8 −15 src/hotspot/share/oops/method.cpp
  4. +2 −2 src/hotspot/share/opto/loopUnswitch.cpp
  5. +15 −15 src/hotspot/share/opto/loopnode.cpp
  6. +71 −38 src/hotspot/share/opto/superword.cpp
  7. +4 −0 src/hotspot/share/opto/superword.hpp
  8. +32 −8 src/hotspot/share/prims/jni.cpp
  9. +20 −55 src/hotspot/share/runtime/reflection.cpp
  10. +54 −3 src/hotspot/share/runtime/signature.cpp
  11. +46 −0 src/hotspot/share/runtime/signature.hpp
  12. +65 −1 src/java.base/share/classes/java/util/UUID.java
  13. +0 −4 src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Secmod.java
  14. +2 −2 test/hotspot/gtest/oops/test_oop.cpp
  15. +70 −0 test/hotspot/jtreg/compiler/loopopts/superword/CoLocatePackMemoryState.java
  16. +3 −2 test/hotspot/jtreg/runtime/Metaspace/FragmentMetaspace.java
  17. +73 −0 test/hotspot/jtreg/runtime/jni/atExit/TestAtExit.java
  18. +113 −0 test/hotspot/jtreg/runtime/jni/atExit/libatExit.c
  19. +0 −94 test/hotspot/jtreg/runtime/logging/loadLibraryTest/LoadLibrary.java
  20. +96 −6 test/hotspot/jtreg/runtime/logging/loadLibraryTest/LoadLibraryTest.java
  21. +1 −1 test/hotspot/jtreg/runtime/logging/loadLibraryTest/libLoadLibraryClass.c
  22. +5 −4 test/jdk/java/util/UUID/UUIDTest.java
  23. +68 −0 test/jdk/jdk/jfr/event/runtime/TestMetaspaceAllocationFailure.java
  24. +6 −0 test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
  25. +5 −4 ...ary/GeneratedClassLoader.java → lib/jdk/test/lib/classloader/GeneratingCompilingClassLoader.java}
  26. +154 −0 test/micro/org/openjdk/bench/java/nio/DatagramChannelSendReceive.java
  27. +75 −0 test/micro/org/openjdk/bench/java/util/UUIDBench.java
@@ -881,7 +881,7 @@ ifeq ($(call isTargetOs, windows), true)
BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exejvm-test-launcher := jvm.lib

BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib
else
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exejvm-test-launcher := -ljvm
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libbootclssearch_agent += -lpthread
@@ -1517,6 +1517,7 @@ else
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libgetphase001 += -lpthread
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libgetphase002 += -lpthread
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm
endif

# This evaluation is expensive and should only be done if this target was
@@ -969,8 +969,7 @@ Klass* SystemDictionary::find_instance_or_array_klass(Symbol* class_name,
if (t != T_OBJECT) {
k = Universe::typeArrayKlassObj(t);
} else {
Symbol* obj_class = ss.as_symbol();
k = SystemDictionary::find(obj_class, class_loader, protection_domain, THREAD);
k = SystemDictionary::find(ss.as_symbol(), class_loader, protection_domain, THREAD);
}
if (k != NULL) {
k = k->array_klass_or_null(ndims);
@@ -2527,8 +2526,8 @@ static bool is_always_visible_class(oop mirror) {
InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke
}

// Find or construct the Java mirror (java.lang.Class instance) for a
// for the given field type signature, as interpreted relative to the
// Find or construct the Java mirror (java.lang.Class instance) for
// the given field type signature, as interpreted relative to the
// given class loader. Handles primitives, void, references, arrays,
// and all other reflectable types, except method types.
// N.B. Code in reflection should use this entry point.
@@ -2538,57 +2537,33 @@ Handle SystemDictionary::find_java_mirror_for_type(Symbol* signature,
Handle protection_domain,
SignatureStream::FailureMode failure_mode,
TRAPS) {
Handle empty;

assert(accessing_klass == NULL || (class_loader.is_null() && protection_domain.is_null()),
"one or the other, or perhaps neither");

SignatureStream ss(signature, false);

// What we have here must be a valid field descriptor,
// and all valid field descriptors are supported.
// Produce the same java.lang.Class that reflection reports.
if (ss.is_primitive() || (ss.type() == T_VOID)) {

// It's a primitive. (Void has a primitive mirror too.)
return Handle(THREAD, java_lang_Class::primitive_mirror(ss.type()));

} else if (ss.is_reference()) {

// It's a reference type.
if (accessing_klass != NULL) {
class_loader = Handle(THREAD, accessing_klass->class_loader());
protection_domain = Handle(THREAD, accessing_klass->protection_domain());
}
Klass* constant_type_klass;
if (failure_mode == SignatureStream::ReturnNull) {
constant_type_klass = resolve_or_null(signature, class_loader, protection_domain,
CHECK_(empty));
} else {
bool throw_error = (failure_mode == SignatureStream::NCDFError);
constant_type_klass = resolve_or_fail(signature, class_loader, protection_domain,
throw_error, CHECK_(empty));
}
if (constant_type_klass == NULL) {
return Handle(); // report failure this way
}
Handle mirror(THREAD, constant_type_klass->java_mirror());
if (accessing_klass != NULL) {
class_loader = Handle(THREAD, accessing_klass->class_loader());
protection_domain = Handle(THREAD, accessing_klass->protection_domain());
}
ResolvingSignatureStream ss(signature, class_loader, protection_domain, false);
oop mirror_oop = ss.as_java_mirror(failure_mode, CHECK_NH);
if (mirror_oop == NULL) {
return Handle(); // report failure this way
}
Handle mirror(THREAD, mirror_oop);

if (accessing_klass != NULL) {
// Check accessibility, emulating ConstantPool::verify_constant_pool_resolve.
if (accessing_klass != NULL) {
Klass* sel_klass = constant_type_klass;
Klass* sel_klass = java_lang_Class::as_Klass(mirror());
if (sel_klass != NULL) {
bool fold_type_to_class = true;
LinkResolver::check_klass_accessability(accessing_klass, sel_klass,
fold_type_to_class, CHECK_(empty));
fold_type_to_class, CHECK_NH);
}

return mirror;

}

// Fall through to an error.
assert(false, "unsupported mirror syntax");
THROW_MSG_(vmSymbols::java_lang_InternalError(), "unsupported mirror syntax", empty);
return mirror;
}


@@ -1680,7 +1680,6 @@ void Method::init_intrinsic_id() {
}
}

// These two methods are static since a GC may move the Method
bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
if (!THREAD->can_call_java()) {
// There is nothing useful this routine can do from within the Compile thread.
@@ -1689,16 +1688,11 @@ bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
return false;
}
bool sig_is_loaded = true;
Handle class_loader(THREAD, m->method_holder()->class_loader());
Handle protection_domain(THREAD, m->method_holder()->protection_domain());
ResourceMark rm(THREAD);
Symbol* signature = m->signature();
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
for (ResolvingSignatureStream ss(m()); !ss.is_done(); ss.next()) {
if (ss.is_reference()) {
Symbol* sym = ss.as_symbol();
Symbol* name = sym;
Klass* klass = SystemDictionary::resolve_or_null(name, class_loader,
protection_domain, THREAD);
// load everything, including arrays "[Lfoo;"
Klass* klass = ss.as_klass(SignatureStream::ReturnNull, THREAD);
// We are loading classes eagerly. If a ClassNotFoundException or
// a LinkageError was generated, be sure to ignore it.
if (HAS_PENDING_EXCEPTION) {
@@ -1716,14 +1710,13 @@ bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
}

bool Method::has_unloaded_classes_in_signature(const methodHandle& m, TRAPS) {
Handle class_loader(THREAD, m->method_holder()->class_loader());
Handle protection_domain(THREAD, m->method_holder()->protection_domain());
ResourceMark rm(THREAD);
Symbol* signature = m->signature();
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
for(ResolvingSignatureStream ss(m()); !ss.is_done(); ss.next()) {
if (ss.type() == T_OBJECT) {
Symbol* name = ss.as_symbol();
Klass* klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD);
// Do not use ss.is_reference() here, since we don't care about
// unloaded array component types.
Klass* klass = ss.as_klass_if_loaded(THREAD);
assert(!HAS_PENDING_EXCEPTION, "as_klass_if_loaded contract");
if (klass == NULL) return true;
}
}
@@ -156,15 +156,15 @@ void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) {
if (predicate != NULL) {
entry = skip_loop_predicates(entry);
}
if (predicate != NULL && UseLoopPredicate) {
if (predicate != NULL && UseProfiledLoopPredicate) {
// We may have two predicates, find first.
Node* n = find_predicate(entry);
if (n != NULL) {
predicate = n;
entry = skip_loop_predicates(entry);
}
}
if (predicate != NULL && UseProfiledLoopPredicate) {
if (predicate != NULL && UseLoopPredicate) {
entry = find_predicate(entry);
if (entry != NULL) predicate = entry;
}
@@ -2543,17 +2543,17 @@ void IdealLoopTree::dump_head() const {
tty->print(" limit_check");
entry = PhaseIdealLoop::skip_loop_predicates(entry);
}
if (UseLoopPredicate) {
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
if (UseProfiledLoopPredicate) {
predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate);
if (predicate != NULL) {
tty->print(" profile_predicated");
entry = PhaseIdealLoop::skip_loop_predicates(entry);
}
}
if (UseProfiledLoopPredicate) {
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate);
if (entry != NULL) {
tty->print(" profile_predicated");
if (UseLoopPredicate) {
predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (predicate != NULL) {
tty->print(" predicated");
}
}
if (_head->is_CountedLoop()) {
@@ -2658,22 +2658,22 @@ void PhaseIdealLoop::collect_potentially_useful_predicates(
LoopNode* lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
Node* predicate_proj = find_predicate(entry); // loop_limit_check first
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
if (predicate_proj != NULL) { // right pattern that can be used by loop predication
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
entry = skip_loop_predicates(entry);
}
predicate_proj = find_predicate(entry); // Predicate
if (predicate_proj != NULL ) {
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
entry = skip_loop_predicates(entry);
}
if (UseProfiledLoopPredicate) {
predicate_proj = find_predicate(entry); // Predicate
if (predicate_proj != NULL ) {
if (predicate_proj != NULL) {
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
entry = skip_loop_predicates(entry);
}
}
predicate_proj = find_predicate(entry); // Predicate
if (predicate_proj != NULL) {
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
}
}

if (loop->_next) { // sibling
@@ -2259,55 +2259,88 @@ void SuperWord::co_locate_pack(Node_List* pk) {
_igvn.replace_input_of(ld, MemNode::Memory, upper_insert_pt);
}
}
} else if (pk->at(0)->is_Load()) { //load
// all loads in the pack should have the same memory state. By default,
} else if (pk->at(0)->is_Load()) { // Load pack
// All loads in the pack should have the same memory state. By default,
// we use the memory state of the last load. However, if any load could
// not be moved down due to the dependence constraint, we use the memory
// state of the first load.
Node* last_mem = pk->at(0)->in(MemNode::Memory);
Node* first_mem = last_mem;
// Walk the memory graph from the current first load until the
// start of the loop and check if nodes on the way are memory
// edges of loads in the pack. The last one we encounter is the
// first load.
for (Node* current = first_mem; in_bb(current); current = current->is_Phi() ? current->in(LoopNode::EntryControl) : current->in(MemNode::Memory)) {
assert(current->is_Mem() || (current->is_Phi() && current->in(0) == bb()), "unexpected memory");
for (uint i = 1; i < pk->size(); i++) {
Node* ld = pk->at(i);
if (ld->in(MemNode::Memory) == current) {
first_mem = current;
break;
}
Node* mem_input = pick_mem_state(pk);
_igvn.hash_delete(mem_input);
// Give each load the same memory state
for (uint i = 0; i < pk->size(); i++) {
LoadNode* ld = pk->at(i)->as_Load();
_igvn.replace_input_of(ld, MemNode::Memory, mem_input);
}
}
}

// Finds the first and last memory state and then picks either of them by checking dependence constraints.
// If a store is dependent on an earlier load then we need to pick the memory state of the first load and cannot
// pick the memory state of the last load.
Node* SuperWord::pick_mem_state(Node_List* pk) {
Node* first_mem = find_first_mem_state(pk);
Node* last_mem = find_last_mem_state(pk, first_mem);

for (uint i = 0; i < pk->size(); i++) {
Node* ld = pk->at(i);
for (Node* current = last_mem; current != ld->in(MemNode::Memory); current = current->in(MemNode::Memory)) {
assert(current->is_Mem() && in_bb(current), "unexpected memory");
assert(current != first_mem, "corrupted memory graph");
if (!independent(current, ld)) {
#ifdef ASSERT
// Added assertion code since no case has been observed that should pick the first memory state.
// Remove the assertion code whenever we find a (valid) case that really needs the first memory state.
pk->dump();
first_mem->dump();
last_mem->dump();
current->dump();
ld->dump();
ld->in(MemNode::Memory)->dump();
assert(false, "never observed that first memory should be picked");
#endif
return first_mem; // A later store depends on this load, pick memory state of first load
}
}
// Find the last load by going over the pack again and walking
// the memory graph from the loads of the pack to the memory of
// the first load. If we encounter the memory of the current last
// load, then we started from further down in the memory graph and
// the load we started from is the last load. Check for dependence
// constraints in that loop as well.
bool schedule_last = true;
for (uint i = 0; i < pk->size(); i++) {
}
return last_mem;
}

// Walk the memory graph from the current first load until the
// start of the loop and check if nodes on the way are memory
// edges of loads in the pack. The last one we encounter is the
// first load.
Node* SuperWord::find_first_mem_state(Node_List* pk) {
Node* first_mem = pk->at(0)->in(MemNode::Memory);
for (Node* current = first_mem; in_bb(current); current = current->is_Phi() ? current->in(LoopNode::EntryControl) : current->in(MemNode::Memory)) {
assert(current->is_Mem() || (current->is_Phi() && current->in(0) == bb()), "unexpected memory");
for (uint i = 1; i < pk->size(); i++) {
Node* ld = pk->at(i);
for (Node* current = ld->in(MemNode::Memory); current != first_mem; current = current->in(MemNode::Memory)) {
assert(current->is_Mem() && in_bb(current), "unexpected memory");
if (current->in(MemNode::Memory) == last_mem) {
last_mem = ld->in(MemNode::Memory);
}
if (!independent(current, ld)) {
schedule_last = false; // a later store depends on this load
}
if (ld->in(MemNode::Memory) == current) {
first_mem = current;
break;
}
}
}
return first_mem;
}

Node* mem_input = schedule_last ? last_mem : first_mem;
_igvn.hash_delete(mem_input);
// Give each load the same memory state
for (uint i = 0; i < pk->size(); i++) {
LoadNode* ld = pk->at(i)->as_Load();
_igvn.replace_input_of(ld, MemNode::Memory, mem_input);
// Find the last load by going over the pack again and walking
// the memory graph from the loads of the pack to the memory of
// the first load. If we encounter the memory of the current last
// load, then we started from further down in the memory graph and
// the load we started from is the last load.
Node* SuperWord::find_last_mem_state(Node_List* pk, Node* first_mem) {
Node* last_mem = pk->at(0)->in(MemNode::Memory);
for (uint i = 0; i < pk->size(); i++) {
Node* ld = pk->at(i);
for (Node* current = ld->in(MemNode::Memory); current != first_mem; current = current->in(MemNode::Memory)) {
assert(current->is_Mem() && in_bb(current), "unexpected memory");
if (current->in(MemNode::Memory) == last_mem) {
last_mem = ld->in(MemNode::Memory);
}
}
}
return last_mem;
}

#ifndef PRODUCT
@@ -481,6 +481,10 @@ class SuperWord : public ResourceObj {
// Within a store pack, schedule stores together by moving out the sandwiched memory ops according
// to dependence info; and within a load pack, move loads down to the last executed load.
void co_locate_pack(Node_List* p);
Node* pick_mem_state(Node_List* pk);
Node* find_first_mem_state(Node_List* pk);
Node* find_last_mem_state(Node_List* pk, Node* first_mem);

// Convert packs into vector node operations
void output();
// Create a vector operand for the nodes in pack p for operand: in(opd_idx)

0 comments on commit 26a7b0d

Please sign in to comment.