/*
 * 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)
#include <sys/time.h>
#endif

#if OS(STARBOARD)
#define getenv(x) NULL
#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 (PLATFORM(MAC) && 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 PLATFORM(MAC) && 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)
{
#if !OS(WINCE)
    // 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);
#endif
}

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 (PLATFORM(MAC) && 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 (PLATFORM(MAC) && CPU(X86_64)) || (OS(LINUX) && CPU(X86))
    // Stop profiling
    setProfileTimer(0);
#endif

    current->report();
    delete current;
}

}
