Skip to content

Commit 26a7b0d

Browse files
committedMar 3, 2020
Merge
2 parents 65bf618 + c42de93 commit 26a7b0d

File tree

27 files changed

+1008
-298
lines changed

27 files changed

+1008
-298
lines changed
 

‎make/test/JtregNativeHotspot.gmk

+2-1
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ ifeq ($(call isTargetOs, windows), true)
881881
BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
882882
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c
883883
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exejvm-test-launcher := jvm.lib
884-
884+
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib
885885
else
886886
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exejvm-test-launcher := -ljvm
887887
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libbootclssearch_agent += -lpthread
@@ -1517,6 +1517,7 @@ else
15171517
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libgetphase001 += -lpthread
15181518
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libgetphase002 += -lpthread
15191519
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread
1520+
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm
15201521
endif
15211522

15221523
# This evaluation is expensive and should only be done if this target was

‎src/hotspot/share/classfile/systemDictionary.cpp

+18-43
Original file line numberDiff line numberDiff line change
@@ -969,8 +969,7 @@ Klass* SystemDictionary::find_instance_or_array_klass(Symbol* class_name,
969969
if (t != T_OBJECT) {
970970
k = Universe::typeArrayKlassObj(t);
971971
} else {
972-
Symbol* obj_class = ss.as_symbol();
973-
k = SystemDictionary::find(obj_class, class_loader, protection_domain, THREAD);
972+
k = SystemDictionary::find(ss.as_symbol(), class_loader, protection_domain, THREAD);
974973
}
975974
if (k != NULL) {
976975
k = k->array_klass_or_null(ndims);
@@ -2527,8 +2526,8 @@ static bool is_always_visible_class(oop mirror) {
25272526
InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke
25282527
}
25292528

2530-
// Find or construct the Java mirror (java.lang.Class instance) for a
2531-
// for the given field type signature, as interpreted relative to the
2529+
// Find or construct the Java mirror (java.lang.Class instance) for
2530+
// the given field type signature, as interpreted relative to the
25322531
// given class loader. Handles primitives, void, references, arrays,
25332532
// and all other reflectable types, except method types.
25342533
// N.B. Code in reflection should use this entry point.
@@ -2538,57 +2537,33 @@ Handle SystemDictionary::find_java_mirror_for_type(Symbol* signature,
25382537
Handle protection_domain,
25392538
SignatureStream::FailureMode failure_mode,
25402539
TRAPS) {
2541-
Handle empty;
2542-
25432540
assert(accessing_klass == NULL || (class_loader.is_null() && protection_domain.is_null()),
25442541
"one or the other, or perhaps neither");
25452542

2546-
SignatureStream ss(signature, false);
2547-
25482543
// What we have here must be a valid field descriptor,
25492544
// and all valid field descriptors are supported.
25502545
// Produce the same java.lang.Class that reflection reports.
2551-
if (ss.is_primitive() || (ss.type() == T_VOID)) {
2552-
2553-
// It's a primitive. (Void has a primitive mirror too.)
2554-
return Handle(THREAD, java_lang_Class::primitive_mirror(ss.type()));
2555-
2556-
} else if (ss.is_reference()) {
2557-
2558-
// It's a reference type.
2559-
if (accessing_klass != NULL) {
2560-
class_loader = Handle(THREAD, accessing_klass->class_loader());
2561-
protection_domain = Handle(THREAD, accessing_klass->protection_domain());
2562-
}
2563-
Klass* constant_type_klass;
2564-
if (failure_mode == SignatureStream::ReturnNull) {
2565-
constant_type_klass = resolve_or_null(signature, class_loader, protection_domain,
2566-
CHECK_(empty));
2567-
} else {
2568-
bool throw_error = (failure_mode == SignatureStream::NCDFError);
2569-
constant_type_klass = resolve_or_fail(signature, class_loader, protection_domain,
2570-
throw_error, CHECK_(empty));
2571-
}
2572-
if (constant_type_klass == NULL) {
2573-
return Handle(); // report failure this way
2574-
}
2575-
Handle mirror(THREAD, constant_type_klass->java_mirror());
2546+
if (accessing_klass != NULL) {
2547+
class_loader = Handle(THREAD, accessing_klass->class_loader());
2548+
protection_domain = Handle(THREAD, accessing_klass->protection_domain());
2549+
}
2550+
ResolvingSignatureStream ss(signature, class_loader, protection_domain, false);
2551+
oop mirror_oop = ss.as_java_mirror(failure_mode, CHECK_NH);
2552+
if (mirror_oop == NULL) {
2553+
return Handle(); // report failure this way
2554+
}
2555+
Handle mirror(THREAD, mirror_oop);
25762556

2557+
if (accessing_klass != NULL) {
25772558
// Check accessibility, emulating ConstantPool::verify_constant_pool_resolve.
2578-
if (accessing_klass != NULL) {
2579-
Klass* sel_klass = constant_type_klass;
2559+
Klass* sel_klass = java_lang_Class::as_Klass(mirror());
2560+
if (sel_klass != NULL) {
25802561
bool fold_type_to_class = true;
25812562
LinkResolver::check_klass_accessability(accessing_klass, sel_klass,
2582-
fold_type_to_class, CHECK_(empty));
2563+
fold_type_to_class, CHECK_NH);
25832564
}
2584-
2585-
return mirror;
2586-
25872565
}
2588-
2589-
// Fall through to an error.
2590-
assert(false, "unsupported mirror syntax");
2591-
THROW_MSG_(vmSymbols::java_lang_InternalError(), "unsupported mirror syntax", empty);
2566+
return mirror;
25922567
}
25932568

25942569

‎src/hotspot/share/oops/method.cpp

+8-15
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,6 @@ void Method::init_intrinsic_id() {
16801680
}
16811681
}
16821682

1683-
// These two methods are static since a GC may move the Method
16841683
bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
16851684
if (!THREAD->can_call_java()) {
16861685
// 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) {
16891688
return false;
16901689
}
16911690
bool sig_is_loaded = true;
1692-
Handle class_loader(THREAD, m->method_holder()->class_loader());
1693-
Handle protection_domain(THREAD, m->method_holder()->protection_domain());
16941691
ResourceMark rm(THREAD);
1695-
Symbol* signature = m->signature();
1696-
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
1692+
for (ResolvingSignatureStream ss(m()); !ss.is_done(); ss.next()) {
16971693
if (ss.is_reference()) {
1698-
Symbol* sym = ss.as_symbol();
1699-
Symbol* name = sym;
1700-
Klass* klass = SystemDictionary::resolve_or_null(name, class_loader,
1701-
protection_domain, THREAD);
1694+
// load everything, including arrays "[Lfoo;"
1695+
Klass* klass = ss.as_klass(SignatureStream::ReturnNull, THREAD);
17021696
// We are loading classes eagerly. If a ClassNotFoundException or
17031697
// a LinkageError was generated, be sure to ignore it.
17041698
if (HAS_PENDING_EXCEPTION) {
@@ -1716,14 +1710,13 @@ bool Method::load_signature_classes(const methodHandle& m, TRAPS) {
17161710
}
17171711

17181712
bool Method::has_unloaded_classes_in_signature(const methodHandle& m, TRAPS) {
1719-
Handle class_loader(THREAD, m->method_holder()->class_loader());
1720-
Handle protection_domain(THREAD, m->method_holder()->protection_domain());
17211713
ResourceMark rm(THREAD);
1722-
Symbol* signature = m->signature();
1723-
for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
1714+
for(ResolvingSignatureStream ss(m()); !ss.is_done(); ss.next()) {
17241715
if (ss.type() == T_OBJECT) {
1725-
Symbol* name = ss.as_symbol();
1726-
Klass* klass = SystemDictionary::find(name, class_loader, protection_domain, THREAD);
1716+
// Do not use ss.is_reference() here, since we don't care about
1717+
// unloaded array component types.
1718+
Klass* klass = ss.as_klass_if_loaded(THREAD);
1719+
assert(!HAS_PENDING_EXCEPTION, "as_klass_if_loaded contract");
17271720
if (klass == NULL) return true;
17281721
}
17291722
}

‎src/hotspot/share/opto/loopUnswitch.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,15 @@ void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) {
156156
if (predicate != NULL) {
157157
entry = skip_loop_predicates(entry);
158158
}
159-
if (predicate != NULL && UseLoopPredicate) {
159+
if (predicate != NULL && UseProfiledLoopPredicate) {
160160
// We may have two predicates, find first.
161161
Node* n = find_predicate(entry);
162162
if (n != NULL) {
163163
predicate = n;
164164
entry = skip_loop_predicates(entry);
165165
}
166166
}
167-
if (predicate != NULL && UseProfiledLoopPredicate) {
167+
if (predicate != NULL && UseLoopPredicate) {
168168
entry = find_predicate(entry);
169169
if (entry != NULL) predicate = entry;
170170
}

‎src/hotspot/share/opto/loopnode.cpp

+15-15
Original file line numberDiff line numberDiff line change
@@ -2543,17 +2543,17 @@ void IdealLoopTree::dump_head() const {
25432543
tty->print(" limit_check");
25442544
entry = PhaseIdealLoop::skip_loop_predicates(entry);
25452545
}
2546-
if (UseLoopPredicate) {
2547-
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
2548-
if (entry != NULL) {
2549-
tty->print(" predicated");
2546+
if (UseProfiledLoopPredicate) {
2547+
predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate);
2548+
if (predicate != NULL) {
2549+
tty->print(" profile_predicated");
25502550
entry = PhaseIdealLoop::skip_loop_predicates(entry);
25512551
}
25522552
}
2553-
if (UseProfiledLoopPredicate) {
2554-
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate);
2555-
if (entry != NULL) {
2556-
tty->print(" profile_predicated");
2553+
if (UseLoopPredicate) {
2554+
predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
2555+
if (predicate != NULL) {
2556+
tty->print(" predicated");
25572557
}
25582558
}
25592559
if (_head->is_CountedLoop()) {
@@ -2658,22 +2658,22 @@ void PhaseIdealLoop::collect_potentially_useful_predicates(
26582658
LoopNode* lpn = loop->_head->as_Loop();
26592659
Node* entry = lpn->in(LoopNode::EntryControl);
26602660
Node* predicate_proj = find_predicate(entry); // loop_limit_check first
2661-
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
2661+
if (predicate_proj != NULL) { // right pattern that can be used by loop predication
26622662
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
26632663
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
26642664
entry = skip_loop_predicates(entry);
26652665
}
2666-
predicate_proj = find_predicate(entry); // Predicate
2667-
if (predicate_proj != NULL ) {
2668-
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
2669-
entry = skip_loop_predicates(entry);
2670-
}
26712666
if (UseProfiledLoopPredicate) {
26722667
predicate_proj = find_predicate(entry); // Predicate
2673-
if (predicate_proj != NULL ) {
2668+
if (predicate_proj != NULL) {
26742669
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
2670+
entry = skip_loop_predicates(entry);
26752671
}
26762672
}
2673+
predicate_proj = find_predicate(entry); // Predicate
2674+
if (predicate_proj != NULL) {
2675+
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
2676+
}
26772677
}
26782678

26792679
if (loop->_next) { // sibling

‎src/hotspot/share/opto/superword.cpp

+71-38
Original file line numberDiff line numberDiff line change
@@ -2259,55 +2259,88 @@ void SuperWord::co_locate_pack(Node_List* pk) {
22592259
_igvn.replace_input_of(ld, MemNode::Memory, upper_insert_pt);
22602260
}
22612261
}
2262-
} else if (pk->at(0)->is_Load()) { //load
2263-
// all loads in the pack should have the same memory state. By default,
2262+
} else if (pk->at(0)->is_Load()) { // Load pack
2263+
// All loads in the pack should have the same memory state. By default,
22642264
// we use the memory state of the last load. However, if any load could
22652265
// not be moved down due to the dependence constraint, we use the memory
22662266
// state of the first load.
2267-
Node* last_mem = pk->at(0)->in(MemNode::Memory);
2268-
Node* first_mem = last_mem;
2269-
// Walk the memory graph from the current first load until the
2270-
// start of the loop and check if nodes on the way are memory
2271-
// edges of loads in the pack. The last one we encounter is the
2272-
// first load.
2273-
for (Node* current = first_mem; in_bb(current); current = current->is_Phi() ? current->in(LoopNode::EntryControl) : current->in(MemNode::Memory)) {
2274-
assert(current->is_Mem() || (current->is_Phi() && current->in(0) == bb()), "unexpected memory");
2275-
for (uint i = 1; i < pk->size(); i++) {
2276-
Node* ld = pk->at(i);
2277-
if (ld->in(MemNode::Memory) == current) {
2278-
first_mem = current;
2279-
break;
2280-
}
2267+
Node* mem_input = pick_mem_state(pk);
2268+
_igvn.hash_delete(mem_input);
2269+
// Give each load the same memory state
2270+
for (uint i = 0; i < pk->size(); i++) {
2271+
LoadNode* ld = pk->at(i)->as_Load();
2272+
_igvn.replace_input_of(ld, MemNode::Memory, mem_input);
2273+
}
2274+
}
2275+
}
2276+
2277+
// Finds the first and last memory state and then picks either of them by checking dependence constraints.
2278+
// If a store is dependent on an earlier load then we need to pick the memory state of the first load and cannot
2279+
// pick the memory state of the last load.
2280+
Node* SuperWord::pick_mem_state(Node_List* pk) {
2281+
Node* first_mem = find_first_mem_state(pk);
2282+
Node* last_mem = find_last_mem_state(pk, first_mem);
2283+
2284+
for (uint i = 0; i < pk->size(); i++) {
2285+
Node* ld = pk->at(i);
2286+
for (Node* current = last_mem; current != ld->in(MemNode::Memory); current = current->in(MemNode::Memory)) {
2287+
assert(current->is_Mem() && in_bb(current), "unexpected memory");
2288+
assert(current != first_mem, "corrupted memory graph");
2289+
if (!independent(current, ld)) {
2290+
#ifdef ASSERT
2291+
// Added assertion code since no case has been observed that should pick the first memory state.
2292+
// Remove the assertion code whenever we find a (valid) case that really needs the first memory state.
2293+
pk->dump();
2294+
first_mem->dump();
2295+
last_mem->dump();
2296+
current->dump();
2297+
ld->dump();
2298+
ld->in(MemNode::Memory)->dump();
2299+
assert(false, "never observed that first memory should be picked");
2300+
#endif
2301+
return first_mem; // A later store depends on this load, pick memory state of first load
22812302
}
22822303
}
2283-
// Find the last load by going over the pack again and walking
2284-
// the memory graph from the loads of the pack to the memory of
2285-
// the first load. If we encounter the memory of the current last
2286-
// load, then we started from further down in the memory graph and
2287-
// the load we started from is the last load. Check for dependence
2288-
// constraints in that loop as well.
2289-
bool schedule_last = true;
2290-
for (uint i = 0; i < pk->size(); i++) {
2304+
}
2305+
return last_mem;
2306+
}
2307+
2308+
// Walk the memory graph from the current first load until the
2309+
// start of the loop and check if nodes on the way are memory
2310+
// edges of loads in the pack. The last one we encounter is the
2311+
// first load.
2312+
Node* SuperWord::find_first_mem_state(Node_List* pk) {
2313+
Node* first_mem = pk->at(0)->in(MemNode::Memory);
2314+
for (Node* current = first_mem; in_bb(current); current = current->is_Phi() ? current->in(LoopNode::EntryControl) : current->in(MemNode::Memory)) {
2315+
assert(current->is_Mem() || (current->is_Phi() && current->in(0) == bb()), "unexpected memory");
2316+
for (uint i = 1; i < pk->size(); i++) {
22912317
Node* ld = pk->at(i);
2292-
for (Node* current = ld->in(MemNode::Memory); current != first_mem; current = current->in(MemNode::Memory)) {
2293-
assert(current->is_Mem() && in_bb(current), "unexpected memory");
2294-
if (current->in(MemNode::Memory) == last_mem) {
2295-
last_mem = ld->in(MemNode::Memory);
2296-
}
2297-
if (!independent(current, ld)) {
2298-
schedule_last = false; // a later store depends on this load
2299-
}
2318+
if (ld->in(MemNode::Memory) == current) {
2319+
first_mem = current;
2320+
break;
23002321
}
23012322
}
2323+
}
2324+
return first_mem;
2325+
}
23022326

2303-
Node* mem_input = schedule_last ? last_mem : first_mem;
2304-
_igvn.hash_delete(mem_input);
2305-
// Give each load the same memory state
2306-
for (uint i = 0; i < pk->size(); i++) {
2307-
LoadNode* ld = pk->at(i)->as_Load();
2308-
_igvn.replace_input_of(ld, MemNode::Memory, mem_input);
2327+
// Find the last load by going over the pack again and walking
2328+
// the memory graph from the loads of the pack to the memory of
2329+
// the first load. If we encounter the memory of the current last
2330+
// load, then we started from further down in the memory graph and
2331+
// the load we started from is the last load.
2332+
Node* SuperWord::find_last_mem_state(Node_List* pk, Node* first_mem) {
2333+
Node* last_mem = pk->at(0)->in(MemNode::Memory);
2334+
for (uint i = 0; i < pk->size(); i++) {
2335+
Node* ld = pk->at(i);
2336+
for (Node* current = ld->in(MemNode::Memory); current != first_mem; current = current->in(MemNode::Memory)) {
2337+
assert(current->is_Mem() && in_bb(current), "unexpected memory");
2338+
if (current->in(MemNode::Memory) == last_mem) {
2339+
last_mem = ld->in(MemNode::Memory);
2340+
}
23092341
}
23102342
}
2343+
return last_mem;
23112344
}
23122345

23132346
#ifndef PRODUCT

‎src/hotspot/share/opto/superword.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ class SuperWord : public ResourceObj {
481481
// Within a store pack, schedule stores together by moving out the sandwiched memory ops according
482482
// to dependence info; and within a load pack, move loads down to the last executed load.
483483
void co_locate_pack(Node_List* p);
484+
Node* pick_mem_state(Node_List* pk);
485+
Node* find_first_mem_state(Node_List* pk);
486+
Node* find_last_mem_state(Node_List* pk, Node* first_mem);
487+
484488
// Convert packs into vector node operations
485489
void output();
486490
// Create a vector operand for the nodes in pack p for operand: in(opd_idx)

0 commit comments

Comments
 (0)
Please sign in to comment.