/*
 * Copyright (C) 2012 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "config.h"
#include "CodeProfile.h"

#include "CodeBlock.h"
#include "CodeProfiling.h"
#include "LinkBuffer.h"
#include "ProfileTreeNode.h"
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>

#if PLATFORM(MAC)
#include <cxxabi.h>
#include <dlfcn.h>
#include <execinfo.h>
#endif

namespace JSC {

// Map from CodeType enum to a corresponding name.
const char* CodeProfile::s_codeTypeNames[CodeProfile::NumberOfCodeTypes] = {
    "[[EngineCode]]",
    "[[GlobalThunk]]",
    "[[RegExpCode]]",
    "[[DFGJIT]]",
    "[[BaselineOnly]]",
    "[[BaselineProfile]]",
    "[[BaselineOSR]]",
    "[[EngineFrame]]"
};

// Helper function, find the symbol name for a pc in JSC.
static const char* symbolName(void* address)
{
#if PLATFORM(MAC)
    Dl_info info;
    if (!dladdr(address, &info) || !info.dli_sname)
        return "<unknown>";

    const char* mangledName = info.dli_sname;
    const char* cxaDemangled = abi::__cxa_demangle(mangledName, 0, 0, 0);
    return cxaDemangled ? cxaDemangled : mangledName;
#else
    UNUSED_PARAM(address);
    return "<unknown>";
#endif
}

// Helper function, truncate traces to prune the output & make very verbose mode a little more readable.
static bool truncateTrace(const char* symbolName)
{
    return !strcmp(symbolName, "JSC::BytecodeGenerator::generate()")
        || !strcmp(symbolName, "JSC::Parser<JSC::Lexer<unsigned char> >::parseInner()")
        || !strcmp(symbolName, "WTF::fastMalloc(unsigned long)")
        || !strcmp(symbolName, "WTF::calculateUTCOffset()")
        || !strcmp(symbolName, "JSC::DFG::ByteCodeParser::parseCodeBlock()");
        
}

// Each trace consists of a sequence of zero or more 'EngineFrame' entries,
// followed by a sample in JIT code, or one or more 'EngineFrame' entries,
// followed by a 'EngineCode' terminator.
void CodeProfile::sample(void* pc, void** framePointer)
{
    // Disallow traces containing only a 'EngineCode' terminator, without any 'EngineFrame' frames.
    if (!framePointer)
        return;

    while (framePointer) {
        CodeType type;

#if ENABLE(JIT)
        // Determine if this sample fell in JIT code, and if so, from which JIT & why.
        void* ownerUID = CodeProfiling::getOwnerUIDForPC(pc);

        if (!ownerUID)
            type = EngineFrame;
        else if (ownerUID == GLOBAL_THUNK_ID)
            type = GlobalThunk;
        else if (ownerUID == REGEXP_CODE_ID)
            type = RegExpCode;
        else {
            CodeBlock* codeBlock = static_cast<CodeBlock*>(ownerUID);
            if (codeBlock->getJITType() == JITCode::DFGJIT)
                type = DFGJIT;
            else if (codeBlock->canCompileWithDFGState() != DFG::CanCompile)
                type = BaselineOnly;
            else if (codeBlock->replacement())
                type = BaselineOSR;
            else
                type = BaselineProfile;
        }
#else
        type = EngineFrame;
#endif

        // A sample in JIT code terminates the trace.
        m_samples.append(CodeRecord(pc, type));
        if (type != EngineFrame)
            return;

#if PLATFORM(MAC) && CPU(X86_64)
        // Walk up the stack.
        pc = framePointer[1];
        framePointer = reinterpret_cast<void**>(*framePointer);
#elif OS(LINUX) && CPU(X86)
        // Don't unwind the stack as some dependent third party libraries
        // may be compiled with -fomit-frame-pointer.
        framePointer = 0;
#else
        // This platform is not yet supported!
        ASSERT_NOT_REACHED();
#endif
    }

    // If we get here, we walked the entire stack without finding any frames of JIT code.
    m_samples.append(CodeRecord(0, EngineCode));
}

void CodeProfile::report()
{
    dataLog("<CodeProfiling %s:%d>\n", m_file.data(), m_lineNo);

    // How many frames of C-code to print - 0, if not verbose, 1 if verbose, up to 1024 if very verbose.
    unsigned recursionLimit = CodeProfiling::beVeryVerbose() ? 1024 : CodeProfiling::beVerbose();

    ProfileTreeNode profile;

    // Walk through the sample buffer.
    size_t trace = 0;
    while (trace < m_samples.size()) {

        // All traces are zero or more 'EngineFrame's, followed by a non-'EngineFrame'.
        // Scan to find the last sample in the trace.
        size_t lastInTrace = trace;
        while (m_samples[lastInTrace].type == EngineFrame)
            ++lastInTrace;

        // We use the last sample type to look up a name (used as a bucket in the profiler).
        ProfileTreeNode* callbacks = profile.sampleChild(s_codeTypeNames[m_samples[lastInTrace].type]);

        // If there are any samples in C-code, add up to recursionLimit of them into the profile tree.
        size_t lastEngineFrame = lastInTrace;
        for (unsigned count = 0; lastEngineFrame > trace && count < recursionLimit; ++count) {
            --lastEngineFrame;
            ASSERT(m_samples[lastEngineFrame].type == EngineFrame);
            const char* name = symbolName(m_samples[lastEngineFrame].pc);
            callbacks = callbacks->sampleChild(name);
            if (truncateTrace(name))
                break;
        }

        // Move on to the next trace.
        trace = lastInTrace + 1;
        ASSERT(trace <= m_samples.size());
    }

    // Output the profile tree.
    dataLog("Total samples: %lld\n", static_cast<long long>(profile.childCount()));
    profile.dump();
    
    for (size_t i = 0 ; i < m_children.size(); ++i)
        m_children[i]->report();

    dataLog("</CodeProfiling %s:%d>\n", m_file.data(), m_lineNo);
}

}
