summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic.h')
-rw-r--r--deps/v8/src/ic.h226
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