comparison src/share/vm/graal/graalCompilerToVM.cpp @ 14106:ca37cb080dad

reorganized graalCompilerToVM.cpp
author twisti
date Thu, 06 Mar 2014 22:45:25 -0800
parents f62c770c22be
children 800057208a2c
comparison
equal deleted inserted replaced
14105:f62c770c22be 14106:ca37cb080dad
55 JNIEXPORT result_type JNICALL c2v_ ## name signature { \ 55 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
56 TRACE_graal_3("CompilerToVM::" #name); \ 56 TRACE_graal_3("CompilerToVM::" #name); \
57 57
58 #define C2V_END } 58 #define C2V_END }
59 59
60 C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
61 methodHandle method = asMethod(metaspace_method);
62 ResourceMark rm;
63
64 int code_size = method->code_size();
65 jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
66
67 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
68 // iterate over all bytecodes and replace non-Java bytecodes
69
70 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
71 Bytecodes::Code code = s.code();
72 Bytecodes::Code raw_code = s.raw_code();
73 int bci = s.bci();
74 int len = s.instruction_size();
75
76 // Restore original byte code.
77 reconstituted_code[bci] = (jbyte) (s.is_wide()? Bytecodes::_wide : code);
78 if (len > 1) {
79 memcpy(&reconstituted_code[bci+1], s.bcp()+1, len-1);
80 }
81
82 if (len > 1) {
83 // Restore the big-endian constant pool indexes.
84 // Cf. Rewriter::scan_method
85 switch (code) {
86 case Bytecodes::_getstatic:
87 case Bytecodes::_putstatic:
88 case Bytecodes::_getfield:
89 case Bytecodes::_putfield:
90 case Bytecodes::_invokevirtual:
91 case Bytecodes::_invokespecial:
92 case Bytecodes::_invokestatic:
93 case Bytecodes::_invokeinterface:
94 case Bytecodes::_invokehandle: {
95 int cp_index = Bytes::get_native_u2((address) &reconstituted_code[bci + 1]);
96 Bytes::put_Java_u2((address) &reconstituted_code[bci + 1], (u2) cp_index);
97 break;
98 }
99
100 case Bytecodes::_invokedynamic:
101 int cp_index = Bytes::get_native_u4((address) &reconstituted_code[bci + 1]);
102 Bytes::put_Java_u4((address) &reconstituted_code[bci + 1], (u4) cp_index);
103 break;
104 }
105
106 // Not all ldc byte code are rewritten.
107 switch (raw_code) {
108 case Bytecodes::_fast_aldc: {
109 int cpc_index = reconstituted_code[bci + 1] & 0xff;
110 int cp_index = method->constants()->object_to_cp_index(cpc_index);
111 assert(cp_index < method->constants()->length(), "sanity check");
112 reconstituted_code[bci + 1] = (jbyte) cp_index;
113 break;
114 }
115
116 case Bytecodes::_fast_aldc_w: {
117 int cpc_index = Bytes::get_native_u2((address) &reconstituted_code[bci + 1]);
118 int cp_index = method->constants()->object_to_cp_index(cpc_index);
119 assert(cp_index < method->constants()->length(), "sanity check");
120 Bytes::put_Java_u2((address) &reconstituted_code[bci + 1], (u2) cp_index);
121 break;
122 }
123 }
124 }
125 }
126
127 env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
128
129 return result;
130 C2V_END
131
132 C2V_VMENTRY(jint, exceptionTableLength, (JNIEnv *, jobject, jlong metaspace_method))
133 ResourceMark rm;
134 methodHandle method = asMethod(metaspace_method);
135 return method->exception_table_length();
136 C2V_END
137
138 C2V_VMENTRY(jlong, exceptionTableStart, (JNIEnv *, jobject, jlong metaspace_method))
139 ResourceMark rm;
140 methodHandle method = asMethod(metaspace_method);
141 assert(method->exception_table_length() != 0, "should be handled in Java code");
142 return (jlong) (address) method->exception_table_start();
143 C2V_END
144
145 C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
146 // Analyze the method to see if monitors are used properly.
147 methodHandle method(THREAD, asMethod(metaspace_method));
148 {
149 EXCEPTION_MARK;
150 ResourceMark rm(THREAD);
151 GeneratePairingInfo gpi(method);
152 gpi.compute_map(CATCH);
153 if (!gpi.monitor_safe()) {
154 return false;
155 }
156 method->set_guaranteed_monitor_matching();
157 }
158 return true;
159 C2V_END
160
161 C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jclass holder_handle, jint slot))
162 oop java_class = JNIHandles::resolve(holder_handle);
163 Klass* holder = java_lang_Class::as_Klass(java_class);
164 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
165 return (jlong) (address) method();
166 }
167
168 C2V_VMENTRY(jlong, findUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method))
169 methodHandle method = asMethod(metaspace_method);
170 KlassHandle holder = method->method_holder();
171 assert(!holder->is_interface(), "should be handled in Java code");
172 ResourceMark rm;
173 MutexLocker locker(Compile_lock);
174 Method* ucm = Dependencies::find_unique_concrete_method(holder(), method());
175 return (jlong) (address) ucm;
176 C2V_END
177
178 C2V_VMENTRY(jlong, getKlassImplementor, (JNIEnv *, jobject, jlong metaspace_klass))
179 InstanceKlass* klass = (InstanceKlass*) asKlass(metaspace_klass);
180 return (jlong) (address) klass->implementor();
181 C2V_END
182
183 C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
184 methodHandle method = asMethod(metaspace_method);
185 InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
186 HotSpotResolvedJavaMethod::set_callerSensitive(hotspot_method, method->caller_sensitive());
187 HotSpotResolvedJavaMethod::set_forceInline(hotspot_method, method->force_inline());
188 HotSpotResolvedJavaMethod::set_dontInline(hotspot_method, method->dont_inline());
189 HotSpotResolvedJavaMethod::set_ignoredBySecurityStackWalk(hotspot_method, method->is_ignored_by_security_stack_walk());
190 C2V_END
191
192 C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
193 methodHandle method = asMethod(metaspace_method);
194 return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
195 C2V_END
196
197 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
198 methodHandle method = asMethod(metaspace_method);
199 return CompilerOracle::should_inline(method) || method->force_inline();
200 C2V_END
201
202 C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
203 nmethod* code = (asMethod(metaspace_method))->code();
204 return code == NULL ? 0 : code->insts_size();
205 C2V_END
206
207 C2V_VMENTRY(jlong, lookupType, (JNIEnv *env, jobject, jstring jname, jclass accessing_class, jboolean eagerResolve))
208 ResourceMark rm;
209 Handle name = JNIHandles::resolve(jname);
210 Symbol* class_name = java_lang_String::as_symbol(name, THREAD);
211 assert(class_name != NULL, "name to symbol creation failed");
212 assert(class_name->size() > 1, "primitive types should be handled in Java code");
213
214 Klass* resolved_klass = NULL;
215 Handle class_loader;
216 Handle protection_domain;
217 if (JNIHandles::resolve(accessing_class) != NULL) {
218 Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class));
219 class_loader = accessing_klass->class_loader();
220 protection_domain = accessing_klass->protection_domain();
221 }
222
223 if (eagerResolve) {
224 resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, THREAD);
225 } else {
226 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, THREAD);
227 }
228
229 return (jlong) (address) resolved_klass;
230 C2V_END
231
232 C2V_VMENTRY(jlong, lookupKlassByName, (JNIEnv *env, jobject, jstring name, jclass loading_class))
233 KlassHandle loading_klass = java_lang_Class::as_Klass(JNIHandles::resolve(loading_class));
234 Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
235 KlassHandle klass = GraalEnv::get_klass_by_name(loading_klass, name_symbol, false);
236 return (jlong) (address) klass();
237 C2V_END
238
239 C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
240 ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
241 oop result = NULL;
242 constantTag tag = cp->tag_at(index);
243 switch (tag.value()) {
244 case JVM_CONSTANT_String:
245 result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
246 break;
247 case JVM_CONSTANT_MethodHandle:
248 case JVM_CONSTANT_MethodHandleInError:
249 case JVM_CONSTANT_MethodType:
250 case JVM_CONSTANT_MethodTypeInError:
251 result = cp->resolve_constant_at(index, CHECK_NULL);
252 break;
253 default:
254 fatal(err_msg_res("unknown constant pool tag %s at cpi %d in %s", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string()));
255 }
256 return JNIHandles::make_local(THREAD, result);
257 C2V_END
258
259 C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
260 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
261 return cp->name_and_type_ref_index_at(index);
262 C2V_END
263
264 C2V_VMENTRY(jlong, lookupNameRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
265 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
266 return (jlong) (address) cp->name_ref_at(index);
267 C2V_END
268
269 C2V_VMENTRY(jlong, lookupSignatureRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
270 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
271 return (jlong) (address) cp->signature_ref_at(index);
272 C2V_END
273
274 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
275 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
276 return cp->klass_ref_index_at(index);
277 C2V_END
278
279 C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
280 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
281 KlassHandle loading_klass(cp->pool_holder());
282 bool is_accessible = false;
283 KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
284 if (klass.is_null()) {
285 // We have to lock the cpool to keep the oop from being resolved
286 // while we are accessing it.
287 MonitorLockerEx ml(cp->lock());
288 constantTag tag = cp->tag_at(index);
289 if (tag.is_klass()) {
290 // The klass has been inserted into the constant pool
291 // very recently.
292 return (jlong) CompilerToVM::tag_pointer(cp->resolved_klass_at(index));
293 } else if (tag.is_symbol()) {
294 return (jlong) CompilerToVM::tag_pointer(cp->symbol_at(index));
295 } else {
296 assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
297 return (jlong) CompilerToVM::tag_pointer(cp->unresolved_klass_at(index));
298 }
299 }
300 return (jlong) CompilerToVM::tag_pointer(klass());
301 C2V_END
302
303 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
304 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
305 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
306 return JNIHandles::make_local(THREAD, appendix_oop);
307 C2V_END
308
309 C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
310 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
311 instanceKlassHandle pool_holder(cp->pool_holder());
312 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
313 methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
314 return (jlong) (address) method();
315 C2V_END
316
317 C2V_VMENTRY(void, loadReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op))
318 ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
319 Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF);
320 if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray
321 && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w)
322 {
323 index = cp->remap_instruction_operand_from_cache(index);
324 }
325 constantTag tag = cp->tag_at(index);
326 if (tag.is_field_or_method()) {
327 index = cp->uncached_klass_ref_index_at(index);
328 tag = cp->tag_at(index);
329 }
330
331 if (tag.is_unresolved_klass() || tag.is_klass()) {
332 Klass* klass = cp->klass_at(index, CHECK);
333 if (klass->oop_is_instance()) {
334 InstanceKlass::cast(klass)->initialize(CHECK);
335 }
336 }
337 C2V_END
338
339 C2V_VMENTRY(jlong, resolveField, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
340 ResourceMark rm;
341 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
342 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
343 fieldDescriptor result;
344 LinkResolver::resolve_field_access(result, cp, index, Bytecodes::java_code(code), true, false, CHECK_0);
345 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
346 assert(info != NULL && info->length() == 2, "must be");
347 info->long_at_put(0, (jlong) result.access_flags().as_int());
348 info->long_at_put(1, (jlong) result.offset());
349 return (jlong) (address) result.field_holder();
350 C2V_END
351
352 C2V_VMENTRY(jlong, resolveMethod, (JNIEnv *, jobject, jlong metaspace_klass, jstring name, jstring signature))
353 Klass* klass = (Klass*) metaspace_klass;
354 Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
355 Symbol* signature_symbol = java_lang_String::as_symbol(JNIHandles::resolve(signature), THREAD);
356 return (jlong) (address) klass->lookup_method(name_symbol, signature_symbol);
357 C2V_END
358
359 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jlong metaspace_klass))
360 Klass* klass = (Klass*) metaspace_klass;
361 assert(klass != NULL, "method must not be called for primitive types");
362 return Dependencies::find_finalizable_subclass(klass) != NULL;
363 C2V_END
364
365 C2V_VMENTRY(jlong, getClassInitializer, (JNIEnv *, jobject, jlong metaspace_klass))
366 InstanceKlass* klass = (InstanceKlass*) metaspace_klass;
367 return (jlong) (address) klass->class_initializer();
368 C2V_END
369
370 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong addr))
371 address target_addr = (address) addr;
372 if (target_addr != 0x0) {
373 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
374 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
375 return MAX2(ABS(off_low), ABS(off_high));
376 }
377 return -1;
378 C2V_END
379
380
381 // helpers used to set fields in the HotSpotVMConfig object
382 jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
383 jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
384 if (id == NULL) {
385 fatal(err_msg("field not found: %s (%s)", name, sig));
386 }
387 return id;
388 }
389
390 C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jlong metaspace_method))
391 methodHandle method = asMethod(metaspace_method);
392 method->set_not_c1_compilable();
393 method->set_not_c2_compilable();
394 method->set_dont_inline(true);
395 C2V_END
396
397 extern "C" { 60 extern "C" {
398 extern VMStructEntry* gHotSpotVMStructs; 61 extern VMStructEntry* gHotSpotVMStructs;
399 extern uint64_t gHotSpotVMStructEntryTypeNameOffset; 62 extern uint64_t gHotSpotVMStructEntryTypeNameOffset;
400 extern uint64_t gHotSpotVMStructEntryFieldNameOffset; 63 extern uint64_t gHotSpotVMStructEntryFieldNameOffset;
401 extern uint64_t gHotSpotVMStructEntryTypeStringOffset; 64 extern uint64_t gHotSpotVMStructEntryTypeStringOffset;
420 83
421 extern VMLongConstantEntry* gHotSpotVMLongConstants; 84 extern VMLongConstantEntry* gHotSpotVMLongConstants;
422 extern uint64_t gHotSpotVMLongConstantEntryNameOffset; 85 extern uint64_t gHotSpotVMLongConstantEntryNameOffset;
423 extern uint64_t gHotSpotVMLongConstantEntryValueOffset; 86 extern uint64_t gHotSpotVMLongConstantEntryValueOffset;
424 extern uint64_t gHotSpotVMLongConstantEntryArrayStride; 87 extern uint64_t gHotSpotVMLongConstantEntryArrayStride;
88 }
89
90 // helpers used to set fields in the HotSpotVMConfig object
91 static jfieldID getFieldID(JNIEnv* env, jobject obj, const char* name, const char* sig) {
92 jfieldID id = env->GetFieldID(env->GetObjectClass(obj), name, sig);
93 if (id == NULL) {
94 fatal(err_msg("field not found: %s (%s)", name, sig));
95 }
96 return id;
425 } 97 }
426 98
427 C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config)) 99 C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config))
428 100
429 #define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0) 101 #define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0)
530 202
531 #undef set_boolean 203 #undef set_boolean
532 #undef set_int 204 #undef set_int
533 #undef set_long 205 #undef set_long
534 206
207 C2V_END
208
209 C2V_ENTRY(jbyteArray, initializeBytecode, (JNIEnv *env, jobject, jlong metaspace_method, jbyteArray result))
210 methodHandle method = asMethod(metaspace_method);
211 ResourceMark rm;
212
213 int code_size = method->code_size();
214 jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
215
216 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
217 // iterate over all bytecodes and replace non-Java bytecodes
218
219 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
220 Bytecodes::Code code = s.code();
221 Bytecodes::Code raw_code = s.raw_code();
222 int bci = s.bci();
223 int len = s.instruction_size();
224
225 // Restore original byte code.
226 reconstituted_code[bci] = (jbyte) (s.is_wide()? Bytecodes::_wide : code);
227 if (len > 1) {
228 memcpy(&reconstituted_code[bci+1], s.bcp()+1, len-1);
229 }
230
231 if (len > 1) {
232 // Restore the big-endian constant pool indexes.
233 // Cf. Rewriter::scan_method
234 switch (code) {
235 case Bytecodes::_getstatic:
236 case Bytecodes::_putstatic:
237 case Bytecodes::_getfield:
238 case Bytecodes::_putfield:
239 case Bytecodes::_invokevirtual:
240 case Bytecodes::_invokespecial:
241 case Bytecodes::_invokestatic:
242 case Bytecodes::_invokeinterface:
243 case Bytecodes::_invokehandle: {
244 int cp_index = Bytes::get_native_u2((address) &reconstituted_code[bci + 1]);
245 Bytes::put_Java_u2((address) &reconstituted_code[bci + 1], (u2) cp_index);
246 break;
247 }
248
249 case Bytecodes::_invokedynamic:
250 int cp_index = Bytes::get_native_u4((address) &reconstituted_code[bci + 1]);
251 Bytes::put_Java_u4((address) &reconstituted_code[bci + 1], (u4) cp_index);
252 break;
253 }
254
255 // Not all ldc byte code are rewritten.
256 switch (raw_code) {
257 case Bytecodes::_fast_aldc: {
258 int cpc_index = reconstituted_code[bci + 1] & 0xff;
259 int cp_index = method->constants()->object_to_cp_index(cpc_index);
260 assert(cp_index < method->constants()->length(), "sanity check");
261 reconstituted_code[bci + 1] = (jbyte) cp_index;
262 break;
263 }
264
265 case Bytecodes::_fast_aldc_w: {
266 int cpc_index = Bytes::get_native_u2((address) &reconstituted_code[bci + 1]);
267 int cp_index = method->constants()->object_to_cp_index(cpc_index);
268 assert(cp_index < method->constants()->length(), "sanity check");
269 Bytes::put_Java_u2((address) &reconstituted_code[bci + 1], (u2) cp_index);
270 break;
271 }
272 }
273 }
274 }
275
276 env->SetByteArrayRegion(result, 0, code_size, reconstituted_code);
277
278 return result;
279 C2V_END
280
281 C2V_VMENTRY(jint, exceptionTableLength, (JNIEnv *, jobject, jlong metaspace_method))
282 ResourceMark rm;
283 methodHandle method = asMethod(metaspace_method);
284 return method->exception_table_length();
285 C2V_END
286
287 C2V_VMENTRY(jlong, exceptionTableStart, (JNIEnv *, jobject, jlong metaspace_method))
288 ResourceMark rm;
289 methodHandle method = asMethod(metaspace_method);
290 assert(method->exception_table_length() != 0, "should be handled in Java code");
291 return (jlong) (address) method->exception_table_start();
292 C2V_END
293
294 C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
295 // Analyze the method to see if monitors are used properly.
296 methodHandle method(THREAD, asMethod(metaspace_method));
297 {
298 EXCEPTION_MARK;
299 ResourceMark rm(THREAD);
300 GeneratePairingInfo gpi(method);
301 gpi.compute_map(CATCH);
302 if (!gpi.monitor_safe()) {
303 return false;
304 }
305 method->set_guaranteed_monitor_matching();
306 }
307 return true;
308 C2V_END
309
310 C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jclass holder_handle, jint slot))
311 oop java_class = JNIHandles::resolve(holder_handle);
312 Klass* holder = java_lang_Class::as_Klass(java_class);
313 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
314 return (jlong) (address) method();
315 }
316
317 C2V_VMENTRY(jlong, findUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_method))
318 methodHandle method = asMethod(metaspace_method);
319 KlassHandle holder = method->method_holder();
320 assert(!holder->is_interface(), "should be handled in Java code");
321 ResourceMark rm;
322 MutexLocker locker(Compile_lock);
323 Method* ucm = Dependencies::find_unique_concrete_method(holder(), method());
324 return (jlong) (address) ucm;
325 C2V_END
326
327 C2V_VMENTRY(jlong, getKlassImplementor, (JNIEnv *, jobject, jlong metaspace_klass))
328 InstanceKlass* klass = (InstanceKlass*) asKlass(metaspace_klass);
329 return (jlong) (address) klass->implementor();
330 C2V_END
331
332 C2V_VMENTRY(void, initializeMethod,(JNIEnv *, jobject, jlong metaspace_method, jobject hotspot_method))
333 methodHandle method = asMethod(metaspace_method);
334 InstanceKlass::cast(HotSpotResolvedJavaMethod::klass())->initialize(CHECK);
335 HotSpotResolvedJavaMethod::set_callerSensitive(hotspot_method, method->caller_sensitive());
336 HotSpotResolvedJavaMethod::set_forceInline(hotspot_method, method->force_inline());
337 HotSpotResolvedJavaMethod::set_dontInline(hotspot_method, method->dont_inline());
338 HotSpotResolvedJavaMethod::set_ignoredBySecurityStackWalk(hotspot_method, method->is_ignored_by_security_stack_walk());
339 C2V_END
340
341 C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
342 methodHandle method = asMethod(metaspace_method);
343 return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
344 C2V_END
345
346 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
347 methodHandle method = asMethod(metaspace_method);
348 return CompilerOracle::should_inline(method) || method->force_inline();
349 C2V_END
350
351 C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
352 nmethod* code = (asMethod(metaspace_method))->code();
353 return code == NULL ? 0 : code->insts_size();
354 C2V_END
355
356 C2V_VMENTRY(jlong, lookupType, (JNIEnv *env, jobject, jstring jname, jclass accessing_class, jboolean eagerResolve))
357 ResourceMark rm;
358 Handle name = JNIHandles::resolve(jname);
359 Symbol* class_name = java_lang_String::as_symbol(name, THREAD);
360 assert(class_name != NULL, "name to symbol creation failed");
361 assert(class_name->size() > 1, "primitive types should be handled in Java code");
362
363 Klass* resolved_klass = NULL;
364 Handle class_loader;
365 Handle protection_domain;
366 if (JNIHandles::resolve(accessing_class) != NULL) {
367 Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class));
368 class_loader = accessing_klass->class_loader();
369 protection_domain = accessing_klass->protection_domain();
370 }
371
372 if (eagerResolve) {
373 resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, THREAD);
374 } else {
375 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, THREAD);
376 }
377
378 return (jlong) (address) resolved_klass;
379 C2V_END
380
381 C2V_VMENTRY(jlong, lookupKlassByName, (JNIEnv *env, jobject, jstring name, jclass loading_class))
382 KlassHandle loading_klass = java_lang_Class::as_Klass(JNIHandles::resolve(loading_class));
383 Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
384 KlassHandle klass = GraalEnv::get_klass_by_name(loading_klass, name_symbol, false);
385 return (jlong) (address) klass();
386 C2V_END
387
388 C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
389 ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
390 oop result = NULL;
391 constantTag tag = cp->tag_at(index);
392 switch (tag.value()) {
393 case JVM_CONSTANT_String:
394 result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
395 break;
396 case JVM_CONSTANT_MethodHandle:
397 case JVM_CONSTANT_MethodHandleInError:
398 case JVM_CONSTANT_MethodType:
399 case JVM_CONSTANT_MethodTypeInError:
400 result = cp->resolve_constant_at(index, CHECK_NULL);
401 break;
402 default:
403 fatal(err_msg_res("unknown constant pool tag %s at cpi %d in %s", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string()));
404 }
405 return JNIHandles::make_local(THREAD, result);
406 C2V_END
407
408 C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
409 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
410 return cp->name_and_type_ref_index_at(index);
411 C2V_END
412
413 C2V_VMENTRY(jlong, lookupNameRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
414 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
415 return (jlong) (address) cp->name_ref_at(index);
416 C2V_END
417
418 C2V_VMENTRY(jlong, lookupSignatureRefInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
419 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
420 return (jlong) (address) cp->signature_ref_at(index);
421 C2V_END
422
423 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
424 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
425 return cp->klass_ref_index_at(index);
426 C2V_END
427
428 C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
429 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
430 KlassHandle loading_klass(cp->pool_holder());
431 bool is_accessible = false;
432 KlassHandle klass = GraalEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
433 if (klass.is_null()) {
434 // We have to lock the cpool to keep the oop from being resolved
435 // while we are accessing it.
436 MonitorLockerEx ml(cp->lock());
437 constantTag tag = cp->tag_at(index);
438 if (tag.is_klass()) {
439 // The klass has been inserted into the constant pool
440 // very recently.
441 return (jlong) CompilerToVM::tag_pointer(cp->resolved_klass_at(index));
442 } else if (tag.is_symbol()) {
443 return (jlong) CompilerToVM::tag_pointer(cp->symbol_at(index));
444 } else {
445 assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
446 return (jlong) CompilerToVM::tag_pointer(cp->unresolved_klass_at(index));
447 }
448 }
449 return (jlong) CompilerToVM::tag_pointer(klass());
450 C2V_END
451
452 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index))
453 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
454 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
455 return JNIHandles::make_local(THREAD, appendix_oop);
456 C2V_END
457
458 C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
459 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
460 instanceKlassHandle pool_holder(cp->pool_holder());
461 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
462 methodHandle method = GraalEnv::get_method_by_index(cp, index, bc, pool_holder);
463 return (jlong) (address) method();
464 C2V_END
465
466 C2V_VMENTRY(void, loadReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op))
467 ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
468 Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF);
469 if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray
470 && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w)
471 {
472 index = cp->remap_instruction_operand_from_cache(index);
473 }
474 constantTag tag = cp->tag_at(index);
475 if (tag.is_field_or_method()) {
476 index = cp->uncached_klass_ref_index_at(index);
477 tag = cp->tag_at(index);
478 }
479
480 if (tag.is_unresolved_klass() || tag.is_klass()) {
481 Klass* klass = cp->klass_at(index, CHECK);
482 if (klass->oop_is_instance()) {
483 InstanceKlass::cast(klass)->initialize(CHECK);
484 }
485 }
486 C2V_END
487
488 C2V_VMENTRY(jlong, resolveField, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
489 ResourceMark rm;
490 constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
491 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
492 fieldDescriptor result;
493 LinkResolver::resolve_field_access(result, cp, index, Bytecodes::java_code(code), true, false, CHECK_0);
494 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
495 assert(info != NULL && info->length() == 2, "must be");
496 info->long_at_put(0, (jlong) result.access_flags().as_int());
497 info->long_at_put(1, (jlong) result.offset());
498 return (jlong) (address) result.field_holder();
499 C2V_END
500
501 C2V_VMENTRY(jlong, resolveMethod, (JNIEnv *, jobject, jlong metaspace_klass, jstring name, jstring signature))
502 Klass* klass = (Klass*) metaspace_klass;
503 Symbol* name_symbol = java_lang_String::as_symbol(JNIHandles::resolve(name), THREAD);
504 Symbol* signature_symbol = java_lang_String::as_symbol(JNIHandles::resolve(signature), THREAD);
505 return (jlong) (address) klass->lookup_method(name_symbol, signature_symbol);
506 C2V_END
507
508 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jlong metaspace_klass))
509 Klass* klass = (Klass*) metaspace_klass;
510 assert(klass != NULL, "method must not be called for primitive types");
511 return Dependencies::find_finalizable_subclass(klass) != NULL;
512 C2V_END
513
514 C2V_VMENTRY(jlong, getClassInitializer, (JNIEnv *, jobject, jlong metaspace_klass))
515 InstanceKlass* klass = (InstanceKlass*) metaspace_klass;
516 return (jlong) (address) klass->class_initializer();
517 C2V_END
518
519 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv *env, jobject, jlong addr))
520 address target_addr = (address) addr;
521 if (target_addr != 0x0) {
522 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
523 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
524 return MAX2(ABS(off_low), ABS(off_high));
525 }
526 return -1;
527 C2V_END
528
529 C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jlong metaspace_method))
530 methodHandle method = asMethod(metaspace_method);
531 method->set_not_c1_compilable();
532 method->set_not_c2_compilable();
533 method->set_dont_inline(true);
535 C2V_END 534 C2V_END
536 535
537 C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compiled_code, jobject installed_code, jobject speculation_log)) 536 C2V_VMENTRY(jint, installCode0, (JNIEnv *jniEnv, jobject, jobject compiled_code, jobject installed_code, jobject speculation_log))
538 ResourceMark rm; 537 ResourceMark rm;
539 HandleMark hm; 538 HandleMark hm;