Migrate HotSpot 14 to 25

I use x86 cpu platform-dependent for an instance.

JDK-8174962

$ hg log -pr 8504 > 8504.patch

Metadata

JDK-6964458 Reimplement class meta-data storage to use native memory.

$ hg log -pr 3602 > 3602.patch

assembler_x86

Add case relocInfo::metadata_type in AddressLiteral constructor.

AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) {    
  _is_lval = false;                                                                 
  _target = target;                                                                 
  switch (rtype) {                                                                  
  case relocInfo::oop_type:                                                         
+ case relocInfo::metadata_type:
  

Change bool disp_is_oop to relocInfo::relocType disp_reloc for Address::make_raw.

-Address Address::make_raw(int base, int index, int scale, int disp, bool disp_is_oop) {
+Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) {
   RelocationHolder rspec;
-  if (disp_is_oop) {
-    rspec = Relocation::spec_simple(relocInfo::oop_type);
+  if (disp_reloc != relocInfo::none) {
+    rspec = Relocation::spec_simple(disp_reloc);
  

Exception Handler

c1_Runtime1_x86, c1_LIRAssembler_x86

JDK-7012914 JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc

$ hg log -pr 2168 > 2168.patch

Add handle_exception_from_callee StubID. But why set_frame_size as 2 in Runtime1::generate_handle_exception? if purposely modified set_frame_size to 60, then assert(caller_frame.is_compiled_frame()) failed prospective. Because CodeBlob allocation use frame size of StubAssembler, and frame_x86 use CodeBlob's frame size.

void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
  ...
  // create blob - distinguish a few special cases
  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
                                                 &code,
                                                 CodeOffsets::frame_never_safe,
                                                 sasm->frame_size(),
                                                 oop_maps,
                                                 sasm->must_gc_arguments());
  ...
  

OopMap use Amalloc to allocate memory.

OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) {
  ...
+  case handle_exception_from_callee_id: {
+    // At this point all registers except exception oop (RAX) and
+    // exception pc (RDX) are dead.
+    const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
+    oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word /*2*/, 0);
+    sasm->set_frame_size(frame_size);
+    WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes));
+    break;
+  }
  ...
  

And aarch64 set to 2 toOo :) but sparc doesn't set to 2.

+  case handle_exception_from_callee_id:
+    // At this point all registers except exception oop (Oexception)
+    // and exception pc (Oissuing_pc) are dead.
+    oop_map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
+    sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
+    __ save_frame_c1(frame_size_in_bytes);
+    __ mov(Oexception->after_save(),  Oexception);
+    __ mov(Oissuing_pc->after_save(), Oissuing_pc);
+    break;
  

sparc also use the same frame_size_in_bytes, pay more attention to Runtime1::initialize_pd, in generate_oop_map.

So it is better to understand the different stack layout between x86, sparc, aarch64 and mips.

enum reg_save_layout {
  // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that
  // happen and will assert if the stack size we create is misaligned
...
-  reg_save_frame_size,  // As noted: neglects any parameters to runtime                     // 504
-                                                                                  
-#ifdef _WIN64                                                                     
-  c_rarg0_off = rcx_off,                                                          
-#else                                                                             
-  c_rarg0_off = rdi_off,                                                          
-#endif // WIN64                                                                   
-                                                                                  
-  // equates                                                                      
-                                                                                  
-  // illegal instruction handler                                                  
-  continue_dest_off = temp_1_off,                                                 
-                                                                                  
-  // deoptimization equates                                                       
-  fp0_off = float_regs_as_doubles_off, // slot for java float/double return value
-  xmm0_off = xmm_regs_as_doubles_off,  // slot for java float/double return value
-  deopt_type = temp_2_off,             // slot for type of deopt in progress   
-  ret_type = temp_1_off                // slot for return type                    
+  reg_save_frame_size   // As noted: neglects any parameters to runtime                     // 504
 };
  

JDK-6919934 JSR 292 needs to support x86 C1

$ hg log -pr 1295 > 1295.patch

Remove the if (compilation()->has_exception_handlers()) condition in LIR_Assembler::emit_exception_handler, but how to know the method has an exception handler without the if check? Rename monitorexit to emit_unwind_handler. Seperate unwind handler from exception handler, because Christian Thalinger refactory LIR_Assembler::emit_exception_handler heavily.

int LIR_Assembler::emit_exception_handler() {
  ...
-  // if the method does not have an exception handler, then there is
-  // no reason to search for one
-  if (compilation()->has_exception_handlers() || compilation()->env()->jvmti_can_post_on_exceptions()) {
-    // the exception oop and pc are in rax, and rdx
-    // no other registers need to be preserved, so invalidate them
-    __ invalidate_registers(false, true, true, false, true, true);
-
-    // check that there is really an exception
-    __ verify_not_null_oop(rax);
-
-    // search an exception handler (rax: exception oop, rdx: throwing pc)
-    __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
-
-    // if the call returns here, then the exception handler for particular
-    // exception doesn't exist -> unwind activation and forward exception to caller
-  }
-
-  // unlock the receiver/klass if necessary
-  // rax,: exception
-  ciMethod* method = compilation()->method();
-  if (method->is_synchronized() && GenerateSynchronizationCode) {
-    monitorexit(FrameMap::rbx_oop_opr, FrameMap::rcx_opr, SYNC_header, 0, rax);
-  }
-
-  // unwind activation and forward exception to caller
-  // rax,: exception
-  __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));
+  // search an exception handler (rax: exception oop, rdx: throwing pc)
+  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_nofpu_id)));
  ...
  

JDK-6921352 JSR 292 needs its own deopt handler (new CR for 6917766)

$ hg log -pr 1204 > 1204.patch

Change the return type of LIR_Assembler::emit_exception_handler from void to int Why?

-void LIR_Assembler::emit_exception_handler() {
+int LIR_Assembler::emit_exception_handler() {
  

Because Christian Thalinger refactory Compilation::emit_code_epilog. It doesn't need to call code_offsets->set_value in your target.

void Compilation::emit_code_epilog(LIR_Assembler* assembler) {
   ...
+  CodeOffsets* code_offsets = assembler->offsets();
+
   // generate code or slow cases
   assembler->emit_slow_case_stubs();
   CHECK_BAILOUT();
@@ -213,10 +215,18 @@
   assembler->emit_exception_entries(exception_info_list());
   CHECK_BAILOUT();
 
-  // generate code for exception handler
-  assembler->emit_exception_handler();
+  // Generate code for exception handler.
+  code_offsets->set_value(CodeOffsets::Exceptions, assembler->emit_exception_handler());
  ...
  

But return code_offset.

int LIR_Assembler::emit_exception_handler() {
  ...
-    return;
+    return -1;
  ...
-  compilation()->offsets()->set_value(CodeOffsets::Exceptions, code_offset());
  ...
+  return offset;
  

Compressed Oops

JDK-6985015 C1 needs to support compressed oops.

$ hg log -pr 1909 > 1909.patch

Compressed Class Pointers

Profiling

JDK-8023657 New type profiling points: arguments to call.

$ hg log -pr 5479 > 5479.patch

Reference