From db97984cbb74634ca3374208665dbfe99276ec1e Mon Sep 17 00:00:00 2001 From: CoreRasurae <luis.p.mendes@gmail.com> Date: Fri, 24 Aug 2018 00:36:47 +0100 Subject: [PATCH] Fix: Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception - Partial fix for (refs #138) - the fix itself --- CHANGELOG.md | 1 + CONTRIBUTORS.md | 1 + .../aparapi/internal/writer/BlockWriter.java | 32 +++++++++++++++++-- .../runtime/LocalAtomicVariableArrayTest.java | 5 +-- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ff92765..b312ab1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Java execution mode now provides detailed backtraces of failed Kernel threads including passId, groupIds, globalIds and localIds * Internal translation of bytecode is now facilitated by the BCEL library * Scala support has been added (see unit tests). +* Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception while generating OpenCL (support for I_ALOAD_0,1,2,3 bytecode instructions) ## 1.9.0 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 07babbf4..7f4eef94 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -58,3 +58,4 @@ Below are some of the specific details of various contributions. * Luis Mendes submited PR to Fix Java execution mode to fail-fast when Kernel execution fails * Luis Mendes submited PR to Java execution mode now provides detailed backtraces of failed Kernel threads including passId, groupIds, globalIds and localIds * Saurabh Rawat contributed apache BCEL bytecode parsing and Scala support. +* Luis Mendes submited PR #139 to Fix arrays of AtomicInteger stored on local variables no longer fail with type cast exception - Partial fix for #138 \ No newline at end of file diff --git a/src/main/java/com/aparapi/internal/writer/BlockWriter.java b/src/main/java/com/aparapi/internal/writer/BlockWriter.java index 22789c60..ba7aca90 100644 --- a/src/main/java/com/aparapi/internal/writer/BlockWriter.java +++ b/src/main/java/com/aparapi/internal/writer/BlockWriter.java @@ -790,12 +790,20 @@ public abstract class BlockWriter{ } private boolean isMultiDimensionalArray(final AccessArrayElement arrayLoadInstruction) { - AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); - return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry()); + AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); + if (accessInstanceField != null) { + return isMultiDimensionalArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry()); + } else { + //Arrays can be accessed through local variables instead of instance fields, thus, AccessField instruction + //can be null. + LocalVariableConstIndexAccessor accessLocalVariable = getUltimateInstanceLocalVarAccess(arrayLoadInstruction); + //Directly check for multi-dimensional array... + return accessLocalVariable.getLocalVariableInfo().getVariableDescriptor().startsWith("[["); + } } private boolean isObjectArray(final AccessArrayElement arrayLoadInstruction) { - AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); + AccessField accessInstanceField = getUltimateInstanceFieldAccess(arrayLoadInstruction); return isObjectArray(accessInstanceField.getConstantPoolFieldEntry().getNameAndTypeEntry()); } @@ -804,10 +812,28 @@ public abstract class BlockWriter{ while (load instanceof I_AALOAD) { load = load.getFirstChild(); } + + if (load instanceof I_ALOAD_0 || load instanceof I_ALOAD_1 || load instanceof I_ALOAD_2 || load instanceof I_ALOAD_3) { + //It is not a Field Access + return null; + } return (AccessField) load; } + private LocalVariableConstIndexAccessor getUltimateInstanceLocalVarAccess(AccessArrayElement arrayLoadInstruction) { + Instruction load = arrayLoadInstruction.getArrayRef(); + while (load instanceof I_AALOAD) { + load = load.getFirstChild(); + } + + if (load instanceof I_ALOAD) { + return null; + } + + return (LocalVariableConstIndexAccessor)load; + } + public void writeMethod(MethodCall _methodCall, MethodEntry _methodEntry) throws CodeGenException { boolean noCL = _methodEntry.getOwnerClassModel().getNoCLMethods() .contains(_methodEntry.getNameAndTypeEntry().getNameUTF8Entry().getUTF8()); diff --git a/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java index 5034c91e..26978d75 100644 --- a/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java +++ b/src/test/java/com/aparapi/runtime/LocalAtomicVariableArrayTest.java @@ -74,7 +74,7 @@ public class LocalAtomicVariableArrayTest { @Test public void openCLTest() { SimpleLocalVarKernel myKernel = new SimpleLocalVarKernel(); - Range range = openCLDevice.createRange(SIZE, SIZE);; + Range range = openCLDevice.createRange(SIZE, SIZE); try { myKernel.execute(range); assertEquals("Atomic increment doesn't match", SIZE, myKernel.atomics[1].get()); @@ -93,13 +93,10 @@ public class LocalAtomicVariableArrayTest { } @Override public void run() { - int gid = getGlobalId(); - atomicUpdate(atomics, 1); } public int atomicUpdate(AtomicInteger[] arr, int index) { - //Other logic could be included to avoid having to call atomicUpdate, just to update an atomic return atomicInc(arr[index]); } } -- GitLab