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 }
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 cardtable_start_address = 0;
178 cardtable_shift = 0;
179 // No post barriers
180 break;
181 default:
182 ShouldNotReachHere();
183 break;
184 }
185
186 vm_page_size = os::vm_page_size();
187
188 #define SET_TRIGFUNC(name) \
189 if (StubRoutines::name() != NULL) { \
190 name = StubRoutines::name(); \
191 } else { \
192 name = CAST_FROM_FN_PTR(address, SharedRuntime::name); \
193 }
194
195 SET_TRIGFUNC(dsin);
196 SET_TRIGFUNC(dcos);
197 SET_TRIGFUNC(dtan);
198 SET_TRIGFUNC(dexp);
199 SET_TRIGFUNC(dlog10);
200 SET_TRIGFUNC(dlog);
201 SET_TRIGFUNC(dpow);
202
220 kls_sid = SID_ENUM(kls); \
221 } \
222 Handle name_str = VM_SYMBOL_TO_STRING(name); \
223 Handle sig_str = VM_SYMBOL_TO_STRING(sig); \
224 VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str()); \
225 VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str()); \
226 VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str()); \
227 VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id); \
228 vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod()); \
229 }
230
231 VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
232 #undef SID_ENUM
233 #undef VM_SYMBOL_TO_STRING
234 #undef VM_INTRINSIC_INFO
235 assert(index == vmIntrinsics::ID_LIMIT - 1, "must be");
236
237 return vmIntrinsics;
238 }
239
240 C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
241 #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)
242 #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)
243 ResourceMark rm;
244 HandleMark hm;
245
246 CompilerToVM::Data::initialize();
247
248 VMField::klass()->initialize(CHECK_NULL);
249 VMFlag::klass()->initialize(CHECK_NULL);
250 VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
251
252 int len = JVMCIVMStructs::localHotSpotVMStructs_count();
253 objArrayHandle vmFields = oopFactory::new_objArray(VMField::klass(), len, CHECK_NULL);
254 for (int i = 0; i < len ; i++) {
255 VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
256 instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
257 size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
258 char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
259 sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
260 Handle name = java_lang_String::create_from_str(name_buf, CHECK_NULL);
261 Handle type = java_lang_String::create_from_str(vmField.typeString, CHECK_NULL);
262 VMField::set_name(vmFieldObj, name());
263 VMField::set_type(vmFieldObj, type());
264 VMField::set_offset(vmFieldObj, vmField.offset);
265 VMField::set_address(vmFieldObj, (jlong) vmField.address);
266 if (vmField.isStatic) {
267 if (strcmp(vmField.typeString, "bool") == 0) {
268 BOXED_LONG(value, *(jbyte*) vmField.address);
269 VMField::set_value(vmFieldObj, value);
270 } else if (strcmp(vmField.typeString, "int") == 0 ||
271 strcmp(vmField.typeString, "jint") == 0) {
272 BOXED_LONG(value, *(jint*) vmField.address);
273 VMField::set_value(vmFieldObj, value);
274 } else if (strcmp(vmField.typeString, "uint64_t") == 0) {
275 BOXED_LONG(value, *(uint64_t*) vmField.address);
276 VMField::set_value(vmFieldObj, value);
277 } else if (strcmp(vmField.typeString, "address") == 0 ||
278 strcmp(vmField.typeString, "intptr_t") == 0 ||
279 strcmp(vmField.typeString, "uintptr_t") == 0 ||
280 strcmp(vmField.typeString, "size_t") == 0 ||
281 // All foo* types are addresses.
282 vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
283 BOXED_LONG(value, *((address*) vmField.address));
284 VMField::set_value(vmFieldObj, value);
285 } else {
286 JVMCI_ERROR_NULL("VM field %s has unsupported type %s", name_buf, vmField.typeString);
287 }
288 }
289 vmFields->obj_at_put(i, vmFieldObj());
290 }
291
292 len = JVMCIVMStructs::localHotSpotVMTypes_count();
293 objArrayHandle vmTypes = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
294 for (int i = 0; i < len ; i++) {
295 VMTypeEntry vmType = JVMCIVMStructs::localHotSpotVMTypes[i];
296 Handle name = java_lang_String::create_from_str(vmType.typeName, CHECK_NULL);
297 BOXED_LONG(size, vmType.size);
298 vmTypes->obj_at_put(i * 2, name());
299 vmTypes->obj_at_put(i * 2 + 1, size);
300 }
301
302 int ints_len = JVMCIVMStructs::localHotSpotVMIntConstants_count();
303 int longs_len = JVMCIVMStructs::localHotSpotVMLongConstants_count();
304 len = ints_len + longs_len;
305 objArrayHandle vmConstants = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
306 int insert = 0;
307 for (int i = 0; i < ints_len ; i++) {
308 VMIntConstantEntry c = JVMCIVMStructs::localHotSpotVMIntConstants[i];
309 Handle name = java_lang_String::create_from_str(c.name, CHECK_NULL);
310 BOXED_LONG(value, c.value);
311 vmConstants->obj_at_put(insert++, name());
312 vmConstants->obj_at_put(insert++, value);
313 }
314 for (int i = 0; i < longs_len ; i++) {
315 VMLongConstantEntry c = JVMCIVMStructs::localHotSpotVMLongConstants[i];
316 Handle name = java_lang_String::create_from_str(c.name, CHECK_NULL);
317 BOXED_LONG(value, c.value);
318 vmConstants->obj_at_put(insert++, name());
319 vmConstants->obj_at_put(insert++, value);
320 }
321 assert(insert == len * 2, "must be");
322
323 len = JVMCIVMStructs::localHotSpotVMAddresses_count();
324 objArrayHandle vmAddresses = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
325 for (int i = 0; i < len ; i++) {
326 VMAddressEntry a = JVMCIVMStructs::localHotSpotVMAddresses[i];
327 Handle name = java_lang_String::create_from_str(a.name, CHECK_NULL);
328 BOXED_LONG(value, a.value);
329 vmAddresses->obj_at_put(i * 2, name());
330 vmAddresses->obj_at_put(i * 2 + 1, value);
331 }
332
333 // The last entry is the null entry.
334 len = (int) Flag::numFlags - 1;
335 objArrayHandle vmFlags = oopFactory::new_objArray(VMFlag::klass(), len, CHECK_NULL);
336 for (int i = 0; i < len; i++) {
337 Flag* flag = &Flag::flags[i];
338 instanceHandle vmFlagObj = InstanceKlass::cast(VMFlag::klass())->allocate_instance_handle(CHECK_NULL);
339 Handle name = java_lang_String::create_from_str(flag->_name, CHECK_NULL);
340 Handle type = java_lang_String::create_from_str(flag->_type, CHECK_NULL);
341 VMFlag::set_name(vmFlagObj, name());
342 VMFlag::set_type(vmFlagObj, type());
343 if (flag->is_bool()) {
344 BOXED_LONG(value, flag->get_bool());
345 VMFlag::set_value(vmFlagObj, value);
346 } else if (flag->is_ccstr()) {
347 Handle value = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_NULL);
348 VMFlag::set_value(vmFlagObj, value());
349 } else if (flag->is_int()) {
350 BOXED_LONG(value, flag->get_int());
351 VMFlag::set_value(vmFlagObj, value);
352 } else if (flag->is_intx()) {
353 BOXED_LONG(value, flag->get_intx());
354 VMFlag::set_value(vmFlagObj, value);
355 } else if (flag->is_uint()) {
356 BOXED_LONG(value, flag->get_uint());
357 VMFlag::set_value(vmFlagObj, value);
358 } else if (flag->is_uint64_t()) {
359 BOXED_LONG(value, flag->get_uint64_t());
360 VMFlag::set_value(vmFlagObj, value);
361 } else if (flag->is_uintx()) {
362 BOXED_LONG(value, flag->get_uintx());
363 VMFlag::set_value(vmFlagObj, value);
364 } else if (flag->is_double()) {
365 BOXED_DOUBLE(value, flag->get_double());
366 VMFlag::set_value(vmFlagObj, value);
367 } else if (flag->is_size_t()) {
368 BOXED_LONG(value, flag->get_size_t());
369 VMFlag::set_value(vmFlagObj, value);
370 } else {
371 JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type);
372 }
373 vmFlags->obj_at_put(i, vmFlagObj());
374 }
375
376 objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
377
378 objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 6, CHECK_NULL);
379 data->obj_at_put(0, vmFields());
380 data->obj_at_put(1, vmTypes());
381 data->obj_at_put(2, vmConstants());
382 data->obj_at_put(3, vmAddresses());
383 data->obj_at_put(4, vmFlags());
384 data->obj_at_put(5, vmIntrinsics());
385
386 return (jobjectArray) JNIHandles::make_local(THREAD, data);
387 #undef BOXED_LONG
388 #undef BOXED_DOUBLE
389 C2V_END
390
391 C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
392 methodHandle method = CompilerToVM::asMethod(jvmci_method);
393 ResourceMark rm;
394
395 int code_size = method->code_size();
396 typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL);
397
398 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
399 // iterate over all bytecodes and replace non-Java bytecodes
400
401 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
402 Bytecodes::Code code = s.code();
403 Bytecodes::Code raw_code = s.raw_code();
404 int bci = s.bci();
405 int len = s.instruction_size();
406
407 // Restore original byte code.
408 reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code));
409 if (len > 1) {
726 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
727 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
728 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
729 return JNIHandles::make_local(THREAD, appendix_oop);
730 C2V_END
731
732 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
733 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
734 instanceKlassHandle pool_holder(cp->pool_holder());
735 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
736 methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder);
737 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
738 return JNIHandles::make_local(THREAD, result);
739 C2V_END
740
741 C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
742 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
743 return cp->remap_instruction_operand_from_cache(index);
744 C2V_END
745
746 C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jlongArray info_handle))
747 ResourceMark rm;
748 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
749 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
750 fieldDescriptor fd;
751 LinkInfo link_info(cp, index, (jvmci_method != NULL) ? CompilerToVM::asMethod(jvmci_method) : NULL, CHECK_0);
752 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
753 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
754 assert(info != NULL && info->length() == 2, "must be");
755 info->long_at_put(0, (jlong) fd.access_flags().as_int());
756 info->long_at_put(1, (jlong) fd.offset());
757 oop field_holder = CompilerToVM::get_jvmci_type(fd.field_holder(), CHECK_NULL);
758 return JNIHandles::make_local(THREAD, field_holder);
759 C2V_END
760
761 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
762 ResourceMark rm;
763 Klass* klass = CompilerToVM::asKlass(jvmci_type);
764 Method* method = CompilerToVM::asMethod(jvmci_method);
765 if (klass->is_interface()) {
766 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name()));
767 }
768 if (!method->method_holder()->is_interface()) {
769 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()));
770 }
771 if (!InstanceKlass::cast(klass)->is_linked()) {
772 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name()));
773 }
774 return LinkResolver::vtable_index_of_interface_method(klass, method);
775 C2V_END
776
1593 {CC "findUniqueConcreteMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")" HS_RESOLVED_METHOD, FN_PTR(findUniqueConcreteMethod)},
1594 {CC "getImplementor", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getImplementor)},
1595 {CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)},
1596 {CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)},
1597 {CC "doNotInlineOrCompile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(doNotInlineOrCompile)},
1598 {CC "isCompilable", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(isCompilable)},
1599 {CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)},
1600 {CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},
1601 {CC "lookupType", CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS, FN_PTR(lookupType)},
1602 {CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},
1603 {CC "lookupNameAndTypeRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)},
1604 {CC "lookupSignatureInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupSignatureInPool)},
1605 {CC "lookupKlassRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupKlassRefIndexInPool)},
1606 {CC "lookupKlassInPool", CC "(" HS_CONSTANT_POOL "I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)},
1607 {CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(lookupAppendixInPool)},
1608 {CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)},
1609 {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
1610 {CC "resolveConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolveConstantInPool)},
1611 {CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)},
1612 {CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)},
1613 {CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[J)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)},
1614 {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},
1615 {CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeHandleInPool)},
1616 {CC "resolveMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
1617 {CC "getSignaturePolymorphicHolders", CC "()[" STRING, FN_PTR(getSignaturePolymorphicHolders)},
1618 {CC "getVtableIndexForInterfaceMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I", FN_PTR(getVtableIndexForInterfaceMethod)},
1619 {CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)},
1620 {CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)},
1621 {CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},
1622 {CC "asResolvedJavaMethod", CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD, FN_PTR(asResolvedJavaMethod)},
1623 {CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
1624 {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
1625 {CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
1626 {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
1627 {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},
1628 {CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},
1629 {CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
1630 {CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
1631 {CC "executeInstalledCode", CC "([" OBJECT INSTALLED_CODE ")" OBJECT, FN_PTR(executeInstalledCode)},
1632 {CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},
1633 {CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},
1634 {CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},
1635 {CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},
1636 {CC "invalidateInstalledCode", CC "(" INSTALLED_CODE ")V", FN_PTR(invalidateInstalledCode)},
1637 {CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
1638 {CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},
1639 {CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},
1640 {CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
1641 {CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
1642 {CC "getNextStackFrame", CC "(" HS_STACK_FRAME_REF "[" RESOLVED_METHOD "I)" HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
1643 {CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
1644 {CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
1645 {CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
1646 {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
1647 {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
1648 {CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
1649 {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
1650 {CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)},
1651 };
1652
1653 int CompilerToVM::methods_count() {
1654 return sizeof(methods) / sizeof(JNINativeMethod);
1655 }
|
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 #include "utilities/resourceHash.hpp"
57
58
59 // Entry to native method implementation that transitions current thread to '_thread_in_vm'.
60 #define C2V_VMENTRY(result_type, name, signature) \
61 JNIEXPORT result_type JNICALL c2v_ ## name signature { \
62 TRACE_jvmci_1("CompilerToVM::" #name); \
63 TRACE_CALL(result_type, jvmci_ ## name signature) \
64 JVMCI_VM_ENTRY_MARK; \
65
66 #define C2V_END }
67
68 oop CompilerToVM::get_jvmci_method(const methodHandle& method, TRAPS) {
69 if (method() != NULL) {
70 JavaValue result(T_OBJECT);
71 JavaCallArguments args;
72 args.push_long((jlong) (address) method());
73 JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_NULL);
74
75 return (oop)result.get_jobject();
76 }
104 CollectedHeap* CompilerToVM::Data::Universe_collectedHeap;
105 int CompilerToVM::Data::Universe_base_vtable_size;
106 address CompilerToVM::Data::Universe_narrow_oop_base;
107 int CompilerToVM::Data::Universe_narrow_oop_shift;
108 address CompilerToVM::Data::Universe_narrow_klass_base;
109 int CompilerToVM::Data::Universe_narrow_klass_shift;
110 void* CompilerToVM::Data::Universe_non_oop_bits;
111 uintptr_t CompilerToVM::Data::Universe_verify_oop_mask;
112 uintptr_t CompilerToVM::Data::Universe_verify_oop_bits;
113
114 bool CompilerToVM::Data::_supports_inline_contig_alloc;
115 HeapWord** CompilerToVM::Data::_heap_end_addr;
116 HeapWord* volatile* CompilerToVM::Data::_heap_top_addr;
117 int CompilerToVM::Data::_max_oop_map_stack_offset;
118
119 jbyte* CompilerToVM::Data::cardtable_start_address;
120 int CompilerToVM::Data::cardtable_shift;
121
122 int CompilerToVM::Data::vm_page_size;
123
124 int CompilerToVM::Data::sizeof_vtableEntry = sizeof(vtableEntry);
125 int CompilerToVM::Data::sizeof_ExceptionTableElement = sizeof(ExceptionTableElement);
126 int CompilerToVM::Data::sizeof_LocalVariableTableElement = sizeof(LocalVariableTableElement);
127 int CompilerToVM::Data::sizeof_ConstantPool = sizeof(ConstantPool);
128 int CompilerToVM::Data::sizeof_SymbolPointer = sizeof(Symbol*);
129 int CompilerToVM::Data::sizeof_narrowKlass = sizeof(narrowKlass);
130 int CompilerToVM::Data::sizeof_arrayOopDesc = sizeof(arrayOopDesc);
131 int CompilerToVM::Data::sizeof_BasicLock = sizeof(BasicLock);
132
133 address CompilerToVM::Data::dsin;
134 address CompilerToVM::Data::dcos;
135 address CompilerToVM::Data::dtan;
136 address CompilerToVM::Data::dexp;
137 address CompilerToVM::Data::dlog;
138 address CompilerToVM::Data::dlog10;
139 address CompilerToVM::Data::dpow;
140
141 address CompilerToVM::Data::symbol_init;
142 address CompilerToVM::Data::symbol_clinit;
143
144 void CompilerToVM::Data::initialize(TRAPS) {
145 Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
146 Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
147
148 Method_extra_stack_entries = Method::extra_stack_entries();
149
150 SharedRuntime_ic_miss_stub = SharedRuntime::get_ic_miss_stub();
151 SharedRuntime_handle_wrong_method_stub = SharedRuntime::get_handle_wrong_method_stub();
152 SharedRuntime_deopt_blob_unpack = SharedRuntime::deopt_blob()->unpack();
153 SharedRuntime_deopt_blob_uncommon_trap = SharedRuntime::deopt_blob()->uncommon_trap();
154
155 ThreadLocalAllocBuffer_alignment_reserve = ThreadLocalAllocBuffer::alignment_reserve();
156
157 Universe_collectedHeap = Universe::heap();
158 Universe_base_vtable_size = Universe::base_vtable_size();
159 Universe_narrow_oop_base = Universe::narrow_oop_base();
160 Universe_narrow_oop_shift = Universe::narrow_oop_shift();
161 Universe_narrow_klass_base = Universe::narrow_klass_base();
162 Universe_narrow_klass_shift = Universe::narrow_klass_shift();
163 Universe_non_oop_bits = Universe::non_oop_word();
164 Universe_verify_oop_mask = Universe::verify_oop_mask();
165 Universe_verify_oop_bits = Universe::verify_oop_bits();
166
167 _supports_inline_contig_alloc = Universe::heap()->supports_inline_contig_alloc();
168 _heap_end_addr = _supports_inline_contig_alloc ? Universe::heap()->end_addr() : (HeapWord**) -1;
169 _heap_top_addr = _supports_inline_contig_alloc ? Universe::heap()->top_addr() : (HeapWord* volatile*) -1;
170
171 _max_oop_map_stack_offset = (OopMapValue::register_mask - VMRegImpl::stack2reg(0)->value()) * VMRegImpl::stack_slot_size;
172 int max_oop_map_stack_index = _max_oop_map_stack_offset / VMRegImpl::stack_slot_size;
173 assert(OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index)), "should be valid");
174 assert(!OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index + 1)), "should be invalid");
175
176 symbol_init = (address) vmSymbols::object_initializer_name();
177 symbol_clinit = (address) vmSymbols::class_initializer_name();
178
179 BarrierSet* bs = Universe::heap()->barrier_set();
180 switch (bs->kind()) {
181 case BarrierSet::CardTableModRef:
182 case BarrierSet::CardTableForRS:
183 case BarrierSet::CardTableExtension:
184 case BarrierSet::G1SATBCT:
185 case BarrierSet::G1SATBCTLogging: {
186 jbyte* base = barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base;
187 assert(base != 0, "unexpected byte_map_base");
188 cardtable_start_address = base;
189 cardtable_shift = CardTableModRefBS::card_shift;
190 break;
191 }
192 case BarrierSet::ModRef:
193 cardtable_start_address = 0;
194 cardtable_shift = 0;
195 // No post barriers
196 break;
197 default:
198 JVMCI_ERROR("Unsupported BarrierSet kind %d", bs->kind());
199 break;
200 }
201
202 vm_page_size = os::vm_page_size();
203
204 #define SET_TRIGFUNC(name) \
205 if (StubRoutines::name() != NULL) { \
206 name = StubRoutines::name(); \
207 } else { \
208 name = CAST_FROM_FN_PTR(address, SharedRuntime::name); \
209 }
210
211 SET_TRIGFUNC(dsin);
212 SET_TRIGFUNC(dcos);
213 SET_TRIGFUNC(dtan);
214 SET_TRIGFUNC(dexp);
215 SET_TRIGFUNC(dlog10);
216 SET_TRIGFUNC(dlog);
217 SET_TRIGFUNC(dpow);
218
236 kls_sid = SID_ENUM(kls); \
237 } \
238 Handle name_str = VM_SYMBOL_TO_STRING(name); \
239 Handle sig_str = VM_SYMBOL_TO_STRING(sig); \
240 VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str()); \
241 VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str()); \
242 VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str()); \
243 VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id); \
244 vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod()); \
245 }
246
247 VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
248 #undef SID_ENUM
249 #undef VM_SYMBOL_TO_STRING
250 #undef VM_INTRINSIC_INFO
251 assert(index == vmIntrinsics::ID_LIMIT - 1, "must be");
252
253 return vmIntrinsics;
254 }
255
256 /**
257 * The set of VM flags known to be used.
258 */
259 #define PREDEFINED_CONFIG_FLAGS(do_bool_flag, do_intx_flag, do_uintx_flag) \
260 do_intx_flag(AllocateInstancePrefetchLines) \
261 do_intx_flag(AllocatePrefetchDistance) \
262 do_intx_flag(AllocatePrefetchInstr) \
263 do_intx_flag(AllocatePrefetchLines) \
264 do_intx_flag(AllocatePrefetchStepSize) \
265 do_intx_flag(AllocatePrefetchStyle) \
266 do_intx_flag(BciProfileWidth) \
267 do_bool_flag(BootstrapJVMCI) \
268 do_bool_flag(CITime) \
269 do_bool_flag(CITimeEach) \
270 do_uintx_flag(CodeCacheSegmentSize) \
271 do_intx_flag(CodeEntryAlignment) \
272 do_bool_flag(CompactFields) \
273 NOT_PRODUCT(do_intx_flag(CompileTheWorldStartAt)) \
274 NOT_PRODUCT(do_intx_flag(CompileTheWorldStopAt)) \
275 do_intx_flag(ContendedPaddingWidth) \
276 do_bool_flag(DontCompileHugeMethods) \
277 do_bool_flag(EnableContended) \
278 do_intx_flag(FieldsAllocationStyle) \
279 do_bool_flag(FoldStableValues) \
280 do_bool_flag(ForceUnreachable) \
281 do_intx_flag(HugeMethodLimit) \
282 do_bool_flag(Inline) \
283 do_intx_flag(JVMCICounterSize) \
284 do_bool_flag(JVMCIPrintProperties) \
285 do_bool_flag(JVMCIUseFastLocking) \
286 do_intx_flag(MethodProfileWidth) \
287 do_intx_flag(ObjectAlignmentInBytes) \
288 do_bool_flag(PrintInlining) \
289 do_bool_flag(ReduceInitialCardMarks) \
290 do_bool_flag(RestrictContended) \
291 do_intx_flag(StackReservedPages) \
292 do_intx_flag(StackShadowPages) \
293 do_bool_flag(TLABStats) \
294 do_uintx_flag(TLABWasteIncrement) \
295 do_intx_flag(TypeProfileWidth) \
296 do_bool_flag(UseAESIntrinsics) \
297 X86_ONLY(do_intx_flag(UseAVX)) \
298 do_bool_flag(UseBiasedLocking) \
299 do_bool_flag(UseCRC32Intrinsics) \
300 do_bool_flag(UseCompressedClassPointers) \
301 do_bool_flag(UseCompressedOops) \
302 do_bool_flag(UseConcMarkSweepGC) \
303 X86_ONLY(do_bool_flag(UseCountLeadingZerosInstruction)) \
304 X86_ONLY(do_bool_flag(UseCountTrailingZerosInstruction)) \
305 do_bool_flag(UseG1GC) \
306 COMPILER2_PRESENT(do_bool_flag(UseMontgomeryMultiplyIntrinsic)) \
307 COMPILER2_PRESENT(do_bool_flag(UseMontgomerySquareIntrinsic)) \
308 COMPILER2_PRESENT(do_bool_flag(UseMulAddIntrinsic)) \
309 COMPILER2_PRESENT(do_bool_flag(UseMultiplyToLenIntrinsic)) \
310 do_bool_flag(UsePopCountInstruction) \
311 do_bool_flag(UseSHA1Intrinsics) \
312 do_bool_flag(UseSHA256Intrinsics) \
313 do_bool_flag(UseSHA512Intrinsics) \
314 do_intx_flag(UseSSE) \
315 COMPILER2_PRESENT(do_bool_flag(UseSquareToLenIntrinsic)) \
316 do_bool_flag(UseStackBanging) \
317 do_bool_flag(UseTLAB) \
318 do_bool_flag(VerifyOops) \
319
320 #define BOXED_BOOLEAN(name, value) oop name = ((jboolean)(value) ? boxedTrue() : boxedFalse())
321 #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)
322 #define BOXED_LONG(name, value) \
323 oop name; \
324 do { \
325 jvalue p; p.j = (jlong) (value); \
326 Handle* e = longs.get(p.j); \
327 if (e == NULL) { \
328 Handle h = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL); \
329 longs.put(p.j, h); \
330 name = h(); \
331 } else { \
332 name = (*e)(); \
333 } \
334 } while (0)
335
336 #define CSTRING_TO_JSTRING(name, value) \
337 Handle name; \
338 do { \
339 if (value != NULL) { \
340 Handle* e = strings.get(value); \
341 if (e == NULL) { \
342 Handle h = java_lang_String::create_from_str(value, CHECK_NULL); \
343 strings.put(value, h); \
344 name = h(); \
345 } else { \
346 name = (*e)(); \
347 } \
348 } \
349 } while (0)
350
351 C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
352 ResourceMark rm;
353 HandleMark hm;
354
355 // Used to canonicalize Long and String values.
356 ResourceHashtable<jlong, Handle> longs;
357 ResourceHashtable<const char*, Handle, &CompilerToVM::cstring_hash, &CompilerToVM::cstring_equals> strings;
358
359 jvalue prim;
360 prim.z = true; Handle boxedTrue = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
361 prim.z = false; Handle boxedFalse = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
362
363 CompilerToVM::Data::initialize(CHECK_NULL);
364
365 VMField::klass()->initialize(CHECK_NULL);
366 VMFlag::klass()->initialize(CHECK_NULL);
367 VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
368
369 int len = JVMCIVMStructs::localHotSpotVMStructs_count();
370 objArrayHandle vmFields = oopFactory::new_objArray(VMField::klass(), len, CHECK_NULL);
371 for (int i = 0; i < len ; i++) {
372 VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
373 instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
374 size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
375 char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
376 sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
377 CSTRING_TO_JSTRING(name, name_buf);
378 CSTRING_TO_JSTRING(type, vmField.typeString);
379 VMField::set_name(vmFieldObj, name());
380 VMField::set_type(vmFieldObj, type());
381 VMField::set_offset(vmFieldObj, vmField.offset);
382 VMField::set_address(vmFieldObj, (jlong) vmField.address);
383 if (vmField.isStatic && vmField.typeString != NULL) {
384 if (strcmp(vmField.typeString, "bool") == 0) {
385 BOXED_BOOLEAN(box, *(jbyte*) vmField.address);
386 VMField::set_value(vmFieldObj, box);
387 } else if (strcmp(vmField.typeString, "int") == 0 ||
388 strcmp(vmField.typeString, "jint") == 0) {
389 BOXED_LONG(box, *(jint*) vmField.address);
390 VMField::set_value(vmFieldObj, box);
391 } else if (strcmp(vmField.typeString, "uint64_t") == 0) {
392 BOXED_LONG(box, *(uint64_t*) vmField.address);
393 VMField::set_value(vmFieldObj, box);
394 } else if (strcmp(vmField.typeString, "address") == 0 ||
395 strcmp(vmField.typeString, "intptr_t") == 0 ||
396 strcmp(vmField.typeString, "uintptr_t") == 0 ||
397 strcmp(vmField.typeString, "size_t") == 0 ||
398 // All foo* types are addresses.
399 vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
400 BOXED_LONG(box, *((address*) vmField.address));
401 VMField::set_value(vmFieldObj, box);
402 } else {
403 JVMCI_ERROR_NULL("VM field %s has unsupported type %s", name_buf, vmField.typeString);
404 }
405 }
406 vmFields->obj_at_put(i, vmFieldObj());
407 }
408
409 int ints_len = JVMCIVMStructs::localHotSpotVMIntConstants_count();
410 int longs_len = JVMCIVMStructs::localHotSpotVMLongConstants_count();
411 len = ints_len + longs_len;
412 objArrayHandle vmConstants = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
413 int insert = 0;
414 for (int i = 0; i < ints_len ; i++) {
415 VMIntConstantEntry c = JVMCIVMStructs::localHotSpotVMIntConstants[i];
416 CSTRING_TO_JSTRING(name, c.name);
417 BOXED_LONG(value, c.value);
418 vmConstants->obj_at_put(insert++, name());
419 vmConstants->obj_at_put(insert++, value);
420 }
421 for (int i = 0; i < longs_len ; i++) {
422 VMLongConstantEntry c = JVMCIVMStructs::localHotSpotVMLongConstants[i];
423 CSTRING_TO_JSTRING(name, c.name);
424 BOXED_LONG(value, c.value);
425 vmConstants->obj_at_put(insert++, name());
426 vmConstants->obj_at_put(insert++, value);
427 }
428 assert(insert == len * 2, "must be");
429
430 len = JVMCIVMStructs::localHotSpotVMAddresses_count();
431 objArrayHandle vmAddresses = oopFactory::new_objArray(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
432 for (int i = 0; i < len ; i++) {
433 VMAddressEntry a = JVMCIVMStructs::localHotSpotVMAddresses[i];
434 CSTRING_TO_JSTRING(name, a.name);
435 BOXED_LONG(value, a.value);
436 vmAddresses->obj_at_put(i * 2, name());
437 vmAddresses->obj_at_put(i * 2 + 1, value);
438 }
439
440 #define COUNT_FLAG(ignore) +1
441 #ifdef ASSERT
442 #define CHECK_FLAG(type, name) { \
443 Flag* flag = Flag::find_flag(#name, strlen(#name), /*allow_locked*/ true, /* return_flag */ true); \
444 assert(flag != NULL, "No such flag named " #name); \
445 assert(flag->is_##type(), "Flag " #name " is not of type " #type); \
446 }
447 #else
448 #define CHECK_FLAG(type, name)
449 #endif
450
451 #define ADD_FLAG(type, name, convert) { \
452 CHECK_FLAG(type, name) \
453 instanceHandle vmFlagObj = InstanceKlass::cast(VMFlag::klass())->allocate_instance_handle(CHECK_NULL); \
454 CSTRING_TO_JSTRING(fname, #name); \
455 CSTRING_TO_JSTRING(ftype, #type); \
456 VMFlag::set_name(vmFlagObj, fname()); \
457 VMFlag::set_type(vmFlagObj, ftype()); \
458 convert(value, name); \
459 VMFlag::set_value(vmFlagObj, value); \
460 vmFlags->obj_at_put(i++, vmFlagObj()); \
461 }
462 #define ADD_BOOL_FLAG(name) ADD_FLAG(bool, name, BOXED_BOOLEAN)
463 #define ADD_INTX_FLAG(name) ADD_FLAG(intx, name, BOXED_LONG)
464 #define ADD_UINTX_FLAG(name) ADD_FLAG(uintx, name, BOXED_LONG)
465
466 len = 0 + PREDEFINED_CONFIG_FLAGS(COUNT_FLAG, COUNT_FLAG, COUNT_FLAG);
467 objArrayHandle vmFlags = oopFactory::new_objArray(VMFlag::klass(), len, CHECK_NULL);
468 int i = 0;
469 PREDEFINED_CONFIG_FLAGS(ADD_BOOL_FLAG, ADD_INTX_FLAG, ADD_UINTX_FLAG)
470
471 objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
472
473 objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 5, CHECK_NULL);
474 data->obj_at_put(0, vmFields());
475 data->obj_at_put(1, vmConstants());
476 data->obj_at_put(2, vmAddresses());
477 data->obj_at_put(3, vmFlags());
478 data->obj_at_put(4, vmIntrinsics());
479
480 return (jobjectArray) JNIHandles::make_local(THREAD, data);
481 #undef COUNT_FLAG
482 #undef ADD_FLAG
483 #undef ADD_BOOL_FLAG
484 #undef ADD_INTX_FLAG
485 #undef ADD_UINTX_FLAG
486 #undef CHECK_FLAG
487 C2V_END
488
489 C2V_VMENTRY(jobject, getFlagValue, (JNIEnv *, jobject c2vm, jobject name_handle))
490 #define RETURN_BOXED_LONG(value) oop box; jvalue p; p.j = (jlong) (value); box = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL); return JNIHandles::make_local(THREAD, box);
491 #define RETURN_BOXED_DOUBLE(value) oop box; jvalue p; p.d = (jdouble) (value); box = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL); return JNIHandles::make_local(THREAD, box);
492 Handle name = JNIHandles::resolve(name_handle);
493 if (name.is_null()) {
494 THROW_0(vmSymbols::java_lang_NullPointerException());
495 }
496 ResourceMark rm;
497 const char* cstring = java_lang_String::as_utf8_string(name());
498 Flag* flag = Flag::find_flag(cstring, strlen(cstring), /* allow_locked */ true, /* return_flag */ true);
499 if (flag == NULL) {
500 return c2vm;
501 }
502 if (flag->is_bool()) {
503 jvalue prim;
504 prim.z = flag->get_bool();
505 oop box = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
506 return JNIHandles::make_local(THREAD, box);
507 } else if (flag->is_ccstr()) {
508 Handle value = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_NULL);
509 return JNIHandles::make_local(THREAD, value());
510 } else if (flag->is_intx()) {
511 RETURN_BOXED_LONG(flag->get_intx());
512 } else if (flag->is_int()) {
513 RETURN_BOXED_LONG(flag->get_int());
514 } else if (flag->is_uint()) {
515 RETURN_BOXED_LONG(flag->get_uint());
516 } else if (flag->is_uint64_t()) {
517 RETURN_BOXED_LONG(flag->get_uint64_t());
518 } else if (flag->is_size_t()) {
519 RETURN_BOXED_LONG(flag->get_size_t());
520 } else if (flag->is_uintx()) {
521 RETURN_BOXED_LONG(flag->get_uintx());
522 } else if (flag->is_double()) {
523 RETURN_BOXED_DOUBLE(flag->get_double());
524 } else {
525 JVMCI_ERROR_NULL("VM flag %s has unsupported type %s", flag->_name, flag->_type);
526 }
527 C2V_END
528
529 #undef BOXED_LONG
530 #undef BOXED_DOUBLE
531 #undef CSTRING_TO_JSTRING
532
533 C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
534 methodHandle method = CompilerToVM::asMethod(jvmci_method);
535 ResourceMark rm;
536
537 int code_size = method->code_size();
538 typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL);
539
540 guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
541 // iterate over all bytecodes and replace non-Java bytecodes
542
543 for (BytecodeStream s(method); s.next() != Bytecodes::_illegal; ) {
544 Bytecodes::Code code = s.code();
545 Bytecodes::Code raw_code = s.raw_code();
546 int bci = s.bci();
547 int len = s.instruction_size();
548
549 // Restore original byte code.
550 reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code));
551 if (len > 1) {
868 C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
869 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
870 oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
871 return JNIHandles::make_local(THREAD, appendix_oop);
872 C2V_END
873
874 C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
875 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
876 instanceKlassHandle pool_holder(cp->pool_holder());
877 Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
878 methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder);
879 oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
880 return JNIHandles::make_local(THREAD, result);
881 C2V_END
882
883 C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
884 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
885 return cp->remap_instruction_operand_from_cache(index);
886 C2V_END
887
888 C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
889 ResourceMark rm;
890 constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
891 Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
892 fieldDescriptor fd;
893 LinkInfo link_info(cp, index, (jvmci_method != NULL) ? CompilerToVM::asMethod(jvmci_method) : NULL, CHECK_0);
894 LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
895 typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
896 if (info == NULL || info->length() != 3) {
897 JVMCI_ERROR_NULL("info must not be null and have a length of 3");
898 }
899 info->int_at_put(0, fd.access_flags().as_int());
900 info->int_at_put(1, fd.offset());
901 info->int_at_put(2, fd.index());
902 oop field_holder = CompilerToVM::get_jvmci_type(fd.field_holder(), CHECK_NULL);
903 return JNIHandles::make_local(THREAD, field_holder);
904 C2V_END
905
906 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
907 ResourceMark rm;
908 Klass* klass = CompilerToVM::asKlass(jvmci_type);
909 Method* method = CompilerToVM::asMethod(jvmci_method);
910 if (klass->is_interface()) {
911 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name()));
912 }
913 if (!method->method_holder()->is_interface()) {
914 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()));
915 }
916 if (!InstanceKlass::cast(klass)->is_linked()) {
917 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name()));
918 }
919 return LinkResolver::vtable_index_of_interface_method(klass, method);
920 C2V_END
921
1738 {CC "findUniqueConcreteMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")" HS_RESOLVED_METHOD, FN_PTR(findUniqueConcreteMethod)},
1739 {CC "getImplementor", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS, FN_PTR(getImplementor)},
1740 {CC "getStackTraceElement", CC "(" HS_RESOLVED_METHOD "I)" STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)},
1741 {CC "methodIsIgnoredBySecurityStackWalk", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(methodIsIgnoredBySecurityStackWalk)},
1742 {CC "doNotInlineOrCompile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(doNotInlineOrCompile)},
1743 {CC "isCompilable", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(isCompilable)},
1744 {CC "hasNeverInlineDirective", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(hasNeverInlineDirective)},
1745 {CC "shouldInlineMethod", CC "(" HS_RESOLVED_METHOD ")Z", FN_PTR(shouldInlineMethod)},
1746 {CC "lookupType", CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS, FN_PTR(lookupType)},
1747 {CC "lookupNameInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupNameInPool)},
1748 {CC "lookupNameAndTypeRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)},
1749 {CC "lookupSignatureInPool", CC "(" HS_CONSTANT_POOL "I)" STRING, FN_PTR(lookupSignatureInPool)},
1750 {CC "lookupKlassRefIndexInPool", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(lookupKlassRefIndexInPool)},
1751 {CC "lookupKlassInPool", CC "(" HS_CONSTANT_POOL "I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)},
1752 {CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(lookupAppendixInPool)},
1753 {CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)},
1754 {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
1755 {CC "resolveConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolveConstantInPool)},
1756 {CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)},
1757 {CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)},
1758 {CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)},
1759 {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},
1760 {CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeHandleInPool)},
1761 {CC "resolveMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
1762 {CC "getSignaturePolymorphicHolders", CC "()[" STRING, FN_PTR(getSignaturePolymorphicHolders)},
1763 {CC "getVtableIndexForInterfaceMethod", CC "(" HS_RESOLVED_KLASS HS_RESOLVED_METHOD ")I", FN_PTR(getVtableIndexForInterfaceMethod)},
1764 {CC "getClassInitializer", CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_METHOD, FN_PTR(getClassInitializer)},
1765 {CC "hasFinalizableSubclass", CC "(" HS_RESOLVED_KLASS ")Z", FN_PTR(hasFinalizableSubclass)},
1766 {CC "getMaxCallTargetOffset", CC "(J)J", FN_PTR(getMaxCallTargetOffset)},
1767 {CC "asResolvedJavaMethod", CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD, FN_PTR(asResolvedJavaMethod)},
1768 {CC "getResolvedJavaMethod", CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
1769 {CC "getConstantPool", CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
1770 {CC "getResolvedJavaType", CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
1771 {CC "readConfiguration", CC "()[" OBJECT, FN_PTR(readConfiguration)},
1772 {CC "installCode", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I", FN_PTR(installCode)},
1773 {CC "getMetadata", CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I", FN_PTR(getMetadata)},
1774 {CC "resetCompilationStatistics", CC "()V", FN_PTR(resetCompilationStatistics)},
1775 {CC "disassembleCodeBlob", CC "(" INSTALLED_CODE ")" STRING, FN_PTR(disassembleCodeBlob)},
1776 {CC "executeInstalledCode", CC "([" OBJECT INSTALLED_CODE ")" OBJECT, FN_PTR(executeInstalledCode)},
1777 {CC "getLineNumberTable", CC "(" HS_RESOLVED_METHOD ")[J", FN_PTR(getLineNumberTable)},
1778 {CC "getLocalVariableTableStart", CC "(" HS_RESOLVED_METHOD ")J", FN_PTR(getLocalVariableTableStart)},
1779 {CC "getLocalVariableTableLength", CC "(" HS_RESOLVED_METHOD ")I", FN_PTR(getLocalVariableTableLength)},
1780 {CC "reprofile", CC "(" HS_RESOLVED_METHOD ")V", FN_PTR(reprofile)},
1781 {CC "invalidateInstalledCode", CC "(" INSTALLED_CODE ")V", FN_PTR(invalidateInstalledCode)},
1782 {CC "collectCounters", CC "()[J", FN_PTR(collectCounters)},
1783 {CC "allocateCompileId", CC "(" HS_RESOLVED_METHOD "I)I", FN_PTR(allocateCompileId)},
1784 {CC "isMature", CC "(" METASPACE_METHOD_DATA ")Z", FN_PTR(isMature)},
1785 {CC "hasCompiledCodeForOSR", CC "(" HS_RESOLVED_METHOD "II)Z", FN_PTR(hasCompiledCodeForOSR)},
1786 {CC "getSymbol", CC "(J)" STRING, FN_PTR(getSymbol)},
1787 {CC "getNextStackFrame", CC "(" HS_STACK_FRAME_REF "[" RESOLVED_METHOD "I)" HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
1788 {CC "materializeVirtualObjects", CC "(" HS_STACK_FRAME_REF "Z)V", FN_PTR(materializeVirtualObjects)},
1789 {CC "shouldDebugNonSafepoints", CC "()Z", FN_PTR(shouldDebugNonSafepoints)},
1790 {CC "writeDebugOutput", CC "([BII)V", FN_PTR(writeDebugOutput)},
1791 {CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
1792 {CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
1793 {CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
1794 {CC "interpreterFrameSize", CC "(" BYTECODE_FRAME ")I", FN_PTR(interpreterFrameSize)},
1795 {CC "compileToBytecode", CC "(" OBJECT ")V", FN_PTR(compileToBytecode)},
1796 {CC "getFlagValue", CC "(" STRING ")" OBJECT, FN_PTR(getFlagValue)},
1797 };
1798
1799 int CompilerToVM::methods_count() {
1800 return sizeof(methods) / sizeof(JNINativeMethod);
1801 }
|