Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/code/codeBlob.cpp
32285 views
/*1* Copyright (c) 1998, 2018, 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 "code/codeBlob.hpp"26#include "code/codeCache.hpp"27#include "code/relocInfo.hpp"28#include "compiler/disassembler.hpp"29#include "interpreter/bytecode.hpp"30#include "memory/allocation.inline.hpp"31#include "memory/heap.hpp"32#include "oops/oop.inline.hpp"33#include "prims/forte.hpp"34#include "runtime/handles.inline.hpp"35#include "runtime/interfaceSupport.hpp"36#include "runtime/mutexLocker.hpp"37#include "runtime/safepoint.hpp"38#include "runtime/sharedRuntime.hpp"39#include "runtime/vframe.hpp"40#include "services/memoryService.hpp"41#ifdef TARGET_ARCH_x8642# include "nativeInst_x86.hpp"43#endif44#ifdef TARGET_ARCH_aarch3245# include "nativeInst_aarch32.hpp"46#endif47#ifdef TARGET_ARCH_aarch6448# include "nativeInst_aarch64.hpp"49#endif50#ifdef TARGET_ARCH_sparc51# include "nativeInst_sparc.hpp"52#endif53#ifdef TARGET_ARCH_zero54# include "nativeInst_zero.hpp"55#endif56#ifdef TARGET_ARCH_arm57# include "nativeInst_arm.hpp"58#endif59#ifdef TARGET_ARCH_ppc60# include "nativeInst_ppc.hpp"61#endif62#ifdef COMPILER163#include "c1/c1_Runtime1.hpp"64#endif6566unsigned int CodeBlob::align_code_offset(int offset) {67// align the size to CodeEntryAlignment68return69((offset + (int)CodeHeap::header_size() + (CodeEntryAlignment-1)) & ~(CodeEntryAlignment-1))70- (int)CodeHeap::header_size();71}727374// This must be consistent with the CodeBlob constructor's layout actions.75unsigned int CodeBlob::allocation_size(CodeBuffer* cb, int header_size) {76unsigned int size = header_size;77size += round_to(cb->total_relocation_size(), oopSize);78// align the size to CodeEntryAlignment79size = align_code_offset(size);80size += round_to(cb->total_content_size(), oopSize);81size += round_to(cb->total_oop_size(), oopSize);82size += round_to(cb->total_metadata_size(), oopSize);83return size;84}858687// Creates a simple CodeBlob. Sets up the size of the different regions.88CodeBlob::CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size) {89assert(size == round_to(size, oopSize), "unaligned size");90assert(locs_size == round_to(locs_size, oopSize), "unaligned size");91assert(header_size == round_to(header_size, oopSize), "unaligned size");92assert(!UseRelocIndex, "no space allocated for reloc index yet");9394// Note: If UseRelocIndex is enabled, there needs to be (at least) one95// extra word for the relocation information, containing the reloc96// index table length. Unfortunately, the reloc index table imple-97// mentation is not easily understandable and thus it is not clear98// what exactly the format is supposed to be. For now, we just turn99// off the use of this table (gri 7/6/2000).100101_name = name;102_size = size;103_frame_complete_offset = frame_complete;104_header_size = header_size;105_relocation_size = locs_size;106_content_offset = align_code_offset(header_size + _relocation_size);107_code_offset = _content_offset;108_data_offset = size;109_frame_size = 0;110set_oop_maps(NULL);111}112113114// Creates a CodeBlob from a CodeBuffer. Sets up the size of the different regions,115// and copy code and relocation info.116CodeBlob::CodeBlob(117const char* name,118CodeBuffer* cb,119int header_size,120int size,121int frame_complete,122int frame_size,123OopMapSet* oop_maps124) {125assert(size == round_to(size, oopSize), "unaligned size");126assert(header_size == round_to(header_size, oopSize), "unaligned size");127128_name = name;129_size = size;130_frame_complete_offset = frame_complete;131_header_size = header_size;132_relocation_size = round_to(cb->total_relocation_size(), oopSize);133_content_offset = align_code_offset(header_size + _relocation_size);134_code_offset = _content_offset + cb->total_offset_of(cb->insts());135_data_offset = _content_offset + round_to(cb->total_content_size(), oopSize);136assert(_data_offset <= size, "codeBlob is too small");137138cb->copy_code_and_locs_to(this);139set_oop_maps(oop_maps);140_frame_size = frame_size;141#ifdef COMPILER1142// probably wrong for tiered143assert(_frame_size >= -1, "must use frame size or -1 for runtime stubs");144#endif // COMPILER1145}146147148void CodeBlob::set_oop_maps(OopMapSet* p) {149// Danger Will Robinson! This method allocates a big150// chunk of memory, its your job to free it.151if (p != NULL) {152// We need to allocate a chunk big enough to hold the OopMapSet and all of its OopMaps153_oop_maps = (OopMapSet* )NEW_C_HEAP_ARRAY(unsigned char, p->heap_size(), mtCode);154p->copy_to((address)_oop_maps);155} else {156_oop_maps = NULL;157}158}159160161void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* name2) {162// Do not hold the CodeCache lock during name formatting.163assert(!CodeCache_lock->owned_by_self(), "release CodeCache before registering the stub");164165if (stub != NULL) {166char stub_id[256];167assert(strlen(name1) + strlen(name2) < sizeof(stub_id), "");168jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2);169if (PrintStubCode) {170ttyLocker ttyl;171tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);172Disassembler::decode(stub->code_begin(), stub->code_end());173tty->cr();174}175Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());176177if (JvmtiExport::should_post_dynamic_code_generated()) {178const char* stub_name = name2;179if (name2[0] == '\0') stub_name = name1;180JvmtiExport::post_dynamic_code_generated(stub_name, stub->code_begin(), stub->code_end());181}182}183184// Track memory usage statistic after releasing CodeCache_lock185MemoryService::track_code_cache_memory_usage();186}187188189void CodeBlob::flush() {190if (_oop_maps) {191FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);192_oop_maps = NULL;193}194_strings.free();195}196197198OopMap* CodeBlob::oop_map_for_return_address(address return_address) {199assert(oop_maps() != NULL, "nope");200return oop_maps()->find_map_at_offset((intptr_t) return_address - (intptr_t) code_begin());201}202203void CodeBlob::print_code() {204HandleMark hm;205ResourceMark m;206Disassembler::decode(this, tty);207}208209//----------------------------------------------------------------------------------------------------210// Implementation of BufferBlob211212213BufferBlob::BufferBlob(const char* name, int size)214: CodeBlob(name, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, /*locs_size:*/ 0)215{}216217BufferBlob* BufferBlob::create(const char* name, int buffer_size) {218ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock219220BufferBlob* blob = NULL;221unsigned int size = sizeof(BufferBlob);222// align the size to CodeEntryAlignment223size = align_code_offset(size);224size += round_to(buffer_size, oopSize);225assert(name != NULL, "must provide a name");226{227MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);228blob = new (size) BufferBlob(name, size);229}230// Track memory usage statistic after releasing CodeCache_lock231MemoryService::track_code_cache_memory_usage();232233return blob;234}235236237BufferBlob::BufferBlob(const char* name, int size, CodeBuffer* cb)238: CodeBlob(name, cb, sizeof(BufferBlob), size, CodeOffsets::frame_never_safe, 0, NULL)239{}240241BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {242ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock243244BufferBlob* blob = NULL;245unsigned int size = allocation_size(cb, sizeof(BufferBlob));246assert(name != NULL, "must provide a name");247{248MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);249blob = new (size) BufferBlob(name, size, cb);250}251// Track memory usage statistic after releasing CodeCache_lock252MemoryService::track_code_cache_memory_usage();253254return blob;255}256257258void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() {259void* p = CodeCache::allocate(size, is_critical);260return p;261}262263264void BufferBlob::free( BufferBlob *blob ) {265ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock266blob->flush();267{268MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);269CodeCache::free((CodeBlob*)blob);270}271// Track memory usage statistic after releasing CodeCache_lock272MemoryService::track_code_cache_memory_usage();273}274275276//----------------------------------------------------------------------------------------------------277// Implementation of AdapterBlob278279AdapterBlob::AdapterBlob(int size, CodeBuffer* cb) :280BufferBlob("I2C/C2I adapters", size, cb) {281CodeCache::commit(this);282}283284AdapterBlob* AdapterBlob::create(CodeBuffer* cb) {285ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock286287AdapterBlob* blob = NULL;288unsigned int size = allocation_size(cb, sizeof(AdapterBlob));289{290MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);291// The parameter 'true' indicates a critical memory allocation.292// This means that CodeCacheMinimumFreeSpace is used, if necessary293const bool is_critical = true;294blob = new (size, is_critical) AdapterBlob(size, cb);295}296// Track memory usage statistic after releasing CodeCache_lock297MemoryService::track_code_cache_memory_usage();298299return blob;300}301302VtableBlob::VtableBlob(const char* name, int size) :303BufferBlob(name, size) {304}305306VtableBlob* VtableBlob::create(const char* name, int buffer_size) {307ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock308309VtableBlob* blob = NULL;310unsigned int size = sizeof(VtableBlob);311// align the size to CodeEntryAlignment312size = align_code_offset(size);313size += round_to(buffer_size, oopSize);314assert(name != NULL, "must provide a name");315{316MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);317blob = new (size) VtableBlob(name, size);318}319// Track memory usage statistic after releasing CodeCache_lock320MemoryService::track_code_cache_memory_usage();321322return blob;323}324325//----------------------------------------------------------------------------------------------------326// Implementation of MethodHandlesAdapterBlob327328MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {329ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock330331MethodHandlesAdapterBlob* blob = NULL;332unsigned int size = sizeof(MethodHandlesAdapterBlob);333// align the size to CodeEntryAlignment334size = align_code_offset(size);335size += round_to(buffer_size, oopSize);336{337MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);338// The parameter 'true' indicates a critical memory allocation.339// This means that CodeCacheMinimumFreeSpace is used, if necessary340const bool is_critical = true;341blob = new (size, is_critical) MethodHandlesAdapterBlob(size);342}343// Track memory usage statistic after releasing CodeCache_lock344MemoryService::track_code_cache_memory_usage();345346return blob;347}348349350//----------------------------------------------------------------------------------------------------351// Implementation of RuntimeStub352353RuntimeStub::RuntimeStub(354const char* name,355CodeBuffer* cb,356int size,357int frame_complete,358int frame_size,359OopMapSet* oop_maps,360bool caller_must_gc_arguments361)362: CodeBlob(name, cb, sizeof(RuntimeStub), size, frame_complete, frame_size, oop_maps)363{364_caller_must_gc_arguments = caller_must_gc_arguments;365}366367368RuntimeStub* RuntimeStub::new_runtime_stub(const char* stub_name,369CodeBuffer* cb,370int frame_complete,371int frame_size,372OopMapSet* oop_maps,373bool caller_must_gc_arguments)374{375RuntimeStub* stub = NULL;376ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock377{378MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);379unsigned int size = allocation_size(cb, sizeof(RuntimeStub));380stub = new (size) RuntimeStub(stub_name, cb, size, frame_complete, frame_size, oop_maps, caller_must_gc_arguments);381}382383trace_new_stub(stub, "RuntimeStub - ", stub_name);384385return stub;386}387388389void* RuntimeStub::operator new(size_t s, unsigned size) throw() {390void* p = CodeCache::allocate(size, true);391if (!p) fatal("Initial size of CodeCache is too small");392return p;393}394395// operator new shared by all singletons:396void* SingletonBlob::operator new(size_t s, unsigned size) throw() {397void* p = CodeCache::allocate(size, true);398if (!p) fatal("Initial size of CodeCache is too small");399return p;400}401402403//----------------------------------------------------------------------------------------------------404// Implementation of DeoptimizationBlob405406DeoptimizationBlob::DeoptimizationBlob(407CodeBuffer* cb,408int size,409OopMapSet* oop_maps,410int unpack_offset,411int unpack_with_exception_offset,412int unpack_with_reexecution_offset,413int frame_size414)415: SingletonBlob("DeoptimizationBlob", cb, sizeof(DeoptimizationBlob), size, frame_size, oop_maps)416{417_unpack_offset = unpack_offset;418_unpack_with_exception = unpack_with_exception_offset;419_unpack_with_reexecution = unpack_with_reexecution_offset;420#ifdef COMPILER1421_unpack_with_exception_in_tls = -1;422#endif423}424425426DeoptimizationBlob* DeoptimizationBlob::create(427CodeBuffer* cb,428OopMapSet* oop_maps,429int unpack_offset,430int unpack_with_exception_offset,431int unpack_with_reexecution_offset,432int frame_size)433{434DeoptimizationBlob* blob = NULL;435ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock436{437MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);438unsigned int size = allocation_size(cb, sizeof(DeoptimizationBlob));439blob = new (size) DeoptimizationBlob(cb,440size,441oop_maps,442unpack_offset,443unpack_with_exception_offset,444unpack_with_reexecution_offset,445frame_size);446}447448trace_new_stub(blob, "DeoptimizationBlob");449450return blob;451}452453454//----------------------------------------------------------------------------------------------------455// Implementation of UncommonTrapBlob456457#ifdef COMPILER2458UncommonTrapBlob::UncommonTrapBlob(459CodeBuffer* cb,460int size,461OopMapSet* oop_maps,462int frame_size463)464: SingletonBlob("UncommonTrapBlob", cb, sizeof(UncommonTrapBlob), size, frame_size, oop_maps)465{}466467468UncommonTrapBlob* UncommonTrapBlob::create(469CodeBuffer* cb,470OopMapSet* oop_maps,471int frame_size)472{473UncommonTrapBlob* blob = NULL;474ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock475{476MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);477unsigned int size = allocation_size(cb, sizeof(UncommonTrapBlob));478blob = new (size) UncommonTrapBlob(cb, size, oop_maps, frame_size);479}480481trace_new_stub(blob, "UncommonTrapBlob");482483return blob;484}485486487#endif // COMPILER2488489490//----------------------------------------------------------------------------------------------------491// Implementation of ExceptionBlob492493#ifdef COMPILER2494ExceptionBlob::ExceptionBlob(495CodeBuffer* cb,496int size,497OopMapSet* oop_maps,498int frame_size499)500: SingletonBlob("ExceptionBlob", cb, sizeof(ExceptionBlob), size, frame_size, oop_maps)501{}502503504ExceptionBlob* ExceptionBlob::create(505CodeBuffer* cb,506OopMapSet* oop_maps,507int frame_size)508{509ExceptionBlob* blob = NULL;510ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock511{512MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);513unsigned int size = allocation_size(cb, sizeof(ExceptionBlob));514blob = new (size) ExceptionBlob(cb, size, oop_maps, frame_size);515}516517trace_new_stub(blob, "ExceptionBlob");518519return blob;520}521522523#endif // COMPILER2524525526//----------------------------------------------------------------------------------------------------527// Implementation of SafepointBlob528529SafepointBlob::SafepointBlob(530CodeBuffer* cb,531int size,532OopMapSet* oop_maps,533int frame_size534)535: SingletonBlob("SafepointBlob", cb, sizeof(SafepointBlob), size, frame_size, oop_maps)536{}537538539SafepointBlob* SafepointBlob::create(540CodeBuffer* cb,541OopMapSet* oop_maps,542int frame_size)543{544SafepointBlob* blob = NULL;545ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock546{547MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);548unsigned int size = allocation_size(cb, sizeof(SafepointBlob));549blob = new (size) SafepointBlob(cb, size, oop_maps, frame_size);550}551552trace_new_stub(blob, "SafepointBlob");553554return blob;555}556557558//----------------------------------------------------------------------------------------------------559// Verification and printing560561void CodeBlob::verify() {562ShouldNotReachHere();563}564565void CodeBlob::print_on(outputStream* st) const {566st->print_cr("[CodeBlob (" INTPTR_FORMAT ")]", p2i(this));567st->print_cr("Framesize: %d", _frame_size);568}569570void CodeBlob::print_value_on(outputStream* st) const {571st->print_cr("[CodeBlob]");572}573574void BufferBlob::verify() {575// unimplemented576}577578void BufferBlob::print_on(outputStream* st) const {579CodeBlob::print_on(st);580print_value_on(st);581}582583void BufferBlob::print_value_on(outputStream* st) const {584st->print_cr("BufferBlob (" INTPTR_FORMAT ") used for %s", p2i(this), name());585}586587void RuntimeStub::verify() {588// unimplemented589}590591void RuntimeStub::print_on(outputStream* st) const {592ttyLocker ttyl;593CodeBlob::print_on(st);594st->print("Runtime Stub (" INTPTR_FORMAT "): ", p2i(this));595st->print_cr("%s", name());596Disassembler::decode((CodeBlob*)this, st);597}598599void RuntimeStub::print_value_on(outputStream* st) const {600st->print("RuntimeStub (" INTPTR_FORMAT "): ", p2i(this)); st->print("%s", name());601}602603void SingletonBlob::verify() {604// unimplemented605}606607void SingletonBlob::print_on(outputStream* st) const {608ttyLocker ttyl;609CodeBlob::print_on(st);610st->print_cr("%s", name());611Disassembler::decode((CodeBlob*)this, st);612}613614void SingletonBlob::print_value_on(outputStream* st) const {615st->print_cr("%s", name());616}617618void DeoptimizationBlob::print_value_on(outputStream* st) const {619st->print_cr("Deoptimization (frame not available)");620}621622623