/*
 * Copyright (C) 2012, 2013 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.
 */

#ifndef CodeCache_h
#define CodeCache_h

#include "CodeSpecializationKind.h"
#include "ParserModes.h"
#include "SourceCode.h"
#include "Strong.h"
#include "VariableEnvironment.h"
#include <wtf/CurrentTime.h>
#include <wtf/Forward.h>
#include <wtf/RandomNumber.h>
#include <wtf/WeakRandom.h>
#include <wtf/text/WTFString.h>

namespace JSC {

class EvalExecutable;
class FunctionMetadataNode;
class Identifier;
class JSScope;
class ParserError;
class ProgramExecutable;
class ModuleProgramExecutable;
class UnlinkedCodeBlock;
class UnlinkedEvalCodeBlock;
class UnlinkedModuleProgramCodeBlock;
class UnlinkedFunctionCodeBlock;
class UnlinkedFunctionExecutable;
class UnlinkedProgramCodeBlock;
class VM;
class SourceCode;
class SourceProvider;

class SourceCodeKey {
public:
    enum CodeType { EvalType, ProgramType, FunctionType, ModuleType };

    SourceCodeKey()
    {
    }

    SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserBuiltinMode builtinMode,
        JSParserStrictMode strictMode, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
        : m_sourceCode(sourceCode)
        , m_name(name)
        , m_flags(
            (static_cast<unsigned>(codeType) << 3)
            | (static_cast<unsigned>(builtinMode) << 2)
            | (static_cast<unsigned>(strictMode) << 1)
            | static_cast<unsigned>(thisTDZMode))
        , m_hash(string().impl()->hash())
    {
    }

    SourceCodeKey(WTF::HashTableDeletedValueType)
        : m_sourceCode(WTF::HashTableDeletedValue)
    {
    }

    bool isHashTableDeletedValue() const { return m_sourceCode.isHashTableDeletedValue(); }

    unsigned hash() const { return m_hash; }

    size_t length() const { return m_sourceCode.length(); }

    bool isNull() const { return m_sourceCode.isNull(); }

    // To save memory, we compute our string on demand. It's expected that source
    // providers cache their strings to make this efficient.
    String string() const { return m_sourceCode.toString(); }

    bool operator==(const SourceCodeKey& other) const
    {
        return m_hash == other.m_hash
            && length() == other.length()
            && m_flags == other.m_flags
            && m_name == other.m_name
            && string() == other.string();
    }

private:
    SourceCode m_sourceCode;
    String m_name;
    unsigned m_flags;
    unsigned m_hash;
};

struct SourceCodeKeyHash {
    static unsigned hash(const SourceCodeKey& key) { return key.hash(); }
    static bool equal(const SourceCodeKey& a, const SourceCodeKey& b) { return a == b; }
    static const bool safeToCompareToEmptyOrDeleted = false;
};

struct SourceCodeKeyHashTraits : SimpleClassHashTraits<SourceCodeKey> {
    static const bool hasIsEmptyValueFunction = true;
    static bool isEmptyValue(const SourceCodeKey& sourceCodeKey) { return sourceCodeKey.isNull(); }
};

struct SourceCodeValue {
    SourceCodeValue()
    {
    }

    SourceCodeValue(VM& vm, JSCell* cell, int64_t age)
        : cell(vm, cell)
        , age(age)
    {
    }

    Strong<JSCell> cell;
    int64_t age;
};

class CodeCacheMap {
public:
    typedef HashMap<SourceCodeKey, SourceCodeValue, SourceCodeKeyHash, SourceCodeKeyHashTraits> MapType;
    typedef MapType::iterator iterator;
    typedef MapType::AddResult AddResult;

    CodeCacheMap()
        : m_size(0)
        , m_sizeAtLastPrune(0)
        , m_timeAtLastPrune(monotonicallyIncreasingTime())
        , m_minCapacity(0)
        , m_capacity(0)
        , m_age(0)
    {
    }

    SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key)
    {
        prune();

        iterator findResult = m_map.find(key);
        if (findResult == m_map.end())
            return nullptr;

        int64_t age = m_age - findResult->value.age;
        if (age > m_capacity) {
            // A requested object is older than the cache's capacity. We can
            // infer that requested objects are subject to high eviction probability,
            // so we grow the cache to improve our hit rate.
            m_capacity += recencyBias * oldObjectSamplingMultiplier * key.length();
        } else if (age < m_capacity / 2) {
            // A requested object is much younger than the cache's capacity. We can
            // infer that requested objects are subject to low eviction probability,
            // so we shrink the cache to save memory.
            m_capacity -= recencyBias * key.length();
            if (m_capacity < m_minCapacity)
                m_capacity = m_minCapacity;
        }

        findResult->value.age = m_age;
        m_age += key.length();

        return &findResult->value;
    }

    AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value)
    {
        prune();

        AddResult addResult = m_map.add(key, value);
        ASSERT(addResult.isNewEntry);

        m_size += key.length();
        m_age += key.length();
        return addResult;
    }

    void remove(iterator it)
    {
        m_size -= it->key.length();
        m_map.remove(it);
    }

    void clear()
    {
        m_size = 0;
        m_age = 0;
        m_map.clear();
    }

    int64_t age() { return m_age; }

private:
    // This constant factor biases cache capacity toward allowing a minimum
    // working set to enter the cache before it starts evicting.
    static const double workingSetTime;
    static const int64_t workingSetMaxBytes = 16000000;
    static const size_t workingSetMaxEntries = 2000;

    // This constant factor biases cache capacity toward recent activity. We
    // want to adapt to changing workloads.
    static const int64_t recencyBias = 4;

    // This constant factor treats a sampled event for one old object as if it
    // happened for many old objects. Most old objects are evicted before we can
    // sample them, so we need to extrapolate from the ones we do sample.
    static const int64_t oldObjectSamplingMultiplier = 32;

    size_t numberOfEntries() const { return static_cast<size_t>(m_map.size()); }
    bool canPruneQuickly() const { return numberOfEntries() < workingSetMaxEntries; }

    void pruneSlowCase();
    void prune()
    {
        if (m_size <= m_capacity && canPruneQuickly())
            return;

        if (monotonicallyIncreasingTime() - m_timeAtLastPrune < workingSetTime
            && m_size - m_sizeAtLastPrune < workingSetMaxBytes
            && canPruneQuickly())
                return;

        pruneSlowCase();
    }

    MapType m_map;
    int64_t m_size;
    int64_t m_sizeAtLastPrune;
    double m_timeAtLastPrune;
    int64_t m_minCapacity;
    int64_t m_capacity;
    int64_t m_age;
};

// Caches top-level code such as <script>, eval(), new Function, and JSEvaluateScript().
class CodeCache {
    WTF_MAKE_FAST_ALLOCATED;
public:
    CodeCache();
    ~CodeCache();

    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&);
    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);
    UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ProfilerMode, ParserError&);
    UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);

    void clear()
    {
        m_sourceCode.clear();
    }

private:
    template <class UnlinkedCodeBlockType, class ExecutableType> 
    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*);

    CodeCacheMap m_sourceCode;
};

}

#endif // CodeCache_h
