MIPS: Improving art_quick_imt_conflict_trampoline
This is fixing stub_test for MIPS32 and MIPS64. This is follow up
change for Ie74d1c77cf73d451a1142bdc5e3683f9f84bb4e7.
Change-Id: I3c53ef690aff49d7cf9ad3de3aaed9a3d2e1c6b9
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 5a901f1..da7db1d 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1247,7 +1247,7 @@
ldr r4, [r0, #(2 * __SIZEOF_POINTER__)]!
b .Limt_table_iterate
.Limt_table_found:
- // We successuflly hit an entry in the table. Load the target method
+ // We successfully hit an entry in the table. Load the target method
// and jump to it.
ldr r0, [r0, #__SIZEOF_POINTER__]
ldr pc, [r0, #ART_METHOD_QUICK_CODE_OFFSET_32]
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 8b497fe..506316e 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1780,7 +1780,7 @@
ldr x0, [xIP1, #(2 * __SIZEOF_POINTER__)]!
b .Limt_table_iterate
.Limt_table_found:
- // We successuflly hit an entry in the table. Load the target method
+ // We successfully hit an entry in the table. Load the target method
// and jump to it.
ldr x0, [xIP1, #__SIZEOF_POINTER__]
ldr xIP0, [x0, #ART_METHOD_QUICK_CODE_OFFSET_64]
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index fd1851f..c85887a 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -1540,11 +1540,41 @@
END art_quick_proxy_invoke_handler
/*
- * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
- * dex method index.
+ * Called to resolve an imt conflict.
+ * a0 is the conflict ArtMethod.
+ * t0 is a hidden argument that holds the target interface method's dex method index.
+ *
+ * Note that this stub writes to a0, t0 and t1.
*/
ENTRY art_quick_imt_conflict_trampoline
- move $a0, $t0
+ lw $t1, 0($sp) # Load referrer.
+ lw $t1, ART_METHOD_DEX_CACHE_METHODS_OFFSET_32($t1) # Load dex cache methods array.
+ sll $t0, $t0, POINTER_SIZE_SHIFT # Calculate offset.
+ addu $t0, $t1, $t0 # Add offset to base.
+ lw $t0, 0($t0) # Load interface method.
+ lw $a0, ART_METHOD_JNI_OFFSET_32($a0) # Load ImtConflictTable.
+
+.Limt_table_iterate:
+ lw $t1, 0($a0) # Load next entry in ImtConflictTable.
+ # Branch if found.
+ beq $t1, $t0, .Limt_table_found
+ nop
+ # If the entry is null, the interface method is not in the ImtConflictTable.
+ beqz $t1, .Lconflict_trampoline
+ nop
+ # Iterate over the entries of the ImtConflictTable.
+ b .Limt_table_iterate
+ addiu $a0, $a0, 2 * __SIZEOF_POINTER__ # Iterate to the next entry.
+
+.Limt_table_found:
+ # We successfully hit an entry in the table. Load the target method and jump to it.
+ lw $a0, __SIZEOF_POINTER__($a0)
+ lw $t9, ART_METHOD_QUICK_CODE_OFFSET_32($a0)
+ jr $t9
+ nop
+
+.Lconflict_trampoline:
+ # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method.
INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline
END art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index f1e605a..667b4a3 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1534,11 +1534,40 @@
END art_quick_proxy_invoke_handler
/*
- * Called to resolve an imt conflict. t0 is a hidden argument that holds the target method's
- * dex method index.
+ * Called to resolve an imt conflict.
+ * a0 is the conflict ArtMethod.
+ * t0 is a hidden argument that holds the target interface method's dex method index.
+ *
+ * Mote that this stub writes to a0, t0 and t1.
*/
ENTRY art_quick_imt_conflict_trampoline
- move $a0, $t0
+ ld $t1, 0($sp) # Load referrer.
+ ld $t1, ART_METHOD_DEX_CACHE_METHODS_OFFSET_64($t1) # Load dex cache methods array.
+ dsll $t0, $t0, POINTER_SIZE_SHIFT # Calculate offset.
+ daddu $t0, $t1, $t0 # Add offset to base.
+ ld $t0, 0($t0) # Load interface method.
+ ld $a0, ART_METHOD_JNI_OFFSET_64($a0) # Load ImtConflictTable.
+
+.Limt_table_iterate:
+ ld $t1, 0($a0) # Load next entry in ImtConflictTable.
+ # Branch if found.
+ beq $t1, $t0, .Limt_table_found
+ nop
+ # If the entry is null, the interface method is not in the ImtConflictTable.
+ beqzc $t1, .Lconflict_trampoline
+ # Iterate over the entries of the ImtConflictTable.
+ daddiu $a0, $a0, 2 * __SIZEOF_POINTER__ # Iterate to the next entry.
+ bc .Limt_table_iterate
+
+.Limt_table_found:
+ # We successfully hit an entry in the table. Load the target method and jump to it.
+ ld $a0, __SIZEOF_POINTER__($a0)
+ ld $t9, ART_METHOD_QUICK_CODE_OFFSET_64($a0)
+ jr $t9
+ .cpreturn # Restore gp from t8 in branch delay slot.
+
+.Lconflict_trampoline:
+ # Call the runtime stub to populate the ImtConflictTable and jump to the resolved method.
INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline
END art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 82ac574..551ec68 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -1422,7 +1422,7 @@
.Limt_table_iterate:
cmpl %edi, 0(%eax)
jne .Limt_table_next_entry
- // We successuflly hit an entry in the table. Load the target method
+ // We successfully hit an entry in the table. Load the target method
// and jump to it.
POP EDI
movl __SIZEOF_POINTER__(%eax), %eax
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 90049cc..26e668e 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1331,7 +1331,7 @@
.Limt_table_iterate:
cmpq %r10, 0(%rdi)
jne .Limt_table_next_entry
- // We successuflly hit an entry in the table. Load the target method
+ // We successfully hit an entry in the table. Load the target method
// and jump to it.
movq __SIZEOF_POINTER__(%rdi), %rdi
jmp *ART_METHOD_QUICK_CODE_OFFSET_64(%rdi)