20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "ci/ciArray.hpp"
26 #include "ci/ciArrayKlass.hpp"
27 #include "ci/ciConstant.hpp"
28 #include "ci/ciKlass.hpp"
29 #include "ci/ciUtilities.inline.hpp"
30 #include "oops/objArrayOop.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "oops/typeArrayOop.inline.hpp"
33 #include "utilities/powerOfTwo.hpp"
34
35 // ciArray
36 //
37 // This class represents an arrayOop in the HotSpot virtual
38 // machine.
39 static BasicType fixup_element_type(BasicType bt) {
40 if (is_reference_type(bt)) return T_OBJECT;
41 if (bt == T_BOOLEAN) return T_BYTE;
42 return bt;
43 }
44
45 ciConstant ciArray::element_value_impl(BasicType elembt,
46 arrayOop ary,
47 int index) {
48 if (ary == nullptr)
49 return ciConstant();
50 assert(ary->is_array(), "");
51 if (index < 0 || index >= ary->length())
52 return ciConstant();
53 ArrayKlass* ak = (ArrayKlass*) ary->klass();
54 BasicType abt = ak->element_type();
55 if (fixup_element_type(elembt) !=
56 fixup_element_type(abt))
57 return ciConstant();
58 switch (elembt) {
59 case T_ARRAY:
102 return value;
103 }
104
105 // ------------------------------------------------------------------
106 // ciArray::element_value_by_offset
107 //
108 // Current value of an element at the specified offset.
109 // Returns T_ILLEGAL if there is no element at the given offset.
110 ciConstant ciArray::element_value_by_offset(intptr_t element_offset) {
111 BasicType elembt = element_basic_type();
112 intptr_t shift = exact_log2(type2aelembytes(elembt));
113 intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt);
114 intptr_t index = (element_offset - header) >> shift;
115 intptr_t offset = header + ((intptr_t)index << shift);
116 if (offset != element_offset || index != (jint)index || index < 0 || index >= length()) {
117 return ciConstant();
118 }
119 return element_value((jint) index);
120 }
121
122 // ------------------------------------------------------------------
123 // ciArray::print_impl
124 //
125 // Implementation of the print method.
126 void ciArray::print_impl(outputStream* st) {
127 st->print(" length=%d type=", length());
128 klass()->print(st);
129 }
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "ci/ciArray.hpp"
26 #include "ci/ciArrayKlass.hpp"
27 #include "ci/ciConstant.hpp"
28 #include "ci/ciKlass.hpp"
29 #include "ci/ciUtilities.inline.hpp"
30 #include "oops/objArrayOop.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "oops/typeArrayOop.inline.hpp"
33 #include "utilities/powerOfTwo.hpp"
34
35 // ciArray
36 //
37 // This class represents an arrayOop in the HotSpot virtual
38 // machine.
39 static BasicType fixup_element_type(BasicType bt) {
40 if (bt == T_FLAT_ELEMENT) return T_OBJECT;
41 if (is_reference_type(bt)) return T_OBJECT;
42 if (bt == T_BOOLEAN) return T_BYTE;
43 return bt;
44 }
45
46 ciConstant ciArray::element_value_impl(BasicType elembt,
47 arrayOop ary,
48 int index) {
49 if (ary == nullptr)
50 return ciConstant();
51 assert(ary->is_array(), "");
52 if (index < 0 || index >= ary->length())
53 return ciConstant();
54 ArrayKlass* ak = (ArrayKlass*) ary->klass();
55 BasicType abt = ak->element_type();
56 if (fixup_element_type(elembt) !=
57 fixup_element_type(abt))
58 return ciConstant();
59 switch (elembt) {
60 case T_ARRAY:
103 return value;
104 }
105
106 // ------------------------------------------------------------------
107 // ciArray::element_value_by_offset
108 //
109 // Current value of an element at the specified offset.
110 // Returns T_ILLEGAL if there is no element at the given offset.
111 ciConstant ciArray::element_value_by_offset(intptr_t element_offset) {
112 BasicType elembt = element_basic_type();
113 intptr_t shift = exact_log2(type2aelembytes(elembt));
114 intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt);
115 intptr_t index = (element_offset - header) >> shift;
116 intptr_t offset = header + ((intptr_t)index << shift);
117 if (offset != element_offset || index != (jint)index || index < 0 || index >= length()) {
118 return ciConstant();
119 }
120 return element_value((jint) index);
121 }
122
123 bool ciArray::is_null_free() {
124 VM_ENTRY_MARK;
125 return get_oop()->is_null_free_array();
126 }
127
128 bool ciArray::is_atomic() {
129 VM_ENTRY_MARK;
130 arrayOop oop = get_arrayOop();
131 if (oop->is_refArray()) {
132 return oop->klass()->is_inline_klass();
133 }
134 if (oop->is_flatArray()) {
135 FlatArrayKlass* fak = FlatArrayKlass::cast(oop->klass());
136 if (fak->element_klass()->is_naturally_atomic() || fak->layout_kind() == LayoutKind::ATOMIC_FLAT || fak->layout_kind() == LayoutKind::NULLABLE_ATOMIC_FLAT) {
137 return true;
138 }
139 }
140 return false;
141 }
142
143 // ------------------------------------------------------------------
144 // ciArray::print_impl
145 //
146 // Implementation of the print method.
147 void ciArray::print_impl(outputStream* st) {
148 st->print(" length=%d type=", length());
149 klass()->print(st);
150 }
|