diff options
Diffstat (limited to 'deps/v8/src/ic.h')
-rw-r--r-- | deps/v8/src/ic.h | 356 |
1 files changed, 187 insertions, 169 deletions
diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h index 8f09e1d0a..fde4bc77a 100644 --- a/deps/v8/src/ic.h +++ b/deps/v8/src/ic.h @@ -57,8 +57,8 @@ namespace internal { ICU(LoadPropertyWithInterceptorForCall) \ ICU(KeyedLoadPropertyWithInterceptor) \ ICU(StoreInterceptorProperty) \ - ICU(BinaryOp_Patch) \ ICU(CompareIC_Miss) \ + ICU(BinaryOpIC_Miss) \ ICU(CompareNilIC_Miss) \ ICU(Unreachable) \ ICU(ToBooleanIC_Miss) @@ -95,11 +95,17 @@ class IC { virtual ~IC() {} // Get the call-site target; used for determining the state. - Code* target() const { return GetTargetAtAddress(address()); } + Handle<Code> target() const { return target_; } + Code* raw_target() const { return GetTargetAtAddress(address()); } + + State state() const { return state_; } inline Address address() const; // Compute the current IC state based on the target stub, receiver and name. - static State StateFrom(Code* target, Object* receiver, Object* name); + void UpdateState(Handle<Object> receiver, Handle<Object> name); + void MarkMonomorphicPrototypeFailure() { + state_ = MONOMORPHIC_PROTOTYPE_FAILURE; + } // Clear the inline cache to initial state. static void Clear(Isolate* isolate, Address address); @@ -128,12 +134,15 @@ class IC { // These methods should not be called with undefined or null. static inline InlineCacheHolderFlag GetCodeCacheForObject(Object* object, JSObject* holder); - static inline InlineCacheHolderFlag GetCodeCacheForObject(JSObject* object, - JSObject* holder); static inline JSObject* GetCodeCacheHolder(Isolate* isolate, Object* object, InlineCacheHolderFlag holder); + static bool IsCleared(Code* code) { + InlineCacheState state = code->ic_state(); + return state == UNINITIALIZED || state == PREMONOMORPHIC; + } + protected: Address fp() const { return fp_; } Address pc() const { return *pc_address_; } @@ -146,15 +155,17 @@ class IC { #endif // Set the call-site target. - void set_target(Code* code) { SetTargetAtAddress(address(), code); } + void set_target(Code* code) { + SetTargetAtAddress(address(), code); + target_set_ = true; + } + + bool is_target_set() { return target_set_; } #ifdef DEBUG char TransitionMarkFromState(IC::State state); - void TraceIC(const char* type, - Handle<Object> name, - State old_state, - Code* new_target); + void TraceIC(const char* type, Handle<Object> name); #endif Failure* TypeError(const char* type, @@ -167,51 +178,52 @@ class IC { static inline void SetTargetAtAddress(Address address, Code* target); static void PostPatching(Address address, Code* target, Code* old_target); - virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver, - Handle<Code> handler, - Handle<String> name, - StrictModeFlag strict_mode) { - set_target(*handler); - } - bool UpdatePolymorphicIC(State state, - Handle<HeapObject> receiver, - Handle<String> name, - Handle<Code> code, - StrictModeFlag strict_mode); - - virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps, - CodeHandleList* handlers, - int number_of_valid_maps, - Handle<Name> name, - StrictModeFlag strict_mode) { + // Compute the handler either by compiling or by retrieving a cached version. + Handle<Code> ComputeHandler(LookupResult* lookup, + Handle<JSObject> receiver, + Handle<String> name, + Handle<Object> value = Handle<Code>::null()); + virtual Handle<Code> CompileHandler(LookupResult* lookup, + Handle<JSObject> receiver, + Handle<String> name, + Handle<Object> value) { UNREACHABLE(); return Handle<Code>::null(); - }; + } + void UpdateMonomorphicIC(Handle<HeapObject> receiver, + Handle<Code> handler, + Handle<String> name); + + bool UpdatePolymorphicIC(Handle<HeapObject> receiver, + Handle<String> name, + Handle<Code> code); void CopyICToMegamorphicCache(Handle<String> name); bool IsTransitionedMapOfMonomorphicTarget(Map* receiver_map); - void PatchCache(State state, - StrictModeFlag strict_mode, - Handle<HeapObject> receiver, + void PatchCache(Handle<HeapObject> receiver, Handle<String> name, Handle<Code> code); virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code); - virtual Handle<Code> megamorphic_stub() { + virtual Code::Kind kind() const { UNREACHABLE(); - return Handle<Code>::null(); + return Code::STUB; } - virtual Handle<Code> megamorphic_stub_strict() { + virtual Handle<Code> slow_stub() const { UNREACHABLE(); return Handle<Code>::null(); } - virtual Handle<Code> generic_stub() const { + virtual Handle<Code> megamorphic_stub() { UNREACHABLE(); return Handle<Code>::null(); } - virtual Handle<Code> generic_stub_strict() const { + virtual Handle<Code> generic_stub() const { UNREACHABLE(); return Handle<Code>::null(); } + virtual StrictModeFlag strict_mode() const { return kNonStrictMode; } + bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, + Handle<String> name); + void TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name); private: // Frame pointer for the frame that uses (calls) the IC. @@ -225,6 +237,11 @@ class IC { Isolate* isolate_; + // The original code target that missed. + Handle<Code> target_; + State state_; + bool target_set_; + DISALLOW_IMPLICIT_CONSTRUCTORS(IC); }; @@ -251,31 +268,23 @@ class CallICBase: public IC { class StringStubState: public BitField<StringStubFeedback, 1, 1> {}; // Returns a JSFunction or a Failure. - MUST_USE_RESULT MaybeObject* LoadFunction(State state, - Code::ExtraICState extra_ic_state, - Handle<Object> object, + MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, Handle<String> name); protected: CallICBase(Code::Kind kind, Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate), kind_(kind) {} - bool TryUpdateExtraICState(LookupResult* lookup, - Handle<Object> object, - Code::ExtraICState* extra_ic_state); + virtual Code::ExtraICState extra_ic_state() { return Code::kNoExtraICState; } // Compute a monomorphic stub if possible, otherwise return a null handle. Handle<Code> ComputeMonomorphicStub(LookupResult* lookup, - State state, - Code::ExtraICState extra_state, Handle<Object> object, Handle<String> name); // Update the inline cache and the global stub cache based on the lookup // result. void UpdateCaches(LookupResult* lookup, - State state, - Code::ExtraICState extra_ic_state, Handle<Object> object, Handle<String> name); @@ -302,6 +311,9 @@ class CallICBase: public IC { Code::Kind kind, Code::ExtraICState extra_state); + virtual Handle<Code> megamorphic_stub(); + virtual Handle<Code> pre_monomorphic_stub(); + Code::Kind kind_; friend class IC; @@ -310,7 +322,9 @@ class CallICBase: public IC { class CallIC: public CallICBase { public: - explicit CallIC(Isolate* isolate) : CallICBase(Code::CALL_IC, isolate) { + explicit CallIC(Isolate* isolate) + : CallICBase(Code::CALL_IC, isolate), + extra_ic_state_(target()->extra_ic_state()) { ASSERT(target()->is_call_stub()); } @@ -335,6 +349,13 @@ class CallIC: public CallICBase { CallICBase::GenerateNormal(masm, argc); GenerateMiss(masm, argc, Code::kNoExtraICState); } + bool TryUpdateExtraICState(LookupResult* lookup, Handle<Object> object); + + protected: + virtual Code::ExtraICState extra_ic_state() { return extra_ic_state_; } + + private: + Code::ExtraICState extra_ic_state_; }; @@ -345,8 +366,7 @@ class KeyedCallIC: public CallICBase { ASSERT(target()->is_keyed_call_stub()); } - MUST_USE_RESULT MaybeObject* LoadFunction(State state, - Handle<Object> object, + MUST_USE_RESULT MaybeObject* LoadFunction(Handle<Object> object, Handle<Object> key); // Code generator routines. @@ -381,8 +401,7 @@ class LoadIC: public IC { static void GenerateNormal(MacroAssembler* masm); static void GenerateRuntimeGetProperty(MacroAssembler* masm); - MUST_USE_RESULT MaybeObject* Load(State state, - Handle<Object> object, + MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, Handle<String> name); protected: @@ -399,34 +418,33 @@ class LoadIC: public IC { // 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); - virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver, - Handle<Code> handler, - Handle<String> name, - StrictModeFlag strict_mode); - - virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps, - CodeHandleList* handlers, - int number_of_valid_maps, - Handle<Name> name, - StrictModeFlag strict_mode); - - virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup, - Handle<JSObject> receiver, - Handle<String> name); + virtual Handle<Code> CompileHandler(LookupResult* lookup, + Handle<JSObject> receiver, + Handle<String> name, + Handle<Object> unused); private: // Stub accessors. static Handle<Code> initialize_stub(Isolate* isolate) { return isolate->builtins()->LoadIC_Initialize(); } + + static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { + return isolate->builtins()->LoadIC_PreMonomorphic(); + } + virtual Handle<Code> pre_monomorphic_stub() { - return isolate()->builtins()->LoadIC_PreMonomorphic(); + return pre_monomorphic_stub(isolate()); } + Handle<Code> SimpleFieldLoad(int offset, + bool inobject = true, + Representation representation = + Representation::Tagged()); + static void Clear(Isolate* isolate, Address address, Code* target); friend class IC; @@ -446,8 +464,7 @@ class KeyedLoadIC: public LoadIC { ASSERT(target()->is_keyed_load_stub()); } - MUST_USE_RESULT MaybeObject* Load(State state, - Handle<Object> object, + MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, Handle<Object> key, ICMissMode force_generic); @@ -487,14 +504,6 @@ class KeyedLoadIC: public LoadIC { return isolate()->builtins()->KeyedLoadIC_Slow(); } - // Update the inline cache. - virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver, - Handle<Code> handler, - Handle<String> name, - StrictModeFlag strict_mode); - virtual Handle<Code> ComputeLoadHandler(LookupResult* lookup, - Handle<JSObject> receiver, - Handle<String> name); virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } private: @@ -502,8 +511,11 @@ class KeyedLoadIC: public LoadIC { static Handle<Code> initialize_stub(Isolate* isolate) { return isolate->builtins()->KeyedLoadIC_Initialize(); } + static Handle<Code> pre_monomorphic_stub(Isolate* isolate) { + return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); + } virtual Handle<Code> pre_monomorphic_stub() { - return isolate()->builtins()->KeyedLoadIC_PreMonomorphic(); + return pre_monomorphic_stub(isolate()); } Handle<Code> indexed_interceptor_stub() { return isolate()->builtins()->KeyedLoadIC_IndexedInterceptor(); @@ -523,10 +535,14 @@ class KeyedLoadIC: public LoadIC { class StoreIC: public IC { public: - StoreIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) { + StoreIC(FrameDepth depth, Isolate* isolate) + : IC(depth, isolate), + strict_mode_(Code::GetStrictMode(target()->extra_ic_state())) { ASSERT(target()->is_store_stub() || target()->is_keyed_store_stub()); } + virtual StrictModeFlag strict_mode() const { return strict_mode_; } + // Code generators for stub routines. Only called once at startup. static void GenerateSlow(MacroAssembler* masm); static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } @@ -541,8 +557,6 @@ class StoreIC: public IC { StrictModeFlag strict_mode); MUST_USE_RESULT MaybeObject* Store( - State state, - StrictModeFlag strict_mode, Handle<Object> object, Handle<String> name, Handle<Object> value, @@ -552,58 +566,60 @@ class StoreIC: public IC { protected: virtual Code::Kind kind() const { return Code::STORE_IC; } virtual Handle<Code> megamorphic_stub() { - return isolate()->builtins()->StoreIC_Megamorphic(); + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->StoreIC_Megamorphic_Strict(); + } else { + return isolate()->builtins()->StoreIC_Megamorphic(); + } } // Stub accessors. - virtual Handle<Code> megamorphic_stub_strict() { - return isolate()->builtins()->StoreIC_Megamorphic_Strict(); - } virtual Handle<Code> generic_stub() const { - return isolate()->builtins()->StoreIC_Generic(); + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->StoreIC_Generic_Strict(); + } else { + return isolate()->builtins()->StoreIC_Generic(); + } } - virtual Handle<Code> generic_stub_strict() const { - return isolate()->builtins()->StoreIC_Generic_Strict(); + + virtual Handle<Code> slow_stub() const { + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->StoreIC_Slow_Strict(); + } else { + return isolate()->builtins()->StoreIC_Slow(); + } } - virtual Handle<Code> pre_monomorphic_stub() const { - return isolate()->builtins()->StoreIC_PreMonomorphic(); + + virtual Handle<Code> pre_monomorphic_stub() { + return pre_monomorphic_stub(isolate(), strict_mode()); } - virtual Handle<Code> pre_monomorphic_stub_strict() const { - return isolate()->builtins()->StoreIC_PreMonomorphic_Strict(); + + static Handle<Code> pre_monomorphic_stub(Isolate* isolate, + StrictModeFlag strict_mode) { + if (strict_mode == kStrictMode) { + return isolate->builtins()->StoreIC_PreMonomorphic_Strict(); + } else { + return isolate->builtins()->StoreIC_PreMonomorphic(); + } } + virtual Handle<Code> global_proxy_stub() { - return isolate()->builtins()->StoreIC_GlobalProxy(); - } - virtual Handle<Code> global_proxy_stub_strict() { - return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->StoreIC_GlobalProxy_Strict(); + } else { + return isolate()->builtins()->StoreIC_GlobalProxy(); + } } - virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver, - Handle<Code> handler, - Handle<String> name, - StrictModeFlag strict_mode); - - virtual Handle<Code> ComputePolymorphicIC(MapHandleList* receiver_maps, - CodeHandleList* handlers, - int number_of_valid_maps, - Handle<Name> name, - StrictModeFlag strict_mode); - // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupResult* lookup, - State state, - StrictModeFlag strict_mode, Handle<JSObject> receiver, Handle<String> name, Handle<Object> value); - // Compute the code stub for this store; used for rewriting to - // monomorphic state and making sure that the code stub is in the - // stub cache. - virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup, - StrictModeFlag strict_mode, - Handle<JSObject> receiver, - Handle<String> name, - Handle<Object> value); + virtual Handle<Code> CompileHandler(LookupResult* lookup, + Handle<JSObject> receiver, + Handle<String> name, + Handle<Object> value); private: void set_target(Code* code) { @@ -613,14 +629,19 @@ class StoreIC: public IC { IC::set_target(code); } - static Handle<Code> initialize_stub(Isolate* isolate) { - return isolate->builtins()->StoreIC_Initialize(); - } - static Handle<Code> initialize_stub_strict(Isolate* isolate) { - return isolate->builtins()->StoreIC_Initialize_Strict(); + static Handle<Code> initialize_stub(Isolate* isolate, + StrictModeFlag strict_mode) { + if (strict_mode == kStrictMode) { + return isolate->builtins()->StoreIC_Initialize_Strict(); + } else { + return isolate->builtins()->StoreIC_Initialize(); + } } + static void Clear(Isolate* isolate, Address address, Code* target); + StrictModeFlag strict_mode_; + friend class IC; }; @@ -644,9 +665,7 @@ class KeyedStoreIC: public StoreIC { ASSERT(target()->is_keyed_store_stub()); } - MUST_USE_RESULT MaybeObject* Store(State state, - StrictModeFlag strict_mode, - Handle<Object> object, + MUST_USE_RESULT MaybeObject* Store(Handle<Object> object, Handle<Object> name, Handle<Object> value, ICMissMode force_generic); @@ -668,56 +687,62 @@ class KeyedStoreIC: public StoreIC { protected: virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } - virtual Handle<Code> ComputeStoreMonomorphic(LookupResult* lookup, - StrictModeFlag strict_mode, - Handle<JSObject> receiver, - Handle<String> name, - Handle<Object> value); virtual void UpdateMegamorphicCache(Map* map, Name* name, Code* code) { } - virtual Handle<Code> pre_monomorphic_stub() const { - return isolate()->builtins()->KeyedStoreIC_PreMonomorphic(); + virtual Handle<Code> pre_monomorphic_stub() { + return pre_monomorphic_stub(isolate(), strict_mode()); } - virtual Handle<Code> pre_monomorphic_stub_strict() const { - return isolate()->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); + static Handle<Code> pre_monomorphic_stub(Isolate* isolate, + StrictModeFlag strict_mode) { + if (strict_mode == kStrictMode) { + return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict(); + } else { + return isolate->builtins()->KeyedStoreIC_PreMonomorphic(); + } } - virtual Handle<Code> megamorphic_stub() { - return isolate()->builtins()->KeyedStoreIC_Generic(); + virtual Handle<Code> slow_stub() const { + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->KeyedStoreIC_Slow_Strict(); + } else { + return isolate()->builtins()->KeyedStoreIC_Slow(); + } } - virtual Handle<Code> megamorphic_stub_strict() { - return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); + virtual Handle<Code> megamorphic_stub() { + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); + } else { + return isolate()->builtins()->KeyedStoreIC_Generic(); + } } Handle<Code> StoreElementStub(Handle<JSObject> receiver, - KeyedAccessStoreMode store_mode, - StrictModeFlag strict_mode); - - virtual void UpdateMonomorphicIC(Handle<HeapObject> receiver, - Handle<Code> handler, - Handle<String> name, - StrictModeFlag strict_mode); + KeyedAccessStoreMode store_mode); private: void set_target(Code* code) { // Strict mode must be preserved across IC patching. - ASSERT(Code::GetStrictMode(code->extra_ic_state()) == - Code::GetStrictMode(target()->extra_ic_state())); + ASSERT(Code::GetStrictMode(code->extra_ic_state()) == strict_mode()); IC::set_target(code); } // Stub accessors. - static Handle<Code> initialize_stub(Isolate* isolate) { - return isolate->builtins()->KeyedStoreIC_Initialize(); - } - static Handle<Code> initialize_stub_strict(Isolate* isolate) { - return isolate->builtins()->KeyedStoreIC_Initialize_Strict(); - } - Handle<Code> generic_stub() const { - return isolate()->builtins()->KeyedStoreIC_Generic(); + static Handle<Code> initialize_stub(Isolate* isolate, + StrictModeFlag strict_mode) { + if (strict_mode == kStrictMode) { + return isolate->builtins()->KeyedStoreIC_Initialize_Strict(); + } else { + return isolate->builtins()->KeyedStoreIC_Initialize(); + } } - Handle<Code> generic_stub_strict() const { - return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); + + virtual Handle<Code> generic_stub() const { + if (strict_mode() == kStrictMode) { + return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); + } else { + return isolate()->builtins()->KeyedStoreIC_Generic(); + } } + Handle<Code> non_strict_arguments_stub() { return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); } @@ -748,22 +773,14 @@ class BinaryOpIC: public IC { GENERIC }; - static void StubInfoToType(int minor_key, - Handle<Type>* left, - Handle<Type>* right, - Handle<Type>* result, - Isolate* isolate); - - explicit BinaryOpIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) { } + explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } - void patch(Code* code); + static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); static const char* GetName(TypeInfo type_info); - static State ToState(TypeInfo type_info); - - private: - static Handle<Type> TypeInfoToType(TypeInfo binary_type, Isolate* isolate); + MUST_USE_RESULT MaybeObject* Transition(Handle<Object> left, + Handle<Object> right); }; @@ -870,6 +887,7 @@ DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure); DECLARE_RUNTIME_FUNCTION(MaybeObject*, UnaryOpIC_Miss); DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure); DECLARE_RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss); +DECLARE_RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss); DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); |