1/*
2 * Copyright (c) 2005, 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.functions;
25
26import java.util.Collection;
27import java.util.List;
28import jdk.test.lib.jittester.IRNode;
29import jdk.test.lib.jittester.Symbol;
30import jdk.test.lib.jittester.SymbolTable;
31import jdk.test.lib.jittester.types.TypeKlass;
32import jdk.test.lib.jittester.visitors.Visitor;
33
34
35public class Function extends IRNode {
36    private FunctionInfo functionInfo = new FunctionInfo();
37
38    public Function(TypeKlass ownerClass, FunctionInfo functionInfo, List<IRNode> args) {
39        super(functionInfo.type);
40        setOwner(ownerClass);
41        this.functionInfo = functionInfo;
42        addChildren(args);
43    }
44
45    @Override
46    public long complexity() {
47        int argsComplexity = 0;
48        for (IRNode child : getChildren()) {
49            argsComplexity += child.complexity();
50        }
51        long funcComplexity = functionInfo.complexity;
52        TypeKlass typeKlass = this.owner;
53        if (functionInfo.isConstructor()) {
54            // Sum complexities of all default constructors of parent classes
55            for (TypeKlass parent : typeKlass.getAllParents()) {
56                Collection<Symbol> parentFuncs = SymbolTable.getAllCombined(parent, FunctionInfo.class);
57                for (Symbol f : parentFuncs) {
58                    FunctionInfo c = (FunctionInfo) f;
59                    if (c.name.equals(c.owner.getName()) && c.argTypes.isEmpty()) {
60                        funcComplexity += c.complexity;
61                    }
62                }
63            }
64            // TODO: Complexities of all non-static initializers should be also added..
65        } else {
66            // Perform the CHA and find the highest complexity
67            for (TypeKlass child : typeKlass.getAllChildren()) {
68                Collection<Symbol> childFuncs = SymbolTable.getAllCombined(child, FunctionInfo.class);
69                for (Symbol childFunc : childFuncs) {
70                    if (childFunc.equals(functionInfo)) {
71                        funcComplexity = Math.max(funcComplexity, ((FunctionInfo) childFunc).complexity);
72                    }
73                }
74            }
75        }
76        return argsComplexity + funcComplexity;
77    }
78
79    @Override
80    public<T> T accept(Visitor<T> v) {
81        return v.visit(this);
82    }
83
84    public FunctionInfo getValue() {
85        return functionInfo;
86    }
87}
88