diff options
Diffstat (limited to 'deps/v8/src/ic.h')
-rw-r--r-- | deps/v8/src/ic.h | 226 |
1 files changed, 165 insertions, 61 deletions
diff --git a/deps/v8/src/ic.h b/deps/v8/src/ic.h index e70cb82c96..895c21e736 100644 --- a/deps/v8/src/ic.h +++ b/deps/v8/src/ic.h @@ -1,29 +1,6 @@ // Copyright 2012 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. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #ifndef V8_IC_H_ #define V8_IC_H_ @@ -42,6 +19,7 @@ const int kMaxKeyedPolymorphism = 4; #define IC_UTIL_LIST(ICU) \ ICU(LoadIC_Miss) \ ICU(KeyedLoadIC_Miss) \ + ICU(CallIC_Miss) \ ICU(StoreIC_Miss) \ ICU(StoreIC_ArrayLength) \ ICU(StoreIC_Slow) \ @@ -96,10 +74,24 @@ class IC { // Compute the current IC state based on the target stub, receiver and name. void UpdateState(Handle<Object> receiver, Handle<Object> name); - void MarkMonomorphicPrototypeFailure() { - state_ = MONOMORPHIC_PROTOTYPE_FAILURE; + + bool IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name); + bool TryMarkMonomorphicPrototypeFailure(Handle<Object> name) { + if (IsNameCompatibleWithMonomorphicPrototypeFailure(name)) { + state_ = MONOMORPHIC_PROTOTYPE_FAILURE; + return true; + } + return false; } + // If the stub contains weak maps then this function adds the stub to + // the dependent code array of each weak map. + static void RegisterWeakMapDependency(Handle<Code> stub); + + // This function is called when a weak map in the stub is dying, + // invalidates the stub by setting maps in it to undefined. + static void InvalidateMaps(Code* stub); + // Clear the inline cache to initial state. static void Clear(Isolate* isolate, Address address, @@ -113,6 +105,10 @@ class IC { bool IsStoreStub() const { return target()->is_store_stub() || target()->is_keyed_store_stub(); } + + bool IsCallStub() const { + return target()->is_call_stub(); + } #endif // Determines which map must be used for keeping the code stub. @@ -156,17 +152,18 @@ class IC { Address pc() const { return *pc_address_; } Isolate* isolate() const { return isolate_; } -#ifdef ENABLE_DEBUGGER_SUPPORT // Get the shared function info of the caller. SharedFunctionInfo* GetSharedFunctionInfo() const; // Get the code object of the caller. Code* GetCode() const; // Get the original (non-breakpointed) code object of the caller. Code* GetOriginalCode() const; -#endif // Set the call-site target. void set_target(Code* code) { +#ifdef VERIFY_HEAP + code->VerifyEmbeddedObjectsDependency(); +#endif SetTargetAtAddress(address(), code, constant_pool()); target_set_ = true; } @@ -179,10 +176,10 @@ class IC { void TraceIC(const char* type, Handle<Object> name); #endif - Failure* TypeError(const char* type, - Handle<Object> object, - Handle<Object> key); - Failure* ReferenceError(const char* type, Handle<String> name); + MaybeHandle<Object> TypeError(const char* type, + Handle<Object> object, + Handle<Object> key); + MaybeHandle<Object> ReferenceError(const char* type, Handle<String> name); // Access the target code for the given IC address. static inline Code* GetTargetAtAddress(Address address, @@ -247,6 +244,25 @@ class IC { extra_ic_state_ = state; } + void TargetMaps(MapHandleList* list) { + FindTargetMaps(); + for (int i = 0; i < target_maps_.length(); i++) { + list->Add(target_maps_.at(i)); + } + } + + void TargetTypes(TypeHandleList* list) { + FindTargetMaps(); + for (int i = 0; i < target_maps_.length(); i++) { + list->Add(IC::MapToType<HeapType>(target_maps_.at(i), isolate_)); + } + } + + Map* FirstTargetMap() { + FindTargetMaps(); + return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; + } + protected: void UpdateTarget() { target_ = handle(raw_target(), isolate_); @@ -259,6 +275,17 @@ class IC { inline ConstantPoolArray* constant_pool() const; inline ConstantPoolArray* raw_constant_pool() const; + void FindTargetMaps() { + if (target_maps_set_) return; + target_maps_set_ = true; + if (state_ == MONOMORPHIC) { + Map* map = target_->FindFirstMap(); + if (map != NULL) target_maps_.Add(handle(map)); + } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { + target_->FindAllMaps(&target_maps_); + } + } + // Frame pointer for the frame that uses (calls) the IC. Address fp_; @@ -280,6 +307,8 @@ class IC { bool target_set_; ExtraICState extra_ic_state_; + MapHandleList target_maps_; + bool target_maps_set_; DISALLOW_IMPLICIT_CONSTRUCTORS(IC); }; @@ -301,6 +330,78 @@ class IC_Utility { }; +class CallIC: public IC { + public: + enum CallType { METHOD, FUNCTION }; + + class State V8_FINAL BASE_EMBEDDED { + public: + explicit State(ExtraICState extra_ic_state); + + static State DefaultCallState(int argc, CallType call_type) { + return State(argc, call_type); + } + + static State MegamorphicCallState(int argc, CallType call_type) { + return State(argc, call_type); + } + + InlineCacheState GetICState() const { return ::v8::internal::GENERIC; } + + ExtraICState GetExtraICState() const; + + static void GenerateAheadOfTime( + Isolate*, void (*Generate)(Isolate*, const State&)); + + int arg_count() const { return argc_; } + CallType call_type() const { return call_type_; } + + bool CallAsMethod() const { return call_type_ == METHOD; } + + void Print(StringStream* stream) const; + + bool operator==(const State& other_state) const { + return (argc_ == other_state.argc_ && + call_type_ == other_state.call_type_); + } + + bool operator!=(const State& other_state) const { + return !(*this == other_state); + } + + private: + State(int argc, + CallType call_type) + : argc_(argc), + call_type_(call_type) { + } + + class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {}; + class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {}; + + const int argc_; + const CallType call_type_; + }; + + explicit CallIC(Isolate* isolate) + : IC(EXTRA_CALL_FRAME, isolate) { + } + + void HandleMiss(Handle<Object> receiver, + Handle<Object> function, + Handle<FixedArray> vector, + Handle<Smi> slot); + + // Code generator routines. + static Handle<Code> initialize_stub(Isolate* isolate, + int argc, + CallType call_type); + + static void Clear(Isolate* isolate, Address address, Code* target, + ConstantPoolArray* constant_pool); +}; + + class LoadIC: public IC { public: // ExtraICState bits @@ -348,8 +449,8 @@ class LoadIC: public IC { static Handle<Code> initialize_stub(Isolate* isolate, ExtraICState extra_state); - MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, - Handle<String> name); + MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, + Handle<String> name); protected: virtual Code::Kind kind() const { return Code::LOAD_IC; } @@ -410,8 +511,8 @@ class KeyedLoadIC: public LoadIC { ASSERT(target()->is_keyed_load_stub()); } - MUST_USE_RESULT MaybeObject* Load(Handle<Object> object, - Handle<Object> key); + MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, + Handle<Object> key); // Code generator routines. static void GenerateMiss(MacroAssembler* masm); @@ -515,7 +616,7 @@ class StoreIC: public IC { static Handle<Code> initialize_stub(Isolate* isolate, StrictMode strict_mode); - MUST_USE_RESULT MaybeObject* Store( + MUST_USE_RESULT MaybeHandle<Object> Store( Handle<Object> object, Handle<String> name, Handle<Object> value, @@ -604,9 +705,9 @@ class KeyedStoreIC: public StoreIC { ASSERT(target()->is_keyed_store_stub()); } - MUST_USE_RESULT MaybeObject* Store(Handle<Object> object, - Handle<Object> name, - Handle<Object> value); + MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, + Handle<Object> name, + Handle<Object> value); // Code generators for stub routines. Only called once at startup. static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } @@ -679,7 +780,7 @@ class KeyedStoreIC: public StoreIC { Handle<Object> key, Handle<Object> value); - Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, + Handle<Map> ComputeTransitionedMap(Handle<Map> map, KeyedAccessStoreMode store_mode); friend class IC; @@ -694,11 +795,11 @@ class BinaryOpIC: public IC { public: class State V8_FINAL BASE_EMBEDDED { public: - explicit State(ExtraICState extra_ic_state); + State(Isolate* isolate, ExtraICState extra_ic_state); - State(Token::Value op, OverwriteMode mode) + State(Isolate* isolate, Token::Value op, OverwriteMode mode) : op_(op), mode_(mode), left_kind_(NONE), right_kind_(NONE), - result_kind_(NONE) { + result_kind_(NONE), isolate_(isolate) { ASSERT_LE(FIRST_TOKEN, op); ASSERT_LE(op, LAST_TOKEN); } @@ -775,6 +876,8 @@ class BinaryOpIC: public IC { Handle<Object> right, Handle<Object> result); + Isolate* isolate() const { return isolate_; } + private: enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; @@ -805,15 +908,16 @@ class BinaryOpIC: public IC { Kind right_kind_; Kind result_kind_; Maybe<int> fixed_right_arg_; + Isolate* isolate_; }; explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } static Builtins::JavaScript TokenToJSBuiltin(Token::Value op); - MaybeObject* Transition(Handle<AllocationSite> allocation_site, - Handle<Object> left, - Handle<Object> right) V8_WARN_UNUSED_RESULT; + MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site, + Handle<Object> left, + Handle<Object> right) V8_WARN_UNUSED_RESULT; }; @@ -895,7 +999,7 @@ class CompareNilIC: public IC { public: explicit CompareNilIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} - MUST_USE_RESULT MaybeObject* CompareNil(Handle<Object> object); + Handle<Object> CompareNil(Handle<Object> object); static Handle<Code> GetUninitialized(); @@ -903,8 +1007,8 @@ class CompareNilIC: public IC { Code* target, ConstantPoolArray* constant_pool); - static MUST_USE_RESULT MaybeObject* DoCompareNilSlow(NilValue nil, - Handle<Object> object); + static Handle<Object> DoCompareNilSlow(Isolate* isolate, NilValue nil, + Handle<Object> object); }; @@ -912,7 +1016,7 @@ class ToBooleanIC: public IC { public: explicit ToBooleanIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) { } - MaybeObject* ToBoolean(Handle<Object> object); + Handle<Object> ToBoolean(Handle<Object> object); }; @@ -920,15 +1024,15 @@ class ToBooleanIC: public IC { enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; void PatchInlinedSmiCode(Address address, InlinedSmiCheck check); -DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure); -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*, BinaryOpIC_MissWithAllocationSite); -DECLARE_RUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss); -DECLARE_RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss); +DECLARE_RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure); +DECLARE_RUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure); +DECLARE_RUNTIME_FUNCTION(UnaryOpIC_Miss); +DECLARE_RUNTIME_FUNCTION(StoreIC_MissFromStubFailure); +DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); +DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); +DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); +DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); +DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); } } // namespace v8::internal |