< prev index next >

src/share/vm/c1/c1_Runtime1.cpp

Print this page
rev 12906 : [mq]: gc_interface

@@ -37,19 +37,21 @@
 #include "code/pcDesc.hpp"
 #include "code/scopeDesc.hpp"
 #include "code/vtableStubs.hpp"
 #include "compiler/disassembler.hpp"
 #include "gc/shared/barrierSet.hpp"
+#include "gc/shared/c1BarrierSetCodeGen.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/bytecode.hpp"
 #include "interpreter/interpreter.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/access.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/javaCalls.hpp"

@@ -103,11 +105,10 @@
 
 #ifndef PRODUCT
 // statistics
 int Runtime1::_generic_arraycopy_cnt = 0;
 int Runtime1::_primitive_arraycopy_cnt = 0;
-int Runtime1::_oop_arraycopy_cnt = 0;
 int Runtime1::_generic_arraycopystub_cnt = 0;
 int Runtime1::_arraycopy_slowcase_cnt = 0;
 int Runtime1::_arraycopy_checkcast_cnt = 0;
 int Runtime1::_arraycopy_checkcast_attempt_cnt = 0;
 int Runtime1::_new_type_array_slowcase_cnt = 0;

@@ -175,13 +176,21 @@
     Deoptimization::deoptimize_frame(thread, caller_frame.id());
     assert(caller_is_deopted(), "Must be deoptimized");
   }
 }
 
+class StubIDStubAssemblerCodeGenClosure: public StubAssemblerCodeGenClosure {
+ private:
+  Runtime1::StubID _id;
+ public:
+  StubIDStubAssemblerCodeGenClosure(Runtime1::StubID id) : _id(id) {}
+  virtual OopMapSet* generate_code(StubAssembler* sasm) {
+    return Runtime1::generate_code_for(_id, sasm);
+  }
+};
 
-void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
-  assert(0 <= id && id < number_of_ids, "illegal stub id");
+CodeBlob* Runtime1::generate_blob(BufferBlob* buffer_blob, int stub_id, const char* name, bool expect_oop_map, StubAssemblerCodeGenClosure* cl) {
   ResourceMark rm;
   // create code buffer for code storage
   CodeBuffer code(buffer_blob);
 
   OopMapSet* oop_maps;

@@ -189,58 +198,60 @@
   bool must_gc_arguments;
 
   Compilation::setup_code_buffer(&code, 0);
 
   // create assembler for code generation
-  StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
+  StubAssembler* sasm = new StubAssembler(&code, name, stub_id);
   // generate code for runtime stub
-  oop_maps = generate_code_for(id, sasm);
+  oop_maps = cl->generate_code(sasm);
   assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
          "if stub has an oop map it must have a valid frame size");
+  assert(!expect_oop_map || oop_maps != NULL, "must have an oopmap");
+
+  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
+  sasm->align(BytesPerWord);
+  // make sure all code is in code buffer
+  sasm->flush();
+
+  frame_size = sasm->frame_size();
+  must_gc_arguments = sasm->must_gc_arguments();
+  // create blob - distinguish a few special cases
+  CodeBlob* blob = RuntimeStub::new_runtime_stub(name,
+                                                 &code,
+                                                 CodeOffsets::frame_never_safe,
+                                                 frame_size,
+                                                 oop_maps,
+                                                 must_gc_arguments);
+  assert(blob != NULL, "blob must exist");
+  return blob;
+}
 
+void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {
+  assert(0 <= id && id < number_of_ids, "illegal stub id");
+  bool expect_oop_map = true;
 #ifdef ASSERT
   // Make sure that stubs that need oopmaps have them
   switch (id) {
     // These stubs don't need to have an oopmap
   case dtrace_object_alloc_id:
-  case g1_pre_barrier_slow_id:
-  case g1_post_barrier_slow_id:
   case slow_subtype_check_id:
   case fpu2long_stub_id:
   case unwind_exception_id:
   case counter_overflow_id:
 #if defined(SPARC) || defined(PPC32)
   case handle_exception_nofpu_id:  // Unused on sparc
 #endif
+    expect_oop_map = false;
     break;
-
-    // All other stubs should have oopmaps
-  default:
-    assert(oop_maps != NULL, "must have an oopmap");
   }
 #endif
-
-  // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
-  sasm->align(BytesPerWord);
-  // make sure all code is in code buffer
-  sasm->flush();
-
-  frame_size = sasm->frame_size();
-  must_gc_arguments = sasm->must_gc_arguments();
-  // create blob - distinguish a few special cases
-  CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
-                                                 &code,
-                                                 CodeOffsets::frame_never_safe,
-                                                 frame_size,
-                                                 oop_maps,
-                                                 must_gc_arguments);
+  StubIDStubAssemblerCodeGenClosure cl(id);
+  CodeBlob* blob = generate_blob(buffer_blob, id, name_for(id), expect_oop_map, &cl);
   // install blob
-  assert(blob != NULL, "blob must exist");
   _blobs[id] = blob;
 }
 
-
 void Runtime1::initialize(BufferBlob* blob) {
   // platform-dependent initialization
   initialize_pd();
   // generate stubs
   for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);

@@ -254,13 +265,14 @@
         _blobs[id]->oop_maps()->print();
       }
     }
   }
 #endif
+  C1BarrierSetCodeGen* code_gen = Universe::heap()->barrier_set()->c1_code_gen();
+  code_gen->generate_c1_runtime_stubs(blob);
 }
 
-
 CodeBlob* Runtime1::blob_for(StubID id) {
   assert(0 <= id && id < number_of_ids, "illegal stub id");
   return _blobs[id];
 }
 

@@ -1223,15 +1235,10 @@
   // is on the right list.
   if (ScavengeRootsInCode) {
     MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
     nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
     guarantee(nm != NULL, "only nmethods can contain non-perm oops");
-    if (!nm->on_scavenge_root_list() &&
-        ((mirror.not_null() && mirror()->is_scavengable()) ||
-         (appendix.not_null() && appendix->is_scavengable()))) {
-      CodeCache::add_scavenge_root_nmethod(nm);
-    }
 
     // Since we've patched some oops in the nmethod,
     // (re)register it with the heap.
     Universe::heap()->register_nmethod(nm);
   }

@@ -1374,31 +1381,19 @@
 
 // Below length is the # elements copied.
 template <class T> int obj_arraycopy_work(oopDesc* src, T* src_addr,
                                           oopDesc* dst, T* dst_addr,
                                           int length) {
-
-  // For performance reasons, we assume we are using a card marking write
-  // barrier. The assert will fail if this is not the case.
-  // Note that we use the non-virtual inlineable variant of write_ref_array.
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
-  assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
   if (src == dst) {
-    // same object, no check
-    bs->write_ref_array_pre(dst_addr, length);
-    Copy::conjoint_oops_atomic(src_addr, dst_addr, length);
-    bs->write_ref_array((HeapWord*)dst_addr, length);
+    HeapAccess<DEST_CONJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length);
     return ac_ok;
   } else {
     Klass* bound = ObjArrayKlass::cast(dst->klass())->element_klass();
     Klass* stype = ObjArrayKlass::cast(src->klass())->element_klass();
     if (stype == bound || stype->is_subtype_of(bound)) {
       // Elements are guaranteed to be subtypes, so no check necessary
-      bs->write_ref_array_pre(dst_addr, length);
-      Copy::conjoint_oops_atomic(src_addr, dst_addr, length);
-      bs->write_ref_array((HeapWord*)dst_addr, length);
+      HeapAccess<DEST_DISJOINT | DEST_COVARIANT | ACCESS_ATOMIC>::oop_copy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length);
       return ac_ok;
     }
   }
   return ac_failed;
 }

@@ -1452,29 +1447,10 @@
   // Not guaranteed to be word atomic, but that doesn't matter
   // for anything but an oop array, which is covered by oop_arraycopy.
   Copy::conjoint_jbytes(src, dst, length);
 JRT_END
 
-JRT_LEAF(void, Runtime1::oop_arraycopy(HeapWord* src, HeapWord* dst, int num))
-#ifndef PRODUCT
-  _oop_arraycopy_cnt++;
-#endif
-
-  if (num == 0) return;
-  BarrierSet* bs = Universe::heap()->barrier_set();
-  assert(bs->has_write_ref_array_opt(), "Barrier set must have ref array opt");
-  assert(bs->has_write_ref_array_pre_opt(), "For pre-barrier as well.");
-  if (UseCompressedOops) {
-    bs->write_ref_array_pre((narrowOop*)dst, num);
-    Copy::conjoint_oops_atomic((narrowOop*) src, (narrowOop*) dst, num);
-  } else {
-    bs->write_ref_array_pre((oop*)dst, num);
-    Copy::conjoint_oops_atomic((oop*) src, (oop*) dst, num);
-  }
-  bs->write_ref_array(dst, num);
-JRT_END
-
 
 JRT_LEAF(int, Runtime1::is_instance_of(oopDesc* mirror, oopDesc* obj))
   // had to return int instead of bool, otherwise there may be a mismatch
   // between the C calling convention and the Java one.
   // e.g., on x86, GCC may clear only %al when returning a bool false, but

@@ -1544,11 +1520,10 @@
   tty->print_cr(" _byte_arraycopy_cnt:             %d", _byte_arraycopy_stub_cnt);
   tty->print_cr(" _short_arraycopy_cnt:            %d", _short_arraycopy_stub_cnt);
   tty->print_cr(" _int_arraycopy_cnt:              %d", _int_arraycopy_stub_cnt);
   tty->print_cr(" _long_arraycopy_cnt:             %d", _long_arraycopy_stub_cnt);
   tty->print_cr(" _primitive_arraycopy_cnt:        %d", _primitive_arraycopy_cnt);
-  tty->print_cr(" _oop_arraycopy_cnt (C):          %d", Runtime1::_oop_arraycopy_cnt);
   tty->print_cr(" _oop_arraycopy_cnt (stub):       %d", _oop_arraycopy_stub_cnt);
   tty->print_cr(" _arraycopy_slowcase_cnt:         %d", _arraycopy_slowcase_cnt);
   tty->print_cr(" _arraycopy_checkcast_cnt:        %d", _arraycopy_checkcast_cnt);
   tty->print_cr(" _arraycopy_checkcast_attempt_cnt:%d", _arraycopy_checkcast_attempt_cnt);
 
< prev index next >