diff options
author | David Gross <dgross@google.com> | 2017-07-27 13:40:38 -0700 |
---|---|---|
committer | David Gross <dgross@google.com> | 2017-08-04 10:44:34 -0700 |
commit | 0730cbcaecc8c1376d845ad2f0f2d803e4a03d05 (patch) | |
tree | 8d90cce4940805ee2dcc101099ec63bbcd633a04 | |
parent | 871b18c89d347c8726f7350dee0e3fdb3705fb16 (diff) | |
download | rs-0730cbcaecc8c1376d845ad2f0f2d803e4a03d05.tar.gz |
Improve Java reflection for 32-bit versus 64-bit differences.
Bug: 32780232
Bug: 20260865
Bug: 21597073
This CL goes along with a frameworks/compile/slang change that
contains the actual fixes. This CL makes three changes:
1) Adds RenderScript.getPointerSize() method to compatibility library
for use by reflected code.
2) Adds UT_reflection3264 test case to tests/java_api/RSUnitTests.
3) Fixes test case apitest.rs to conform to 32-bit/64-bit consistency
requirements.
Test: many
- RsTest aosp_x86_64-eng (aosp, emulator) 32-bit and 64-bit
- RSTestBackward
- aosp_arm-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_arm64-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- RSTest_Backward19
- aosp_arm-eng
- n5 KLP MR2 Release (KT)
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- RSTest_CompatLib
- aosp_arm-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_arm64-eng
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_x86-eng
- emulator aosp
- aosp_x86_64-eng
- emulator aosp
- RSTest_Compat19
- aosp_arm-eng
- n5 KLP MR2 Release (KT)
- n9 LMP MR1 Release (LM)
- angler MNC DR Release (MD)
- aosp_x86
- emulator aosp
Merged-In: I101e30c69062a65fde1d928a2396db0fb7d86497
Merged-In: I4764aac63a880a7594c05ce9a6c5afc20f4d52d3
Change-Id: If65a3b7fbe281d24e9707a02304a1e676bf3a072
(cherry picked from commit a5eaa3f317eca21b72429b0616acc0882852efdc)
8 files changed, 405 insertions, 2 deletions
diff --git a/support/java/src/android/support/v8/renderscript/RenderScript.java b/support/java/src/android/support/v8/renderscript/RenderScript.java index 19a33d77..13c5dc25 100644 --- a/support/java/src/android/support/v8/renderscript/RenderScript.java +++ b/support/java/src/android/support/v8/renderscript/RenderScript.java @@ -131,10 +131,22 @@ public class RenderScript { return useNative; } /* - * Detect the bitness of the VM to allow FieldPacker to do the right thing. + * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing. */ static native int rsnSystemGetPointerSize(); static int sPointerSize; + static public int getPointerSize() { + // We provide an accessor rather than making the data item public for two reasons. + // 1) Prevents anyone outside this class from writing the data item. + // 2) Prevents anyone outside this class from reading the data item unless a class + // instance has been created (ensuring the data item has been initialized). + // DISCLAIMER: Reflection can circumvent these preventive measures. + synchronized(lock) { + if (!sInitialized) + throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated"); + } + return sPointerSize; + } /** * Determines whether or not we should be thunking into the native diff --git a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java index 7ee559e2..72f941dc 100644 --- a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java +++ b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/RSTestCore.java @@ -103,6 +103,7 @@ public class RSTestCore { unitTests.add(new UT_fp_mad(this, mRes, mCtx)); unitTests.add(new UT_reduce(this, mRes, mCtx)); unitTests.add(new UT_reduce_backward(this, mRes, mCtx)); + unitTests.add(new UT_reflection3264(this, mCtx)); /* unitTests.add(new UnitTest(null, "<Pass>", 1)); diff --git a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/UT_reflection3264.java b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/UT_reflection3264.java new file mode 100644 index 00000000..fa82b078 --- /dev/null +++ b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/UT_reflection3264.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_compat; + +import android.content.Context; +import android.content.res.Resources; +import android.support.v8.renderscript.Allocation; +import android.support.v8.renderscript.Element; +import android.support.v8.renderscript.RenderScript; +import android.support.v8.renderscript.Short4; +import android.support.v8.renderscript.Type; +import android.util.Log; +import java.util.Random; + +import static junit.framework.Assert.assertEquals; + +public class UT_reflection3264 extends UnitTest { + private static final String TAG = "reflection3264"; + + protected UT_reflection3264(RSTestCore rstc, Context ctx) { + super(rstc, "reflection3264", ctx); + } + + private final int xSize = 17, ySize = 23; // arbitrary values + + private final long seed = 20170609; // arbitrary value + + private static long unsigned(int v) { + if (v >= 0) + return (long)v; + else + return (long)v + ((long)1 << 32); + } + + private static short unsigned(byte v) { + if (v >= 0) + return (short)v; + else + return (short)((short)v + (short)(1 << 8)); + } + + public void run() { + Random r = new Random(seed); + + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_reflection3264 s = new ScriptC_reflection3264(pRS); + pRS.setMessageHandler(mRsMessage); + + Type.Builder typeBuilder = new Type.Builder(pRS, Element.U8_4(pRS)); + typeBuilder.setX(xSize).setY(ySize); + Allocation inputAllocation = Allocation.createTyped(pRS, typeBuilder.create()); + byte[] inputArray = new byte[xSize * ySize * 4]; + r.nextBytes(inputArray); + inputAllocation.copyFrom(inputArray); + + ScriptField_user_t.Item usrData = new ScriptField_user_t.Item(); + usrData.ans = new Short4( + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt())); + s.set_expect_ans(usrData.ans); + usrData.x = unsigned(r.nextInt()); + s.set_expect_x(usrData.x); + usrData.y = unsigned(r.nextInt()); + s.set_expect_y(usrData.y); + + usrData.alloc = inputAllocation; + + Allocation outputAllocation = Allocation.createTyped(pRS, typeBuilder.create()); + + s.set_expect_dAlloc_GetDimX(xSize); + s.set_expect_sAlloc_GetDimX(xSize); + final int dXOff = r.nextInt(); + s.set_expect_dXOff(dXOff); + final int dMip = r.nextInt(); + s.set_expect_dMip(dMip); + final int count = r.nextInt(); + s.set_expect_count(count); + final int sXOff = r.nextInt(); + s.set_expect_sXOff(sXOff); + final int sMip = r.nextInt(); + s.set_expect_sMip(sMip); + s.invoke_args(outputAllocation, dXOff, dMip, count, inputAllocation, sXOff, sMip); + + s.forEach_root(outputAllocation, usrData); + byte[] outputArray = new byte[xSize * ySize * 4]; + outputAllocation.copyTo(outputArray); + + for (int i = 0; i < xSize; ++i) + for (int j = 0; j < ySize; ++j) { + int idx = j * xSize + i; + assertEquals("[" + i + "][" + j + "]", inputArray[idx], outputArray[idx]); + } + + s.invoke_check_asserts(); + pRS.finish(); + waitForMessage(); + inputAllocation.destroy(); + outputAllocation.destroy(); + s.destroy(); + pRS.destroy(); + } +} diff --git a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/apitest.rs b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/apitest.rs index 25766480..9dcd6b58 100644 --- a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/apitest.rs +++ b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/apitest.rs @@ -20,7 +20,7 @@ volatile rs_data_kind dk; volatile rs_sampler_value rsv; -volatile rs_time_t rst; +volatile static rs_time_t rst; volatile static rs_tm rstm; char *allocPtr; diff --git a/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/reflection3264.rs b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/reflection3264.rs new file mode 100644 index 00000000..159b3184 --- /dev/null +++ b/tests/java_api/RSTest_CompatLib/src/com/android/rs/test/reflection3264.rs @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "shared.rsh" + +typedef struct user_t { + uchar4 ans; + uint x; + uint y; + rs_allocation alloc; +} user; + +uchar4 expect_ans; +uint expect_x; +uint expect_y; + +uint32_t expect_dAlloc_GetDimX; +int expect_dXOff; +int expect_dMip; +int expect_count; +uint32_t expect_sAlloc_GetDimX; +int expect_sXOff; +int expect_sMip; + +static bool failed = false; + +// See http://b/21597073 "Broken structure layout for RenderScript on 32-bit/64-bit compiles" +void root(uchar4 *output, const user * usr, uint x, uint y) { + if (!x && !y) { + // Only check one coordinate, so as to avoid contention on global variable "failed" + _RS_ASSERT(usr->ans.x == expect_ans.x); + _RS_ASSERT(usr->ans.y == expect_ans.y); + _RS_ASSERT(usr->ans.z == expect_ans.z); + _RS_ASSERT(usr->ans.w == expect_ans.w); + _RS_ASSERT(usr->x == expect_x); + _RS_ASSERT(usr->y == expect_y); + } + + uchar4 * e_in = (uchar4*)rsGetElementAt(usr->alloc, x, y); + *output = *e_in; +} + +// See http://b/32780232 "Corrupted rs_allocation instances when passed as arguments to invocables" +void args(rs_allocation dAlloc, int dXOff, int dMip, int count, + rs_allocation sAlloc, int sXOff, int sMip) { + _RS_ASSERT(rsIsObject(dAlloc) && + (rsAllocationGetDimX(dAlloc) == expect_dAlloc_GetDimX)); + _RS_ASSERT(dXOff == expect_dXOff); + _RS_ASSERT(dMip == expect_dMip); + _RS_ASSERT(count == expect_count); + _RS_ASSERT(rsIsObject(sAlloc) && + (rsAllocationGetDimX(sAlloc) == expect_sAlloc_GetDimX)); + _RS_ASSERT(sXOff == expect_sXOff); + _RS_ASSERT(sMip == expect_sMip); +} + +void check_asserts() { + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} diff --git a/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java b/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java index 133a48de..c6af0786 100644 --- a/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java +++ b/tests/java_api/RsTest/src/com/android/rs/test/RSTestCore.java @@ -111,6 +111,7 @@ public class RSTestCore { unitTests.add(new UT_struct_field(this, mCtx)); unitTests.add(new UT_struct_field_simple(this, mCtx)); unitTests.add(new UT_bitfield(this, mCtx)); + unitTests.add(new UT_reflection3264(this, mCtx)); /* unitTests.add(new UnitTest(null, "<Pass>", 1)); diff --git a/tests/java_api/RsTest/src/com/android/rs/test/UT_reflection3264.java b/tests/java_api/RsTest/src/com/android/rs/test/UT_reflection3264.java new file mode 100644 index 00000000..2ced238b --- /dev/null +++ b/tests/java_api/RsTest/src/com/android/rs/test/UT_reflection3264.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.Short4; +import android.renderscript.Type; +import android.util.Log; +import java.util.Random; + +import static junit.framework.Assert.assertEquals; + +public class UT_reflection3264 extends UnitTest { + private static final String TAG = "reflection3264"; + + protected UT_reflection3264(RSTestCore rstc, Context ctx) { + super(rstc, "reflection3264", ctx); + } + + private final int xSize = 17, ySize = 23; // arbitrary values + + private final long seed = 20170609; // arbitrary value + + private static long unsigned(int v) { + if (v >= 0) + return (long)v; + else + return (long)v + ((long)1 << 32); + } + + private static short unsigned(byte v) { + if (v >= 0) + return (short)v; + else + return (short)((short)v + (short)(1 << 8)); + } + + public void run() { + Random r = new Random(seed); + + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_reflection3264 s = new ScriptC_reflection3264(pRS); + pRS.setMessageHandler(mRsMessage); + + Type.Builder typeBuilder = new Type.Builder(pRS, Element.U8_4(pRS)); + typeBuilder.setX(xSize).setY(ySize); + Allocation inputAllocation = Allocation.createTyped(pRS, typeBuilder.create()); + byte[] inputArray = new byte[xSize * ySize * 4]; + r.nextBytes(inputArray); + inputAllocation.copyFrom(inputArray); + + ScriptField_user_t.Item usrData = new ScriptField_user_t.Item(); + usrData.ans = new Short4( + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt()), + unsigned((byte)r.nextInt())); + s.set_expect_ans(usrData.ans); + usrData.x = unsigned(r.nextInt()); + s.set_expect_x(usrData.x); + usrData.y = unsigned(r.nextInt()); + s.set_expect_y(usrData.y); + + usrData.alloc = inputAllocation; + + Allocation outputAllocation = Allocation.createTyped(pRS, typeBuilder.create()); + + s.set_expect_dAlloc_GetDimX(xSize); + s.set_expect_sAlloc_GetDimX(xSize); + final int dXOff = r.nextInt(); + s.set_expect_dXOff(dXOff); + final int dMip = r.nextInt(); + s.set_expect_dMip(dMip); + final int count = r.nextInt(); + s.set_expect_count(count); + final int sXOff = r.nextInt(); + s.set_expect_sXOff(sXOff); + final int sMip = r.nextInt(); + s.set_expect_sMip(sMip); + s.invoke_args(outputAllocation, dXOff, dMip, count, inputAllocation, sXOff, sMip); + + s.forEach_root(outputAllocation, usrData); + byte[] outputArray = new byte[xSize * ySize * 4]; + outputAllocation.copyTo(outputArray); + + for (int i = 0; i < xSize; ++i) + for (int j = 0; j < ySize; ++j) { + int idx = j * xSize + i; + assertEquals("[" + i + "][" + j + "]", inputArray[idx], outputArray[idx]); + } + + s.invoke_check_asserts(); + pRS.finish(); + waitForMessage(); + inputAllocation.destroy(); + outputAllocation.destroy(); + s.destroy(); + pRS.destroy(); + } +} diff --git a/tests/java_api/RsTest/src/com/android/rs/test/reflection3264.rs b/tests/java_api/RsTest/src/com/android/rs/test/reflection3264.rs new file mode 100644 index 00000000..159b3184 --- /dev/null +++ b/tests/java_api/RsTest/src/com/android/rs/test/reflection3264.rs @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "shared.rsh" + +typedef struct user_t { + uchar4 ans; + uint x; + uint y; + rs_allocation alloc; +} user; + +uchar4 expect_ans; +uint expect_x; +uint expect_y; + +uint32_t expect_dAlloc_GetDimX; +int expect_dXOff; +int expect_dMip; +int expect_count; +uint32_t expect_sAlloc_GetDimX; +int expect_sXOff; +int expect_sMip; + +static bool failed = false; + +// See http://b/21597073 "Broken structure layout for RenderScript on 32-bit/64-bit compiles" +void root(uchar4 *output, const user * usr, uint x, uint y) { + if (!x && !y) { + // Only check one coordinate, so as to avoid contention on global variable "failed" + _RS_ASSERT(usr->ans.x == expect_ans.x); + _RS_ASSERT(usr->ans.y == expect_ans.y); + _RS_ASSERT(usr->ans.z == expect_ans.z); + _RS_ASSERT(usr->ans.w == expect_ans.w); + _RS_ASSERT(usr->x == expect_x); + _RS_ASSERT(usr->y == expect_y); + } + + uchar4 * e_in = (uchar4*)rsGetElementAt(usr->alloc, x, y); + *output = *e_in; +} + +// See http://b/32780232 "Corrupted rs_allocation instances when passed as arguments to invocables" +void args(rs_allocation dAlloc, int dXOff, int dMip, int count, + rs_allocation sAlloc, int sXOff, int sMip) { + _RS_ASSERT(rsIsObject(dAlloc) && + (rsAllocationGetDimX(dAlloc) == expect_dAlloc_GetDimX)); + _RS_ASSERT(dXOff == expect_dXOff); + _RS_ASSERT(dMip == expect_dMip); + _RS_ASSERT(count == expect_count); + _RS_ASSERT(rsIsObject(sAlloc) && + (rsAllocationGetDimX(sAlloc) == expect_sAlloc_GetDimX)); + _RS_ASSERT(sXOff == expect_sXOff); + _RS_ASSERT(sMip == expect_sMip); +} + +void check_asserts() { + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} |