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