// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "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 THE COPYRIGHT
// OWNER 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 V8_STUB_CACHE_H_
#define V8_STUB_CACHE_H_

#include "macro-assembler.h"

namespace v8 {
namespace internal {


// The stub cache is used for megamorphic calls and property accesses.
// It maps (map, name, type)->Code*

// The design of the table uses the inline cache stubs used for
// mono-morphic calls. The beauty of this, we do not have to
// invalidate the cache whenever a prototype map is changed.  The stub
// validates the map chain as in the mono-morphic case.

class SCTableReference;

class StubCache : public AllStatic {
 public:
  struct Entry {
    String* key;
    Code* value;
  };


  static void Initialize(bool create_heap_objects);

  // Computes the right stub matching. Inserts the result in the
  // cache before returning.  This might compile a stub if needed.
  MUST_USE_RESULT static Object* ComputeLoadNonexistent(String* name,
                                                        JSObject* receiver);

  MUST_USE_RESULT static Object* ComputeLoadField(String* name,
                                                  JSObject* receiver,
                                                  JSObject* holder,
                                                  int field_index);

  MUST_USE_RESULT static Object* ComputeLoadCallback(String* name,
                                                     JSObject* receiver,
                                                     JSObject* holder,
                                                     AccessorInfo* callback);

  MUST_USE_RESULT static Object* ComputeLoadConstant(String* name,
                                                     JSObject* receiver,
                                                     JSObject* holder,
                                                     Object* value);

  MUST_USE_RESULT static Object* ComputeLoadInterceptor(String* name,
                                                        JSObject* receiver,
                                                        JSObject* holder);

  MUST_USE_RESULT static Object* ComputeLoadNormal();


  MUST_USE_RESULT static Object* ComputeLoadGlobal(String* name,
                                                   JSObject* receiver,
                                                   GlobalObject* holder,
                                                   JSGlobalPropertyCell* cell,
                                                   bool is_dont_delete);


  // ---

  MUST_USE_RESULT static Object* ComputeKeyedLoadField(String* name,
                                                       JSObject* receiver,
                                                       JSObject* holder,
                                                       int field_index);

  MUST_USE_RESULT static Object* ComputeKeyedLoadCallback(
      String* name,
      JSObject* receiver,
      JSObject* holder,
      AccessorInfo* callback);

  MUST_USE_RESULT static Object* ComputeKeyedLoadConstant(String* name,
                                                          JSObject* receiver,
                                                          JSObject* holder,
                                                          Object* value);

  MUST_USE_RESULT static Object* ComputeKeyedLoadInterceptor(String* name,
                                                             JSObject* receiver,
                                                             JSObject* holder);

  MUST_USE_RESULT static Object* ComputeKeyedLoadArrayLength(String* name,
                                                             JSArray* receiver);

  MUST_USE_RESULT static Object* ComputeKeyedLoadStringLength(String* name,
                                                              String* receiver);

  MUST_USE_RESULT static Object* ComputeKeyedLoadFunctionPrototype(
      String* name,
      JSFunction* receiver);

  // ---

  MUST_USE_RESULT static Object* ComputeStoreField(String* name,
                                                   JSObject* receiver,
                                                   int field_index,
                                                   Map* transition = NULL);

  MUST_USE_RESULT static Object* ComputeStoreNormal();

  MUST_USE_RESULT static Object* ComputeStoreGlobal(String* name,
                                                    GlobalObject* receiver,
                                                    JSGlobalPropertyCell* cell);

  MUST_USE_RESULT static Object* ComputeStoreCallback(String* name,
                                                      JSObject* receiver,
                                                      AccessorInfo* callback);

  MUST_USE_RESULT static Object* ComputeStoreInterceptor(String* name,
                                                         JSObject* receiver);

  // ---

  MUST_USE_RESULT static Object* ComputeKeyedStoreField(String* name,
                                                        JSObject* receiver,
                                                        int field_index,
                                                        Map* transition = NULL);

  // ---

  MUST_USE_RESULT static Object* ComputeCallField(int argc,
                                                  InLoopFlag in_loop,
                                                  Code::Kind,
                                                  String* name,
                                                  Object* object,
                                                  JSObject* holder,
                                                  int index);

  MUST_USE_RESULT static Object* ComputeCallConstant(int argc,
                                                     InLoopFlag in_loop,
                                                     Code::Kind,
                                                     String* name,
                                                     Object* object,
                                                     JSObject* holder,
                                                     JSFunction* function);

  MUST_USE_RESULT static Object* ComputeCallNormal(int argc,
                                                   InLoopFlag in_loop,
                                                   Code::Kind,
                                                   String* name,
                                                   JSObject* receiver);

  MUST_USE_RESULT static Object* ComputeCallInterceptor(int argc,
                                                        Code::Kind,
                                                        String* name,
                                                        Object* object,
                                                        JSObject* holder);

  MUST_USE_RESULT static Object* ComputeCallGlobal(int argc,
                                                   InLoopFlag in_loop,
                                                   Code::Kind,
                                                   String* name,
                                                   JSObject* receiver,
                                                   GlobalObject* holder,
                                                   JSGlobalPropertyCell* cell,
                                                   JSFunction* function);

  // ---

  MUST_USE_RESULT static Object* ComputeCallInitialize(int argc,
                                                       InLoopFlag in_loop,
                                                       Code::Kind kind);

  MUST_USE_RESULT static Object* ComputeCallPreMonomorphic(int argc,
                                                           InLoopFlag in_loop,
                                                           Code::Kind kind);

  MUST_USE_RESULT static Object* ComputeCallNormal(int argc,
                                                   InLoopFlag in_loop,
                                                   Code::Kind kind);

  MUST_USE_RESULT static Object* ComputeCallMegamorphic(int argc,
                                                        InLoopFlag in_loop,
                                                        Code::Kind kind);

  MUST_USE_RESULT static Object* ComputeCallMiss(int argc, Code::Kind kind);

  // Finds the Code object stored in the Heap::non_monomorphic_cache().
  MUST_USE_RESULT static Code* FindCallInitialize(int argc,
                                                  InLoopFlag in_loop,
                                                  Code::Kind kind);

#ifdef ENABLE_DEBUGGER_SUPPORT
  MUST_USE_RESULT static Object* ComputeCallDebugBreak(int argc,
                                                       Code::Kind kind);

  MUST_USE_RESULT static Object* ComputeCallDebugPrepareStepIn(int argc,
                                                               Code::Kind kind);
#endif

  // Update cache for entry hash(name, map).
  static Code* Set(String* name, Map* map, Code* code);

  // Clear the lookup table (@ mark compact collection).
  static void Clear();

  // Generate code for probing the stub cache table.
  // If extra != no_reg it might be used as am extra scratch register.
  static void GenerateProbe(MacroAssembler* masm,
                            Code::Flags flags,
                            Register receiver,
                            Register name,
                            Register scratch,
                            Register extra);

  enum Table {
    kPrimary,
    kSecondary
  };

 private:
  friend class SCTableReference;
  static const int kPrimaryTableSize = 2048;
  static const int kSecondaryTableSize = 512;
  static Entry primary_[];
  static Entry secondary_[];

  // Computes the hashed offsets for primary and secondary caches.
  static int PrimaryOffset(String* name, Code::Flags flags, Map* map) {
    // This works well because the heap object tag size and the hash
    // shift are equal.  Shifting down the length field to get the
    // hash code would effectively throw away two bits of the hash
    // code.
    ASSERT(kHeapObjectTagSize == String::kHashShift);
    // Compute the hash of the name (use entire hash field).
    ASSERT(name->HasHashCode());
    uint32_t field = name->hash_field();
    // Using only the low bits in 64-bit mode is unlikely to increase the
    // risk of collision even if the heap is spread over an area larger than
    // 4Gb (and not at all if it isn't).
    uint32_t map_low32bits =
        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
    // We always set the in_loop bit to zero when generating the lookup code
    // so do it here too so the hash codes match.
    uint32_t iflags =
        (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
    // Base the offset on a simple combination of name, flags, and map.
    uint32_t key = (map_low32bits + field) ^ iflags;
    return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
  }

  static int SecondaryOffset(String* name, Code::Flags flags, int seed) {
    // Use the seed from the primary cache in the secondary cache.
    uint32_t string_low32bits =
        static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
    // We always set the in_loop bit to zero when generating the lookup code
    // so do it here too so the hash codes match.
    uint32_t iflags =
        (static_cast<uint32_t>(flags) & ~Code::kFlagsICInLoopMask);
    uint32_t key = seed - string_low32bits + iflags;
    return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
  }

  // Compute the entry for a given offset in exactly the same way as
  // we do in generated code.  We generate an hash code that already
  // ends in String::kHashShift 0s.  Then we shift it so it is a multiple
  // of sizeof(Entry).  This makes it easier to avoid making mistakes
  // in the hashed offset computations.
  static Entry* entry(Entry* table, int offset) {
    const int shift_amount = kPointerSizeLog2 + 1 - String::kHashShift;
    return reinterpret_cast<Entry*>(
        reinterpret_cast<Address>(table) + (offset << shift_amount));
  }
};


class SCTableReference {
 public:
  static SCTableReference keyReference(StubCache::Table table) {
    return SCTableReference(
        reinterpret_cast<Address>(&first_entry(table)->key));
  }


  static SCTableReference valueReference(StubCache::Table table) {
    return SCTableReference(
        reinterpret_cast<Address>(&first_entry(table)->value));
  }

  Address address() const { return address_; }

 private:
  explicit SCTableReference(Address address) : address_(address) {}

  static StubCache::Entry* first_entry(StubCache::Table table) {
    switch (table) {
      case StubCache::kPrimary: return StubCache::primary_;
      case StubCache::kSecondary: return StubCache::secondary_;
    }
    UNREACHABLE();
    return NULL;
  }

  Address address_;
};

// ------------------------------------------------------------------------


// Support functions for IC stubs for callbacks.
Object* LoadCallbackProperty(Arguments args);
Object* StoreCallbackProperty(Arguments args);


// Support functions for IC stubs for interceptors.
Object* LoadPropertyWithInterceptorOnly(Arguments args);
Object* LoadPropertyWithInterceptorForLoad(Arguments args);
Object* LoadPropertyWithInterceptorForCall(Arguments args);
Object* StoreInterceptorProperty(Arguments args);
Object* CallInterceptorProperty(Arguments args);
Object* KeyedLoadPropertyWithInterceptor(Arguments args);


// The stub compiler compiles stubs for the stub cache.
class StubCompiler BASE_EMBEDDED {
 public:
  enum CheckType {
    RECEIVER_MAP_CHECK,
    STRING_CHECK,
    NUMBER_CHECK,
    BOOLEAN_CHECK
  };

  StubCompiler() : scope_(), masm_(NULL, 256), failure_(NULL) { }

  Object* CompileCallInitialize(Code::Flags flags);
  Object* CompileCallPreMonomorphic(Code::Flags flags);
  Object* CompileCallNormal(Code::Flags flags);
  Object* CompileCallMegamorphic(Code::Flags flags);
  Object* CompileCallMiss(Code::Flags flags);
#ifdef ENABLE_DEBUGGER_SUPPORT
  Object* CompileCallDebugBreak(Code::Flags flags);
  Object* CompileCallDebugPrepareStepIn(Code::Flags flags);
#endif

  // Static functions for generating parts of stubs.
  static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
                                                  int index,
                                                  Register prototype);

  // Generates prototype loading code that uses the objects from the
  // context we were in when this function was called.  This ties the
  // generated code to a particular context and so must not be used in
  // cases where the generated code is not allowed to have references
  // to objects from a context.
  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
                                                        int index,
                                                        Register prototype);

  static void GenerateFastPropertyLoad(MacroAssembler* masm,
                                       Register dst, Register src,
                                       JSObject* holder, int index);

  static void GenerateLoadArrayLength(MacroAssembler* masm,
                                      Register receiver,
                                      Register scratch,
                                      Label* miss_label);

  static void GenerateLoadStringLength(MacroAssembler* masm,
                                       Register receiver,
                                       Register scratch1,
                                       Register scratch2,
                                       Label* miss_label);

  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
                                            Register receiver,
                                            Register scratch1,
                                            Register scratch2,
                                            Label* miss_label);

  static void GenerateStoreField(MacroAssembler* masm,
                                 JSObject* object,
                                 int index,
                                 Map* transition,
                                 Register receiver_reg,
                                 Register name_reg,
                                 Register scratch,
                                 Label* miss_label);

  static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);

  // Generates code that verifies that the property holder has not changed
  // (checking maps of objects in the prototype chain for fast and global
  // objects or doing negative lookup for slow objects, ensures that the
  // property cells for global objects are still empty) and checks that the map
  // of the holder has not changed. If necessary the function also generates
  // code for security check in case of global object holders. Helps to make
  // sure that the current IC is still valid.
  //
  // The scratch and holder registers are always clobbered, but the object
  // register is only clobbered if it the same as the holder register. The
  // function returns a register containing the holder - either object_reg or
  // holder_reg.
  // The function can optionally (when save_at_depth !=
  // kInvalidProtoDepth) save the object at the given depth by moving
  // it to [esp + kPointerSize].

  Register CheckPrototypes(JSObject* object,
                           Register object_reg,
                           JSObject* holder,
                           Register holder_reg,
                           Register scratch1,
                           Register scratch2,
                           String* name,
                           Label* miss) {
    return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
                           scratch2, name, kInvalidProtoDepth, miss);
  }

  Register CheckPrototypes(JSObject* object,
                           Register object_reg,
                           JSObject* holder,
                           Register holder_reg,
                           Register scratch1,
                           Register scratch2,
                           String* name,
                           int save_at_depth,
                           Label* miss);

 protected:
  Object* GetCodeWithFlags(Code::Flags flags, const char* name);
  Object* GetCodeWithFlags(Code::Flags flags, String* name);

  MacroAssembler* masm() { return &masm_; }
  void set_failure(Failure* failure) { failure_ = failure; }

  void GenerateLoadField(JSObject* object,
                         JSObject* holder,
                         Register receiver,
                         Register scratch1,
                         Register scratch2,
                         Register scratch3,
                         int index,
                         String* name,
                         Label* miss);

  bool GenerateLoadCallback(JSObject* object,
                            JSObject* holder,
                            Register receiver,
                            Register name_reg,
                            Register scratch1,
                            Register scratch2,
                            Register scratch3,
                            AccessorInfo* callback,
                            String* name,
                            Label* miss,
                            Failure** failure);

  void GenerateLoadConstant(JSObject* object,
                            JSObject* holder,
                            Register receiver,
                            Register scratch1,
                            Register scratch2,
                            Register scratch3,
                            Object* value,
                            String* name,
                            Label* miss);

  void GenerateLoadInterceptor(JSObject* object,
                               JSObject* holder,
                               LookupResult* lookup,
                               Register receiver,
                               Register name_reg,
                               Register scratch1,
                               Register scratch2,
                               Register scratch3,
                               String* name,
                               Label* miss);

  static void LookupPostInterceptor(JSObject* holder,
                                    String* name,
                                    LookupResult* lookup);

 private:
  HandleScope scope_;
  MacroAssembler masm_;
  Failure* failure_;
};


class LoadStubCompiler: public StubCompiler {
 public:
  Object* CompileLoadNonexistent(String* name,
                                 JSObject* object,
                                 JSObject* last);

  Object* CompileLoadField(JSObject* object,
                           JSObject* holder,
                           int index,
                           String* name);

  Object* CompileLoadCallback(String* name,
                              JSObject* object,
                              JSObject* holder,
                              AccessorInfo* callback);

  Object* CompileLoadConstant(JSObject* object,
                              JSObject* holder,
                              Object* value,
                              String* name);

  Object* CompileLoadInterceptor(JSObject* object,
                                 JSObject* holder,
                                 String* name);

  Object* CompileLoadGlobal(JSObject* object,
                            GlobalObject* holder,
                            JSGlobalPropertyCell* cell,
                            String* name,
                            bool is_dont_delete);

 private:
  Object* GetCode(PropertyType type, String* name);
};


class KeyedLoadStubCompiler: public StubCompiler {
 public:
  Object* CompileLoadField(String* name,
                           JSObject* object,
                           JSObject* holder,
                           int index);

  Object* CompileLoadCallback(String* name,
                              JSObject* object,
                              JSObject* holder,
                              AccessorInfo* callback);

  Object* CompileLoadConstant(String* name,
                              JSObject* object,
                              JSObject* holder,
                              Object* value);

  Object* CompileLoadInterceptor(JSObject* object,
                                 JSObject* holder,
                                 String* name);

  Object* CompileLoadArrayLength(String* name);
  Object* CompileLoadStringLength(String* name);
  Object* CompileLoadFunctionPrototype(String* name);

 private:
  Object* GetCode(PropertyType type, String* name);
};


class StoreStubCompiler: public StubCompiler {
 public:
  Object* CompileStoreField(JSObject* object,
                            int index,
                            Map* transition,
                            String* name);
  Object* CompileStoreCallback(JSObject* object,
                               AccessorInfo* callbacks,
                               String* name);
  Object* CompileStoreInterceptor(JSObject* object, String* name);
  Object* CompileStoreGlobal(GlobalObject* object,
                             JSGlobalPropertyCell* holder,
                             String* name);


 private:
  Object* GetCode(PropertyType type, String* name);
};


class KeyedStoreStubCompiler: public StubCompiler {
 public:
  Object* CompileStoreField(JSObject* object,
                            int index,
                            Map* transition,
                            String* name);

 private:
  Object* GetCode(PropertyType type, String* name);
};


// List of functions with custom constant call IC stubs.
//
// Installation of custom call generators for the selected builtins is
// handled by the bootstrapper.
//
// Each entry has a name of a global function (lowercased), a flag
// controlling whether the generator is set on the function itself or
// on its instance prototype, a name of a builtin function on the
// function or its instance prototype (the one the generator is set
// for), and a name of a generator itself (used to build ids and
// generator function names).
#define CUSTOM_CALL_IC_GENERATORS(V)                          \
  V(array, INSTANCE_PROTOTYPE, push, ArrayPush)               \
  V(array, INSTANCE_PROTOTYPE, pop, ArrayPop)                 \
  V(string, INSTANCE_PROTOTYPE, charCodeAt, StringCharCodeAt) \
  V(string, INSTANCE_PROTOTYPE, charAt, StringCharAt)         \
  V(string, FUNCTION, fromCharCode, StringFromCharCode)


class CallStubCompiler: public StubCompiler {
 public:
  enum CustomGeneratorOwner {
    FUNCTION,
    INSTANCE_PROTOTYPE
  };

  enum {
#define DECLARE_CALL_GENERATOR_ID(ignored1, ignore2, ignored3, name) \
    k##name##CallGenerator,
    CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR_ID)
#undef DECLARE_CALL_GENERATOR_ID
    kNumCallGenerators
  };

  CallStubCompiler(int argc,
                   InLoopFlag in_loop,
                   Code::Kind kind,
                   InlineCacheHolderFlag cache_holder);

  Object* CompileCallField(JSObject* object,
                           JSObject* holder,
                           int index,
                           String* name);
  Object* CompileCallConstant(Object* object,
                              JSObject* holder,
                              JSFunction* function,
                              String* name,
                              CheckType check);
  Object* CompileCallInterceptor(JSObject* object,
                                 JSObject* holder,
                                 String* name);
  Object* CompileCallGlobal(JSObject* object,
                            GlobalObject* holder,
                            JSGlobalPropertyCell* cell,
                            JSFunction* function,
                            String* name);

  // Compiles a custom call constant/global IC using the generator
  // with given id. For constant calls cell is NULL.
  Object* CompileCustomCall(int generator_id,
                            Object* object,
                            JSObject* holder,
                            JSGlobalPropertyCell* cell,
                            JSFunction* function,
                            String* name);

#define DECLARE_CALL_GENERATOR(ignored1, ignored2, ignored3, name) \
  Object* Compile##name##Call(Object* object,                      \
                              JSObject* holder,                    \
                              JSGlobalPropertyCell* cell,          \
                              JSFunction* function,                \
                              String* fname);
  CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR)
#undef DECLARE_CALL_GENERATOR

 private:
  const ParameterCount arguments_;
  const InLoopFlag in_loop_;
  const Code::Kind kind_;
  const InlineCacheHolderFlag cache_holder_;

  const ParameterCount& arguments() { return arguments_; }

  Object* GetCode(PropertyType type, String* name);

  // Convenience function. Calls GetCode above passing
  // CONSTANT_FUNCTION type and the name of the given function.
  Object* GetCode(JSFunction* function);

  void GenerateNameCheck(String* name, Label* miss);

  void GenerateGlobalReceiverCheck(JSObject* object,
                                   JSObject* holder,
                                   String* name,
                                   Label* miss);

  // Generates code to load the function from the cell checking that
  // it still contains the same function.
  void GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
                                    JSFunction* function,
                                    Label* miss);

  // Generates a jump to CallIC miss stub. Returns Failure if the jump cannot
  // be generated.
  Object* GenerateMissBranch();
};


class ConstructStubCompiler: public StubCompiler {
 public:
  explicit ConstructStubCompiler() {}

  Object* CompileConstructStub(SharedFunctionInfo* shared);

 private:
  Object* GetCode();
};


// Holds information about possible function call optimizations.
class CallOptimization BASE_EMBEDDED {
 public:
  explicit CallOptimization(LookupResult* lookup);

  explicit CallOptimization(JSFunction* function);

  bool is_constant_call() const {
    return constant_function_ != NULL;
  }

  JSFunction* constant_function() const {
    ASSERT(constant_function_ != NULL);
    return constant_function_;
  }

  bool is_simple_api_call() const {
    return is_simple_api_call_;
  }

  FunctionTemplateInfo* expected_receiver_type() const {
    ASSERT(is_simple_api_call_);
    return expected_receiver_type_;
  }

  CallHandlerInfo* api_call_info() const {
    ASSERT(is_simple_api_call_);
    return api_call_info_;
  }

  // Returns the depth of the object having the expected type in the
  // prototype chain between the two arguments.
  int GetPrototypeDepthOfExpectedType(JSObject* object,
                                      JSObject* holder) const;

 private:
  void Initialize(JSFunction* function);

  // Determines whether the given function can be called using the
  // fast api call builtin.
  void AnalyzePossibleApiFunction(JSFunction* function);

  JSFunction* constant_function_;
  bool is_simple_api_call_;
  FunctionTemplateInfo* expected_receiver_type_;
  CallHandlerInfo* api_call_info_;
};

} }  // namespace v8::internal

#endif  // V8_STUB_CACHE_H_
