@@ -413,6 +413,43 @@ Node* CastLLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
413413 return nullptr ;
414414}
415415
416+ // CastPPNodes are removed before matching, while alias classes are needed in global code motion.
417+ // As a result, it is not valid for a CastPPNode to change the oop such that the derived pointers
418+ // lie in different alias classes with and without the node. For example, a CastPPNode c may not
419+ // cast an Object to a Bottom[], because later removal of c would affect the alias class of c's
420+ // array length field (c + arrayOopDesc::length_offset_in_bytes()).
421+ //
422+ // This function verifies that a CastPPNode on an oop does not violate the aforementioned property.
423+ //
424+ // TODO 8382147: Currently, this verification only applies during the construction of a CastPPNode,
425+ // we may want to apply the same verification during IGVN transformations, as well as final graph
426+ // reshaping.
427+ void CastPPNode::verify_type (const Type* in_type, const Type* out_type) {
428+ #ifdef ASSERT
429+ out_type = out_type->join (in_type);
430+ if (in_type->empty () || out_type->empty ()) {
431+ return ;
432+ }
433+ if (in_type == TypePtr::NULL_PTR || out_type == TypePtr::NULL_PTR) {
434+ return ;
435+ }
436+ if (!in_type->isa_oopptr () && !out_type->isa_oopptr ()) {
437+ return ;
438+ }
439+
440+ assert (in_type->isa_oopptr () && out_type->isa_oopptr (), " must be both oops or both non-oops" );
441+ if (in_type->isa_aryptr () && out_type->isa_aryptr ()) {
442+ const Type* e1 = in_type->is_aryptr ()->elem ();
443+ const Type* e2 = out_type->is_aryptr ()->elem ();
444+ assert (e1 ->basic_type () == e2 ->basic_type (), " must both be arrays of the same primitive type or both be oops arrays" );
445+ return ;
446+ }
447+
448+ assert (in_type->isa_instptr () && out_type->isa_instptr (), " must be both array oops or both non-array oops" );
449+ assert (in_type->is_instptr ()->instance_klass () == out_type->is_instptr ()->instance_klass (), " must not cast to a different type" );
450+ #endif // ASSERT
451+ }
452+
416453// ------------------------------Value------------------------------------------
417454// Take 'join' of input and cast-up type, unless working with an Interface
418455const Type* CheckCastPPNode::Value (PhaseGVN* phase) const {
@@ -440,6 +477,11 @@ const Type* CheckCastPPNode::Value(PhaseGVN* phase) const {
440477 return result;
441478}
442479
480+ Node* CheckCastPPNode::pin_node_under_control_impl () const {
481+ assert (_dependency.is_floating (), " already pinned" );
482+ return new CheckCastPPNode (in (0 ), in (1 ), bottom_type (), _dependency.with_pinned_dependency (), _extra_types);
483+ }
484+
443485// =============================================================================
444486// ------------------------------Value------------------------------------------
445487const Type* CastX2PNode::Value (PhaseGVN* phase) const {
0 commit comments