811 transition(itos, dtos);
812 // rax: index
813 // rdx: array
814 index_check(rdx, rax); // kills rbx
815 __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, noreg /* dtos */,
816 Address(rdx, rax,
817 Address::times_8,
818 arrayOopDesc::base_offset_in_bytes(T_DOUBLE)),
819 noreg, noreg);
820 }
821
822 void TemplateTable::aaload() {
823 transition(itos, atos);
824
825 Register array = rcx;
826 Register index = rax;
827
828 index_check(array, index); // kills rbx
829 if (ValueArrayFlatten) {
830 Label is_flat_array, done;
831 __ test_flat_array_oop(array, rbx, is_flat_array);
832 do_oop_load(_masm,
833 Address(array, index,
834 UseCompressedOops ? Address::times_4 : Address::times_ptr,
835 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
836 rax,
837 IS_ARRAY);
838 __ jmp(done);
839 __ bind(is_flat_array);
840 __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::value_array_load), array, index);
841 __ bind(done);
842 } else {
843 do_oop_load(_masm,
844 Address(array, index,
845 UseCompressedOops ? Address::times_4 : Address::times_ptr,
846 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
847 rax,
848 IS_ARRAY);
849 }
850 }
851
1134 void TemplateTable::aastore() {
1135 Label is_null, is_flat_array, ok_is_subtype, done;
1136 transition(vtos, vtos);
1137 // stack: ..., array, index, value
1138 __ movptr(rax, at_tos()); // value
1139 __ movl(rcx, at_tos_p1()); // index
1140 __ movptr(rdx, at_tos_p2()); // array
1141
1142 Address element_address(rdx, rcx,
1143 UseCompressedOops? Address::times_4 : Address::times_ptr,
1144 arrayOopDesc::base_offset_in_bytes(T_OBJECT));
1145
1146 index_check_without_pop(rdx, rcx); // kills rbx
1147
1148 __ testptr(rax, rax);
1149 __ jcc(Assembler::zero, is_null);
1150
1151 // Move array class to rdi
1152 __ load_klass(rdi, rdx);
1153 if (ValueArrayFlatten) {
1154 __ test_flat_array_klass(rdi, rbx, is_flat_array);
1155 }
1156
1157 // Move subklass into rbx
1158 __ load_klass(rbx, rax);
1159 // Move array element superklass into rax
1160 __ movptr(rax, Address(rdi,
1161 ObjArrayKlass::element_klass_offset()));
1162
1163 // Generate subtype check. Blows rcx, rdi
1164 // Superklass in rax. Subklass in rbx.
1165 // is "rbx <: rax" ? (value subclass <: array element superclass)
1166 __ gen_subtype_check(rbx, ok_is_subtype);
1167
1168 // Come here on failure
1169 // object is at TOS
1170 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
1171
1172 // Come here on success
1173 __ bind(ok_is_subtype);
1174
1175 // Get the value we will store
1176 __ movptr(rax, at_tos());
1177 __ movl(rcx, at_tos_p1()); // index
1178 // Now store using the appropriate barrier
1179 do_oop_store(_masm, element_address, rax, IS_ARRAY);
1180 __ jmp(done);
1181
1182 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
1183 __ bind(is_null);
1184 __ profile_null_seen(rbx);
1185 if (EnableValhalla) {
1186 Label is_null_into_value_array_npe, store_null;
1187
1188 __ load_klass(rdi, rdx);
1189 // No way to store null in flat array
1190 __ test_flat_array_klass(rdi, rbx, is_null_into_value_array_npe);
1191
1192 // Use case for storing values in objArray where element_klass is specifically
1193 // a value type because they could not be flattened "for reasons",
1194 // these need to have the same semantics as flat arrays, i.e. NPE
1195 __ movptr(rdi, Address(rdi, ObjArrayKlass::element_klass_offset()));
1196 __ test_klass_is_value(rdi, rdi, is_null_into_value_array_npe);
1197 __ jmp(store_null);
1198
1199 __ bind(is_null_into_value_array_npe);
1200 __ jump(ExternalAddress(Interpreter::_throw_NullPointerException_entry));
1201
1202 __ bind(store_null);
1203 }
1204 // Store a NULL
1205 do_oop_store(_masm, element_address, noreg, IS_ARRAY);
1206 __ jmp(done);
1207
1208 if (EnableValhalla) {
1209 Label is_type_ok;
1210 __ bind(is_flat_array); // Store non-null value to flat
1211
1212 // Simplistic type check...
1213
1214 // Profile the not-null value's klass.
1215 __ load_klass(rbx, rax);
1216 __ profile_typecheck(rcx, rbx, rax); // blows rcx, and rax
|
811 transition(itos, dtos);
812 // rax: index
813 // rdx: array
814 index_check(rdx, rax); // kills rbx
815 __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, noreg /* dtos */,
816 Address(rdx, rax,
817 Address::times_8,
818 arrayOopDesc::base_offset_in_bytes(T_DOUBLE)),
819 noreg, noreg);
820 }
821
822 void TemplateTable::aaload() {
823 transition(itos, atos);
824
825 Register array = rcx;
826 Register index = rax;
827
828 index_check(array, index); // kills rbx
829 if (ValueArrayFlatten) {
830 Label is_flat_array, done;
831 __ test_flattened_array_oop(array, rbx, is_flat_array);
832 do_oop_load(_masm,
833 Address(array, index,
834 UseCompressedOops ? Address::times_4 : Address::times_ptr,
835 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
836 rax,
837 IS_ARRAY);
838 __ jmp(done);
839 __ bind(is_flat_array);
840 __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::value_array_load), array, index);
841 __ bind(done);
842 } else {
843 do_oop_load(_masm,
844 Address(array, index,
845 UseCompressedOops ? Address::times_4 : Address::times_ptr,
846 arrayOopDesc::base_offset_in_bytes(T_OBJECT)),
847 rax,
848 IS_ARRAY);
849 }
850 }
851
1134 void TemplateTable::aastore() {
1135 Label is_null, is_flat_array, ok_is_subtype, done;
1136 transition(vtos, vtos);
1137 // stack: ..., array, index, value
1138 __ movptr(rax, at_tos()); // value
1139 __ movl(rcx, at_tos_p1()); // index
1140 __ movptr(rdx, at_tos_p2()); // array
1141
1142 Address element_address(rdx, rcx,
1143 UseCompressedOops? Address::times_4 : Address::times_ptr,
1144 arrayOopDesc::base_offset_in_bytes(T_OBJECT));
1145
1146 index_check_without_pop(rdx, rcx); // kills rbx
1147
1148 __ testptr(rax, rax);
1149 __ jcc(Assembler::zero, is_null);
1150
1151 // Move array class to rdi
1152 __ load_klass(rdi, rdx);
1153 if (ValueArrayFlatten) {
1154 __ test_flattened_array_oop(rdx, rbx, is_flat_array);
1155 }
1156
1157 // Move subklass into rbx
1158 __ load_klass(rbx, rax);
1159 // Move array element superklass into rax
1160 __ movptr(rax, Address(rdi,
1161 ObjArrayKlass::element_klass_offset()));
1162
1163 // Generate subtype check. Blows rcx, rdi
1164 // Superklass in rax. Subklass in rbx.
1165 // is "rbx <: rax" ? (value subclass <: array element superclass)
1166 __ gen_subtype_check(rbx, ok_is_subtype);
1167
1168 // Come here on failure
1169 // object is at TOS
1170 __ jump(ExternalAddress(Interpreter::_throw_ArrayStoreException_entry));
1171
1172 // Come here on success
1173 __ bind(ok_is_subtype);
1174
1175 // Get the value we will store
1176 __ movptr(rax, at_tos());
1177 __ movl(rcx, at_tos_p1()); // index
1178 // Now store using the appropriate barrier
1179 do_oop_store(_masm, element_address, rax, IS_ARRAY);
1180 __ jmp(done);
1181
1182 // Have a NULL in rax, rdx=array, ecx=index. Store NULL at ary[idx]
1183 __ bind(is_null);
1184 __ profile_null_seen(rbx);
1185 if (EnableValhalla) {
1186 Label is_null_into_value_array_npe, store_null;
1187
1188 // No way to store null in null-free array
1189 __ test_null_free_array_oop(rdx, rbx, is_null_into_value_array_npe);
1190 __ jmp(store_null);
1191
1192 __ bind(is_null_into_value_array_npe);
1193 __ jump(ExternalAddress(Interpreter::_throw_NullPointerException_entry));
1194
1195 __ bind(store_null);
1196 }
1197 // Store a NULL
1198 do_oop_store(_masm, element_address, noreg, IS_ARRAY);
1199 __ jmp(done);
1200
1201 if (EnableValhalla) {
1202 Label is_type_ok;
1203 __ bind(is_flat_array); // Store non-null value to flat
1204
1205 // Simplistic type check...
1206
1207 // Profile the not-null value's klass.
1208 __ load_klass(rbx, rax);
1209 __ profile_typecheck(rcx, rbx, rax); // blows rcx, and rax
|