jdk

Форк
0
311 строк · 9.3 Кб
1
/*
2
 * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 *
23
 */
24

25
#include "precompiled.hpp"
26
#include "classfile/vmSymbols.hpp"
27
#include "jni.h"
28
#include "jvm.h"
29
#include "memory/allocation.inline.hpp"
30
#include "memory/resourceArea.hpp"
31
#include "oops/oop.inline.hpp"
32
#include "runtime/interfaceSupport.inline.hpp"
33
#include "runtime/perfData.inline.hpp"
34
#include "runtime/perfMemory.hpp"
35

36
/*
37
 *      Implementation of class jdk.internal.perf.Perf
38
 */
39

40

41
#define PERF_ENTRY(result_type, header) \
42
  JVM_ENTRY(result_type, header)
43

44
#define PERF_END JVM_END
45

46
#define PerfWrapper(arg) /* Unimplemented at this time */
47

48
static char* jstr_to_utf(JNIEnv *env, jstring str, TRAPS) {
49

50
  char* utfstr = nullptr;
51

52
  if (str == nullptr) {
53
    THROW_0(vmSymbols::java_lang_NullPointerException());
54
    //throw_new(env,"NullPointerException");
55
  }
56

57
  int len = env->GetStringUTFLength(str);
58
  int unicode_len = env->GetStringLength(str);
59

60
  utfstr = NEW_RESOURCE_ARRAY(char, len + 1);
61

62
  env->GetStringUTFRegion(str, 0, unicode_len, utfstr);
63

64
  return utfstr;
65
}
66

67
PERF_ENTRY(jobject, Perf_Attach(JNIEnv *env, jobject unused, int vmid))
68

69
  PerfWrapper("Perf_Attach");
70

71
  char* address = 0;
72
  size_t capacity = 0;
73

74
  // attach to the PerfData memory region for the specified VM
75
  PerfMemory::attach(vmid, &address, &capacity, CHECK_NULL);
76

77
  {
78
    ThreadToNativeFromVM ttnfv(thread);
79
    return env->NewDirectByteBuffer(address, (jlong)capacity);
80
  }
81

82
PERF_END
83

84
PERF_ENTRY(void, Perf_Detach(JNIEnv *env, jobject unused, jobject buffer))
85

86
  PerfWrapper("Perf_Detach");
87

88
  if (!UsePerfData) {
89
    // With -XX:-UsePerfData, detach is just a NOP
90
    return;
91
  }
92

93
  void* address = 0;
94
  jlong capacity = 0;
95

96
  // get buffer address and capacity
97
  {
98
   ThreadToNativeFromVM ttnfv(thread);
99
   address = env->GetDirectBufferAddress(buffer);
100
   capacity = env->GetDirectBufferCapacity(buffer);
101
  }
102

103
  PerfMemory::detach((char*)address, capacity);
104

105
PERF_END
106

107
PERF_ENTRY(jobject, Perf_CreateLong(JNIEnv *env, jobject perf, jstring name,
108
           int variability, int units, jlong value))
109

110
  PerfWrapper("Perf_CreateLong");
111

112
  char* name_utf = nullptr;
113

114
  if (units <= 0 || units > PerfData::U_Last) {
115
    debug_only(warning("unexpected units argument, units = %d", units));
116
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
117
  }
118

119
  ResourceMark rm;
120

121
  {
122
    ThreadToNativeFromVM ttnfv(thread);
123

124
    name_utf = jstr_to_utf(env, name, CHECK_NULL);
125
  }
126

127
  PerfLong* pl = nullptr;
128

129
  // check that the PerfData name doesn't already exist
130
  if (PerfDataManager::exists(name_utf)) {
131
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfLong name already exists");
132
  }
133

134
  switch(variability) {
135
  case PerfData::V_Constant:
136
    pl = PerfDataManager::create_long_constant(NULL_NS, (char *)name_utf,
137
                                               (PerfData::Units)units, value,
138
                                               CHECK_NULL);
139
    break;
140

141
  case PerfData::V_Monotonic:
142
    pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf,
143
                                               (PerfData::Units)units, value,
144
                                               CHECK_NULL);
145
    break;
146

147
  case PerfData::V_Variable:
148
    pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf,
149
                                              (PerfData::Units)units, value,
150
                                              CHECK_NULL);
151
    break;
152

153
  default: /* Illegal Argument */
154
    debug_only(warning("unexpected variability value: %d", variability));
155
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
156
    break;
157
  }
158

159
  long* lp = (long*)pl->get_address();
160

161
  {
162
    ThreadToNativeFromVM ttnfv(thread);
163
    return env->NewDirectByteBuffer(lp, sizeof(jlong));
164
  }
165

166
PERF_END
167

168
PERF_ENTRY(jobject, Perf_CreateByteArray(JNIEnv *env, jobject perf,
169
                                         jstring name, jint variability,
170
                                         jint units, jbyteArray value,
171
                                         jint maxlength))
172

173
  PerfWrapper("Perf_CreateByteArray");
174

175
  // check for valid byte array objects
176
  if (name == nullptr || value == nullptr) {
177
    THROW_0(vmSymbols::java_lang_NullPointerException());
178
  }
179

180
  // check for valid variability classification
181
  if (variability != PerfData::V_Constant &&
182
      variability != PerfData::V_Variable) {
183
    debug_only(warning("unexpected variability value: %d", variability));
184
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
185
  }
186

187
  // check for valid units
188
  if (units != PerfData::U_String) {
189
    // only String based ByteArray objects are currently supported
190
    debug_only(warning("unexpected units value: %d", variability));
191
    THROW_0(vmSymbols::java_lang_IllegalArgumentException());
192
  }
193

194
  int value_length;
195
  char* name_utf = nullptr;
196
  jbyte* value_local = nullptr;
197

198
  ResourceMark rm;
199

200
  {
201
    ThreadToNativeFromVM ttnfv(thread);
202

203
    name_utf = jstr_to_utf(env, name, CHECK_NULL);
204

205
    value_length = env->GetArrayLength(value);
206

207
    value_local = NEW_RESOURCE_ARRAY(jbyte, value_length + 1);
208

209
    env->GetByteArrayRegion(value, 0, value_length, value_local);
210
  }
211

212
  // check that the counter name doesn't already exist
213
  if (PerfDataManager::exists((char*)name_utf)) {
214
    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "PerfByteArray name already exists");
215
  }
216

217
  PerfByteArray* pbv = nullptr;
218

219
  if (units == PerfData::U_String) {
220

221
    if (variability == PerfData::V_Constant) {
222
      // create the string constant
223
      pbv = PerfDataManager::create_string_constant(NULL_NS, (char*)name_utf,
224
                                                    (char*)value_local,
225
                                                    CHECK_NULL);
226

227
      assert(maxlength == value_length, "string constant length should be == maxlength");
228
      maxlength = value_length;
229
    }
230
    else {
231

232
      // create the string variable
233
      pbv = PerfDataManager::create_string_variable(NULL_NS, (char*)name_utf,
234
                                                    maxlength,
235
                                                    (char*)value_local,
236
                                                    CHECK_NULL);
237

238
     assert(maxlength >= value_length,"string variable length should be <= maxlength");
239
    }
240
  }
241

242
  char* cp = (char*)pbv->get_address();
243

244
  {
245
    ThreadToNativeFromVM ttnfv(thread);
246
    return env->NewDirectByteBuffer(cp, maxlength+1);
247
  }
248

249
PERF_END
250

251
PERF_ENTRY(jlong, Perf_HighResCounter(JNIEnv *env, jobject perf))
252

253
  PerfWrapper("Perf_HighResCounter");
254

255
  // this should be a method in java.lang.System. This value could
256
  // be acquired through access to a PerfData performance counter, but
257
  // doing so would require that the PerfData monitoring overhead be
258
  // incurred by all Java applications, which is unacceptable.
259

260
  return os::elapsed_counter();
261

262
PERF_END
263

264
PERF_ENTRY(jlong, Perf_HighResFrequency(JNIEnv *env, jobject perf))
265

266
  PerfWrapper("Perf_HighResFrequency");
267

268
  // this should be a method in java.lang.System. This value could
269
  // be acquired through access to a PerfData performance counter, but
270
  // doing so would require that the PerfData monitoring overhead be
271
  // incurred by all Java applications, which is unacceptable.
272

273
  return os::elapsed_frequency();
274

275
PERF_END
276

277
/// JVM_RegisterPerfMethods
278

279
#define CC (char*)  /*cast a literal from (const char*)*/
280
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
281
#define BB "Ljava/nio/ByteBuffer;"
282
#define JLS "Ljava/lang/String;"
283
#define CL_ARGS     CC "(" JLS "IIJ)" BB
284
#define CBA_ARGS    CC "(" JLS "II[BI)" BB
285

286
static JNINativeMethod perfmethods[] = {
287

288
  {CC "attach0",             CC "(I)" BB,         FN_PTR(Perf_Attach)},
289
  {CC "detach",              CC "(" BB ")V",      FN_PTR(Perf_Detach)},
290
  {CC "createLong",          CL_ARGS,             FN_PTR(Perf_CreateLong)},
291
  {CC "createByteArray",     CBA_ARGS,            FN_PTR(Perf_CreateByteArray)},
292
  {CC "highResCounter",      CC "()J",            FN_PTR(Perf_HighResCounter)},
293
  {CC "highResFrequency",    CC "()J",            FN_PTR(Perf_HighResFrequency)}
294
};
295

296
#undef CBA_ARGS
297
#undef CL_ARGS
298
#undef JLS
299
#undef BB
300
#undef FN_PTR
301
#undef CC
302

303
// This one function is exported, used by NativeLookup.
304
JVM_ENTRY(void, JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass))
305
  PerfWrapper("JVM_RegisterPerfMethods");
306
  {
307
    ThreadToNativeFromVM ttnfv(thread);
308
    int ok = env->RegisterNatives(perfclass, perfmethods, sizeof(perfmethods)/sizeof(JNINativeMethod));
309
    guarantee(ok == 0, "register perf natives");
310
  }
311
JVM_END
312

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.