tools/perf/jvmti/libjvmti.c

Source file repositories/reference/linux-study-clean/tools/perf/jvmti/libjvmti.c

File Facts

System
Linux kernel
Corpus path
tools/perf/jvmti/libjvmti.c
Extension
.c
Size
11191 bytes
Lines
420
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (hdr->kind == JVMTI_CMLR_INLINE_INFO) {
			rec = (jvmtiCompiledMethodLoadInlineRecord *)hdr;
			nr_total += rec->numpcs;
		}
	}

	if (nr_total == 0)
		return JVMTI_ERROR_NOT_FOUND;

	/*
	 * Phase 2 -- allocate big enough line table
	 */
	*tab = calloc(nr_total, sizeof(**tab));
	if (!*tab)
		return JVMTI_ERROR_OUT_OF_MEMORY;

	for (hdr = compile_info; hdr != NULL; hdr = hdr->next) {
		if (hdr->kind == JVMTI_CMLR_INLINE_INFO) {
			rec = (jvmtiCompiledMethodLoadInlineRecord *)hdr;
			for (i = 0; i < rec->numpcs; i++) {
				c = rec->pcinfo + i;
                                /*
                                 * c->methods is the stack of inlined method calls
                                 * at c->pc. [0] is the leaf method. Caller frames
                                 * are ignored at the moment.
                                 */
				ret = do_get_line_number(jvmti, c->pc,
							 c->methods[0],
							 c->bcis[0],
							 *tab + lines_total);
				if (ret == JVMTI_ERROR_NONE)
					lines_total++;
			}
		}
	}
	*nr_lines = lines_total;
	return JVMTI_ERROR_NONE;
}
#else /* HAVE_JVMTI_CMLR */

static jvmtiError
get_line_numbers(jvmtiEnv *jvmti __maybe_unused, const void *compile_info __maybe_unused,
		 jvmti_line_info_t **tab __maybe_unused, int *nr_lines __maybe_unused)
{
	return JVMTI_ERROR_NONE;
}
#endif /* HAVE_JVMTI_CMLR */

static void
copy_class_filename(const char * class_sign, const char * file_name, char * result, size_t max_length)
{
	/*
	* Assume path name is class hierarchy, this is a common practice with Java programs
	*/
	if (*class_sign == 'L') {
		size_t j, i = 0;
		const char *p = strrchr(class_sign, '/');
		if (p) {
			/* drop the 'L' prefix and copy up to the final '/' */
			for (i = 0; i < (size_t)(p - class_sign); i++)
				result[i] = class_sign[i+1];
		}
		/*
		* append file name, we use loops and not string ops to avoid modifying
		* class_sign which is used later for the symbol name
		*/
		for (j = 0; i < (max_length - 1) && file_name && j < strlen(file_name); j++, i++)
			result[i] = file_name[j];

		result[i] = '\0';
	} else {
		/* fallback case */
		strlcpy(result, file_name, max_length);
	}
}

static jvmtiError
get_source_filename(jvmtiEnv *jvmti, jmethodID methodID, char ** buffer)
{
	jvmtiError ret;
	jclass decl_class;
	char *file_name = NULL;
	char *class_sign = NULL;
	char fn[PATH_MAX];
	size_t len;

	ret = (*jvmti)->GetMethodDeclaringClass(jvmti, methodID, &decl_class);
	if (ret != JVMTI_ERROR_NONE) {
		print_error(jvmti, "GetMethodDeclaringClass", ret);
		return ret;

Annotation

Implementation Notes