changeset 3881:1acccb7c0b01

8003850: add support for constants in stub code Summary: remember the code section and switch back to the proper one when adding constants. Reviewed-by: twisti, kvn Contributed-by: goetz.lindenmaier@sap.com
author kvn
date Tue, 27 Nov 2012 17:41:38 -0800
parents 2aff40cb4703
children 6ab62ad83507
files src/share/vm/asm/assembler.cpp src/share/vm/asm/assembler.hpp src/share/vm/asm/codeBuffer.cpp
diffstat 3 files changed, 29 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/asm/assembler.cpp	Tue Nov 27 17:24:15 2012 -0800
+++ b/src/share/vm/asm/assembler.cpp	Tue Nov 27 17:41:38 2012 -0800
@@ -104,7 +104,7 @@
 address AbstractAssembler::start_a_const(int required_space, int required_align) {
   CodeBuffer*  cb = code();
   CodeSection* cs = cb->consts();
-  assert(_code_section == cb->insts(), "not in insts?");
+  assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?");
   sync();
   address end = cs->end();
   int pad = -(intptr_t)end & (required_align-1);
@@ -121,14 +121,13 @@
 }
 
 // Inform CodeBuffer that incoming code and relocation will be code
-// Should not be called if start_a_const() returned NULL
-void AbstractAssembler::end_a_const() {
+// in section cs (insts or stubs).
+void AbstractAssembler::end_a_const(CodeSection* cs) {
   assert(_code_section == code()->consts(), "not in consts?");
   sync();
-  set_code_section(code()->insts());
+  set_code_section(cs);
 }
 
-
 void AbstractAssembler::flush() {
   sync();
   ICache::invalidate_range(addr_at(0), offset());
--- a/src/share/vm/asm/assembler.hpp	Tue Nov 27 17:24:15 2012 -0800
+++ b/src/share/vm/asm/assembler.hpp	Tue Nov 27 17:41:38 2012 -0800
@@ -348,52 +348,60 @@
   void       end_a_stub();
   // Ditto for constants.
   address    start_a_const(int required_space, int required_align = sizeof(double));
-  void       end_a_const();
+  void       end_a_const(CodeSection* cs);  // Pass the codesection to continue in (insts or stubs?).
 
   // constants support
+  //
+  // We must remember the code section (insts or stubs) in c1
+  // so we can reset to the proper section in end_a_const().
   address long_constant(jlong c) {
+    CodeSection* c1 = _code_section;
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
       *(jlong*)ptr = c;
       _code_pos = ptr + sizeof(c);
-      end_a_const();
+      end_a_const(c1);
     }
     return ptr;
   }
   address double_constant(jdouble c) {
+    CodeSection* c1 = _code_section;
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
       *(jdouble*)ptr = c;
       _code_pos = ptr + sizeof(c);
-      end_a_const();
+      end_a_const(c1);
     }
     return ptr;
   }
   address float_constant(jfloat c) {
+    CodeSection* c1 = _code_section;
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
       *(jfloat*)ptr = c;
       _code_pos = ptr + sizeof(c);
-      end_a_const();
+      end_a_const(c1);
     }
     return ptr;
   }
   address address_constant(address c) {
+    CodeSection* c1 = _code_section;
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
       *(address*)ptr = c;
       _code_pos = ptr + sizeof(c);
-      end_a_const();
+      end_a_const(c1);
     }
     return ptr;
   }
   address address_constant(address c, RelocationHolder const& rspec) {
+    CodeSection* c1 = _code_section;
     address ptr = start_a_const(sizeof(c), sizeof(c));
     if (ptr != NULL) {
       relocate(rspec);
       *(address*)ptr = c;
       _code_pos = ptr + sizeof(c);
-      end_a_const();
+      end_a_const(c1);
     }
     return ptr;
   }
--- a/src/share/vm/asm/codeBuffer.cpp	Tue Nov 27 17:24:15 2012 -0800
+++ b/src/share/vm/asm/codeBuffer.cpp	Tue Nov 27 17:41:38 2012 -0800
@@ -749,7 +749,18 @@
 
     // Make the new code copy use the old copy's relocations:
     dest_cs->initialize_locs_from(cs);
+  }
 
+  // Do relocation after all sections are copied.
+  // This is necessary if the code uses constants in stubs, which are
+  // relocated when the corresponding instruction in the code (e.g., a
+  // call) is relocated. Stubs are placed behind the main code
+  // section, so that section has to be copied before relocating.
+  for (int n = (int) SECT_FIRST; n < (int)SECT_LIMIT; n++) {
+    // pull code out of each section
+    const CodeSection* cs = code_section(n);
+    if (cs->is_empty()) continue;  // skip trivial section
+    CodeSection* dest_cs = dest->code_section(n);
     { // Repair the pc relative information in the code after the move
       RelocIterator iter(dest_cs);
       while (iter.next()) {