/*
 * 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 "CodeProfiling.h"

#include "CodeProfile.h"
#include <wtf/MetaAllocator.h>

#if HAVE(SIGNAL_H)
#include <signal.h>
#endif

#if OS(LINUX) || OS(DARWIN)
#include <sys/time.h>
#endif

namespace JSC {

volatile CodeProfile* CodeProfiling::s_profileStack = 0;
CodeProfiling::Mode CodeProfiling::s_mode = CodeProfiling::Disabled;
WTF::MetaAllocatorTracker* CodeProfiling::s_tracker = 0;

#if COMPILER(CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
#endif

#if (OS(DARWIN) && !PLATFORM(EFL) && !PLATFORM(GTK) && CPU(X86_64)) || (OS(LINUX) && CPU(X86))
// Helper function to start & stop the timer.
// Presently we're using the wall-clock timer, since this seems to give the best results.
static void setProfileTimer(unsigned usec)
{
    itimerval timer;
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_usec = usec;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = usec;
    setitimer(ITIMER_REAL, &timer, 0);
}
#endif

#if COMPILER(CLANG)
#pragma clang diagnostic pop
#endif

#if OS(DARWIN) && !PLATFORM(EFL) && !PLATFORM(GTK) && CPU(X86_64)
static void profilingTimer(int, siginfo_t*, void* uap)
{
    mcontext_t context = static_cast<ucontext_t*>(uap)->uc_mcontext;
    CodeProfiling::sample(reinterpret_cast<void*>(context->__ss.__rip),
                          reinterpret_cast<void**>(context->__ss.__rbp));
}
#elif OS(LINUX) && CPU(X86)
static void profilingTimer(int, siginfo_t*, void* uap)
{
    mcontext_t context = static_cast<ucontext_t*>(uap)->uc_mcontext;
    CodeProfiling::sample(reinterpret_cast<void*>(context.gregs[REG_EIP]),
                          reinterpret_cast<void**>(context.gregs[REG_EBP]));
}
#endif

// Callback triggered when the timer is fired.
void CodeProfiling::sample(void* pc, void** framePointer)
{
    CodeProfile* profileStack = const_cast<CodeProfile*>(s_profileStack);
    if (profileStack)
        profileStack->sample(pc, framePointer);
}

void CodeProfiling::notifyAllocator(WTF::MetaAllocator* allocator)
{
    // Check for JSC_CODE_PROFILING.
    const char* codeProfilingMode = getenv("JSC_CODE_PROFILING");
    if (!codeProfilingMode)
        return;

    // Check for a valid mode, currently "1", "2", or "3".
    if (!codeProfilingMode[0] || codeProfilingMode[1])
        return;
    switch (*codeProfilingMode) {
    case '1':
        s_mode = Enabled;
        break;
    case '2':
        s_mode = Verbose;
        break;
    case '3':
        s_mode = VeryVerbose;
        break;
    default:
        return;
    }

    ASSERT(enabled());
    ASSERT(!s_tracker);
    s_tracker = new WTF::MetaAllocatorTracker();
    allocator->trackAllocations(s_tracker);
}

void* CodeProfiling::getOwnerUIDForPC(void* address)
{
    if (!s_tracker)
        return 0;
    WTF::MetaAllocatorHandle* handle = s_tracker->find(address);
    if (!handle)
        return 0;
    return handle->ownerUID();
}

void CodeProfiling::begin(const SourceCode& source)
{
    // Push a new CodeProfile onto the stack for each script encountered.
    CodeProfile* profileStack = const_cast<CodeProfile*>(s_profileStack);
    bool alreadyProfiling = profileStack;
    s_profileStack = profileStack = new CodeProfile(source, profileStack);

    // Is the profiler already running - if so, the timer will already be set up.
    if (alreadyProfiling)
        return;

#if (OS(DARWIN) && !PLATFORM(EFL) && !PLATFORM(GTK) && CPU(X86_64)) || (OS(LINUX) && CPU(X86))
    // Regsiter a signal handler & itimer.
    struct sigaction action;
    action.sa_sigaction = reinterpret_cast<void (*)(int, siginfo_t *, void *)>(profilingTimer);
    sigfillset(&action.sa_mask);
    action.sa_flags = SA_SIGINFO;
    sigaction(SIGALRM, &action, 0);
    setProfileTimer(100);
#endif
}

void CodeProfiling::end()
{
    // Pop the current profiler off the stack.
    CodeProfile* current = const_cast<CodeProfile*>(s_profileStack);
    ASSERT(current);
    s_profileStack = current->parent();

    // Is this the outermost script being profiled? - if not, just return.
    // We perform all output of profiles recursively from the outermost script,
    // to minimize profiling overhead from skewing results.
    if (s_profileStack)
        return;

#if (OS(DARWIN) && !PLATFORM(EFL) && !PLATFORM(GTK) && CPU(X86_64)) || (OS(LINUX) && CPU(X86))
    // Stop profiling
    setProfileTimer(0);
#endif

    current->report();
    delete current;
}

}
