1 /*
2 * Copyright (c) 2011, 2016, 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 #include "precompiled.hpp"
25 #include "classfile/javaClasses.inline.hpp"
26 #include "code/codeCache.hpp"
27 #include "code/scopeDesc.hpp"
28 #include "interpreter/linkResolver.hpp"
29 #include "memory/oopFactory.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "oops/generateOopMap.hpp"
32 #include "oops/fieldStreams.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "oops/objArrayOop.inline.hpp"
35 #include "runtime/fieldDescriptor.hpp"
36 #include "runtime/javaCalls.hpp"
37 #include "jvmci/jvmciRuntime.hpp"
38 #include "compiler/abstractCompiler.hpp"
39 #include "compiler/compileBroker.hpp"
40 #include "compiler/compilerOracle.hpp"
41 #include "compiler/disassembler.hpp"
42 #include "compiler/oopMap.hpp"
43 #include "jvmci/jvmciCompilerToVM.hpp"
44 #include "jvmci/jvmciCompiler.hpp"
45 #include "jvmci/jvmciEnv.hpp"
46 #include "jvmci/jvmciJavaClasses.hpp"
47 #include "jvmci/jvmciCodeInstaller.hpp"
48 #include "jvmci/vmStructs_jvmci.hpp"
49 #include "gc/g1/heapRegion.hpp"
50 #include "runtime/javaCalls.hpp"
51 #include "runtime/deoptimization.hpp"
52 #include "runtime/timerTrace.hpp"
53 #include "runtime/vframe.hpp"
54 #include "runtime/vframe_hp.hpp"
55 #include "runtime/vmStructs.hpp"
56
57
58 // Entry to native method implementation that transitions current thread to '_thread_in_vm'.
59 #define C2V_VMENTRY(result_type, name, signature) \
60 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
61 TRACE_jvmci_1("CompilerToVM::" #name); \
62 TRACE_CALL(result_type, jvmci_ ## name signature) \
63 JVMCI_VM_ENTRY_MARK; \
64
65 #define C2V_END }
66
67 oop CompilerToVM::get_jvmci_method(const methodHandle& method, TRAPS) {
68 if (method() != NULL) {
69 JavaValue result(T_OBJECT);
70 JavaCallArguments args;
71 args.push_long((jlong) (address) method());
72 JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_NULL);
73
74 return (oop)result.get_jobject();
75 }
76 return NULL;
77 }
78
79 oop CompilerToVM::get_jvmci_type(KlassHandle klass, TRAPS) {
80 if (klass() != NULL) {
81 JavaValue result(T_OBJECT);
82 JavaCallArguments args;
83 args.push_oop(klass->java_mirror());
84 JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedObjectTypeImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::klass_fromMetaspace_signature(), &args, CHECK_NULL);
85
86 return (oop)result.get_jobject();
87 }
88 return NULL;
89 }
90
91 int CompilerToVM::Data::Klass_vtable_start_offset;
92 int CompilerToVM::Data::Klass_vtable_length_offset;
93
94 int CompilerToVM::Data::Method_extra_stack_entries;
95
96 address CompilerToVM::Data::SharedRuntime_ic_miss_stub;
97 address CompilerToVM::Data::SharedRuntime_handle_wrong_method_stub;
98 address CompilerToVM::Data::SharedRuntime_deopt_blob_unpack;
99 address CompilerToVM::Data::SharedRuntime_deopt_blob_uncommon_trap;
100
101 size_t CompilerToVM::Data::ThreadLocalAllocBuffer_alignment_reserve;
102
103 CollectedHeap* CompilerToVM::Data::Universe_collectedHeap;
104 int CompilerToVM::Data::Universe_base_vtable_size;
105 address CompilerToVM::Data::Universe_narrow_oop_base;
106 int CompilerToVM::Data::Universe_narrow_oop_shift;
107 address CompilerToVM::Data::Universe_narrow_klass_base;
108 int CompilerToVM::Data::Universe_narrow_klass_shift;
109 void* CompilerToVM::Data::Universe_non_oop_bits;
110 uintptr_t CompilerToVM::Data::Universe_verify_oop_mask;
111 uintptr_t CompilerToVM::Data::Universe_verify_oop_bits;
112
113 bool CompilerToVM::Data::_supports_inline_contig_alloc;
114 HeapWord** CompilerToVM::Data::_heap_end_addr;
115 HeapWord* volatile* CompilerToVM::Data::_heap_top_addr;
116 int CompilerToVM::Data::_max_oop_map_stack_offset;
117
118 jbyte* CompilerToVM::Data::cardtable_start_address;
119 int CompilerToVM::Data::cardtable_shift;
120
121 int CompilerToVM::Data::vm_page_size;
122
123 address CompilerToVM::Data::dsin;
124 address CompilerToVM::Data::dcos;
125 address CompilerToVM::Data::dtan;
126 address CompilerToVM::Data::dexp;
127 address CompilerToVM::Data::dlog;
128 address CompilerToVM::Data::dlog10;
129 address CompilerToVM::Data::dpow;
130
131 void CompilerToVM::Data::initialize() {
132 Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
133 Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
134
135 Method_extra_stack_entries = Method::extra_stack_entries();
136
137 SharedRuntime_ic_miss_stub = SharedRuntime::get_ic_miss_stub();
138 SharedRuntime_handle_wrong_method_stub = SharedRuntime::get_handle_wrong_method_stub();
139 SharedRuntime_deopt_blob_unpack = SharedRuntime::deopt_blob()->unpack();
140 SharedRuntime_deopt_blob_uncommon_trap = SharedRuntime::deopt_blob()->uncommon_trap();
141
142 ThreadLocalAllocBuffer_alignment_reserve = ThreadLocalAllocBuffer::alignment_reserve();
143
144 Universe_collectedHeap = Universe::heap();
145 Universe_base_vtable_size = Universe::base_vtable_size();
146 Universe_narrow_oop_base = Universe::narrow_oop_base();
147 Universe_narrow_oop_shift = Universe::narrow_oop_shift();
148 Universe_narrow_klass_base = Universe::narrow_klass_base();
149 Universe_narrow_klass_shift = Universe::narrow_klass_shift();
150 Universe_non_oop_bits = Universe::non_oop_word();
151 Universe_verify_oop_mask = Universe::verify_oop_mask();
152 Universe_verify_oop_bits = Universe::verify_oop_bits();
153
154 _supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc();
155 _heap_end_addr = _supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1;
156 _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord* volatile*) -1;
157
158 _max_oop_map_stack_offset = (OopMapValue::register_mask - VMRegImpl::stack2reg(0)->value()) * VMRegImpl::stack_slot_size;
159 int max_oop_map_stack_index = _max_oop_map_stack_offset / VMRegImpl::stack_slot_size;
160 assert(OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index)), "should be valid");
161 assert(!OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index + 1)), "should be invalid");
162
163 BarrierSet* bs = Universe::heap()->barrier_set();
164 switch (bs->kind()) {
165 case BarrierSet::CardTableModRef:
166 case BarrierSet::CardTableForRS:
167 case BarrierSet::CardTableExtension:
168 case BarrierSet::G1SATBCT:
169 case BarrierSet::G1SATBCTLogging: {
170 jbyte* base = barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base;
171 assert(base != 0, "unexpected byte_map_base");
172 cardtable_start_address = base;
173 cardtable_shift = CardTableModRefBS::card_shift;
174 break;
175 }
176 case BarrierSet::ModRef:
177 case BarrierSet::Epsilon:
178 cardtable_start_address = 0;
179 cardtable_shift = 0;
180 // No post barriers
181 break;
182 default:
183 ShouldNotReachHere();
184 break;
185 }
186
187 vm_page_size = os::vm_page_size();
188
189 #define SET_TRIGFUNC(name) \
190 if (StubRoutines::name() != NULL) { \
191 name = StubRoutines::name(); \
192 } else { \
193 name = CAST_FROM_FN_PTR(address, SharedRuntime::name); \
194 }
195
196 SET_TRIGFUNC(dsin);
197 SET_TRIGFUNC(dcos);
198 SET_TRIGFUNC(dtan);
199 SET_TRIGFUNC(dexp);
200 SET_TRIGFUNC(dlog10);
201 SET_TRIGFUNC(dlog);
202 SET_TRIGFUNC(dpow);
203
204 #undef SET_TRIGFUNC
205 }
206
207 objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
208 objArrayHandle vmIntrinsics = oopFactory::new_objArray(VMIntrinsicMethod::klass(), (vmIntrinsics::ID_LIMIT - 1), CHECK_(objArrayHandle()));
209 int index = 0;
210 // The intrinsics for a class are usually adjacent to each other.
211 // When they are, the string for the class name can be reused.
212 vmSymbols::SID kls_sid = vmSymbols::NO_SID;
213 Handle kls_str;
214 #define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
215 #define VM_SYMBOL_TO_STRING(s) \
216 java_lang_String::create_from_symbol(vmSymbols::symbol_at(SID_ENUM(s)), CHECK_(objArrayHandle()))
217 #define VM_INTRINSIC_INFO(id, kls, name, sig, ignore_fcode) { \
218 instanceHandle vmIntrinsicMethod = InstanceKlass::cast(VMIntrinsicMethod::klass())->allocate_instance_handle(CHECK_(objArrayHandle())); \
219 if (kls_sid != SID_ENUM(kls)) { \
220 kls_str = VM_SYMBOL_TO_STRING(kls); \
221 kls_sid = SID_ENUM(kls); \
222 } \
223 Handle name_str = VM_SYMBOL_TO_STRING(name); \
224 Handle sig_str = VM_SYMBOL_TO_STRING(sig); \
225 VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str()); \
226 VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str()); \
227 VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str()); \
228 VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id); \
229 vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod()); \
230 }
231
232 VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
233 #undef SID_ENUM
234 #undef VM_SYMBOL_TO_STRING
235 #undef VM_INTRINSIC_INFO
236 assert(index == vmIntrinsics::ID_LIMIT - 1, "must be");
237
238 return vmIntrinsics;
239 }
240
241 C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
242 #define BOXED_LONG(name, value) oop name; do { jvalue p; p.j = (jlong) (value); name = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL);} while(0)
243 #define BOXED_DOUBLE(name, value) oop name; do { jvalue p; p.d = (jdouble) (value); name = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL);} while(0)
244 ResourceMark rm;
245 HandleMark hm;
246
247 CompilerToVM::Data::initialize();
248
249 VMField::klass()->initialize(CHECK_NULL);
250 VMFlag::klass()->initialize(CHECK_NULL);
251 VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
252
253 int len = JVMCIVMStructs::localHotSpotVMStructs_count();
254 objArrayHandle vmFields = oopFactory::new_objArray(VMField::klass(), len, CHECK_NULL);
255 for (int i = 0; i < len ; i++) {
256 VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
257 instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
258 size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
259 char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
260 sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
261 Handle name = java_lang_String::create_from_str(name_buf, CHECK_NULL);
262 Handle type = java_lang_String::create_from_str(vmField.typeString, CHECK_NULL);
263 VMField::set_name(vmFieldObj, name());
264 VMField::set_type(vmFieldObj, type());
265 VMField::set_offset(vmFieldObj, vmField.offset);
266 VMField::set_address(vmFieldObj, (jlong) vmField.address);
267 if (vmField.isStatic) {
268 if (strcmp(vmField.typeString, "bool") == 0) {
269 BOXED_LONG(value, *(jbyte*) vmField.address);
270 VMField::set_value(vmFieldObj, value);
271 } else if (strcmp(vmField.typeString, "int") == 0 ||
272 strcmp(vmField.typeString, "jint") == 0) {
273 BOXED_LONG(value, *(jint*) vmField.address);
274 VMField::set_value(vmFieldObj, value);
275 } else if (strcmp(vmField.typeString, "uint64_t") == 0) {
276 BOXED_LONG(value, *(uint64_t*) vmField.address);
277 VMField::set_value(vmFieldObj, value);
278 } else if (strcmp(vmField.typeString, "address") == 0 ||
279 strcmp(vmField.typeString, "intptr_t") == 0 ||
280 strcmp(vmField.typeString, "uintptr_t") == 0 ||
281 strcmp(vmField.typeString, "size_t") == 0 ||
282 // All foo* types are addresses.
283 vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
284 BOXED_LONG(value, *((address*) vmField.address));
285 VMField::set_value(vmFieldObj, value);
286 } else {
287 JVMCI_ERROR_NULL("VM field %s has unsupported type %s", name_buf, vmField.typeString);
288 }
289 }
290 vmFields->obj_at_put(i, vmFieldObj());
291 }
292
293 len = JVMCIVMStructs::localHotSpotVMTypes_count();
294 objArrayHandle vmTypes = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
295 for (int i = 0; i < len ; i++) {
296 VMTypeEntry vmType = JVMCIVMStructs::localHotSpotVMTypes[i];
297 Handle name = java_lang_String::create_from_str(vmType.typeName, CHECK_NULL);
298 BOXED_LONG(size, vmType.size);
299 vmTypes->obj_at_put(i * 2, name());
300 vmTypes->obj_at_put(i * 2 + 1, size);
301 }
302
303 int ints_len = JVMCIVMStructs::localHotSpotVMIntConstants_count();
304 int longs_len = JVMCIVMStructs::localHotSpotVMLongConstants_count();
305 len = ints_len + longs_len;
306 objArrayHandle vmConstants = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
307 int insert = 0;
308 for (int i = 0; i < ints_len ; i++) {
309 VMIntConstantEntry c = JVMCIVMStructs::localHotSpotVMIntConstants[i];
310 Handle name = java_lang_String::create_from_str(c.name, CHECK_NULL);
311 BOXED_LONG(value, c.value);
312 vmConstants->obj_at_put(insert++, name());
313 vmConstants->obj_at_put(insert++, value);
314 }
315 for (int i = 0; i < longs_len ; i++) {
316 VMLongConstantEntry c = JVMCIVMStructs::localHotSpotVMLongConstants[i];
317 Handle name = java_lang_String::create_from_str(c.name, CHECK_NULL);
318 BOXED_LONG(value, c.value);
319 vmConstants->obj_at_put(insert++, name());
320 vmConstants->obj_at_put(insert++, value);
321 }
322 assert(insert == len * 2, "must be");
323
324 len = JVMCIVMStructs::localHotSpotVMAddresses_count();
325 objArrayHandle vmAddresses = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
326 for (int i = 0; i < len ; i++) {
327 VMAddressEntry a = JVMCIVMStructs::localHotSpotVMAddresses[i];
328 Handle name = java_lang_String::create_from_str(a.name, CHECK_NULL);
329 BOXED_LONG(value, a.value);
330 vmAddresses->obj_at_put(i * 2, name());
331 vmAddresses->obj_at_put(i * 2 + 1, value);
332 }
333
334 // The last entry is the null entry.
335 len = (int) Flag::numFlags - 1;
336 objArrayHandle vmFlags = oopFactory::new_objArray(VMFlag::klass(), len, CHECK_NULL);
337 for (int i = 0; i < len; i++) {
338 Flag* flag = &Flag::flags[i];
339 instanceHandle vmFlagObj = InstanceKlass::cast(VMFlag::klass())->allocate_instance_handle(CHECK_NULL);
340 Handle name = java_lang_String::create_from_str(flag->_name, CHECK_NULL);
341 Handle type = java_lang_String::create_from_str(flag->_type, CHECK_NULL);
342 VMFlag::set_name(vmFlagObj, name());
343 VMFlag::set_type(vmFlagObj, type());
344 if (flag->is_bool()) {
345 BOXED_LONG(value, flag->get_bool());
346 VMFlag::set_value(vmFlagObj, value);
347 } else if (flag->is_ccstr()) {
348 Handle value = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_NULL);
349 VMFlag::set_value(vmFlagObj, value());
350 } else if (flag->is_int()) {
351 BOXED_LONG(value, flag->get_int());
352 VMFlag::set_value(vmFlagObj, value);
353 } else if (flag->is_intx()) {
354 BOXED_LONG(value, flag->get_intx());
355 VMFlag::set_value(vmFlagObj, value);
356 } else if (flag->is_uint()) {
357 BOXED_LONG(value, flag->get_uint());
358 VMFlag::set_value(vmFlagObj, value);
359 } else if (flag->is_uint64_t()) {
360 BOXED_LONG(value, flag->get_uint64_t());
361 VMFlag::set_value(vmFlagObj, value);
362 } else if (flag->is_uintx()) {
363 BOXED_LONG(value, flag->get_uintx());
364 VMFlag::set_value(vmFlagObj, value);
365 } else if (flag->is_double()) {
366 BOXED_DOUBLE(value, flag->get_double());
367 VMFlag::set_value(vmFlagObj, value);
368 } else if (flag->is_size_t()) {
369 BOXED_LONG(value, flag->get_size_t());
370 VMFlag::set_value(vmFlagObj, value);
371 } else {
372 JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type);
373 }
374 vmFlags->obj_at_put(i, vmFlagObj());
375 }
376
377 objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
378
379 objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 6, CHECK_NULL);
380 data->obj_at_put(0, vmFields());
381 data->obj_at_put(1, vmTypes());
382 data->obj_at_put(2, vmConstants());
383 data->obj_at_put(3, vmAddresses());
384 data->obj_at_put(4, vmFlags());
385 data->obj_at_put(5, vmIntrinsics());
386
387 return (jobjectArray) JNIHandles::make_local(THREAD, data);
388 #undef BOXED_LONG
389 #undef BOXED_DOUBLE
390 C2V_END
391
392 C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
393 methodHandle method = CompilerToVM::asMethod(jvmci_method);
394 ResourceMark rm;
395
396 int code_size = method->code_size();
397 typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL);
398
399 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
400 // iterate over all bytecodes and replace non-Java bytecodes
401
402 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
403 Bytecodes::Code code = s.code();
404 Bytecodes::Code raw_code = s.raw_code();
405 int bci = s.bci();
406 int len = s.instruction_size();
407
408 // Restore original byte code.
409 reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code));
410 if (len > 1) {
411 memcpy(reconstituted_code->byte_at_addr(bci + 1), s.bcp()+1, len-1);
412 }
413
414 if (len > 1) {
415 // Restore the big-endian constant pool indexes.
416 // Cf. Rewriter::scan_method
417 switch (code) {
418 case Bytecodes::_getstatic:
419 case Bytecodes::_putstatic:
420 case Bytecodes::_getfield:
421 case Bytecodes::_putfield:
422 case Bytecodes::_invokevirtual:
423 case Bytecodes::_invokespecial:
424 case Bytecodes::_invokestatic:
425 case Bytecodes::_invokeinterface:
426 case Bytecodes::_invokehandle: {
427 int cp_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
428 Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
429 break;
430 }
431
432 case Bytecodes::_invokedynamic:
433 int cp_index = Bytes::get_native_u4((address) reconstituted_code->byte_at_addr(bci + 1));
434 Bytes::put_Java_u4((address) reconstituted_code->byte_at_addr(bci + 1), (u4) cp_index);
435 break;
436 }
437
438 // Not all ldc byte code are rewritten.
439 switch (raw_code) {
440 case Bytecodes::_fast_aldc: {
441 int cpc_index = reconstituted_code->byte_at(bci + 1) & 0xff;
442 int cp_index = method->constants()->object_to_cp_index(cpc_index);
443 assert(cp_index < method->constants()->length(), "sanity check");
444 reconstituted_code->byte_at_put(bci + 1, (jbyte) cp_index);
445 break;
446 }
447
448 case Bytecodes::_fast_aldc_w: {
449 int cpc_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
450 int cp_index = method->constants()->object_to_cp_index(cpc_index);
451 assert(cp_index < method->constants()->length(), "sanity check");
452 Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
453 break;
454 }
455 }
456 }
457 }
458
459 return (jbyteArray) JNIHandles::make_local(THREAD, reconstituted_code);
460 C2V_END
461
462 C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jobject jvmci_method))
463 ResourceMark rm;
464 methodHandle method = CompilerToVM::asMethod(jvmci_method);
465 return method->exception_table_length();
466 C2V_END
467
468 C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_method))
469 ResourceMark rm;
470 methodHandle method = CompilerToVM::asMethod(jvmci_method);
471 if (method->exception_table_length() == 0) {
472 return 0L;
473 }
474 return (jlong) (address) method->exception_table_start();
475 C2V_END
476
477 C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv *, jobject, jobject executable_handle))
478 oop executable = JNIHandles::resolve(executable_handle);
479 oop mirror = NULL;
480 int slot = 0;
481
482 if (executable->klass() == SystemDictionary::reflect_Constructor_klass()) {
483 mirror = java_lang_reflect_Constructor::clazz(executable);
484 slot = java_lang_reflect_Constructor::slot(executable);
485 } else {
486 assert(executable->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
487 mirror = java_lang_reflect_Method::clazz(executable);
488 slot = java_lang_reflect_Method::slot(executable);
489 }
490 Klass* holder = java_lang_Class::as_Klass(mirror);
491 methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
492 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
493 return JNIHandles::make_local(THREAD, result);
494 }
495
496 C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset))
497 methodHandle method;
498 oop base_object = JNIHandles::resolve(base);
499 if (base_object == NULL) {
500 method = *((Method**)(offset));
501 } else if (base_object->is_a(SystemDictionary::MemberName_klass())) {
502 method = (Method*) (intptr_t) base_object->long_field(offset);
503 } else if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
504 method = *((Method**)(HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object) + offset));
505 } else {
506 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
507 err_msg("Unexpected type: %s", base_object->klass()->external_name()));
508 }
509 assert (method.is_null() || method->is_method(), "invalid read");
510 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
511 return JNIHandles::make_local(THREAD, result);
512 }
513
514 C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject object_handle))
515 constantPoolHandle cp;
516 oop object = JNIHandles::resolve(object_handle);
517 if (object == NULL) {
518 THROW_0(vmSymbols::java_lang_NullPointerException());
519 }
520 if (object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
521 cp = CompilerToVM::asMethod(object)->constMethod()->constants();
522 } else if (object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
523 cp = InstanceKlass::cast(CompilerToVM::asKlass(object))->constants();
524 } else {
525 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
526 err_msg("Unexpected type: %s", object->klass()->external_name()));
527 }
528 assert(!cp.is_null(), "npe");
529 JavaValue method_result(T_OBJECT);
530 JavaCallArguments args;
531 args.push_long((jlong) (address) cp());
532 JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
533 return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
534 }
535
536 C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
537 KlassHandle klass;
538 oop base_object = JNIHandles::resolve(base);
539 jlong base_address = 0;
540 if (base_object != NULL && offset == oopDesc::klass_offset_in_bytes()) {
541 klass = base_object->klass();
542 } else if (!compressed) {
543 if (base_object != NULL) {
544 if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
545 base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
546 } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
547 base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
548 } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
549 base_address = (jlong) CompilerToVM::asKlass(base_object);
550 } else if (base_object->is_a(SystemDictionary::Class_klass())) {
551 base_address = (jlong) (address) base_object;
552 } else {
553 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
554 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false"));
555 }
556 }
557 klass = *((Klass**) (intptr_t) (base_address + offset));
558 } else {
559 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
560 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false"));
561 }
562 assert (klass.is_null() || klass->is_klass(), "invalid read");
563 oop result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
564 return JNIHandles::make_local(THREAD, result);
565 }
566
567 C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
568 ResourceMark rm;
569 methodHandle method = CompilerToVM::asMethod(jvmci_method);
570 KlassHandle holder = CompilerToVM::asKlass(jvmci_type);
571 if (holder->is_interface()) {
572 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", holder->external_name()));
573 }
574
575 methodHandle ucm;
576 {
577 MutexLocker locker(Compile_lock);
578 ucm = Dependencies::find_unique_concrete_method(holder(), method());
579 }
580 oop result = CompilerToVM::get_jvmci_method(ucm, CHECK_NULL);
581 return JNIHandles::make_local(THREAD, result);
582 C2V_END
583
584 C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
585 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
586 oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
587 return JNIHandles::make_local(THREAD, implementor);
588 C2V_END
589
590 C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method))
591 methodHandle method = CompilerToVM::asMethod(jvmci_method);
592 return method->is_ignored_by_security_stack_walk();
593 C2V_END
594
595 C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
596 methodHandle method = CompilerToVM::asMethod(jvmci_method);
597 // In hosted mode ignore the not_compilable flags since they are never set by
598 // the JVMCI compiler.
599 bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true;
600 return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
601 C2V_END
602
603 C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
604 methodHandle method = CompilerToVM::asMethod(jvmci_method);
605 return CompilerOracle::should_inline(method) || method->force_inline();
606 C2V_END
607
608 C2V_VMENTRY(jobject, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
609 ResourceMark rm;
610 Handle name = JNIHandles::resolve(jname);
611 Symbol* class_name = java_lang_String::as_symbol(name, CHECK_0);
612 if (java_lang_String::length(name()) <= 1) {
613 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
614 }
615
616 Klass* resolved_klass = NULL;
617 Handle class_loader;
618 Handle protection_domain;
619 if (JNIHandles::resolve(accessing_class) == NULL) {
620 THROW_0(vmSymbols::java_lang_NullPointerException());
621 }
622 Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class));
623 class_loader = accessing_klass->class_loader();
624 protection_domain = accessing_klass->protection_domain();
625
626 if (resolve) {
627 resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
628 } else {
629 if (class_name->byte_at(0) == 'L' &&
630 class_name->byte_at(class_name->utf8_length()-1) == ';') {
631 // This is a name from a signature. Strip off the trimmings.
632 // Call recursive to keep scope of strippedsym.
633 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
634 class_name->utf8_length()-2,
635 CHECK_0);
636 resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
637 } else if (FieldType::is_array(class_name)) {
638 FieldArrayInfo fd;
639 // dimension and object_key in FieldArrayInfo are assigned as a side-effect
640 // of this call
641 BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
642 if (t == T_OBJECT) {
643 TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
644 class_name->utf8_length()-2-fd.dimension(),
645 CHECK_0);
646 // naked oop "k" is OK here -- we assign back into it
647 resolved_klass = SystemDictionary::find(strippedsym,
648 class_loader,
649 protection_domain,
650 CHECK_0);
651 if (resolved_klass != NULL) {
652 resolved_klass = resolved_klass->array_klass(fd.dimension(), CHECK_0);
653 }
654 } else {
655 resolved_klass = Universe::typeArrayKlassObj(t);
656 resolved_klass = TypeArrayKlass::cast(resolved_klass)->array_klass(fd.dimension(), CHECK_0);
657 }
658 }
659 }
660 Handle result = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
661 return JNIHandles::make_local(THREAD, result());
662 C2V_END
663
664 C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
665 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
666 oop result = cp->resolve_constant_at(index, CHECK_NULL);
667 return JNIHandles::make_local(THREAD, result);
668 C2V_END
669
670 C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
671 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
672 oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
673 return JNIHandles::make_local(THREAD, result);
674 C2V_END
675
676 C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
677 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
678 return cp->name_and_type_ref_index_at(index);
679 C2V_END
680
681 C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
682 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
683 Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(which), CHECK_NULL);
684 return JNIHandles::make_local(THREAD, sym());
685 C2V_END
686
687 C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
688 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
689 Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(which), CHECK_NULL);
690 return JNIHandles::make_local(THREAD, sym());
691 C2V_END
692
693 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
694 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
695 return cp->klass_ref_index_at(index);
696 C2V_END
697
698 C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
699 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
700 Klass* resolved_klass = cp->klass_at(index, CHECK_NULL);
701 Handle klass = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
702 return JNIHandles::make_local(THREAD, klass());
703 C2V_END
704
705 C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
706 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
707 KlassHandle loading_klass(cp->pool_holder());
708 bool is_accessible = false;
709 KlassHandle klass = JVMCIEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
710 Symbol* symbol = NULL;
711 if (klass.is_null()) {
712 symbol = cp->klass_name_at(index);
713 }
714 Handle result;
715 if (!klass.is_null()) {
716 result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
717 } else {
718 result = java_lang_String::create_from_symbol(symbol, CHECK_NULL);
719 }
720 return JNIHandles::make_local(THREAD, result());
721 C2V_END
722
723 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
724 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
725 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
726 return JNIHandles::make_local(THREAD, appendix_oop);
727 C2V_END
728
729 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
730 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
731 instanceKlassHandle pool_holder(cp->pool_holder());
732 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
733 methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder);
734 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
735 return JNIHandles::make_local(THREAD, result);
736 C2V_END
737
738 C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
739 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
740 return cp->remap_instruction_operand_from_cache(index);
741 C2V_END
742
743 C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jlongArray info_handle))
744 ResourceMark rm;
745 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
746 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
747 fieldDescriptor fd;
748 LinkInfo link_info(cp, index, (jvmci_method != NULL) ? CompilerToVM::asMethod(jvmci_method) : NULL, CHECK_0);
749 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
750 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
751 assert(info != NULL && info->length() == 2, "must be");
752 info->long_at_put(0, (jlong) fd.access_flags().as_int());
753 info->long_at_put(1, (jlong) fd.offset());
754 oop field_holder = CompilerToVM::get_jvmci_type(fd.field_holder(), CHECK_NULL);
755 return JNIHandles::make_local(THREAD, field_holder);
756 C2V_END
757
758 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
759 ResourceMark rm;
760 Klass* klass = CompilerToVM::asKlass(jvmci_type);
761 Method* method = CompilerToVM::asMethod(jvmci_method);
762 if (klass->is_interface()) {
763 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name()));
764 }
765 if (!method->method_holder()->is_interface()) {
766 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
767 }
768 if (!InstanceKlass::cast(klass)->is_linked()) {
769 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name()));
770 }
771 return LinkResolver::vtable_index_of_interface_method(klass, method);
772 C2V_END
773
774 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
775 KlassHandle recv_klass = CompilerToVM::asKlass(receiver_jvmci_type);
776 KlassHandle caller_klass = CompilerToVM::asKlass(caller_jvmci_type);
777 methodHandle method = CompilerToVM::asMethod(jvmci_method);
778
779 KlassHandle h_resolved (THREAD, method->method_holder());
780 Symbol* h_name = method->name();
781 Symbol* h_signature = method->signature();
782
783 if (MethodHandles::is_signature_polymorphic_method(method())) {
784 // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case.
785 return NULL;
786 }
787
788 LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass);
789 methodHandle m;
790 // Only do exact lookup if receiver klass has been linked. Otherwise,
791 // the vtable has not been setup, and the LinkResolver will fail.
792 if (recv_klass->is_array_klass() ||
793 InstanceKlass::cast(recv_klass())->is_linked() && !recv_klass->is_interface()) {
794 if (h_resolved->is_interface()) {
795 m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info);
796 } else {
797 m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info);
798 }
799 }
800
801 if (m.is_null()) {
802 // Return NULL if there was a problem with lookup (uninitialized class, etc.)
803 return NULL;
804 }
805
806 oop result = CompilerToVM::get_jvmci_method(m, CHECK_NULL);
807 return JNIHandles::make_local(THREAD, result);
808 C2V_END
809
810 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type))
811 Klass* klass = CompilerToVM::asKlass(jvmci_type);
812 assert(klass != NULL, "method must not be called for primitive types");
813 return Dependencies::find_finalizable_subclass(klass) != NULL;
814 C2V_END
815
816 C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
817 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
818 oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL);
819 return JNIHandles::make_local(THREAD, result);
820 C2V_END
821
822 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr))
823 address target_addr = (address) addr;
824 if (target_addr != 0x0) {
825 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
826 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int));
827 return MAX2(ABS(off_low), ABS(off_high));
828 }
829 return -1;
830 C2V_END
831
832 C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jobject jvmci_method))
833 methodHandle method = CompilerToVM::asMethod(jvmci_method);
834 method->set_not_c1_compilable();
835 method->set_not_c2_compilable();
836 method->set_dont_inline(true);
837 C2V_END
838
839 C2V_VMENTRY(jint, installCode, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject installed_code, jobject speculation_log))
840 ResourceMark rm;
841 HandleMark hm;
842 Handle target_handle = JNIHandles::resolve(target);
843 Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
844 CodeBlob* cb = NULL;
845 Handle installed_code_handle = JNIHandles::resolve(installed_code);
846 Handle speculation_log_handle = JNIHandles::resolve(speculation_log);
847
848 JVMCICompiler* compiler = JVMCICompiler::instance(CHECK_JNI_ERR);
849
850 TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
851 bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0;
852 CodeInstaller installer(is_immutable_PIC);
853 JVMCIEnv::CodeInstallResult result = installer.install(compiler, target_handle, compiled_code_handle, cb, installed_code_handle, speculation_log_handle, CHECK_0);
854
855 if (PrintCodeCacheOnCompilation) {
856 stringStream s;
857 // Dump code cache into a buffer before locking the tty,
858 {
859 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
860 CodeCache::print_summary(&s, false);
861 }
862 ttyLocker ttyl;
863 tty->print_raw_cr(s.as_string());
864 }
865
866 if (result != JVMCIEnv::ok) {
867 assert(cb == NULL, "should be");
868 } else {
869 if (!installed_code_handle.is_null()) {
870 assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type");
871 nmethod::invalidate_installed_code(installed_code_handle, CHECK_0);
872 {
873 // Ensure that all updates to the InstalledCode fields are consistent.
874 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
875 InstalledCode::set_address(installed_code_handle, (jlong) cb);
876 InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1);
877 if (cb->is_nmethod()) {
878 InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->as_nmethod_or_null()->verified_entry_point());
879 } else {
880 InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->code_begin());
881 }
882 if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) {
883 HotSpotInstalledCode::set_size(installed_code_handle, cb->size());
884 HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin());
885 HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size());
886 }
887 }
888 nmethod* nm = cb->as_nmethod_or_null();
889 if (nm != NULL && installed_code_handle->is_scavengable()) {
890 assert(nm->detect_scavenge_root_oops(), "nm should be scavengable if installed_code is scavengable");
891 if (!UseG1GC) {
892 assert(nm->on_scavenge_root_list(), "nm should be on scavengable list");
893 }
894 }
895 }
896 }
897 return result;
898 C2V_END
899
900 C2V_VMENTRY(jint, getMetadata, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject metadata))
901 ResourceMark rm;
902 HandleMark hm;
903
904 Handle target_handle = JNIHandles::resolve(target);
905 Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
906 Handle metadata_handle = JNIHandles::resolve(metadata);
907
908 CodeMetadata code_metadata;
909 CodeBlob *cb = NULL;
910 CodeInstaller installer(true /* immutable PIC compilation */);
911
912 JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, CHECK_0);
913 if (result != JVMCIEnv::ok) {
914 return result;
915 }
916
917 if (code_metadata.get_nr_pc_desc() > 0) {
918 typeArrayHandle pcArrayOop = oopFactory::new_byteArray(sizeof(PcDesc) * code_metadata.get_nr_pc_desc(), CHECK_(JVMCIEnv::cache_full));
919 memcpy(pcArrayOop->byte_at_addr(0), code_metadata.get_pc_desc(), sizeof(PcDesc) * code_metadata.get_nr_pc_desc());
920 HotSpotMetaData::set_pcDescBytes(metadata_handle, pcArrayOop());
921 }
922
923 if (code_metadata.get_scopes_size() > 0) {
924 typeArrayHandle scopesArrayOop = oopFactory::new_byteArray(code_metadata.get_scopes_size(), CHECK_(JVMCIEnv::cache_full));
925 memcpy(scopesArrayOop->byte_at_addr(0), code_metadata.get_scopes_desc(), code_metadata.get_scopes_size());
926 HotSpotMetaData::set_scopesDescBytes(metadata_handle, scopesArrayOop());
927 }
928
929 RelocBuffer* reloc_buffer = code_metadata.get_reloc_buffer();
930 typeArrayHandle relocArrayOop = oopFactory::new_byteArray((int) reloc_buffer->size(), CHECK_(JVMCIEnv::cache_full));
931 if (reloc_buffer->size() > 0) {
932 memcpy(relocArrayOop->byte_at_addr(0), reloc_buffer->begin(), reloc_buffer->size());
933 }
934 HotSpotMetaData::set_relocBytes(metadata_handle, relocArrayOop());
935
936 const OopMapSet* oopMapSet = installer.oopMapSet();
937 {
938 ResourceMark mark;
939 ImmutableOopMapBuilder builder(oopMapSet);
940 int oopmap_size = builder.heap_size();
941 typeArrayHandle oopMapArrayHandle = oopFactory::new_byteArray(oopmap_size, CHECK_(JVMCIEnv::cache_full));
942 builder.generate_into((address) oopMapArrayHandle->byte_at_addr(0));
943 HotSpotMetaData::set_oopMaps(metadata_handle, oopMapArrayHandle());
944 }
945
946 AOTOopRecorder* recorder = code_metadata.get_oop_recorder();
947
948 int nr_meta_strings = recorder->nr_meta_strings();
949 objArrayHandle metadataArrayHandle = oopFactory::new_objectArray(nr_meta_strings, CHECK_(JVMCIEnv::cache_full));
950 for (int i = 0; i < nr_meta_strings; ++i) {
951 const char* element = recorder->meta_element(i);
952 Handle java_string = java_lang_String::create_from_str(element, CHECK_(JVMCIEnv::cache_full));
953 metadataArrayHandle->obj_at_put(i, java_string());
954 }
955 HotSpotMetaData::set_metadata(metadata_handle, metadataArrayHandle());
956
957 ExceptionHandlerTable* handler = code_metadata.get_exception_table();
958 int table_size = handler->size_in_bytes();
959 typeArrayHandle exceptionArrayOop = oopFactory::new_byteArray(table_size, CHECK_(JVMCIEnv::cache_full));
960
961 if (table_size > 0) {
962 handler->copy_bytes_to((address) exceptionArrayOop->byte_at_addr(0));
963 }
964 HotSpotMetaData::set_exceptionBytes(metadata_handle, exceptionArrayOop());
965
966 return result;
967 C2V_END
968
969 C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
970 JVMCICompiler* compiler = JVMCICompiler::instance(CHECK);
971 CompilerStatistics* stats = compiler->stats();
972 stats->_standard.reset();
973 stats->_osr.reset();
974 C2V_END
975
976 C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jobject installedCode))
977 ResourceMark rm;
978 HandleMark hm;
979
980 if (installedCode == NULL) {
981 THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "installedCode is null");
982 }
983
984 jlong codeBlob = InstalledCode::address(installedCode);
985 if (codeBlob == 0L) {
986 return NULL;
987 }
988
989 CodeBlob* cb = (CodeBlob*) (address) codeBlob;
990 if (cb == NULL) {
991 return NULL;
992 }
993
994 // We don't want the stringStream buffer to resize during disassembly as it
995 // uses scoped resource memory. If a nested function called during disassembly uses
996 // a ResourceMark and the buffer expands within the scope of the mark,
997 // the buffer becomes garbage when that scope is exited. Experience shows that
998 // the disassembled code is typically about 10x the code size so a fixed buffer
999 // sized to 20x code size plus a fixed amount for header info should be sufficient.
1000 int bufferSize = cb->code_size() * 20 + 1024;
1001 char* buffer = NEW_RESOURCE_ARRAY(char, bufferSize);
1002 stringStream st(buffer, bufferSize);
1003 if (cb->is_nmethod()) {
1004 nmethod* nm = (nmethod*) cb;
1005 if (!nm->is_alive()) {
1006 return NULL;
1007 }
1008 }
1009 Disassembler::decode(cb, &st);
1010 if (st.size() <= 0) {
1011 return NULL;
1012 }
1013
1014 Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
1015 return JNIHandles::make_local(THREAD, result());
1016 C2V_END
1017
1018 C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jobject jvmci_method, int bci))
1019 ResourceMark rm;
1020 HandleMark hm;
1021
1022 methodHandle method = CompilerToVM::asMethod(jvmci_method);
1023 oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
1024 return JNIHandles::make_local(THREAD, element);
1025 C2V_END
1026
1027 C2V_VMENTRY(jobject, executeInstalledCode, (JNIEnv*, jobject, jobject args, jobject hotspotInstalledCode))
1028 ResourceMark rm;
1029 HandleMark hm;
1030
1031 jlong nmethodValue = InstalledCode::address(hotspotInstalledCode);
1032 if (nmethodValue == 0L) {
1033 THROW_NULL(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
1034 }
1035 nmethod* nm = (nmethod*) (address) nmethodValue;
1036 methodHandle mh = nm->method();
1037 Symbol* signature = mh->signature();
1038 JavaCallArguments jca(mh->size_of_parameters());
1039
1040 JavaArgumentUnboxer jap(signature, &jca, (arrayOop) JNIHandles::resolve(args), mh->is_static());
1041 JavaValue result(jap.get_ret_type());
1042 jca.set_alternative_target(nm);
1043 JavaCalls::call(&result, mh, &jca, CHECK_NULL);
1044
1045 if (jap.get_ret_type() == T_VOID) {
1046 return NULL;
1047 } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
1048 return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
1049 } else {
1050 jvalue *value = (jvalue *) result.get_value_addr();
1051 // Narrow the value down if required (Important on big endian machines)
1052 switch (jap.get_ret_type()) {
1053 case T_BOOLEAN:
1054 value->z = (jboolean) value->i;
1055 break;
1056 case T_BYTE:
1057 value->b = (jbyte) value->i;
1058 break;
1059 case T_CHAR:
1060 value->c = (jchar) value->i;
1061 break;
1062 case T_SHORT:
1063 value->s = (jshort) value->i;
1064 break;
1065 }
1066 oop o = java_lang_boxing_object::create(jap.get_ret_type(), value, CHECK_NULL);
1067 return JNIHandles::make_local(THREAD, o);
1068 }
1069 C2V_END
1070
1071 C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jobject jvmci_method))
1072 Method* method = CompilerToVM::asMethod(jvmci_method);
1073 if (!method->has_linenumber_table()) {
1074 return NULL;
1075 }
1076 u2 num_entries = 0;
1077 CompressedLineNumberReadStream streamForSize(method->compressed_linenumber_table());
1078 while (streamForSize.read_pair()) {
1079 num_entries++;
1080 }
1081
1082 CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
1083 typeArrayOop result = oopFactory::new_longArray(2 * num_entries, CHECK_NULL);
1084
1085 int i = 0;
1086 jlong value;
1087 while (stream.read_pair()) {
1088 value = ((long) stream.bci());
1089 result->long_at_put(i, value);
1090 value = ((long) stream.line());
1091 result->long_at_put(i + 1, value);
1092 i += 2;
1093 }
1094
1095 return (jlongArray) JNIHandles::make_local(THREAD, result);
1096 C2V_END
1097
1098 C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jobject jvmci_method))
1099 ResourceMark rm;
1100 Method* method = CompilerToVM::asMethod(jvmci_method);
1101 if (!method->has_localvariable_table()) {
1102 return 0;
1103 }
1104 return (jlong) (address) method->localvariable_table_start();
1105 C2V_END
1106
1107 C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv *, jobject, jobject jvmci_method))
1108 ResourceMark rm;
1109 Method* method = CompilerToVM::asMethod(jvmci_method);
1110 return method->localvariable_table_length();
1111 C2V_END
1112
1113 C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jobject jvmci_method))
1114 Method* method = CompilerToVM::asMethod(jvmci_method);
1115 MethodCounters* mcs = method->method_counters();
1116 if (mcs != NULL) {
1117 mcs->clear_counters();
1118 }
1119 NOT_PRODUCT(method->set_compiled_invocation_count(0));
1120
1121 CompiledMethod* code = method->code();
1122 if (code != NULL) {
1123 code->make_not_entrant();
1124 }
1125
1126 MethodData* method_data = method->method_data();
1127 if (method_data == NULL) {
1128 ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
1129 method_data = MethodData::allocate(loader_data, method, CHECK);
1130 method->set_method_data(method_data);
1131 } else {
1132 method_data->initialize();
1133 }
1134 C2V_END
1135
1136
1137 C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject installed_code))
1138 Handle installed_code_handle = JNIHandles::resolve(installed_code);
1139 nmethod::invalidate_installed_code(installed_code_handle, CHECK);
1140 C2V_END
1141
1142 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
1143 typeArrayOop arrayOop = oopFactory::new_longArray(JVMCICounterSize, CHECK_NULL);
1144 JavaThread::collect_counters(arrayOop);
1145 return (jlongArray) JNIHandles::make_local(THREAD, arrayOop);
1146 C2V_END
1147
1148 C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci))
1149 HandleMark hm;
1150 ResourceMark rm;
1151 if (JNIHandles::resolve(jvmci_method) == NULL) {
1152 THROW_0(vmSymbols::java_lang_NullPointerException());
1153 }
1154 Method* method = CompilerToVM::asMethod(jvmci_method);
1155 if (entry_bci >= method->code_size() || entry_bci < -1) {
1156 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Unexpected bci %d", entry_bci));
1157 }
1158 return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
1159 C2V_END
1160
1161
1162 C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data))
1163 MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
1164 return mdo != NULL && mdo->is_mature();
1165 C2V_END
1166
1167 C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci, int comp_level))
1168 Method* method = CompilerToVM::asMethod(jvmci_method);
1169 return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
1170 C2V_END
1171
1172 C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong symbol))
1173 Handle sym = java_lang_String::create_from_symbol((Symbol*)(address)symbol, CHECK_NULL);
1174 return JNIHandles::make_local(THREAD, sym());
1175 C2V_END
1176
1177 bool matches(jobjectArray methods, Method* method) {
1178 objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
1179
1180 for (int i = 0; i < methods_oop->length(); i++) {
1181 oop resolved = methods_oop->obj_at(i);
1182 if (resolved->is_a(HotSpotResolvedJavaMethodImpl::klass()) && CompilerToVM::asMethod(resolved) == method) {
1183 return true;
1184 }
1185 }
1186 return false;
1187 }
1188
1189 C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jobjectArray methods, jint initialSkip))
1190 ResourceMark rm;
1191
1192 if (!thread->has_last_Java_frame()) return NULL;
1193 Handle result = HotSpotStackFrameReference::klass()->allocate_instance(thread);
1194 HotSpotStackFrameReference::klass()->initialize(thread);
1195
1196 StackFrameStream fst(thread);
1197 if (hs_frame != NULL) {
1198 // look for the correct stack frame if one is given
1199 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
1200 while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
1201 fst.next();
1202 }
1203 if (fst.current()->sp() != stack_pointer) {
1204 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "stack frame not found")
1205 }
1206 }
1207
1208 int frame_number = 0;
1209 vframe* vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
1210 if (hs_frame != NULL) {
1211 // look for the correct vframe within the stack frame if one is given
1212 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
1213 while (frame_number < last_frame_number) {
1214 if (vf->is_top()) {
1215 THROW_MSG_NULL(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
1216 }
1217 vf = vf->sender();
1218 frame_number ++;
1219 }
1220 // move one frame forward
1221 if (vf->is_top()) {
1222 if (fst.is_done()) {
1223 return NULL;
1224 }
1225 fst.next();
1226 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
1227 frame_number = 0;
1228 } else {
1229 vf = vf->sender();
1230 frame_number++;
1231 }
1232 }
1233
1234 while (true) {
1235 // look for the given method
1236 while (true) {
1237 StackValueCollection* locals = NULL;
1238 if (vf->is_compiled_frame()) {
1239 // compiled method frame
1240 compiledVFrame* cvf = compiledVFrame::cast(vf);
1241 if (methods == NULL || matches(methods, cvf->method())) {
1242 if (initialSkip > 0) {
1243 initialSkip --;
1244 } else {
1245 ScopeDesc* scope = cvf->scope();
1246 // native wrapper do not have a scope
1247 if (scope != NULL && scope->objects() != NULL) {
1248 bool realloc_failures = Deoptimization::realloc_objects(thread, fst.current(), scope->objects(), THREAD);
1249 Deoptimization::reassign_fields(fst.current(), fst.register_map(), scope->objects(), realloc_failures, false);
1250
1251 GrowableArray<ScopeValue*>* local_values = scope->locals();
1252 typeArrayHandle array = oopFactory::new_boolArray(local_values->length(), thread);
1253 for (int i = 0; i < local_values->length(); i++) {
1254 ScopeValue* value = local_values->at(i);
1255 if (value->is_object()) {
1256 array->bool_at_put(i, true);
1257 }
1258 }
1259 HotSpotStackFrameReference::set_localIsVirtual(result, array());
1260 } else {
1261 HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
1262 }
1263
1264 locals = cvf->locals();
1265 HotSpotStackFrameReference::set_bci(result, cvf->bci());
1266 oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL);
1267 HotSpotStackFrameReference::set_method(result, method);
1268 }
1269 }
1270 } else if (vf->is_interpreted_frame()) {
1271 // interpreted method frame
1272 interpretedVFrame* ivf = interpretedVFrame::cast(vf);
1273 if (methods == NULL || matches(methods, ivf->method())) {
1274 if (initialSkip > 0) {
1275 initialSkip --;
1276 } else {
1277 locals = ivf->locals();
1278 HotSpotStackFrameReference::set_bci(result, ivf->bci());
1279 oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL);
1280 HotSpotStackFrameReference::set_method(result, method);
1281 HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
1282 }
1283 }
1284 }
1285
1286 // locals != NULL means that we found a matching frame and result is already partially initialized
1287 if (locals != NULL) {
1288 HotSpotStackFrameReference::set_compilerToVM(result, JNIHandles::resolve(compilerToVM));
1289 HotSpotStackFrameReference::set_stackPointer(result, (jlong) fst.current()->sp());
1290 HotSpotStackFrameReference::set_frameNumber(result, frame_number);
1291
1292 // initialize the locals array
1293 objArrayHandle array = oopFactory::new_objectArray(locals->size(), thread);
1294 for (int i = 0; i < locals->size(); i++) {
1295 StackValue* var = locals->at(i);
1296 if (var->type() == T_OBJECT) {
1297 array->obj_at_put(i, locals->at(i)->get_obj()());
1298 }
1299 }
1300 HotSpotStackFrameReference::set_locals(result, array());
1301
1302 return JNIHandles::make_local(thread, result());
1303 }
1304
1305 if (vf->is_top()) {
1306 break;
1307 }
1308 frame_number++;
1309 vf = vf->sender();
1310 } // end of vframe loop
1311
1312 if (fst.is_done()) {
1313 break;
1314 }
1315 fst.next();
1316 vf = vframe::new_vframe(fst.current(), fst.register_map(), thread);
1317 frame_number = 0;
1318 } // end of frame loop
1319
1320 // the end was reached without finding a matching method
1321 return NULL;
1322 C2V_END
1323
1324 C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
1325 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
1326 CallInfo callInfo;
1327 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);
1328 ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);
1329 cp_cache_entry->set_dynamic_call(cp, callInfo);
1330 C2V_END
1331
1332 C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
1333 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
1334 KlassHandle holder = cp->klass_ref_at(index, CHECK);
1335 Symbol* name = cp->name_ref_at(index);
1336 if (MethodHandles::is_signature_polymorphic_name(holder(), name)) {
1337 CallInfo callInfo;
1338 LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokehandle, CHECK);
1339 ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
1340 cp_cache_entry->set_method_handle(cp, callInfo);
1341 }
1342 C2V_END
1343
1344 C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv*, jobject))
1345 objArrayHandle holders = oopFactory::new_objArray(SystemDictionary::String_klass(), 2, CHECK_NULL);
1346 Handle mh = java_lang_String::create_from_str("Ljava/lang/invoke/MethodHandle;", CHECK_NULL);
1347 Handle vh = java_lang_String::create_from_str("Ljava/lang/invoke/VarHandle;", CHECK_NULL);
1348 holders->obj_at_put(0, mh());
1349 holders->obj_at_put(1, vh());
1350 return JNIHandles::make_local(THREAD, holders());
1351 C2V_END
1352
1353 C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject))
1354 //see compute_recording_non_safepoints in debugInfroRec.cpp
1355 if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
1356 return true;
1357 }
1358 return DebugNonSafepoints;
1359 C2V_END
1360
1361 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
1362 C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame, bool invalidate))
1363 ResourceMark rm;
1364
1365 if (hs_frame == NULL) {
1366 THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null")
1367 }
1368
1369 HotSpotStackFrameReference::klass()->initialize(thread);
1370
1371 // look for the given stack frame
1372 StackFrameStream fst(thread);
1373 intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
1374 while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
1375 fst.next();
1376 }
1377 if (fst.current()->sp() != stack_pointer) {
1378 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found")
1379 }
1380
1381 if (invalidate) {
1382 if (!fst.current()->is_compiled_frame()) {
1383 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
1384 }
1385 assert(fst.current()->cb()->is_nmethod(), "nmethod expected");
1386 ((nmethod*) fst.current()->cb())->make_not_entrant();
1387 }
1388 Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_none);
1389 // look for the frame again as it has been updated by deopt (pc, deopt state...)
1390 StackFrameStream fstAfterDeopt(thread);
1391 while (fstAfterDeopt.current()->sp() != stack_pointer && !fstAfterDeopt.is_done()) {
1392 fstAfterDeopt.next();
1393 }
1394 if (fstAfterDeopt.current()->sp() != stack_pointer) {
1395 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found after deopt")
1396 }
1397
1398 vframe* vf = vframe::new_vframe(fstAfterDeopt.current(), fstAfterDeopt.register_map(), thread);
1399 if (!vf->is_compiled_frame()) {
1400 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
1401 }
1402
1403 GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10);
1404 while (true) {
1405 assert(vf->is_compiled_frame(), "Wrong frame type");
1406 virtualFrames->push(compiledVFrame::cast(vf));
1407 if (vf->is_top()) {
1408 break;
1409 }
1410 vf = vf->sender();
1411 }
1412
1413 int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
1414 if (last_frame_number >= virtualFrames->length()) {
1415 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
1416 }
1417
1418 // Reallocate the non-escaping objects and restore their fields.
1419 assert (virtualFrames->at(last_frame_number)->scope() != NULL,"invalid scope");
1420 GrowableArray<ScopeValue*>* objects = virtualFrames->at(last_frame_number)->scope()->objects();
1421
1422 if (objects == NULL) {
1423 // no objects to materialize
1424 return;
1425 }
1426
1427 bool realloc_failures = Deoptimization::realloc_objects(thread, fstAfterDeopt.current(), objects, THREAD);
1428 Deoptimization::reassign_fields(fstAfterDeopt.current(), fstAfterDeopt.register_map(), objects, realloc_failures, false);
1429
1430 for (int frame_index = 0; frame_index < virtualFrames->length(); frame_index++) {
1431 compiledVFrame* cvf = virtualFrames->at(frame_index);
1432
1433 GrowableArray<ScopeValue*>* scopeLocals = cvf->scope()->locals();
1434 StackValueCollection* locals = cvf->locals();
1435
1436 if (locals != NULL) {
1437 for (int i2 = 0; i2 < locals->size(); i2++) {
1438 StackValue* var = locals->at(i2);
1439 if (var->type() == T_OBJECT && scopeLocals->at(i2)->is_object()) {
1440 jvalue val;
1441 val.l = (jobject) locals->at(i2)->get_obj()();
1442 cvf->update_local(T_OBJECT, i2, val);
1443 }
1444 }
1445 }
1446 }
1447
1448 // all locals are materialized by now
1449 HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL);
1450
1451 // update the locals array
1452 objArrayHandle array = HotSpotStackFrameReference::locals(hs_frame);
1453 StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();
1454 for (int i = 0; i < locals->size(); i++) {
1455 StackValue* var = locals->at(i);
1456 if (var->type() == T_OBJECT) {
1457 array->obj_at_put(i, locals->at(i)->get_obj()());
1458 }
1459 }
1460 C2V_END
1461
1462 C2V_VMENTRY(void, writeDebugOutput, (JNIEnv*, jobject, jbyteArray bytes, jint offset, jint length))
1463 if (bytes == NULL) {
1464 THROW(vmSymbols::java_lang_NullPointerException());
1465 }
1466 typeArrayOop array = (typeArrayOop) JNIHandles::resolve(bytes);
1467
1468 // Check if offset and length are non negative.
1469 if (offset < 0 || length < 0) {
1470 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
1471 }
1472 // Check if the range is valid.
1473 if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array->length())) {
1474 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
1475 }
1476 while (length > 0) {
1477 jbyte* start = array->byte_at_addr(offset);
1478 tty->write((char*) start, MIN2(length, O_BUFLEN));
1479 length -= O_BUFLEN;
1480 offset += O_BUFLEN;
1481 }
1482 C2V_END
1483
1484 C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject))
1485 tty->flush();
1486 C2V_END
1487
1488 C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv*, jobject, jlong metaspace_method_data, jint position))
1489 ResourceMark rm;
1490 MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
1491 ProfileData* profile_data = mdo->data_at(position);
1492 if (mdo->is_valid(profile_data)) {
1493 return profile_data->size_in_bytes();
1494 }
1495 DataLayout* data = mdo->extra_data_base();
1496 DataLayout* end = mdo->extra_data_limit();
1497 for (;; data = mdo->next_extra(data)) {
1498 assert(data < end, "moved past end of extra data");
1499 profile_data = data->data_in();
1500 if (mdo->dp_to_di(profile_data->dp()) == position) {
1501 return profile_data->size_in_bytes();
1502 }
1503 }
1504 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid profile data position %d", position));
1505 C2V_END
1506
1507 C2V_VMENTRY(jlong, getFingerprint, (JNIEnv*, jobject, jlong metaspace_klass))
1508 Klass *k = CompilerToVM::asKlass(metaspace_klass);
1509 if (k->is_instance_klass()) {
1510 return InstanceKlass::cast(k)->get_stored_fingerprint();
1511 } else {
1512 return 0;
1513 }
1514 C2V_END
1515
1516 C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv*, jobject, jobject bytecode_frame_handle))
1517 if (bytecode_frame_handle == NULL) {
1518 THROW_0(vmSymbols::java_lang_NullPointerException());
1519 }
1520
1521 oop top_bytecode_frame = JNIHandles::resolve_non_null(bytecode_frame_handle);
1522 oop bytecode_frame = top_bytecode_frame;
1523 int size = 0;
1524 int callee_parameters = 0;
1525 int callee_locals = 0;
1526 Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame));
1527 int extra_args = method->max_stack() - BytecodeFrame::numStack(bytecode_frame);
1528
1529 while (bytecode_frame != NULL) {
1530 int locks = BytecodeFrame::numLocks(bytecode_frame);
1531 int temps = BytecodeFrame::numStack(bytecode_frame);
1532 bool is_top_frame = (bytecode_frame == top_bytecode_frame);
1533 Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame));
1534
1535 int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
1536 temps + callee_parameters,
1537 extra_args,
1538 locks,
1539 callee_parameters,
1540 callee_locals,
1541 is_top_frame);
1542 size += frame_size;
1543
1544 callee_parameters = method->size_of_parameters();
1545 callee_locals = method->max_locals();
1546 extra_args = 0;
1547 bytecode_frame = BytecodePosition::caller(bytecode_frame);
1548 }
1549 return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
1550 C2V_END
1551
1552 C2V_VMENTRY(void, compileToBytecode, (JNIEnv*, jobject, jobject lambda_form_handle))
1553 Handle lambda_form = JNIHandles::resolve_non_null(lambda_form_handle);
1554 if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) {
1555 TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK);
1556 JavaValue result(T_VOID);
1557 JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);
1558 } else {
1559 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1560 err_msg("Unexpected type: %s", lambda_form->klass()->external_name()));
1561 }
1562 C2V_END
1563
1564 #define CC (char*) /*cast a literal from (const char*)*/
1565 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
1566
1567 #define STRING "Ljava/lang/String;"
1568 #define OBJECT "Ljava/lang/Object;"
1569 #define CLASS "Ljava/lang/Class;"
1570 #define EXECUTABLE "Ljava/lang/reflect/Executable;"
1571 #define STACK_TRACE_ELEMENT "Ljava/lang/StackTraceElement;"
1572 #define INSTALLED_CODE "Ljdk/vm/ci/code/InstalledCode;"
1573 #define TARGET_DESCRIPTION "Ljdk/vm/ci/code/TargetDescription;"
1574 #define BYTECODE_FRAME "Ljdk/vm/ci/code/BytecodeFrame;"
1575 #define RESOLVED_METHOD "Ljdk/vm/ci/meta/ResolvedJavaMethod;"
1576 #define HS_RESOLVED_METHOD "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;"
1577 #define HS_RESOLVED_KLASS "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;"
1578 #define HS_CONSTANT_POOL "Ljdk/vm/ci/hotspot/HotSpotConstantPool;"
1579 #define HS_COMPILED_CODE "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"
1580 #define HS_CONFIG "Ljdk/vm/ci/hotspot/HotSpotVMConfig;"
1581 #define HS_METADATA "Ljdk/vm/ci/hotspot/HotSpotMetaData;"
1582 #define HS_STACK_FRAME_REF "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"
1583 #define HS_SPECULATION_LOG "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;"
1584 #define METASPACE_METHOD_DATA "J"
1585
1586 JNINativeMethod CompilerToVM::methods[] = {
1587 {CC "getBytecode", CC "(" HS_RESOLVED_METHOD ")[B", FN_PTR(getBytecode)},
1588 {CC "getExceptionTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getExceptionTableStart)},
1589 {CC "getExceptionTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getExceptionTableLength)},
1590 {CC "findUniqueConcreteMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")" HS_RESOLVED_METHOD, FN_PTR(findUniqueConcreteMethod)},
1591 {CC "getImplementor", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getImplementor)},
1592 {CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)},
1593 {CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)},
1594 {CC "doNotInlineOrCompile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(doNotInlineOrCompile)},
1595 {CC "canInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(canInlineMethod)},
1596 {CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},
1597 {CC "lookupType", CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS, FN_PTR(lookupType)},
1598 {CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},
1599 {CC "lookupNameAndTypeRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)},
1600 {CC "lookupSignatureInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupSignatureInPool)},
1601 {CC "lookupKlassRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupKlassRefIndexInPool)},
1602 {CC "lookupKlassInPool", CC "(" HS_CONSTANT_POOL "I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)},
1603 {CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(lookupAppendixInPool)},
1604 {CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)},
1605 {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
1606 {CC "resolveConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolveConstantInPool)},
1607 {CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)},
1608 {CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)},
1609 {CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[J)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)},
1610 {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},
1611 {CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeHandleInPool)},
1612 {CC "resolveMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
1613 {CC "getSignaturePolymorphicHolders", CC "()[" STRING, FN_PTR(getSignaturePolymorphicHolders)},
1614 {CC "getVtableIndexForInterfaceMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I", FN_PTR(getVtableIndexForInterfaceMethod)},
1615 {CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)},
1616 {CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)},
1617 {CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},
1618 {CC "asResolvedJavaMethod", CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD, FN_PTR(asResolvedJavaMethod)},
1619 {CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
1620 {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
1621 {CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
1622 {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
1623 {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},
1624 {CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},
1625 {CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
1626 {CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
1627 {CC "executeInstalledCode", CC "([" OBJECT INSTALLED_CODE ")" OBJECT, FN_PTR(executeInstalledCode)},
1628 {CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},
1629 {CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},
1630 {CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},
1631 {CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},
1632 {CC "invalidateInstalledCode", CC "(" INSTALLED_CODE ")V", FN_PTR(invalidateInstalledCode)},
1633 {CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
1634 {CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},
1635 {CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},
1636 {CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
1637 {CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
1638 {CC "getNextStackFrame", CC "(" HS_STACK_FRAME_REF "[" RESOLVED_METHOD "I)" HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
1639 {CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
1640 {CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
1641 {CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
1642 {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
1643 {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
1644 {CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
1645 {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
1646 {CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)},
1647 };
1648
1649 int CompilerToVM::methods_count() {
1650 return sizeof(methods) / sizeof(JNINativeMethod);
1651 }
--- EOF ---