diff options
author | Calin Juravle <calin@google.com> | 2015-04-17 19:12:31 +0100 |
---|---|---|
committer | Calin Juravle <calin@google.com> | 2015-04-20 14:02:51 +0100 |
commit | 27df758e2e7baebb6e3f393f9732fd0d064420c8 (patch) | |
tree | 261207281fd574deffb4dc1c1bc6bea8f150993e /test/476-checker-ctor-memory-barrier | |
parent | f8bdd9f3a002970e4b8fdcf6fe6730116f1626c3 (diff) | |
download | art-27df758e2e7baebb6e3f393f9732fd0d064420c8.tar.gz art-27df758e2e7baebb6e3f393f9732fd0d064420c8.tar.bz2 art-27df758e2e7baebb6e3f393f9732fd0d064420c8.zip |
[optimizing] Add memory barriers in constructors when needed
If a class has final fields we must add a memory barrier before
returning from constructor. This makes sure the fields are visible to
other threads.
Bug: 19851497
Change-Id: If8c485092fc512efb9636cd568cb0543fb27688e
Diffstat (limited to 'test/476-checker-ctor-memory-barrier')
-rw-r--r-- | test/476-checker-ctor-memory-barrier/expected.txt | 0 | ||||
-rw-r--r-- | test/476-checker-ctor-memory-barrier/info.txt | 2 | ||||
-rw-r--r-- | test/476-checker-ctor-memory-barrier/src/Main.java | 147 |
3 files changed, 149 insertions, 0 deletions
diff --git a/test/476-checker-ctor-memory-barrier/expected.txt b/test/476-checker-ctor-memory-barrier/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/476-checker-ctor-memory-barrier/expected.txt diff --git a/test/476-checker-ctor-memory-barrier/info.txt b/test/476-checker-ctor-memory-barrier/info.txt new file mode 100644 index 0000000000..9bd311f784 --- /dev/null +++ b/test/476-checker-ctor-memory-barrier/info.txt @@ -0,0 +1,2 @@ +Tests if we add memory barriers on constructors when needed (i.e when the +class has final fields). diff --git a/test/476-checker-ctor-memory-barrier/src/Main.java b/test/476-checker-ctor-memory-barrier/src/Main.java new file mode 100644 index 0000000000..10aa2ab164 --- /dev/null +++ b/test/476-checker-ctor-memory-barrier/src/Main.java @@ -0,0 +1,147 @@ +/* +* 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 ClassWithoutFinals { + // CHECK-START: void ClassWithoutFinals.<init>() register (after) + // CHECK-NOT: MemoryBarrier {{StoreStore}} + public ClassWithoutFinals() {} +} + +class ClassWithFinals { + public final int x; + public ClassWithFinals obj; + + // CHECK-START: void ClassWithFinals.<init>(boolean) register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + public ClassWithFinals(boolean cond) { + x = 0; + if (cond) { + // avoid inlining + throw new RuntimeException(); + } + } + + // CHECK-START: void ClassWithFinals.<init>() register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + public ClassWithFinals() { + x = 0; + } + + // CHECK-START: void ClassWithFinals.<init>(int) register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + public ClassWithFinals(int x) { + // This should have two barriers: + // - one for the constructor + // - one for the `new` which should be inlined. + obj = new ClassWithFinals(); + this.x = x; + } +} + +class InheritFromClassWithFinals extends ClassWithFinals { + // CHECK-START: void InheritFromClassWithFinals.<init>() register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + + // CHECK-START: void InheritFromClassWithFinals.<init>() register (after) + // CHECK-NOT: InvokeStaticOrDirect + public InheritFromClassWithFinals() { + // Should inline the super constructor. + } + + // CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after) + // CHECK: InvokeStaticOrDirect + + // CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after) + // CHECK-NOT: MemoryBarrier {{StoreStore}} + public InheritFromClassWithFinals(boolean cond) { + super(cond); + // should not inline the super constructor + } +} + +class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals { + final int y; + + // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + + // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after) + // CHECK-NOT: InvokeStaticOrDirect + public HaveFinalsAndInheritFromClassWithFinals() { + // Should inline the super constructor. + y = 0; + } + + // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) register (after) + // CHECK: InvokeStaticOrDirect + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: ReturnVoid + public HaveFinalsAndInheritFromClassWithFinals(boolean cond) { + super(cond); + // should not inline the super constructor + y = 0; + } +} + +public class Main { + + // CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after) + // CHECK: InvokeStaticOrDirect + + // CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after) + // CHECK-NOT: MemoryBarrier {{StoreStore}} + public static ClassWithFinals noInlineNoConstructorBarrier() { + return new ClassWithFinals(false); + } + + // CHECK-START: ClassWithFinals Main.inlineConstructorBarrier() register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: Return + + // CHECK-START: ClassWithFinals Main.inlineConstructorBarrier() register (after) + // CHECK-NOT: InvokeStaticOrDirect + public static ClassWithFinals inlineConstructorBarrier() { + return new ClassWithFinals(); + } + + // CHECK-START: InheritFromClassWithFinals Main.doubleInlineConstructorBarrier() register (after) + // CHECK: MemoryBarrier {{StoreStore}} + // CHECK-NOT: {{.*}} + // CHECK: Return + + // CHECK-START: InheritFromClassWithFinals Main.doubleInlineConstructorBarrier() register (after) + // CHECK-NOT: InvokeStaticOrDirect + public static InheritFromClassWithFinals doubleInlineConstructorBarrier() { + return new InheritFromClassWithFinals(); + } + + public static void main(String[] args) { } +} |