Tracing Inline Cache Misses using V8 standalone

236 views
Skip to first unread message

Malek Musleh

unread,
Feb 9, 2015, 6:55:57 PM2/9/15
to v8-u...@googlegroups.com
Hi,

I was wondering if there is a way to trace, or count Inline Cache Misses when running a benchmark using v8 standalone.
I know there exists the --trace-ic flag, but I want to determine what is the IC miss rate, and specifically what is getting hit/missed.

That traceflag does tell me when a IC entry is patched (due to an IC miss) but that doesn't cover all instances of IC misses.

Any help would be appreciated.

Thanks,

Malek

Jakob Kummerow

unread,
Feb 10, 2015, 4:12:06 AM2/10/15
to v8-u...@googlegroups.com
--trace-ic is the only IC tracing flag that I'm aware of. I've never had the impression that it lacks coverage. Is there a specific kind of IC miss events that you think it's not covering?


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

Malek Musleh

unread,
Feb 10, 2015, 12:02:40 PM2/10/15
to v8-u...@googlegroups.com
Actually, I was hoping for something with a little more clarity, e.g. simple hit/miss ratio for each of ICs, or better understanding what the traces mean:

Here is an example run:

/home/musleh/V8/v8/out/x64.release/shell --trace-ic run.js >& inlinecache_trace_all

1)
So I presume where it prints "patching.." indicates an IC miss:

[CompareIC in ~ConfigureTemplateInstance+1367 at native apinatives.js:68 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#LT @ 0x28b1cf730d01]
[  patching ic at 0x28b1cf762ff3, test=0x28b1cf762ff7, delta=21

2)
And to see a IC hit would be something like a CompareIC followed directly by a LoadIC?

[CompareIC in ~Instantiate+171 at native apinatives.js:14 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#EQ_STRICT @ 0x28b1cf7611c1]
[LoadIC in ~Instantiate+291 at native apinatives.js:15 (0->.) 0x1b54a19209c9 <String[19]: InstantiateFunction>]
[LoadIC in ~InstantiateFunction+53 at native apinatives.js:32 (0->.) 0x1b54a1922131 <String[17]: kApiFunctionCache>]

3) 

Are there cases where there is an IC miss, but the IC does not get patched?

short snippit below:

[ToBooleanStub: (None)=>(Bool)]
[CompareIC in ~Instantiate+171 at native apinatives.js:14 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#EQ_STRICT @ 0x28b1cf7611c1]
[LoadIC in ~Instantiate+291 at native apinatives.js:15 (0->.) 0x1b54a19209c9 <String[19]: InstantiateFunction>]
[LoadIC in ~InstantiateFunction+53 at native apinatives.js:32 (0->.) 0x1b54a1922131 <String[17]: kApiFunctionCache>]
[ToBooleanStub: (None)=>(Bool)]
[ToBooleanStub: (None)=>(Bool)]
[BinaryOpIC(BIT_AND:None*None->None) => (BIT_AND:Smi*Smi->Smi) @ 0x28b1cf708941 <- ~InstantiateFunction+453 at native apinatives.js:40]
[ToBooleanStub: (None)=>(Smi)]
[LoadIC in ~InstantiateFunction+607 at native apinatives.js:43 (0->.) 0x1b54a1922679 <String[11]: Instantiate>]
[CompareIC in ~Instantiate+223 at native apinatives.js:16 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#EQ_STRICT @ 0x28b1cf7611c1]
[LoadIC in ~Instantiate+542 at native apinatives.js:23 (0->.) 0x1b54a1922679 <String[11]: Instantiate>]
[LoadIC in ~Instantiate+291 at native apinatives.js:15 (.->1) 0x1b54a19209c9 <String[19]: InstantiateFunction>]
[LoadIC in ~InstantiateFunction+53 at native apinatives.js:32 (.->1) 0x1b54a1922131 <String[17]: kApiFunctionCache>]
[BinaryOpIC(BIT_AND:None*None->None) => (BIT_AND:Smi*Smi->Smi) @ 0x28b1cf708941 <- ~InstantiateFunction+978 at native apinatives.js:52]
[ToBooleanStub: (None)=>(Smi)]
[KeyedStoreIC in ~InstantiateFunction+1018 at native apinatives.js:53 (0->1.GROW) 6]
[LoadIC in ~InstantiateFunction+1037 at native apinatives.js:54 (0->.) 0x1b54a1928339 <String[25]: ConfigureTemplateInstance>]
[ToBooleanStub: (None)=>(Undefined)]
[ToBooleanStub: (None)=>(Smi)]
[KeyedLoadIC in ~InstantiateFunction+1198 at native apinatives.js:61 (0->1) 6]
[ToBooleanStub: (Undefined)=>(Undefined,SpecObject)]
[KeyedLoadIC in ~ConfigureTemplateInstance+1336 at native apinatives.js:68 (0->1) 0]
[CompareIC in ~ConfigureTemplateInstance+1367 at native apinatives.js:68 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#LT @ 0x28b1cf730d01]
[  patching ic at 0x28b1cf762ff3, test=0x28b1cf762ff7, delta=21

Jakob Kummerow

unread,
Feb 10, 2015, 5:27:23 PM2/10/15
to v8-u...@googlegroups.com
There is no tracing for IC hits.

With a few exceptions, every line of --trace-ic output indicates one IC miss.

With a few exceptions, every IC that misses will be patched.

More specifically:

On Tue, Feb 10, 2015 at 6:02 PM, Malek Musleh <malek....@gmail.com> wrote:
1)
So I presume where it prints "patching.." indicates an IC miss:

[CompareIC in ~ConfigureTemplateInstance+1367 at native apinatives.js:68 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#LT @ 0x28b1cf730d01]

This line means that a CompareIC missed and was patched (from UNINITIALIZED to SMI state).
 
[  patching ic at 0x28b1cf762ff3, test=0x28b1cf762ff7, delta=21

"[  patching ic at ...]" is the line that's printed when an "inline smi case" is patched. That's a special performance improvement for some kinds of ICs.

2)
And to see a IC hit would be something like a CompareIC followed directly by a LoadIC?

[CompareIC in ~Instantiate+171 at native apinatives.js:14 ((UNINITIALIZED+UNINITIALIZED=UNINITIALIZED)->(SMI+SMI=SMI))#EQ_STRICT @ 0x28b1cf7611c1]

This is a CompareIC miss + patch.
 
[LoadIC in ~Instantiate+291 at native apinatives.js:15 (0->.) 0x1b54a19209c9 <String[19]: InstantiateFunction>]

This is a LoadIC miss + patch.
 
[LoadIC in ~InstantiateFunction+53 at native apinatives.js:32 (0->.) 0x1b54a1922131 <String[17]: kApiFunctionCache>]

This is another LoadIC miss + patch. 

3) 

Are there cases where there is an IC miss, but the IC does not get patched?

Not in the snippet below. When you see an "N->N" transition, the IC wasn't actually patched, there was only a new handler getting compiled and added to the stub cache (which has the same effect as patching insofar as it will avoid future misses for the same situation).

Malek Musleh

unread,
Feb 10, 2015, 6:55:00 PM2/10/15
to v8-u...@googlegroups.com
Could you pinpoint the location (highest level routine) where the IC
is accessed, and thus determined if its a hit/miss. That way, I can
create my own flag/statistic to determine the miss ratio.

Looking at the code, I see that an IC_Miss from ic/ic.cc is invoked
from is-<arch>.cc
from the ::GenerateMiss routine, one for each IC. However, its not
clear to me from where GenerateMiss is called, that I can determine
hit/miss. In other words, I am looking for something like

if(hit) {
return;
} else {
GenerateMiss()
}

Rather, what I see is something like the following code snippet where
GenerateMiss() is called after __bind() and after a ret(). In this
case, I presume it would be a hit if it did actually call Ret() and
not continue down to __bind() & GenerateMiss()


void StoreIC::GenerateNormal(MacroAssembler* masm) {
Label miss;
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
Register dictionary = r3;
DCHECK(receiver.is(r1));
DCHECK(name.is(r2));
DCHECK(value.is(r0));

__ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));

GenerateDictionaryStore(masm, &miss, dictionary, name, value, r4, r5);
Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->store_normal_hit(), 1, r4, r5);
__ Ret();

__ bind(&miss);
__ IncrementCounter(counters->store_normal_miss(), 1, r4, r5);
GenerateMiss(masm);
> You received this message because you are subscribed to a topic in the
> Google Groups "v8-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/v8-users/754yrynh8so/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to

Jakob Kummerow

unread,
Feb 11, 2015, 4:31:05 AM2/11/15
to v8-u...@googlegroups.com
On Wed, Feb 11, 2015 at 12:54 AM, Malek Musleh <malek....@gmail.com> wrote:
Could you pinpoint the location (highest level routine) where the IC
is accessed, and thus determined if its a hit/miss.

There is no such location. That's kind of the point of having ICs. C++ code is only called when the generated handler that's been installed previously can't handle something. This event is called an "IC miss".
 
That way, I can
create my own flag/statistic to determine the miss ratio.

Looking at the code, I see that an IC_Miss from ic/ic.cc is invoked
from is-<arch>.cc
from the ::GenerateMiss routine, one for each IC.

Not quite. GenerateMiss doesn't invoke IC_Miss. It generates code that will invoke the miss handler (hence the name GenerateMiss).
Reply all
Reply to author
Forward
0 new messages