// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_COMPILATION_CACHE_TABLE_H_
#define V8_OBJECTS_COMPILATION_CACHE_TABLE_H_

#include "src/objects/feedback-cell.h"
#include "src/objects/hash-table.h"
#include "src/objects/js-regexp.h"
#include "src/objects/shared-function-info.h"
#include "src/roots/roots.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

class CompilationCacheShape : public BaseShape<HashTableKey*> {
 public:
  static inline bool IsMatch(HashTableKey* key, Object value) {
    return key->IsMatch(value);
  }

  static inline uint32_t Hash(ReadOnlyRoots roots, HashTableKey* key) {
    return key->Hash();
  }

  static inline uint32_t RegExpHash(String string, Smi flags);

  static inline uint32_t StringSharedHash(String source,
                                          SharedFunctionInfo shared,
                                          LanguageMode language_mode,
                                          int position);

  static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);

  static const int kPrefixSize = 0;
  // An 'entry' is essentially a grouped collection of slots. Entries are used
  // in various ways by the different caches; most store the actual key in the
  // first entry slot, but it may also be used differently.
  // Why 3 slots? Because of the eval cache.
  static const int kEntrySize = 3;
  static const bool kMatchNeedsHoleCheck = true;
};

class InfoCellPair {
 public:
  InfoCellPair() = default;
  inline InfoCellPair(Isolate* isolate, SharedFunctionInfo shared,
                      FeedbackCell feedback_cell);

  FeedbackCell feedback_cell() const {
    DCHECK(is_compiled_scope_.is_compiled());
    return feedback_cell_;
  }
  SharedFunctionInfo shared() const {
    DCHECK(is_compiled_scope_.is_compiled());
    return shared_;
  }

  bool has_feedback_cell() const {
    return !feedback_cell_.is_null() && is_compiled_scope_.is_compiled();
  }
  bool has_shared() const {
    // Only return true if SFI is compiled - the bytecode could have been
    // flushed while it's in the compilation cache, and not yet have been
    // removed form the compilation cache.
    return !shared_.is_null() && is_compiled_scope_.is_compiled();
  }

 private:
  IsCompiledScope is_compiled_scope_;
  SharedFunctionInfo shared_;
  FeedbackCell feedback_cell_;
};

EXTERN_DECLARE_HASH_TABLE(CompilationCacheTable, CompilationCacheShape)

class CompilationCacheTable
    : public HashTable<CompilationCacheTable, CompilationCacheShape> {
 public:
  NEVER_READ_ONLY_SPACE

  // The 'script' cache contains SharedFunctionInfos.
  static MaybeHandle<SharedFunctionInfo> LookupScript(
      Handle<CompilationCacheTable> table, Handle<String> src,
      Handle<Context> native_context, LanguageMode language_mode);
  static Handle<CompilationCacheTable> PutScript(
      Handle<CompilationCacheTable> cache, Handle<String> src,
      Handle<Context> native_context, LanguageMode language_mode,
      Handle<SharedFunctionInfo> value);

  // Eval code only gets cached after a second probe for the
  // code object. To do so, on first "put" only a hash identifying the
  // source is entered into the cache, mapping it to a lifetime count of
  // the hash. On each call to Age all such lifetimes get reduced, and
  // removed once they reach zero. If a second put is called while such
  // a hash is live in the cache, the hash gets replaced by an actual
  // cache entry. Age also removes stale live entries from the cache.
  // Such entries are identified by SharedFunctionInfos pointing to
  // either the recompilation stub, or to "old" code. This avoids memory
  // leaks due to premature caching of eval strings that are
  // never needed later.
  static InfoCellPair LookupEval(Handle<CompilationCacheTable> table,
                                 Handle<String> src,
                                 Handle<SharedFunctionInfo> shared,
                                 Handle<Context> native_context,
                                 LanguageMode language_mode, int position);
  static Handle<CompilationCacheTable> PutEval(
      Handle<CompilationCacheTable> cache, Handle<String> src,
      Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
      Handle<Context> native_context, Handle<FeedbackCell> feedback_cell,
      int position);

  // The RegExp cache contains JSRegExp::data fixed arrays.
  Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
  static Handle<CompilationCacheTable> PutRegExp(
      Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
      JSRegExp::Flags flags, Handle<FixedArray> value);

  // The Code cache shares native-context-independent (NCI) code between
  // contexts.
  MaybeHandle<Code> LookupCode(Handle<SharedFunctionInfo> key);
  static Handle<CompilationCacheTable> PutCode(
      Isolate* isolate, Handle<CompilationCacheTable> cache,
      Handle<SharedFunctionInfo> key, Handle<Code> value);

  void Remove(Object value);
  void Age();

  DECL_CAST(CompilationCacheTable)

 private:
  void RemoveEntry(int entry_index);

  OBJECT_CONSTRUCTORS(CompilationCacheTable,
                      HashTable<CompilationCacheTable, CompilationCacheShape>);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_COMPILATION_CACHE_TABLE_H_
