2323#include  < string.h> 
2424#include  < sys/syscall.h> 
2525
26+ #include  " counters.h" 
27+ #include  " tsc.h" 
28+ 
2629#ifdef  __APPLE__
2730#define  REG (l, m ) _ucontext->uc_mcontext->__ss.__##m
2831#else 
@@ -57,6 +60,7 @@ void StackFrame::ret() { pc() = link(); }
5760
5861bool  StackFrame::unwindStub (instruction_t  *entry, const  char  *name,
5962                            uintptr_t  &pc, uintptr_t  &sp, uintptr_t  &fp) {
63+   const  u64  startTime = TSC::ticks ();
6064  instruction_t  *ip = (instruction_t  *)pc;
6165  if  (ip == entry || *ip == 0xd65f03c0  || strncmp (name, " itable"  , 6 ) == 0  ||
6266      strncmp (name, " vtable"  , 6 ) == 0  ||
@@ -67,6 +71,12 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
6771      strcmp (name, " atomic entry points"  ) == 0  ||
6872      strcmp (name, " InlineCacheBuffer"  ) == 0 ) {
6973    pc = link ();
74+ 
75+     const  u64  endTime = TSC::ticks ();
76+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
77+     if  (duration > 1 ) {
78+       Counters::increment (UNWINDING_STUB_TIME, duration);
79+     }
7080    return  true ;
7181  } else  if  (strcmp (name, " forward_copy_longs"  ) == 0  ||
7282             strcmp (name, " backward_copy_longs"  ) == 0 
@@ -83,6 +93,12 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
8393      //  When cstack=vm, unwind stub frames one by one
8494      pc = link ();
8595    }
96+ 
97+     const  u64  endTime = TSC::ticks ();
98+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
99+     if  (duration > 1 ) {
100+       Counters::increment (UNWINDING_STUB_TIME, duration);
101+     }
86102    return  true ;
87103  } else  if  (entry != NULL  && entry[0 ] == 0xa9bf7bfd ) {
88104    //  The stub begins with
@@ -91,11 +107,23 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
91107    if  (ip == entry + 1 ) {
92108      sp += 16 ;
93109      pc = ((uintptr_t  *)sp)[-1 ];
110+ 
111+       const  u64  endTime = TSC::ticks ();
112+       const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
113+       if  (duration > 1 ) {
114+         Counters::increment (UNWINDING_STUB_TIME, duration);
115+       }
94116      return  true ;
95117    } else  if  (entry[1 ] == 0x910003fd  && withinCurrentStack (fp)) {
96118      sp = fp + 16 ;
97119      fp = ((uintptr_t  *)sp)[-2 ];
98120      pc = ((uintptr_t  *)sp)[-1 ];
121+ 
122+       const  u64  endTime = TSC::ticks ();
123+       const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
124+       if  (duration > 1 ) {
125+         Counters::increment (UNWINDING_STUB_TIME, duration);
126+       }
99127      return  true ;
100128    }
101129  } else  if  (strncmp (name, " indexof_linear_"  , 15 ) == 0  &&
@@ -104,8 +132,20 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
104132            //  Entry and exit are covered by the very first 'if', in all other cases SP is 4 words off.
105133            sp += 32 ;
106134            pc = link ();
107-             return  true ;
135+ 
136+     const  u64  endTime = TSC::ticks ();
137+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
138+     if  (duration > 1 ) {
139+       Counters::increment (UNWINDING_STUB_TIME, duration);
140+     }
141+     return  true ;
108142   }
143+ 
144+   const  u64  endTime = TSC::ticks ();
145+   const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
146+   if  (duration > 1 ) {
147+     Counters::increment (UNWINDING_STUB_TIME, duration);
148+   }
109149  return  false ;
110150}
111151
@@ -117,6 +157,7 @@ static inline bool isEntryBarrier(instruction_t *ip) {
117157
118158bool  StackFrame::unwindCompiled (NMethod *nm, uintptr_t  &pc, uintptr_t  &sp,
119159                                uintptr_t  &fp) {
160+   const  u64  startTime = TSC::ticks ();
120161  instruction_t  *ip = (instruction_t  *)pc;
121162  instruction_t  *entry = (instruction_t  *)nm->entry ();
122163  if  ((*ip & 0xffe07fff ) == 0xa9007bfd ) {
@@ -125,34 +166,71 @@ bool StackFrame::unwindCompiled(NMethod *nm, uintptr_t &pc, uintptr_t &sp,
125166    unsigned  int  offset = (*ip >> 12 ) & 0x1f8 ;
126167    sp += offset + 16 ;
127168    pc = link ();
169+ 
170+     const  u64  endTime = TSC::ticks ();
171+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
172+     if  (duration > 1 ) {
173+       Counters::increment (UNWINDING_COMPILED_TIME, duration);
174+     }
128175  } else  if  (ip > entry && ip[0 ] == 0x910003fd  && ip[-1 ] == 0xa9bf7bfd ) {
129176    //  stp  x29, x30, [sp, #-16]!
130177    //  mov  x29, sp
131178    sp += 16 ;
132179    pc = ((uintptr_t  *)sp)[-1 ];
180+ 
181+     const  u64  endTime = TSC::ticks ();
182+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
183+     if  (duration > 1 ) {
184+       Counters::increment (UNWINDING_COMPILED_TIME, duration);
185+     }
133186  } else  if  (ip > entry + 3  && !nm->isFrameCompleteAt (ip) &&
134187             (isEntryBarrier (ip) || isEntryBarrier (ip + 1 ))) {
135188    //  Frame should be complete at this point
136189    sp += nm->frameSize () * sizeof (void  *);
137190    fp = ((uintptr_t  *)sp)[-2 ];
138191    pc = ((uintptr_t  *)sp)[-1 ];
192+ 
193+     const  u64  endTime = TSC::ticks ();
194+     const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
195+     if  (duration > 1 ) {
196+       Counters::increment (UNWINDING_COMPILED_TIME, duration);
197+     }
139198  } else  {
140199    //  Just try
141200    pc = link ();
142201  }
202+ 
203+   const  u64  endTime = TSC::ticks ();
204+   const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
205+   if  (duration > 1 ) {
206+     Counters::increment (UNWINDING_COMPILED_TIME, duration);
207+   }
143208  return  true ;
144209}
145210
146211bool  StackFrame::unwindAtomicStub (const  void *& pc) {
147212  //  VM threads may call generated atomic stubs, which are not normally walkable
213+   const  u64  startTime = TSC::ticks ();
148214  const  void * lr = (const  void *)link ();
149215  if  (VMStructs::libjvm ()->contains (lr)) {
150216    NMethod* nm = CodeHeap::findNMethod (pc);
151217    if  (nm != NULL  && strncmp (nm->name (), " Stub"  , 4 ) == 0 ) {
152218      pc = lr;
219+ 
220+       const  u64  endTime = TSC::ticks ();
221+       const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
222+       if  (duration > 1 ) {
223+         Counters::increment (UNWINDING_ATOMIC_STUB_TIME, duration);
224+       }
153225      return  true ;
154226    }
155227  }
228+ 
229+   const  u64  endTime = TSC::ticks ();
230+   const  u64  duration = TSC::ticks_to_millis (endTime - startTime);
231+   if  (duration > 1 ) {
232+     Counters::increment (UNWINDING_ATOMIC_STUB_TIME, duration);
233+   }
156234  return  false ;
157235}
158236
0 commit comments