165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without
343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met:
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions of source code must retain the above copyright
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       notice, this list of conditions and the following disclaimer.
843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Redistributions in binary form must reproduce the above
943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       copyright notice, this list of conditions and the following
1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       disclaimer in the documentation and/or other materials provided
1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       with the distribution.
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     * Neither the name of Google Inc. nor the names of its
1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       contributors may be used to endorse or promote products derived
1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//       from this software without specific prior written permission.
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_IC_H_
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_IC_H_
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "macro-assembler.h"
3240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#include "type-info.h"
3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// IC_UTIL_LIST defines all utility functions called from generated
3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// inline caching code. The argument for the macro, ICU, is the function name.
400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org#define IC_UTIL_LIST(ICU)                             \
410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(LoadIC_Miss)                                    \
420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(KeyedLoadIC_Miss)                               \
430b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(CallIC_Miss)                                    \
441af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  ICU(KeyedCallIC_Miss)                               \
450b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(StoreIC_Miss)                                   \
465c838251403b0be9a882540f1922577abba4c872ager@chromium.org  ICU(StoreIC_ArrayLength)                            \
4757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  ICU(StoreIC_Slow)                                   \
480b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(SharedStoreIC_ExtendStorage)                    \
490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(KeyedStoreIC_Miss)                              \
50ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  ICU(KeyedStoreIC_Slow)                              \
510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  /* Utilities for IC stubs. */                       \
520b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(StoreCallbackProperty)                          \
530b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(LoadPropertyWithInterceptorOnly)                \
540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(LoadPropertyWithInterceptorForLoad)             \
550b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  ICU(LoadPropertyWithInterceptorForCall)             \
565c838251403b0be9a882540f1922577abba4c872ager@chromium.org  ICU(KeyedLoadPropertyWithInterceptor)               \
57ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  ICU(StoreInterceptorProperty)                       \
589fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org  ICU(CompareIC_Miss)                                 \
5925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  ICU(BinaryOpIC_Miss)                                \
60ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  ICU(CompareNilIC_Miss)                              \
6177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  ICU(Unreachable)                                    \
62b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  ICU(ToBooleanIC_Miss)
6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
64e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC,
65e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org// and KeyedStoreIC.
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass IC {
6843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
6943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The ids for utility called from the generated code.
7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  enum UtilityId {
7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  #define CONST_NAME(name) k##name,
7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    IC_UTIL_LIST(CONST_NAME)
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  #undef CONST_NAME
7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    kUtilityCount
7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  };
7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Looks up the address of the named utility.
7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static Address AddressFromUtilityId(UtilityId id);
7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Alias the inline cache state type to make the IC code more readable.
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  typedef InlineCacheState State;
8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The IC code is either invoked with no extra frames on the stack
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // or with a single extra frame for supporting calls.
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  enum FrameDepth {
8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    NO_EXTRA_FRAME = 0,
8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    EXTRA_CALL_FRAME = 1
8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  };
8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Construct the IC structure with the given number of extra
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // JavaScript frames on the stack.
92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  IC(FrameDepth depth, Isolate* isolate);
9364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  virtual ~IC() {}
9443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
95fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  State state() const { return state_; }
9664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  inline Address address() const;
9764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
98ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Compute the current IC state based on the target stub, receiver and name.
99d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void UpdateState(Handle<Object> receiver, Handle<Object> name);
100fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void MarkMonomorphicPrototypeFailure() {
101fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
102fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Clear the inline cache to initial state.
1053d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address);
10643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Computes the reloc info for this IC. This is a fairly expensive
10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // operation as it has to search through the heap to find the code
10943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // object that contains this IC site.
110236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  RelocInfo::Mode ComputeMode();
11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Returns if this IC is for contextual (no explicit receiver)
11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // access to properties.
114c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org  bool IsUndeclaredGlobal(Handle<Object> receiver) {
11513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    if (receiver->IsGlobalObject()) {
116c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org      return SlowIsUndeclaredGlobal();
11713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    } else {
118c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org      ASSERT(!SlowIsUndeclaredGlobal());
11913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org      return false;
12013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org    }
12113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  }
12213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
123c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org  bool SlowIsUndeclaredGlobal() {
124236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org    return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT;
125236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  }
12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org#ifdef DEBUG
128b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  bool IsLoadStub() {
129b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return target()->is_load_stub() || target()->is_keyed_load_stub();
130b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
131b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
132b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  bool IsStoreStub() {
133b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return target()->is_store_stub() || target()->is_keyed_store_stub();
134b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
135b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
136b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  bool IsCallStub() {
137b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    return target()->is_call_stub() || target()->is_keyed_call_stub();
138b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  }
139b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org#endif
140b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
14169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Determines which map must be used for keeping the code stub.
14269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // These methods should not be called with undefined or null.
143b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object);
144b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // TODO(verwaest): This currently returns a HeapObject rather than JSObject*
145b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // since loading the IC for loading the length from strings are stored on
146b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // the string map directly, rather than on the JSObject-typed prototype.
147b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  static inline HeapObject* GetCodeCacheHolder(Isolate* isolate,
148b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                               Object* object,
149b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                               InlineCacheHolderFlag holder);
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
151af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static inline InlineCacheHolderFlag GetCodeCacheFlag(Type* type);
152af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static inline Handle<Map> GetCodeCacheHolder(InlineCacheHolderFlag flag,
153af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org                                               Type* type,
154af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org                                               Isolate* isolate);
155af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1568e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static bool IsCleared(Code* code) {
1578e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    InlineCacheState state = code->ic_state();
1588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return state == UNINITIALIZED || state == PREMONOMORPHIC;
1598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
1608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
161af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // Utility functions to convert maps to types and back. There are two special
162af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // cases:
163af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // - The heap_number_map is used as a marker which includes heap numbers as
164af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  //   well as smis.
165af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  // - The oddball map is only used for booleans.
166af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static Handle<Map> TypeToMap(Type* type, Isolate* isolate);
167af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static Type* MapToType(Handle<Map> type);
168f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  static Handle<Type> CurrentTypeOf(Handle<Object> object, Isolate* isolate);
169af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen protected:
171b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  // Get the call-site target; used for determining the state.
172b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Handle<Code> target() const { return target_; }
173b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address fp() const { return fp_; }
17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address pc() const { return *pc_address_; }
176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate() const { return isolate_; }
17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Computes the address in the original code when the code running is
18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // containing break points (calls to DebugBreakXXX builtins).
18164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Address OriginalCodeAddress() const;
18265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Set the call-site target.
185c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  void set_target(Code* code) {
186c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    SetTargetAtAddress(address(), code);
187c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org    target_set_ = true;
188c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  }
189c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
190c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  bool is_target_set() { return target_set_; }
19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG
19364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  char TransitionMarkFromState(IC::State state);
19464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
195d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void TraceIC(const char* type, Handle<Object> name);
19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
19743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
198ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Failure* TypeError(const char* type,
199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                     Handle<Object> object,
200ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                     Handle<Object> key);
201ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Failure* ReferenceError(const char* type, Handle<String> name);
20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Access the target code for the given IC address.
20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static inline Code* GetTargetAtAddress(Address address);
20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static inline void SetTargetAtAddress(Address address, Code* target);
206f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  static void PostPatching(Address address, Code* target, Code* old_target);
20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  // Compute the handler either by compiling or by retrieving a cached version.
2092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  Handle<Code> ComputeHandler(LookupResult* lookup,
210b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                              Handle<Object> object,
2112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                              Handle<String> name,
2122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                              Handle<Object> value = Handle<Code>::null());
2132efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> CompileHandler(LookupResult* lookup,
214b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> object,
2152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                      Handle<String> name,
216b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> value,
217b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      InlineCacheHolderFlag cache_holder) {
2182efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    UNREACHABLE();
2192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    return Handle<Code>::null();
2202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
221af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
222af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void UpdateMonomorphicIC(Handle<Type> type,
223fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                           Handle<Code> handler,
224fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                           Handle<String> name);
225fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
226af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  bool UpdatePolymorphicIC(Handle<Type> type,
2274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org                           Handle<String> name,
228fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                           Handle<Code> code);
229bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
230af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code);
231af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
2326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org  void CopyICToMegamorphicCache(Handle<String> name);
233af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  bool IsTransitionOfMonomorphicTarget(Type* type);
234af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void PatchCache(Handle<Type> type,
235d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                  Handle<String> name,
236d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                  Handle<Code> code);
2372efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Code::Kind kind() const {
2382efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    UNREACHABLE();
2392efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    return Code::STUB;
2402efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
2412efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> slow_stub() const {
2422efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    UNREACHABLE();
2432efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org    return Handle<Code>::null();
2442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
245d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  virtual Handle<Code> megamorphic_stub() {
246d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org    UNREACHABLE();
247d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org    return Handle<Code>::null();
248d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  }
249068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  virtual Handle<Code> generic_stub() const {
250068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    UNREACHABLE();
251068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    return Handle<Code>::null();
252068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
253cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
254d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
255d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                                              Handle<String> name);
2562efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name);
257d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org
258cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  virtual ExtraICState extra_ic_state() { return kNoExtraICState; }
259cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
261b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Code* raw_target() const { return GetTargetAtAddress(address()); }
262b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org
26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Frame pointer for the frame that uses (calls) the IC.
26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address fp_;
26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // All access to the program counter of an IC structure is indirect
26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // to make the code GC safe. This feature is crucial since
26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // GetProperty and SetProperty are called and they in turn might
26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // invoke the garbage collector.
27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address* pc_address_;
27131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager
272ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
273ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
274fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  // The original code target that missed.
275fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  Handle<Code> target_;
276fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  State state_;
277c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  bool target_set_;
278fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
27931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// An IC_Utility encapsulates IC::UtilityId. It exists mainly because you
28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// cannot make forward declarations to an enum.
28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass IC_Utility {
28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  explicit IC_Utility(IC::UtilityId id)
28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    : address_(IC::AddressFromUtilityId(id)), id_(id) {}
28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address address() const { return address_; }
29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IC::UtilityId id() const { return id_; }
29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Address address_;
29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  IC::UtilityId id_;
29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgclass CallICBase: public IC {
30040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org public:
301cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // ExtraICState bits
302cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  class Contextual: public BitField<ContextualMode, 0, 1> {};
30340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  class StringStubState: public BitField<StringStubFeedback, 1, 1> {};
304cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static ExtraICState ComputeExtraICState(ContextualMode mode,
305cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                          StringStubFeedback feedback) {
306cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return Contextual::encode(mode) | StringStubState::encode(feedback);
307cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
30840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
309394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Returns a JSFunction or a Failure.
310fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
311303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            Handle<String> name);
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3131af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org protected:
314394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  CallICBase(Code::Kind kind, Isolate* isolate)
315394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {}
31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
317394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Compute a monomorphic stub if possible, otherwise return a null handle.
318394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> ComputeMonomorphicStub(LookupResult* lookup,
319394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                      Handle<Object> object,
320394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                      Handle<String> name);
3210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com
322394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Update the inline cache and the global stub cache based on the lookup
323394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // result.
32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void UpdateCaches(LookupResult* lookup,
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Handle<Object> object,
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                    Handle<String> name);
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
328394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Returns a JSFunction if the object can be called as a function, and
329394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // patches the stack to be ready for the call.  Otherwise, it returns the
330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // undefined value.
331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Object> TryCallAsFunction(Handle<Object> object);
3329258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org
3333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object);
334b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void Clear(Address address, Code* target);
33640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Platform-specific code generation functions used by both call and
338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // keyed call.
339394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateMiss(MacroAssembler* masm,
340394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                           int argc,
341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                           IC::UtilityId id,
342cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                           ExtraICState extra_state);
343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateNormal(MacroAssembler* masm, int argc);
345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            int argc,
348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                            Code::Kind kind,
349cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                            ExtraICState extra_state);
350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
351d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  virtual Handle<Code> megamorphic_stub();
352d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  virtual Handle<Code> pre_monomorphic_stub();
353d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
354394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Code::Kind kind_;
355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class IC;
35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3601af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgclass CallIC: public CallICBase {
3611af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org public:
362fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  explicit CallIC(Isolate* isolate)
363fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      : CallICBase(Code::CALL_IC, isolate),
364fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org        extra_ic_state_(target()->extra_ic_state()) {
365ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ASSERT(target()->is_call_stub());
366ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
3671af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
3681af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Code generator routines.
36940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  static void GenerateInitialize(MacroAssembler* masm,
37040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                 int argc,
371cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                 ExtraICState extra_state) {
372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    GenerateMiss(masm, argc, extra_state);
37340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
37540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  static void GenerateMiss(MacroAssembler* masm,
37640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                           int argc,
377cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                           ExtraICState extra_state) {
378394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state);
379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
38140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  static void GenerateMegamorphic(MacroAssembler* masm,
38240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                                  int argc,
383cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                  ExtraICState extra_ic_state);
384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateNormal(MacroAssembler* masm, int argc) {
386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallICBase::GenerateNormal(masm, argc);
387cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    GenerateMiss(masm, argc, kNoExtraICState);
388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
389fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object);
390fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
391fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org protected:
392cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  virtual ExtraICState extra_ic_state() { return extra_ic_state_; }
393fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
394fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org private:
395cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  ExtraICState extra_ic_state_;
3961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org};
3971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
3981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
3991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgclass KeyedCallIC: public CallICBase {
4001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org public:
401ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit KeyedCallIC(Isolate* isolate)
402ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : CallICBase(Code::KEYED_CALL_IC, isolate) {
4031af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    ASSERT(target()->is_keyed_call_stub());
4041af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
4051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
406fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object,
407303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                            Handle<Object> key);
4081af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
4091af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  // Code generator routines.
4101af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  static void GenerateInitialize(MacroAssembler* masm, int argc) {
4111af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org    GenerateMiss(masm, argc);
4121af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  }
413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
414394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateMiss(MacroAssembler* masm, int argc) {
415394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss,
416cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                             kNoExtraICState);
417394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4191af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  static void GenerateMegamorphic(MacroAssembler* masm, int argc);
4201af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org  static void GenerateNormal(MacroAssembler* masm, int argc);
4217b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static void GenerateNonStrictArguments(MacroAssembler* masm, int argc);
4221af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org};
4231af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
4241af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass LoadIC: public IC {
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
427e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
428b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    ASSERT(IsLoadStub());
429ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generator routines.
4325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
4335c838251403b0be9a882540f1922577abba4c872ager@chromium.org  static void GeneratePreMonomorphic(MacroAssembler* masm) {
4345c838251403b0be9a882540f1922577abba4c872ager@chromium.org    GenerateMiss(masm);
4355c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void GenerateMiss(MacroAssembler* masm);
43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void GenerateMegamorphic(MacroAssembler* masm);
43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void GenerateNormal(MacroAssembler* masm);
439d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
441fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
442003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                                    Handle<String> name);
443003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
4446bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org protected:
4456bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Code::Kind kind() const { return Code::LOAD_IC; }
4466bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org
4474a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  virtual Handle<Code> slow_stub() const {
448d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return isolate()->builtins()->LoadIC_Slow();
449003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
450003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
4516bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> megamorphic_stub() {
4526bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    return isolate()->builtins()->LoadIC_Megamorphic();
4536bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  }
4546bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org
45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update the inline cache and the global stub cache based on the
45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // lookup result.
457003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void UpdateCaches(LookupResult* lookup,
458003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                    Handle<Object> object,
459003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org                    Handle<String> name);
460bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
4612efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> CompileHandler(LookupResult* lookup,
462b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> object,
4632efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                      Handle<String> name,
464b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> unused,
465b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      InlineCacheHolderFlag cache_holder);
46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4676bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org private:
46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Stub accessors.
4693d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static Handle<Code> initialize_stub(Isolate* isolate) {
4703d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    return isolate->builtins()->LoadIC_Initialize();
47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
472fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
4738e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
4748e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return isolate->builtins()->LoadIC_PreMonomorphic();
4758e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
476fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
4776bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> pre_monomorphic_stub() {
4788e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return pre_monomorphic_stub(isolate());
47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4812efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  Handle<Code> SimpleFieldLoad(int offset,
4822efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                               bool inobject = true,
4832efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                               Representation representation =
4842efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                    Representation::Tagged());
4852efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org
4863d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address, Code* target);
4875ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class IC;
48943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
492003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgclass KeyedLoadIC: public LoadIC {
493ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org public:
494e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate)
495e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org      : LoadIC(depth, isolate) {
496ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    ASSERT(target()->is_keyed_load_stub());
497ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
499fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* Load(Handle<Object> object,
500b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                    Handle<Object> key);
50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generator routines.
503af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static void GenerateMiss(MacroAssembler* masm);
5045c838251403b0be9a882540f1922577abba4c872ager@chromium.org  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
505af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
5065c838251403b0be9a882540f1922577abba4c872ager@chromium.org  static void GeneratePreMonomorphic(MacroAssembler* masm) {
507af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    GenerateMiss(masm);
5085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
50943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void GenerateGeneric(MacroAssembler* masm);
5100c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  static void GenerateString(MacroAssembler* masm);
5115c838251403b0be9a882540f1922577abba4c872ager@chromium.org  static void GenerateIndexedInterceptor(MacroAssembler* masm);
5127b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static void GenerateNonStrictArguments(MacroAssembler* masm);
5133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
514eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // Bit mask to be tested against bit field for the cases when
515eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // generic stub should go into slow case.
516eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // Access check is necessary explicitly since generic stub does not perform
517eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // map checks.
518eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  static const int kSlowCaseBitFieldMask =
519eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org      (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
520eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org
521ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org protected:
522ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
523ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
524003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> LoadElementStub(Handle<JSObject> receiver);
525003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
5266bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> megamorphic_stub() {
5276bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    return isolate()->builtins()->KeyedLoadIC_Generic();
5286bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  }
5296bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> generic_stub() const {
5306bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org    return isolate()->builtins()->KeyedLoadIC_Generic();
5316bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  }
5324a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  virtual Handle<Code> slow_stub() const {
5334a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    return isolate()->builtins()->KeyedLoadIC_Slow();
5344a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
5356bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org
536af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5386bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org private:
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Stub accessors.
5403d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static Handle<Code> initialize_stub(Isolate* isolate) {
5413d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    return isolate->builtins()->KeyedLoadIC_Initialize();
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
5438e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static Handle<Code> pre_monomorphic_stub(Isolate* isolate) {
5448e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
5458e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
5466bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> pre_monomorphic_stub() {
5478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return pre_monomorphic_stub(isolate());
54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
549394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> indexed_interceptor_stub() {
550394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor();
5515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
552394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> non_strict_arguments_stub() {
553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return isolate()->builtins()->KeyedLoadIC_NonStrictArguments();
5547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
555003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> string_stub() {
556003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org    return isolate()->builtins()->KeyedLoadIC_String();
557003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  }
5585c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5593d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address, Code* target);
56037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class IC;
56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass StoreIC: public IC {
56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
567cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // ExtraICState bits
568cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  class StrictModeState: public BitField<StrictModeFlag, 0, 1> {};
569cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static ExtraICState ComputeExtraICState(StrictModeFlag flag) {
570cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return StrictModeState::encode(flag);
571cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
572cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
573cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static StrictModeFlag GetStrictMode(ExtraICState state) {
574cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return StrictModeState::decode(state);
575cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
576cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
577cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // For convenience, a statically declared encoding of strict mode extra
578cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // IC state.
579cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static const ExtraICState kStrictModeState =
580cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      1 << StrictModeState::kShift;
581cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
582fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  StoreIC(FrameDepth depth, Isolate* isolate)
583fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      : IC(depth, isolate),
584cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org        strict_mode_(GetStrictMode(target()->extra_ic_state())) {
585b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    ASSERT(IsStoreStub());
586ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
588cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  StrictModeFlag strict_mode() const { return strict_mode_; }
589fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generators for stub routines. Only called once at startup.
59157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  static void GenerateSlow(MacroAssembler* masm);
592b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
5933d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void GeneratePreMonomorphic(MacroAssembler* masm) {
5943d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org    GenerateMiss(masm);
5953d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  static void GenerateMiss(MacroAssembler* masm);
597496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  static void GenerateMegamorphic(MacroAssembler* masm,
598ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                                  ExtraICState extra_ic_state);
59969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  static void GenerateNormal(MacroAssembler* masm);
600b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  static void GenerateRuntimeSetProperty(MacroAssembler* masm,
601b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                         StrictModeFlag strict_mode);
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
603003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  MUST_USE_RESULT MaybeObject* Store(
604003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      Handle<Object> object,
605003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      Handle<String> name,
606003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      Handle<Object> value,
607003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org      JSReceiver::StoreFromKeyed store_mode =
608003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org          JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
609003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
6106bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org protected:
6116bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Code::Kind kind() const { return Code::STORE_IC; }
6126bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> megamorphic_stub() {
613fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode() == kStrictMode) {
614fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->StoreIC_Megamorphic_Strict();
615fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
616fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->StoreIC_Megamorphic();
617fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
6186bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  }
6196bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  // Stub accessors.
620b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  virtual Handle<Code> generic_stub() const {
621fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode() == kStrictMode) {
622fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->StoreIC_Generic_Strict();
623fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
624fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->StoreIC_Generic();
625fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
626b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
627fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
6282efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> slow_stub() const {
629c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    return isolate()->builtins()->StoreIC_Slow();
6302efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
6312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org
6328e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  virtual Handle<Code> pre_monomorphic_stub() {
633fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    return pre_monomorphic_stub(isolate(), strict_mode());
6348e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
635fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
636fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
637fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                           StrictModeFlag strict_mode) {
638fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode == kStrictMode) {
639fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->StoreIC_PreMonomorphic_Strict();
640fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
641fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->StoreIC_PreMonomorphic();
642fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
6433d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
644fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update the inline cache and the global stub cache based on the
64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // lookup result.
647d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  void UpdateCaches(LookupResult* lookup,
648d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                    Handle<JSObject> receiver,
649d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                    Handle<String> name,
650d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                    Handle<Object> value);
6512efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> CompileHandler(LookupResult* lookup,
652b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> object,
6532efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org                                      Handle<String> name,
654b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      Handle<Object> value,
655b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                      InlineCacheHolderFlag cache_holder);
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
657cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  virtual ExtraICState extra_ic_state() {
658cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return ComputeExtraICState(strict_mode());
659cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
660cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
6616bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org private:
6629ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void set_target(Code* code) {
6639ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Strict mode must be preserved across IC patching.
664cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ASSERT(GetStrictMode(code->extra_ic_state()) ==
665cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org           GetStrictMode(target()->extra_ic_state()));
6669ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    IC::set_target(code);
6679ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
6689ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
669fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  static Handle<Code> initialize_stub(Isolate* isolate,
670fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                      StrictModeFlag strict_mode) {
671fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode == kStrictMode) {
672fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->StoreIC_Initialize_Strict();
673fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
674fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->StoreIC_Initialize();
675fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
676496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  }
677fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
6783d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address, Code* target);
679ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org
680fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  StrictModeFlag strict_mode_;
681fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
68243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class IC;
68343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
68443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
68633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgenum KeyedStoreCheckMap {
68733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  kDontCheckMap,
68833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  kCheckMap
68933e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org};
69033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
69133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
69233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.orgenum KeyedStoreIncrementLength {
69333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  kDontIncrementLength,
69433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  kIncrementLength
69533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org};
69633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
69733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
698003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgclass KeyedStoreIC: public StoreIC {
69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
700cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // ExtraICState bits (building on IC)
701cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  // ExtraICState bits
702cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  class ExtraICStateKeyedAccessStoreMode:
703cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      public BitField<KeyedAccessStoreMode, 1, 4> {};  // NOLINT
704cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
705cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static ExtraICState ComputeExtraICState(StrictModeFlag flag,
706cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org                                                KeyedAccessStoreMode mode) {
707cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return StrictModeState::encode(flag) |
708cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org        ExtraICStateKeyedAccessStoreMode::encode(mode);
709cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
710cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
711cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  static KeyedAccessStoreMode GetKeyedAccessStoreMode(
712cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org      ExtraICState extra_state) {
713cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
714cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
715cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
7167bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org  KeyedStoreIC(FrameDepth depth, Isolate* isolate)
7177bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org      : StoreIC(depth, isolate) {
718ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    ASSERT(target()->is_keyed_store_stub());
719ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  }
72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
721fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* Store(Handle<Object> object,
722303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                     Handle<Object> name,
723b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org                                     Handle<Object> value);
72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Code generators for stub routines.  Only called once at startup.
726af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
7273d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void GeneratePreMonomorphic(MacroAssembler* masm) {
728af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    GenerateMiss(masm);
7293d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
730af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static void GenerateMiss(MacroAssembler* masm);
731ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  static void GenerateSlow(MacroAssembler* masm);
7329ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  static void GenerateRuntimeSetProperty(MacroAssembler* masm,
7339ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                                         StrictModeFlag strict_mode);
7349ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
7357b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  static void GenerateNonStrictArguments(MacroAssembler* masm);
73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
737ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org protected:
738ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
739ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
740af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  virtual void UpdateMegamorphicCache(Type* type, Name* name, Code* code) { }
7416bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org
742cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  virtual ExtraICState extra_ic_state() {
743cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    return ComputeExtraICState(strict_mode(), STANDARD_STORE);
744cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  }
745cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org
7468e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  virtual Handle<Code> pre_monomorphic_stub() {
747fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    return pre_monomorphic_stub(isolate(), strict_mode());
7483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
749fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
750fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                           StrictModeFlag strict_mode) {
751fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode == kStrictMode) {
752fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
753fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
754fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
755fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
7563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  }
7572efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  virtual Handle<Code> slow_stub() const {
758c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org    return isolate()->builtins()->KeyedStoreIC_Slow();
7592efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org  }
7606bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  virtual Handle<Code> megamorphic_stub() {
761fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode() == kStrictMode) {
762fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
763fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
764fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->KeyedStoreIC_Generic();
765fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
7666bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org  }
76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
768003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Code> StoreElementStub(Handle<JSObject> receiver,
769fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                KeyedAccessStoreMode store_mode);
770bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
7716bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org private:
7729ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void set_target(Code* code) {
7739ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    // Strict mode must be preserved across IC patching.
774cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org    ASSERT(GetStrictMode(code->extra_ic_state()) == strict_mode());
7759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    IC::set_target(code);
7769ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
7779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
77843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Stub accessors.
779fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  static Handle<Code> initialize_stub(Isolate* isolate,
780fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                                      StrictModeFlag strict_mode) {
781fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode == kStrictMode) {
782fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->KeyedStoreIC_Initialize_Strict();
783fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
784fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate->builtins()->KeyedStoreIC_Initialize();
785fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
7869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
787fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
788fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  virtual Handle<Code> generic_stub() const {
789fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    if (strict_mode() == kStrictMode) {
790fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
791fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    } else {
792fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org      return isolate()->builtins()->KeyedStoreIC_Generic();
793fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    }
794394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
795fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
796394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Handle<Code> non_strict_arguments_stub() {
797394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
7987b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org  }
79943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8003d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address, Code* target);
801eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
802750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
803750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                    Handle<Object> key,
804750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                    Handle<Object> value);
805003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
806003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
807750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                     KeyedAccessStoreMode store_mode);
808003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
80943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  friend class IC;
81043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
81243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
813ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org// Mode to overwrite BinaryExpression values.
814ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgenum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
815ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
816a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Type Recording BinaryOpIC, that records the types of the inputs and outputs.
81740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgclass BinaryOpIC: public IC {
818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
819ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org  class State V8_FINAL BASE_EMBEDDED {
820ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org   public:
821ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    explicit State(ExtraICState extra_ic_state);
822ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
823ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    State(Token::Value op, OverwriteMode mode)
824ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE),
825ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org          result_kind_(NONE) {
826ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      ASSERT_LE(FIRST_TOKEN, op);
827ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      ASSERT_LE(op, LAST_TOKEN);
828ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
829ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
830ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    InlineCacheState GetICState() const {
831ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      if (Max(left_kind_, right_kind_) == NONE) {
832ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        return ::v8::internal::UNINITIALIZED;
833ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      }
834ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      if (Max(left_kind_, right_kind_) == GENERIC) {
835ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        return ::v8::internal::MEGAMORPHIC;
836ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      }
837ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      if (Min(left_kind_, right_kind_) == GENERIC) {
838ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        return ::v8::internal::GENERIC;
839ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      }
840ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return ::v8::internal::MONOMORPHIC;
841ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
842ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
843ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    ExtraICState GetExtraICState() const;
844ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
845ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static void GenerateAheadOfTime(
846ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org        Isolate*, void (*Generate)(Isolate*, const State&));
847ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
848ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    bool CanReuseDoubleBox() const {
849ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
850ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org          ((mode_ == OVERWRITE_LEFT &&
851ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org            left_kind_ > SMI && left_kind_ <= NUMBER) ||
852ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org           (mode_ == OVERWRITE_RIGHT &&
853ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org            right_kind_ > SMI && right_kind_ <= NUMBER));
854ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
855ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
856ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    bool HasSideEffects() const {
857ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return Max(left_kind_, right_kind_) == GENERIC;
858ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
859ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
860ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    bool UseInlinedSmiCode() const {
861ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return KindMaybeSmi(left_kind_) || KindMaybeSmi(right_kind_);
862ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
863ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
864ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static const int FIRST_TOKEN = Token::BIT_OR;
865ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static const int LAST_TOKEN = Token::MOD;
866ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
867ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Token::Value op() const { return op_; }
868ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    OverwriteMode mode() const { return mode_; }
869ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
870ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
871ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Handle<Type> GetLeftType(Isolate* isolate) const {
872ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return KindToType(left_kind_, isolate);
873ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
874ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Handle<Type> GetRightType(Isolate* isolate) const {
875ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return KindToType(right_kind_, isolate);
876ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
877ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Handle<Type> GetResultType(Isolate* isolate) const;
878ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
879ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    void Print(StringStream* stream) const;
880ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
881ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    void Update(Handle<Object> left,
882ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                Handle<Object> right,
883ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org                Handle<Object> result);
884ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
885ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org   private:
886ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
887ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
888ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Kind UpdateKind(Handle<Object> object, Kind kind) const;
889ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
890ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static const char* KindToString(Kind kind);
891ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static Handle<Type> KindToType(Kind kind, Isolate* isolate);
892ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    static bool KindMaybeSmi(Kind kind) {
893ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org      return (kind >= SMI && kind <= NUMBER) || kind == GENERIC;
894ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    }
895ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
896ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    // We truncate the last bit of the token.
897ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
898ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class OpField:                 public BitField<int, 0, 4> {};
899ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class OverwriteModeField:      public BitField<OverwriteMode, 4, 2> {};
900ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class SSE2Field:               public BitField<bool, 6, 1> {};
901ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class ResultKindField:         public BitField<Kind, 7, 3> {};
902ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class LeftKindField:           public BitField<Kind, 10,  3> {};
903ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    // When fixed right arg is set, we don't need to store the right kind.
904ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    // Thus the two fields can overlap.
905ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class HasFixedRightArgField:   public BitField<bool, 13, 1> {};
906ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class FixedRightArgValueField: public BitField<int,  14, 4> {};
907ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    class RightKindField:          public BitField<Kind, 14, 3> {};
908ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org
909ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Token::Value op_;
910ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    OverwriteMode mode_;
911ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Kind left_kind_;
912ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Kind right_kind_;
913ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Kind result_kind_;
914ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org    Maybe<int> fixed_right_arg_;
915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
91725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
91925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  static Builtins::JavaScript TokenToJSBuiltin(Token::Value op);
920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
92125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left,
92225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org                                          Handle<Object> right);
923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
926a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CompareIC: public IC {
927a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
9288432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  // The type/state lattice is defined by the following inequations:
9298432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  //   UNINITIALIZED < ...
9308432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  //   ... < GENERIC
9318432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  //   SMI < NUMBER
9324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  //   INTERNALIZED_STRING < STRING
9338432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  //   KNOWN_OBJECT < OBJECT
934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  enum State {
935a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    UNINITIALIZED,
936fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    SMI,
9378432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    NUMBER,
938fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    STRING,
9394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    INTERNALIZED_STRING,
9404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    UNIQUE_NAME,    // Symbol or InternalizedString
9418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    OBJECT,         // JSObject
9428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org    KNOWN_OBJECT,   // JSObject with specific map (faster check)
943a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    GENERIC
944a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
945a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
946b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  static State NewInputState(State old_state, Handle<Object> value);
947b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
948b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  static Handle<Type> StateToType(Isolate* isolate,
949b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                  State state,
950b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                  Handle<Map> map = Handle<Map>());
951b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
952b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  static void StubInfoToType(int stub_minor_key,
953b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                             Handle<Type>* left_type,
954b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                             Handle<Type>* right_type,
955b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                             Handle<Type>* overall_type,
956b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                             Handle<Map> map,
957b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                             Isolate* isolate);
95841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CompareIC(Isolate* isolate, Token::Value op)
960ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      : IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
961a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Update the inline cache for the given operands.
963b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Code* UpdateCaches(Handle<Object> x, Handle<Object> y);
964a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
965fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
966a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Factory method for getting an uninitialized compare stub.
9678432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op);
968a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
969a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Helper function for computing the condition for a compare operation.
970a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static Condition ComputeCondition(Token::Value op);
971a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
972a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const char* GetStateName(State state);
973a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
974a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
975fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  static bool HasInlinedSmiCode(Address address);
976fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
977fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  State TargetState(State old_state,
978fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    State old_left,
979fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    State old_right,
980fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    bool has_inlined_smi_code,
981fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    Handle<Object> x,
982fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                    Handle<Object> y);
983a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
984a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool strict() const { return op_ == Token::EQ_STRICT; }
985a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Condition GetCondition() const { return ComputeCondition(op_); }
986a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9873d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static Code* GetRawUninitialized(Isolate* isolate, Token::Value op);
988212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
9893d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static void Clear(Isolate* isolate, Address address, Code* target);
990212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
991a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Token::Value op_;
992212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org
993212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org  friend class IC;
994a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
995a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
9969fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org
997ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgclass CompareNilIC: public IC {
998ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org public:
999ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
1000ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1001ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  MUST_USE_RESULT MaybeObject* CompareNil(Handle<Object> object);
1002ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1003ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  static Handle<Code> GetUninitialized();
1004ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1005ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  static void Clear(Address address, Code* target);
1006ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1007837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  static MUST_USE_RESULT MaybeObject* DoCompareNilSlow(NilValue nil,
1008ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org                                                       Handle<Object> object);
1009ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org};
1010ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
1011ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
10129fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.orgclass ToBooleanIC: public IC {
10139fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org public:
1014b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { }
10159fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org
1016b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  MaybeObject* ToBoolean(Handle<Object> object);
10179fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org};
10189fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org
10199fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org
102040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org// Helper for BinaryOpIC and CompareIC.
1021212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgenum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
1022212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.orgvoid PatchInlinedSmiCode(Address address, InlinedSmiCheck check);
1023a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1024e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure);
10257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure);
1026e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss);
1027e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure);
1028ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure);
1029ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss);
103025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss);
1031ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss);
1032b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgDECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss);
1033ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
103459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // V8_IC_H_
1038