23
23
#include < string.h>
24
24
#include < sys/syscall.h>
25
25
26
+ #include " counters.h"
27
+ #include " tsc.h"
28
+
26
29
#ifdef __APPLE__
27
30
#define REG (l, m ) _ucontext->uc_mcontext->__ss.__##m
28
31
#else
@@ -57,6 +60,7 @@ void StackFrame::ret() { pc() = link(); }
57
60
58
61
bool StackFrame::unwindStub (instruction_t *entry, const char *name,
59
62
uintptr_t &pc, uintptr_t &sp, uintptr_t &fp) {
63
+ const u64 startTime = TSC::ticks ();
60
64
instruction_t *ip = (instruction_t *)pc;
61
65
if (ip == entry || *ip == 0xd65f03c0 || strncmp (name, " itable" , 6 ) == 0 ||
62
66
strncmp (name, " vtable" , 6 ) == 0 ||
@@ -67,6 +71,12 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
67
71
strcmp (name, " atomic entry points" ) == 0 ||
68
72
strcmp (name, " InlineCacheBuffer" ) == 0 ) {
69
73
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
+ }
70
80
return true ;
71
81
} else if (strcmp (name, " forward_copy_longs" ) == 0 ||
72
82
strcmp (name, " backward_copy_longs" ) == 0
@@ -83,6 +93,12 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
83
93
// When cstack=vm, unwind stub frames one by one
84
94
pc = link ();
85
95
}
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
+ }
86
102
return true ;
87
103
} else if (entry != NULL && entry[0 ] == 0xa9bf7bfd ) {
88
104
// The stub begins with
@@ -91,11 +107,23 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
91
107
if (ip == entry + 1 ) {
92
108
sp += 16 ;
93
109
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
+ }
94
116
return true ;
95
117
} else if (entry[1 ] == 0x910003fd && withinCurrentStack (fp)) {
96
118
sp = fp + 16 ;
97
119
fp = ((uintptr_t *)sp)[-2 ];
98
120
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
+ }
99
127
return true ;
100
128
}
101
129
} else if (strncmp (name, " indexof_linear_" , 15 ) == 0 &&
@@ -104,8 +132,20 @@ bool StackFrame::unwindStub(instruction_t *entry, const char *name,
104
132
// Entry and exit are covered by the very first 'if', in all other cases SP is 4 words off.
105
133
sp += 32 ;
106
134
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 ;
108
142
}
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
+ }
109
149
return false ;
110
150
}
111
151
@@ -117,6 +157,7 @@ static inline bool isEntryBarrier(instruction_t *ip) {
117
157
118
158
bool StackFrame::unwindCompiled (NMethod *nm, uintptr_t &pc, uintptr_t &sp,
119
159
uintptr_t &fp) {
160
+ const u64 startTime = TSC::ticks ();
120
161
instruction_t *ip = (instruction_t *)pc;
121
162
instruction_t *entry = (instruction_t *)nm->entry ();
122
163
if ((*ip & 0xffe07fff ) == 0xa9007bfd ) {
@@ -125,34 +166,71 @@ bool StackFrame::unwindCompiled(NMethod *nm, uintptr_t &pc, uintptr_t &sp,
125
166
unsigned int offset = (*ip >> 12 ) & 0x1f8 ;
126
167
sp += offset + 16 ;
127
168
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
+ }
128
175
} else if (ip > entry && ip[0 ] == 0x910003fd && ip[-1 ] == 0xa9bf7bfd ) {
129
176
// stp x29, x30, [sp, #-16]!
130
177
// mov x29, sp
131
178
sp += 16 ;
132
179
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
+ }
133
186
} else if (ip > entry + 3 && !nm->isFrameCompleteAt (ip) &&
134
187
(isEntryBarrier (ip) || isEntryBarrier (ip + 1 ))) {
135
188
// Frame should be complete at this point
136
189
sp += nm->frameSize () * sizeof (void *);
137
190
fp = ((uintptr_t *)sp)[-2 ];
138
191
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
+ }
139
198
} else {
140
199
// Just try
141
200
pc = link ();
142
201
}
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
+ }
143
208
return true ;
144
209
}
145
210
146
211
bool StackFrame::unwindAtomicStub (const void *& pc) {
147
212
// VM threads may call generated atomic stubs, which are not normally walkable
213
+ const u64 startTime = TSC::ticks ();
148
214
const void * lr = (const void *)link ();
149
215
if (VMStructs::libjvm ()->contains (lr)) {
150
216
NMethod* nm = CodeHeap::findNMethod (pc);
151
217
if (nm != NULL && strncmp (nm->name (), " Stub" , 4 ) == 0 ) {
152
218
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
+ }
153
225
return true ;
154
226
}
155
227
}
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
+ }
156
234
return false ;
157
235
}
158
236
0 commit comments