src/share/vm/opto/graphKit.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/graphKit.hpp

Print this page
rev 6132 : 8031755: Type speculation should be used to optimize explicit null checks
Summary: feed profiling data about reference nullness to type speculation.
Reviewed-by:


 333   Node* CmpP(Node* l, Node* r)                { return _gvn.transform(new (C) CmpPNode(l, r));       }
 334   Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); }
 335 
 336   Node* AddP(Node* b, Node* a, Node* o)       { return _gvn.transform(new (C) AddPNode(b, a, o));    }
 337 
 338   // Convert between int and long, and size_t.
 339   // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.)
 340   Node* ConvI2L(Node* offset);
 341   Node* ConvL2I(Node* offset);
 342   // Find out the klass of an object.
 343   Node* load_object_klass(Node* object);
 344   // Find out the length of an array.
 345   Node* load_array_length(Node* array);
 346 
 347 
 348   // Helper function to do a NULL pointer check or ZERO check based on type.
 349   // Throw an exception if a given value is null.
 350   // Return the value cast to not-null.
 351   // Be clever about equivalent dominating null checks.
 352   Node* null_check_common(Node* value, BasicType type,
 353                           bool assert_null = false, Node* *null_control = NULL);


 354   Node* null_check(Node* value, BasicType type = T_OBJECT) {
 355     return null_check_common(value, type);
 356   }
 357   Node* null_check_receiver() {
 358     assert(argument(0)->bottom_type()->isa_ptr(), "must be");
 359     return null_check(argument(0));
 360   }
 361   Node* zero_check_int(Node* value) {
 362     assert(value->bottom_type()->basic_type() == T_INT,
 363         err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
 364     return null_check_common(value, T_INT);
 365   }
 366   Node* zero_check_long(Node* value) {
 367     assert(value->bottom_type()->basic_type() == T_LONG,
 368         err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
 369     return null_check_common(value, T_LONG);
 370   }
 371   // Throw an uncommon trap if a given value is __not__ null.
 372   // Return the value cast to null, and be clever about dominating checks.
 373   Node* null_assert(Node* value, BasicType type = T_OBJECT) {
 374     return null_check_common(value, type, true);
 375   }
 376 
 377   // Null check oop.  Return null-path control into (*null_control).
 378   // Return a cast-not-null node which depends on the not-null control.
 379   // If never_see_null, use an uncommon trap (*null_control sees a top).
 380   // The cast is not valid along the null path; keep a copy of the original.
 381   // If safe_for_replace, then we can replace the value with the cast
 382   // in the parsing map (the cast is guaranteed to dominate the map)
 383   Node* null_check_oop(Node* value, Node* *null_control,
 384                        bool never_see_null = false, bool safe_for_replace = false);


 385 
 386   // Check the null_seen bit.
 387   bool seems_never_null(Node* obj, ciProfileData* data);
 388 
 389   // Check for unique class for receiver at call
 390   ciKlass* profile_has_unique_klass() {
 391     ciCallProfile profile = method()->call_profile_at_bci(bci());
 392     if (profile.count() >= 0 &&         // no cast failures here
 393         profile.has_receiver(0) &&
 394         profile.morphism() == 1) {
 395       return profile.receiver(0);
 396     }
 397     return NULL;
 398   }
 399 
 400   // record type from profiling with the type system
 401   Node* record_profile_for_speculation(Node* n, ciKlass* exact_kls);
 402   Node* record_profiled_receiver_for_speculation(Node* n);
 403   void record_profiled_arguments_for_speculation(ciMethod* dest_method, Bytecodes::Code bc);
 404   void record_profiled_parameters_for_speculation();


 405 
 406   // Use the type profile to narrow an object type.
 407   Node* maybe_cast_profiled_receiver(Node* not_null_obj,
 408                                      ciKlass* require_klass,
 409                                      ciKlass* spec,
 410                                      bool safe_for_replace);
 411 
 412   // Cast obj to type and emit guard unless we had too many traps here already
 413   Node* maybe_cast_profiled_obj(Node* obj,
 414                                 ciKlass* type,
 415                                 bool not_null = false);
 416 
 417   // Cast obj to not-null on this path
 418   Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
 419   // Replace all occurrences of one node by another.
 420   void replace_in_map(Node* old, Node* neww);
 421 
 422   void  push(Node* n)     { map_not_null();        _map->set_stack(_map->_jvms,   _sp++        , n); }
 423   Node* pop()             { map_not_null(); return _map->stack(    _map->_jvms, --_sp             ); }
 424   Node* peek(int off = 0) { map_not_null(); return _map->stack(    _map->_jvms,   _sp - off - 1   ); }




 333   Node* CmpP(Node* l, Node* r)                { return _gvn.transform(new (C) CmpPNode(l, r));       }
 334   Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); }
 335 
 336   Node* AddP(Node* b, Node* a, Node* o)       { return _gvn.transform(new (C) AddPNode(b, a, o));    }
 337 
 338   // Convert between int and long, and size_t.
 339   // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.)
 340   Node* ConvI2L(Node* offset);
 341   Node* ConvL2I(Node* offset);
 342   // Find out the klass of an object.
 343   Node* load_object_klass(Node* object);
 344   // Find out the length of an array.
 345   Node* load_array_length(Node* array);
 346 
 347 
 348   // Helper function to do a NULL pointer check or ZERO check based on type.
 349   // Throw an exception if a given value is null.
 350   // Return the value cast to not-null.
 351   // Be clever about equivalent dominating null checks.
 352   Node* null_check_common(Node* value, BasicType type,
 353                           bool assert_null = false,
 354                           Node* *null_control = NULL,
 355                           bool speculative = false);
 356   Node* null_check(Node* value, BasicType type = T_OBJECT) {
 357     return null_check_common(value, type, false, NULL, !_gvn.type(value)->speculative_maybe_null());
 358   }
 359   Node* null_check_receiver() {
 360     assert(argument(0)->bottom_type()->isa_ptr(), "must be");
 361     return null_check(argument(0));
 362   }
 363   Node* zero_check_int(Node* value) {
 364     assert(value->bottom_type()->basic_type() == T_INT,
 365         err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
 366     return null_check_common(value, T_INT);
 367   }
 368   Node* zero_check_long(Node* value) {
 369     assert(value->bottom_type()->basic_type() == T_LONG,
 370         err_msg_res("wrong type: %s", type2name(value->bottom_type()->basic_type())));
 371     return null_check_common(value, T_LONG);
 372   }
 373   // Throw an uncommon trap if a given value is __not__ null.
 374   // Return the value cast to null, and be clever about dominating checks.
 375   Node* null_assert(Node* value, BasicType type = T_OBJECT) {
 376     return null_check_common(value, type, true);
 377   }
 378 
 379   // Null check oop.  Return null-path control into (*null_control).
 380   // Return a cast-not-null node which depends on the not-null control.
 381   // If never_see_null, use an uncommon trap (*null_control sees a top).
 382   // The cast is not valid along the null path; keep a copy of the original.
 383   // If safe_for_replace, then we can replace the value with the cast
 384   // in the parsing map (the cast is guaranteed to dominate the map)
 385   Node* null_check_oop(Node* value, Node* *null_control,
 386                        bool never_see_null = false,
 387                        bool safe_for_replace = false,
 388                        bool speculative = false);
 389 
 390   // Check the null_seen bit.
 391   bool seems_never_null(Node* obj, ciProfileData* data, bool& speculating);
 392 
 393   // Check for unique class for receiver at call
 394   ciKlass* profile_has_unique_klass() {
 395     ciCallProfile profile = method()->call_profile_at_bci(bci());
 396     if (profile.count() >= 0 &&         // no cast failures here
 397         profile.has_receiver(0) &&
 398         profile.morphism() == 1) {
 399       return profile.receiver(0);
 400     }
 401     return NULL;
 402   }
 403 
 404   // record type from profiling with the type system
 405   Node* record_profile_for_speculation(Node* n, ciKlass* exact_kls, bool maybe_null);

 406   void record_profiled_arguments_for_speculation(ciMethod* dest_method, Bytecodes::Code bc);
 407   void record_profiled_parameters_for_speculation();
 408   void record_profiled_return_for_speculation();
 409   Node* record_profiled_receiver_for_speculation(Node* n);
 410 
 411   // Use the type profile to narrow an object type.
 412   Node* maybe_cast_profiled_receiver(Node* not_null_obj,
 413                                      ciKlass* require_klass,
 414                                      ciKlass* spec,
 415                                      bool safe_for_replace);
 416 
 417   // Cast obj to type and emit guard unless we had too many traps here already
 418   Node* maybe_cast_profiled_obj(Node* obj,
 419                                 ciKlass* type,
 420                                 bool not_null = false);
 421 
 422   // Cast obj to not-null on this path
 423   Node* cast_not_null(Node* obj, bool do_replace_in_map = true);
 424   // Replace all occurrences of one node by another.
 425   void replace_in_map(Node* old, Node* neww);
 426 
 427   void  push(Node* n)     { map_not_null();        _map->set_stack(_map->_jvms,   _sp++        , n); }
 428   Node* pop()             { map_not_null(); return _map->stack(    _map->_jvms, --_sp             ); }
 429   Node* peek(int off = 0) { map_not_null(); return _map->stack(    _map->_jvms,   _sp - off - 1   ); }


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