1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_IC_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_IC_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic-state.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IC_UTIL_LIST defines all utility functions called from generated
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// inline caching code. The argument for the macro, ICU, is the function name.
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define IC_UTIL_LIST(ICU)              \
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(LoadIC_Miss)                     \
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(KeyedLoadIC_Miss)                \
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(CallIC_Miss)                     \
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(CallIC_Customization_Miss)       \
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(StoreIC_Miss)                    \
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(StoreIC_Slow)                    \
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(SharedStoreIC_ExtendStorage)     \
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(KeyedStoreIC_Miss)               \
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(KeyedStoreIC_Slow)               \
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  /* Utilities for IC stubs. */        \
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(StoreCallbackProperty)           \
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(LoadPropertyWithInterceptorOnly) \
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(LoadPropertyWithInterceptor)     \
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(LoadElementWithInterceptor)      \
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(StorePropertyWithInterceptor)    \
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(CompareIC_Miss)                  \
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(BinaryOpIC_Miss)                 \
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(CompareNilIC_Miss)               \
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(Unreachable)                     \
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ICU(ToBooleanIC_Miss)
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IC is the base class for LoadIC, StoreIC, KeyedLoadIC, and KeyedStoreIC.
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass IC {
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The ids for utility called from the generated code.
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum UtilityId {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CONST_NAME(name) k##name,
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IC_UTIL_LIST(CONST_NAME)
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CONST_NAME
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kUtilityCount
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Looks up the address of the named utility.
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Address AddressFromUtilityId(UtilityId id);
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Alias the inline cache state type to make the IC code more readable.
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef InlineCacheState State;
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The IC code is either invoked with no extra frames on the stack
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // or with a single extra frame for supporting calls.
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum FrameDepth { NO_EXTRA_FRAME = 0, EXTRA_CALL_FRAME = 1 };
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Construct the IC structure with the given number of extra
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // JavaScript frames on the stack.
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IC(FrameDepth depth, Isolate* isolate);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~IC() {}
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  State state() const { return state_; }
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Address address() const;
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the current IC state based on the target stub, receiver and name.
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateState(Handle<Object> receiver, Handle<Object> name);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name);
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkPrototypeFailure(Handle<Object> name) {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsNameCompatibleWithPrototypeFailure(name));
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    state_ = PROTOTYPE_FAILURE;
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the stub contains weak maps then this function adds the stub to
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the dependent code array of each weak map.
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void RegisterWeakMapDependency(Handle<Code> stub);
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This function is called when a weak map in the stub is dying,
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // invalidates the stub by setting maps in it to undefined.
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void InvalidateMaps(Code* stub);
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Clear the inline cache to initial state.
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address,
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsLoadStub() const {
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target()->is_load_stub() || target()->is_keyed_load_stub();
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsStoreStub() const {
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target()->is_store_stub() || target()->is_keyed_store_stub();
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsCallStub() const { return target()->is_call_stub(); }
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class TypeClass>
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static JSFunction* GetRootConstructor(TypeClass* type,
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Context* native_context);
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Handle<Map> GetHandlerCacheHolder(HeapType* type,
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  bool receiver_is_holder,
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  Isolate* isolate,
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  CacheHolderFlag* flag);
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Handle<Map> GetICCacheHolder(HeapType* type, Isolate* isolate,
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             CacheHolderFlag* flag);
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsCleared(Code* code) {
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    InlineCacheState state = code->ic_state();
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return state == UNINITIALIZED || state == PREMONOMORPHIC;
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Utility functions to convert maps to types and back. There are two special
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // cases:
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - The heap_number_map is used as a marker which includes heap numbers as
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //   well as smis.
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - The oddball map is only used for booleans.
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Map> TypeToMap(HeapType* type, Isolate* isolate);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <class T>
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static typename T::TypeHandle MapToType(Handle<Map> map,
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          typename T::Region* region);
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<HeapType> CurrentTypeOf(Handle<Object> object,
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Isolate* isolate);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the call-site target; used for determining the state.
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> target() const { return target_; }
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address fp() const { return fp_; }
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address pc() const { return *pc_address_; }
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate() const { return isolate_; }
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the shared function info of the caller.
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SharedFunctionInfo* GetSharedFunctionInfo() const;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the code object of the caller.
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* GetCode() const;
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the original (non-breakpointed) code object of the caller.
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* GetOriginalCode() const;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Set the call-site target.
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_target(Code* code);
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_target_set() { return target_set_; }
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  char TransitionMarkFromState(IC::State state);
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TraceIC(const char* type, Handle<Object> name);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TraceIC(const char* type, Handle<Object> name, State old_state,
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               State new_state);
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaybeHandle<Object> TypeError(const char* type, Handle<Object> object,
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Handle<Object> key);
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Access the target code for the given IC address.
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline Code* GetTargetAtAddress(Address address,
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         ConstantPoolArray* constant_pool);
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline void SetTargetAtAddress(Address address, Code* target,
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        ConstantPoolArray* constant_pool);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    State old_state, State new_state,
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    bool target_remains_ic_stub);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void PostPatching(Address address, Code* target, Code* old_target);
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the handler either by compiling or by retrieving a cached version.
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> ComputeHandler(LookupIterator* lookup,
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Handle<Object> value = Handle<Code>::null());
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> CompileHandler(LookupIterator* lookup,
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Handle<Object> value,
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      CacheHolderFlag cache_holder) {
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<Code>::null();
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name);
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code);
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateMegamorphicCache(HeapType* type, Name* name, Code* code);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CopyICToMegamorphicCache(Handle<Name> name);
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PatchCache(Handle<Name> name, Handle<Code> code);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code::Kind kind() const { return kind_; }
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code::Kind handler_kind() const {
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC;
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC ||
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           kind_ == Code::KEYED_STORE_IC);
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kind_;
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> megamorphic_stub() {
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<Code>::null();
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Handle<String> name);
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExtraICState extra_ic_state() const { return extra_ic_state_; }
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; }
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<HeapType> receiver_type() { return receiver_type_; }
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void update_receiver_type(Handle<Object> receiver) {
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    receiver_type_ = CurrentTypeOf(receiver, isolate_);
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TargetMaps(MapHandleList* list) {
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindTargetMaps();
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < target_maps_.length(); i++) {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      list->Add(target_maps_.at(i));
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TargetTypes(TypeHandleList* list) {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindTargetMaps();
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < target_maps_.length(); i++) {
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      list->Add(MapToType<HeapType>(target_maps_.at(i), isolate_));
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Map* FirstTargetMap() {
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FindTargetMaps();
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void UpdateTarget();
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline Code* raw_target() const;
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline ConstantPoolArray* constant_pool() const;
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline ConstantPoolArray* raw_constant_pool() const;
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FindTargetMaps() {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (target_maps_set_) return;
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    target_maps_set_ = true;
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (state_ == MONOMORPHIC) {
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Map* map = target_->FindFirstMap();
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map != NULL) target_maps_.Add(handle(map));
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      target_->FindAllMaps(&target_maps_);
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Frame pointer for the frame that uses (calls) the IC.
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address fp_;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // All access to the program counter of an IC structure is indirect
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to make the code GC safe. This feature is crucial since
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // GetProperty and SetProperty are called and they in turn might
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // invoke the garbage collector.
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address* pc_address_;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The constant pool of the code which originally called the IC (which might
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // be for the breakpointed copy of the original code).
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<ConstantPoolArray> raw_constant_pool_;
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The original code target that missed.
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> target_;
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool target_set_;
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  State state_;
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code::Kind kind_;
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<HeapType> receiver_type_;
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaybeHandle<Code> maybe_handler_;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExtraICState extra_ic_state_;
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MapHandleList target_maps_;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool target_maps_set_;
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// cannot make forward declarations to an enum.
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass IC_Utility {
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit IC_Utility(IC::UtilityId id)
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : address_(IC::AddressFromUtilityId(id)), id_(id) {}
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address() const { return address_; }
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IC::UtilityId id() const { return id_; }
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address address_;
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IC::UtilityId id_;
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CallIC : public IC {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PatchMegamorphic(Handle<Object> function,
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void HandleMiss(Handle<Object> receiver, Handle<Object> function,
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns true if a custom handler was installed.
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       Handle<TypeFeedbackVector> vector, Handle<Smi> slot,
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       const CallICState& state);
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generator routines.
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> initialize_stub(Isolate* isolate, int argc,
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      CallICState::CallType call_type);
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline IC::State FeedbackToState(Handle<TypeFeedbackVector> vector,
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   Handle<Smi> slot) const;
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LoadIC : public IC {
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) {
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LoadICState(contextual_mode).GetExtraICState();
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContextualMode contextual_mode() const {
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LoadICState::GetContextualMode(extra_ic_state());
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsLoadStub());
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns if this IC is for contextual (no explicit receiver)
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // access to properties.
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsUndeclaredGlobal(Handle<Object> receiver) {
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (receiver->IsGlobalObject()) {
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return contextual_mode() == CONTEXTUAL;
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(contextual_mode() != CONTEXTUAL);
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return false;
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generator routines.
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GeneratePreMonomorphic(MacroAssembler* masm) {
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateMiss(masm);
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateMiss(MacroAssembler* masm);
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateNormal(MacroAssembler* masm);
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> initialize_stub(Isolate* isolate,
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      ExtraICState extra_state);
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Handle<Name> name);
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_target(Code* code);
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> slow_stub() const {
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (kind() == Code::LOAD_IC) {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return isolate()->builtins()->LoadIC_Slow();
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return isolate()->builtins()->KeyedLoadIC_Slow();
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> megamorphic_stub() OVERRIDE;
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update the inline cache and the global stub cache based on the
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // lookup result.
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateCaches(LookupIterator* lookup);
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> CompileHandler(LookupIterator* lookup,
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Handle<Object> unused,
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      CacheHolderFlag cache_holder);
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> pre_monomorphic_stub() const;
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           ExtraICState extra_state);
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> SimpleFieldLoad(FieldIndex index);
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class IC;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass KeyedLoadIC : public LoadIC {
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate)
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : LoadIC(depth, isolate) {
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target()->is_keyed_load_stub());
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Handle<Object> key);
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generator routines.
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateMiss(MacroAssembler* masm);
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GeneratePreMonomorphic(MacroAssembler* masm) {
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateMiss(masm);
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateGeneric(MacroAssembler* masm);
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateString(MacroAssembler* masm);
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Bit mask to be tested against bit field for the cases when
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generic stub should go into slow case.
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Access check is necessary explicitly since generic stub does not perform
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // map checks.
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kSlowCaseBitFieldMask =
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> generic_stub(Isolate* isolate);
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> pre_monomorphic_stub(Isolate* isolate);
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> LoadElementStub(Handle<JSObject> receiver);
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> pre_monomorphic_stub() const {
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pre_monomorphic_stub(isolate());
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> generic_stub() const { return generic_stub(isolate()); }
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> string_stub() {
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate()->builtins()->KeyedLoadIC_String();
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class IC;
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StoreIC : public IC {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class StrictModeState : public BitField<StrictMode, 1, 1> {};
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExtraICState ComputeExtraICState(StrictMode flag) {
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return StrictModeState::encode(flag);
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static StrictMode GetStrictMode(ExtraICState state) {
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return StrictModeState::decode(state);
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For convenience, a statically declared encoding of strict mode extra
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // IC state.
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const ExtraICState kStrictModeState = 1 << StrictModeState::kShift;
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StoreIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsStoreStub());
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StrictMode strict_mode() const {
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return StrictModeState::decode(extra_ic_state());
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generators for stub routines. Only called once at startup.
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateSlow(MacroAssembler* masm);
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GeneratePreMonomorphic(MacroAssembler* masm) {
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateMiss(masm);
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateMiss(MacroAssembler* masm);
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateMegamorphic(MacroAssembler* masm);
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateNormal(MacroAssembler* masm);
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateRuntimeSetProperty(MacroAssembler* masm,
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         StrictMode strict_mode);
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> initialize_stub(Isolate* isolate, StrictMode strict_mode);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT MaybeHandle<Object> Store(
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Object> object, Handle<Name> name, Handle<Object> value,
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JSReceiver::StoreFromKeyed store_mode =
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool LookupForWrite(LookupIterator* it, Handle<Object> value,
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      JSReceiver::StoreFromKeyed store_mode);
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> megamorphic_stub() OVERRIDE;
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stub accessors.
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> generic_stub() const;
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> slow_stub() const;
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> pre_monomorphic_stub() const {
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pre_monomorphic_stub(isolate(), strict_mode());
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           StrictMode strict_mode);
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update the inline cache and the global stub cache based on the
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // lookup result.
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void UpdateCaches(LookupIterator* lookup, Handle<Object> value,
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    JSReceiver::StoreFromKeyed store_mode);
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> CompileHandler(LookupIterator* lookup,
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Handle<Object> value,
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      CacheHolderFlag cache_holder);
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_target(Code* code);
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class IC;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum KeyedStoreCheckMap { kDontCheckMap, kCheckMap };
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength };
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass KeyedStoreIC : public StoreIC {
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ExtraICState bits (building on IC)
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ExtraICState bits
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class ExtraICStateKeyedAccessStoreMode
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : public BitField<KeyedAccessStoreMode, 2, 4> {};  // NOLINT
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static ExtraICState ComputeExtraICState(StrictMode flag,
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          KeyedAccessStoreMode mode) {
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return StrictModeState::encode(flag) |
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           ExtraICStateKeyedAccessStoreMode::encode(mode);
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static KeyedAccessStoreMode GetKeyedAccessStoreMode(
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExtraICState extra_state) {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  KeyedStoreIC(FrameDepth depth, Isolate* isolate) : StoreIC(depth, isolate) {
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(target()->is_keyed_store_stub());
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object,
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Handle<Object> name,
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Handle<Object> value);
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Code generators for stub routines.  Only called once at startup.
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GeneratePreMonomorphic(MacroAssembler* masm) {
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateMiss(masm);
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateMiss(MacroAssembler* masm);
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateSlow(MacroAssembler* masm);
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateGeneric(MacroAssembler* masm, StrictMode strict_mode);
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateSloppyArguments(MacroAssembler* masm);
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Handle<Code> pre_monomorphic_stub() const {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pre_monomorphic_stub(isolate(), strict_mode());
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           StrictMode strict_mode) {
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (strict_mode == STRICT) {
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> StoreElementStub(Handle<JSObject> receiver,
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                KeyedAccessStoreMode store_mode);
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void set_target(Code* code);
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stub accessors.
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> sloppy_arguments_stub() {
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return isolate()->builtins()->KeyedStoreIC_SloppyArguments();
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Handle<Object> key, Handle<Object> value);
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> ComputeTransitionedMap(Handle<Map> map,
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     KeyedAccessStoreMode store_mode);
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class IC;
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Type Recording BinaryOpIC, that records the types of the inputs and outputs.
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BinaryOpIC : public IC {
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Handle<Object> left,
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Handle<Object> right) WARN_UNUSED_RESULT;
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CompareIC : public IC {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompareIC(Isolate* isolate, Token::Value op)
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : IC(EXTRA_CALL_FRAME, isolate), op_(op) {}
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Update the inline cache for the given operands.
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Code* UpdateCaches(Handle<Object> x, Handle<Object> y);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Helper function for computing the condition for a compare operation.
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Condition ComputeCondition(Token::Value op);
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Factory method for getting an uninitialized compare stub.
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool HasInlinedSmiCode(Address address);
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool strict() const { return op_ == Token::EQ_STRICT; }
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Condition GetCondition() const { return ComputeCondition(op_); }
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Code* GetRawUninitialized(Isolate* isolate, Token::Value op);
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Isolate* isolate, Address address, Code* target,
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Token::Value op_;
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class IC;
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CompareNilIC : public IC {
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> CompareNil(Handle<Object> object);
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> GetUninitialized();
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void Clear(Address address, Code* target,
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    ConstantPoolArray* constant_pool);
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil,
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Handle<Object> object);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ToBooleanIC : public IC {
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> ToBoolean(Handle<Object> object);
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helper for BinaryOpIC and CompareIC.
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure);
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure);
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(UnaryOpIC_Miss);
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(StoreIC_MissFromStubFailure);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss);
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss);
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite);
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss);
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss);
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure);
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure);
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support functions for callbacks handlers.
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(StoreCallbackProperty);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Support functions for interceptor handlers.
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly);
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor);
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor);
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8::internal
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_IC_H_
699