// List of methods that could be triggered by a GC. It isn't possible to control // when GCs happen especially in gcstress configs. So we ignore certain methods // that could be executed based on when GC occurs. staticconst std::string_view ignored_methods_list[] = { "java.lang.ref.ReferenceQueue add (Ljava/lang/ref/Reference;)V ReferenceQueue.java"
};
uint64_t ReadNumber(int num_bytes, uint8_t* header) {
uint64_t number = 0; for (int i = 0; i < num_bytes; i++) {
uint64_t c = header[i];
number += c << (i * 8);
} return number;
}
bool MethodInIgnoreList(const std::string& method_name) { for (const std::string_view& ignored_method : ignored_methods_list) { if (method_name.compare(ignored_method) == 0) { returntrue;
}
}
// Also ignore clinit methods. Classes maybe pre-initialized if they are a part of the image. if (method_name.find("<clinit>") != std::string::npos) { returntrue;
} returnfalse;
}
void PrintTraceEntry(const std::string& thread_name, const std::string& method_name, int event_type, int* current_depth,
std::string& ignored_method, int* ignored_method_depth) { bool ignore_trace_entry = false; if (ignored_method.empty()) { // Check if we need to ignore the method. if (MethodInIgnoreList(method_name)) {
CHECK_EQ(event_type, kMethodEntry);
ignored_method = method_name;
*ignored_method_depth = *current_depth;
ignore_trace_entry = true;
}
} else { // Check if the ignored method is exiting. if (MethodInIgnoreList(method_name) && *current_depth == *ignored_method_depth + 1) {
CHECK_NE(event_type, kMethodEntry);
ignored_method.clear();
}
ignore_trace_entry = true;
}
std::string entry; for (int i = 0; i < *current_depth; i++) {
entry.push_back('.');
} if (event_type == kMethodEntry) {
*current_depth += 1;
entry.append(".>> ");
} elseif (event_type == kMethodExitNormal) {
*current_depth -= 1;
entry.append("<< ");
} elseif (event_type == kMethodExitError) {
*current_depth -= 1;
entry.append("<<E ");
} else {
entry.append("?? ");
}
entry.append(thread_name);
entry.append(" ");
entry.append(method_name);
entry.append("\n"); if (!ignore_trace_entry) {
printf("%s", entry.c_str());
}
}
uint32_t thread_id = ReadNumber(4, header); int offset = 4; int num_records = ReadNumber(3, header + offset);
offset += 3; int total_size = ReadNumber(4, header + offset);
std::unique_ptr<uint8_t[]> buffer(new uint8_t[total_size]); if (!file->ReadFully(buffer.get(), total_size)) { returnfalse;
}
int current_depth = 0; if (current_depth_map.find(thread_id) != current_depth_map.end()) { // Get the current call stack depth. If it is the first method we are seeing on this thread // then this map wouldn't haven an entry we start with the depth of 0.
current_depth = current_depth_map[thread_id];
}
int ignored_method_depth = 0;
std::string ignored_method; if (ignored_method_map.find(thread_id) != ignored_method_map.end()) {
ignored_method = ignored_method_map[thread_id];
ignored_method_depth = ignored_method_depth_map[thread_id];
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.