Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/hotspot/share/ci/ciFlatArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,33 @@ ciConstant ciFlatArray::field_value_by_offset(intptr_t field_offset) {
}

ciConstant ciFlatArray::field_value(int index, ciField* field) {
auto get_field_from_object_constant = [field](const ciConstant& v) -> ciConstant {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really agree with this fix, ciFlatArray::field_value should be dumber, it is the caller who knows that we do not fold the load if the element is null, the callee should just return the field as it is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear I don't understand. Let's say, I have a flat array MyValue[] arr where MyValue is a value class with a single field f. Let's also assume arr[0] == null, arr.field_value(0, f) (assuming the ci... versions of it with matching names) tries to get the constant value of the field f of arr[0], and arr[0].f is not null, it's rather undefined. It's not about stability and folding. On the other hand, if arr[0] is not null, but arr[0].f is null, arr.field_value(0, f) already returns null (the ciConstant that means that).

Am I missing something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is only true from the Java perspective. From the VM perspective, a flat array would be something like (C++ pseudocode):

class MyValuePayload {
  oop* f;
  bool null_marker;
};

MyValuePayload* arr = new MyValuePayload[n];

Then, it is clear that even if arr[0].null_marker == false, arr[0].f is still defined and has a value (which should be nullptr).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, I'm trying change that.

ciObject* obj = v.as_object();
if (obj->is_null_object()) {
return ciConstant();
}
// obj cannot be an ciArray since it is an element of a flat array, so it must be a value class, which arrays are not.
ciInstance* inst = obj->as_instance();
if (field == nullptr) {
return inst->null_marker_value();
}
return inst->field_value(field);
};

BasicType elembt = element_basic_type();
ciConstant value = check_constant_value_cache(index, elembt);
if (value.is_valid()) {
if (field == nullptr) {
return value.as_object()->as_instance()->null_marker_value();
}
return value.as_object()->as_instance()->field_value(field);
return get_field_from_object_constant(value);
}
GUARDED_VM_ENTRY(
value = element_value_impl(T_OBJECT, get_arrayOop(), index);
)

add_to_constant_value_cache(index, value);

if (field == nullptr) {
return value.as_object()->as_instance()->null_marker_value();
if (!value.is_valid()) {
return ciConstant();
}
return value.as_object()->as_instance()->field_value(field);

add_to_constant_value_cache(index, value);
return get_field_from_object_constant(value);
}

2 changes: 1 addition & 1 deletion src/hotspot/share/opto/type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static const Type* make_constant_from_flat_array_element(ciFlatArray* array, int
// Decode the results of GraphKit::array_element_address.
ciConstant element_value = array->field_value_by_offset(off + field_offset);
if (element_value.basic_type() == T_ILLEGAL) {
return nullptr; // wrong offset
return nullptr; // wrong offset, or the array element at offset off is null.
}
ciConstant con = check_mismatched_access(element_value, loadbt, is_unsigned_load);

Expand Down