changeset 12115:4c7c4d8333ac

8166562: C2: Suppress relocations in scratch emit. Reviewed-by: kvn
author goetz
date Thu, 22 Sep 2016 18:33:47 +0200
parents 1d70c7ca92cc
children 160d63f639af
files src/cpu/ppc/vm/ppc.ad src/share/vm/asm/assembler.cpp src/share/vm/asm/codeBuffer.cpp src/share/vm/asm/codeBuffer.hpp src/share/vm/opto/compile.cpp
diffstat 5 files changed, 90 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/ppc/vm/ppc.ad	Wed Oct 05 13:35:57 2016 +0200
+++ b/src/cpu/ppc/vm/ppc.ad	Thu Sep 22 18:33:47 2016 +0200
@@ -1097,21 +1097,19 @@
   // No entry point given, use the current pc.
   if (entry_point == NULL) entry_point = __ pc();
 
-  if (!Compile::current()->in_scratch_emit_size()) {
-    // Put the entry point as a constant into the constant pool.
-    const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
-    if (entry_point_toc_addr == NULL) {
-      ciEnv::current()->record_out_of_memory_failure();
-      return offsets;
-    }
-    const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
-
-    // Emit the trampoline stub which will be related to the branch-and-link below.
-    CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
-    if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
-    __ relocate(rtype);
+  // Put the entry point as a constant into the constant pool.
+  const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
+  if (entry_point_toc_addr == NULL) {
+    ciEnv::current()->record_out_of_memory_failure();
+    return offsets;
   }
-
+  const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
+  
+  // Emit the trampoline stub which will be related to the branch-and-link below.
+  CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, offsets.insts_call_instruction_offset);
+  if (ciEnv::current()->failing()) { return offsets; } // Code cache may be full.
+  __ relocate(rtype);
+  
   // Note: At this point we do not have the address of the trampoline
   // stub, and the entry point might be too far away for bl, so __ pc()
   // serves as dummy and the bl will be patched later.
@@ -2434,6 +2432,29 @@
     MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
 
+    address const_toc_addr;
+    // Create a non-oop constant, no relocation needed.
+    // If it is an IC, it has a virtual_call_Relocation.
+    const_toc_addr = __ long_constant((jlong)$src$$constant);
+    if (const_toc_addr == NULL) {
+      ciEnv::current()->record_out_of_memory_failure();
+      return;
+    }
+    
+    // Get the constant's TOC offset.
+    toc_offset = __ offset_to_method_toc(const_toc_addr);
+    
+    // Keep the current instruction offset in mind.
+    ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
+  
+    __ ld($dst$$Register, toc_offset, $toc$$Register);
+  %}
+
+  enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
+
+    MacroAssembler _masm(&cbuf);
+
     if (!ra_->C->in_scratch_emit_size()) {
       address const_toc_addr;
       // Create a non-oop constant, no relocation needed.
@@ -2445,31 +2466,6 @@
       }
 
       // Get the constant's TOC offset.
-      toc_offset = __ offset_to_method_toc(const_toc_addr);
-
-      // Keep the current instruction offset in mind.
-      ((loadConLNode*)this)->_cbuf_insts_offset = __ offset();
-    }
-
-    __ ld($dst$$Register, toc_offset, $toc$$Register);
-  %}
-
-  enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
-
-    MacroAssembler _masm(&cbuf);
-
-    if (!ra_->C->in_scratch_emit_size()) {
-      address const_toc_addr;
-      // Create a non-oop constant, no relocation needed.
-      // If it is an IC, it has a virtual_call_Relocation.
-      const_toc_addr = __ long_constant((jlong)$src$$constant);
-      if (const_toc_addr == NULL) {
-        ciEnv::current()->record_out_of_memory_failure();
-        return;
-      }
-
-      // Get the constant's TOC offset.
       const int toc_offset = __ offset_to_method_toc(const_toc_addr);
       // Store the toc offset of the constant.
       ((loadConL_hiNode*)this)->_const_toc_offset = toc_offset;
@@ -2586,31 +2582,29 @@
     MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
 
-    if (!ra_->C->in_scratch_emit_size()) {
-      intptr_t val = $src$$constant;
-      relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
-      address const_toc_addr;
-      if (constant_reloc == relocInfo::oop_type) {
-        // Create an oop constant and a corresponding relocation.
-        AddressLiteral a = __ allocate_oop_address((jobject)val);
-        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
-        __ relocate(a.rspec());
-      } else if (constant_reloc == relocInfo::metadata_type) {
-        AddressLiteral a = __ constant_metadata_address((Metadata *)val);
-        const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
-        __ relocate(a.rspec());
-      } else {
-        // Create a non-oop constant, no relocation needed.
-        const_toc_addr = __ long_constant((jlong)$src$$constant);
-      }
-
-      if (const_toc_addr == NULL) {
-        ciEnv::current()->record_out_of_memory_failure();
-        return;
-      }
-      // Get the constant's TOC offset.
-      toc_offset = __ offset_to_method_toc(const_toc_addr);
-    }
+    intptr_t val = $src$$constant;
+    relocInfo::relocType constant_reloc = $src->constant_reloc();  // src
+    address const_toc_addr;
+    if (constant_reloc == relocInfo::oop_type) {
+      // Create an oop constant and a corresponding relocation.
+      AddressLiteral a = __ allocate_oop_address((jobject)val);
+      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
+      __ relocate(a.rspec());
+    } else if (constant_reloc == relocInfo::metadata_type) {
+      AddressLiteral a = __ constant_metadata_address((Metadata *)val);
+      const_toc_addr = __ address_constant((address)a.value(), RelocationHolder::none);
+      __ relocate(a.rspec());
+    } else {
+      // Create a non-oop constant, no relocation needed.
+      const_toc_addr = __ long_constant((jlong)$src$$constant);
+    }
+
+    if (const_toc_addr == NULL) {
+      ciEnv::current()->record_out_of_memory_failure();
+      return;
+    }
+    // Get the constant's TOC offset.
+    toc_offset = __ offset_to_method_toc(const_toc_addr);
 
     __ ld($dst$$Register, toc_offset, $toc$$Register);
   %}
@@ -3282,28 +3276,26 @@
     } else {
       // Remember the offset not the address.
       const int start_offset = __ offset();
+
       // The trampoline stub.
-      if (!Compile::current()->in_scratch_emit_size()) {
-        // No entry point given, use the current pc.
-        // Make sure branch fits into
-        if (entry_point == 0) entry_point = __ pc();
-
-        // Put the entry point as a constant into the constant pool.
-        const address entry_point_toc_addr   = __ address_constant(entry_point, RelocationHolder::none);
-        if (entry_point_toc_addr == NULL) {
-          ciEnv::current()->record_out_of_memory_failure();
-          return;
-        }
-        const int     entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
-
-
-        // Emit the trampoline stub which will be related to the branch-and-link below.
-        CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
-        if (ciEnv::current()->failing()) { return; } // Code cache may be full.
-        int method_index = resolved_method_index(cbuf);
-        __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
-                                       : static_call_Relocation::spec(method_index));
+      // No entry point given, use the current pc.
+      // Make sure branch fits into
+      if (entry_point == 0) entry_point = __ pc();
+
+      // Put the entry point as a constant into the constant pool.
+      const address entry_point_toc_addr = __ address_constant(entry_point, RelocationHolder::none);
+      if (entry_point_toc_addr == NULL) {
+        ciEnv::current()->record_out_of_memory_failure();
+        return;
       }
+      const int entry_point_toc_offset = __ offset_to_method_toc(entry_point_toc_addr);
+
+      // Emit the trampoline stub which will be related to the branch-and-link below.
+      CallStubImpl::emit_trampoline_stub(_masm, entry_point_toc_offset, start_offset);
+      if (ciEnv::current()->failing()) { return; } // Code cache may be full.
+      int method_index = resolved_method_index(cbuf);
+      __ relocate(_optimized_virtual ? opt_virtual_call_Relocation::spec(method_index)
+                  : static_call_Relocation::spec(method_index));
 
       // The real call.
       // Note: At this point we do not have the address of the trampoline
--- a/src/share/vm/asm/assembler.cpp	Wed Oct 05 13:35:57 2016 +0200
+++ b/src/share/vm/asm/assembler.cpp	Thu Sep 22 18:33:47 2016 +0200
@@ -153,6 +153,8 @@
 
 void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
   assert(_loc == -1, "Label is unbound");
+  // Don't add patch locations during scratch emit.
+  if (cb->insts()->scratch_emit()) { return; }
   if (_patch_index < PatchCacheSize) {
     _patches[_patch_index] = branch_loc;
   } else {
--- a/src/share/vm/asm/codeBuffer.cpp	Wed Oct 05 13:35:57 2016 +0200
+++ b/src/share/vm/asm/codeBuffer.cpp	Thu Sep 22 18:33:47 2016 +0200
@@ -331,6 +331,8 @@
 }
 
 void CodeSection::relocate(address at, RelocationHolder const& spec, int format) {
+  // Do not relocate in scratch buffers.
+  if (scratch_emit()) { return; }
   Relocation* reloc = spec.reloc();
   relocInfo::relocType rtype = (relocInfo::relocType) reloc->type();
   if (rtype == relocInfo::none)  return;
--- a/src/share/vm/asm/codeBuffer.hpp	Wed Oct 05 13:35:57 2016 +0200
+++ b/src/share/vm/asm/codeBuffer.hpp	Thu Sep 22 18:33:47 2016 +0200
@@ -92,6 +92,7 @@
   address     _locs_point;      // last relocated position (grows upward)
   bool        _locs_own;        // did I allocate the locs myself?
   bool        _frozen;          // no more expansion of this section
+  bool        _scratch_emit;    // Buffer is used for scratch emit, don't relocate.
   char        _index;           // my section number (SECT_INST, etc.)
   CodeBuffer* _outer;           // enclosing CodeBuffer
 
@@ -108,6 +109,7 @@
     _locs_point    = NULL;
     _locs_own      = false;
     _frozen        = false;
+    _scratch_emit  = false;
     debug_only(_index = (char)-1);
     debug_only(_outer = (CodeBuffer*)badAddress);
   }
@@ -166,6 +168,10 @@
   bool        is_frozen() const     { return _frozen; }
   bool        has_locs() const      { return _locs_end != NULL; }
 
+  // Mark scratch buffer.
+  void        set_scratch_emit()    { _scratch_emit = true; }
+  bool        scratch_emit()        { return _scratch_emit; }
+
   CodeBuffer* outer() const         { return _outer; }
 
   // is a given address in this section?  (2nd version is end-inclusive)
--- a/src/share/vm/opto/compile.cpp	Wed Oct 05 13:35:57 2016 +0200
+++ b/src/share/vm/opto/compile.cpp	Thu Sep 22 18:33:47 2016 +0200
@@ -574,6 +574,10 @@
   buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize);
   buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize);
   buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize);
+  // Mark as scratch buffer.
+  buf.consts()->set_scratch_emit();
+  buf.insts()->set_scratch_emit();
+  buf.stubs()->set_scratch_emit();
 
   // Do the emission.