-
Notifications
You must be signed in to change notification settings - Fork 140
/
Copy pathProfiling.c
152 lines (135 loc) · 5.8 KB
/
Profiling.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*******************************************************************************
* Copyright IBM Corp. and others 2016
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution
* and is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception [1] and GNU General Public
* License, version 2 with the OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "omr.h"
#include "omrprofiler.h"
void ex_omr_checkSampleStack(OMR_VMThread *omrVMThread, const void *context);
void ex_omr_insertMethodEntryInMethodDictionary(OMR_VM *omrVM, const void *method);
static void ex_omr_sampleStack(OMR_VMThread *omrVMThread, const void *context);
#define EX_OMR_SAMPLESTACK_BACKOFF_MAX 10
#define EX_OMR_SAMPLESTACK_BACKOFF_TIMER_DECR 1
#define EX_OMR_PROF_METHOD_NAME_IDX 0
#define EX_OMR_PROF_FILE_NAME_IDX 1
#define EX_OMR_PROF_LINE_NUMBER_IDX 2
#define EX_METHOD_PROPERTY_COUNT 3
static const char *methodPropertyNames[EX_METHOD_PROPERTY_COUNT] = {
"methodName",
"fileName",
"lineNumber"
};
typedef struct EX_OMR_MethodDictionaryEntry {
const void *key;
const char *propertyValues[EX_METHOD_PROPERTY_COUNT];
} EX_OMR_MethodDictionaryEntry;
int
OMR_Glue_GetMethodDictionaryPropertyNum(void)
{
return EX_METHOD_PROPERTY_COUNT;
}
const char * const *
OMR_Glue_GetMethodDictionaryPropertyNames(void)
{
return methodPropertyNames;
}
/**
* This is an example of how the language runtime can iterate the omrVMThread's language callstack.
*
* Iterate from top to bottom. For the top-most stack frame, call omr_ras_sampleStackTraceStart()
* with the frame's method key. For each successive stack frame, call omr_ras_sampleStackTraceContinue()
* with the frame's method key.
*
* The method key must be the same as the key value that was used to insert the method in the method dictionary
* by omr_ras_insertMethodDictionary(). The context represents a language-specific data structure which
* contains the callstack's method keys for each stack frame.
*
* This function is only an example, and may be completely customized by the language runtime. It
* may be omitted if method profiling is not implemented.
*/
static void
ex_omr_sampleStack(OMR_VMThread *omrVMThread, const void *context)
{
#if 0
omr_ras_sampleStackTraceStart(omrVMThread, /* method key from top-most stack frame */);
For each successive stack frame:
omr_ras_sampleStackTraceContinue(omrVMThread, /* method key from stack frame */);
#endif
}
/**
* This is an example of how the language runtime can sample callstacks to produce method profiles.
*
* This function should be called periodically by the interpreter to sample the currently running
* thread's stack. If a JIT is implemented, then JITted code may also need to call this function
* periodically.
*
* In this example, a backoff counter is used to control the sampling frequency and restrict the
* overhead of callstack sampling. The context parameter represents a language-specific data structure
* containing the current callstack, such as the current thread.
*
* This function is only an example, and may be completely customized by the language runtime. It
* may be omitted if method profiling is not implemented.
*/
void
ex_omr_checkSampleStack(OMR_VMThread *omrVMThread, const void *context)
{
if (0 == omrVMThread->_sampleStackBackoff) {
omrVMThread->_sampleStackBackoff = EX_OMR_SAMPLESTACK_BACKOFF_MAX;
if (omr_ras_sampleStackEnabled()) {
ex_omr_sampleStack(omrVMThread, context);
}
}
if (EX_OMR_SAMPLESTACK_BACKOFF_TIMER_DECR > omrVMThread->_sampleStackBackoff) {
omrVMThread->_sampleStackBackoff = 0;
} else {
omrVMThread->_sampleStackBackoff -= EX_OMR_SAMPLESTACK_BACKOFF_TIMER_DECR;
}
}
/**
* This is an example of how the language runtime can insert a method entry into the method
* dictionary.
*
* Method dictionary entries are needed to provide the names and locations of methods that
* are sampled (see omr_ras_sampleStackTraceStart(), omr_ras_sampleStackTraceContinue()).
* The method parameter represents a language-specific data structure which contains the
* properties for the method entry.
*
* This function is only an example, and may be completely customized by the language runtime.
* It may be omitted if method profiling is not implemented.
*/
void
ex_omr_insertMethodEntryInMethodDictionary(OMR_VM *omrVM, const void *method)
{
omr_error_t rc = OMR_ERROR_NONE;
if (NULL != omrVM->_methodDictionary) {
EX_OMR_MethodDictionaryEntry tempEntry;
memset(&tempEntry, 0, sizeof(tempEntry));
tempEntry.key = method;
/* These properties should be extracted from the language-specific method structure. */
tempEntry.propertyValues[EX_OMR_PROF_METHOD_NAME_IDX] = "exampleMethod";
tempEntry.propertyValues[EX_OMR_PROF_FILE_NAME_IDX] = "exampleFile";
tempEntry.propertyValues[EX_OMR_PROF_LINE_NUMBER_IDX] = "1";
rc = omr_ras_insertMethodDictionary(omrVM, (OMR_MethodDictionaryEntry *)&tempEntry);
if (OMR_ERROR_NONE != rc) {
fprintf(stderr, "omr_insertMethodEntryInMethodDictionary failed.\n");
}
}
}