1%def op_check_cast(): 2% slow_path = add_slow_path(op_check_cast_slow_path) 3 // Fast-path which gets the class from thread-local cache. 4% fetch_from_thread_cache("%rsi", miss_label="2f") 51: 6 GET_VREG %edi, rINSTq 7 testl %edi, %edi 8 je .L${opcode}_resume 9 // Fast path without read barriers. 10 POISON_HEAP_REF esi // Poison class reference for in-memory comparison. 11 cmpl MIRROR_OBJECT_CLASS_OFFSET(%edi), %esi 12 jne ${slow_path} 13.L${opcode}_resume: 14 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 152: 16 EXPORT_PC 17 movq rSELF:THREAD_SELF_OFFSET, %rdi 18 movq 0(%rsp), %rsi 19 movq rPC, %rdx 20 call nterp_get_class 21 movq %rax, %rsi 22 jmp 1b 23 24%def op_check_cast_slow_path(): 25 UNPOISON_HEAP_REF esi // Unpoison class reference poisoned in main path. 26 testl $$MIRROR_CLASS_IS_INTERFACE_FLAG, MIRROR_CLASS_ACCESS_FLAGS_OFFSET(%rsi) 27 jne 2f 28 movl MIRROR_OBJECT_CLASS_OFFSET(%edi), %eax 29 UNPOISON_HEAP_REF eax 30 cmpl $$0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rsi) 31 jne 2f 321: 33 movl MIRROR_CLASS_SUPER_CLASS_OFFSET(%eax), %eax 34 UNPOISON_HEAP_REF eax 35 cmpl %eax, %esi 36 je .L${opcode}_resume 37 testl %eax, %eax 38 jne 1b 392: 40 cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET 41 jne 4f 423: 43 EXPORT_PC 44 call art_quick_check_instance_of 45 jmp .L${opcode}_resume 464: 47 // 06 is %rsi 48 call art_quick_read_barrier_mark_reg06 49 jmp 3b 505: 51 movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%eax), %eax 52 UNPOISON_HEAP_REF eax 53 // Check if object is an array. 54 testl %eax, %eax 55 je 2b 56 movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%esi), %ecx 57 UNPOISON_HEAP_REF ecx 58 cmpl $$0, MIRROR_CLASS_SUPER_CLASS_OFFSET(%ecx) 59 jne 2b 60 cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%ecx) 61 jne 2b 62 // %ecx is Object[] 63 // Check if the object is a primitive array. 64 cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%eax) 65 je .L${opcode}_resume 66 jmp 2b 67 68%def op_iget_boolean(): 69 jmp NterpGetBooleanInstanceField 70 71%def op_iget_byte(): 72 jmp NterpGetByteInstanceField 73 74%def op_iget_char(): 75 jmp NterpGetCharInstanceField 76 77%def op_iget_object(): 78 jmp NterpGetObjectInstanceField 79 80%def op_iget_short(): 81 jmp NterpGetShortInstanceField 82 83%def op_iget_wide(): 84 jmp NterpGetWideInstanceField 85 86%def op_instance_of(): 87% slow_path = add_slow_path(op_instance_of_slow_path) 88 /* instance-of vA, vB, class@CCCC */ 89 // Fast-path which gets the class from thread-local cache. 90% fetch_from_thread_cache("%rsi", miss_label=".L"+opcode+"_init") 91.L${opcode}_start: 92 movzbl rINSTbl,%edi 93 sarl $$4,%edi # edi<- B 94 GET_VREG %edi %rdi # edi<- vB (object) 95 andb $$0xf,rINSTbl # rINST<- A 96 testl %edi, %edi 97 je .L${opcode}_set_vreg 98 // Fast path without read barriers. 99 POISON_HEAP_REF esi // Poison class reference for in-memory comparison. 100 cmpl MIRROR_OBJECT_CLASS_OFFSET(%edi), %esi 101 jne ${slow_path} 102.L${opcode}_set_one: 103 movl $$1, %edi 104.L${opcode}_set_vreg: 105 SET_VREG %edi, rINSTq 106.L${opcode}_resume: 107 ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 108 109%def op_instance_of_slow_path(): 110 UNPOISON_HEAP_REF esi // Unpoison class reference poisoned in main path. 111 // Go slow path if we are marking. Checking now allows 112 // not going to slow path if the super class hierarchy check fails. 113 cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET 114 jne 4f 115 testl $$MIRROR_CLASS_IS_INTERFACE_FLAG, MIRROR_CLASS_ACCESS_FLAGS_OFFSET(%rsi) 116 jne 5f 117 movl MIRROR_OBJECT_CLASS_OFFSET(%edi), %eax 118 UNPOISON_HEAP_REF eax 119 cmpl $$0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rsi) 120 jne 3f 1211: 122 movl MIRROR_CLASS_SUPER_CLASS_OFFSET(%eax), %eax 123 UNPOISON_HEAP_REF eax 124 cmpl %eax, %esi 125 je .L${opcode}_set_one 126 testl %eax, %eax 127 jne 1b 1282: 129 SET_VREG $$0, rINSTq # fp[A] <- value 130 jmp .L${opcode}_resume 1313: 132 movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%eax), %eax 133 UNPOISON_HEAP_REF eax 134 // Check if object is an array. 135 testl %eax, %eax 136 je 2b 137 movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%esi), %ecx 138 UNPOISON_HEAP_REF ecx 139 cmpl $$0, MIRROR_CLASS_SUPER_CLASS_OFFSET(%ecx) 140 jne 5f 141 cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%ecx) 142 jne 2b 143 // %ecx is Object[] 144 // Check if the object is a primitive array. 145 xorl %ecx, %ecx 146 cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%eax) 147 sete %cl 148 SET_VREG %ecx, rINSTq 149 jmp .L${opcode}_resume 1504: 151 // 06 is %rsi 152 call art_quick_read_barrier_mark_reg06 1535: 154 EXPORT_PC 155 call artInstanceOfFromCode 156 SET_VREG %eax, rINSTq # fp[A] <- value 157 jmp .L${opcode}_resume 158 159.L${opcode}_init: 160 EXPORT_PC 161 movq rSELF:THREAD_SELF_OFFSET, %rdi 162 movq 0(%rsp), %rsi 163 movq rPC, %rdx 164 call nterp_get_class 165 movq %rax, %rsi 166 jmp .L${opcode}_start 167 168%def op_iget(): 169 jmp NterpGetInstanceField 170 171%def op_iput(): 172 jmp NterpPutInstanceField 173 174%def op_iput_boolean(): 175 jmp NterpPutBooleanInstanceField 176 177%def op_iput_byte(): 178 jmp NterpPutByteInstanceField 179 180%def op_iput_char(): 181 jmp NterpPutCharInstanceField 182 183%def op_iput_object(): 184 jmp NterpPutObjectInstanceField 185 186%def op_iput_short(): 187 jmp NterpPutShortInstanceField 188 189%def op_iput_wide(): 190 jmp NterpPutWideInstanceField 191 192%def op_sget(load="movl", wide="0"): 193 jmp NterpGetIntStaticField 194 195%def op_sget_boolean(): 196 jmp NterpGetBooleanStaticField 197 198%def op_sget_byte(): 199 jmp NterpGetByteStaticField 200 201%def op_sget_char(): 202 jmp NterpGetCharStaticField 203 204%def op_sget_object(): 205 jmp NterpGetObjectStaticField 206 207%def op_sget_short(): 208 jmp NterpGetShortStaticField 209 210%def op_sget_wide(): 211 jmp NterpGetWideStaticField 212 213%def op_sput(): 214 jmp NterpPutStaticField 215 216%def op_sput_boolean(): 217 jmp NterpPutBooleanStaticField 218 219%def op_sput_byte(): 220 jmp NterpPutByteStaticField 221 222%def op_sput_char(): 223 jmp NterpPutCharStaticField 224 225%def op_sput_object(): 226 jmp NterpPutObjectStaticField 227 228%def op_sput_short(): 229 jmp NterpPutShortStaticField 230 231%def op_sput_wide(): 232 jmp NterpPutWideStaticField 233 234%def op_new_instance(): 235 // The routine is too big to fit in a handler, so jump to it. 236 jmp NterpNewInstance 237