Skip to content

Commit e788e6d

Browse files
committed
Merge
2 parents c670ebb + 4b1be3e commit e788e6d

30 files changed

+392
-94
lines changed

src/hotspot/share/code/compiledMethod.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,21 @@ bool CompiledMethod::unload_nmethod_caches(bool unloading_occurred) {
549549
return true;
550550
}
551551

552+
void CompiledMethod::run_nmethod_entry_barrier() {
553+
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
554+
if (bs_nm != NULL) {
555+
// We want to keep an invariant that nmethods found through iterations of a Thread's
556+
// nmethods found in safepoints have gone through an entry barrier and are not armed.
557+
// By calling this nmethod entry barrier, it plays along and acts
558+
// like any other nmethod found on the stack of a thread (fewer surprises).
559+
nmethod* nm = as_nmethod_or_null();
560+
if (nm != NULL) {
561+
bool alive = bs_nm->nmethod_entry_barrier(nm);
562+
assert(alive, "should be alive");
563+
}
564+
}
565+
}
566+
552567
void CompiledMethod::cleanup_inline_caches(bool clean_all) {
553568
for (;;) {
554569
ICRefillVerifier ic_refill_verifier;
@@ -557,18 +572,8 @@ void CompiledMethod::cleanup_inline_caches(bool clean_all) {
557572
return;
558573
}
559574
}
560-
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
561-
if (bs_nm != NULL) {
562-
// We want to keep an invariant that nmethods found through iterations of a Thread's
563-
// nmethods found in safepoints have gone through an entry barrier and are not armed.
564-
// By calling this nmethod entry barrier from the sweeper, it plays along and acts
565-
// like any other nmethod found on the stack of a thread (fewer surprises).
566-
nmethod* nm = as_nmethod_or_null();
567-
if (nm != NULL) {
568-
bool alive = bs_nm->nmethod_entry_barrier(nm);
569-
assert(alive, "should be alive");
570-
}
571-
}
575+
// Call this nmethod entry barrier from the sweeper.
576+
run_nmethod_entry_barrier();
572577
InlineCacheBuffer::refill_ic_stubs();
573578
}
574579
}

src/hotspot/share/code/compiledMethod.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ class CompiledMethod : public CodeBlob {
366366
virtual void clear_inline_caches();
367367
void clear_ic_callsites();
368368

369+
// Execute nmethod barrier code, as if entering through nmethod call.
370+
void run_nmethod_entry_barrier();
371+
369372
// Verify and count cached icholder relocations.
370373
int verify_icholder_relocations();
371374
void verify_oop_relocations();

src/hotspot/share/code/nmethod.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,12 @@ void nmethod::flush_dependencies(bool delete_immediately) {
15671567
// Transfer information from compilation to jvmti
15681568
void nmethod::post_compiled_method_load_event(JvmtiThreadState* state) {
15691569

1570+
// Don't post this nmethod load event if it is already dying
1571+
// because the sweeper might already be deleting this nmethod.
1572+
if (is_not_entrant() && can_convert_to_zombie()) {
1573+
return;
1574+
}
1575+
15701576
// This is a bad time for a safepoint. We don't want
15711577
// this nmethod to get unloaded while we're queueing the event.
15721578
NoSafepointVerifier nsv;
@@ -1585,15 +1591,16 @@ void nmethod::post_compiled_method_load_event(JvmtiThreadState* state) {
15851591
if (JvmtiExport::should_post_compiled_method_load()) {
15861592
// Only post unload events if load events are found.
15871593
set_load_reported();
1588-
// Keep sweeper from turning this into zombie until it is posted.
1589-
mark_as_seen_on_stack();
1590-
15911594
// If a JavaThread hasn't been passed in, let the Service thread
15921595
// (which is a real Java thread) post the event
15931596
JvmtiDeferredEvent event = JvmtiDeferredEvent::compiled_method_load_event(this);
15941597
if (state == NULL) {
1598+
// Execute any barrier code for this nmethod as if it's called, since
1599+
// keeping it alive looks like stack walking.
1600+
run_nmethod_entry_barrier();
15951601
ServiceThread::enqueue_deferred_event(&event);
15961602
} else {
1603+
// This enters the nmethod barrier outside in the caller.
15971604
state->enqueue_event(&event);
15981605
}
15991606
}

src/hotspot/share/gc/parallel/psParallelCompact.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -630,25 +630,25 @@ inline bool ParallelCompactData::RegionData::claim()
630630
}
631631

632632
inline bool ParallelCompactData::RegionData::mark_normal() {
633-
return Atomic::cmpxchg(&_shadow_state, UnusedRegion, NormalRegion, memory_order_relaxed) == UnusedRegion;
633+
return Atomic::cmpxchg(&_shadow_state, UnusedRegion, NormalRegion) == UnusedRegion;
634634
}
635635

636636
inline bool ParallelCompactData::RegionData::mark_shadow() {
637637
if (_shadow_state != UnusedRegion) return false;
638-
return Atomic::cmpxchg(&_shadow_state, UnusedRegion, ShadowRegion, memory_order_relaxed) == UnusedRegion;
638+
return Atomic::cmpxchg(&_shadow_state, UnusedRegion, ShadowRegion) == UnusedRegion;
639639
}
640640

641641
inline void ParallelCompactData::RegionData::mark_filled() {
642-
int old = Atomic::cmpxchg(&_shadow_state, ShadowRegion, FilledShadow, memory_order_relaxed);
642+
int old = Atomic::cmpxchg(&_shadow_state, ShadowRegion, FilledShadow);
643643
assert(old == ShadowRegion, "Fail to mark the region as filled");
644644
}
645645

646646
inline bool ParallelCompactData::RegionData::mark_copied() {
647-
return Atomic::cmpxchg(&_shadow_state, FilledShadow, CopiedShadow, memory_order_relaxed) == FilledShadow;
647+
return Atomic::cmpxchg(&_shadow_state, FilledShadow, CopiedShadow) == FilledShadow;
648648
}
649649

650650
void ParallelCompactData::RegionData::shadow_to_normal() {
651-
int old = Atomic::cmpxchg(&_shadow_state, ShadowRegion, NormalRegion, memory_order_relaxed);
651+
int old = Atomic::cmpxchg(&_shadow_state, ShadowRegion, NormalRegion);
652652
assert(old == ShadowRegion, "Fail to mark the region as finish");
653653
}
654654

src/hotspot/share/gc/shared/genCollectedHeap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t siz
472472
HandleMark hm; // Discard invalid handles created during verification
473473
Universe::verify("Before GC");
474474
}
475-
COMPILER2_PRESENT(DerivedPointerTable::clear());
475+
COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::clear());
476476

477477
if (restore_marks_for_biased_locking) {
478478
// We perform this mark word preservation work lazily
@@ -520,7 +520,7 @@ void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t siz
520520
rp->verify_no_references_recorded();
521521
}
522522

523-
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
523+
COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::update_pointers());
524524

525525
gen->stat_record()->accumulated_time.stop();
526526

src/hotspot/share/gc/z/zRootsIterator.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
#include "memory/universe.hpp"
4545
#include "prims/jvmtiExport.hpp"
4646
#include "prims/resolvedMethodTable.hpp"
47-
#include "runtime/atomic.hpp"
48-
#include "runtime/safepoint.hpp"
47+
#include "runtime/atomic.hpp"#include "runtime/safepoint.hpp"
4948
#include "runtime/synchronizer.hpp"
5049
#include "runtime/thread.hpp"
5150
#include "runtime/vmThread.hpp"
@@ -208,7 +207,7 @@ ZRootsIterator::ZRootsIterator(bool visit_jvmti_weak_export) :
208207
_code_cache(this) {
209208
assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
210209
ZStatTimer timer(ZSubPhasePauseRootsSetup);
211-
COMPILER2_PRESENT(DerivedPointerTable::clear());
210+
COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::clear());
212211
if (ClassUnloading) {
213212
nmethod::oops_do_marking_prologue();
214213
} else {
@@ -225,7 +224,7 @@ ZRootsIterator::~ZRootsIterator() {
225224
ZNMethod::oops_do_end();
226225
}
227226

228-
COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
227+
COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::update_pointers());
229228
}
230229

231230
void ZRootsIterator::do_universe(ZRootsIteratorClosure* cl) {

src/hotspot/share/jvmci/jvmci_globals.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
114114
CHECK_NOT_SET(JVMCILibPath, EnableJVMCI)
115115
CHECK_NOT_SET(JVMCILibDumpJNIConfig, EnableJVMCI)
116116

117+
#ifndef COMPILER2
118+
JVMCI_FLAG_CHECKED(MaxVectorSize)
119+
JVMCI_FLAG_CHECKED(ReduceInitialCardMarks)
120+
JVMCI_FLAG_CHECKED(UseMultiplyToLenIntrinsic)
121+
JVMCI_FLAG_CHECKED(UseSquareToLenIntrinsic)
122+
JVMCI_FLAG_CHECKED(UseMulAddIntrinsic)
123+
JVMCI_FLAG_CHECKED(UseMontgomeryMultiplyIntrinsic)
124+
JVMCI_FLAG_CHECKED(UseMontgomerySquareIntrinsic)
125+
#endif // !COMPILER2
126+
117127
#ifndef PRODUCT
118128
#define JVMCI_CHECK4(type, name, value, doc) assert(name##checked, #name " flag not checked");
119129
#define JVMCI_CHECK3(type, name, doc) assert(name##checked, #name " flag not checked");

src/hotspot/share/opto/loopopts.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,10 @@ Node *PhaseIdealLoop::convert_add_to_muladd(Node* n) {
498498
Node * in2 = n->in(2);
499499
if (in1->Opcode() == Op_MulI && in2->Opcode() == Op_MulI) {
500500
IdealLoopTree* loop_n = get_loop(get_ctrl(n));
501-
if (loop_n->_head->as_Loop()->is_valid_counted_loop() &&
502-
Matcher::match_rule_supported(Op_MulAddS2I) &&
503-
Matcher::match_rule_supported(Op_MulAddVS2VI)) {
501+
if (loop_n->is_counted() &&
502+
loop_n->_head->as_Loop()->is_valid_counted_loop() &&
503+
Matcher::match_rule_supported(Op_MulAddVS2VI) &&
504+
Matcher::match_rule_supported(Op_MulAddS2I)) {
504505
Node* mul_in1 = in1->in(1);
505506
Node* mul_in2 = in1->in(2);
506507
Node* mul_in3 = in2->in(1);

src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "prims/jvmtiExport.hpp"
3535
#include "prims/jvmtiThreadState.inline.hpp"
3636
#include "runtime/handles.inline.hpp"
37+
#include "runtime/safepointVerifiers.hpp"
3738
#include "runtime/vmThread.hpp"
3839

3940
// Support class to collect a list of the non-nmethod CodeBlobs in
@@ -222,16 +223,22 @@ jvmtiError JvmtiCodeBlobEvents::generate_dynamic_code_events(JvmtiEnv* env) {
222223
jvmtiError JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv* env) {
223224
JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
224225
{
225-
// Walk the CodeCache notifying for live nmethods, don't release the CodeCache_lock
226-
// because the sweeper may be running concurrently.
227-
// Save events to the queue for posting outside the CodeCache_lock.
228-
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
229-
// Iterate over non-profiled and profiled nmethods
230-
NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading);
231-
while(iter.next()) {
232-
nmethod* current = iter.method();
233-
current->post_compiled_method_load_event(state);
226+
NoSafepointVerifier nsv; // safepoints are not safe while collecting methods to post.
227+
{
228+
// Walk the CodeCache notifying for live nmethods, don't release the CodeCache_lock
229+
// because the sweeper may be running concurrently.
230+
// Save events to the queue for posting outside the CodeCache_lock.
231+
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
232+
// Iterate over non-profiled and profiled nmethods
233+
NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading);
234+
while(iter.next()) {
235+
nmethod* current = iter.method();
236+
current->post_compiled_method_load_event(state);
237+
}
234238
}
239+
240+
// Enter nmethod barrier code if present outside CodeCache_lock
241+
state->run_nmethod_entry_barriers();
235242
}
236243

237244
// Now post all the events outside the CodeCache_lock.

src/hotspot/share/prims/jvmtiImpl.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "precompiled.hpp"
2626
#include "classfile/symbolTable.hpp"
2727
#include "classfile/systemDictionary.hpp"
28+
#include "code/nmethod.hpp"
2829
#include "interpreter/interpreter.hpp"
2930
#include "interpreter/oopMapCache.hpp"
3031
#include "jvmtifiles/jvmtiEnv.hpp"
@@ -992,6 +993,12 @@ void JvmtiDeferredEvent::post_compiled_method_load_event(JvmtiEnv* env) {
992993
JvmtiExport::post_compiled_method_load(env, nm);
993994
}
994995

996+
void JvmtiDeferredEvent::run_nmethod_entry_barriers() {
997+
if (_type == TYPE_COMPILED_METHOD_LOAD) {
998+
_event_data.compiled_method_load->run_nmethod_entry_barrier();
999+
}
1000+
}
1001+
9951002

9961003
// Keep the nmethod for compiled_method_load from being unloaded.
9971004
void JvmtiDeferredEvent::oops_do(OopClosure* f, CodeBlobClosure* cf) {
@@ -1008,8 +1015,16 @@ void JvmtiDeferredEvent::nmethods_do(CodeBlobClosure* cf) {
10081015
}
10091016
}
10101017

1018+
10111019
bool JvmtiDeferredEventQueue::has_events() {
1012-
return _queue_head != NULL;
1020+
// We save the queued events before the live phase and post them when it starts.
1021+
// This code could skip saving the events on the queue before the live
1022+
// phase and ignore them, but this would change how we do things now.
1023+
// Starting the service thread earlier causes this to be called before the live phase begins.
1024+
// The events on the queue should all be posted after the live phase so this is an
1025+
// ok check. Before the live phase, DynamicCodeGenerated events are posted directly.
1026+
// If we add other types of events to the deferred queue, this could get ugly.
1027+
return JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE && _queue_head != NULL;
10131028
}
10141029

10151030
void JvmtiDeferredEventQueue::enqueue(JvmtiDeferredEvent event) {
@@ -1057,6 +1072,13 @@ void JvmtiDeferredEventQueue::post(JvmtiEnv* env) {
10571072
}
10581073
}
10591074

1075+
void JvmtiDeferredEventQueue::run_nmethod_entry_barriers() {
1076+
for(QueueNode* node = _queue_head; node != NULL; node = node->next()) {
1077+
node->event().run_nmethod_entry_barriers();
1078+
}
1079+
}
1080+
1081+
10601082
void JvmtiDeferredEventQueue::oops_do(OopClosure* f, CodeBlobClosure* cf) {
10611083
for(QueueNode* node = _queue_head; node != NULL; node = node->next()) {
10621084
node->event().oops_do(f, cf);

src/hotspot/share/prims/jvmtiImpl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ class JvmtiDeferredEvent {
481481
// Actually posts the event.
482482
void post() NOT_JVMTI_RETURN;
483483
void post_compiled_method_load_event(JvmtiEnv* env) NOT_JVMTI_RETURN;
484+
void run_nmethod_entry_barriers() NOT_JVMTI_RETURN;
484485
// Sweeper support to keep nmethods from being zombied while in the queue.
485486
void nmethods_do(CodeBlobClosure* cf) NOT_JVMTI_RETURN;
486487
// GC support to keep nmethod from being unloaded while in the queue.
@@ -522,6 +523,7 @@ class JvmtiDeferredEventQueue : public CHeapObj<mtInternal> {
522523
// Post all events in the queue for the current Jvmti environment
523524
void post(JvmtiEnv* env) NOT_JVMTI_RETURN;
524525
void enqueue(JvmtiDeferredEvent event) NOT_JVMTI_RETURN;
526+
void run_nmethod_entry_barriers();
525527

526528
// Sweeper support to keep nmethods from being zombied while in the queue.
527529
void nmethods_do(CodeBlobClosure* cf) NOT_JVMTI_RETURN;

src/hotspot/share/prims/jvmtiThreadState.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,8 @@ void JvmtiThreadState::post_events(JvmtiEnv* env) {
432432
}
433433
}
434434

435+
void JvmtiThreadState::run_nmethod_entry_barriers() {
436+
if (_jvmti_event_queue != NULL) {
437+
_jvmti_event_queue->run_nmethod_entry_barriers();
438+
}
439+
}

src/hotspot/share/prims/jvmtiThreadState.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
398398
// Thread local event queue, which doesn't require taking the Service_lock.
399399
void enqueue_event(JvmtiDeferredEvent* event);
400400
void post_events(JvmtiEnv* env);
401+
void run_nmethod_entry_barriers();
401402
};
402403

403404
class RedefineVerifyMark : public StackObj {

src/hotspot/share/runtime/deoptimization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
302302

303303
// Reallocate the non-escaping objects and restore their fields. Then
304304
// relock objects if synchronization on them was eliminated.
305-
if (jvmci_enabled || (DoEscapeAnalysis && EliminateAllocations)) {
305+
if (jvmci_enabled COMPILER2_PRESENT( || (DoEscapeAnalysis && EliminateAllocations) )) {
306306
realloc_failures = eliminate_allocations(thread, exec_mode, cm, deoptee, map, chunk);
307307
}
308308
#endif // COMPILER2_OR_JVMCI
@@ -318,7 +318,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
318318
NoSafepointVerifier no_safepoint;
319319

320320
#if COMPILER2_OR_JVMCI
321-
if (jvmci_enabled || ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateLocks)) {
321+
if (jvmci_enabled COMPILER2_PRESENT( || ((DoEscapeAnalysis || EliminateNestedLocks) && EliminateLocks) )) {
322322
eliminate_locks(thread, chunk, realloc_failures);
323323
}
324324
#endif // COMPILER2_OR_JVMCI

src/hotspot/share/runtime/serviceThread.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
ServiceThread* ServiceThread::_instance = NULL;
4949
JvmtiDeferredEvent* ServiceThread::_jvmti_event = NULL;
5050
// The service thread has it's own static deferred event queue.
51-
// Events can be posted before the service thread is created.
51+
// Events can be posted before JVMTI vm_start, so it's too early to call JvmtiThreadState::state_for
52+
// to add this field to the per-JavaThread event queue. TODO: fix this sometime later
5253
JvmtiDeferredEventQueue ServiceThread::_jvmti_service_queue;
5354

5455
void ServiceThread::initialize() {
@@ -195,6 +196,10 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
195196

196197
void ServiceThread::enqueue_deferred_event(JvmtiDeferredEvent* event) {
197198
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
199+
// If you enqueue events before the service thread runs, gc and the sweeper
200+
// cannot keep the nmethod alive. This could be restricted to compiled method
201+
// load and unload events, if we wanted to be picky.
202+
assert(_instance != NULL, "cannot enqueue events before the service thread runs");
198203
_jvmti_service_queue.enqueue(*event);
199204
Service_lock->notify_all();
200205
}

src/hotspot/share/runtime/thread.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
#include "runtime/safepoint.hpp"
8989
#include "runtime/safepointMechanism.inline.hpp"
9090
#include "runtime/safepointVerifiers.hpp"
91+
#include "runtime/serviceThread.hpp"
9192
#include "runtime/sharedRuntime.hpp"
9293
#include "runtime/statSampler.hpp"
9394
#include "runtime/stubRoutines.hpp"
@@ -3995,6 +3996,10 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
39953996
Chunk::start_chunk_pool_cleaner_task();
39963997
}
39973998

3999+
// Start the service thread
4000+
// The service thread enqueues JVMTI deferred events and does various hashtable
4001+
// and other cleanups. Needs to start before the compilers start posting events.
4002+
ServiceThread::initialize();
39984003

39994004
// initialize compiler(s)
40004005
#if defined(COMPILER1) || COMPILER2_OR_JVMCI

src/hotspot/share/services/management.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
#include "runtime/jniHandles.inline.hpp"
4747
#include "runtime/notificationThread.hpp"
4848
#include "runtime/os.hpp"
49-
#include "runtime/serviceThread.hpp"
5049
#include "runtime/thread.inline.hpp"
5150
#include "runtime/threadSMR.hpp"
5251
#include "services/classLoadingService.hpp"
@@ -147,8 +146,6 @@ void Management::init() {
147146
}
148147

149148
void Management::initialize(TRAPS) {
150-
// Start the service thread
151-
ServiceThread::initialize();
152149
if (UseNotificationThread) {
153150
NotificationThread::initialize();
154151
}

0 commit comments

Comments
 (0)