|
30 | 30 | #include "ci/ciUtilities.inline.hpp" |
31 | 31 | #include "oops/oop.inline.hpp" |
32 | 32 |
|
33 | | -ciConstant ciFlatArray::null_marker_of_element_by_offset_impl(arrayOop ary, int index) { |
34 | | - if (ary == nullptr) { |
35 | | - return ciConstant(); |
36 | | - } |
37 | | - assert(ary->is_array(), ""); |
38 | | - if (index < 0 || index >= ary->length()) { |
39 | | - return ciConstant(); |
40 | | - } |
41 | | - assert(ary->is_objArray(), ""); |
42 | | - flatArrayOop objary = (flatArrayOop) ary; |
43 | | - jboolean elem = objary->null_marker_of_obj_at(index); |
44 | | - return ciConstant(T_BOOLEAN, elem); |
45 | | -} |
46 | | - |
47 | | -ciConstant ciFlatArray::check_constant_null_marker_cache(int off) { |
48 | | - if (_constant_null_markers != nullptr) { |
49 | | - for (int i = 0; i < _constant_null_markers->length(); ++i) { |
50 | | - ConstantValue cached_val = _constant_null_markers->at(i); |
51 | | - if (cached_val.off() == off) { |
52 | | - return cached_val.value(); |
53 | | - } |
54 | | - } |
55 | | - } |
56 | | - return ciConstant(); |
57 | | -} |
58 | | - |
59 | | -void ciFlatArray::add_to_constant_null_marker_cache(int off, ciConstant val) { |
60 | | - assert(val.is_valid(), "value must be valid"); |
61 | | - assert(!check_constant_value_cache(off, val.basic_type()).is_valid(), "duplicate"); |
62 | | - if (_constant_null_markers == nullptr) { |
63 | | - Arena* arena = CURRENT_ENV->arena(); |
64 | | - _constant_null_markers = new (arena) GrowableArray<ConstantValue>(arena, 1, 0, ConstantValue()); |
65 | | - } |
66 | | - _constant_null_markers->append(ConstantValue(off, val)); |
67 | | -} |
68 | | - |
69 | 33 | // Current value of an element. |
70 | 34 | // Returns T_ILLEGAL if there is no element at the given index. |
71 | 35 | ciConstant ciFlatArray::null_marker_of_element_by_index(int index) { |
72 | | - ciConstant value = check_constant_null_marker_cache(index); |
73 | | - if (value.is_valid()) { |
74 | | - return value; |
75 | | - } |
76 | | - GUARDED_VM_ENTRY( |
77 | | - value = null_marker_of_element_by_offset_impl(get_arrayOop(), index);) |
78 | | - add_to_constant_null_marker_cache(index, value); |
79 | | - return value; |
| 36 | + ciConstant nm = field_value(index, nullptr); |
| 37 | + postcond(!nm.is_valid() || nm.basic_type() == T_BOOLEAN); |
| 38 | + return nm; |
80 | 39 | } |
81 | 40 |
|
82 | 41 | ciConstant ciFlatArray::null_marker_of_element_by_offset(intptr_t element_offset) { |
@@ -133,23 +92,36 @@ ciConstant ciFlatArray::field_value_by_offset(intptr_t field_offset) { |
133 | 92 | } |
134 | 93 |
|
135 | 94 | ciConstant ciFlatArray::field_value(int index, ciField* field) { |
| 95 | + auto get_field_from_object_constant = [field](const ciConstant& v) -> ciConstant { |
| 96 | + ciObject* obj = v.as_object(); |
| 97 | + if (obj->is_null_object()) { |
| 98 | + if (field == nullptr) { |
| 99 | + return ciConstant::make_zero_or_null(T_BOOLEAN); |
| 100 | + } |
| 101 | + return ciConstant::make_zero_or_null(field->type()->basic_type()); |
| 102 | + } |
| 103 | + // 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. |
| 104 | + ciInstance* inst = obj->as_instance(); |
| 105 | + if (field == nullptr) { |
| 106 | + return ciConstant(T_BOOLEAN, 1); |
| 107 | + } |
| 108 | + return inst->field_value(field); |
| 109 | + }; |
| 110 | + |
136 | 111 | BasicType elembt = element_basic_type(); |
137 | 112 | ciConstant value = check_constant_value_cache(index, elembt); |
138 | 113 | if (value.is_valid()) { |
139 | | - if (field == nullptr) { |
140 | | - return value.as_object()->as_instance()->null_marker_value(); |
141 | | - } |
142 | | - return value.as_object()->as_instance()->field_value(field); |
| 114 | + return get_field_from_object_constant(value); |
143 | 115 | } |
144 | 116 | GUARDED_VM_ENTRY( |
145 | 117 | value = element_value_impl(T_OBJECT, get_arrayOop(), index); |
146 | 118 | ) |
147 | 119 |
|
148 | | - add_to_constant_value_cache(index, value); |
149 | | - |
150 | | - if (field == nullptr) { |
151 | | - return value.as_object()->as_instance()->null_marker_value(); |
| 120 | + if (!value.is_valid()) { |
| 121 | + return ciConstant(); |
152 | 122 | } |
153 | | - return value.as_object()->as_instance()->field_value(field); |
| 123 | + |
| 124 | + add_to_constant_value_cache(index, value); |
| 125 | + return get_field_from_object_constant(value); |
154 | 126 | } |
155 | 127 |
|
0 commit comments