diff options
author | David Brazdil <dbrazdil@google.com> | 2015-07-08 19:13:19 +0100 |
---|---|---|
committer | David Brazdil <dbrazdil@google.com> | 2015-07-09 11:24:34 +0100 |
commit | 3a4923292aa45ea8ef2ee1b4643c64c83225ddd0 (patch) | |
tree | 72995430fe7c5ecc2d764dcde9be1a02f7428ec4 /test/522-checker-regression-monitor-exit | |
parent | 4880fd5695ea1726dde27bb448dae1338d0a0973 (diff) | |
download | art-3a4923292aa45ea8ef2ee1b4643c64c83225ddd0.tar.gz art-3a4923292aa45ea8ef2ee1b4643c64c83225ddd0.tar.bz2 art-3a4923292aa45ea8ef2ee1b4643c64c83225ddd0.zip |
ART: Add regression test
This adds a test for CL I624c0f91676d9baaada6f33be9d7091f68d57535.
Change-Id: Ib9ea1400082ad03c4355983d95268e084c0b6a6e
Diffstat (limited to 'test/522-checker-regression-monitor-exit')
4 files changed, 127 insertions, 0 deletions
diff --git a/test/522-checker-regression-monitor-exit/expected.txt b/test/522-checker-regression-monitor-exit/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/522-checker-regression-monitor-exit/expected.txt diff --git a/test/522-checker-regression-monitor-exit/info.txt b/test/522-checker-regression-monitor-exit/info.txt new file mode 100644 index 0000000000..7cfc963090 --- /dev/null +++ b/test/522-checker-regression-monitor-exit/info.txt @@ -0,0 +1,3 @@ +Regression test for removal of monitor-exit due to lack of specified side-effects. +The test invokes a synchronized version of Object.hashCode in multiple threads. +If monitor-exit is removed, the following threads will get stuck and timeout.
\ No newline at end of file diff --git a/test/522-checker-regression-monitor-exit/smali/Test.smali b/test/522-checker-regression-monitor-exit/smali/Test.smali new file mode 100644 index 0000000000..c8e91984e0 --- /dev/null +++ b/test/522-checker-regression-monitor-exit/smali/Test.smali @@ -0,0 +1,40 @@ +# +# Copyright (C) 2015 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. + +.class public LTest; + +.super Ljava/lang/Object; + +## CHECK-START: int Test.synchronizedHashCode(java.lang.Object) dead_code_elimination (before) +## CHECK: MonitorOperation [<<Param:l\d+>>] kind:enter +## CHECK: MonitorOperation [<<Param>>] kind:exit + +## CHECK-START: int Test.synchronizedHashCode(java.lang.Object) dead_code_elimination (after) +## CHECK: MonitorOperation [<<Param:l\d+>>] kind:enter +## CHECK: MonitorOperation [<<Param>>] kind:exit + +.method public static synchronizedHashCode(Ljava/lang/Object;)I + .registers 2 + + monitor-enter p0 + invoke-virtual {p0}, Ljava/lang/Object;->hashCode()I + move-result v0 + + # Must not get removed by DCE. + monitor-exit p0 + + return v0 + +.end method diff --git a/test/522-checker-regression-monitor-exit/src/Main.java b/test/522-checker-regression-monitor-exit/src/Main.java new file mode 100644 index 0000000000..c85ac966ad --- /dev/null +++ b/test/522-checker-regression-monitor-exit/src/Main.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 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. + */ + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.CancellationException; +import java.util.concurrent.TimeoutException; + +public class Main { + + // Workaround for b/18051191. + class InnerClass {} + + private static class HashCodeQuery implements Callable<Integer> { + public HashCodeQuery(Object obj) { + m_obj = obj; + } + + public Integer call() { + Integer result; + try { + Class<?> c = Class.forName("Test"); + Method m = c.getMethod("synchronizedHashCode", new Class[] { Object.class }); + result = (Integer) m.invoke(null, m_obj); + } catch (Exception e) { + System.err.println("Hash code query exception"); + e.printStackTrace(); + result = -1; + } + return result; + } + + private Object m_obj; + private int m_index; + } + + public static void main(String args[]) throws Exception { + Object obj = new Object(); + int numThreads = 10; + + ExecutorService pool = Executors.newFixedThreadPool(numThreads); + + List<HashCodeQuery> queries = new ArrayList<HashCodeQuery>(numThreads); + for (int i = 0; i < numThreads; ++i) { + queries.add(new HashCodeQuery(obj)); + } + + try { + List<Future<Integer>> results = pool.invokeAll(queries, 5, TimeUnit.SECONDS); + + int hash = obj.hashCode(); + for (int i = 0; i < numThreads; ++i) { + int result = results.get(i).get(); + if (hash != result) { + throw new Error("Query #" + i + " wrong. Expected " + hash + ", got " + result); + } + } + pool.shutdown(); + } catch (CancellationException ex) { + System.err.println("Job timeout"); + System.exit(1); + } + } +} |