@@ -130,6 +130,11 @@ template<int x> NOINLINE static bool verify_continuation(oop cont) { return Cont
130
130
template <int x> NOINLINE static bool verify_stack_chunk (oop chunk) { return Continuation::debug_verify_stack_chunk (chunk); }
131
131
#endif
132
132
133
+ #ifdef ASSERT
134
+ extern " C" void pns2 ();
135
+ extern " C" void pfl ();
136
+ #endif
137
+
133
138
int Continuations::_flags = 0 ;
134
139
int ContinuationEntry::return_pc_offset = 0 ;
135
140
nmethod* ContinuationEntry::continuation_enter = NULL ;
@@ -657,7 +662,7 @@ class ContMirror {
657
662
template <typename ConfigT> inline bool allocate_stacks (int size, int oops, int frames);
658
663
659
664
template <typename ConfigT>
660
- void make_keepalive (CompiledMethodKeepalive<ConfigT>* keepalive);
665
+ void make_keepalive (Thread* thread, CompiledMethodKeepalive<ConfigT>* keepalive);
661
666
662
667
inline bool in_hstack (void *p) { return (_hstack != NULL && p >= _hstack && p < (_hstack + _stack_length)); }
663
668
@@ -1972,7 +1977,7 @@ class CompiledMethodKeepalive {
1972
1977
int _nr_oops;
1973
1978
bool _required;
1974
1979
1975
- void store_keepalive (JavaThread * thread, oop* keepalive) { _keepalive = KeepaliveObjectT::make_keepalive (thread, keepalive); }
1980
+ void store_keepalive (Thread * thread, oop* keepalive) { _keepalive = KeepaliveObjectT::make_keepalive (thread, keepalive); }
1976
1981
oop read_keepalive () { return KeepaliveObjectT::read_keepalive (_keepalive); }
1977
1982
1978
1983
public:
@@ -2199,6 +2204,11 @@ class Freeze {
2199
2204
int nr_bytes () const { return _size; }
2200
2205
int nr_frames () const { return _frames; }
2201
2206
2207
+ Thread* cur_thread () {
2208
+ assert (_preempt || _thread == Thread::current (), " " ); // could be VM thread in force preempt
2209
+ return mode == mode_fast ? _thread : Thread::current ();
2210
+ }
2211
+
2202
2212
void verify () {
2203
2213
if (_cont.refStack () == NULL ) {
2204
2214
return ;
@@ -2230,19 +2240,22 @@ class Freeze {
2230
2240
2231
2241
freeze_result freeze_preempt () {
2232
2242
_preempt = true ;
2243
+ // if (!is_safe_to_preempt(_thread)) {
2244
+ // return freeze_pinned_native;
2245
+ // }
2233
2246
return freeze_no_chunk ();
2234
2247
}
2235
2248
2236
2249
freeze_result freeze_no_chunk () {
2237
2250
log_develop_trace (jvmcont)(" no young freeze mode: %d #" INTPTR_FORMAT, mode, _cont.hash ());
2238
2251
2239
2252
assert (mode == mode_slow || !_preempt, " " );
2240
- assert (_thread->thread_state () == _thread_in_vm, " " );
2253
+ assert (_thread->thread_state () == _thread_in_vm || _thread-> thread_state () == _thread_blocked , " " );
2241
2254
2242
2255
init_rest ();
2243
2256
_cont.read_rest ();
2244
2257
2245
- HandleMark hm (_thread );
2258
+ HandleMark hm (cur_thread () );
2246
2259
2247
2260
// tty->print_cr(">>> freeze mode: %d", mode);
2248
2261
@@ -2668,18 +2681,22 @@ class Freeze {
2668
2681
2669
2682
f.set_fp (f.real_fp ()); // Instead of this, maybe in ContMirror::set_last_frame always use the real_fp? // TODO PD
2670
2683
if (Interpreter::contains (f.pc ())) {
2671
- log_develop_trace (jvmcont)(" INTERPRETER SAFEPOINT" );
2672
2684
ContinuationHelper::update_register_map<Interpreted>(&_map, f);
2673
2685
// f.set_sp(f.sp() - 1); // state pushed to the stack
2674
2686
} else {
2675
- log_develop_trace (jvmcont)(" COMPILER SAFEPOINT" );
2676
2687
#ifdef ASSERT
2677
2688
if (!is_stub (f.cb ())) { f.print_value_on (tty, JavaThread::current ()); }
2678
2689
#endif
2679
2690
assert (is_stub (f.cb ()), " must be" );
2680
2691
assert (f.oop_map () != NULL , " must be" );
2681
- ContinuationHelper::update_register_map<StubF>(&_map, f);
2682
- f.oop_map ()->update_register_map (&f, (RegisterMap*)&_map); // we have callee-save registers in this case
2692
+
2693
+ if (Interpreter::contains (StubF::return_pc (f))) {
2694
+ log_develop_trace (jvmcont)(" Safepoint stub in interpreter" );
2695
+ f = sender<StubF>(f);
2696
+ } else {
2697
+ ContinuationHelper::update_register_map<StubF>(&_map, f);
2698
+ f.oop_map ()->update_register_map (&f, (RegisterMap*)&_map); // we have callee-save registers in this case
2699
+ }
2683
2700
}
2684
2701
2685
2702
// Log(jvmcont) logv; LogStream st(logv.debug()); f.print_on(st);
@@ -2786,7 +2803,7 @@ class Freeze {
2786
2803
2787
2804
CompiledMethodKeepaliveT* current = _keepalive;
2788
2805
while (current != NULL ) {
2789
- _cont.make_keepalive <ConfigT>(current);
2806
+ _cont.make_keepalive <ConfigT>(cur_thread (), current);
2790
2807
current = current->parent ();
2791
2808
}
2792
2809
}
@@ -3300,7 +3317,7 @@ static void post_JVMTI_yield(JavaThread* thread, ContMirror& cont) {
3300
3317
set_anchor_to_entry (thread, cont.entry ()); // ensure frozen frames are invisible
3301
3318
3302
3319
// The call to JVMTI can safepoint, so we need to restore oops.
3303
- Handle conth (thread , cont.mirror ());
3320
+ Handle conth (Thread::current () , cont.mirror ());
3304
3321
JvmtiExport::post_continuation_yield (JavaThread::current (), num_java_frames (cont));
3305
3322
cont.post_safepoint (conth);
3306
3323
}
@@ -3390,7 +3407,7 @@ int freeze0(JavaThread* thread, intptr_t* const sp, bool preempt) {
3390
3407
#endif
3391
3408
return freeze_epilog (thread, cont);
3392
3409
} else if (mode != mode_fast && UNLIKELY (preempt)) {
3393
- assert (thread->thread_state () == _thread_in_vm, " " );
3410
+ assert (thread->thread_state () == _thread_in_vm || thread-> thread_state () == _thread_blocked , " " );
3394
3411
freeze_result res = fr.freeze_preempt ();
3395
3412
return freeze_epilog (thread, cont, res);
3396
3413
} else {
@@ -3500,10 +3517,58 @@ static freeze_result is_pinned0(JavaThread* thread, oop cont_scope, bool safepoi
3500
3517
3501
3518
typedef int (*DoYieldStub)(int scopes);
3502
3519
3520
+ static bool is_safe_to_preempt (JavaThread* thread) {
3521
+ if (!thread->has_last_Java_frame ()) {
3522
+ log_develop_trace (jvmcont)(" is_safe_to_preempt: no last Java frame" );
3523
+ return false ;
3524
+ }
3525
+
3526
+ // assert (thread->thread_state() == _thread_blocked || thread == Thread::current(), "state: %s thread == Thread::current(): %d", thread->thread_state_name(), thread == Thread::current());
3527
+ // if (Thread::current()->is_VM_thread() && thread->thread_state() == _thread_blocked) {
3528
+ // log_develop_trace(jvmcont)("is_safe_to_preempt: thread blocked");
3529
+ // return false; // if we do this, we can assume in the freeze code that the given thread is also the current thread
3530
+ // }
3531
+
3532
+ frame f = thread->last_frame ();
3533
+ if (log_develop_is_enabled (Trace, jvmcont)) {
3534
+ log_develop_trace (jvmcont)(" is_safe_to_preempt %sSAFEPOINT" , Interpreter::contains (f.pc ()) ? " INTERPRETER " : " " );
3535
+ f.cb ()->print_on (tty);
3536
+ f.print_on (tty);
3537
+ }
3538
+
3539
+ if (Interpreter::contains (f.pc ())) {
3540
+ InterpreterCodelet* desc = Interpreter::codelet_containing (f.pc ());
3541
+ if (desc != NULL ) {
3542
+ if (log_develop_is_enabled (Trace, jvmcont)) desc->print_on (tty);
3543
+ // We allow preemption only when no bytecode (safepoint codelet) or a return byteocde
3544
+ if (desc->bytecode () >= 0 && !Bytecodes::is_return (desc->bytecode ())) {
3545
+ log_develop_trace (jvmcont)(" is_safe_to_preempt: unsafe bytecode: %s" , Bytecodes::name (desc->bytecode ()));
3546
+ return false ;
3547
+ } else {
3548
+ log_develop_trace (jvmcont)(" is_safe_to_preempt: %s (safe)" , desc->description ());
3549
+ // assert (Bytecodes::is_return(desc->bytecode()) || desc->description() != NULL && strncmp("safepoint", desc->description(), 9) == 0, "desc: %s", desc->description());
3550
+ }
3551
+ } else {
3552
+ log_develop_trace (jvmcont)(" is_safe_to_preempt: no codelet (safe?)" );
3553
+ }
3554
+ } else {
3555
+ // if (f.is_compiled_frame()) {
3556
+ // RelocIterator iter(f.cb()->as_compiled_method(), f.pc(), f.pc()+1);
3557
+ // while (iter.next()) {
3558
+ // iter.print_current();
3559
+ // }
3560
+ // }
3561
+ if (!f.cb ()->is_safepoint_stub ()) {
3562
+ log_develop_trace (jvmcont)(" is_safe_to_preempt: not safepoint stub" );
3563
+ return false ;
3564
+ }
3565
+ }
3566
+ return true ;
3567
+ }
3568
+
3503
3569
// called in a safepoint
3504
3570
int Continuation::try_force_yield (JavaThread* thread, const oop cont) {
3505
- assert (thread->thread_state () == _thread_in_vm, " " );
3506
- // assert (thread->thread_state() == _thread_in_vm || thread->thread_state() == _thread_blocked, "thread->thread_state(): %d", thread->thread_state());
3571
+ assert (thread->thread_state () == _thread_in_vm || thread->thread_state () == _thread_blocked, " state: %s java: %d vm: %d" , thread->thread_state_name (), thread->is_Java_thread (), thread->is_VM_thread ());
3507
3572
3508
3573
ContinuationEntry* ce = thread->cont_entry ();
3509
3574
oop innermost = ce->continuation ();
@@ -3516,6 +3581,10 @@ int Continuation::try_force_yield(JavaThread* thread, const oop cont) {
3516
3581
if (thread->_cont_yield ) {
3517
3582
return -2 ; // during yield
3518
3583
}
3584
+ if (!is_safe_to_preempt (thread)) {
3585
+ return freeze_pinned_native;
3586
+ }
3587
+
3519
3588
const oop scope = java_lang_Continuation::scope (cont);
3520
3589
if (innermost != cont) { // we have nested continuations
3521
3590
// make sure none of the continuations in the hierarchy are pinned
@@ -5239,8 +5308,8 @@ oop Continuation::continuation_scope(oop cont) {
5239
5308
// /// Allocation
5240
5309
5241
5310
template <typename ConfigT>
5242
- void ContMirror::make_keepalive (CompiledMethodKeepalive<ConfigT>* keepalive) {
5243
- Handle conth (_thread , _cont);
5311
+ void ContMirror::make_keepalive (Thread* thread, CompiledMethodKeepalive<ConfigT>* keepalive) {
5312
+ Handle conth (thread , _cont);
5244
5313
int oops = keepalive->nr_oops ();
5245
5314
if (oops == 0 ) {
5246
5315
oops = 1 ;
@@ -5249,7 +5318,7 @@ void ContMirror::make_keepalive(CompiledMethodKeepalive<ConfigT>* keepalive) {
5249
5318
5250
5319
uint64_t counter = SafepointSynchronize::safepoint_counter ();
5251
5320
// check gc cycle
5252
- Handle keepaliveHandle = Handle (_thread , keepalive_obj);
5321
+ Handle keepaliveHandle = Handle (thread , keepalive_obj);
5253
5322
keepalive->set_handle (keepaliveHandle);
5254
5323
// check gc cycle and maybe reload
5255
5324
// if (!SafepointSynchronize::is_same_safepoint(counter)) {
@@ -5560,7 +5629,7 @@ oop ContMirror::raw_allocate(Klass* klass, size_t size_in_words, size_t elements
5560
5629
return allocator.initialize (start);
5561
5630
} else {
5562
5631
// HandleMark hm(_thread);
5563
- Handle conth (_thread , _cont);
5632
+ Handle conth (Thread::current () , _cont);
5564
5633
uint64_t counter = SafepointSynchronize::safepoint_counter ();
5565
5634
oop result = allocator.allocate ();
5566
5635
// if (!SafepointSynchronize::is_same_safepoint(counter)) {
@@ -5578,6 +5647,7 @@ oop ContMirror::allocate_stack_chunk(int stack_size) {
5578
5647
if (start != NULL ) {
5579
5648
return allocator.initialize (start);
5580
5649
} else {
5650
+ assert (_thread == Thread::current (), " " );
5581
5651
// HandleMark hm(_thread);
5582
5652
Handle conth (_thread, _cont);
5583
5653
// uint64_t counter = SafepointSynchronize::safepoint_counter();
@@ -5726,7 +5796,7 @@ class HandleKeepalive {
5726
5796
public:
5727
5797
typedef Handle TypeT;
5728
5798
5729
- static Handle make_keepalive (JavaThread * thread, oop* keepalive) {
5799
+ static Handle make_keepalive (Thread * thread, oop* keepalive) {
5730
5800
return Handle (thread, WeakHandle<vm_nmethod_keepalive_data>::from_raw (keepalive).resolve ());
5731
5801
}
5732
5802
@@ -5739,7 +5809,7 @@ class NoKeepalive {
5739
5809
public:
5740
5810
typedef oop* TypeT;
5741
5811
5742
- static oop* make_keepalive (JavaThread * thread, oop* keepalive) {
5812
+ static oop* make_keepalive (Thread * thread, oop* keepalive) {
5743
5813
return keepalive;
5744
5814
}
5745
5815
0 commit comments