< prev index next >

src/share/vm/c1/c1_Runtime1.cpp

Print this page
rev 12906 : [mq]: gc_interface

*** 37,55 **** --- 37,57 ---- #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,113 **** #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; --- 105,114 ----
*** 175,187 **** Deoptimization::deoptimize_frame(thread, caller_frame.id()); assert(caller_is_deopted(), "Must be deoptimized"); } } ! void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) { ! assert(0 <= id && id < number_of_ids, "illegal stub id"); ResourceMark rm; // create code buffer for code storage CodeBuffer code(buffer_blob); OopMapSet* oop_maps; --- 176,196 ---- 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); + } + }; ! 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,246 **** bool must_gc_arguments; Compilation::setup_code_buffer(&code, 0); // create assembler for code generation ! StubAssembler* sasm = new StubAssembler(&code, name_for(id), id); // generate code for runtime stub ! oop_maps = generate_code_for(id, sasm); assert(oop_maps == NULL || sasm->frame_size() != no_frame_size, "if stub has an oop map it must have a valid frame size"); #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 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); // 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); --- 198,257 ---- bool must_gc_arguments; Compilation::setup_code_buffer(&code, 0); // create assembler for code generation ! StubAssembler* sasm = new StubAssembler(&code, name, stub_id); // generate code for runtime stub ! 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 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; } #endif ! StubIDStubAssemblerCodeGenClosure cl(id); ! CodeBlob* blob = generate_blob(buffer_blob, id, name_for(id), expect_oop_map, &cl); // install blob _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,266 **** _blobs[id]->oop_maps()->print(); } } } #endif } - CodeBlob* Runtime1::blob_for(StubID id) { assert(0 <= id && id < number_of_ids, "illegal stub id"); return _blobs[id]; } --- 265,278 ---- _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,1237 **** // 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); } --- 1235,1244 ----
*** 1374,1404 **** // 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); 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); return ac_ok; } } return ac_failed; } --- 1381,1399 ---- // 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) { if (src == dst) { ! 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 ! 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,1480 **** // 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 --- 1447,1456 ----
*** 1544,1554 **** 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); --- 1520,1529 ----
< prev index next >