| 77 | } |
| 78 | |
| 79 | void J9StackTraces::timerLoop() { |
| 80 | JNIEnv* jni = VM::attachThread("Async-profiler Sampler"); |
| 81 | storeRelease(_self_env, jni); |
| 82 | |
| 83 | jni->PushLocalFrame(64); |
| 84 | |
| 85 | jvmtiEnv* jvmti = VM::jvmti(); |
| 86 | char notification_buf[65536]; |
| 87 | std::map<void*, jthread> known_threads; |
| 88 | |
| 89 | int max_frames = _max_stack_depth + MAX_J9_NATIVE_FRAMES + RESERVED_FRAMES; |
| 90 | ASGCT_CallFrame* frames = (ASGCT_CallFrame*)malloc(max_frames * sizeof(ASGCT_CallFrame)); |
| 91 | jvmtiFrameInfoExtended* jvmti_frames = (jvmtiFrameInfoExtended*)malloc(max_frames * sizeof(jvmtiFrameInfoExtended)); |
| 92 | |
| 93 | while (true) { |
| 94 | ssize_t bytes = read(_pipe[0], notification_buf, sizeof(notification_buf)); |
| 95 | if (bytes <= 0) { |
| 96 | if (bytes < 0 && errno == EAGAIN) { |
| 97 | continue; |
| 98 | } |
| 99 | break; |
| 100 | } |
| 101 | |
| 102 | ssize_t ptr = 0; |
| 103 | while (ptr < bytes) { |
| 104 | J9StackTraceNotification* notif = (J9StackTraceNotification*)(notification_buf + ptr); |
| 105 | u64 start_time = TSC::ticks(); |
| 106 | |
| 107 | jthread thread = known_threads[notif->env]; |
| 108 | jint num_jvmti_frames; |
| 109 | if (thread == NULL || J9Ext::GetStackTraceExtended(thread, 0, _max_stack_depth, jvmti_frames, &num_jvmti_frames) != 0) { |
| 110 | jni->PopLocalFrame(NULL); |
| 111 | jni->PushLocalFrame(64); |
| 112 | |
| 113 | jint thread_count; |
| 114 | jthread* threads; |
| 115 | if (jvmti->GetAllThreads(&thread_count, &threads) == 0) { |
| 116 | known_threads.clear(); |
| 117 | for (jint i = 0; i < thread_count; i++) { |
| 118 | known_threads[J9Ext::GetJ9vmThread(threads[i])] = threads[i]; |
| 119 | } |
| 120 | jvmti->Deallocate((unsigned char*)threads); |
| 121 | } |
| 122 | |
| 123 | if ((thread = known_threads[notif->env]) == NULL || |
| 124 | J9Ext::GetStackTraceExtended(thread, 0, _max_stack_depth, jvmti_frames, &num_jvmti_frames) != 0) { |
| 125 | continue; |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | int num_frames = Profiler::instance()->convertNativeTrace(notif->num_frames, notif->addr, frames, EXECUTION_SAMPLE); |
| 130 | |
| 131 | for (int j = 0; j < num_jvmti_frames; j++) { |
| 132 | frames[num_frames].method_id = jvmti_frames[j].method; |
| 133 | frames[num_frames].bci = FrameType::encode(jvmti_frames[j].type, jvmti_frames[j].location); |
| 134 | num_frames++; |
| 135 | } |
| 136 |
nothing calls this directly
no test coverage detected