src/share/vm/opto/parseHelper.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File valhalla Sdiff src/share/vm/opto

src/share/vm/opto/parseHelper.cpp

Print this page




  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciValueKlass.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "compiler/compileLog.hpp"
  29 #include "oops/objArrayKlass.hpp"

  30 #include "opto/addnode.hpp"
  31 #include "opto/memnode.hpp"
  32 #include "opto/mulnode.hpp"
  33 #include "opto/parse.hpp"
  34 #include "opto/rootnode.hpp"
  35 #include "opto/runtime.hpp"
  36 #include "opto/valuetypenode.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 
  39 //------------------------------make_dtrace_method_entry_exit ----------------
  40 // Dtrace -- record entry or exit of a method if compiled with dtrace support
  41 void GraphKit::make_dtrace_method_entry_exit(ciMethod* method, bool is_entry) {
  42   const TypeFunc *call_type    = OptoRuntime::dtrace_method_entry_exit_Type();
  43   address         call_address = is_entry ? CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry) :
  44                                             CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit);
  45   const char     *call_name    = is_entry ? "dtrace_method_entry" : "dtrace_method_exit";
  46 
  47   // Get base of thread-local storage area
  48   Node* thread = _gvn.transform( new ThreadLocalNode() );
  49 


 122     assert( stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR), "what's left behind is null" );
 123     if (!stopped()) {
 124       // The object is now known to be null.
 125       // Shortcut the effect of gen_instanceof and return "false" directly.
 126       pop();                   // pop the null
 127       push(_gvn.intcon(0));    // push false answer
 128     }
 129     return;
 130   }
 131 
 132   // Push the bool result back on stack
 133   Node* res = gen_instanceof(peek(), makecon(TypeKlassPtr::make(klass)), true);
 134 
 135   // Pop from stack AFTER gen_instanceof because it can uncommon trap.
 136   pop();
 137   push(res);
 138 }
 139 
 140 //------------------------------array_store_check------------------------------
 141 // pull array from stack and check that the store is valid
 142 void Parse::array_store_check() {
 143 
 144   // Shorthand access to array store elements without popping them.
 145   Node *obj = peek(0);
 146   Node *idx = peek(1);
 147   Node *ary = peek(2);
 148 
 149   if (_gvn.type(obj) == TypePtr::NULL_PTR) {
 150     // There's never a type check on null values.
 151     // This cutout lets us avoid the uncommon_trap(Reason_array_check)
 152     // below, which turns into a performance liability if the
 153     // gen_checkcast folds up completely.
 154     return;
 155   }
 156 
 157   // Extract the array klass type
 158   int klass_offset = oopDesc::klass_offset_in_bytes();
 159   Node* p = basic_plus_adr( ary, ary, klass_offset );
 160   // p's type is array-of-OOPS plus klass_offset
 161   Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS));
 162   // Get the array klass


 206                     Deoptimization::Action_maybe_recompile,
 207                     tak->klass());
 208     }
 209     if (stopped()) {          // MUST uncommon-trap?
 210       set_control(ctrl);      // Then Don't Do It, just fall into the normal checking
 211     } else {                  // Cast array klass to exactness:
 212       // Use the exact constant value we know it is.
 213       replace_in_map(array_klass,con);
 214       CompileLog* log = C->log();
 215       if (log != NULL) {
 216         log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
 217                   log->identify(tak->klass()));
 218       }
 219       array_klass = con;      // Use cast value moving forward
 220     }
 221   }
 222 
 223   // Come here for polymorphic array klasses
 224 
 225   // Extract the array element class
 226   int element_klass_offset = in_bytes(ObjArrayKlass::element_klass_offset());

 227   Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
 228   // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true,
 229   // we must set a control edge from the IfTrue node created by the uncommon_trap above to the
 230   // LoadKlassNode.
 231   Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL,
 232                                                        immutable_memory(), p2, tak));
 233 












 234   // Check (the hard way) and throw if not a subklass.
 235   // Result is ignored, we just need the CFG effects.
 236   gen_checkcast(obj, a_e_klass);

 237 }
 238 
 239 
 240 void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
 241   // Emit guarded new
 242   //   if (klass->_init_thread != current_thread ||
 243   //       klass->_init_state != being_initialized)
 244   //      uncommon_trap
 245   Node* cur_thread = _gvn.transform( new ThreadLocalNode() );
 246   Node* merge = new RegionNode(3);
 247   _gvn.set_type(merge, Type::CONTROL);
 248   Node* kls = makecon(TypeKlassPtr::make(klass));
 249 
 250   Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
 251   Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
 252   Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
 253   Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
 254   IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
 255   set_control(IfTrue(iff));
 256   merge->set_req(1, IfFalse(iff));




  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "ci/ciValueKlass.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "compiler/compileLog.hpp"
  29 #include "oops/objArrayKlass.hpp"
  30 #include "oops/valueArrayKlass.hpp"
  31 #include "opto/addnode.hpp"
  32 #include "opto/memnode.hpp"
  33 #include "opto/mulnode.hpp"
  34 #include "opto/parse.hpp"
  35 #include "opto/rootnode.hpp"
  36 #include "opto/runtime.hpp"
  37 #include "opto/valuetypenode.hpp"
  38 #include "runtime/sharedRuntime.hpp"
  39 
  40 //------------------------------make_dtrace_method_entry_exit ----------------
  41 // Dtrace -- record entry or exit of a method if compiled with dtrace support
  42 void GraphKit::make_dtrace_method_entry_exit(ciMethod* method, bool is_entry) {
  43   const TypeFunc *call_type    = OptoRuntime::dtrace_method_entry_exit_Type();
  44   address         call_address = is_entry ? CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry) :
  45                                             CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit);
  46   const char     *call_name    = is_entry ? "dtrace_method_entry" : "dtrace_method_exit";
  47 
  48   // Get base of thread-local storage area
  49   Node* thread = _gvn.transform( new ThreadLocalNode() );
  50 


 123     assert( stopped() || _gvn.type(peek())->higher_equal(TypePtr::NULL_PTR), "what's left behind is null" );
 124     if (!stopped()) {
 125       // The object is now known to be null.
 126       // Shortcut the effect of gen_instanceof and return "false" directly.
 127       pop();                   // pop the null
 128       push(_gvn.intcon(0));    // push false answer
 129     }
 130     return;
 131   }
 132 
 133   // Push the bool result back on stack
 134   Node* res = gen_instanceof(peek(), makecon(TypeKlassPtr::make(klass)), true);
 135 
 136   // Pop from stack AFTER gen_instanceof because it can uncommon trap.
 137   pop();
 138   push(res);
 139 }
 140 
 141 //------------------------------array_store_check------------------------------
 142 // pull array from stack and check that the store is valid
 143 void Parse::array_store_check(bool target_is_valuetypearray) {
 144 
 145   // Shorthand access to array store elements without popping them.
 146   Node *obj = peek(0);
 147   Node *idx = peek(1);
 148   Node *ary = peek(2);
 149 
 150   if (_gvn.type(obj) == TypePtr::NULL_PTR) {
 151     // There's never a type check on null values.
 152     // This cutout lets us avoid the uncommon_trap(Reason_array_check)
 153     // below, which turns into a performance liability if the
 154     // gen_checkcast folds up completely.
 155     return;
 156   }
 157 
 158   // Extract the array klass type
 159   int klass_offset = oopDesc::klass_offset_in_bytes();
 160   Node* p = basic_plus_adr( ary, ary, klass_offset );
 161   // p's type is array-of-OOPS plus klass_offset
 162   Node* array_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeInstPtr::KLASS));
 163   // Get the array klass


 207                     Deoptimization::Action_maybe_recompile,
 208                     tak->klass());
 209     }
 210     if (stopped()) {          // MUST uncommon-trap?
 211       set_control(ctrl);      // Then Don't Do It, just fall into the normal checking
 212     } else {                  // Cast array klass to exactness:
 213       // Use the exact constant value we know it is.
 214       replace_in_map(array_klass,con);
 215       CompileLog* log = C->log();
 216       if (log != NULL) {
 217         log->elem("cast_up reason='monomorphic_array' from='%d' to='(exact)'",
 218                   log->identify(tak->klass()));
 219       }
 220       array_klass = con;      // Use cast value moving forward
 221     }
 222   }
 223 
 224   // Come here for polymorphic array klasses
 225 
 226   // Extract the array element class
 227   int element_klass_offset = in_bytes(ArrayKlass::element_klass_offset());
 228 
 229   Node *p2 = basic_plus_adr(array_klass, array_klass, element_klass_offset);
 230   // We are allowed to use the constant type only if cast succeeded. If always_see_exact_class is true,
 231   // we must set a control edge from the IfTrue node created by the uncommon_trap above to the
 232   // LoadKlassNode.
 233   Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL,
 234                                                        immutable_memory(), p2, tak));
 235 
 236   if (target_is_valuetypearray) {
 237     ciKlass* target_elem_klass = gvn().type(a_e_klass)->is_klassptr()->klass();
 238     ciKlass* source_klass = gvn().type(obj)->is_valuetype()->value_klass();
 239     if (!target_elem_klass->equals(source_klass)) {
 240       Node* slow_ctl = type_check(a_e_klass, TypeKlassPtr::make(source_klass), 1.0);
 241       {
 242         PreserveJVMState pjvms(this);
 243         set_control(slow_ctl);
 244         builtin_throw(Deoptimization::Reason_class_check);
 245       }
 246     }
 247   } else {
 248     // Check (the hard way) and throw if not a subklass.
 249     // Result is ignored, we just need the CFG effects.
 250     gen_checkcast(obj, a_e_klass);
 251   }
 252 }
 253 
 254 
 255 void Parse::emit_guard_for_new(ciInstanceKlass* klass) {
 256   // Emit guarded new
 257   //   if (klass->_init_thread != current_thread ||
 258   //       klass->_init_state != being_initialized)
 259   //      uncommon_trap
 260   Node* cur_thread = _gvn.transform( new ThreadLocalNode() );
 261   Node* merge = new RegionNode(3);
 262   _gvn.set_type(merge, Type::CONTROL);
 263   Node* kls = makecon(TypeKlassPtr::make(klass));
 264 
 265   Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
 266   Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
 267   Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
 268   Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
 269   IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
 270   set_control(IfTrue(iff));
 271   merge->set_req(1, IfFalse(iff));


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