/*
 * Copyright (c) 2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "cpu/profile.hh"

#include <string>

#include "base/callback.hh"
#include "base/loader/symtab.hh"
#include "base/statistics.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"

void
BaseStackTrace::dump()
{
    StringWrap name(tc->getCpuPtr()->name());
    auto *symtab = &tc->getSystemPtr()->workload->symtab(tc);

    DPRINTFN("------ Stack ------\n");

    std::string symbol;
    for (int i = 0, size = stack.size(); i < size; ++i) {
        Addr addr = stack[size - i - 1];
        getSymbol(symbol, addr, symtab);
        DPRINTFN("%#x: %s\n", addr, symbol);
    }
}

bool
BaseStackTrace::tryGetSymbol(std::string &symbol, Addr addr,
                             const Loader::SymbolTable *symtab)
{
    const auto it = symtab->find(addr);
    if (it == symtab->end())
        return false;
    symbol = it->name;
    return true;
}

void
ProfileNode::dump(const std::string &symbol, uint64_t id,
                  const FunctionProfile &prof, std::ostream &os) const
{
    ccprintf(os, "%#x %s %d ", id, symbol, count);
    for (const auto &p: children)
        ccprintf(os, "%#x ", (intptr_t)(p.second));

    ccprintf(os, "\n");

    for (const auto &p: children) {
        Addr addr = p.first;
        std::string symbol;

        prof.trace->getSymbol(symbol, addr, &prof.symtab);

        const auto *node = p.second;
        node->dump(symbol, (intptr_t)node, prof, os);
    }
}

void
ProfileNode::clear()
{
    count = 0;
    for (const auto &p: children)
        p.second->clear();
}

FunctionProfile::FunctionProfile(std::unique_ptr<BaseStackTrace> _trace,
                                 const Loader::SymbolTable &_symtab) :
    symtab(_symtab), trace(std::move(_trace))
{
    Stats::registerResetCallback([this]() { clear(); });
}

ProfileNode *
FunctionProfile::consume(const std::vector<Addr> &stack)
{
    ProfileNode *current = &top;
    for (int i = 0, size = stack.size(); i < size; ++i) {
        ProfileNode *&ptr = current->children[stack[size - i - 1]];
        if (!ptr)
            ptr = new ProfileNode;

        current = ptr;
    }

    return current;
}

void
FunctionProfile::clear()
{
    top.clear();
    pc_count.clear();
}

void
FunctionProfile::dump(std::ostream &os) const
{
    ccprintf(os, ">>>PC data\n");
    for (const auto &p: pc_count) {
        Addr pc = p.first;
        Counter count = p.second;

        std::string symbol;
        if (trace->tryGetSymbol(symbol, pc, &symtab))
            ccprintf(os, "%s %d\n", symbol, count);
        else
            ccprintf(os, "%#x %d\n", pc, count);
    }

    ccprintf(os, ">>>function data\n");
    top.dump("top", 0, *this, os);
}

void
FunctionProfile::sample(ProfileNode *node, Addr pc)
{
    node->count++;

    auto it = symtab.findNearest(pc);
    if (it != symtab.end()) {
        pc_count[it->address]++;
    } else {
        // record PC even if we don't have a symbol to avoid
        // silently biasing the histogram
        pc_count[pc]++;
    }
}
