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 7267 : 8060252: JDK-7173584 compiler changes regress SPECjvm2008 on SPARC
Summary: arraycopy code misses opportunities to optimize copies to just allocated array.
Reviewed-by:


4594     set_i_o(        _gvn.transform(result_i_o));
4595     set_all_memory( _gvn.transform(result_mem));
4596   } // original reexecute is set back here
4597 
4598   set_result(_gvn.transform(result_val));
4599   return true;
4600 }
4601 
4602 //------------------------------inline_arraycopy-----------------------
4603 // public static native void java.lang.System.arraycopy(Object src,  int  srcPos,
4604 //                                                      Object dest, int destPos,
4605 //                                                      int length);
4606 bool LibraryCallKit::inline_arraycopy() {
4607   // Get the arguments.
4608   Node* src         = argument(0);  // type: oop
4609   Node* src_offset  = argument(1);  // type: int
4610   Node* dest        = argument(2);  // type: oop
4611   Node* dest_offset = argument(3);  // type: int
4612   Node* length      = argument(4);  // type: int
4613 




4614   // The following tests must be performed
4615   // (1) src and dest are arrays.
4616   // (2) src and dest arrays must have elements of the same BasicType
4617   // (3) src and dest must not be null.
4618   // (4) src_offset must not be negative.
4619   // (5) dest_offset must not be negative.
4620   // (6) length must not be negative.
4621   // (7) src_offset + length must not exceed length of src.
4622   // (8) dest_offset + length must not exceed length of dest.
4623   // (9) each element of an oop array must be assignable
4624 
4625   // (3) src and dest must not be null.
4626   // always do this here because we need the JVM state for uncommon traps
4627   src  = null_check(src,  T_ARRAY);
4628   dest = null_check(dest, T_ARRAY);
4629 
4630   bool notest = false;
4631 
4632   const Type* src_type  = _gvn.type(src);
4633   const Type* dest_type = _gvn.type(dest);


4767     if (not_subtype_ctrl != top()) {
4768       PreserveJVMState pjvms(this);
4769       set_control(not_subtype_ctrl);
4770       uncommon_trap(Deoptimization::Reason_intrinsic,
4771                     Deoptimization::Action_make_not_entrant);
4772       assert(stopped(), "Should be stopped");
4773     }
4774     {
4775       PreserveJVMState pjvms(this);
4776       set_control(_gvn.transform(slow_region));
4777       uncommon_trap(Deoptimization::Reason_intrinsic,
4778                     Deoptimization::Action_make_not_entrant);
4779       assert(stopped(), "Should be stopped");
4780     }
4781   }
4782 
4783   if (stopped()) {
4784     return true;
4785   }
4786 
4787   AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
4788   ArrayCopyNode* ac = ArrayCopyNode::make(this, true, src, src_offset, dest, dest_offset, length, alloc != NULL,
4789                                           // Create LoadRange and LoadKlass nodes for use during macro expansion here
4790                                           // so the compiler has a chance to eliminate them: during macro expansion,
4791                                           // we have to set their control (CastPP nodes are eliminated).
4792                                           load_object_klass(src), load_object_klass(dest),
4793                                           load_array_length(src), load_array_length(dest));
4794 
4795   if (notest) {
4796     ac->set_arraycopy_notest();
4797   }
4798 
4799   Node* n = _gvn.transform(ac);
4800   assert(n == ac, "cannot disappear");
4801   ac->connect_outputs(this);
4802 
4803   return true;
4804 }
4805 
4806 
4807 // Helper function which determines if an arraycopy immediately follows




4594     set_i_o(        _gvn.transform(result_i_o));
4595     set_all_memory( _gvn.transform(result_mem));
4596   } // original reexecute is set back here
4597 
4598   set_result(_gvn.transform(result_val));
4599   return true;
4600 }
4601 
4602 //------------------------------inline_arraycopy-----------------------
4603 // public static native void java.lang.System.arraycopy(Object src,  int  srcPos,
4604 //                                                      Object dest, int destPos,
4605 //                                                      int length);
4606 bool LibraryCallKit::inline_arraycopy() {
4607   // Get the arguments.
4608   Node* src         = argument(0);  // type: oop
4609   Node* src_offset  = argument(1);  // type: int
4610   Node* dest        = argument(2);  // type: oop
4611   Node* dest_offset = argument(3);  // type: int
4612   Node* length      = argument(4);  // type: int
4613 
4614   // Check for allocation before we add nodes that would confuse
4615   // tightly_coupled_allocation()
4616   AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL);
4617 
4618   // The following tests must be performed
4619   // (1) src and dest are arrays.
4620   // (2) src and dest arrays must have elements of the same BasicType
4621   // (3) src and dest must not be null.
4622   // (4) src_offset must not be negative.
4623   // (5) dest_offset must not be negative.
4624   // (6) length must not be negative.
4625   // (7) src_offset + length must not exceed length of src.
4626   // (8) dest_offset + length must not exceed length of dest.
4627   // (9) each element of an oop array must be assignable
4628 
4629   // (3) src and dest must not be null.
4630   // always do this here because we need the JVM state for uncommon traps
4631   src  = null_check(src,  T_ARRAY);
4632   dest = null_check(dest, T_ARRAY);
4633 
4634   bool notest = false;
4635 
4636   const Type* src_type  = _gvn.type(src);
4637   const Type* dest_type = _gvn.type(dest);


4771     if (not_subtype_ctrl != top()) {
4772       PreserveJVMState pjvms(this);
4773       set_control(not_subtype_ctrl);
4774       uncommon_trap(Deoptimization::Reason_intrinsic,
4775                     Deoptimization::Action_make_not_entrant);
4776       assert(stopped(), "Should be stopped");
4777     }
4778     {
4779       PreserveJVMState pjvms(this);
4780       set_control(_gvn.transform(slow_region));
4781       uncommon_trap(Deoptimization::Reason_intrinsic,
4782                     Deoptimization::Action_make_not_entrant);
4783       assert(stopped(), "Should be stopped");
4784     }
4785   }
4786 
4787   if (stopped()) {
4788     return true;
4789   }
4790 

4791   ArrayCopyNode* ac = ArrayCopyNode::make(this, true, src, src_offset, dest, dest_offset, length, alloc != NULL,
4792                                           // Create LoadRange and LoadKlass nodes for use during macro expansion here
4793                                           // so the compiler has a chance to eliminate them: during macro expansion,
4794                                           // we have to set their control (CastPP nodes are eliminated).
4795                                           load_object_klass(src), load_object_klass(dest),
4796                                           load_array_length(src), load_array_length(dest));
4797 
4798   if (notest) {
4799     ac->set_arraycopy_notest();
4800   }
4801 
4802   Node* n = _gvn.transform(ac);
4803   assert(n == ac, "cannot disappear");
4804   ac->connect_outputs(this);
4805 
4806   return true;
4807 }
4808 
4809 
4810 // Helper function which determines if an arraycopy immediately follows


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