diff options
author | 2016-07-22 10:52:24 +0100 | |
---|---|---|
committer | 2016-07-22 13:36:21 +0100 | |
commit | d9ad357ca598996f7c44727bf6772b74e50e74e9 (patch) | |
tree | 8c123c8ae6341357f64e7f423f23fae9027a5cb6 | |
parent | 41c7e2e6ac0a59da2f3e066e20630b295fbe4661 (diff) |
ARM64/x86-64: Fix mterp fill-array-data-payload pointer calculation.
Fix the pointer calculation to sign-extend the offset
instead of zero-extending it, just like we do for the switch
table pointer calculation. Clean up comments for the switch.
Test: Additional test in 412-new-array.
Change-Id: Ibb1d2d3fcb109f59280aca08de21e42edc4ce66b
-rw-r--r-- | runtime/interpreter/mterp/arm64/op_fill_array_data.S | 8 | ||||
-rw-r--r-- | runtime/interpreter/mterp/arm64/op_packed_switch.S | 2 | ||||
-rw-r--r-- | runtime/interpreter/mterp/out/mterp_arm64.S | 12 | ||||
-rw-r--r-- | runtime/interpreter/mterp/out/mterp_x86_64.S | 12 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86_64/op_fill_array_data.S | 4 | ||||
-rw-r--r-- | runtime/interpreter/mterp/x86_64/op_packed_switch.S | 4 | ||||
-rw-r--r-- | test/412-new-array/info.txt | 2 | ||||
-rw-r--r-- | test/412-new-array/smali/fill_array_data.smali | 15 | ||||
-rw-r--r-- | test/412-new-array/src/Main.java | 39 |
9 files changed, 77 insertions, 21 deletions
diff --git a/runtime/interpreter/mterp/arm64/op_fill_array_data.S b/runtime/interpreter/mterp/arm64/op_fill_array_data.S index f50d9e40ad..86fa6dbbd2 100644 --- a/runtime/interpreter/mterp/arm64/op_fill_array_data.S +++ b/runtime/interpreter/mterp/arm64/op_fill_array_data.S @@ -1,11 +1,11 @@ /* fill-array-data vAA, +BBBBBBBB */ EXPORT_PC - FETCH w0, 1 // w0<- bbbb (lo) - FETCH w1, 2 // w1<- BBBB (hi) + FETCH w0, 1 // x0<- 000000000000bbbb (lo) + FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi) lsr w3, wINST, #8 // w3<- AA - orr w1, w0, w1, lsl #16 // w1<- BBBBbbbb + orr x1, x0, x1, lsl #16 // x1<- ssssssssBBBBbbbb GET_VREG w0, w3 // w0<- vAA (array object) - add x1, xPC, w1, lsl #1 // w1<- PC + BBBBbbbb*2 (array data off.) + add x1, xPC, x1, lsl #1 // x1<- PC + ssssssssBBBBbbbb*2 (array data off.) bl MterpFillArrayData // (obj, payload) cbz w0, MterpPossibleException // exception? FETCH_ADVANCE_INST 3 // advance rPC, load rINST diff --git a/runtime/interpreter/mterp/arm64/op_packed_switch.S b/runtime/interpreter/mterp/arm64/op_packed_switch.S index 4faa6d2410..408e03069b 100644 --- a/runtime/interpreter/mterp/arm64/op_packed_switch.S +++ b/runtime/interpreter/mterp/arm64/op_packed_switch.S @@ -14,7 +14,7 @@ lsr w3, wINST, #8 // w3<- AA orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb GET_VREG w1, w3 // w1<- vAA - add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2 + add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2 bl $func // w0<- code-unit branch offset sxtw xINST, w0 b MterpCommonTakenBranchNoFlags diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S index 79d3c9a6f7..e318782c6d 100644 --- a/runtime/interpreter/mterp/out/mterp_arm64.S +++ b/runtime/interpreter/mterp/out/mterp_arm64.S @@ -1050,12 +1050,12 @@ artMterpAsmInstructionStart = .L_op_nop /* File: arm64/op_fill_array_data.S */ /* fill-array-data vAA, +BBBBBBBB */ EXPORT_PC - FETCH w0, 1 // w0<- bbbb (lo) - FETCH w1, 2 // w1<- BBBB (hi) + FETCH w0, 1 // x0<- 000000000000bbbb (lo) + FETCH_S x1, 2 // x1<- ssssssssssssBBBB (hi) lsr w3, wINST, #8 // w3<- AA - orr w1, w0, w1, lsl #16 // w1<- BBBBbbbb + orr x1, x0, x1, lsl #16 // x1<- ssssssssBBBBbbbb GET_VREG w0, w3 // w0<- vAA (array object) - add x1, xPC, w1, lsl #1 // w1<- PC + BBBBbbbb*2 (array data off.) + add x1, xPC, x1, lsl #1 // x1<- PC + ssssssssBBBBbbbb*2 (array data off.) bl MterpFillArrayData // (obj, payload) cbz w0, MterpPossibleException // exception? FETCH_ADVANCE_INST 3 // advance rPC, load rINST @@ -1145,7 +1145,7 @@ artMterpAsmInstructionStart = .L_op_nop lsr w3, wINST, #8 // w3<- AA orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb GET_VREG w1, w3 // w1<- vAA - add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2 + add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2 bl MterpDoPackedSwitch // w0<- code-unit branch offset sxtw xINST, w0 b MterpCommonTakenBranchNoFlags @@ -1170,7 +1170,7 @@ artMterpAsmInstructionStart = .L_op_nop lsr w3, wINST, #8 // w3<- AA orr x0, x0, x1, lsl #16 // x0<- ssssssssBBBBbbbb GET_VREG w1, w3 // w1<- vAA - add x0, xPC, x0, lsl #1 // x0<- PC + BBBBbbbb*2 + add x0, xPC, x0, lsl #1 // x0<- PC + ssssssssBBBBbbbb*2 bl MterpDoSparseSwitch // w0<- code-unit branch offset sxtw xINST, w0 b MterpCommonTakenBranchNoFlags diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S index 9e2dcea002..2f7b8548a3 100644 --- a/runtime/interpreter/mterp/out/mterp_x86_64.S +++ b/runtime/interpreter/mterp/out/mterp_x86_64.S @@ -965,8 +965,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop /* File: x86_64/op_fill_array_data.S */ /* fill-array-data vAA, +BBBBBBBB */ EXPORT_PC - movl 2(rPC), %ecx # ecx <- BBBBbbbb - leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + BBBBbbbb*2 + movslq 2(rPC), %rcx # rcx <- ssssssssBBBBbbbb + leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + ssssssssBBBBbbbb*2 GET_VREG OUT_32_ARG0, rINSTq # OUT_ARG0 <- vAA (array object) call SYMBOL(MterpFillArrayData) # (obj, payload) testb %al, %al # 0 means an exception is thrown @@ -1051,8 +1051,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ - movslq 2(rPC), OUT_ARG0 # rcx <- BBBBbbbb - leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + BBBBbbbb*2 + movslq 2(rPC), OUT_ARG0 # rcx <- ssssssssBBBBbbbb + leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + ssssssssBBBBbbbb*2 GET_VREG OUT_32_ARG1, rINSTq # eax <- vAA call SYMBOL(MterpDoPackedSwitch) testl %eax, %eax @@ -1074,8 +1074,8 @@ SYMBOL(artMterpAsmInstructionStart) = .L_op_nop * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ - movslq 2(rPC), OUT_ARG0 # rcx <- BBBBbbbb - leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + BBBBbbbb*2 + movslq 2(rPC), OUT_ARG0 # rcx <- ssssssssBBBBbbbb + leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + ssssssssBBBBbbbb*2 GET_VREG OUT_32_ARG1, rINSTq # eax <- vAA call SYMBOL(MterpDoSparseSwitch) testl %eax, %eax diff --git a/runtime/interpreter/mterp/x86_64/op_fill_array_data.S b/runtime/interpreter/mterp/x86_64/op_fill_array_data.S index 626bad47c9..7ea36a6136 100644 --- a/runtime/interpreter/mterp/x86_64/op_fill_array_data.S +++ b/runtime/interpreter/mterp/x86_64/op_fill_array_data.S @@ -1,7 +1,7 @@ /* fill-array-data vAA, +BBBBBBBB */ EXPORT_PC - movl 2(rPC), %ecx # ecx <- BBBBbbbb - leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + BBBBbbbb*2 + movslq 2(rPC), %rcx # rcx <- ssssssssBBBBbbbb + leaq (rPC,%rcx,2), OUT_ARG1 # OUT_ARG1 <- PC + ssssssssBBBBbbbb*2 GET_VREG OUT_32_ARG0, rINSTq # OUT_ARG0 <- vAA (array object) call SYMBOL(MterpFillArrayData) # (obj, payload) testb %al, %al # 0 means an exception is thrown diff --git a/runtime/interpreter/mterp/x86_64/op_packed_switch.S b/runtime/interpreter/mterp/x86_64/op_packed_switch.S index fdf5a50f9c..148552f77e 100644 --- a/runtime/interpreter/mterp/x86_64/op_packed_switch.S +++ b/runtime/interpreter/mterp/x86_64/op_packed_switch.S @@ -9,8 +9,8 @@ * for: packed-switch, sparse-switch */ /* op vAA, +BBBB */ - movslq 2(rPC), OUT_ARG0 # rcx <- BBBBbbbb - leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + BBBBbbbb*2 + movslq 2(rPC), OUT_ARG0 # rcx <- ssssssssBBBBbbbb + leaq (rPC,OUT_ARG0,2), OUT_ARG0 # rcx <- PC + ssssssssBBBBbbbb*2 GET_VREG OUT_32_ARG1, rINSTq # eax <- vAA call SYMBOL($func) testl %eax, %eax diff --git a/test/412-new-array/info.txt b/test/412-new-array/info.txt index cb388b6023..b5f834aa31 100644 --- a/test/412-new-array/info.txt +++ b/test/412-new-array/info.txt @@ -1 +1,3 @@ Simple tests for new-array, filled-new-array and fill-array-data. +Regression test for the arm64 mterp miscalculating the fill-array-data-payload +address, zero-extending a register instead of sign-extending. diff --git a/test/412-new-array/smali/fill_array_data.smali b/test/412-new-array/smali/fill_array_data.smali index 34776db5de..2b24e56cef 100644 --- a/test/412-new-array/smali/fill_array_data.smali +++ b/test/412-new-array/smali/fill_array_data.smali @@ -15,6 +15,21 @@ .end method +.method public static intArrayFillInstructionAfterData([I)V + .registers 1 + goto :FillInstruction + +:ArrayData + .array-data 4 + 1 2 3 4 5 + .end array-data + +:FillInstruction + fill-array-data v0, :ArrayData + return-void + +.end method + .method public static shortArray([S)V .registers 1 diff --git a/test/412-new-array/src/Main.java b/test/412-new-array/src/Main.java index b9c2a053e0..d95d2c52f3 100644 --- a/test/412-new-array/src/Main.java +++ b/test/412-new-array/src/Main.java @@ -259,6 +259,45 @@ public class Main extends TestCase { } { + Method m = c.getMethod("intArrayFillInstructionAfterData", int[].class); + int[] array = new int[7]; + Object[] args = { array }; + m.invoke(null, args); + assertEquals(7, array.length); + assertEquals(1, array[0]); + assertEquals(2, array[1]); + assertEquals(3, array[2]); + assertEquals(4, array[3]); + assertEquals(5, array[4]); + assertEquals(0, array[5]); + assertEquals(0, array[6]); + + array = new int[2]; + args[0] = array; + Throwable exception = null; + try { + m.invoke(null, args); + } catch (InvocationTargetException e) { + exception = e.getCause(); + assertTrue(exception instanceof IndexOutOfBoundsException); + } + assertNotNull(exception); + exception = null; + // Test that nothing has been written to the array. + assertEquals(0, array[0]); + assertEquals(0, array[1]); + + args[0] = null; + try { + m.invoke(null, args); + } catch (InvocationTargetException e) { + exception = e.getCause(); + assertTrue(exception instanceof NullPointerException); + } + assertNotNull(exception); + } + + { Method m = c.getMethod("shortArray", short[].class); short[] array = new short[7]; Object[] args = { array }; |