src/share/vm/opto/generateOptoStub.cpp

Print this page
rev 5661 : 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering.


  87 
  88   Node* adr_last_Java_pc = basic_plus_adr(top(),
  89                                             thread,
  90                                             in_bytes(JavaThread::frame_anchor_offset()) +
  91                                             in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
  92 #if defined(SPARC)
  93   Node* adr_flags = basic_plus_adr(top(),
  94                                    thread,
  95                                    in_bytes(JavaThread::frame_anchor_offset()) +
  96                                    in_bytes(JavaFrameAnchor::flags_offset()));
  97 #endif /* defined(SPARC) */
  98 
  99 
 100   // Drop in the last_Java_sp.  last_Java_fp is not touched.
 101   // Always do this after the other "last_Java_frame" fields are set since
 102   // as soon as last_Java_sp != NULL the has_last_Java_frame is true and
 103   // users will look at the other fields.
 104   //
 105   Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
 106   Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
 107   store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias);
 108 
 109   // Set _thread_in_native
 110   // The order of stores into TLS is critical!  Setting _thread_in_native MUST
 111   // be last, because a GC is allowed at any time after setting it and the GC
 112   // will require last_Java_pc and last_Java_sp.
 113   Node* adr_state = basic_plus_adr(top(), thread, in_bytes(JavaThread::thread_state_offset()));
 114 
 115   //-----------------------------
 116   // Compute signature for C call.  Varies from the Java signature!
 117   const Type **fields = TypeTuple::fields(2*parm_cnt+2);
 118   uint cnt = TypeFunc::Parms;
 119   // The C routines gets the base of thread-local storage passed in as an
 120   // extra argument.  Not all calls need it, but its cheap to add here.
 121   for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
 122     // Convert ints to longs if required.
 123     if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
 124       fields[cnt++] = TypeLong::LONG;
 125       fields[cnt]   = Type::HALF; // must add an additional half for a long
 126     } else {
 127       fields[cnt] = jdomain->field_at(pcnt);
 128     }
 129   }
 130 
 131   fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
 132   // Also pass in the caller's PC, if asked for.
 133   if( return_pc )


 208     Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) );
 209     // C-land is allowed to return sub-word values.  Convert to integer type.
 210     assert( retval != Type::TOP, "" );
 211     if (retval == TypeInt::BOOL) {
 212       retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) );
 213     } else if (retval == TypeInt::CHAR) {
 214       retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) );
 215     } else if (retval == TypeInt::BYTE) {
 216       retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) );
 217       retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) );
 218     } else if (retval == TypeInt::SHORT) {
 219       retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) );
 220       retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) );
 221     }
 222     map()->set_req( TypeFunc::Parms, retnode );
 223   }
 224 
 225   //-----------------------------
 226 
 227   // Clear last_Java_sp
 228   store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias);
 229   // Clear last_Java_pc and (optionally)_flags
 230   store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias);
 231 #if defined(SPARC)
 232   store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias);
 233 #endif /* defined(SPARC) */
 234 #if (defined(IA64) && !defined(AIX))
 235   Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
 236   if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
 237   store_to_memory(NULL, adr_last_Java_fp,    null(),    T_ADDRESS, NoAlias);
 238 #endif
 239 
 240   // For is-fancy-jump, the C-return value is also the branch target
 241   Node* target = map()->in(TypeFunc::Parms);
 242   // Runtime call returning oop in TLS?  Fetch it out
 243   if( pass_tls ) {
 244     Node* adr = basic_plus_adr(top(), thread, in_bytes(JavaThread::vm_result_offset()));
 245     Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
 246     map()->set_req(TypeFunc::Parms, vm_result); // vm_result passed as result
 247     // clear thread-local-storage(tls)
 248     store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias);
 249   }
 250 
 251   //-----------------------------
 252   // check exception
 253   Node* adr = basic_plus_adr(top(), thread, in_bytes(Thread::pending_exception_offset()));
 254   Node* pending = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
 255 
 256   Node* exit_memory = reset_memory();
 257 
 258   Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) );
 259   Node* bo  = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) );
 260   IfNode   *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN);
 261 
 262   Node* if_null     = _gvn.transform( new (C) IfFalseNode(iff) );
 263   Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff)  );
 264 
 265   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
 266   Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() ));
 267   Node *to_exc = new (C) TailCallNode(if_not_null,
 268                                       i_o(),
 269                                       exit_memory,
 270                                       frameptr(),
 271                                       returnadr(),
 272                                       exc_target, null());
 273   root()->add_req(_gvn.transform(to_exc));  // bind to root to keep live
 274   C->init_start(start);




  87 
  88   Node* adr_last_Java_pc = basic_plus_adr(top(),
  89                                             thread,
  90                                             in_bytes(JavaThread::frame_anchor_offset()) +
  91                                             in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
  92 #if defined(SPARC)
  93   Node* adr_flags = basic_plus_adr(top(),
  94                                    thread,
  95                                    in_bytes(JavaThread::frame_anchor_offset()) +
  96                                    in_bytes(JavaFrameAnchor::flags_offset()));
  97 #endif /* defined(SPARC) */
  98 
  99 
 100   // Drop in the last_Java_sp.  last_Java_fp is not touched.
 101   // Always do this after the other "last_Java_frame" fields are set since
 102   // as soon as last_Java_sp != NULL the has_last_Java_frame is true and
 103   // users will look at the other fields.
 104   //
 105   Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
 106   Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
 107   store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias, false, StoreNode::unordered);
 108 
 109   // Set _thread_in_native
 110   // The order of stores into TLS is critical!  Setting _thread_in_native MUST
 111   // be last, because a GC is allowed at any time after setting it and the GC
 112   // will require last_Java_pc and last_Java_sp.

 113 
 114   //-----------------------------
 115   // Compute signature for C call.  Varies from the Java signature!
 116   const Type **fields = TypeTuple::fields(2*parm_cnt+2);
 117   uint cnt = TypeFunc::Parms;
 118   // The C routines gets the base of thread-local storage passed in as an
 119   // extra argument.  Not all calls need it, but its cheap to add here.
 120   for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
 121     // Convert ints to longs if required.
 122     if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
 123       fields[cnt++] = TypeLong::LONG;
 124       fields[cnt]   = Type::HALF; // must add an additional half for a long
 125     } else {
 126       fields[cnt] = jdomain->field_at(pcnt);
 127     }
 128   }
 129 
 130   fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
 131   // Also pass in the caller's PC, if asked for.
 132   if( return_pc )


 207     Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) );
 208     // C-land is allowed to return sub-word values.  Convert to integer type.
 209     assert( retval != Type::TOP, "" );
 210     if (retval == TypeInt::BOOL) {
 211       retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) );
 212     } else if (retval == TypeInt::CHAR) {
 213       retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) );
 214     } else if (retval == TypeInt::BYTE) {
 215       retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) );
 216       retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) );
 217     } else if (retval == TypeInt::SHORT) {
 218       retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) );
 219       retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) );
 220     }
 221     map()->set_req( TypeFunc::Parms, retnode );
 222   }
 223 
 224   //-----------------------------
 225 
 226   // Clear last_Java_sp
 227   store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias, false, StoreNode::unordered);
 228   // Clear last_Java_pc and (optionally)_flags
 229   store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias, false, StoreNode::unordered);
 230 #if defined(SPARC)
 231   store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias, false, StoreNode::unordered);
 232 #endif /* defined(SPARC) */
 233 #if (defined(IA64) && !defined(AIX))
 234   Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
 235   store_to_memory(NULL, adr_last_Java_fp, null(), T_ADDRESS, NoAlias, false, StoreNode::unordered);

 236 #endif
 237 
 238   // For is-fancy-jump, the C-return value is also the branch target
 239   Node* target = map()->in(TypeFunc::Parms);
 240   // Runtime call returning oop in TLS?  Fetch it out
 241   if( pass_tls ) {
 242     Node* adr = basic_plus_adr(top(), thread, in_bytes(JavaThread::vm_result_offset()));
 243     Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false, LoadNode::unordered);
 244     map()->set_req(TypeFunc::Parms, vm_result); // vm_result passed as result
 245     // clear thread-local-storage(tls)
 246     store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias, false, StoreNode::unordered);
 247   }
 248 
 249   //-----------------------------
 250   // check exception
 251   Node* adr = basic_plus_adr(top(), thread, in_bytes(Thread::pending_exception_offset()));
 252   Node* pending = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false, LoadNode::unordered);
 253 
 254   Node* exit_memory = reset_memory();
 255 
 256   Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) );
 257   Node* bo  = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) );
 258   IfNode   *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN);
 259 
 260   Node* if_null     = _gvn.transform( new (C) IfFalseNode(iff) );
 261   Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff)  );
 262 
 263   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
 264   Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() ));
 265   Node *to_exc = new (C) TailCallNode(if_not_null,
 266                                       i_o(),
 267                                       exit_memory,
 268                                       frameptr(),
 269                                       returnadr(),
 270                                       exc_target, null());
 271   root()->add_req(_gvn.transform(to_exc));  // bind to root to keep live
 272   C->init_start(start);