src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6498581 Sdiff src/share/vm/opto

src/share/vm/opto/library_call.cpp

Print this page
6498581: ThreadInterruptTest3 produces wrong output on Windows


3229   Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0));
3230 #ifdef ASSERT
3231   Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1));
3232   assert(value_top == top(), "second value must be top");
3233 #endif
3234   set_result(value);
3235   return true;
3236 }
3237 
3238 //------------------------inline_native_currentThread------------------
3239 bool LibraryCallKit::inline_native_currentThread() {
3240   Node* junk = NULL;
3241   set_result(generate_current_thread(junk));
3242   return true;
3243 }
3244 
3245 //------------------------inline_native_isInterrupted------------------
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
3247 bool LibraryCallKit::inline_native_isInterrupted() {
3248   // Add a fast path to t.isInterrupted(clear_int):
3249   //   (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int))

3250   //   ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
3251   // So, in the common case that the interrupt bit is false,
3252   // we avoid making a call into the VM.  Even if the interrupt bit
3253   // is true, if the clear_int argument is false, we avoid the VM call.
3254   // However, if the receiver is not currentThread, we must call the VM,
3255   // because there must be some locking done around the operation.
3256 
3257   // We only go to the fast case code if we pass two guards.
3258   // Paths which do not pass are accumulated in the slow_region.
3259 
3260   enum {
3261     no_int_result_path   = 1, // t == Thread.current() && !TLS._osthread._interrupted
3262     no_clear_result_path = 2, // t == Thread.current() &&  TLS._osthread._interrupted && !clear_int
3263     slow_result_path     = 3, // slow path: t.isInterrupted(clear_int)
3264     PATH_LIMIT
3265   };
3266 
3267   // Ensure that it's not possible to move the load of TLS._osthread._interrupted flag
3268   // out of the function.
3269   insert_mem_bar(Op_MemBarCPUOrder);


3286   // (b) Interrupt bit on TLS must be false.
3287   Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
3288   Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
3289   p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
3290 
3291   // Set the control input on the field _interrupted read to prevent it floating up.
3292   Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered);
3293   Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0)));
3294   Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne));
3295 
3296   IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
3297 
3298   // First fast path:  if (!TLS._interrupted) return false;
3299   Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit));
3300   result_rgn->init_req(no_int_result_path, false_bit);
3301   result_val->init_req(no_int_result_path, intcon(0));
3302 
3303   // drop through to next case
3304   set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
3305 

3306   // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
3307   Node* clr_arg = argument(1);
3308   Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
3309   Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
3310   IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
3311 
3312   // Second fast path:  ... else if (!clear_int) return true;
3313   Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg));
3314   result_rgn->init_req(no_clear_result_path, false_arg);
3315   result_val->init_req(no_clear_result_path, intcon(1));
3316 
3317   // drop through to next case
3318   set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));




3319 
3320   // (d) Otherwise, go to the slow path.
3321   slow_region->add_req(control());
3322   set_control( _gvn.transform(slow_region));
3323 
3324   if (stopped()) {
3325     // There is no slow path.
3326     result_rgn->init_req(slow_result_path, top());
3327     result_val->init_req(slow_result_path, top());
3328   } else {
3329     // non-virtual because it is a private non-static
3330     CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted);
3331 
3332     Node* slow_val = set_results_for_java_call(slow_call);
3333     // this->control() comes from set_results_for_java_call
3334 
3335     Node* fast_io  = slow_call->in(TypeFunc::I_O);
3336     Node* fast_mem = slow_call->in(TypeFunc::Memory);
3337 
3338     // These two phis are pre-filled with copies of of the fast IO and Memory




3229   Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0));
3230 #ifdef ASSERT
3231   Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+1));
3232   assert(value_top == top(), "second value must be top");
3233 #endif
3234   set_result(value);
3235   return true;
3236 }
3237 
3238 //------------------------inline_native_currentThread------------------
3239 bool LibraryCallKit::inline_native_currentThread() {
3240   Node* junk = NULL;
3241   set_result(generate_current_thread(junk));
3242   return true;
3243 }
3244 
3245 //------------------------inline_native_isInterrupted------------------
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
3247 bool LibraryCallKit::inline_native_isInterrupted() {
3248   // Add a fast path to t.isInterrupted(clear_int):
3249   //   (t == Thread.current() &&
3250   //    (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
3251   //   ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
3252   // So, in the common case that the interrupt bit is false,
3253   // we avoid making a call into the VM.  Even if the interrupt bit
3254   // is true, if the clear_int argument is false, we avoid the VM call.
3255   // However, if the receiver is not currentThread, we must call the VM,
3256   // because there must be some locking done around the operation.
3257 
3258   // We only go to the fast case code if we pass two guards.
3259   // Paths which do not pass are accumulated in the slow_region.
3260 
3261   enum {
3262     no_int_result_path   = 1, // t == Thread.current() && !TLS._osthread._interrupted
3263     no_clear_result_path = 2, // t == Thread.current() &&  TLS._osthread._interrupted && !clear_int
3264     slow_result_path     = 3, // slow path: t.isInterrupted(clear_int)
3265     PATH_LIMIT
3266   };
3267 
3268   // Ensure that it's not possible to move the load of TLS._osthread._interrupted flag
3269   // out of the function.
3270   insert_mem_bar(Op_MemBarCPUOrder);


3287   // (b) Interrupt bit on TLS must be false.
3288   Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
3289   Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
3290   p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
3291 
3292   // Set the control input on the field _interrupted read to prevent it floating up.
3293   Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered);
3294   Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0)));
3295   Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne));
3296 
3297   IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
3298 
3299   // First fast path:  if (!TLS._interrupted) return false;
3300   Node* false_bit = _gvn.transform(new (C) IfFalseNode(iff_bit));
3301   result_rgn->init_req(no_int_result_path, false_bit);
3302   result_val->init_req(no_int_result_path, intcon(0));
3303 
3304   // drop through to next case
3305   set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
3306 
3307 #ifndef TARGET_OS_FAMILY_windows
3308   // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
3309   Node* clr_arg = argument(1);
3310   Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
3311   Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
3312   IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
3313 
3314   // Second fast path:  ... else if (!clear_int) return true;
3315   Node* false_arg = _gvn.transform(new (C) IfFalseNode(iff_arg));
3316   result_rgn->init_req(no_clear_result_path, false_arg);
3317   result_val->init_req(no_clear_result_path, intcon(1));
3318 
3319   // drop through to next case
3320   set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
3321 #else
3322   // To return true on Windows you must read the _interrupted field
3323   // and check the the event state i.e. take the slow path.
3324 #endif // TARGET_OS_FAMILY_windows
3325 
3326   // (d) Otherwise, go to the slow path.
3327   slow_region->add_req(control());
3328   set_control( _gvn.transform(slow_region));
3329 
3330   if (stopped()) {
3331     // There is no slow path.
3332     result_rgn->init_req(slow_result_path, top());
3333     result_val->init_req(slow_result_path, top());
3334   } else {
3335     // non-virtual because it is a private non-static
3336     CallJavaNode* slow_call = generate_method_call(vmIntrinsics::_isInterrupted);
3337 
3338     Node* slow_val = set_results_for_java_call(slow_call);
3339     // this->control() comes from set_results_for_java_call
3340 
3341     Node* fast_io  = slow_call->in(TypeFunc::I_O);
3342     Node* fast_mem = slow_call->in(TypeFunc::Memory);
3343 
3344     // These two phis are pre-filled with copies of of the fast IO and Memory


src/share/vm/opto/library_call.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File