aoqi@0: /* aoqi@0: * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #include "precompiled.hpp" aoqi@0: #include "code/codeBlob.hpp" aoqi@0: #include "code/codeCache.hpp" aoqi@0: #include "code/relocInfo.hpp" aoqi@0: #include "compiler/disassembler.hpp" aoqi@0: #include "interpreter/bytecode.hpp" aoqi@0: #include "memory/allocation.inline.hpp" aoqi@0: #include "memory/heap.hpp" aoqi@0: #include "oops/oop.inline.hpp" aoqi@0: #include "prims/forte.hpp" aoqi@0: #include "runtime/handles.inline.hpp" aoqi@0: #include "runtime/interfaceSupport.hpp" aoqi@0: #include "runtime/mutexLocker.hpp" aoqi@0: #include "runtime/safepoint.hpp" aoqi@0: #include "runtime/sharedRuntime.hpp" aoqi@0: #include "runtime/vframe.hpp" aoqi@0: #include "services/memoryService.hpp" aoqi@0: #ifdef TARGET_ARCH_x86 aoqi@0: # include "nativeInst_x86.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_ARCH_sparc aoqi@0: # include "nativeInst_sparc.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_ARCH_zero aoqi@0: # include "nativeInst_zero.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_ARCH_arm aoqi@0: # include "nativeInst_arm.hpp" aoqi@0: #endif aoqi@0: #ifdef TARGET_ARCH_ppc aoqi@0: # include "nativeInst_ppc.hpp" aoqi@0: #endif aoqi@0: #ifdef COMPILER1 aoqi@0: #include "c1/c1_Runtime1.hpp" aoqi@0: #endif aoqi@0: aoqi@0: unsigned int align_code_offset(int offset) { aoqi@0: // align the size to CodeEntryAlignment aoqi@0: return aoqi@0: ((offset + (int)CodeHeap::header_size() + (CodeEntryAlignment-1)) & ~(CodeEntryAlignment-1)) aoqi@0: - (int)CodeHeap::header_size(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // This must be consistent with the CodeBlob constructor's layout actions. aoqi@0: unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) { aoqi@0: unsigned int size = header_size; aoqi@0: size += round_to(cb->total_relocation_size(), oopSize); aoqi@0: // align the size to CodeEntryAlignment aoqi@0: size = align_code_offset(size); aoqi@0: size += round_to(cb->total_content_size(), oopSize); aoqi@0: size += round_to(cb->total_oop_size(), oopSize); aoqi@0: size += round_to(cb->total_metadata_size(), oopSize); aoqi@0: return size; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // Creates a simple CodeBlob. Sets up the size of the different regions. aoqi@0: CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size) { aoqi@0: assert(size == round_to(size, oopSize), "unaligned size"); aoqi@0: assert(locs_size == round_to(locs_size, oopSize), "unaligned size"); aoqi@0: assert(header_size == round_to(header_size, oopSize), "unaligned size"); aoqi@0: assert(!UseRelocIndex, "no space allocated for reloc index yet"); aoqi@0: aoqi@0: // Note: If UseRelocIndex is enabled, there needs to be (at least) one aoqi@0: // extra word for the relocation information, containing the reloc aoqi@0: // index table length. Unfortunately, the reloc index table imple- aoqi@0: // mentation is not easily understandable and thus it is not clear aoqi@0: // what exactly the format is supposed to be. For now, we just turn aoqi@0: // off the use of this table (gri 7/6/2000). aoqi@0: aoqi@0: _name = name; aoqi@0: _size = size; aoqi@0: _frame_complete_offset = frame_complete; aoqi@0: _header_size = header_size; aoqi@0: _relocation_size = locs_size; aoqi@0: _content_offset = align_code_offset(header_size + _relocation_size); aoqi@0: _code_offset = _content_offset; aoqi@0: _data_offset = size; aoqi@0: _frame_size = 0; aoqi@0: set_oop_maps(NULL); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // Creates a CodeBlob from a CodeBuffer. Sets up the size of the different regions, aoqi@0: // and copy code and relocation info. aoqi@0: CodeBlob::CodeBlob( aoqi@0: const char* name, aoqi@0: CodeBuffer* cb, aoqi@0: int header_size, aoqi@0: int size, aoqi@0: int frame_complete, aoqi@0: int frame_size, aoqi@0: OopMapSet* oop_maps aoqi@0: ) { aoqi@0: assert(size == round_to(size, oopSize), "unaligned size"); aoqi@0: assert(header_size == round_to(header_size, oopSize), "unaligned size"); aoqi@0: aoqi@0: _name = name; aoqi@0: _size = size; aoqi@0: _frame_complete_offset = frame_complete; aoqi@0: _header_size = header_size; aoqi@0: _relocation_size = round_to(cb->total_relocation_size(), oopSize); aoqi@0: _content_offset = align_code_offset(header_size + _relocation_size); aoqi@0: _code_offset = _content_offset + cb->total_offset_of(cb->insts()); aoqi@0: _data_offset = _content_offset + round_to(cb->total_content_size(), oopSize); aoqi@0: assert(_data_offset <= size, "codeBlob is too small"); aoqi@0: aoqi@0: cb->copy_code_and_locs_to(this); aoqi@0: set_oop_maps(oop_maps); aoqi@0: _frame_size = frame_size; aoqi@0: #ifdef COMPILER1 aoqi@0: // probably wrong for tiered aoqi@0: assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs"); aoqi@0: #endif // COMPILER1 aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void CodeBlob::set_oop_maps(OopMapSet* p) { aoqi@0: // Danger Will Robinson! This method allocates a big aoqi@0: // chunk of memory, its your job to free it. aoqi@0: if (p != NULL) { aoqi@0: // We need to allocate a chunk big enough to hold the OopMapSet and all of its OopMaps aoqi@0: _oop_maps = (OopMapSet* )NEW_C_HEAP_ARRAY(unsigned char, p->heap_size(), mtCode); aoqi@0: p->copy_to((address)_oop_maps); aoqi@0: } else { aoqi@0: _oop_maps = NULL; aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* name2) { aoqi@0: // Do not hold the CodeCache lock during name formatting. aoqi@0: assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub"); aoqi@0: aoqi@0: if (stub != NULL) { aoqi@0: char stub_id[256]; aoqi@0: assert(strlen(name1) + strlen(name2) < sizeof(stub_id), ""); aoqi@0: jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2); aoqi@0: if (PrintStubCode) { aoqi@0: ttyLocker ttyl; aoqi@0: tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub); aoqi@0: Disassembler::decode(stub->code_begin(), stub->code_end()); aoqi@0: tty->cr(); aoqi@0: } aoqi@0: Forte::register_stub(stub_id, stub->code_begin(), stub->code_end()); aoqi@0: aoqi@0: if (JvmtiExport::should_post_dynamic_code_generated()) { aoqi@0: const char* stub_name = name2; aoqi@0: if (name2[0] == '\0') stub_name = name1; aoqi@0: JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end()); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void CodeBlob::flush() { aoqi@0: if (_oop_maps) { aoqi@0: FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode); aoqi@0: _oop_maps = NULL; aoqi@0: } aoqi@0: _strings.free(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: OopMap* CodeBlob::oop_map_for_return_address(address return_address) { aoqi@0: assert(oop_maps() != NULL, "nope"); aoqi@0: return oop_maps()->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin()); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of BufferBlob aoqi@0: aoqi@0: aoqi@0: BufferBlob::BufferBlob(const char* name, int size) aoqi@0: : CodeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0) aoqi@0: {} aoqi@0: aoqi@0: BufferBlob* BufferBlob::create(const char* name, int buffer_size) { aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: aoqi@0: BufferBlob* blob = NULL; aoqi@0: unsigned int size = sizeof(BufferBlob); aoqi@0: // align the size to CodeEntryAlignment aoqi@0: size = align_code_offset(size); aoqi@0: size += round_to(buffer_size, oopSize); aoqi@0: assert(name != NULL, "must provide a name"); aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: blob = new (size) BufferBlob(name, size); aoqi@0: } aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: BufferBlob::BufferBlob(const char* name, int size, CodeBuffer* cb) aoqi@0: : CodeBlob(name, cb, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, 0, NULL) aoqi@0: {} aoqi@0: aoqi@0: BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) { aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: aoqi@0: BufferBlob* blob = NULL; aoqi@0: unsigned int size = allocation_size(cb, sizeof(BufferBlob)); aoqi@0: assert(name != NULL, "must provide a name"); aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: blob = new (size) BufferBlob(name, size, cb); aoqi@0: } aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() { aoqi@0: void* p = CodeCache::allocate(size, is_critical); aoqi@0: return p; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void BufferBlob::free( BufferBlob *blob ) { aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: CodeCache::free((CodeBlob*)blob); aoqi@0: } aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of AdapterBlob aoqi@0: aoqi@0: AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) : aoqi@0: BufferBlob("I2C/C2I adapters", size, cb) { aoqi@0: CodeCache::commit(this); aoqi@0: } aoqi@0: aoqi@0: AdapterBlob* AdapterBlob::create(CodeBuffer* cb) { aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: aoqi@0: AdapterBlob* blob = NULL; aoqi@0: unsigned int size = allocation_size(cb, sizeof(AdapterBlob)); aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: // The parameter 'true' indicates a critical memory allocation. aoqi@0: // This means that CodeCacheMinimumFreeSpace is used, if necessary aoqi@0: const bool is_critical = true; aoqi@0: blob = new (size, is_critical) AdapterBlob(size, cb); aoqi@0: } aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of MethodHandlesAdapterBlob aoqi@0: aoqi@0: MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) { aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: aoqi@0: MethodHandlesAdapterBlob* blob = NULL; aoqi@0: unsigned int size = sizeof(MethodHandlesAdapterBlob); aoqi@0: // align the size to CodeEntryAlignment aoqi@0: size = align_code_offset(size); aoqi@0: size += round_to(buffer_size, oopSize); aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: // The parameter 'true' indicates a critical memory allocation. aoqi@0: // This means that CodeCacheMinimumFreeSpace is used, if necessary aoqi@0: const bool is_critical = true; aoqi@0: blob = new (size, is_critical) MethodHandlesAdapterBlob(size); aoqi@0: } aoqi@0: // Track memory usage statistic after releasing CodeCache_lock aoqi@0: MemoryService::track_code_cache_memory_usage(); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of RuntimeStub aoqi@0: aoqi@0: RuntimeStub::RuntimeStub( aoqi@0: const char* name, aoqi@0: CodeBuffer* cb, aoqi@0: int size, aoqi@0: int frame_complete, aoqi@0: int frame_size, aoqi@0: OopMapSet* oop_maps, aoqi@0: bool caller_must_gc_arguments aoqi@0: ) aoqi@0: : CodeBlob(name, cb, sizeof(RuntimeStub), size, frame_complete, frame_size, oop_maps) aoqi@0: { aoqi@0: _caller_must_gc_arguments = caller_must_gc_arguments; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name, aoqi@0: CodeBuffer* cb, aoqi@0: int frame_complete, aoqi@0: int frame_size, aoqi@0: OopMapSet* oop_maps, aoqi@0: bool caller_must_gc_arguments) aoqi@0: { aoqi@0: RuntimeStub* stub = NULL; aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: unsigned int size = allocation_size(cb, sizeof(RuntimeStub)); aoqi@0: stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments); aoqi@0: } aoqi@0: aoqi@0: trace_new_stub(stub, "RuntimeStub - ", stub_name); aoqi@0: aoqi@0: return stub; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: void* RuntimeStub::operator new(size_t s, unsigned size) throw() { aoqi@0: void* p = CodeCache::allocate(size, true); aoqi@0: if (!p) fatal("Initial size of CodeCache is too small"); aoqi@0: return p; aoqi@0: } aoqi@0: aoqi@0: // operator new shared by all singletons: aoqi@0: void* SingletonBlob::operator new(size_t s, unsigned size) throw() { aoqi@0: void* p = CodeCache::allocate(size, true); aoqi@0: if (!p) fatal("Initial size of CodeCache is too small"); aoqi@0: return p; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of DeoptimizationBlob aoqi@0: aoqi@0: DeoptimizationBlob::DeoptimizationBlob( aoqi@0: CodeBuffer* cb, aoqi@0: int size, aoqi@0: OopMapSet* oop_maps, aoqi@0: int unpack_offset, aoqi@0: int unpack_with_exception_offset, aoqi@0: int unpack_with_reexecution_offset, aoqi@0: int frame_size aoqi@0: ) aoqi@0: : SingletonBlob("DeoptimizationBlob", cb, sizeof(DeoptimizationBlob), size, frame_size, oop_maps) aoqi@0: { aoqi@0: _unpack_offset = unpack_offset; aoqi@0: _unpack_with_exception = unpack_with_exception_offset; aoqi@0: _unpack_with_reexecution = unpack_with_reexecution_offset; aoqi@0: #ifdef COMPILER1 aoqi@0: _unpack_with_exception_in_tls = -1; aoqi@0: #endif aoqi@0: } aoqi@0: aoqi@0: aoqi@0: DeoptimizationBlob* DeoptimizationBlob::create( aoqi@0: CodeBuffer* cb, aoqi@0: OopMapSet* oop_maps, aoqi@0: int unpack_offset, aoqi@0: int unpack_with_exception_offset, aoqi@0: int unpack_with_reexecution_offset, aoqi@0: int frame_size) aoqi@0: { aoqi@0: DeoptimizationBlob* blob = NULL; aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: unsigned int size = allocation_size(cb, sizeof(DeoptimizationBlob)); aoqi@0: blob = new (size) DeoptimizationBlob(cb, aoqi@0: size, aoqi@0: oop_maps, aoqi@0: unpack_offset, aoqi@0: unpack_with_exception_offset, aoqi@0: unpack_with_reexecution_offset, aoqi@0: frame_size); aoqi@0: } aoqi@0: aoqi@0: trace_new_stub(blob, "DeoptimizationBlob"); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of UncommonTrapBlob aoqi@0: aoqi@0: #ifdef COMPILER2 aoqi@0: UncommonTrapBlob::UncommonTrapBlob( aoqi@0: CodeBuffer* cb, aoqi@0: int size, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size aoqi@0: ) aoqi@0: : SingletonBlob("UncommonTrapBlob", cb, sizeof(UncommonTrapBlob), size, frame_size, oop_maps) aoqi@0: {} aoqi@0: aoqi@0: aoqi@0: UncommonTrapBlob* UncommonTrapBlob::create( aoqi@0: CodeBuffer* cb, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size) aoqi@0: { aoqi@0: UncommonTrapBlob* blob = NULL; aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: unsigned int size = allocation_size(cb, sizeof(UncommonTrapBlob)); aoqi@0: blob = new (size) UncommonTrapBlob(cb, size, oop_maps, frame_size); aoqi@0: } aoqi@0: aoqi@0: trace_new_stub(blob, "UncommonTrapBlob"); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: #endif // COMPILER2 aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of ExceptionBlob aoqi@0: aoqi@0: #ifdef COMPILER2 aoqi@0: ExceptionBlob::ExceptionBlob( aoqi@0: CodeBuffer* cb, aoqi@0: int size, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size aoqi@0: ) aoqi@0: : SingletonBlob("ExceptionBlob", cb, sizeof(ExceptionBlob), size, frame_size, oop_maps) aoqi@0: {} aoqi@0: aoqi@0: aoqi@0: ExceptionBlob* ExceptionBlob::create( aoqi@0: CodeBuffer* cb, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size) aoqi@0: { aoqi@0: ExceptionBlob* blob = NULL; aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: unsigned int size = allocation_size(cb, sizeof(ExceptionBlob)); aoqi@0: blob = new (size) ExceptionBlob(cb, size, oop_maps, frame_size); aoqi@0: } aoqi@0: aoqi@0: trace_new_stub(blob, "ExceptionBlob"); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: #endif // COMPILER2 aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Implementation of SafepointBlob aoqi@0: aoqi@0: SafepointBlob::SafepointBlob( aoqi@0: CodeBuffer* cb, aoqi@0: int size, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size aoqi@0: ) aoqi@0: : SingletonBlob("SafepointBlob", cb, sizeof(SafepointBlob), size, frame_size, oop_maps) aoqi@0: {} aoqi@0: aoqi@0: aoqi@0: SafepointBlob* SafepointBlob::create( aoqi@0: CodeBuffer* cb, aoqi@0: OopMapSet* oop_maps, aoqi@0: int frame_size) aoqi@0: { aoqi@0: SafepointBlob* blob = NULL; aoqi@0: ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock aoqi@0: { aoqi@0: MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); aoqi@0: unsigned int size = allocation_size(cb, sizeof(SafepointBlob)); aoqi@0: blob = new (size) SafepointBlob(cb, size, oop_maps, frame_size); aoqi@0: } aoqi@0: aoqi@0: trace_new_stub(blob, "SafepointBlob"); aoqi@0: aoqi@0: return blob; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: //---------------------------------------------------------------------------------------------------- aoqi@0: // Verification and printing aoqi@0: aoqi@0: void CodeBlob::verify() { aoqi@0: ShouldNotReachHere(); aoqi@0: } aoqi@0: aoqi@0: void CodeBlob::print_on(outputStream* st) const { aoqi@0: st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this)); aoqi@0: st->print_cr("Framesize: %d", _frame_size); aoqi@0: } aoqi@0: aoqi@0: void CodeBlob::print_value_on(outputStream* st) const { aoqi@0: st->print_cr("[CodeBlob]"); aoqi@0: } aoqi@0: aoqi@0: void BufferBlob::verify() { aoqi@0: // unimplemented aoqi@0: } aoqi@0: aoqi@0: void BufferBlob::print_on(outputStream* st) const { aoqi@0: CodeBlob::print_on(st); aoqi@0: print_value_on(st); aoqi@0: } aoqi@0: aoqi@0: void BufferBlob::print_value_on(outputStream* st) const { aoqi@0: st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name()); aoqi@0: } aoqi@0: aoqi@0: void RuntimeStub::verify() { aoqi@0: // unimplemented aoqi@0: } aoqi@0: aoqi@0: void RuntimeStub::print_on(outputStream* st) const { aoqi@0: ttyLocker ttyl; aoqi@0: CodeBlob::print_on(st); aoqi@0: st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this)); aoqi@0: st->print_cr("%s", name()); aoqi@0: Disassembler::decode((CodeBlob*)this, st); aoqi@0: } aoqi@0: aoqi@0: void RuntimeStub::print_value_on(outputStream* st) const { aoqi@0: st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name()); aoqi@0: } aoqi@0: aoqi@0: void SingletonBlob::verify() { aoqi@0: // unimplemented aoqi@0: } aoqi@0: aoqi@0: void SingletonBlob::print_on(outputStream* st) const { aoqi@0: ttyLocker ttyl; aoqi@0: CodeBlob::print_on(st); aoqi@0: st->print_cr("%s", name()); aoqi@0: Disassembler::decode((CodeBlob*)this, st); aoqi@0: } aoqi@0: aoqi@0: void SingletonBlob::print_value_on(outputStream* st) const { aoqi@0: st->print_cr("%s", name()); aoqi@0: } aoqi@0: aoqi@0: void DeoptimizationBlob::print_value_on(outputStream* st) const { aoqi@0: st->print_cr("Deoptimization (frame not available)"); aoqi@0: }