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.