13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IC_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IC_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "macro-assembler.h" 32257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "type-info.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IC_UTIL_LIST defines all utility functions called from generated 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// inline caching code. The argument for the macro, ICU, is the function name. 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define IC_UTIL_LIST(ICU) \ 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(LoadIC_Miss) \ 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(KeyedLoadIC_Miss) \ 43257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ICU(KeyedLoadIC_MissForceGeneric) \ 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(CallIC_Miss) \ 457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ICU(KeyedCallIC_Miss) \ 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(StoreIC_Miss) \ 476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ICU(StoreIC_ArrayLength) \ 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(SharedStoreIC_ExtendStorage) \ 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(KeyedStoreIC_Miss) \ 50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ICU(KeyedStoreIC_MissForceGeneric) \ 51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ICU(KeyedStoreIC_Slow) \ 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* Utilities for IC stubs. */ \ 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(LoadCallbackProperty) \ 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(StoreCallbackProperty) \ 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(LoadPropertyWithInterceptorOnly) \ 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(LoadPropertyWithInterceptorForLoad) \ 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ICU(LoadPropertyWithInterceptorForCall) \ 58402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu ICU(KeyedLoadPropertyWithInterceptor) \ 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ICU(StoreInterceptorProperty) \ 60257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ICU(UnaryOp_Patch) \ 61257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ICU(BinaryOp_Patch) \ 6269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ICU(CompareIC_Miss) \ 6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch ICU(ToBoolean_Patch) 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// IC is the base class for LoadIC, StoreIC, CallIC, KeyedLoadIC, 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// and KeyedStoreIC. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IC { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The ids for utility called from the generated code. 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum UtilityId { 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block #define CONST_NAME(name) k##name, 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC_UTIL_LIST(CONST_NAME) 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block #undef CONST_NAME 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kUtilityCount 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Looks up the address of the named utility. 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Address AddressFromUtilityId(UtilityId id); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Alias the inline cache state type to make the IC code more readable. 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef InlineCacheState State; 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The IC code is either invoked with no extra frames on the stack 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // or with a single extra frame for supporting calls. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum FrameDepth { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NO_EXTRA_FRAME = 0, 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EXTRA_CALL_FRAME = 1 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Construct the IC structure with the given number of extra 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // JavaScript frames on the stack. 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block IC(FrameDepth depth, Isolate* isolate); 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual ~IC() {} 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the call-site target; used for determining the state. 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* target() const { return GetTargetAtAddress(address()); } 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Address address() const; 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsGeneric() const { return false; } 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Compute the current IC state based on the target stub, receiver and name. 1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static State StateFrom(Code* target, Object* receiver, Object* name); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the inline cache to initial state. 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the reloc info for this IC. This is a fairly expensive 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // operation as it has to search through the heap to find the code 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object that contains this IC site. 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode ComputeMode(); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns if this IC is for contextual (no explicit receiver) 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // access to properties. 115e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool IsContextual(Handle<Object> receiver) { 116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (receiver->IsGlobalObject()) { 117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return SlowIsContextual(); 118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 119e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(!SlowIsContextual()); 120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return false; 121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 124e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool SlowIsContextual() { 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1288defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Determines which map must be used for keeping the code stub. 1298defd9ff6930b4e24729971a61cf7469daf119beSteve Block // These methods should not be called with undefined or null. 1308defd9ff6930b4e24729971a61cf7469daf119beSteve Block static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, 1318defd9ff6930b4e24729971a61cf7469daf119beSteve Block JSObject* holder); 1328defd9ff6930b4e24729971a61cf7469daf119beSteve Block static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, 1338defd9ff6930b4e24729971a61cf7469daf119beSteve Block JSObject* holder); 13480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static inline JSObject* GetCodeCacheHolder(Object* object, 13580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InlineCacheHolderFlag holder); 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return fp_; } 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address_; } 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate() const { return isolate_; } 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address in the original code when the code running is 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // containing break points (calls to DebugBreakXXX builtins). 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address OriginalCodeAddress() const; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the call-site target. 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_target(Code* code) { SetTargetAtAddress(address(), code); } 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char TransitionMarkFromState(IC::State state); 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void TraceIC(const char* type, 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> name, 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch State old_state, 157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code* new_target); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 16044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Failure* TypeError(const char* type, 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> object, 16244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> key); 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Failure* ReferenceError(const char* type, Handle<String> name); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the target code for the given IC address. 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Code* GetTargetAtAddress(Address address); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline void SetTargetAtAddress(Address address, Code* target); 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PostPatching(Address address, Code* target, Code* old_target); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Frame pointer for the frame that uses (calls) the IC. 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All access to the program counter of an IC structure is indirect 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to make the code GC safe. This feature is crucial since 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetProperty and SetProperty are called and they in turn might 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // invoke the garbage collector. 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address_; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(IC); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An IC_Utility encapsulates IC::UtilityId. It exists mainly because you 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// cannot make forward declarations to an enum. 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IC_Utility { 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit IC_Utility(IC::UtilityId id) 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : address_(IC::AddressFromUtilityId(id)), id_(id) {} 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address() const { return address_; } 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC::UtilityId id() const { return id_; } 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address_; 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC::UtilityId id_; 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass CallICBase: public IC { 203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class Contextual: public BitField<bool, 0, 1> {}; 205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; 206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns a JSFunction or a Failure. 2085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* LoadFunction(State state, 209b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState extra_ic_state, 2105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 2115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch protected: 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallICBase(Code::Kind kind, Isolate* isolate) 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool TryUpdateExtraICState(LookupResult* lookup, 218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Object> object, 219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState* extra_ic_state); 220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Compute a monomorphic stub if possible, otherwise return a null handle. 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ComputeMonomorphicStub(LookupResult* lookup, 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch State state, 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object, 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name); 227b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Update the inline cache and the global stub cache based on the lookup 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // result. 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 232b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState extra_ic_state, 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Returns a JSFunction if the object can be called as a function, and 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // patches the stack to be ready for the call. Otherwise, it returns the 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // undefined value. 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> TryCallAsFunction(Handle<Object> object); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 241e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); 242e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Platform-specific code generation functions used by both call and 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // keyed call. 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateMiss(MacroAssembler* masm, 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int argc, 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::UtilityId id, 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state); 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateNormal(MacroAssembler* masm, int argc); 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int argc, 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Kind kind, 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state); 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Kind kind_; 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass CallIC: public CallICBase { 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { 26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_call_stub()); 26944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Code generator routines. 272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm, 273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenerateMiss(masm, argc, extra_state); 276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, 279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallICBase::GenerateMiss(masm, argc, IC::kCallIC_Miss, extra_state); 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMegamorphic(MacroAssembler* masm, 285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_ic_state); 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateNormal(MacroAssembler* masm, int argc) { 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallICBase::GenerateNormal(masm, argc); 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GenerateMiss(masm, argc, Code::kNoExtraICState); 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 2937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass KeyedCallIC: public CallICBase { 2967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit KeyedCallIC(Isolate* isolate) 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block : CallICBase(Code::KEYED_CALL_IC, isolate) { 2997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(target()->is_keyed_call_stub()); 3007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 3017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* LoadFunction(State state, 3035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 3045913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> key); 3057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Code generator routines. 3077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateInitialize(MacroAssembler* masm, int argc) { 3087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch GenerateMiss(masm, argc); 3097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateMiss(MacroAssembler* masm, int argc) { 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallICBase::GenerateMiss(masm, argc, IC::kKeyedCallIC_Miss, 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::kNoExtraICState); 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateMegamorphic(MacroAssembler* masm, int argc); 3177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateNormal(MacroAssembler* masm, int argc); 3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); 3197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 3207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 3217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LoadIC: public IC { 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_load_stub()); 32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Load(State state, 3295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 3305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generator routines. 333402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 334402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GeneratePreMonomorphic(MacroAssembler* masm) { 335402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu GenerateMiss(masm); 336402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMiss(MacroAssembler* masm); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMegamorphic(MacroAssembler* masm); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateNormal(MacroAssembler* masm); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Specialized code generator routines. 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateArrayLength(MacroAssembler* masm); 3431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void GenerateStringLength(MacroAssembler* masm, 3441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool support_wrappers); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateFunctionPrototype(MacroAssembler* masm); 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache and the global stub cache based on the 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lookup result. 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> megamorphic_stub() { 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->LoadIC_Megamorphic(); 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_Initialize); 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> pre_monomorphic_stub() { 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->LoadIC_PreMonomorphic(); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch friend class IC; 370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 371053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 372053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedIC: public IC { 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum StubKind { 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LOAD, 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_NO_TRANSITION, 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_SMI_TO_OBJECT, 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_SMI_TO_DOUBLE, 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_DOUBLE_TO_OBJECT, 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_NO_TRANSITION, 3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, 3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, 3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT 3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION - 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_NO_TRANSITION; 3893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kGrowICDelta == 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT - 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_SMI_TO_OBJECT); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kGrowICDelta == 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE - 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_SMI_TO_DOUBLE); 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(kGrowICDelta == 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT - 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_TRANSITION_DOUBLE_TO_OBJECT); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} 400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~KeyedIC() {} 401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline KeyedAccessGrowMode GetGrowModeFromStubKind( 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubKind stub_kind) { 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (stub_kind >= STORE_AND_GROW_NO_TRANSITION) 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? ALLOW_JSARRAY_GROWTH 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : DO_NOT_ALLOW_JSARRAY_GROWTH; 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static inline StubKind GetGrowStubKind(StubKind stub_kind) { 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(stub_kind != LOAD); 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (stub_kind < STORE_AND_GROW_NO_TRANSITION) { 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) + 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kGrowICDelta); 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return stub_kind; 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> GetElementStubWithoutMapCheck( 4193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind, 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode) = 0; 422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> string_stub() { 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<Code>::null(); 426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const = 0; 429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ComputeStub(Handle<JSObject> receiver, 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubKind stub_kind, 432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode, 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> default_stub); 434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> ComputePolymorphicStub( 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MapHandleList* receiver_maps, 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode, 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode) = 0; 439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ComputeMonomorphicStubWithoutMapCheck( 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> receiver_map, 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode, 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode); 444592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result); 4475d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver, 4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubKind stub_kind, 45085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch StrictModeFlag strict_mode, 4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> default_stub); 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubKind stub_kind); 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool IsTransitionStubKind(StubKind stub_kind) { 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return stub_kind > STORE_NO_TRANSITION && 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub_kind != STORE_AND_GROW_NO_TRANSITION; 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static bool IsGrowStubKind(StubKind stub_kind) { 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return stub_kind >= STORE_AND_GROW_NO_TRANSITION; 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedLoadIC: public KeyedIC { 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { 47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_keyed_load_stub()); 47144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Load(State state, 4745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> key, 476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool force_generic_stub); 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generator routines. 479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, bool force_generic); 480402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateRuntimeGetProperty(MacroAssembler* masm); 481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm) { 482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 484402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GeneratePreMonomorphic(MacroAssembler* masm) { 485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 486402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateGeneric(MacroAssembler* masm); 488e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static void GenerateString(MacroAssembler* masm); 489402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateIndexedInterceptor(MacroAssembler* masm); 4903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm); 4913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Bit mask to be tested against bit field for the cases when 493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // generic stub should go into slow case. 494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Access check is necessary explicitly since generic stub does not perform 495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // map checks. 496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static const int kSlowCaseBitFieldMask = 497d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); 498d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> GetElementStubWithoutMapCheck( 5003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind, 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode); 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsGeneric() const { 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return target() == *generic_stub(); 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 507c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } 510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode, 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode); 514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> string_stub() { 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_String(); 517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 5196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache. 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_Initialize); 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> megamorphic_stub() { 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_Generic(); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> generic_stub() const { 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_Generic(); 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> pre_monomorphic_stub() { 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_PreMonomorphic(); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> indexed_interceptor_stub() { 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); 542402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> non_strict_arguments_stub() { 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedLoadIC_NonStrictArguments(); 5453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 546402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StoreIC: public IC { 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_store_stub()); 55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Store(State state, 560e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 5615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 5625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name, 5635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> value); 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generators for stub routines. Only called once at startup. 5664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMiss(MacroAssembler* masm); 5681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void GenerateMegamorphic(MacroAssembler* masm, 569e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 5706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static void GenerateArrayLength(MacroAssembler* masm); 5718defd9ff6930b4e24729971a61cf7469daf119beSteve Block static void GenerateNormal(MacroAssembler* masm); 572e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateGlobalProxy(MacroAssembler* masm, 573e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache and the global stub cache based on the 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lookup result. 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block State state, 580e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Handle<JSObject> receiver, 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name, 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 585e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_target(Code* code) { 586e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Strict mode must be preserved across IC patching. 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Code::GetStrictMode(code->extra_ic_state()) == 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::GetStrictMode(target()->extra_ic_state())); 589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch IC::set_target(code); 590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 59344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub() { 59444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Megamorphic); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub_strict() { 59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Megamorphic_Strict); 6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Initialize); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static Code* initialize_stub_strict() { 60644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 60744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Initialize_Strict); 6081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> global_proxy_stub() { 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->StoreIC_GlobalProxy(); 611b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> global_proxy_stub_strict() { 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); 6141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 61750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedStoreIC: public KeyedIC { 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 624257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) { 625257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(target()->is_keyed_store_stub()); 626257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Store(State state, 629257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode, 6305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 6315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> name, 632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> value, 633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool force_generic); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generators for stub routines. Only called once at startup. 636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm) { 637257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 638257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 639257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, bool force_generic); 640257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateSlow(MacroAssembler* masm); 641e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateRuntimeSetProperty(MacroAssembler* masm, 642e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 643e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm); 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm); 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> GetElementStubWithoutMapCheck( 6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind elements_kind, 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode); 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual bool IsGeneric() const { 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return target() == *generic_stub() || 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target() == *generic_stub_strict(); 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 657c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 658257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 659257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode, 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode); 664257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 665257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache. 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 669e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> receiver, 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name, 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value); 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 674e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_target(Code* code) { 675e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Strict mode must be preserved across IC patching. 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(Code::GetStrictMode(code->extra_ic_state()) == 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::GetStrictMode(target()->extra_ic_state())); 678e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch IC::set_target(code); 679e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 680e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 68344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 68444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Initialize); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block static Code* initialize_stub_strict() { 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 68844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Initialize_Strict); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> megamorphic_stub() { 6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedStoreIC_Generic(); 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> megamorphic_stub_strict() { 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 695e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> generic_stub() const { 6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedStoreIC_Generic(); 698592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> generic_stub_strict() const { 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> non_strict_arguments_stub() { 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); 7043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubKind GetStubKind(Handle<JSObject> receiver, 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> key, 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value); 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass UnaryOpIC: public IC { 717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // sorted: increasingly more unspecific (ignoring UNINITIALIZED) 719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead. 720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum TypeInfo { 721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNINITIALIZED, 722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SMI, 723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HEAP_NUMBER, 724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GENERIC 725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 727257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 728257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 729257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void patch(Code* code); 730257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char* GetName(TypeInfo type_info); 732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static State ToState(TypeInfo type_info); 734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static TypeInfo GetTypeInfo(Handle<Object> operand); 736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous); 738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Type Recording BinaryOpIC, that records the types of the inputs and outputs. 742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BinaryOpIC: public IC { 743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum TypeInfo { 745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNINITIALIZED, 746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SMI, 747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32, 748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEAP_NUMBER, 74944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ODDBALL, 750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BOTH_STRING, // Only used for addition operation. 751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch STRING, // Only used for addition operation. At least one string operand. 752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GENERIC 753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 757b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void patch(Code* code); 758b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* GetName(TypeInfo type_info); 760b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 761b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static State ToState(TypeInfo type_info); 762b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 763b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right); 764b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 765b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static TypeInfo JoinTypes(TypeInfo x, TypeInfo y); 766b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 767b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 768b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 769b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass CompareIC: public IC { 770b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 771b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum State { 772b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNINITIALIZED, 773b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SMIS, 774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEAP_NUMBERS, 775257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SYMBOLS, 776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch STRINGS, 777b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch OBJECTS, 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KNOWN_OBJECTS, 779b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GENERIC 780b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 781b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompareIC(Isolate* isolate, Token::Value op) 78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } 784b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 785b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Update the inline cache for the given operands. 786b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void UpdateCaches(Handle<Object> x, Handle<Object> y); 787b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Factory method for getting an uninitialized compare stub. 789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Handle<Code> GetUninitialized(Token::Value op); 790b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 791b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Helper function for computing the condition for a compare operation. 792b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Condition ComputeCondition(Token::Value op); 793b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 794b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Helper function for determining the state of a compare IC. 795b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static State ComputeState(Code* target); 796b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 797b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* GetStateName(State state); 798b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 799b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 800b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch State TargetState(State state, bool has_inlined_smi_code, 801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> x, Handle<Object> y); 802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool strict() const { return op_ == Token::EQ_STRICT; } 804b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition GetCondition() const { return ComputeCondition(op_); } 805b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch State GetState() { return ComputeState(target()); } 806b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 807b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op_; 808b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 809b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 81069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 81169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ToBooleanIC: public IC { 81269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 81369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch explicit ToBooleanIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 81469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 81569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void patch(Code* code); 81669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 81769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 81869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Helper for BinaryOpIC and CompareIC. 820b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid PatchInlinedSmiCode(Address address); 821b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IC_H_ 825