1/*
2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6843752
27 * @summary missing code for an anti-dependent Phi in GCM
28 *
29 * @run main/othervm -Xbatch compiler.c2.Test6843752
30 */
31
32package compiler.c2;
33
34public class Test6843752 {
35
36    Item list;
37
38    static class Item {
39        public Item    next;
40        public Item    prev;
41        public boolean remove;
42
43        Item(boolean r) { remove = r; }
44    }
45
46    private void linkIn(Item item) {
47        Item head = list;
48        if (head == null) {
49            item.next = item;
50            item.prev = item;
51            list = item;
52        } else {
53            item.next = head;
54            item.prev = head.prev;
55            head.prev.next = item;
56            head.prev = item;
57        }
58    }
59
60    private void linkOut(Item item) {
61        Item head = list;
62        if (item.next == item) {
63            list = null;
64        } else {
65            item.prev.next = item.next;
66            item.next.prev = item.prev;
67            if (head == item) {
68                list = item.next;
69            }
70        }
71        item.next = null;
72        item.prev = null; // this is the null pointer we are seeing
73    }
74
75    private void removeItems(int numItems) {
76        Item item = list;
77        if (item == null) {
78            return;
79        }
80        Item last = item.prev;
81        boolean done = false;
82        while (!done && numItems > 1) {
83            // the original code "done = (item == last);" triggered an infinite loop
84            // and was changed slightly in order to produce an exception instead.
85            done = (item.next == last.next);
86            item = item.next;
87            if (item.prev.remove) {
88                linkOut(item.prev);
89            }
90        }
91    }
92
93    public void perform(int numItems) {
94        for (int i = 0; i < numItems; i++) {
95            linkIn(new Item(i == 0));
96        }
97        removeItems(numItems);
98        list = null;
99    }
100
101    static public void main(String[] args) {
102        int caseCnt = 0;
103        Test6843752 bj = new Test6843752();
104        try {
105            for (; caseCnt < 500000;) {
106                int numItems = (++caseCnt % 2);
107                if ((caseCnt % 64) == 0) {
108                    numItems = 5;
109                }
110                bj.perform(numItems);
111                if ((caseCnt % 100000) == 0) {
112                    System.out.println("successfully performed " + caseCnt + " cases");
113                }
114            }
115        } catch (Exception e) {
116            System.out.println("ERROR: crashed during case " + caseCnt);
117            e.printStackTrace(System.out);
118            System.exit(97);
119        }
120    }
121}
122
123