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

src/share/vm/opto/library_call.cpp

Print this page
rev 7901 : 8073796: assert(check_obj_alignment(result)) failed: address not aligned: ...
Summary: Arrays.copyOf intrinsic can deoptimize with uninitialized new array
Reviewed-by:


3852 
3853     // Bail out if length is negative.
3854     // Without this the new_array would throw
3855     // NegativeArraySizeException but IllegalArgumentException is what
3856     // should be thrown
3857     generate_negative_guard(length, bailout, &length);
3858 
3859     if (bailout->req() > 1) {
3860       PreserveJVMState pjvms(this);
3861       set_control(_gvn.transform(bailout));
3862       uncommon_trap(Deoptimization::Reason_intrinsic,
3863                     Deoptimization::Action_maybe_recompile);
3864     }
3865 
3866     if (!stopped()) {
3867       // How many elements will we copy from the original?
3868       // The answer is MinI(orig_length - start, length).
3869       Node* orig_tail = _gvn.transform(new SubINode(orig_length, start));
3870       Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
3871 
3872       newcopy = new_array(klass_node, length, 0);  // no arguments to push
3873 
3874       // Generate a direct call to the right arraycopy function(s).
3875       // We know the copy is disjoint but we might not know if the
3876       // oop stores need checking.
3877       // Extreme case:  Arrays.copyOf((Integer[])x, 10, String[].class).
3878       // This will fail a store-check if x contains any non-nulls.
3879 
3880       // ArrayCopyNode:Ideal may transform the ArrayCopyNode to
3881       // loads/stores but it is legal only if we're sure the
3882       // Arrays.copyOf would succeed. So we need all input arguments
3883       // to the copyOf to be validated, including that the copy to the
3884       // new array won't trigger an ArrayStoreException. That subtype
3885       // check can be optimized if we know something on the type of
3886       // the input array from type speculation.
3887       if (_gvn.type(klass_node)->singleton()) {
3888         ciKlass* subk   = _gvn.type(load_object_klass(original))->is_klassptr()->klass();
3889         ciKlass* superk = _gvn.type(klass_node)->is_klassptr()->klass();
3890 
3891         int test = C->static_subtype_check(superk, subk);
3892         if (test != Compile::SSC_always_true && test != Compile::SSC_always_false) {
3893           const TypeOopPtr* t_original = _gvn.type(original)->is_oopptr();


3896           }
3897         }
3898       }
3899 
3900       bool validated = false;
3901       // Reason_class_check rather than Reason_intrinsic because we
3902       // want to intrinsify even if this traps.
3903       if (!too_many_traps(Deoptimization::Reason_class_check)) {
3904         Node* not_subtype_ctrl = gen_subtype_check(load_object_klass(original),
3905                                                    klass_node);
3906 
3907         if (not_subtype_ctrl != top()) {
3908           PreserveJVMState pjvms(this);
3909           set_control(not_subtype_ctrl);
3910           uncommon_trap(Deoptimization::Reason_class_check,
3911                         Deoptimization::Action_make_not_entrant);
3912           assert(stopped(), "Should be stopped");
3913         }
3914         validated = true;
3915       }


3916 
3917       ArrayCopyNode* ac = ArrayCopyNode::make(this, true, original, start, newcopy, intcon(0), moved, true,
3918                                               load_object_klass(original), klass_node);
3919       if (!is_copyOfRange) {
3920         ac->set_copyof(validated);
3921       } else {
3922         ac->set_copyofrange(validated);
3923       }
3924       Node* n = _gvn.transform(ac);
3925       if (n == ac) {
3926         ac->connect_outputs(this);
3927       } else {
3928         assert(validated, "shouldn't transform if all arguments not validated");
3929         set_all_memory(n);
3930       }
3931     }
3932   } // original reexecute is set back here
3933 
3934   C->set_has_split_ifs(true); // Has chance for split-if optimization
3935   if (!stopped()) {




3852 
3853     // Bail out if length is negative.
3854     // Without this the new_array would throw
3855     // NegativeArraySizeException but IllegalArgumentException is what
3856     // should be thrown
3857     generate_negative_guard(length, bailout, &length);
3858 
3859     if (bailout->req() > 1) {
3860       PreserveJVMState pjvms(this);
3861       set_control(_gvn.transform(bailout));
3862       uncommon_trap(Deoptimization::Reason_intrinsic,
3863                     Deoptimization::Action_maybe_recompile);
3864     }
3865 
3866     if (!stopped()) {
3867       // How many elements will we copy from the original?
3868       // The answer is MinI(orig_length - start, length).
3869       Node* orig_tail = _gvn.transform(new SubINode(orig_length, start));
3870       Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
3871 


3872       // Generate a direct call to the right arraycopy function(s).
3873       // We know the copy is disjoint but we might not know if the
3874       // oop stores need checking.
3875       // Extreme case:  Arrays.copyOf((Integer[])x, 10, String[].class).
3876       // This will fail a store-check if x contains any non-nulls.
3877 
3878       // ArrayCopyNode:Ideal may transform the ArrayCopyNode to
3879       // loads/stores but it is legal only if we're sure the
3880       // Arrays.copyOf would succeed. So we need all input arguments
3881       // to the copyOf to be validated, including that the copy to the
3882       // new array won't trigger an ArrayStoreException. That subtype
3883       // check can be optimized if we know something on the type of
3884       // the input array from type speculation.
3885       if (_gvn.type(klass_node)->singleton()) {
3886         ciKlass* subk   = _gvn.type(load_object_klass(original))->is_klassptr()->klass();
3887         ciKlass* superk = _gvn.type(klass_node)->is_klassptr()->klass();
3888 
3889         int test = C->static_subtype_check(superk, subk);
3890         if (test != Compile::SSC_always_true && test != Compile::SSC_always_false) {
3891           const TypeOopPtr* t_original = _gvn.type(original)->is_oopptr();


3894           }
3895         }
3896       }
3897 
3898       bool validated = false;
3899       // Reason_class_check rather than Reason_intrinsic because we
3900       // want to intrinsify even if this traps.
3901       if (!too_many_traps(Deoptimization::Reason_class_check)) {
3902         Node* not_subtype_ctrl = gen_subtype_check(load_object_klass(original),
3903                                                    klass_node);
3904 
3905         if (not_subtype_ctrl != top()) {
3906           PreserveJVMState pjvms(this);
3907           set_control(not_subtype_ctrl);
3908           uncommon_trap(Deoptimization::Reason_class_check,
3909                         Deoptimization::Action_make_not_entrant);
3910           assert(stopped(), "Should be stopped");
3911         }
3912         validated = true;
3913       }
3914 
3915       newcopy = new_array(klass_node, length, 0);  // no arguments to push
3916 
3917       ArrayCopyNode* ac = ArrayCopyNode::make(this, true, original, start, newcopy, intcon(0), moved, true,
3918                                               load_object_klass(original), klass_node);
3919       if (!is_copyOfRange) {
3920         ac->set_copyof(validated);
3921       } else {
3922         ac->set_copyofrange(validated);
3923       }
3924       Node* n = _gvn.transform(ac);
3925       if (n == ac) {
3926         ac->connect_outputs(this);
3927       } else {
3928         assert(validated, "shouldn't transform if all arguments not validated");
3929         set_all_memory(n);
3930       }
3931     }
3932   } // original reexecute is set back here
3933 
3934   C->set_has_split_ifs(true); // Has chance for split-if optimization
3935   if (!stopped()) {


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