📄 ic.h.svn-base
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met://// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following// disclaimer in the documentation and/or other materials provided// with the distribution.// * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived// from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#ifndef V8_IC_H_#define V8_IC_H_#include "assembler.h"namespace v8 { namespace internal {// IC_UTIL_LIST defines all utility functions called from generated// inline caching code. The argument for the macro, ICU, is the function name.#define IC_UTIL_LIST(ICU) \ ICU(LoadIC_Miss) \ ICU(KeyedLoadIC_Miss) \ ICU(CallIC_Miss) \ ICU(StoreIC_Miss) \ ICU(KeyedStoreIC_Miss) \ /* Utilities for IC stubs. */ \ ICU(LoadCallbackProperty) \ ICU(StoreCallbackProperty) \ ICU(LoadInterceptorProperty) \ ICU(StoreInterceptorProperty)//// IC is the base class for LoadIC, StoreIC and CallIC.//class IC { public: // The ids for utility called from the generated code. enum UtilityId { #define CONST_NAME(name) k##name, IC_UTIL_LIST(CONST_NAME) #undef CONST_NAME kUtilityCount }; // Looks up the address of the named utility. static Address AddressFromUtilityId(UtilityId id); // Alias the inline cache state type to make the IC code more readable. typedef InlineCacheState State; // The IC code is either invoked with no extra frames on the stack // or with a single extra frame for supporting calls. enum FrameDepth { NO_EXTRA_FRAME = 0, EXTRA_CALL_FRAME = 1 }; // Construct the IC structure with the given number of extra // JavaScript frames on the stack. explicit IC(FrameDepth depth); // Get the call-site target; used for determining the state. Code* target() { return GetTargetAtAddress(address()); } inline Address address(); // Compute the current IC state based on the target stub and the receiver. static State StateFrom(Code* target, Object* receiver); // Clear the inline cache to initial state. static void Clear(Address address); // Computes the reloc info for this IC. This is a fairly expensive // operation as it has to search through the heap to find the code // object that contains this IC site. RelocInfo::Mode ComputeMode(); // Returns if this IC is for contextual (no explicit receiver) // access to properties. bool is_contextual() { return ComputeMode() == RelocInfo::CODE_TARGET_CONTEXT; } // Returns the map to use for caching stubs for a given object. // This method should not be called with undefined or null. static inline Map* GetCodeCacheMapForObject(Object* object); protected: Address fp() const { return fp_; } Address pc() const { return *pc_address_; } // Computes the address in the original code when the code running is // containing break points (calls to DebugBreakXXX builtins). Address OriginalCodeAddress(); // Set the call-site target. void set_target(Code* code) { SetTargetAtAddress(address(), code); }#ifdef DEBUG static void TraceIC(const char* type, Handle<String> name, State old_state, Code* new_target);#endif static Failure* TypeError(const char* type, Handle<Object> object, Handle<String> name); static Failure* ReferenceError(const char* type, Handle<String> name); // Access the target code for the given IC address. static inline Code* GetTargetAtAddress(Address address); static inline void SetTargetAtAddress(Address address, Code* target); private: // Frame pointer for the frame that uses (calls) the IC. Address fp_; // All access to the program counter of an IC structure is indirect // to make the code GC safe. This feature is crucial since // GetProperty and SetProperty are called and they in turn might // invoke the garbage collector. Address* pc_address_; DISALLOW_IMPLICIT_CONSTRUCTORS(IC);};// An IC_Utility encapsulates IC::UtilityId. It exists mainly because you// cannot make forward declarations to an enum.class IC_Utility { public: explicit IC_Utility(IC::UtilityId id) : address_(IC::AddressFromUtilityId(id)), id_(id) {} Address address() const { return address_; } IC::UtilityId id() const { return id_; } private: Address address_; IC::UtilityId id_;};class CallIC: public IC { public: CallIC() : IC(EXTRA_CALL_FRAME) { ASSERT(target()->is_call_stub()); } Object* LoadFunction(State state, Handle<Object> object, Handle<String> name); // Code generator routines. static void GenerateInitialize(MacroAssembler* masm, int argc); static void GeneratePreMonomorphic(MacroAssembler* masm, int argc); static void GenerateMiss(MacroAssembler* masm, int argc); static void GenerateMegamorphic(MacroAssembler* masm, int argc); static void GenerateNormal(MacroAssembler* masm, int argc); private: static void Generate(MacroAssembler* masm, int argc, const ExternalReference& f); // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupResult* lookup, State state, Handle<Object> object, Handle<String> name); // Returns a JSFunction if the object can be called as a function, // and patches the stack to be ready for the call. // Otherwise, it returns the undefined value. Object* TryCallAsFunction(Object* object); static void Clear(Address address, Code* target); friend class IC;};class LoadIC: public IC { public: LoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_load_stub()); } Object* Load(State state, Handle<Object> object, Handle<String> name); // Code generator routines. static void GenerateInitialize(MacroAssembler* masm); static void GeneratePreMonomorphic(MacroAssembler* masm); static void GenerateMiss(MacroAssembler* masm); static void GenerateMegamorphic(MacroAssembler* masm); static void GenerateNormal(MacroAssembler* masm); // Specialized code generator routines. static void GenerateArrayLength(MacroAssembler* masm); static void GenerateShortStringLength(MacroAssembler* masm); static void GenerateMediumStringLength(MacroAssembler* masm); static void GenerateLongStringLength(MacroAssembler* masm); static void GenerateFunctionPrototype(MacroAssembler* masm); private: static void Generate(MacroAssembler* masm, const ExternalReference& f); // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupResult* lookup, State state, Handle<Object> object, Handle<String> name); // Stub accessors. static Code* megamorphic_stub() { return Builtins::builtin(Builtins::LoadIC_Megamorphic); } static Code* initialize_stub() { return Builtins::builtin(Builtins::LoadIC_Initialize); } static Code* pre_monomorphic_stub() { return Builtins::builtin(Builtins::LoadIC_PreMonomorphic); } static void Clear(Address address, Code* target); friend class IC;};class KeyedLoadIC: public IC { public: KeyedLoadIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_keyed_load_stub()); } Object* Load(State state, Handle<Object> object, Handle<Object> key); // Code generator routines. static void GenerateMiss(MacroAssembler* masm); static void GenerateInitialize(MacroAssembler* masm); static void GeneratePreMonomorphic(MacroAssembler* masm); static void GenerateGeneric(MacroAssembler* masm); private: static void Generate(MacroAssembler* masm, const ExternalReference& f); // Update the inline cache. void UpdateCaches(LookupResult* lookup, State state, Handle<Object> object, Handle<String> name); // Stub accessors. static Code* initialize_stub() { return Builtins::builtin(Builtins::KeyedLoadIC_Initialize); } static Code* megamorphic_stub() { return Builtins::builtin(Builtins::KeyedLoadIC_Generic); } static Code* generic_stub() { return Builtins::builtin(Builtins::KeyedLoadIC_Generic); } static Code* pre_monomorphic_stub() { return Builtins::builtin(Builtins::KeyedLoadIC_PreMonomorphic); } static void Clear(Address address, Code* target); friend class IC;};class StoreIC: public IC { public: StoreIC() : IC(NO_EXTRA_FRAME) { ASSERT(target()->is_store_stub()); } Object* Store(State state, Handle<Object> object, Handle<String> name, Handle<Object> value); // Code generators for stub routines. Only called once at startup. static void GenerateInitialize(MacroAssembler* masm); static void GenerateMiss(MacroAssembler* masm); static void GenerateMegamorphic(MacroAssembler* masm); private: static void Generate(MacroAssembler* masm, const ExternalReference& f); // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupResult* lookup, State state, Handle<JSObject> receiver, Handle<String> name, Handle<Object> value); // Stub accessors. static Code* megamorphic_stub() { return Builtins::builtin(Builtins::StoreIC_Megamorphic); } static Code* initialize_stub() { return Builtins::builtin(Builtins::StoreIC_Initialize); } static void Clear(Address address, Code* target); friend class IC;};class KeyedStoreIC: public IC { public: KeyedStoreIC() : IC(NO_EXTRA_FRAME) { } Object* Store(State state, Handle<Object> object, Handle<Object> name, Handle<Object> value); // Code generators for stub routines. Only called once at startup. static void GenerateInitialize(MacroAssembler* masm); static void GenerateMiss(MacroAssembler* masm); static void GenerateGeneric(MacroAssembler* masm); private: static void Generate(MacroAssembler* masm, const ExternalReference& f); // Update the inline cache. void UpdateCaches(LookupResult* lookup, State state, Handle<JSObject> receiver, Handle<String> name, Handle<Object> value); // Stub accessors. static Code* initialize_stub() { return Builtins::builtin(Builtins::KeyedStoreIC_Initialize); } static Code* megamorphic_stub() { return Builtins::builtin(Builtins::KeyedStoreIC_Generic); } static Code* generic_stub() { return Builtins::builtin(Builtins::KeyedStoreIC_Generic); } static void Clear(Address address, Code* target); friend class IC;};} } // namespace v8::internal#endif // V8_IC_H_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -