Index: src/ic/ic.h |
diff --git a/src/ic/ic.h b/src/ic/ic.h |
index 0da2cd006937711ed5eac58881f4cc07987d2cf5..c50b43e0b5e6290c4aaad67ea96f0e18e226c374 100644 |
--- a/src/ic/ic.h |
+++ b/src/ic/ic.h |
@@ -59,7 +59,8 @@ class IC { |
// Construct the IC structure with the given number of extra |
// JavaScript frames on the stack. |
- IC(FrameDepth depth, Isolate* isolate); |
+ IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL, |
+ bool for_queries_only = false); |
virtual ~IC() {} |
State state() const { return state_; } |
@@ -71,6 +72,7 @@ class IC { |
bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); |
void MarkPrototypeFailure(Handle<Object> name) { |
DCHECK(IsNameCompatibleWithPrototypeFailure(name)); |
+ old_state_ = state_; |
state_ = PROTOTYPE_FAILURE; |
} |
@@ -87,8 +89,9 @@ class IC { |
ConstantPoolArray* constant_pool); |
// Clear the vector-based inline cache to initial state. |
+ template <class Nexus> |
static void Clear(Isolate* isolate, Code::Kind kind, Code* host, |
- TypeFeedbackVector* vector, FeedbackVectorICSlot slot); |
+ Nexus* nexus); |
#ifdef DEBUG |
bool IsLoadStub() const { |
@@ -117,6 +120,11 @@ class IC { |
return state == UNINITIALIZED || state == PREMONOMORPHIC; |
} |
+ static bool IsCleared(FeedbackNexus* nexus) { |
+ InlineCacheState state = nexus->StateFromFeedback(); |
+ return state == UNINITIALIZED || state == PREMONOMORPHIC; |
+ } |
+ |
// Utility functions to convert maps to types and back. There are two special |
// cases: |
// - The heap_number_map is used as a marker which includes heap numbers as |
@@ -149,6 +157,15 @@ class IC { |
inline void set_target(Code* code); |
bool is_target_set() { return target_set_; } |
+ bool UseVector() const { |
+ bool use = (FLAG_vector_ics && |
+ (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) || |
+ kind() == Code::CALL_IC; |
+ // If we are supposed to use the nexus, verify the nexus is non-null. |
+ DCHECK(!use || nexus_ != NULL); |
+ return use; |
+ } |
+ |
char TransitionMarkFromState(IC::State state); |
void TraceIC(const char* type, Handle<Object> name); |
void TraceIC(const char* type, Handle<Object> name, State old_state, |
@@ -166,6 +183,10 @@ class IC { |
static void OnTypeFeedbackChanged(Isolate* isolate, Address address, |
State old_state, State new_state, |
bool target_remains_ic_stub); |
+ // As a vector-based IC, type feedback must be updated differently. |
+ static void OnTypeFeedbackChanged(Isolate* isolate, Code* host, |
+ TypeFeedbackVector* vector, State old_state, |
+ State new_state); |
static void PostPatching(Address address, Code* target, Code* old_target); |
// Compute the handler either by compiling or by retrieving a cached version. |
@@ -229,6 +250,20 @@ class IC { |
inline void UpdateTarget(); |
+ Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } |
+ FeedbackVectorICSlot slot() const { return nexus()->slot(); } |
+ State saved_state() const { |
+ return state() == PROTOTYPE_FAILURE ? old_state_ : state(); |
+ } |
+ |
+ template <class NexusClass> |
+ NexusClass* casted_nexus() { |
+ return static_cast<NexusClass*>(nexus_); |
+ } |
+ FeedbackNexus* nexus() const { return nexus_; } |
+ |
+ inline Code* get_host(); |
+ |
private: |
inline Code* raw_target() const; |
inline ConstantPoolArray* constant_pool() const; |
@@ -263,6 +298,7 @@ class IC { |
// The original code target that missed. |
Handle<Code> target_; |
bool target_set_; |
+ State old_state_; // For saving if we marked as prototype failure. |
State state_; |
Code::Kind kind_; |
Handle<HeapType> receiver_type_; |
@@ -272,6 +308,8 @@ class IC { |
MapHandleList target_maps_; |
bool target_maps_set_; |
+ FeedbackNexus* nexus_; |
+ |
DISALLOW_IMPLICIT_CONSTRUCTORS(IC); |
}; |
@@ -295,38 +333,24 @@ class IC_Utility { |
class CallIC : public IC { |
public: |
- explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {} |
+ CallIC(Isolate* isolate, CallICNexus* nexus) |
+ : IC(EXTRA_CALL_FRAME, isolate, nexus) { |
+ DCHECK(nexus != NULL); |
+ } |
- void PatchMegamorphic(Handle<Object> function, |
- Handle<TypeFeedbackVector> vector, |
- FeedbackVectorICSlot slot); |
+ void PatchMegamorphic(Handle<Object> function); |
- void HandleMiss(Handle<Object> receiver, Handle<Object> function, |
- Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot); |
+ void HandleMiss(Handle<Object> receiver, Handle<Object> function); |
// Returns true if a custom handler was installed. |
bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function, |
- Handle<TypeFeedbackVector> vector, |
- FeedbackVectorICSlot slot, const CallICState& state); |
+ const CallICState& callic_state); |
// Code generator routines. |
static Handle<Code> initialize_stub(Isolate* isolate, int argc, |
CallICState::CallType call_type); |
- static void Clear(Isolate* isolate, Code* host, TypeFeedbackVector* vector, |
- FeedbackVectorICSlot slot); |
- |
- private: |
- static inline IC::State FeedbackToState(Isolate* isolate, |
- TypeFeedbackVector* vector, |
- FeedbackVectorICSlot slot); |
- |
- inline Code* get_host(); |
- |
- // As a vector-based IC, type feedback must be updated differently. |
- static void OnTypeFeedbackChanged(Isolate* isolate, Code* host, |
- TypeFeedbackVector* vector, State old_state, |
- State new_state); |
+ static void Clear(Isolate* isolate, Code* host, CallICNexus* nexus); |
}; |