Path: blob/master/src/hotspot/share/code/codeBlob.hpp
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#ifndef SHARE_CODE_CODEBLOB_HPP25#define SHARE_CODE_CODEBLOB_HPP2627#include "asm/codeBuffer.hpp"28#include "compiler/compilerDefinitions.hpp"29#include "runtime/javaFrameAnchor.hpp"30#include "runtime/frame.hpp"31#include "runtime/handles.hpp"32#include "utilities/align.hpp"33#include "utilities/macros.hpp"3435class ImmutableOopMap;36class ImmutableOopMapSet;37class JNIHandleBlock;38class OopMapSet;3940// CodeBlob Types41// Used in the CodeCache to assign CodeBlobs to different CodeHeaps42struct CodeBlobType {43enum {44MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods)45MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods46NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs47All = 3, // All types (No code cache segmentation)48NumTypes = 4 // Number of CodeBlobTypes49};50};5152// CodeBlob - superclass for all entries in the CodeCache.53//54// Subtypes are:55// CompiledMethod : Compiled Java methods (include method that calls to native code)56// nmethod : JIT Compiled Java methods57// RuntimeBlob : Non-compiled method code; generated glue code58// BufferBlob : Used for non-relocatable code such as interpreter, stubroutines, etc.59// AdapterBlob : Used to hold C2I/I2C adapters60// VtableBlob : Used for holding vtable chunks61// MethodHandlesAdapterBlob : Used to hold MethodHandles adapters62// OptimizedEntryBlob : Used for upcalls from native code63// RuntimeStub : Call to VM runtime methods64// SingletonBlob : Super-class for all blobs that exist in only one instance65// DeoptimizationBlob : Used for deoptimization66// ExceptionBlob : Used for stack unrolling67// SafepointBlob : Used to handle illegal instruction exceptions68// UncommonTrapBlob : Used to handle uncommon traps69//70//71// Layout : continuous in the CodeCache72// - header73// - relocation74// - content space75// - instruction space76// - data space777879class CodeBlobLayout;80class OptimizedEntryBlob; // for as_optimized_entry_blob()81class JavaFrameAnchor; // for OptimizedEntryBlob::jfa_for_frame8283class CodeBlob {84friend class VMStructs;85friend class JVMCIVMStructs;86friend class CodeCacheDumper;8788protected:8990const CompilerType _type; // CompilerType91int _size; // total size of CodeBlob in bytes92int _header_size; // size of header (depends on subclass)93int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have94// not finished setting up their frame. Beware of pc's in95// that range. There is a similar range(s) on returns96// which we don't detect.97int _data_offset; // offset to where data region begins98int _frame_size; // size of stack frame99100address _code_begin;101address _code_end;102address _content_begin; // address to where content region begins (this includes consts, insts, stubs)103// address _content_end - not required, for all CodeBlobs _code_end == _content_end for now104address _data_end;105address _relocation_begin;106address _relocation_end;107108ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob109bool _caller_must_gc_arguments;110111const char* _name;112S390_ONLY(int _ctable_offset;)113114NOT_PRODUCT(CodeStrings _strings;)115116CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);117CodeBlob(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);118119public:120// Only used by unit test.121CodeBlob()122: _type(compiler_none) {}123124// Returns the space needed for CodeBlob125static unsigned int allocation_size(CodeBuffer* cb, int header_size);126static unsigned int align_code_offset(int offset);127128// Deletion129virtual void flush();130131// Typing132virtual bool is_buffer_blob() const { return false; }133virtual bool is_nmethod() const { return false; }134virtual bool is_runtime_stub() const { return false; }135virtual bool is_deoptimization_stub() const { return false; }136virtual bool is_uncommon_trap_stub() const { return false; }137virtual bool is_exception_stub() const { return false; }138virtual bool is_safepoint_stub() const { return false; }139virtual bool is_adapter_blob() const { return false; }140virtual bool is_vtable_blob() const { return false; }141virtual bool is_method_handles_adapter_blob() const { return false; }142virtual bool is_compiled() const { return false; }143virtual bool is_optimized_entry_blob() const { return false; }144145inline bool is_compiled_by_c1() const { return _type == compiler_c1; };146inline bool is_compiled_by_c2() const { return _type == compiler_c2; };147inline bool is_compiled_by_jvmci() const { return _type == compiler_jvmci; };148const char* compiler_name() const;149CompilerType compiler_type() const { return _type; }150151// Casting152nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; }153nmethod* as_nmethod() { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }154CompiledMethod* as_compiled_method_or_null() { return is_compiled() ? (CompiledMethod*) this : NULL; }155CompiledMethod* as_compiled_method() { assert(is_compiled(), "must be compiled"); return (CompiledMethod*) this; }156CodeBlob* as_codeblob_or_null() const { return (CodeBlob*) this; }157OptimizedEntryBlob* as_optimized_entry_blob() const { assert(is_optimized_entry_blob(), "must be entry blob"); return (OptimizedEntryBlob*) this; }158159// Boundaries160address header_begin() const { return (address) this; }161relocInfo* relocation_begin() const { return (relocInfo*) _relocation_begin; };162relocInfo* relocation_end() const { return (relocInfo*) _relocation_end; }163address content_begin() const { return _content_begin; }164address content_end() const { return _code_end; } // _code_end == _content_end is true for all types of blobs for now, it is also checked in the constructor165address code_begin() const { return _code_begin; }166address code_end() const { return _code_end; }167address data_end() const { return _data_end; }168169// This field holds the beginning of the const section in the old code buffer.170// It is needed to fix relocations of pc-relative loads when resizing the171// the constant pool or moving it.172S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; })173void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) }174175// Sizes176int size() const { return _size; }177int header_size() const { return _header_size; }178int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }179int content_size() const { return content_end() - content_begin(); }180int code_size() const { return code_end() - code_begin(); }181// Only used from CodeCache::free_unused_tail() after the Interpreter blob was trimmed182void adjust_size(size_t used) {183_size = (int)used;184_data_offset = (int)used;185_code_end = (address)this + used;186_data_end = (address)this + used;187}188189// Containment190bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }191bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }192bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); }193bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe &&194code_contains(addr) && addr >= code_begin() + _frame_complete_offset; }195int frame_complete_offset() const { return _frame_complete_offset; }196197// CodeCache support: really only used by the nmethods, but in order to get198// asserts and certain bookkeeping to work in the CodeCache they are defined199// virtual here.200virtual bool is_zombie() const { return false; }201virtual bool is_locked_by_vm() const { return false; }202203virtual bool is_unloaded() const { return false; }204virtual bool is_not_entrant() const { return false; }205206// GC support207virtual bool is_alive() const = 0;208209// OopMap for frame210ImmutableOopMapSet* oop_maps() const { return _oop_maps; }211void set_oop_maps(OopMapSet* p);212const ImmutableOopMap* oop_map_for_return_address(address return_address);213virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) = 0;214215// Frame support. Sizes are in word units.216int frame_size() const { return _frame_size; }217void set_frame_size(int size) { _frame_size = size; }218219// Returns true, if the next frame is responsible for GC'ing oops passed as arguments220bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }221222// Naming223const char* name() const { return _name; }224void set_name(const char* name) { _name = name; }225226// Debugging227virtual void verify() = 0;228virtual void print() const;229virtual void print_on(outputStream* st) const;230virtual void print_value_on(outputStream* st) const;231void dump_for_addr(address addr, outputStream* st, bool verbose) const;232void print_code();233234// Print the comment associated with offset on stream, if there is one235virtual void print_block_comment(outputStream* stream, address block_begin) const {236#ifndef PRODUCT237intptr_t offset = (intptr_t)(block_begin - code_begin());238_strings.print_block_comment(stream, offset);239#endif240}241242#ifndef PRODUCT243void set_strings(CodeStrings& strings) {244_strings.copy(strings);245}246#endif247};248249class CodeBlobLayout : public StackObj {250private:251int _size;252int _header_size;253int _relocation_size;254int _content_offset;255int _code_offset;256int _data_offset;257address _code_begin;258address _code_end;259address _content_begin;260address _content_end;261address _data_end;262address _relocation_begin;263address _relocation_end;264265public:266CodeBlobLayout(address code_begin, address code_end, address content_begin, address content_end, address data_end, address relocation_begin, address relocation_end) :267_size(0),268_header_size(0),269_relocation_size(0),270_content_offset(0),271_code_offset(0),272_data_offset(0),273_code_begin(code_begin),274_code_end(code_end),275_content_begin(content_begin),276_content_end(content_end),277_data_end(data_end),278_relocation_begin(relocation_begin),279_relocation_end(relocation_end)280{281}282283CodeBlobLayout(const address start, int size, int header_size, int relocation_size, int data_offset) :284_size(size),285_header_size(header_size),286_relocation_size(relocation_size),287_content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),288_code_offset(_content_offset),289_data_offset(data_offset)290{291assert(is_aligned(_relocation_size, oopSize), "unaligned size");292293_code_begin = (address) start + _code_offset;294_code_end = (address) start + _data_offset;295296_content_begin = (address) start + _content_offset;297_content_end = (address) start + _data_offset;298299_data_end = (address) start + _size;300_relocation_begin = (address) start + _header_size;301_relocation_end = _relocation_begin + _relocation_size;302}303304CodeBlobLayout(const address start, int size, int header_size, const CodeBuffer* cb) :305_size(size),306_header_size(header_size),307_relocation_size(align_up(cb->total_relocation_size(), oopSize)),308_content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),309_code_offset(_content_offset + cb->total_offset_of(cb->insts())),310_data_offset(_content_offset + align_up(cb->total_content_size(), oopSize))311{312assert(is_aligned(_relocation_size, oopSize), "unaligned size");313314_code_begin = (address) start + _code_offset;315_code_end = (address) start + _data_offset;316317_content_begin = (address) start + _content_offset;318_content_end = (address) start + _data_offset;319320_data_end = (address) start + _size;321_relocation_begin = (address) start + _header_size;322_relocation_end = _relocation_begin + _relocation_size;323}324325int size() const { return _size; }326int header_size() const { return _header_size; }327int relocation_size() const { return _relocation_size; }328int content_offset() const { return _content_offset; }329int code_offset() const { return _code_offset; }330int data_offset() const { return _data_offset; }331address code_begin() const { return _code_begin; }332address code_end() const { return _code_end; }333address data_end() const { return _data_end; }334address relocation_begin() const { return _relocation_begin; }335address relocation_end() const { return _relocation_end; }336address content_begin() const { return _content_begin; }337address content_end() const { return _content_end; }338};339340341class RuntimeBlob : public CodeBlob {342friend class VMStructs;343public:344345// Creation346// a) simple CodeBlob347// frame_complete is the offset from the beginning of the instructions348// to where the frame setup (from stackwalk viewpoint) is complete.349RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size);350351// b) full CodeBlob352RuntimeBlob(353const char* name,354CodeBuffer* cb,355int header_size,356int size,357int frame_complete,358int frame_size,359OopMapSet* oop_maps,360bool caller_must_gc_arguments = false361);362363// GC support364virtual bool is_alive() const = 0;365366void verify();367368// OopMap for frame369virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { ShouldNotReachHere(); }370371// Debugging372virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }373virtual void print_value_on(outputStream* st) const { CodeBlob::print_value_on(st); }374375// Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.376static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");377};378379class WhiteBox;380//----------------------------------------------------------------------------------------------------381// BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.382383class BufferBlob: public RuntimeBlob {384friend class VMStructs;385friend class AdapterBlob;386friend class VtableBlob;387friend class MethodHandlesAdapterBlob;388friend class OptimizedEntryBlob;389friend class WhiteBox;390391private:392// Creation support393BufferBlob(const char* name, int size);394BufferBlob(const char* name, int size, CodeBuffer* cb);395396// This ordinary operator delete is needed even though not used, so the397// below two-argument operator delete will be treated as a placement398// delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.399void operator delete(void* p);400void* operator new(size_t s, unsigned size) throw();401402public:403// Creation404static BufferBlob* create(const char* name, int buffer_size);405static BufferBlob* create(const char* name, CodeBuffer* cb);406407static void free(BufferBlob* buf);408409// Typing410virtual bool is_buffer_blob() const { return true; }411412// GC/Verification support413void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }414bool is_alive() const { return true; }415416void verify();417void print_on(outputStream* st) const;418void print_value_on(outputStream* st) const;419};420421422//----------------------------------------------------------------------------------------------------423// AdapterBlob: used to hold C2I/I2C adapters424425class AdapterBlob: public BufferBlob {426private:427AdapterBlob(int size, CodeBuffer* cb);428429public:430// Creation431static AdapterBlob* create(CodeBuffer* cb);432433// Typing434virtual bool is_adapter_blob() const { return true; }435};436437//---------------------------------------------------------------------------------------------------438class VtableBlob: public BufferBlob {439private:440VtableBlob(const char*, int);441442void* operator new(size_t s, unsigned size) throw();443444public:445// Creation446static VtableBlob* create(const char* name, int buffer_size);447448// Typing449virtual bool is_vtable_blob() const { return true; }450};451452//----------------------------------------------------------------------------------------------------453// MethodHandlesAdapterBlob: used to hold MethodHandles adapters454455class MethodHandlesAdapterBlob: public BufferBlob {456private:457MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {}458459public:460// Creation461static MethodHandlesAdapterBlob* create(int buffer_size);462463// Typing464virtual bool is_method_handles_adapter_blob() const { return true; }465};466467468//----------------------------------------------------------------------------------------------------469// RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine470471class RuntimeStub: public RuntimeBlob {472friend class VMStructs;473private:474// Creation support475RuntimeStub(476const char* name,477CodeBuffer* cb,478int size,479int frame_complete,480int frame_size,481OopMapSet* oop_maps,482bool caller_must_gc_arguments483);484485// This ordinary operator delete is needed even though not used, so the486// below two-argument operator delete will be treated as a placement487// delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.488void operator delete(void* p);489void* operator new(size_t s, unsigned size) throw();490491public:492// Creation493static RuntimeStub* new_runtime_stub(494const char* stub_name,495CodeBuffer* cb,496int frame_complete,497int frame_size,498OopMapSet* oop_maps,499bool caller_must_gc_arguments500);501502// Typing503bool is_runtime_stub() const { return true; }504505address entry_point() const { return code_begin(); }506507// GC/Verification support508void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }509bool is_alive() const { return true; }510511void verify();512void print_on(outputStream* st) const;513void print_value_on(outputStream* st) const;514};515516517//----------------------------------------------------------------------------------------------------518// Super-class for all blobs that exist in only one instance. Implements default behaviour.519520class SingletonBlob: public RuntimeBlob {521friend class VMStructs;522523protected:524// This ordinary operator delete is needed even though not used, so the525// below two-argument operator delete will be treated as a placement526// delete rather than an ordinary sized delete; see C++14 3.7.4.2/p2.527void operator delete(void* p);528void* operator new(size_t s, unsigned size) throw();529530public:531SingletonBlob(532const char* name,533CodeBuffer* cb,534int header_size,535int size,536int frame_size,537OopMapSet* oop_maps538)539: RuntimeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)540{};541542address entry_point() { return code_begin(); }543544bool is_alive() const { return true; }545546// GC/Verification support547void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }548void verify(); // does nothing549void print_on(outputStream* st) const;550void print_value_on(outputStream* st) const;551};552553554//----------------------------------------------------------------------------------------------------555// DeoptimizationBlob556557class DeoptimizationBlob: public SingletonBlob {558friend class VMStructs;559friend class JVMCIVMStructs;560private:561int _unpack_offset;562int _unpack_with_exception;563int _unpack_with_reexecution;564565int _unpack_with_exception_in_tls;566567#if INCLUDE_JVMCI568// Offsets when JVMCI calls uncommon_trap.569int _uncommon_trap_offset;570int _implicit_exception_uncommon_trap_offset;571#endif572573// Creation support574DeoptimizationBlob(575CodeBuffer* cb,576int size,577OopMapSet* oop_maps,578int unpack_offset,579int unpack_with_exception_offset,580int unpack_with_reexecution_offset,581int frame_size582);583584public:585// Creation586static DeoptimizationBlob* create(587CodeBuffer* cb,588OopMapSet* oop_maps,589int unpack_offset,590int unpack_with_exception_offset,591int unpack_with_reexecution_offset,592int frame_size593);594595// Typing596bool is_deoptimization_stub() const { return true; }597598// GC for args599void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }600601// Printing602void print_value_on(outputStream* st) const;603604address unpack() const { return code_begin() + _unpack_offset; }605address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }606address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }607608// Alternate entry point for C1 where the exception and issuing pc609// are in JavaThread::_exception_oop and JavaThread::_exception_pc610// instead of being in registers. This is needed because C1 doesn't611// model exception paths in a way that keeps these registers free so612// there may be live values in those registers during deopt.613void set_unpack_with_exception_in_tls_offset(int offset) {614_unpack_with_exception_in_tls = offset;615assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");616}617address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }618619#if INCLUDE_JVMCI620// Offsets when JVMCI calls uncommon_trap.621void set_uncommon_trap_offset(int offset) {622_uncommon_trap_offset = offset;623assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");624}625address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; }626627void set_implicit_exception_uncommon_trap_offset(int offset) {628_implicit_exception_uncommon_trap_offset = offset;629assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob");630}631address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }632#endif // INCLUDE_JVMCI633};634635636//----------------------------------------------------------------------------------------------------637// UncommonTrapBlob (currently only used by Compiler 2)638639#ifdef COMPILER2640641class UncommonTrapBlob: public SingletonBlob {642friend class VMStructs;643private:644// Creation support645UncommonTrapBlob(646CodeBuffer* cb,647int size,648OopMapSet* oop_maps,649int frame_size650);651652public:653// Creation654static UncommonTrapBlob* create(655CodeBuffer* cb,656OopMapSet* oop_maps,657int frame_size658);659660// GC for args661void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }662663// Typing664bool is_uncommon_trap_stub() const { return true; }665};666667668//----------------------------------------------------------------------------------------------------669// ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2)670671class ExceptionBlob: public SingletonBlob {672friend class VMStructs;673private:674// Creation support675ExceptionBlob(676CodeBuffer* cb,677int size,678OopMapSet* oop_maps,679int frame_size680);681682public:683// Creation684static ExceptionBlob* create(685CodeBuffer* cb,686OopMapSet* oop_maps,687int frame_size688);689690// GC for args691void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }692693// Typing694bool is_exception_stub() const { return true; }695};696#endif // COMPILER2697698699//----------------------------------------------------------------------------------------------------700// SafepointBlob: handles illegal_instruction exceptions during a safepoint701702class SafepointBlob: public SingletonBlob {703friend class VMStructs;704private:705// Creation support706SafepointBlob(707CodeBuffer* cb,708int size,709OopMapSet* oop_maps,710int frame_size711);712713public:714// Creation715static SafepointBlob* create(716CodeBuffer* cb,717OopMapSet* oop_maps,718int frame_size719);720721// GC for args722void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }723724// Typing725bool is_safepoint_stub() const { return true; }726};727728//----------------------------------------------------------------------------------------------------729730class ProgrammableUpcallHandler;731732class OptimizedEntryBlob: public BufferBlob {733friend class ProgrammableUpcallHandler;734private:735intptr_t _exception_handler_offset;736jobject _receiver;737ByteSize _frame_data_offset;738739OptimizedEntryBlob(const char* name, int size, CodeBuffer* cb, intptr_t exception_handler_offset,740jobject receiver, ByteSize frame_data_offset);741742struct FrameData {743JavaFrameAnchor jfa;744JavaThread* thread;745JNIHandleBlock* old_handles;746JNIHandleBlock* new_handles;747bool should_detach;748};749750// defined in frame_ARCH.cpp751FrameData* frame_data_for_frame(const frame& frame) const;752public:753// Creation754static OptimizedEntryBlob* create(const char* name, CodeBuffer* cb,755intptr_t exception_handler_offset, jobject receiver,756ByteSize frame_data_offset);757758address exception_handler() { return code_begin() + _exception_handler_offset; }759jobject receiver() { return _receiver; }760761JavaFrameAnchor* jfa_for_frame(const frame& frame) const;762763void oops_do(OopClosure* f, const frame& frame);764765// Typing766virtual bool is_optimized_entry_blob() const override { return true; }767};768769#endif // SHARE_CODE_CODEBLOB_HPP770771772