@@ -5463,42 +5463,72 @@ void LibraryCallKit::create_new_uncommon_trap(CallStaticJavaNode* uncommon_trap_
54635463 uncommon_trap_call->set_req (0 , top ()); // not used anymore, kill it
54645464}
54655465
5466+ // Common checks for array sorting intrinsics arguments.
5467+ // Returns `true` if checks passed.
5468+ bool LibraryCallKit::check_array_sort_arguments (Node* elementType, Node* obj, BasicType& bt) {
5469+ // check address of the class
5470+ if (elementType == nullptr || elementType->is_top ()) {
5471+ return false ; // dead path
5472+ }
5473+ const TypeInstPtr* elem_klass = gvn ().type (elementType)->isa_instptr ();
5474+ if (elem_klass == nullptr ) {
5475+ return false ; // dead path
5476+ }
5477+ // java_mirror_type() returns non-null for compile-time Class constants only
5478+ ciType* elem_type = elem_klass->java_mirror_type ();
5479+ if (elem_type == nullptr ) {
5480+ return false ;
5481+ }
5482+ bt = elem_type->basic_type ();
5483+ // Disable the intrinsic if the CPU does not support SIMD sort
5484+ if (!Matcher::supports_simd_sort (bt)) {
5485+ return false ;
5486+ }
5487+ // check address of the array
5488+ if (obj == nullptr || obj->is_top ()) {
5489+ return false ; // dead path
5490+ }
5491+ const TypeAryPtr* obj_t = _gvn.type (obj)->isa_aryptr ();
5492+ if (obj_t == nullptr || obj_t ->elem () == Type::BOTTOM) {
5493+ return false ; // failed input validation
5494+ }
5495+ return true ;
5496+ }
5497+
54665498// ------------------------------inline_array_partition-----------------------
54675499bool LibraryCallKit::inline_array_partition () {
5500+ address stubAddr = StubRoutines::select_array_partition_function ();
5501+ if (stubAddr == nullptr ) {
5502+ return false ; // Intrinsic's stub is not implemented on this platform
5503+ }
5504+ assert (callee ()->signature ()->size () == 9 , " arrayPartition has 8 parameters (one long)" );
54685505
5469- Node* elementType = null_check (argument (0 ));
5506+ // no receiver because it is a static method
5507+ Node* elementType = argument (0 );
54705508 Node* obj = argument (1 );
5471- Node* offset = argument (2 );
5509+ Node* offset = argument (2 ); // long
54725510 Node* fromIndex = argument (4 );
54735511 Node* toIndex = argument (5 );
54745512 Node* indexPivot1 = argument (6 );
54755513 Node* indexPivot2 = argument (7 );
5514+ // PartitionOperation: argument(8) is ignored
54765515
54775516 Node* pivotIndices = nullptr ;
5517+ BasicType bt = T_ILLEGAL;
54785518
5519+ if (!check_array_sort_arguments (elementType, obj, bt)) {
5520+ return false ;
5521+ }
5522+ null_check (obj);
5523+ // If obj is dead, only null-path is taken.
5524+ if (stopped ()) {
5525+ return true ;
5526+ }
54795527 // Set the original stack and the reexecute bit for the interpreter to reexecute
54805528 // the bytecode that invokes DualPivotQuicksort.partition() if deoptimization happens.
54815529 { PreserveReexecuteState preexecs (this );
54825530 jvms ()->set_should_reexecute (true );
54835531
5484- const TypeInstPtr* elem_klass = gvn ().type (elementType)->isa_instptr ();
5485- ciType* elem_type = elem_klass->const_oop ()->as_instance ()->java_mirror_type ();
5486- BasicType bt = elem_type->basic_type ();
5487- // Disable the intrinsic if the CPU does not support SIMD sort
5488- if (!Matcher::supports_simd_sort (bt)) {
5489- return false ;
5490- }
5491- address stubAddr = nullptr ;
5492- stubAddr = StubRoutines::select_array_partition_function ();
5493- // stub not loaded
5494- if (stubAddr == nullptr ) {
5495- return false ;
5496- }
5497- // get the address of the array
5498- const TypeAryPtr* obj_t = _gvn.type (obj)->isa_aryptr ();
5499- if (obj_t == nullptr || obj_t ->elem () == Type::BOTTOM ) {
5500- return false ; // failed input validation
5501- }
55025532 Node* obj_adr = make_unsafe_address (obj, offset);
55035533
55045534 // create the pivotIndices array of type int and size = 2
@@ -5531,31 +5561,29 @@ bool LibraryCallKit::inline_array_partition() {
55315561
55325562// ------------------------------inline_array_sort-----------------------
55335563bool LibraryCallKit::inline_array_sort () {
5564+ address stubAddr = StubRoutines::select_arraysort_function ();
5565+ if (stubAddr == nullptr ) {
5566+ return false ; // Intrinsic's stub is not implemented on this platform
5567+ }
5568+ assert (callee ()->signature ()->size () == 7 , " arraySort has 6 parameters (one long)" );
55345569
5535- Node* elementType = null_check (argument (0 ));
5570+ // no receiver because it is a static method
5571+ Node* elementType = argument (0 );
55365572 Node* obj = argument (1 );
5537- Node* offset = argument (2 );
5573+ Node* offset = argument (2 ); // long
55385574 Node* fromIndex = argument (4 );
55395575 Node* toIndex = argument (5 );
5576+ // SortOperation: argument(6) is ignored
55405577
5541- const TypeInstPtr* elem_klass = gvn ().type (elementType)->isa_instptr ();
5542- ciType* elem_type = elem_klass->const_oop ()->as_instance ()->java_mirror_type ();
5543- BasicType bt = elem_type->basic_type ();
5544- // Disable the intrinsic if the CPU does not support SIMD sort
5545- if (!Matcher::supports_simd_sort (bt)) {
5546- return false ;
5547- }
5548- address stubAddr = nullptr ;
5549- stubAddr = StubRoutines::select_arraysort_function ();
5550- // stub not loaded
5551- if (stubAddr == nullptr ) {
5578+ BasicType bt = T_ILLEGAL;
5579+
5580+ if (!check_array_sort_arguments (elementType, obj, bt)) {
55525581 return false ;
55535582 }
5554-
5555- // get address of the array
5556- const TypeAryPtr* obj_t = _gvn.type (obj)->isa_aryptr ();
5557- if (obj_t == nullptr || obj_t ->elem () == Type::BOTTOM ) {
5558- return false ; // failed input validation
5583+ null_check (obj);
5584+ // If obj is dead, only null-path is taken.
5585+ if (stopped ()) {
5586+ return true ;
55595587 }
55605588 Node* obj_adr = make_unsafe_address (obj, offset);
55615589
0 commit comments