Skip to content

Commit b6d0ead

Browse files
author
Vladimir Kozlov
committed
8335221: Some C2 intrinsics incorrectly assume that type argument is compile-time constant
Reviewed-by: thartmann Backport-of: 166f9d9
1 parent 272d11a commit b6d0ead

File tree

2 files changed

+67
-38
lines changed

2 files changed

+67
-38
lines changed

src/hotspot/share/opto/library_call.cpp

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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-----------------------
54675499
bool 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-----------------------
55335563
bool 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

src/hotspot/share/opto/library_call.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ class LibraryCallKit : public GraphKit {
279279
JVMState* arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp);
280280
void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms_before_guards, int saved_reexecute_sp,
281281
uint new_idx);
282+
bool check_array_sort_arguments(Node* elementType, Node* obj, BasicType& bt);
282283
bool inline_array_sort();
283284
bool inline_array_partition();
284285
typedef enum { LS_get_add, LS_get_set, LS_cmp_swap, LS_cmp_swap_weak, LS_cmp_exchange } LoadStoreKind;

0 commit comments

Comments
 (0)