168 map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next()); |
168 map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next()); |
169 #endif |
169 #endif |
170 } |
170 } |
171 } |
171 } |
172 return map; |
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 } |
173 } |
236 } |
174 |
237 |
175 void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) { |
238 void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) { |
176 /* |
239 /* |
177 * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base |
240 * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base |
479 } |
542 } |
480 |
543 |
481 JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) { |
544 JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) { |
482 CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata"); |
545 CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata"); |
483 jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); |
546 jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); |
484 initialize_dependencies(JNIHandles::resolve(compiled_code_obj), NULL, CHECK_OK); |
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); |
485 |
551 |
486 // Get instructions and constants CodeSections early because we need it. |
552 // Get instructions and constants CodeSections early because we need it. |
487 _instructions = buffer.insts(); |
553 _instructions = buffer.insts(); |
488 _constants = buffer.consts(); |
554 _constants = buffer.consts(); |
489 |
555 |
551 } |
617 } |
552 result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer, |
618 result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer, |
553 stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, |
619 stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, |
554 compiler, _debug_recorder, _dependencies, env, id, |
620 compiler, _debug_recorder, _dependencies, env, id, |
555 has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log); |
621 has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log); |
556 cb = nm; |
622 cb = nm->as_codeblob_or_null(); |
557 if (nm != NULL && env == NULL) { |
623 if (nm != NULL && env == NULL) { |
558 DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler); |
624 DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler); |
559 bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption; |
625 bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption; |
560 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { |
626 if (printnmethods || PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers) { |
561 nm->print_nmethod(printnmethods); |
627 nm->print_nmethod(printnmethods); |
621 oop arch = TargetDescription::arch(target); |
687 oop arch = TargetDescription::arch(target); |
622 _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch)); |
688 _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch)); |
623 } |
689 } |
624 |
690 |
625 int CodeInstaller::estimate_stubs_size(TRAPS) { |
691 int CodeInstaller::estimate_stubs_size(TRAPS) { |
626 // Estimate the number of static call stubs that might be emitted. |
692 // Estimate the number of static and aot call stubs that might be emitted. |
627 int static_call_stubs = 0; |
693 int static_call_stubs = 0; |
|
694 int aot_call_stubs = 0; |
628 objArrayOop sites = this->sites(); |
695 objArrayOop sites = this->sites(); |
629 for (int i = 0; i < sites->length(); i++) { |
696 for (int i = 0; i < sites->length(); i++) { |
630 oop site = sites->obj_at(i); |
697 oop site = sites->obj_at(i); |
631 if (site != NULL && site->is_a(site_Mark::klass())) { |
698 if (site != NULL) { |
632 oop id_obj = site_Mark::id(site); |
699 if (site->is_a(site_Mark::klass())) { |
633 if (id_obj != NULL) { |
700 oop id_obj = site_Mark::id(site); |
634 if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { |
701 if (id_obj != NULL) { |
635 JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name()); |
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 } |
636 } |
709 } |
637 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
710 } |
638 if (id == INVOKESTATIC || id == INVOKESPECIAL) { |
711 if (UseAOT && site->is_a(site_Call::klass())) { |
639 static_call_stubs++; |
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++; |
640 } |
717 } |
641 } |
718 } |
642 } |
719 } |
643 } |
720 } |
644 return static_call_stubs * CompiledStaticCall::to_interp_stub_size(); |
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; |
645 } |
726 } |
646 |
727 |
647 // perform data and call relocation on the CodeBuffer |
728 // perform data and call relocation on the CodeBuffer |
648 JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) { |
729 JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, TRAPS) { |
649 HandleMark hm; |
730 HandleMark hm; |
1061 record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK); |
1142 record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, CHECK); |
1062 } |
1143 } |
1063 |
1144 |
1064 if (foreign_call.not_null()) { |
1145 if (foreign_call.not_null()) { |
1065 jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call); |
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 } |
1066 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK); |
1151 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK); |
1067 } else { // method != NULL |
1152 } else { // method != NULL |
1068 if (debug_info.is_null()) { |
1153 if (debug_info.is_null()) { |
1069 JVMCI_ERROR("debug info expected at call at %i", pc_offset); |
1154 JVMCI_ERROR("debug info expected at call at %i", pc_offset); |
1070 } |
1155 } |
1073 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset, CHECK); |
1158 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset, CHECK); |
1074 if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { |
1159 if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { |
1075 // Need a static call stub for transitions from compiled to interpreted. |
1160 // Need a static call stub for transitions from compiled to interpreted. |
1076 CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); |
1161 CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); |
1077 } |
1162 } |
|
1163 #if INCLUDE_AOT |
|
1164 // Trampoline to far aot code. |
|
1165 CompiledStaticCall::emit_to_aot_stub(buffer, _instructions->start() + pc_offset); |
|
1166 #endif |
1078 } |
1167 } |
1079 |
1168 |
1080 _next_call_type = INVOKE_INVALID; |
1169 _next_call_type = INVOKE_INVALID; |
1081 |
1170 |
1082 if (debug_info.not_null()) { |
1171 if (debug_info.not_null()) { |
1091 } else if (reference->is_a(site_ConstantReference::klass())) { |
1180 } else if (reference->is_a(site_ConstantReference::klass())) { |
1092 Handle constant = site_ConstantReference::constant(reference); |
1181 Handle constant = site_ConstantReference::constant(reference); |
1093 if (constant.is_null()) { |
1182 if (constant.is_null()) { |
1094 THROW(vmSymbols::java_lang_NullPointerException()); |
1183 THROW(vmSymbols::java_lang_NullPointerException()); |
1095 } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { |
1184 } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { |
1096 pd_patch_OopConstant(pc_offset, constant, CHECK); |
1185 if (!_immutable_pic_compilation) { |
|
1186 // Do not patch during PIC compilation. |
|
1187 pd_patch_OopConstant(pc_offset, constant, CHECK); |
|
1188 } |
1097 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
1189 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
1098 pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); |
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 } |
1099 } else { |
1197 } else { |
1100 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name()); |
1198 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name()); |
1101 } |
1199 } |
1102 } else if (reference->is_a(site_DataSectionReference::klass())) { |
1200 } else if (reference->is_a(site_DataSectionReference::klass())) { |
1103 int data_offset = site_DataSectionReference::offset(reference); |
1201 int data_offset = site_DataSectionReference::offset(reference); |
1156 case CARD_TABLE_ADDRESS: |
1254 case CARD_TABLE_ADDRESS: |
1157 case HEAP_TOP_ADDRESS: |
1255 case HEAP_TOP_ADDRESS: |
1158 case HEAP_END_ADDRESS: |
1256 case HEAP_END_ADDRESS: |
1159 case NARROW_KLASS_BASE_ADDRESS: |
1257 case NARROW_KLASS_BASE_ADDRESS: |
1160 case CRC_TABLE_ADDRESS: |
1258 case CRC_TABLE_ADDRESS: |
|
1259 case LOG_OF_HEAP_REGION_GRAIN_BYTES: |
|
1260 case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED: |
1161 break; |
1261 break; |
1162 default: |
1262 default: |
1163 JVMCI_ERROR("invalid mark id: %d", id); |
1263 JVMCI_ERROR("invalid mark id: %d", id); |
1164 break; |
1264 break; |
1165 } |
1265 } |