155 typeArrayHandle slots = RegisterSaveLayout::slots(callee_save_info);
156 for (jint i = 0; i < slots->length(); i++) {
157 Handle jvmci_reg = registers->obj_at(i);
158 jint jvmci_reg_number = code_Register::number(jvmci_reg);
159 VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, CHECK_NULL);
160 // HotSpot stack slots are 4 bytes
161 jint jvmci_slot = slots->int_at(i);
162 jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;
163 VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
164 map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
165 #ifdef _LP64
166 // (copied from generate_oop_map() in c1_Runtime1_x86.cpp)
167 VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1);
168 map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next());
169 #endif
170 }
171 }
172 return map;
173 }
174
175 void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
176 /*
177 * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
178 * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
179 * the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the
180 * base class (Metadata* or MetaspaceObj*).
181 */
182 oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
183 if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
184 Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
185 assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
186 int index = _oop_recorder->find_index(klass);
187 section->relocate(dest, metadata_Relocation::spec(index));
188 TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
189 return klass;
190 } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
191 Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
192 assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
193 int index = _oop_recorder->find_index(method);
194 section->relocate(dest, metadata_Relocation::spec(index));
464 return (address) _static_buffer;
465 }
466
467 void RelocBuffer::set_size(size_t bytes) {
468 assert(bytes <= _size, "can't grow in size!");
469 _size = bytes;
470 }
471
472 void RelocBuffer::ensure_size(size_t bytes) {
473 assert(_buffer == NULL, "can only be used once");
474 assert(_size == 0, "can only be used once");
475 if (bytes >= RelocBuffer::stack_size) {
476 _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtInternal);
477 }
478 _size = bytes;
479 }
480
481 JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) {
482 CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata");
483 jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
484 initialize_dependencies(JNIHandles::resolve(compiled_code_obj), NULL, CHECK_OK);
485
486 // Get instructions and constants CodeSections early because we need it.
487 _instructions = buffer.insts();
488 _constants = buffer.consts();
489
490 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
491 JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK);
492 if (result != JVMCIEnv::ok) {
493 return result;
494 }
495
496 _debug_recorder->pcs_size(); // create the sentinel record
497
498 assert(_debug_recorder->pcs_length() >= 2, "must be at least 2");
499
500 metadata.set_pc_desc(_debug_recorder->pcs(), _debug_recorder->pcs_length());
501 metadata.set_scopes(_debug_recorder->stream()->buffer(), _debug_recorder->data_size());
502 metadata.set_exception_table(&_exception_handler_table);
503
504 RelocBuffer* reloc_buffer = metadata.get_reloc_buffer();
536 CodeOffsets::frame_never_safe,
537 stack_slots,
538 _debug_recorder->_oopmaps,
539 false);
540 result = JVMCIEnv::ok;
541 } else {
542 nmethod* nm = NULL;
543 methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
544 jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
545 jint id = HotSpotCompiledNmethod::id(compiled_code);
546 bool has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code) == JNI_TRUE;
547 JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code);
548 if (id == -1) {
549 // Make sure a valid compile_id is associated with every compile
550 id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
551 }
552 result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
553 stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
554 compiler, _debug_recorder, _dependencies, env, id,
555 has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
556 cb = nm;
557 if (nm != NULL && env == NULL) {
558 DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
559 bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
560 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
561 nm->print_nmethod(printnmethods);
562 }
563 DirectivesStack::release(directive);
564 }
565 }
566
567 if (cb != NULL) {
568 // Make sure the pre-calculated constants section size was correct.
569 guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, "%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size);
570 }
571 return result;
572 }
573
574 void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) {
575 if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
576 Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code);
606 if ((_constants->alignment() % HotSpotCompiledCode::dataSectionAlignment(compiled_code)) != 0) {
607 JVMCI_ERROR("invalid data section alignment: %d", HotSpotCompiledCode::dataSectionAlignment(compiled_code));
608 }
609 _constants_size = data_section()->length();
610
611 _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code));
612
613 #ifndef PRODUCT
614 _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code));
615 #endif
616
617 _next_call_type = INVOKE_INVALID;
618
619 _has_wide_vector = false;
620
621 oop arch = TargetDescription::arch(target);
622 _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch));
623 }
624
625 int CodeInstaller::estimate_stubs_size(TRAPS) {
626 // Estimate the number of static call stubs that might be emitted.
627 int static_call_stubs = 0;
628 objArrayOop sites = this->sites();
629 for (int i = 0; i < sites->length(); i++) {
630 oop site = sites->obj_at(i);
631 if (site != NULL && site->is_a(site_Mark::klass())) {
632 oop id_obj = site_Mark::id(site);
633 if (id_obj != NULL) {
634 if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) {
635 JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name());
636 }
637 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
638 if (id == INVOKESTATIC || id == INVOKESPECIAL) {
639 static_call_stubs++;
640 }
641 }
642 }
643 }
644 return static_call_stubs * CompiledStaticCall::to_interp_stub_size();
645 }
646
647 // perform data and call relocation on the CodeBuffer
648 JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) {
649 HandleMark hm;
650 objArrayHandle sites = this->sites();
651 int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
652
653 // Allocate enough space in the stub section for the static call
654 // stubs. Stubs have extra relocs but they are managed by the stub
655 // section itself so they don't need to be accounted for in the
656 // locs_buffer above.
657 int stubs_size = estimate_stubs_size(CHECK_OK);
658 int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment());
659
660 if (total_size > JVMCINMethodSizeLimit) {
661 return JVMCIEnv::code_too_large;
662 }
663
664 buffer.initialize(total_size, locs_buffer_size);
1046 foreign_call = target;
1047 } else {
1048 hotspot_method = target;
1049 }
1050
1051 Handle debug_info = site_Call::debugInfo(site);
1052
1053 assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type");
1054
1055 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
1056 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK);
1057
1058 if (debug_info.not_null()) {
1059 OopMap *map = create_oop_map(debug_info, CHECK);
1060 _debug_recorder->add_safepoint(next_pc_offset, map);
1061 record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
1062 }
1063
1064 if (foreign_call.not_null()) {
1065 jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call);
1066 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK);
1067 } else { // method != NULL
1068 if (debug_info.is_null()) {
1069 JVMCI_ERROR("debug info expected at call at %i", pc_offset);
1070 }
1071
1072 TRACE_jvmci_3("method call");
1073 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset, CHECK);
1074 if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {
1075 // Need a static call stub for transitions from compiled to interpreted.
1076 CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset);
1077 }
1078 }
1079
1080 _next_call_type = INVOKE_INVALID;
1081
1082 if (debug_info.not_null()) {
1083 _debug_recorder->end_safepoint(next_pc_offset);
1084 }
1085 }
1086
1087 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
1088 Handle reference = site_DataPatch::reference(site);
1089 if (reference.is_null()) {
1090 THROW(vmSymbols::java_lang_NullPointerException());
1091 } else if (reference->is_a(site_ConstantReference::klass())) {
1092 Handle constant = site_ConstantReference::constant(reference);
1093 if (constant.is_null()) {
1094 THROW(vmSymbols::java_lang_NullPointerException());
1095 } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
1096 pd_patch_OopConstant(pc_offset, constant, CHECK);
1097 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
1098 pd_patch_MetaspaceConstant(pc_offset, constant, CHECK);
1099 } else {
1100 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name());
1101 }
1102 } else if (reference->is_a(site_DataSectionReference::klass())) {
1103 int data_offset = site_DataSectionReference::offset(reference);
1104 if (0 <= data_offset && data_offset < _constants_size) {
1105 pd_patch_DataSectionReference(pc_offset, data_offset, CHECK);
1106 } else {
1107 JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size);
1108 }
1109 } else {
1110 JVMCI_ERROR("unknown data patch type: %s", reference->klass()->signature_name());
1111 }
1112 }
1113
1114 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
1115 Handle id_obj = site_Mark::id(site);
1116
1117 if (id_obj.not_null()) {
1118 if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) {
1141 case INVOKEVIRTUAL:
1142 case INVOKEINTERFACE:
1143 case INLINE_INVOKE:
1144 case INVOKESTATIC:
1145 case INVOKESPECIAL:
1146 _next_call_type = (MarkId) id;
1147 _invoke_mark_pc = pc;
1148 break;
1149 case POLL_NEAR:
1150 case POLL_FAR:
1151 case POLL_RETURN_NEAR:
1152 case POLL_RETURN_FAR:
1153 pd_relocate_poll(pc, id, CHECK);
1154 break;
1155 case CARD_TABLE_SHIFT:
1156 case CARD_TABLE_ADDRESS:
1157 case HEAP_TOP_ADDRESS:
1158 case HEAP_END_ADDRESS:
1159 case NARROW_KLASS_BASE_ADDRESS:
1160 case CRC_TABLE_ADDRESS:
1161 break;
1162 default:
1163 JVMCI_ERROR("invalid mark id: %d", id);
1164 break;
1165 }
1166 }
1167 }
1168
|
155 typeArrayHandle slots = RegisterSaveLayout::slots(callee_save_info);
156 for (jint i = 0; i < slots->length(); i++) {
157 Handle jvmci_reg = registers->obj_at(i);
158 jint jvmci_reg_number = code_Register::number(jvmci_reg);
159 VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, CHECK_NULL);
160 // HotSpot stack slots are 4 bytes
161 jint jvmci_slot = slots->int_at(i);
162 jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;
163 VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
164 map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
165 #ifdef _LP64
166 // (copied from generate_oop_map() in c1_Runtime1_x86.cpp)
167 VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1);
168 map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next());
169 #endif
170 }
171 }
172 return map;
173 }
174
175 AOTOopRecorder::AOTOopRecorder(Arena* arena, bool deduplicate) : OopRecorder(arena, deduplicate) {
176 _meta_strings = new GrowableArray<const char*>();
177 }
178
179 int AOTOopRecorder::nr_meta_strings() const {
180 return _meta_strings->length();
181 }
182
183 const char* AOTOopRecorder::meta_element(int pos) const {
184 return _meta_strings->at(pos);
185 }
186
187 int AOTOopRecorder::find_index(Metadata* h) {
188 int index = this->OopRecorder::find_index(h);
189
190 Klass* klass = NULL;
191 if (h->is_klass()) {
192 klass = (Klass*) h;
193 record_meta_string(klass->signature_name(), index);
194 } else if (h->is_method()) {
195 Method* method = (Method*) h;
196 // Need klass->signature_name() in method name
197 klass = method->method_holder();
198 const char* klass_name = klass->signature_name();
199 int klass_name_len = (int)strlen(klass_name);
200 Symbol* method_name = method->name();
201 Symbol* signature = method->signature();
202 int method_name_len = method_name->utf8_length();
203 int method_sign_len = signature->utf8_length();
204 int len = klass_name_len + 1 + method_name_len + method_sign_len;
205 char* dest = NEW_RESOURCE_ARRAY(char, len + 1);
206 strcpy(dest, klass_name);
207 dest[klass_name_len] = '.';
208 strcpy(&dest[klass_name_len + 1], method_name->as_C_string());
209 strcpy(&dest[klass_name_len + 1 + method_name_len], signature->as_C_string());
210 dest[len] = 0;
211 record_meta_string(dest, index);
212 }
213
214 return index;
215 }
216
217 int AOTOopRecorder::find_index(jobject h) {
218 if (h == NULL) {
219 return 0;
220 }
221 oop javaMirror = JNIHandles::resolve(h);
222 Klass* klass = java_lang_Class::as_Klass(javaMirror);
223 return find_index(klass);
224 }
225
226 void AOTOopRecorder::record_meta_string(const char* name, int index) {
227 assert(index > 0, "must be 1..n");
228 index -= 1; // reduce by one to convert to array index
229
230 if (index < _meta_strings->length()) {
231 assert(strcmp(name, _meta_strings->at(index)) == 0, "must match");
232 } else {
233 assert(index == _meta_strings->length(), "must be last");
234 _meta_strings->append(name);
235 }
236 }
237
238 void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
239 /*
240 * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
241 * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
242 * the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the
243 * base class (Metadata* or MetaspaceObj*).
244 */
245 oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
246 if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
247 Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
248 assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
249 int index = _oop_recorder->find_index(klass);
250 section->relocate(dest, metadata_Relocation::spec(index));
251 TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
252 return klass;
253 } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
254 Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
255 assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
256 int index = _oop_recorder->find_index(method);
257 section->relocate(dest, metadata_Relocation::spec(index));
527 return (address) _static_buffer;
528 }
529
530 void RelocBuffer::set_size(size_t bytes) {
531 assert(bytes <= _size, "can't grow in size!");
532 _size = bytes;
533 }
534
535 void RelocBuffer::ensure_size(size_t bytes) {
536 assert(_buffer == NULL, "can only be used once");
537 assert(_size == 0, "can only be used once");
538 if (bytes >= RelocBuffer::stack_size) {
539 _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtInternal);
540 }
541 _size = bytes;
542 }
543
544 JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) {
545 CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata");
546 jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
547 AOTOopRecorder* recorder = new AOTOopRecorder(&_arena, true);
548 initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder, CHECK_OK);
549
550 metadata.set_oop_recorder(recorder);
551
552 // Get instructions and constants CodeSections early because we need it.
553 _instructions = buffer.insts();
554 _constants = buffer.consts();
555
556 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
557 JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK);
558 if (result != JVMCIEnv::ok) {
559 return result;
560 }
561
562 _debug_recorder->pcs_size(); // create the sentinel record
563
564 assert(_debug_recorder->pcs_length() >= 2, "must be at least 2");
565
566 metadata.set_pc_desc(_debug_recorder->pcs(), _debug_recorder->pcs_length());
567 metadata.set_scopes(_debug_recorder->stream()->buffer(), _debug_recorder->data_size());
568 metadata.set_exception_table(&_exception_handler_table);
569
570 RelocBuffer* reloc_buffer = metadata.get_reloc_buffer();
602 CodeOffsets::frame_never_safe,
603 stack_slots,
604 _debug_recorder->_oopmaps,
605 false);
606 result = JVMCIEnv::ok;
607 } else {
608 nmethod* nm = NULL;
609 methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
610 jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
611 jint id = HotSpotCompiledNmethod::id(compiled_code);
612 bool has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code) == JNI_TRUE;
613 JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code);
614 if (id == -1) {
615 // Make sure a valid compile_id is associated with every compile
616 id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
617 }
618 result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
619 stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
620 compiler, _debug_recorder, _dependencies, env, id,
621 has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
622 cb = nm->as_codeblob_or_null();
623 if (nm != NULL && env == NULL) {
624 DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
625 bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
626 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) {
627 nm->print_nmethod(printnmethods);
628 }
629 DirectivesStack::release(directive);
630 }
631 }
632
633 if (cb != NULL) {
634 // Make sure the pre-calculated constants section size was correct.
635 guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, "%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size);
636 }
637 return result;
638 }
639
640 void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) {
641 if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
642 Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code);
672 if ((_constants->alignment() % HotSpotCompiledCode::dataSectionAlignment(compiled_code)) != 0) {
673 JVMCI_ERROR("invalid data section alignment: %d", HotSpotCompiledCode::dataSectionAlignment(compiled_code));
674 }
675 _constants_size = data_section()->length();
676
677 _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code));
678
679 #ifndef PRODUCT
680 _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code));
681 #endif
682
683 _next_call_type = INVOKE_INVALID;
684
685 _has_wide_vector = false;
686
687 oop arch = TargetDescription::arch(target);
688 _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch));
689 }
690
691 int CodeInstaller::estimate_stubs_size(TRAPS) {
692 // Estimate the number of static and aot call stubs that might be emitted.
693 int static_call_stubs = 0;
694 int aot_call_stubs = 0;
695 objArrayOop sites = this->sites();
696 for (int i = 0; i < sites->length(); i++) {
697 oop site = sites->obj_at(i);
698 if (site != NULL) {
699 if (site->is_a(site_Mark::klass())) {
700 oop id_obj = site_Mark::id(site);
701 if (id_obj != NULL) {
702 if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) {
703 JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name());
704 }
705 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
706 if (id == INVOKESTATIC || id == INVOKESPECIAL) {
707 static_call_stubs++;
708 }
709 }
710 }
711 if (UseAOT && site->is_a(site_Call::klass())) {
712 oop target = site_Call::target(site);
713 InstanceKlass* target_klass = InstanceKlass::cast(target->klass());
714 if (!target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) {
715 // Add far aot trampolines.
716 aot_call_stubs++;
717 }
718 }
719 }
720 }
721 int size = static_call_stubs * CompiledStaticCall::to_interp_stub_size();
722 #if INCLUDE_AOT
723 size += aot_call_stubs * CompiledStaticCall::to_aot_stub_size();
724 #endif
725 return size;
726 }
727
728 // perform data and call relocation on the CodeBuffer
729 JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) {
730 HandleMark hm;
731 objArrayHandle sites = this->sites();
732 int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
733
734 // Allocate enough space in the stub section for the static call
735 // stubs. Stubs have extra relocs but they are managed by the stub
736 // section itself so they don't need to be accounted for in the
737 // locs_buffer above.
738 int stubs_size = estimate_stubs_size(CHECK_OK);
739 int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment());
740
741 if (total_size > JVMCINMethodSizeLimit) {
742 return JVMCIEnv::code_too_large;
743 }
744
745 buffer.initialize(total_size, locs_buffer_size);
1127 foreign_call = target;
1128 } else {
1129 hotspot_method = target;
1130 }
1131
1132 Handle debug_info = site_Call::debugInfo(site);
1133
1134 assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type");
1135
1136 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
1137 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK);
1138
1139 if (debug_info.not_null()) {
1140 OopMap *map = create_oop_map(debug_info, CHECK);
1141 _debug_recorder->add_safepoint(next_pc_offset, map);
1142 record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
1143 }
1144
1145 if (foreign_call.not_null()) {
1146 jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call);
1147 if (_immutable_pic_compilation) {
1148 // Use fake short distance during PIC compilation.
1149 foreign_call_destination = (jlong)(_instructions->start() + pc_offset);
1150 }
1151 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK);
1152 } else { // method != NULL
1153 if (debug_info.is_null()) {
1154 JVMCI_ERROR("debug info expected at call at %i", pc_offset);
1155 }
1156
1157 TRACE_jvmci_3("method call");
1158 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset, CHECK);
1159 if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {
1160 // Need a static call stub for transitions from compiled to interpreted.
1161 CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset);
1162 }
1163 #if INCLUDE_AOT
1164 // Trampoline to far aot code.
1165 CompiledStaticCall::emit_to_aot_stub(buffer, _instructions->start() + pc_offset);
1166 #endif
1167 }
1168
1169 _next_call_type = INVOKE_INVALID;
1170
1171 if (debug_info.not_null()) {
1172 _debug_recorder->end_safepoint(next_pc_offset);
1173 }
1174 }
1175
1176 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
1177 Handle reference = site_DataPatch::reference(site);
1178 if (reference.is_null()) {
1179 THROW(vmSymbols::java_lang_NullPointerException());
1180 } else if (reference->is_a(site_ConstantReference::klass())) {
1181 Handle constant = site_ConstantReference::constant(reference);
1182 if (constant.is_null()) {
1183 THROW(vmSymbols::java_lang_NullPointerException());
1184 } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
1185 if (!_immutable_pic_compilation) {
1186 // Do not patch during PIC compilation.
1187 pd_patch_OopConstant(pc_offset, constant, CHECK);
1188 }
1189 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
1190 if (!_immutable_pic_compilation) {
1191 pd_patch_MetaspaceConstant(pc_offset, constant, CHECK);
1192 }
1193 } else if (constant->is_a(HotSpotSentinelConstant::klass())) {
1194 if (!_immutable_pic_compilation) {
1195 JVMCI_ERROR("sentinel constant not supported for normal compiles: %s", constant->klass()->signature_name());
1196 }
1197 } else {
1198 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name());
1199 }
1200 } else if (reference->is_a(site_DataSectionReference::klass())) {
1201 int data_offset = site_DataSectionReference::offset(reference);
1202 if (0 <= data_offset && data_offset < _constants_size) {
1203 pd_patch_DataSectionReference(pc_offset, data_offset, CHECK);
1204 } else {
1205 JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size);
1206 }
1207 } else {
1208 JVMCI_ERROR("unknown data patch type: %s", reference->klass()->signature_name());
1209 }
1210 }
1211
1212 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
1213 Handle id_obj = site_Mark::id(site);
1214
1215 if (id_obj.not_null()) {
1216 if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) {
1239 case INVOKEVIRTUAL:
1240 case INVOKEINTERFACE:
1241 case INLINE_INVOKE:
1242 case INVOKESTATIC:
1243 case INVOKESPECIAL:
1244 _next_call_type = (MarkId) id;
1245 _invoke_mark_pc = pc;
1246 break;
1247 case POLL_NEAR:
1248 case POLL_FAR:
1249 case POLL_RETURN_NEAR:
1250 case POLL_RETURN_FAR:
1251 pd_relocate_poll(pc, id, CHECK);
1252 break;
1253 case CARD_TABLE_SHIFT:
1254 case CARD_TABLE_ADDRESS:
1255 case HEAP_TOP_ADDRESS:
1256 case HEAP_END_ADDRESS:
1257 case NARROW_KLASS_BASE_ADDRESS:
1258 case CRC_TABLE_ADDRESS:
1259 case LOG_OF_HEAP_REGION_GRAIN_BYTES:
1260 break;
1261 default:
1262 JVMCI_ERROR("invalid mark id: %d", id);
1263 break;
1264 }
1265 }
1266 }
1267
|