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