From c69fba293481af4a0963ec656c3aa9b959d44e01 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Tue, 6 Sep 2016 16:49:15 +0100 Subject: [PATCH] Optimizing: Fix handling empty fill-array-data. Test: m test-art-host-run-test-412-new-array Bug: 31300081 Change-Id: Id0512fc95a96c37de2ceab481666688435fa30f6 --- compiler/optimizing/instruction_builder.cc | 10 ++++-- test/412-new-array/smali/fill_array_data.smali | 12 +++++++ test/412-new-array/src/Main.java | 46 ++++++++++++++++++++++---- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 453068b56..32dcc2814 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1545,8 +1545,6 @@ void HInstructionBuilder::BuildFillArrayData(HInstruction* object, void HInstructionBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) { HInstruction* array = LoadNullCheckedLocal(instruction.VRegA_31t(), dex_pc); - HInstruction* length = new (arena_) HArrayLength(array, dex_pc); - AppendInstruction(length); int32_t payload_offset = instruction.VRegB_31t() + dex_pc; const Instruction::ArrayDataPayload* payload = @@ -1554,6 +1552,14 @@ void HInstructionBuilder::BuildFillArrayData(const Instruction& instruction, uin const uint8_t* data = payload->data; uint32_t element_count = payload->element_count; + if (element_count == 0u) { + // For empty payload we emit only the null check above. + return; + } + + HInstruction* length = new (arena_) HArrayLength(array, dex_pc); + AppendInstruction(length); + // Implementation of this DEX instruction seems to be that the bounds check is // done before doing any stores. HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1, dex_pc); diff --git a/test/412-new-array/smali/fill_array_data.smali b/test/412-new-array/smali/fill_array_data.smali index 2b24e56ce..f16308443 100644 --- a/test/412-new-array/smali/fill_array_data.smali +++ b/test/412-new-array/smali/fill_array_data.smali @@ -2,6 +2,18 @@ .super Ljava/lang/Object; +.method public static emptyIntArray([I)V + .registers 1 + + fill-array-data v0, :ArrayData + return-void + +:ArrayData + .array-data 4 + .end array-data + +.end method + .method public static intArray([I)V .registers 1 diff --git a/test/412-new-array/src/Main.java b/test/412-new-array/src/Main.java index d95d2c52f..fb348ba9c 100644 --- a/test/412-new-array/src/Main.java +++ b/test/412-new-array/src/Main.java @@ -220,6 +220,38 @@ public class Main extends TestCase { public static void testSmaliFillArrayData() throws Exception { Class c = Class.forName("FillArrayData"); { + Method m = c.getMethod("emptyIntArray", int[].class); + int[] array = new int[0]; + Object[] args = { array }; + m.invoke(null, args); + assertEquals(0, array.length); + + array = new int[2]; + args[0] = array; + m.invoke(null, args); + // Test that nothing has been written to the array. + assertEquals(0, array[0]); + assertEquals(0, array[1]); + + array = new int[] { 42, -42 }; + args[0] = array; + m.invoke(null, args); + // Test that nothing has been written to the array. + assertEquals(42, array[0]); + assertEquals(-42, array[1]); + + Throwable exception = null; + args[0] = null; + try { + m.invoke(null, args); + } catch (InvocationTargetException e) { + exception = e.getCause(); + assertTrue(exception instanceof NullPointerException); + } + assertNotNull(exception); + } + + { Method m = c.getMethod("intArray", int[].class); int[] array = new int[7]; Object[] args = { array }; @@ -235,7 +267,7 @@ public class Main extends TestCase { array = new int[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -274,7 +306,7 @@ public class Main extends TestCase { array = new int[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -313,7 +345,7 @@ public class Main extends TestCase { array = new short[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -352,7 +384,7 @@ public class Main extends TestCase { array = new long[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -391,7 +423,7 @@ public class Main extends TestCase { array = new char[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -430,7 +462,7 @@ public class Main extends TestCase { array = new byte[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { @@ -467,7 +499,7 @@ public class Main extends TestCase { array = new boolean[2]; args[0] = array; - Throwable exception = null; + Throwable exception = null; try { m.invoke(null, args); } catch (InvocationTargetException e) { -- 2.11.0