Revision: 22978
Author:   [email protected]
Date:     Thu Aug  7 15:33:14 2014 UTC
Log:      Clean up IC tracing for CallICs.

CallICs have had some confused tracing, because the IC state is not
entirely captured by the installed code stub - it lives in the type
vector.

Change tracing to be able to use the vector state changes instead.
Introduced a DEFAULT state to be used by all vector-based ICs.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/451643002
http://code.google.com/p/v8/source/detail?r=22978

Modified:
 /branches/bleeding_edge/src/code-stubs.cc
 /branches/bleeding_edge/src/code-stubs.h
 /branches/bleeding_edge/src/globals.h
 /branches/bleeding_edge/src/ic-inl.h
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/ic.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/code-stubs.cc   Wed Aug  6 13:18:36 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.cc   Thu Aug  7 15:33:14 2014 UTC
@@ -320,7 +320,7 @@
 }


-InlineCacheState ICCompareStub::GetICState() {
+InlineCacheState ICCompareStub::GetICState() const {
   CompareIC::State state = Max(left_, right_);
   switch (state) {
     case CompareIC::UNINITIALIZED:
=======================================
--- /branches/bleeding_edge/src/code-stubs.h    Wed Aug  6 13:18:36 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h    Thu Aug  7 15:33:14 2014 UTC
@@ -183,9 +183,7 @@
   virtual Major MajorKey() const = 0;
   virtual int MinorKey() const = 0;

-  virtual InlineCacheState GetICState() {
-    return UNINITIALIZED;
-  }
+  virtual InlineCacheState GetICState() const { return UNINITIALIZED; }
   virtual ExtraICState GetExtraICState() const { return kNoExtraICState; }
   virtual Code::StubType GetStubType() {
     return Code::NORMAL;
@@ -850,9 +848,7 @@
     return Code::CALL_IC;
   }

-  virtual InlineCacheState GetICState() V8_FINAL V8_OVERRIDE {
-    return state_.GetICState();
-  }
+ virtual InlineCacheState GetICState() const V8_OVERRIDE { return DEFAULT; }

   virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE {
     return state_.GetExtraICState();
@@ -878,6 +874,10 @@

   virtual void Generate(MacroAssembler* masm);

+  virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE {
+    return MONOMORPHIC;
+  }
+
  protected:
   virtual void PrintState(OStream& os) const V8_OVERRIDE;  // NOLINT

@@ -903,7 +903,7 @@
  public:
   virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
   virtual ExtraICState GetExtraICState() const { return kind(); }
-  virtual InlineCacheState GetICState() { return MONOMORPHIC; }
+  virtual InlineCacheState GetICState() const { return MONOMORPHIC; }

   virtual void InitializeInterfaceDescriptor(
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
@@ -1126,7 +1126,7 @@
     return Code::BINARY_OP_IC;
   }

-  virtual InlineCacheState GetICState() V8_FINAL V8_OVERRIDE {
+  virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE {
     return state_.GetICState();
   }

@@ -1179,7 +1179,7 @@
     return Code::BINARY_OP_IC;
   }

-  virtual InlineCacheState GetICState() V8_OVERRIDE {
+  virtual InlineCacheState GetICState() const V8_OVERRIDE {
     return state_.GetICState();
   }

@@ -1316,7 +1316,7 @@
                         CompareIC::State* right_state,
                         CompareIC::State* handler_state, Token::Value* op);

-  virtual InlineCacheState GetICState();
+  virtual InlineCacheState GetICState() const;

  private:
   class OpField: public BitField<int, 0, 3> { };
@@ -1384,7 +1384,7 @@
         isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC));
   }

-  virtual InlineCacheState GetICState() {
+  virtual InlineCacheState GetICState() const {
     if (state_.Contains(GENERIC)) {
       return MEGAMORPHIC;
     } else if (state_.Contains(MONOMORPHIC_MAP)) {
@@ -1875,7 +1875,7 @@
   static void InstallDescriptors(Isolate* isolate);

   virtual Code::Kind GetCodeKind() const { return Code::KEYED_LOAD_IC; }
-  virtual InlineCacheState GetICState() { return GENERIC; }
+  virtual InlineCacheState GetICState() const { return GENERIC; }

  private:
   Major MajorKey() const { return KeyedLoadGeneric; }
@@ -2362,7 +2362,7 @@

virtual ExtraICState GetExtraICState() const { return types_.ToIntegral(); }

-  virtual InlineCacheState GetICState() {
+  virtual InlineCacheState GetICState() const {
     if (types_.IsEmpty()) {
       return ::v8::internal::UNINITIALIZED;
     } else {
=======================================
--- /branches/bleeding_edge/src/globals.h       Tue Aug  5 11:53:32 2014 UTC
+++ /branches/bleeding_edge/src/globals.h       Thu Aug  7 15:33:14 2014 UTC
@@ -446,7 +446,11 @@
   // A generic handler is installed and no extra typefeedback is recorded.
   GENERIC,
   // Special state for debug break or step in prepare stubs.
-  DEBUG_STUB
+  DEBUG_STUB,
+  // Type-vector-based ICs have a default state, with the full calculation
+  // of IC state only determined by a look at the IC and the typevector
+  // together.
+  DEFAULT
 };


=======================================
--- /branches/bleeding_edge/src/ic-inl.h        Thu Aug  7 08:52:00 2014 UTC
+++ /branches/bleeding_edge/src/ic-inl.h        Thu Aug  7 15:33:14 2014 UTC
@@ -169,8 +169,10 @@
 }


-IC::State CallIC::FeedbackObjectToState(Object* feedback) const {
+IC::State CallIC::FeedbackToState(Handle<FixedArray> vector,
+                                  Handle<Smi> slot) const {
   IC::State state = UNINITIALIZED;
+  Object* feedback = vector->get(slot->value());

   if (feedback == *TypeFeedbackInfo::MegamorphicSentinel(isolate())) {
     state = GENERIC;
=======================================
--- /branches/bleeding_edge/src/ic.cc   Thu Aug  7 08:52:00 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc   Thu Aug  7 15:33:14 2014 UTC
@@ -33,6 +33,9 @@
     // computed from the original code - not the patched code. Let
     // these cases fall through to the unreachable code below.
     case DEBUG_STUB: break;
+    // Type-vector-based ICs resolve state to one of the above.
+    case DEFAULT:
+      break;
   }
   UNREACHABLE();
   return 0;
@@ -66,10 +69,20 @@

 #endif  // DEBUG

+
 void IC::TraceIC(const char* type, Handle<Object> name) {
   if (FLAG_trace_ic) {
     Code* new_target = raw_target();
     State new_state = new_target->ic_state();
+    TraceIC(type, name, state(), new_state);
+  }
+}
+
+
+void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
+                 State new_state) {
+  if (FLAG_trace_ic) {
+    Code* new_target = raw_target();
     PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);

     // TODO(jkummerow): Add support for "apply". The logic is roughly:
@@ -92,10 +105,8 @@
       modifier = GetTransitionMarkModifier(
           KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
     }
-    PrintF(" (%c->%c%s)",
-           TransitionMarkFromState(state()),
-           TransitionMarkFromState(new_state),
-           modifier);
+    PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state),
+           TransitionMarkFromState(new_state), modifier);
 #ifdef OBJECT_PRINT
     OFStream os(stdout);
     name->Print(os);
@@ -107,7 +118,8 @@
 }

 #define TRACE_IC(type, name) TraceIC(type, name)
-
+#define TRACE_VECTOR_IC(type, name, old_state, new_state) \
+  TraceIC(type, name, old_state, new_state)

 IC::IC(FrameDepth depth, Isolate* isolate)
     : isolate_(isolate),
@@ -365,6 +377,7 @@
       break;
     case PROTOTYPE_FAILURE:
     case DEBUG_STUB:
+    case DEFAULT:
       UNREACHABLE();
   }
 }
@@ -807,6 +820,7 @@
       break;
     case DEBUG_STUB:
       break;
+    case DEFAULT:
     case GENERIC:
       UNREACHABLE();
       break;
@@ -1950,6 +1964,7 @@
       isolate()->native_context()->array_function());
   if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
     // Alter the slot.
+    IC::State old_state = FeedbackToState(vector, slot);
     Object* feedback = vector->get(slot->value());
     if (!feedback->IsAllocationSite()) {
       Handle<AllocationSite> new_site =
@@ -1965,18 +1980,19 @@
                             isolate());
     }

-    TRACE_IC("CallIC (Array call)", name);
-    Object* new_feedback = vector->get(slot->value());
-    UpdateTypeFeedbackInfo(feedback, new_feedback);
+    IC::State new_state = FeedbackToState(vector, slot);
+ OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
+    TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state);
     return true;
   }
   return false;
 }


-void CallIC::PatchMegamorphic(Handle<FixedArray> vector,
-                              Handle<Smi> slot) {
+void CallIC::PatchMegamorphic(Handle<Object> function,
+ Handle<FixedArray> vector, Handle<Smi> slot) {
   State state(target()->extra_ic_state());
+  IC::State old_state = FeedbackToState(vector, slot);

   // We are going generic.
   vector->set(slot->value(),
@@ -1987,15 +2003,15 @@
   Handle<Code> code = stub.GetCode();
   set_target(*code);

-  TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
-}
+  Handle<Object> name = isolate()->factory()->empty_string();
+  if (function->IsJSFunction()) {
+    Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
+    name = handle(js_function->shared()->name(), isolate());
+  }

-
-void CallIC::UpdateTypeFeedbackInfo(Object* old_feedback,
-                                    Object* new_feedback) {
-  IC::State old_state = FeedbackObjectToState(old_feedback);
-  IC::State new_state = FeedbackObjectToState(new_feedback);
+  IC::State new_state = FeedbackToState(vector, slot);
   OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
+  TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
 }


@@ -2004,6 +2020,8 @@
                         Handle<FixedArray> vector,
                         Handle<Smi> slot) {
   State state(target()->extra_ic_state());
+  IC::State old_state = FeedbackToState(vector, slot);
+  Handle<Object> name = isolate()->factory()->empty_string();
   Object* feedback = vector->get(slot->value());

   // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
@@ -2014,8 +2032,6 @@
     vector->set(slot->value(),
                 *TypeFeedbackInfo::MegamorphicSentinel(isolate()),
                 SKIP_WRITE_BARRIER);
-
-    TRACE_GENERIC_IC(isolate(), "CallIC", "megamorphic");
   } else {
     // The feedback is either uninitialized or an allocation site.
// It might be an allocation site because if we re-compile the full code
@@ -2032,14 +2048,17 @@
       return;
     }

+    vector->set(slot->value(), *function);
+  }
+
+  if (function->IsJSFunction()) {
     Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
-    Handle<Object> name(js_function->shared()->name(), isolate());
-    TRACE_IC("CallIC", name);
-    vector->set(slot->value(), *function);
+    name = handle(js_function->shared()->name(), isolate());
   }

-  Object* new_feedback = vector->get(slot->value());
-  UpdateTypeFeedbackInfo(feedback, new_feedback);
+  IC::State new_state = FeedbackToState(vector, slot);
+  OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
+  TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
 }


@@ -2074,7 +2093,7 @@
   Handle<Object> function = args.at<Object>(1);
   Handle<FixedArray> vector = args.at<FixedArray>(2);
   Handle<Smi> slot = args.at<Smi>(3);
-  ic.PatchMegamorphic(vector, slot);
+  ic.PatchMegamorphic(function, vector, slot);
   return *function;
 }

=======================================
--- /branches/bleeding_edge/src/ic.h    Thu Aug  7 08:52:00 2014 UTC
+++ /branches/bleeding_edge/src/ic.h    Thu Aug  7 15:33:14 2014 UTC
@@ -163,6 +163,8 @@

   char TransitionMarkFromState(IC::State state);
   void TraceIC(const char* type, Handle<Object> name);
+  void TraceIC(const char* type, Handle<Object> name, State old_state,
+               State new_state);

   MaybeHandle<Object> TypeError(const char* type,
                                 Handle<Object> object,
@@ -334,8 +336,6 @@
     State(int argc, CallType call_type)
         : argc_(argc), call_type_(call_type) {
     }
-
-    InlineCacheState GetICState() const { return ::v8::internal::GENERIC; }

     ExtraICState GetExtraICState() const;

@@ -359,7 +359,8 @@
       : IC(EXTRA_CALL_FRAME, isolate) {
   }

-  void PatchMegamorphic(Handle<FixedArray> vector, Handle<Smi> slot);
+  void PatchMegamorphic(Handle<Object> function, Handle<FixedArray> vector,
+                        Handle<Smi> slot);

   void HandleMiss(Handle<Object> receiver,
                   Handle<Object> function,
@@ -382,8 +383,8 @@
                     ConstantPoolArray* constant_pool);

  private:
-  void UpdateTypeFeedbackInfo(Object* old_feedback, Object* new_feedback);
-  inline IC::State FeedbackObjectToState(Object* feedback) const;
+  inline IC::State FeedbackToState(Handle<FixedArray> vector,
+                                   Handle<Smi> slot) const;
 };


=======================================
--- /branches/bleeding_edge/src/objects.cc      Thu Aug  7 12:21:01 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Thu Aug  7 15:33:14 2014 UTC
@@ -11320,6 +11320,8 @@
     case MEGAMORPHIC: return "MEGAMORPHIC";
     case GENERIC: return "GENERIC";
     case DEBUG_STUB: return "DEBUG_STUB";
+    case DEFAULT:
+      return "DEFAULT";
   }
   UNREACHABLE();
   return NULL;
=======================================
--- /branches/bleeding_edge/src/objects.h       Wed Aug  6 08:02:21 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Thu Aug  7 15:33:14 2014 UTC
@@ -5878,11 +5878,10 @@
   static const int kProfilerTicksOffset = kFullCodeFlags + 1;

   // Flags layout.  BitField<type, shift, size>.
-  class ICStateField: public BitField<InlineCacheState, 0, 3> {};
-  class TypeField: public BitField<StubType, 3, 1> {};
-  class CacheHolderField : public BitField<CacheHolderFlag, 4, 2> {};
-  class KindField: public BitField<Kind, 6, 4> {};
-  // TODO(bmeurer): Bit 10 is available for free use. :-)
+  class ICStateField : public BitField<InlineCacheState, 0, 4> {};
+  class TypeField : public BitField<StubType, 4, 1> {};
+  class CacheHolderField : public BitField<CacheHolderFlag, 5, 2> {};
+  class KindField : public BitField<Kind, 7, 4> {};
   class ExtraICStateField: public BitField<ExtraICState, 11,
       PlatformSmiTagging::kSmiValueSize - 11 + 1> {};  // NOLINT

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to