%def op_check_cast(): % slow_path = add_slow_path(op_check_cast_slow_path) // Fast-path which gets the class from thread-local cache. % fetch_from_thread_cache("%rsi", miss_label="2f") 1: GET_VREG %edi, rINSTq testl %edi, %edi je .L${opcode}_resume // Fast path without read barriers. cmpl MIRROR_OBJECT_CLASS_OFFSET(%edi), %esi jne ${slow_path} .L${opcode}_resume: ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 2: EXPORT_PC movq rSELF:THREAD_SELF_OFFSET, %rdi movq 0(%rsp), %rsi movq rPC, %rdx call nterp_get_class_or_allocate_object movq %rax, %rsi jmp 1b %def op_check_cast_slow_path(): testl $$MIRROR_CLASS_IS_INTERFACE_FLAG, MIRROR_CLASS_ACCESS_FLAGS_OFFSET(%rsi) jne 2f movl MIRROR_OBJECT_CLASS_OFFSET(%edi), %eax cmpl $$0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rsi) jne 2f 1: movl MIRROR_CLASS_SUPER_CLASS_OFFSET(%eax), %eax cmpl %eax, %esi je .L${opcode}_resume testl %eax, %eax jne 1b 2: cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET jne 4f 3: EXPORT_PC call art_quick_check_instance_of jmp .L${opcode}_resume 4: // 06 is %rsi call art_quick_read_barrier_mark_reg06 jmp 3b 5: movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%eax), %eax // Check if object is an array. testl %eax, %eax je 2b movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%esi), %ecx cmpl $$0, MIRROR_CLASS_SUPER_CLASS_OFFSET(%ecx) jne 2b cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%ecx) jne 2b // %ecx is Object[] // Check if the object is a primitive array. cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%eax) je .L${opcode}_resume jmp 2b %def op_iget_boolean(): jmp NterpGetBooleanInstanceField %def op_iget_byte(): jmp NterpGetByteInstanceField %def op_iget_char(): jmp NterpGetCharInstanceField %def op_iget_object(): jmp NterpGetObjectInstanceField %def op_iget_short(): jmp NterpGetShortInstanceField %def op_iget_wide(): jmp NterpGetWideInstanceField %def op_instance_of(): % slow_path = add_slow_path(op_instance_of_slow_path) /* instance-of vA, vB, class@CCCC */ // Fast-path which gets the class from thread-local cache. % fetch_from_thread_cache("%rsi", miss_label=".L"+opcode+"_init") .L${opcode}_start: movzbl rINSTbl,%edi sarl $$4,%edi # edi<- B GET_VREG %edi %rdi # edi<- vB (object) andb $$0xf,rINSTbl # rINST<- A testl %edi, %edi je .L${opcode}_set_vreg // Fast path without read barriers. cmpl MIRROR_OBJECT_CLASS_OFFSET(%edi), %esi jne ${slow_path} .L${opcode}_set_one: movl $$1, %edi .L${opcode}_set_vreg: SET_VREG %edi, rINSTq .L${opcode}_resume: ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 %def op_instance_of_slow_path(): // Go slow path if we are marking. Checking now allows // not going to slow path if the super class hierarchy check fails. cmpq $$0, rSELF:THREAD_READ_BARRIER_MARK_REG00_OFFSET jne 4f testl $$MIRROR_CLASS_IS_INTERFACE_FLAG, MIRROR_CLASS_ACCESS_FLAGS_OFFSET(%rsi) jne 5f movl MIRROR_OBJECT_CLASS_OFFSET(%edi), %eax cmpl $$0, MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%rsi) jne 3f 1: movl MIRROR_CLASS_SUPER_CLASS_OFFSET(%eax), %eax cmpl %eax, %esi je .L${opcode}_set_one testl %eax, %eax jne 1b 2: SET_VREG $$0, rINSTq # fp[A] <- value jmp .L${opcode}_resume 3: movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%eax), %eax // Check if object is an array. testl %eax, %eax je 2b movl MIRROR_CLASS_COMPONENT_TYPE_OFFSET(%esi), %ecx cmpl $$0, MIRROR_CLASS_SUPER_CLASS_OFFSET(%ecx) jne 5f cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%ecx) jne 2b // %ecx is Object[] // Check if the object is a primitive array. xorl %ecx, %ecx cmpw $$0, MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET(%eax) sete %cl SET_VREG %ecx, rINSTq jmp .L${opcode}_resume 4: // 06 is %rsi call art_quick_read_barrier_mark_reg06 5: EXPORT_PC call artInstanceOfFromCode SET_VREG %eax, rINSTq # fp[A] <- value jmp .L${opcode}_resume .L${opcode}_init: EXPORT_PC movq rSELF:THREAD_SELF_OFFSET, %rdi movq 0(%rsp), %rsi movq rPC, %rdx call nterp_get_class_or_allocate_object movq %rax, %rsi jmp .L${opcode}_start %def op_iget(): jmp NterpGetInstanceField %def op_iput(): jmp NterpPutInstanceField %def op_iput_boolean(): jmp NterpPutBooleanInstanceField %def op_iput_byte(): jmp NterpPutByteInstanceField %def op_iput_char(): jmp NterpPutCharInstanceField %def op_iput_object(): jmp NterpPutObjectInstanceField %def op_iput_short(): jmp NterpPutShortInstanceField %def op_iput_wide(): jmp NterpPutWideInstanceField %def op_sget(load="movl", wide="0"): jmp NterpGetIntStaticField %def op_sget_boolean(): jmp NterpGetBooleanStaticField %def op_sget_byte(): jmp NterpGetByteStaticField %def op_sget_char(): jmp NterpGetCharStaticField %def op_sget_object(): jmp NterpGetObjectStaticField %def op_sget_short(): jmp NterpGetShortStaticField %def op_sget_wide(): jmp NterpGetWideStaticField %def op_sput(): jmp NterpPutStaticField %def op_sput_boolean(): jmp NterpPutBooleanStaticField %def op_sput_byte(): jmp NterpPutByteStaticField %def op_sput_char(): jmp NterpPutCharStaticField %def op_sput_object(): jmp NterpPutObjectStaticField %def op_sput_short(): jmp NterpPutShortStaticField %def op_sput_wide(): jmp NterpPutWideStaticField %def op_new_instance(): // The routine is too big to fit in a handler, so jump to it. jmp NterpNewInstance