Path: blob/master/src/hotspot/share/code/codeBlob.cpp
64440 views
/*1* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm.h"26#include "code/codeBlob.hpp"27#include "code/codeCache.hpp"28#include "code/icBuffer.hpp"29#include "code/relocInfo.hpp"30#include "code/vtableStubs.hpp"31#include "compiler/disassembler.hpp"32#include "compiler/oopMap.hpp"33#include "interpreter/bytecode.hpp"34#include "interpreter/interpreter.hpp"35#include "memory/allocation.inline.hpp"36#include "memory/heap.hpp"37#include "memory/resourceArea.hpp"38#include "oops/oop.inline.hpp"39#include "prims/forte.hpp"40#include "prims/jvmtiExport.hpp"41#include "runtime/handles.inline.hpp"42#include "runtime/interfaceSupport.inline.hpp"43#include "runtime/javaFrameAnchor.hpp"44#include "runtime/jniHandles.hpp"45#include "runtime/mutexLocker.hpp"46#include "runtime/safepoint.hpp"47#include "runtime/sharedRuntime.hpp"48#include "runtime/stubCodeGenerator.hpp"49#include "runtime/stubRoutines.hpp"50#include "runtime/vframe.hpp"51#include "services/memoryService.hpp"52#include "utilities/align.hpp"53#ifdef COMPILER154#include "c1/c1_Runtime1.hpp"55#endif5657const char* CodeBlob::compiler_name() const {58return compilertype2name(_type);59}6061unsigned int CodeBlob::align_code_offset(int offset) {62// align the size to CodeEntryAlignment63int header_size = (int)CodeHeap::header_size();64return align_up(offset + header_size, CodeEntryAlignment) - header_size;65}666768// This must be consistent with the CodeBlob constructor's layout actions.69unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) {70unsigned int size = header_size;71size += align_up(cb->total_relocation_size(), oopSize);72// align the size to CodeEntryAlignment73size = align_code_offset(size);74size += align_up(cb->total_content_size(), oopSize);75size += align_up(cb->total_oop_size(), oopSize);76size += align_up(cb->total_metadata_size(), oopSize);77return size;78}7980CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments) :81_type(type),82_size(layout.size()),83_header_size(layout.header_size()),84_frame_complete_offset(frame_complete_offset),85_data_offset(layout.data_offset()),86_frame_size(frame_size),87_code_begin(layout.code_begin()),88_code_end(layout.code_end()),89_content_begin(layout.content_begin()),90_data_end(layout.data_end()),91_relocation_begin(layout.relocation_begin()),92_relocation_end(layout.relocation_end()),93_oop_maps(oop_maps),94_caller_must_gc_arguments(caller_must_gc_arguments),95_name(name)96NOT_PRODUCT(COMMA _strings(CodeStrings()))97{98assert(is_aligned(layout.size(), oopSize), "unaligned size");99assert(is_aligned(layout.header_size(), oopSize), "unaligned size");100assert(is_aligned(layout.relocation_size(), oopSize), "unaligned size");101assert(layout.code_end() == layout.content_end(), "must be the same - see code_end()");102#ifdef COMPILER1103// probably wrong for tiered104assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");105#endif // COMPILER1106S390_ONLY(_ctable_offset = 0;) // avoid uninitialized fields107}108109CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) :110_type(type),111_size(layout.size()),112_header_size(layout.header_size()),113_frame_complete_offset(frame_complete_offset),114_data_offset(layout.data_offset()),115_frame_size(frame_size),116_code_begin(layout.code_begin()),117_code_end(layout.code_end()),118_content_begin(layout.content_begin()),119_data_end(layout.data_end()),120_relocation_begin(layout.relocation_begin()),121_relocation_end(layout.relocation_end()),122_caller_must_gc_arguments(caller_must_gc_arguments),123_name(name)124NOT_PRODUCT(COMMA _strings(CodeStrings()))125{126assert(is_aligned(_size, oopSize), "unaligned size");127assert(is_aligned(_header_size, oopSize), "unaligned size");128assert(_data_offset <= _size, "codeBlob is too small");129assert(layout.code_end() == layout.content_end(), "must be the same - see code_end()");130131set_oop_maps(oop_maps);132#ifdef COMPILER1133// probably wrong for tiered134assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");135#endif // COMPILER1136S390_ONLY(_ctable_offset = 0;) // avoid uninitialized fields137}138139140// Creates a simple CodeBlob. Sets up the size of the different regions.141RuntimeBlob::RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size)142: CodeBlob(name, compiler_none, CodeBlobLayout((address) this, size, header_size, locs_size, size), frame_complete, 0, NULL, false /* caller_must_gc_arguments */)143{144assert(is_aligned(locs_size, oopSize), "unaligned size");145}146147148// Creates a RuntimeBlob from a CodeBuffer149// and copy code and relocation info.150RuntimeBlob::RuntimeBlob(151const char* name,152CodeBuffer* cb,153int header_size,154int size,155int frame_complete,156int frame_size,157OopMapSet* oop_maps,158bool caller_must_gc_arguments159) : CodeBlob(name, compiler_none, CodeBlobLayout((address) this, size, header_size, cb), cb, frame_complete, frame_size, oop_maps, caller_must_gc_arguments) {160cb->copy_code_and_locs_to(this);161}162163void CodeBlob::flush() {164FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);165_oop_maps = NULL;166NOT_PRODUCT(_strings.free();)167}168169void CodeBlob::set_oop_maps(OopMapSet* p) {170// Danger Will Robinson! This method allocates a big171// chunk of memory, its your job to free it.172if (p != NULL) {173_oop_maps = ImmutableOopMapSet::build_from(p);174} else {175_oop_maps = NULL;176}177}178179180void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const char* name2) {181// Do not hold the CodeCache lock during name formatting.182assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub");183184if (stub != NULL) {185char stub_id[256];186assert(strlen(name1) + strlen(name2) < sizeof(stub_id), "");187jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2);188if (PrintStubCode) {189ttyLocker ttyl;190tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");191tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);192Disassembler::decode(stub->code_begin(), stub->code_end(), tty);193if ((stub->oop_maps() != NULL) && AbstractDisassembler::show_structs()) {194tty->print_cr("- - - [OOP MAPS]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");195stub->oop_maps()->print();196}197tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");198tty->cr();199}200Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());201202if (JvmtiExport::should_post_dynamic_code_generated()) {203const char* stub_name = name2;204if (name2[0] == '\0') stub_name = name1;205JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end());206}207}208209// Track memory usage statistic after releasing CodeCache_lock210MemoryService::track_code_cache_memory_usage();211}212213const ImmutableOopMap* CodeBlob::oop_map_for_return_address(address return_address) {214assert(_oop_maps != NULL, "nope");215return _oop_maps->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());216}217218void CodeBlob::print_code() {219ResourceMark m;220Disassembler::decode(this, tty);221}222223//----------------------------------------------------------------------------------------------------224// Implementation of BufferBlob225226227BufferBlob::BufferBlob(const char* name, int size)228: RuntimeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0)229{}230231BufferBlob* BufferBlob::create(const char* name, int buffer_size) {232ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock233234BufferBlob* blob = NULL;235unsigned int size = sizeof(BufferBlob);236// align the size to CodeEntryAlignment237size = CodeBlob::align_code_offset(size);238size += align_up(buffer_size, oopSize);239assert(name != NULL, "must provide a name");240{241MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);242blob = new (size) BufferBlob(name, size);243}244// Track memory usage statistic after releasing CodeCache_lock245MemoryService::track_code_cache_memory_usage();246247return blob;248}249250251BufferBlob::BufferBlob(const char* name, int size, CodeBuffer* cb)252: RuntimeBlob(name, cb, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, 0, NULL)253{}254255BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {256ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock257258BufferBlob* blob = NULL;259unsigned int size = CodeBlob::allocation_size(cb, sizeof(BufferBlob));260assert(name != NULL, "must provide a name");261{262MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);263blob = new (size) BufferBlob(name, size, cb);264}265// Track memory usage statistic after releasing CodeCache_lock266MemoryService::track_code_cache_memory_usage();267268return blob;269}270271void* BufferBlob::operator new(size_t s, unsigned size) throw() {272return CodeCache::allocate(size, CodeBlobType::NonNMethod);273}274275void BufferBlob::free(BufferBlob *blob) {276assert(blob != NULL, "caller must check for NULL");277ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock278blob->flush();279{280MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);281CodeCache::free((RuntimeBlob*)blob);282}283// Track memory usage statistic after releasing CodeCache_lock284MemoryService::track_code_cache_memory_usage();285}286287288//----------------------------------------------------------------------------------------------------289// Implementation of AdapterBlob290291AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) :292BufferBlob("I2C/C2I adapters", size, cb) {293CodeCache::commit(this);294}295296AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {297ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock298299AdapterBlob* blob = NULL;300unsigned int size = CodeBlob::allocation_size(cb, sizeof(AdapterBlob));301{302MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);303blob = new (size) AdapterBlob(size, cb);304}305// Track memory usage statistic after releasing CodeCache_lock306MemoryService::track_code_cache_memory_usage();307308return blob;309}310311void* VtableBlob::operator new(size_t s, unsigned size) throw() {312// Handling of allocation failure stops compilation and prints a bunch of313// stuff, which requires unlocking the CodeCache_lock, so that the Compile_lock314// can be locked, and then re-locking the CodeCache_lock. That is not safe in315// this context as we hold the CompiledICLocker. So we just don't handle code316// cache exhaustion here; we leave that for a later allocation that does not317// hold the CompiledICLocker.318return CodeCache::allocate(size, CodeBlobType::NonNMethod, false /* handle_alloc_failure */);319}320321VtableBlob::VtableBlob(const char* name, int size) :322BufferBlob(name, size) {323}324325VtableBlob* VtableBlob::create(const char* name, int buffer_size) {326assert(JavaThread::current()->thread_state() == _thread_in_vm, "called with the wrong state");327328VtableBlob* blob = NULL;329unsigned int size = sizeof(VtableBlob);330// align the size to CodeEntryAlignment331size = align_code_offset(size);332size += align_up(buffer_size, oopSize);333assert(name != NULL, "must provide a name");334{335if (!CodeCache_lock->try_lock()) {336// If we can't take the CodeCache_lock, then this is a bad time to perform the ongoing337// IC transition to megamorphic, for which this stub will be needed. It is better to338// bail out the transition, and wait for a more opportune moment. Not only is it not339// worth waiting for the lock blockingly for the megamorphic transition, it might340// also result in a deadlock to blockingly wait, when concurrent class unloading is341// performed. At this point in time, the CompiledICLocker is taken, so we are not342// allowed to blockingly wait for the CodeCache_lock, as these two locks are otherwise343// consistently taken in the opposite order. Bailing out results in an IC transition to344// the clean state instead, which will cause subsequent calls to retry the transitioning345// eventually.346return NULL;347}348blob = new (size) VtableBlob(name, size);349CodeCache_lock->unlock();350}351// Track memory usage statistic after releasing CodeCache_lock352MemoryService::track_code_cache_memory_usage();353354return blob;355}356357//----------------------------------------------------------------------------------------------------358// Implementation of MethodHandlesAdapterBlob359360MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {361ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock362363MethodHandlesAdapterBlob* blob = NULL;364unsigned int size = sizeof(MethodHandlesAdapterBlob);365// align the size to CodeEntryAlignment366size = CodeBlob::align_code_offset(size);367size += align_up(buffer_size, oopSize);368{369MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);370blob = new (size) MethodHandlesAdapterBlob(size);371if (blob == NULL) {372vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "CodeCache: no room for method handle adapter blob");373}374}375// Track memory usage statistic after releasing CodeCache_lock376MemoryService::track_code_cache_memory_usage();377378return blob;379}380381//----------------------------------------------------------------------------------------------------382// Implementation of RuntimeStub383384RuntimeStub::RuntimeStub(385const char* name,386CodeBuffer* cb,387int size,388int frame_complete,389int frame_size,390OopMapSet* oop_maps,391bool caller_must_gc_arguments392)393: RuntimeBlob(name, cb, sizeof(RuntimeStub), size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments)394{395}396397RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,398CodeBuffer* cb,399int frame_complete,400int frame_size,401OopMapSet* oop_maps,402bool caller_must_gc_arguments)403{404RuntimeStub* stub = NULL;405ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock406{407MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);408unsigned int size = CodeBlob::allocation_size(cb, sizeof(RuntimeStub));409stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);410}411412trace_new_stub(stub, "RuntimeStub - ", stub_name);413414return stub;415}416417418void* RuntimeStub::operator new(size_t s, unsigned size) throw() {419void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod);420if (!p) fatal("Initial size of CodeCache is too small");421return p;422}423424// operator new shared by all singletons:425void* SingletonBlob::operator new(size_t s, unsigned size) throw() {426void* p = CodeCache::allocate(size, CodeBlobType::NonNMethod);427if (!p) fatal("Initial size of CodeCache is too small");428return p;429}430431432//----------------------------------------------------------------------------------------------------433// Implementation of DeoptimizationBlob434435DeoptimizationBlob::DeoptimizationBlob(436CodeBuffer* cb,437int size,438OopMapSet* oop_maps,439int unpack_offset,440int unpack_with_exception_offset,441int unpack_with_reexecution_offset,442int frame_size443)444: SingletonBlob("DeoptimizationBlob", cb, sizeof(DeoptimizationBlob), size, frame_size, oop_maps)445{446_unpack_offset = unpack_offset;447_unpack_with_exception = unpack_with_exception_offset;448_unpack_with_reexecution = unpack_with_reexecution_offset;449#ifdef COMPILER1450_unpack_with_exception_in_tls = -1;451#endif452}453454455DeoptimizationBlob* DeoptimizationBlob::create(456CodeBuffer* cb,457OopMapSet* oop_maps,458int unpack_offset,459int unpack_with_exception_offset,460int unpack_with_reexecution_offset,461int frame_size)462{463DeoptimizationBlob* blob = NULL;464ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock465{466MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);467unsigned int size = CodeBlob::allocation_size(cb, sizeof(DeoptimizationBlob));468blob = new (size) DeoptimizationBlob(cb,469size,470oop_maps,471unpack_offset,472unpack_with_exception_offset,473unpack_with_reexecution_offset,474frame_size);475}476477trace_new_stub(blob, "DeoptimizationBlob");478479return blob;480}481482483//----------------------------------------------------------------------------------------------------484// Implementation of UncommonTrapBlob485486#ifdef COMPILER2487UncommonTrapBlob::UncommonTrapBlob(488CodeBuffer* cb,489int size,490OopMapSet* oop_maps,491int frame_size492)493: SingletonBlob("UncommonTrapBlob", cb, sizeof(UncommonTrapBlob), size, frame_size, oop_maps)494{}495496497UncommonTrapBlob* UncommonTrapBlob::create(498CodeBuffer* cb,499OopMapSet* oop_maps,500int frame_size)501{502UncommonTrapBlob* blob = NULL;503ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock504{505MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);506unsigned int size = CodeBlob::allocation_size(cb, sizeof(UncommonTrapBlob));507blob = new (size) UncommonTrapBlob(cb, size, oop_maps, frame_size);508}509510trace_new_stub(blob, "UncommonTrapBlob");511512return blob;513}514515516#endif // COMPILER2517518519//----------------------------------------------------------------------------------------------------520// Implementation of ExceptionBlob521522#ifdef COMPILER2523ExceptionBlob::ExceptionBlob(524CodeBuffer* cb,525int size,526OopMapSet* oop_maps,527int frame_size528)529: SingletonBlob("ExceptionBlob", cb, sizeof(ExceptionBlob), size, frame_size, oop_maps)530{}531532533ExceptionBlob* ExceptionBlob::create(534CodeBuffer* cb,535OopMapSet* oop_maps,536int frame_size)537{538ExceptionBlob* blob = NULL;539ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock540{541MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);542unsigned int size = CodeBlob::allocation_size(cb, sizeof(ExceptionBlob));543blob = new (size) ExceptionBlob(cb, size, oop_maps, frame_size);544}545546trace_new_stub(blob, "ExceptionBlob");547548return blob;549}550551552#endif // COMPILER2553554555//----------------------------------------------------------------------------------------------------556// Implementation of SafepointBlob557558SafepointBlob::SafepointBlob(559CodeBuffer* cb,560int size,561OopMapSet* oop_maps,562int frame_size563)564: SingletonBlob("SafepointBlob", cb, sizeof(SafepointBlob), size, frame_size, oop_maps)565{}566567568SafepointBlob* SafepointBlob::create(569CodeBuffer* cb,570OopMapSet* oop_maps,571int frame_size)572{573SafepointBlob* blob = NULL;574ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock575{576MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);577unsigned int size = CodeBlob::allocation_size(cb, sizeof(SafepointBlob));578blob = new (size) SafepointBlob(cb, size, oop_maps, frame_size);579}580581trace_new_stub(blob, "SafepointBlob");582583return blob;584}585586587//----------------------------------------------------------------------------------------------------588// Verification and printing589590void CodeBlob::print_on(outputStream* st) const {591st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));592st->print_cr("Framesize: %d", _frame_size);593}594595void CodeBlob::print() const { print_on(tty); }596597void CodeBlob::print_value_on(outputStream* st) const {598st->print_cr("[CodeBlob]");599}600601void CodeBlob::dump_for_addr(address addr, outputStream* st, bool verbose) const {602if (is_buffer_blob()) {603// the interpreter is generated into a buffer blob604InterpreterCodelet* i = Interpreter::codelet_containing(addr);605if (i != NULL) {606st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an Interpreter codelet", p2i(addr), (int)(addr - i->code_begin()));607i->print_on(st);608return;609}610if (Interpreter::contains(addr)) {611st->print_cr(INTPTR_FORMAT " is pointing into interpreter code"612" (not bytecode specific)", p2i(addr));613return;614}615//616if (AdapterHandlerLibrary::contains(this)) {617st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an AdapterHandler", p2i(addr), (int)(addr - code_begin()));618AdapterHandlerLibrary::print_handler_on(st, this);619}620// the stubroutines are generated into a buffer blob621StubCodeDesc* d = StubCodeDesc::desc_for(addr);622if (d != NULL) {623st->print_cr(INTPTR_FORMAT " is at begin+%d in a stub", p2i(addr), (int)(addr - d->begin()));624d->print_on(st);625st->cr();626return;627}628if (StubRoutines::contains(addr)) {629st->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", p2i(addr));630return;631}632// the InlineCacheBuffer is using stubs generated into a buffer blob633if (InlineCacheBuffer::contains(addr)) {634st->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", p2i(addr));635return;636}637VtableStub* v = VtableStubs::stub_containing(addr);638if (v != NULL) {639st->print_cr(INTPTR_FORMAT " is at entry_point+%d in a vtable stub", p2i(addr), (int)(addr - v->entry_point()));640v->print_on(st);641st->cr();642return;643}644}645if (is_nmethod()) {646nmethod* nm = (nmethod*)this;647ResourceMark rm;648st->print(INTPTR_FORMAT " is at entry_point+%d in (nmethod*)" INTPTR_FORMAT,649p2i(addr), (int)(addr - nm->entry_point()), p2i(nm));650if (verbose) {651st->print(" for ");652nm->method()->print_value_on(st);653}654st->cr();655nm->print_nmethod(verbose);656return;657}658st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", p2i(addr), (int)(addr - code_begin()));659print_on(st);660}661662void RuntimeBlob::verify() {663ShouldNotReachHere();664}665666void BufferBlob::verify() {667// unimplemented668}669670void BufferBlob::print_on(outputStream* st) const {671RuntimeBlob::print_on(st);672print_value_on(st);673}674675void BufferBlob::print_value_on(outputStream* st) const {676st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name());677}678679void RuntimeStub::verify() {680// unimplemented681}682683void RuntimeStub::print_on(outputStream* st) const {684ttyLocker ttyl;685RuntimeBlob::print_on(st);686st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this));687st->print_cr("%s", name());688Disassembler::decode((RuntimeBlob*)this, st);689}690691void RuntimeStub::print_value_on(outputStream* st) const {692st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name());693}694695void SingletonBlob::verify() {696// unimplemented697}698699void SingletonBlob::print_on(outputStream* st) const {700ttyLocker ttyl;701RuntimeBlob::print_on(st);702st->print_cr("%s", name());703Disassembler::decode((RuntimeBlob*)this, st);704}705706void SingletonBlob::print_value_on(outputStream* st) const {707st->print_cr("%s", name());708}709710void DeoptimizationBlob::print_value_on(outputStream* st) const {711st->print_cr("Deoptimization (frame not available)");712}713714// Implementation of OptimizedEntryBlob715716OptimizedEntryBlob::OptimizedEntryBlob(const char* name, int size, CodeBuffer* cb, intptr_t exception_handler_offset,717jobject receiver, ByteSize frame_data_offset) :718BufferBlob(name, size, cb),719_exception_handler_offset(exception_handler_offset),720_receiver(receiver),721_frame_data_offset(frame_data_offset) {722CodeCache::commit(this);723}724725OptimizedEntryBlob* OptimizedEntryBlob::create(const char* name, CodeBuffer* cb, intptr_t exception_handler_offset,726jobject receiver, ByteSize frame_data_offset) {727ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock728729OptimizedEntryBlob* blob = nullptr;730unsigned int size = CodeBlob::allocation_size(cb, sizeof(OptimizedEntryBlob));731{732MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);733blob = new (size) OptimizedEntryBlob(name, size, cb, exception_handler_offset, receiver, frame_data_offset);734}735// Track memory usage statistic after releasing CodeCache_lock736MemoryService::track_code_cache_memory_usage();737738return blob;739}740741void OptimizedEntryBlob::oops_do(OopClosure* f, const frame& frame) {742frame_data_for_frame(frame)->old_handles->oops_do(f);743}744745JavaFrameAnchor* OptimizedEntryBlob::jfa_for_frame(const frame& frame) const {746return &frame_data_for_frame(frame)->jfa;747}748749750