1#
2# Copyright (C) 2016 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17
18class FunctionSummary(object):
19    """Summarizes a function and its blocks from .gcno file.
20
21    Attributes:
22        blocks: list of BlockSummary objects for each block in the function.
23        ident: integer function identifier.
24        name: function name.
25        src_file_name: name of source file containing the function.
26        first_line_number: integer line number at which the function begins in
27            srcFile.
28    """
29
30    def __init__(self, ident, name, src_file_name, first_line_number):
31        """Inits the function summary with provided values.
32
33        Stores the identification string, name, source file name, and
34        first line number in the object attributes. Initializes the block
35        attribute to the empty list.
36
37        Args:
38            ident: integer function identifier.
39            name: function name.
40            src_file_name: name of source file containing the function.
41            first_line_number: integer line number at which the function begins in
42              the source file.
43        """
44        self.blocks = []
45        self.ident = ident
46        self.name = name
47        self.src_file_name = src_file_name
48        self.first_line_number = first_line_number
49
50    def Resolve(self):
51        """Resolves the block and arc counts.
52
53        Using the edges that were resolved by the GCDA file,
54        counts are resolved in the unresolved arcs. Then, block
55        counts are resolved by summing the counts along arcs entering
56        the block.
57
58        Returns:
59            True if the counts could be resolved and False otherwise.
60        """
61
62        unresolved_arcs = []
63        for block in self.blocks:
64            for arc in block.exit_arcs:
65                if not arc.resolved:
66                    unresolved_arcs.append(arc)
67
68        index = 0
69        prev_length = len(unresolved_arcs) + 1
70        # Resolve the arc counts
71        while len(unresolved_arcs) > 0:
72            index = index % len(unresolved_arcs)
73            if index == 0 and len(unresolved_arcs) == prev_length:
74                return False
75            else:
76                prev_length = len(unresolved_arcs)
77            arc = unresolved_arcs[index]
78            if arc.Resolve():
79                unresolved_arcs.remove(arc)
80            else:
81                index = index + 1
82
83        # Resolve the block counts
84        for block in self.blocks:
85            if len(block.entry_arcs):
86                block.count = sum(arc.count for arc in block.entry_arcs)
87            else:
88                block.count = sum(arc.count for arc in block.exit_arcs)
89
90        return True
91
92    def __str__(self):
93        """Serializes the function summary as a string.
94
95        Returns:
96            String representation of the functions and its blocks.
97        """
98        output = ('Function:  %s : %s\r\n\tFirst Line Number:%i\r\n' %
99                  (self.src_file_name, self.name, self.first_line_number))
100        for b in self.blocks:
101            output += str(b)
102        return output
103