001/*
002 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.replacements.test;
024
025import org.junit.*;
026
027import com.oracle.graal.compiler.test.*;
028import com.oracle.graal.virtual.phases.ea.*;
029
030public class MonitorTest extends GraalCompilerTest {
031
032    @Test
033    public void test0() {
034        test("lockObjectSimple", new Object(), new Object());
035        test("lockObjectSimple", new Object(), null);
036        test("lockObjectSimple", null, null);
037    }
038
039    @Test
040    public void test01() {
041        test("lockThisSimple", "test1", new Object());
042        test("lockThisSimple", "test1", null);
043    }
044
045    @Test
046    public void test02() {
047        test("lockObjectSimple", null, "test1");
048    }
049
050    @Test
051    public void test101() {
052        test("lockObject", new Object(), "test1", new String[1]);
053    }
054
055    @Test
056    public void test102() {
057        test("lockObject", null, "test1_1", new String[1]);
058    }
059
060    @Test
061    public void test2() {
062        test("lockThis", "test2", new String[1]);
063    }
064
065    /**
066     * Tests monitor operations on {@link PartialEscapePhase virtual objects}.
067     */
068    @Test
069    public void test3() {
070        test("lockLocalObject", "test3", new String[1]);
071    }
072
073    /**
074     * Tests recursive locking of objects which should be biasable.
075     */
076    @Test
077    public void test4() {
078        Chars src = new Chars("1234567890".toCharArray());
079        Chars dst = new Chars(src.data.length);
080        test("copyObj", src, dst, 100);
081    }
082
083    /**
084     * Tests recursive locking of objects which do not appear to be biasable.
085     */
086    @Test
087    public void test5() {
088        char[] src = "1234567890".toCharArray();
089        char[] dst = new char[src.length];
090        test("copyArr", src, dst, 100);
091    }
092
093    /**
094     * Extends {@link #test4()} with contention.
095     */
096    @Test
097    public void test6() {
098        Chars src = new Chars("1234567890".toCharArray());
099        Chars dst = new Chars(src.data.length);
100        int n = Runtime.getRuntime().availableProcessors();
101        testN(n, "copyObj", src, dst, 100);
102    }
103
104    /**
105     * Extends {@link #test5()} with contention.
106     */
107    @Test
108    public void test7() {
109        char[] src = "1234567890".toCharArray();
110        char[] dst = new char[src.length];
111        int n = Math.min(32, Runtime.getRuntime().availableProcessors());
112        testN(n, "copyArr", src, dst, 100);
113    }
114
115    private static String setAndGet(String[] box, String value) {
116        synchronized (box) {
117            box[0] = null;
118        }
119
120        // Do a GC while a object is locked (by the caller)
121        System.gc();
122
123        synchronized (box) {
124            box[0] = value;
125        }
126        return box[0];
127    }
128
129    public static Object lockObjectSimple(Object o, Object value) {
130        synchronized (o) {
131            value.hashCode();
132            return value;
133        }
134    }
135
136    public String lockThisSimple(String value, Object o) {
137        synchronized (this) {
138            synchronized (value) {
139                o.hashCode();
140                return value;
141            }
142        }
143    }
144
145    public static String lockObject(Object o, String value, String[] box) {
146        synchronized (o) {
147            return setAndGet(box, value);
148        }
149    }
150
151    public String lockThis(String value, String[] box) {
152        synchronized (this) {
153            return setAndGet(box, value);
154        }
155    }
156
157    public static String lockLocalObject(String value, String[] box) {
158        Object o = new Object();
159        synchronized (o) {
160            return setAndGet(box, value);
161        }
162    }
163
164    static class Chars {
165
166        final char[] data;
167
168        public Chars(int size) {
169            this.data = new char[size];
170        }
171
172        public Chars(char[] data) {
173            this.data = data;
174        }
175    }
176
177    public static String copyObj(Chars src, Chars dst, int n) {
178        for (int j = 0; j < n; j++) {
179            for (int i = 0; i < src.data.length; i++) {
180                synchronized (src) {
181                    synchronized (dst) {
182                        synchronized (src) {
183                            synchronized (dst) {
184                                dst.data[i] = src.data[i];
185                            }
186                        }
187                    }
188                }
189            }
190        }
191        return new String(dst.data);
192    }
193
194    public static String copyArr(char[] src, char[] dst, int n) {
195        for (int j = 0; j < n; j++) {
196            for (int i = 0; i < src.length; i++) {
197                synchronized (src) {
198                    synchronized (dst) {
199                        synchronized (src) {
200                            synchronized (dst) {
201                                dst[i] = src[i];
202                            }
203                        }
204                    }
205                }
206            }
207        }
208        return new String(dst);
209    }
210}