--- old/src/share/vm/jvmci/jvmciCodeInstaller.cpp 2016-11-03 14:16:35.000000000 -0700 +++ new/src/share/vm/jvmci/jvmciCodeInstaller.cpp 2016-11-03 14:16:35.000000000 -0700 @@ -172,6 +172,69 @@ return map; } +AOTOopRecorder::AOTOopRecorder(Arena* arena, bool deduplicate) : OopRecorder(arena, deduplicate) { + _meta_strings = new GrowableArray(); +} + +int AOTOopRecorder::nr_meta_strings() const { + return _meta_strings->length(); +} + +const char* AOTOopRecorder::meta_element(int pos) const { + return _meta_strings->at(pos); +} + +int AOTOopRecorder::find_index(Metadata* h) { + int index = this->OopRecorder::find_index(h); + + Klass* klass = NULL; + if (h->is_klass()) { + klass = (Klass*) h; + record_meta_string(klass->signature_name(), index); + } else if (h->is_method()) { + Method* method = (Method*) h; + // Need klass->signature_name() in method name + klass = method->method_holder(); + const char* klass_name = klass->signature_name(); + int klass_name_len = (int)strlen(klass_name); + Symbol* method_name = method->name(); + Symbol* signature = method->signature(); + int method_name_len = method_name->utf8_length(); + int method_sign_len = signature->utf8_length(); + int len = klass_name_len + 1 + method_name_len + method_sign_len; + char* dest = NEW_RESOURCE_ARRAY(char, len + 1); + strcpy(dest, klass_name); + dest[klass_name_len] = '.'; + strcpy(&dest[klass_name_len + 1], method_name->as_C_string()); + strcpy(&dest[klass_name_len + 1 + method_name_len], signature->as_C_string()); + dest[len] = 0; + record_meta_string(dest, index); + } + + return index; +} + +int AOTOopRecorder::find_index(jobject h) { + if (h == NULL) { + return 0; + } + oop javaMirror = JNIHandles::resolve(h); + Klass* klass = java_lang_Class::as_Klass(javaMirror); + return find_index(klass); +} + +void AOTOopRecorder::record_meta_string(const char* name, int index) { + assert(index > 0, "must be 1..n"); + index -= 1; // reduce by one to convert to array index + + if (index < _meta_strings->length()) { + assert(strcmp(name, _meta_strings->at(index)) == 0, "must match"); + } else { + assert(index == _meta_strings->length(), "must be last"); + _meta_strings->append(name); + } +} + void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) { /* * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base @@ -481,7 +544,10 @@ JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) { CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata"); jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); - initialize_dependencies(JNIHandles::resolve(compiled_code_obj), NULL, CHECK_OK); + AOTOopRecorder* recorder = new AOTOopRecorder(&_arena, true); + initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder, CHECK_OK); + + metadata.set_oop_recorder(recorder); // Get instructions and constants CodeSections early because we need it. _instructions = buffer.insts(); @@ -553,7 +619,7 @@ stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, compiler, _debug_recorder, _dependencies, env, id, has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log); - cb = nm; + cb = nm->as_codeblob_or_null(); if (nm != NULL && env == NULL) { DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler); bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption; @@ -623,25 +689,40 @@ } int CodeInstaller::estimate_stubs_size(TRAPS) { - // Estimate the number of static call stubs that might be emitted. + // Estimate the number of static and aot call stubs that might be emitted. int static_call_stubs = 0; + int aot_call_stubs = 0; objArrayOop sites = this->sites(); for (int i = 0; i < sites->length(); i++) { oop site = sites->obj_at(i); - if (site != NULL && site->is_a(site_Mark::klass())) { - oop id_obj = site_Mark::id(site); - if (id_obj != NULL) { - if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { - JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name()); + if (site != NULL) { + if (site->is_a(site_Mark::klass())) { + oop id_obj = site_Mark::id(site); + if (id_obj != NULL) { + if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { + JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name()); + } + jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); + if (id == INVOKESTATIC || id == INVOKESPECIAL) { + static_call_stubs++; + } } - jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); - if (id == INVOKESTATIC || id == INVOKESPECIAL) { - static_call_stubs++; + } + if (UseAOT && site->is_a(site_Call::klass())) { + oop target = site_Call::target(site); + InstanceKlass* target_klass = InstanceKlass::cast(target->klass()); + if (!target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) { + // Add far aot trampolines. + aot_call_stubs++; } } } } - return static_call_stubs * CompiledStaticCall::to_interp_stub_size(); + int size = static_call_stubs * CompiledStaticCall::to_interp_stub_size(); +#if INCLUDE_AOT + size += aot_call_stubs * CompiledStaticCall::to_aot_stub_size(); +#endif + return size; } // perform data and call relocation on the CodeBuffer @@ -1063,6 +1144,10 @@ if (foreign_call.not_null()) { jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call); + if (_immutable_pic_compilation) { + // Use fake short distance during PIC compilation. + foreign_call_destination = (jlong)(_instructions->start() + pc_offset); + } CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK); } else { // method != NULL if (debug_info.is_null()) { @@ -1075,6 +1160,10 @@ // Need a static call stub for transitions from compiled to interpreted. CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); } +#if INCLUDE_AOT + // Trampoline to far aot code. + CompiledStaticCall::emit_to_aot_stub(buffer, _instructions->start() + pc_offset); +#endif } _next_call_type = INVOKE_INVALID; @@ -1093,9 +1182,18 @@ if (constant.is_null()) { THROW(vmSymbols::java_lang_NullPointerException()); } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { - pd_patch_OopConstant(pc_offset, constant, CHECK); + if (!_immutable_pic_compilation) { + // Do not patch during PIC compilation. + pd_patch_OopConstant(pc_offset, constant, CHECK); + } } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { - pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); + if (!_immutable_pic_compilation) { + pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); + } + } else if (constant->is_a(HotSpotSentinelConstant::klass())) { + if (!_immutable_pic_compilation) { + JVMCI_ERROR("sentinel constant not supported for normal compiles: %s", constant->klass()->signature_name()); + } } else { JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name()); } @@ -1158,6 +1256,7 @@ case HEAP_END_ADDRESS: case NARROW_KLASS_BASE_ADDRESS: case CRC_TABLE_ADDRESS: + case LOG_OF_HEAP_REGION_GRAIN_BYTES: break; default: JVMCI_ERROR("invalid mark id: %d", id);