1/*
2 * Copyright (c) 2015, 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
24package jdk.test.lib.jittester.factories;
25
26import java.util.LinkedList;
27import jdk.test.lib.jittester.IRNode;
28import jdk.test.lib.jittester.ProductionFailedException;
29import jdk.test.lib.jittester.ProductionParams;
30import jdk.test.lib.jittester.Rule;
31import jdk.test.lib.jittester.Symbol;
32import jdk.test.lib.jittester.SymbolTable;
33import jdk.test.lib.jittester.Type;
34import jdk.test.lib.jittester.TypeList;
35import jdk.test.lib.jittester.VariableInfo;
36import jdk.test.lib.jittester.VariableInitialization;
37import jdk.test.lib.jittester.types.TypeKlass;
38import jdk.test.lib.jittester.utils.PseudoRandom;
39
40class VariableInitializationFactory extends SafeFactory<VariableInitialization> {
41    private final int operatorLimit;
42    private final long complexityLimit;
43    private final boolean constant;
44    private final boolean isStatic;
45    private final boolean isLocal;
46    private final boolean exceptionSafe;
47    private final TypeKlass ownerClass;
48
49    VariableInitializationFactory(TypeKlass ownerClass, boolean constant, boolean isStatic,
50            boolean isLocal, long complexityLimit, int operatorLimit, boolean exceptionSafe) {
51        this.ownerClass = ownerClass;
52        this.constant = constant;
53        this.isStatic = isStatic;
54        this.isLocal = isLocal;
55        this.complexityLimit = complexityLimit;
56        this.operatorLimit = operatorLimit;
57        this.exceptionSafe = exceptionSafe;
58    }
59
60    @Override
61    protected VariableInitialization sproduce() throws ProductionFailedException {
62        LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
63        PseudoRandom.shuffle(types);
64        if (types.isEmpty()) {
65            throw new ProductionFailedException();
66        }
67        Type resultType = types.getFirst();
68        IRNodeBuilder b = new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
69                .setOperatorLimit(operatorLimit - 1)
70                .setOwnerKlass(ownerClass)
71                .setResultType(resultType)
72                .setExceptionSafe(exceptionSafe)
73                .setNoConsts(false);
74        Rule<IRNode> rule = new Rule<>("initializer");
75        rule.add("literal_initializer", b.getLiteralFactory());
76        if (!ProductionParams.disableExprInInit.value()) {
77            rule.add("expression", b.getLimitedExpressionFactory());
78        }
79        Symbol thisSymbol = null;
80        if (isStatic) {
81            thisSymbol = SymbolTable.get("this", VariableInfo.class);
82            SymbolTable.remove(thisSymbol);
83        }
84        IRNode init;
85        try {
86            init = rule.produce();
87        } finally {
88            if (isStatic) {
89                SymbolTable.add(thisSymbol);
90            }
91        }
92        String resultName = "var_" + SymbolTable.getNextVariableNumber();
93        int flags = VariableInfo.INITIALIZED;
94        if (constant) {
95            flags |= VariableInfo.FINAL;
96        }
97        if (isStatic) {
98            flags |= VariableInfo.STATIC;
99        }
100        if (isLocal) {
101            flags |= VariableInfo.LOCAL;
102        }
103        VariableInfo varInfo = new VariableInfo(resultName, ownerClass, resultType, flags);
104        SymbolTable.add(varInfo);
105        return new VariableInitialization(varInfo, init);
106    }
107}
108