// array-length vA, vB
// Format 12x: B|A|21
// Store in the given destination register the length of the indicated array, in entries
%def op_array_length():
srliw t0, xINST, 12 // t0 := B
GET_VREG_OBJECT t0, t0 // t0 := refs[B]
beqz t0, 1f
srliw t1, xINST, 8 // t1 := B|A
FETCH_ADVANCE_INST 1
andi t1, t1, 0xF // t1 := A
GET_INST_OPCODE t3
lw t2, MIRROR_ARRAY_LENGTH_OFFSET(t0)
% set_vreg("t2", "t1", z0="t0")
GOTO_OPCODE t3 1:
tail common_errNullObject
// new-array vA, vB, type@CCCC
// Format 22c: B|A|23 CCCC
// Construct a new array of the indicated type and size. The type must be an array type.
%def op_new_array():
EXPORT_PC
srliw s8, xINST, 8 // s8 := B|A
srliw s7, xINST, 12 // s7 := B
andi s8, s8, 0xF // s8 := A
% fetch_from_thread_cache(/*resolved klass*/"a0", f".L{opcode}_miss", "t0", "t1")
TEST_IF_MARKING t0, .L${opcode}_mark
.L${opcode}_resume:
// filled-new-array {vC, vD, vE, vF, vG}, type@BBBB
// Format 35c: A|G|24 BBBB F|E|D|C
// Construct an array of the given type and size, filling it with the supplied contents. The type
// must be an array type. The array's contents must be single-word (that is, no arrays of long or
// double, but reference types are acceptable). The constructed instance is stored as a "result" in
// the same way that the method invocation instructions store their results, so the constructed
// instance must be moved to a register with an immediately subsequent move-result-object
// instruction (if it is to be used).
%def op_filled_new_array(is_range=False):
EXPORT_PC
mv a0, xSELF ld a1, (sp) // a1 := caller ArtMethod*
mv a2, xFP // a2 := vreg array
mv a3, xPC
% if is_range:
call nterp_filled_new_array_range // args a0, a1, a2, a3
% else:
call nterp_filled_new_array // args a0, a1, a2, a3
FETCH_ADVANCE_INST 3
GET_INST_OPCODE t0
GOTO_OPCODE t0
// filled-new-array/range {vCCCC .. vNNNN}, type@BBBB
// where NNNN = CCCC + AA - 1
// Format 3rc: AA|25 BBBB CCCC
// Construct an array of the given type and size, filling it with the supplied contents.
// Clarifications and restrictions are the same as filled-new-array, described above.
%def op_filled_new_array_range():
% op_filled_new_array(is_range=True)
// fill-array-data vAA, +BBBBBBBB
// Format 31t: AA|26 BBBB(lo) BBBB(hi)
// Fill the given array with the indicated data. The reference must be to an array of primitives,
// and the data table must match it in type and must contain no more elements than will fit in the
// array. That is, the array may be larger than the table, and if so, only the initial elements of
// the array are set, leaving the remainder alone.
%def op_fill_array_data():
EXPORT_PC
srliw t0, xINST, 8 // t0 := AA
FETCH t1, count=1, signed=1, width=32
// t1 := ssssssssBBBBBBBB
GET_VREG_OBJECT a1, t0 // a1 := refs[AA] (array ref)
// +BBBBBBBB offset is in code units. Multiply by 2 for byte offset against dex PC.
sh1add a0, t1, xPC // a0 := payload address
call art_quick_handle_fill_data // args a0, a1
FETCH_ADVANCE_INST 3
GET_INST_OPCODE t0
GOTO_OPCODE t0
// Common setup across APUT and AGET variants.
// Sets \array, \index, and \length registers.
// Branches to null handler and out-of-bounds handler.
%def array_prelude(array, index, length, null_label, oob_label):
FETCH $index, count=1 // index := CC|BB
andi $array, $index, 0xFF // array := BB
GET_VREG_OBJECT $array, $array // array := refs[BB], array obj
beqz $array, $null_label
srliw $index, $index, 8 // index := CC
% get_vreg(index, index) # index := fp[CC]
lw $length, MIRROR_ARRAY_LENGTH_OFFSET($array) // length (signed 32b)
bgeu $index, $length, $oob_label // Unsigned comparison also catches negative index.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.