ic.h revision 69a99ed0b2b2ef69d393c371b03db3a98aaf880e
1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 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); 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the call-site target; used for determining the state. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code* target() { return GetTargetAtAddress(address()); } 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Address address(); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Compute the current IC state based on the target stub, receiver and name. 1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static State StateFrom(Code* target, Object* receiver, Object* name); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the inline cache to initial state. 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the reloc info for this IC. This is a fairly expensive 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // operation as it has to search through the heap to find the code 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object that contains this IC site. 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::Mode ComputeMode(); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns if this IC is for contextual (no explicit receiver) 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // access to properties. 112e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool IsContextual(Handle<Object> receiver) { 113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (receiver->IsGlobalObject()) { 114e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return SlowIsContextual(); 115e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } else { 116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(!SlowIsContextual()); 117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return false; 118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 119e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke bool SlowIsContextual() { 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT; 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1258defd9ff6930b4e24729971a61cf7469daf119beSteve Block // Determines which map must be used for keeping the code stub. 1268defd9ff6930b4e24729971a61cf7469daf119beSteve Block // These methods should not be called with undefined or null. 1278defd9ff6930b4e24729971a61cf7469daf119beSteve Block static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, 1288defd9ff6930b4e24729971a61cf7469daf119beSteve Block JSObject* holder); 1298defd9ff6930b4e24729971a61cf7469daf119beSteve Block static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, 1308defd9ff6930b4e24729971a61cf7469daf119beSteve Block JSObject* holder); 13180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen static inline JSObject* GetCodeCacheHolder(Object* object, 13280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen InlineCacheHolderFlag holder); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected: 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp() const { return fp_; } 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address pc() const { return *pc_address_; } 13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate() const { return isolate_; } 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Computes the address in the original code when the code running is 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // containing break points (calls to DebugBreakXXX builtins). 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address OriginalCodeAddress(); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the call-site target. 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_target(Code* code) { SetTargetAtAddress(address(), code); } 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 149257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void TraceIC(const char* type, 150257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> name, 151257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch State old_state, 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code* new_target, 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const char* extra_info = ""); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Failure* TypeError(const char* type, 15744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> object, 15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> key); 15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Failure* ReferenceError(const char* type, Handle<String> name); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Access the target code for the given IC address. 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Code* GetTargetAtAddress(Address address); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline void SetTargetAtAddress(Address address, Code* target); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Frame pointer for the frame that uses (calls) the IC. 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address fp_; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All access to the program counter of an IC structure is indirect 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to make the code GC safe. This feature is crucial since 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // GetProperty and SetProperty are called and they in turn might 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // invoke the garbage collector. 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address* pc_address_; 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 17644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_IMPLICIT_CONSTRUCTORS(IC); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An IC_Utility encapsulates IC::UtilityId. It exists mainly because you 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// cannot make forward declarations to an enum. 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass IC_Utility { 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit IC_Utility(IC::UtilityId id) 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : address_(IC::AddressFromUtilityId(id)), id_(id) {} 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address() const { return address_; } 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC::UtilityId id() const { return id_; } 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address_; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IC::UtilityId id_; 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass CallICBase: public IC { 198257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 199257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class Contextual: public BitField<bool, 0, 1> {}; 200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; 201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch protected: 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CallICBase(Code::Kind kind, Isolate* isolate) 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2067f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 2075913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* LoadFunction(State state, 208b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState extra_ic_state, 2095913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 2105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch protected: 2137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind_; 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch bool TryUpdateExtraICState(LookupResult* lookup, 216b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Object> object, 217b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState* extra_ic_state); 218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch MUST_USE_RESULT MaybeObject* ComputeMonomorphicStub( 220b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch LookupResult* lookup, 221b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch State state, 222b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState extra_ic_state, 223b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Object> object, 224b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<String> name); 225b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache and the global stub cache based on the 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lookup result. 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 230b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::ExtraICState extra_ic_state, 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns a JSFunction if the object can be called as a function, 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and patches the stack to be ready for the call. 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Otherwise, it returns the undefined value. 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* TryCallAsFunction(Object* object); 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void ReceiverToObjectIfRequired(Handle<Object> callee, Handle<Object> object); 240e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass CallIC: public CallICBase { 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { 25044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_call_stub()); 25144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Code generator routines. 254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm, 255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_ic_state) { 257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, argc, extra_ic_state); 258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, 260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_ic_state); 262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMegamorphic(MacroAssembler* masm, 263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_ic_state); 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateNormal(MacroAssembler* masm, int argc); 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 2677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass KeyedCallIC: public CallICBase { 2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public: 27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit KeyedCallIC(Isolate* isolate) 27244f0eee88ff00398ff7f715fab053374d808c90dSteve Block : CallICBase(Code::KEYED_CALL_IC, isolate) { 2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT(target()->is_keyed_call_stub()); 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 2757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* LoadFunction(State state, 2775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 2785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> key); 2797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Code generator routines. 2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateInitialize(MacroAssembler* masm, int argc) { 2827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch GenerateMiss(masm, argc); 2837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 2847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateMiss(MacroAssembler* masm, int argc); 2857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateMegamorphic(MacroAssembler* masm, int argc); 2867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch static void GenerateNormal(MacroAssembler* masm, int argc); 2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm, int argc); 2887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}; 2897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass LoadIC: public IC { 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit LoadIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_load_stub()); 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Load(State state, 2985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 2995913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generator routines. 302402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 303402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GeneratePreMonomorphic(MacroAssembler* masm) { 304402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu GenerateMiss(masm); 305402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMiss(MacroAssembler* masm); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMegamorphic(MacroAssembler* masm); 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateNormal(MacroAssembler* masm); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Specialized code generator routines. 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateArrayLength(MacroAssembler* masm); 3121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void GenerateStringLength(MacroAssembler* masm, 3131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool support_wrappers); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateFunctionPrototype(MacroAssembler* masm); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache and the global stub cache based on the 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lookup result. 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub() { 32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_Megamorphic); 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_Initialize); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* pre_monomorphic_stub() { 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kLoadIC_PreMonomorphic); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch friend class IC; 341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 342053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 343053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedIC: public IC { 345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} 347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual ~KeyedIC() {} 348257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual MaybeObject* GetElementStubWithoutMapCheck( 3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 3513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSObject::ElementsKind elements_kind) = 0; 352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code* string_stub() { 355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return NULL; 356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const = 0; 359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MaybeObject* ComputeStub(JSObject* receiver, 361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_store, 362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode, 363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code* default_stub); 364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual MaybeObject* ConstructMegamorphicStub( 366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MapList* receiver_maps, 367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CodeList* targets, 368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode) = 0; 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GetReceiverMapsForStub(Code* stub, MapList* result); 372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MaybeObject* ComputeMonomorphicStubWithoutMapCheck( 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Map* receiver_map, 3753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StrictModeFlag strict_mode); 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MaybeObject* ComputeMonomorphicStub(JSObject* receiver, 378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_store, 379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode, 380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code* default_stub); 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedLoadIC: public KeyedIC { 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { 38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_keyed_load_stub()); 38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Load(State state, 3915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> key, 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool force_generic_stub); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generator routines. 396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, bool force_generic); 397402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateRuntimeGetProperty(MacroAssembler* masm); 398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm) { 399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 401402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GeneratePreMonomorphic(MacroAssembler* masm) { 402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 403402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateGeneric(MacroAssembler* masm); 405e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static void GenerateString(MacroAssembler* masm); 406402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu static void GenerateIndexedInterceptor(MacroAssembler* masm); 4073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm); 4083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Bit mask to be tested against bit field for the cases when 410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // generic stub should go into slow case. 411d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Access check is necessary explicitly since generic stub does not perform 412d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // map checks. 413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke static const int kSlowCaseBitFieldMask = 414d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); 415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual MaybeObject* GetElementStubWithoutMapCheck( 4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSObject::ElementsKind elements_kind); 419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 421257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } 422257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 423257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual MaybeObject* ConstructMegamorphicStub( 424257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MapList* receiver_maps, 425257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CodeList* targets, 426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode); 427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code* string_stub() { 429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return isolate()->builtins()->builtin( 430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Builtins::kKeyedLoadIC_String); 431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private: 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache. 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> object, 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name); 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_Initialize); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub() { 44644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_Generic); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* generic_stub() { 45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_Generic); 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* pre_monomorphic_stub() { 45444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_PreMonomorphic); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 45744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* indexed_interceptor_stub() { 45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedLoadIC_IndexedInterceptor); 460402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu } 4613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* non_strict_arguments_stub() { 4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->builtins()->builtin( 4633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Builtins::kKeyedLoadIC_NonStrictArguments); 4643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 465402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass StoreIC: public IC { 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 47444f0eee88ff00398ff7f715fab053374d808c90dSteve Block explicit StoreIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(target()->is_store_stub()); 47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Store(State state, 479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 4805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 4815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<String> name, 4825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> value); 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generators for stub routines. Only called once at startup. 4854515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void GenerateMiss(MacroAssembler* masm); 4871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static void GenerateMegamorphic(MacroAssembler* masm, 488e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static void GenerateArrayLength(MacroAssembler* masm); 4908defd9ff6930b4e24729971a61cf7469daf119beSteve Block static void GenerateNormal(MacroAssembler* masm); 491e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateGlobalProxy(MacroAssembler* masm, 492e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache and the global stub cache based on the 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // lookup result. 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 4981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block State state, 499e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 5001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Handle<JSObject> receiver, 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name, 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_target(Code* code) { 505e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Strict mode must be preserved across IC patching. 506e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT((code->extra_ic_state() & kStrictMode) == 507e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (target()->extra_ic_state() & kStrictMode)); 508e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch IC::set_target(code); 509e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 510e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 51244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub() { 51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 51444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Megamorphic); 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 51644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub_strict() { 51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 51844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Megamorphic_Strict); 5191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 52244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Initialize); 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block static Code* initialize_stub_strict() { 52544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_Initialize_Strict); 5271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* global_proxy_stub() { 52944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 53044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_GlobalProxy); 531b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* global_proxy_stub_strict() { 53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kStoreIC_GlobalProxy_Strict); 5351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 53850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass KeyedStoreIC: public KeyedIC { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit KeyedStoreIC(Isolate* isolate) : KeyedIC(isolate) { 546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(target()->is_keyed_store_stub()); 547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5495913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MUST_USE_RESULT MaybeObject* Store(State state, 550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode, 5515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> object, 5525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Handle<Object> name, 553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> value, 554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool force_generic); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Code generators for stub routines. Only called once at startup. 557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateInitialize(MacroAssembler* masm) { 558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GenerateMiss(masm, false); 559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 560257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateMiss(MacroAssembler* masm, bool force_generic); 561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GenerateSlow(MacroAssembler* masm); 562e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateRuntimeSetProperty(MacroAssembler* masm, 563e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode); 564e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch static void GenerateNonStrictArguments(MacroAssembler* masm); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch virtual MaybeObject* GetElementStubWithoutMapCheck( 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool is_js_array, 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch JSObject::ElementsKind elements_kind); 570053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block 571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch protected: 572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch virtual MaybeObject* ConstructMegamorphicStub( 575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MapList* receiver_maps, 576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CodeList* targets, 577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode); 578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the inline cache. 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void UpdateCaches(LookupResult* lookup, 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block State state, 583e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode, 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSObject> receiver, 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name, 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch void set_target(Code* code) { 589e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Strict mode must be preserved across IC patching. 590e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT((code->extra_ic_state() & kStrictMode) == 591e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (target()->extra_ic_state() & kStrictMode)); 592e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch IC::set_target(code); 593e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 594e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Stub accessors. 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Code* initialize_stub() { 59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Initialize); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub() { 60144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Generic); 603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 60444f0eee88ff00398ff7f715fab053374d808c90dSteve Block static Code* initialize_stub_strict() { 60544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->builtins()->builtin( 60644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Initialize_Strict); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* megamorphic_stub_strict() { 60944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 61044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Generic_Strict); 611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 61244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* generic_stub() { 61344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 61444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Generic); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 61644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* generic_stub_strict() { 61744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate()->builtins()->builtin( 61844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Builtins::kKeyedStoreIC_Generic_Strict); 619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 6203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code* non_strict_arguments_stub() { 6213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return isolate()->builtins()->builtin( 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Builtins::kKeyedStoreIC_NonStrictArguments); 6233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Clear(Address address, Code* target); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block friend class IC; 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 631257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass UnaryOpIC: public IC { 632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // sorted: increasingly more unspecific (ignoring UNINITIALIZED) 634257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead. 635257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum TypeInfo { 636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNINITIALIZED, 637257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SMI, 638257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HEAP_NUMBER, 639257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch GENERIC 640257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch }; 641257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 642257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit UnaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 643257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 644257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void patch(Code* code); 645257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 646257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const char* GetName(TypeInfo type_info); 647257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 648257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static State ToState(TypeInfo type_info); 649257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 650257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static TypeInfo GetTypeInfo(Handle<Object> operand); 651257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 652257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static TypeInfo ComputeNewType(TypeInfo type, TypeInfo previous); 653257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 654257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 655257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Type Recording BinaryOpIC, that records the types of the inputs and outputs. 657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass BinaryOpIC: public IC { 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum TypeInfo { 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNINITIALIZED, 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SMI, 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch INT32, 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEAP_NUMBER, 66444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ODDBALL, 665257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BOTH_STRING, // Only used for addition operation. 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch STRING, // Only used for addition operation. At least one string operand. 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GENERIC 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void patch(Code* code); 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* GetName(TypeInfo type_info); 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static State ToState(TypeInfo type_info); 677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static TypeInfo GetTypeInfo(Handle<Object> left, Handle<Object> right); 679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static TypeInfo JoinTypes(TypeInfo x, TypeInfo y); 681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass CompareIC: public IC { 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch enum State { 687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch UNINITIALIZED, 688b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SMIS, 689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HEAP_NUMBERS, 690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SYMBOLS, 691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch STRINGS, 692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch OBJECTS, 693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GENERIC 694b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch }; 695b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompareIC(Isolate* isolate, Token::Value op) 69744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : IC(EXTRA_CALL_FRAME, isolate), op_(op) { } 698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Update the inline cache for the given operands. 700b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch void UpdateCaches(Handle<Object> x, Handle<Object> y); 701b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 702b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Factory method for getting an uninitialized compare stub. 703b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Handle<Code> GetUninitialized(Token::Value op); 704b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Helper function for computing the condition for a compare operation. 706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static Condition ComputeCondition(Token::Value op); 707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Helper function for determining the state of a compare IC. 709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static State ComputeState(Code* target); 710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static const char* GetStateName(State state); 712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch State TargetState(State state, bool has_inlined_smi_code, 715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Object> x, Handle<Object> y); 716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool strict() const { return op_ == Token::EQ_STRICT; } 718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Condition GetCondition() const { return ComputeCondition(op_); } 719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch State GetState() { return ComputeState(target()); } 720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Token::Value op_; 722b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 72469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 72569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochclass ToBooleanIC: public IC { 72669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public: 72769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch explicit ToBooleanIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } 72869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 72969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch void patch(Code* code); 73069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}; 73169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 73269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Helper for BinaryOpIC and CompareIC. 734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid PatchInlinedSmiCode(Address address); 735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_IC_H_ 739