Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/code/codeBlob.hpp
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#ifndef SHARE_VM_CODE_CODEBLOB_HPP25#define SHARE_VM_CODE_CODEBLOB_HPP2627#include "asm/codeBuffer.hpp"28#include "compiler/oopMap.hpp"29#include "runtime/frame.hpp"30#include "runtime/handles.hpp"3132// CodeBlob Types33// Used in the CodeCache to assign CodeBlobs to different CodeHeaps34struct CodeBlobType {35enum {36All = 0, // All types (No code cache segmentation)37NumTypes = 1 // Number of CodeBlobTypes38};39};4041// CodeBlob - superclass for all entries in the CodeCache.42//43// Suptypes are:44// nmethod : Compiled Java methods (include method that calls to native code)45// RuntimeStub : Call to VM runtime methods46// DeoptimizationBlob : Used for deoptimizatation47// ExceptionBlob : Used for stack unrolling48// SafepointBlob : Used to handle illegal instruction exceptions49//50//51// Layout:52// - header53// - relocation54// - content space55// - instruction space56// - data space57class DeoptimizationBlob;5859class CodeBlob VALUE_OBJ_CLASS_SPEC {6061friend class VMStructs;6263private:64const char* _name;65int _size; // total size of CodeBlob in bytes66int _header_size; // size of header (depends on subclass)67int _relocation_size; // size of relocation68int _content_offset; // offset to where content region begins (this includes consts, insts, stubs)69int _code_offset; // offset to where instructions region begins (this includes insts, stubs)70int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have71// not finished setting up their frame. Beware of pc's in72// that range. There is a similar range(s) on returns73// which we don't detect.74int _data_offset; // offset to where data region begins75int _frame_size; // size of stack frame76OopMapSet* _oop_maps; // OopMap for this CodeBlob77CodeStrings _strings;7879public:80// Returns the space needed for CodeBlob81static unsigned int allocation_size(CodeBuffer* cb, int header_size);82static unsigned int align_code_offset(int offset);8384// Creation85// a) simple CodeBlob86// frame_complete is the offset from the beginning of the instructions87// to where the frame setup (from stackwalk viewpoint) is complete.88CodeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size);8990// b) full CodeBlob91CodeBlob(92const char* name,93CodeBuffer* cb,94int header_size,95int size,96int frame_complete,97int frame_size,98OopMapSet* oop_maps99);100101// Deletion102void flush();103104// Typing105virtual bool is_buffer_blob() const { return false; }106virtual bool is_nmethod() const { return false; }107virtual bool is_runtime_stub() const { return false; }108virtual bool is_deoptimization_stub() const { return false; }109virtual bool is_uncommon_trap_stub() const { return false; }110virtual bool is_exception_stub() const { return false; }111virtual bool is_safepoint_stub() const { return false; }112virtual bool is_adapter_blob() const { return false; }113virtual bool is_vtable_blob() const { return false; }114virtual bool is_method_handles_adapter_blob() const { return false; }115116virtual bool is_compiled_by_c2() const { return false; }117virtual bool is_compiled_by_c1() const { return false; }118119// Casting120nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; }121122// Boundaries123address header_begin() const { return (address) this; }124address header_end() const { return ((address) this) + _header_size; };125relocInfo* relocation_begin() const { return (relocInfo*) header_end(); };126relocInfo* relocation_end() const { return (relocInfo*)(header_end() + _relocation_size); }127address content_begin() const { return (address) header_begin() + _content_offset; }128address content_end() const { return (address) header_begin() + _data_offset; }129address code_begin() const { return (address) header_begin() + _code_offset; }130address code_end() const { return (address) header_begin() + _data_offset; }131address data_begin() const { return (address) header_begin() + _data_offset; }132address data_end() const { return (address) header_begin() + _size; }133134// Offsets135int relocation_offset() const { return _header_size; }136int content_offset() const { return _content_offset; }137int code_offset() const { return _code_offset; }138int data_offset() const { return _data_offset; }139140// Sizes141int size() const { return _size; }142int header_size() const { return _header_size; }143int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }144int content_size() const { return content_end() - content_begin(); }145int code_size() const { return code_end() - code_begin(); }146int data_size() const { return data_end() - data_begin(); }147148// Containment149bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }150bool relocation_contains(relocInfo* addr) const{ return relocation_begin() <= addr && addr < relocation_end(); }151bool content_contains(address addr) const { return content_begin() <= addr && addr < content_end(); }152bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }153bool data_contains(address addr) const { return data_begin() <= addr && addr < data_end(); }154bool contains(address addr) const { return content_contains(addr); }155bool is_frame_complete_at(address addr) const { return code_contains(addr) &&156addr >= code_begin() + _frame_complete_offset; }157158// CodeCache support: really only used by the nmethods, but in order to get159// asserts and certain bookkeeping to work in the CodeCache they are defined160// virtual here.161virtual bool is_zombie() const { return false; }162virtual bool is_locked_by_vm() const { return false; }163164virtual bool is_unloaded() const { return false; }165virtual bool is_not_entrant() const { return false; }166167// GC support168virtual bool is_alive() const = 0;169170// OopMap for frame171OopMapSet* oop_maps() const { return _oop_maps; }172void set_oop_maps(OopMapSet* p);173OopMap* oop_map_for_return_address(address return_address);174virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { ShouldNotReachHere(); }175176// Frame support177int frame_size() const { return _frame_size; }178void set_frame_size(int size) { _frame_size = size; }179180// Returns true, if the next frame is responsible for GC'ing oops passed as arguments181virtual bool caller_must_gc_arguments(JavaThread* thread) const { return false; }182183// Naming184const char* name() const { return _name; }185void set_name(const char* name) { _name = name; }186187// Debugging188virtual void verify();189void print() const { print_on(tty); }190virtual void print_on(outputStream* st) const;191virtual void print_value_on(outputStream* st) const;192void print_code();193194// Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.195static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = "");196197// Print the comment associated with offset on stream, if there is one198virtual void print_block_comment(outputStream* stream, address block_begin) const {199intptr_t offset = (intptr_t)(block_begin - code_begin());200_strings.print_block_comment(stream, offset);201}202203// Transfer ownership of comments to this CodeBlob204void set_strings(CodeStrings& strings) {205_strings.assign(strings);206}207};208209210//----------------------------------------------------------------------------------------------------211// BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.212213class BufferBlob: public CodeBlob {214friend class VMStructs;215friend class AdapterBlob;216friend class VtableBlob;217friend class MethodHandlesAdapterBlob;218friend class WhiteBox;219220private:221// Creation support222BufferBlob(const char* name, int size);223BufferBlob(const char* name, int size, CodeBuffer* cb);224225void* operator new(size_t s, unsigned size, bool is_critical = false) throw();226227public:228// Creation229static BufferBlob* create(const char* name, int buffer_size);230static BufferBlob* create(const char* name, CodeBuffer* cb);231232static void free(BufferBlob* buf);233234// Typing235virtual bool is_buffer_blob() const { return true; }236237// GC/Verification support238void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }239bool is_alive() const { return true; }240241void verify();242void print_on(outputStream* st) const;243void print_value_on(outputStream* st) const;244};245246247//----------------------------------------------------------------------------------------------------248// AdapterBlob: used to hold C2I/I2C adapters249250class AdapterBlob: public BufferBlob {251private:252AdapterBlob(int size, CodeBuffer* cb);253254public:255// Creation256static AdapterBlob* create(CodeBuffer* cb);257258// Typing259virtual bool is_adapter_blob() const { return true; }260};261262//---------------------------------------------------------------------------------------------------263class VtableBlob: public BufferBlob {264private:265VtableBlob(const char*, int);266267public:268// Creation269static VtableBlob* create(const char* name, int buffer_size);270271// Typing272virtual bool is_vtable_blob() const { return true; }273};274275//----------------------------------------------------------------------------------------------------276// MethodHandlesAdapterBlob: used to hold MethodHandles adapters277278class MethodHandlesAdapterBlob: public BufferBlob {279private:280MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {}281282public:283// Creation284static MethodHandlesAdapterBlob* create(int buffer_size);285286// Typing287virtual bool is_method_handles_adapter_blob() const { return true; }288};289290291//----------------------------------------------------------------------------------------------------292// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine293294class RuntimeStub: public CodeBlob {295friend class VMStructs;296private:297bool _caller_must_gc_arguments;298299// Creation support300RuntimeStub(301const char* name,302CodeBuffer* cb,303int size,304int frame_complete,305int frame_size,306OopMapSet* oop_maps,307bool caller_must_gc_arguments308);309310void* operator new(size_t s, unsigned size) throw();311312public:313// Creation314static RuntimeStub* new_runtime_stub(315const char* stub_name,316CodeBuffer* cb,317int frame_complete,318int frame_size,319OopMapSet* oop_maps,320bool caller_must_gc_arguments321);322323// Typing324bool is_runtime_stub() const { return true; }325326// GC support327bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }328329address entry_point() { return code_begin(); }330331// GC/Verification support332void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }333bool is_alive() const { return true; }334335void verify();336void print_on(outputStream* st) const;337void print_value_on(outputStream* st) const;338};339340341//----------------------------------------------------------------------------------------------------342// Super-class for all blobs that exist in only one instance. Implements default behaviour.343344class SingletonBlob: public CodeBlob {345friend class VMStructs;346347protected:348void* operator new(size_t s, unsigned size) throw();349350public:351SingletonBlob(352const char* name,353CodeBuffer* cb,354int header_size,355int size,356int frame_size,357OopMapSet* oop_maps358)359: CodeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)360{};361362address entry_point() { return code_begin(); }363364bool is_alive() const { return true; }365366void verify(); // does nothing367void print_on(outputStream* st) const;368void print_value_on(outputStream* st) const;369};370371372//----------------------------------------------------------------------------------------------------373// DeoptimizationBlob374375class DeoptimizationBlob: public SingletonBlob {376friend class VMStructs;377private:378int _unpack_offset;379int _unpack_with_exception;380int _unpack_with_reexecution;381382int _unpack_with_exception_in_tls;383384// Creation support385DeoptimizationBlob(386CodeBuffer* cb,387int size,388OopMapSet* oop_maps,389int unpack_offset,390int unpack_with_exception_offset,391int unpack_with_reexecution_offset,392int frame_size393);394395public:396// Creation397static DeoptimizationBlob* create(398CodeBuffer* cb,399OopMapSet* oop_maps,400int unpack_offset,401int unpack_with_exception_offset,402int unpack_with_reexecution_offset,403int frame_size404);405406// Typing407bool is_deoptimization_stub() const { return true; }408bool exception_address_is_unpack_entry(address pc) const {409address unpack_pc = unpack();410return (pc == unpack_pc || (pc + frame::pc_return_offset) == unpack_pc);411}412413414415416// GC for args417void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }418419// Printing420void print_value_on(outputStream* st) const;421422address unpack() const { return code_begin() + _unpack_offset; }423address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }424address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }425426// Alternate entry point for C1 where the exception and issuing pc427// are in JavaThread::_exception_oop and JavaThread::_exception_pc428// instead of being in registers. This is needed because C1 doesn't429// model exception paths in a way that keeps these registers free so430// there may be live values in those registers during deopt.431void set_unpack_with_exception_in_tls_offset(int offset) {432_unpack_with_exception_in_tls = offset;433assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");434}435address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }436};437438439//----------------------------------------------------------------------------------------------------440// UncommonTrapBlob (currently only used by Compiler 2)441442#ifdef COMPILER2443444class UncommonTrapBlob: public SingletonBlob {445friend class VMStructs;446private:447// Creation support448UncommonTrapBlob(449CodeBuffer* cb,450int size,451OopMapSet* oop_maps,452int frame_size453);454455public:456// Creation457static UncommonTrapBlob* create(458CodeBuffer* cb,459OopMapSet* oop_maps,460int frame_size461);462463// GC for args464void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }465466// Typing467bool is_uncommon_trap_stub() const { return true; }468};469470471//----------------------------------------------------------------------------------------------------472// ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2)473474class ExceptionBlob: public SingletonBlob {475friend class VMStructs;476private:477// Creation support478ExceptionBlob(479CodeBuffer* cb,480int size,481OopMapSet* oop_maps,482int frame_size483);484485public:486// Creation487static ExceptionBlob* create(488CodeBuffer* cb,489OopMapSet* oop_maps,490int frame_size491);492493// GC for args494void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }495496// Typing497bool is_exception_stub() const { return true; }498};499#endif // COMPILER2500501502//----------------------------------------------------------------------------------------------------503// SafepointBlob: handles illegal_instruction exceptions during a safepoint504505class SafepointBlob: public SingletonBlob {506friend class VMStructs;507private:508// Creation support509SafepointBlob(510CodeBuffer* cb,511int size,512OopMapSet* oop_maps,513int frame_size514);515516public:517// Creation518static SafepointBlob* create(519CodeBuffer* cb,520OopMapSet* oop_maps,521int frame_size522);523524// GC for args525void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }526527// Typing528bool is_safepoint_stub() const { return true; }529};530531#endif // SHARE_VM_CODE_CODEBLOB_HPP532533534