/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_CODE_NMETHOD_HPP
#define SHARE_VM_CODE_NMETHOD_HPP
#include "code/codeBlob.hpp"
#include "code/pcDesc.hpp"
// This class is used internally by nmethods, to cache
friend class VMStructs;
private:
int _count;
void set_pc_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _pc[index] = a; }
void set_handler_at(int index, address a) { assert(index >= 0 && index < cache_size,""); _handler[index] = a; }
public:
};
// cache pc descs found in earlier inquiries
friend class VMStructs;
private:
public:
};
// nmethods (native methods) are the compiled code versions of Java methods.
//
// An nmethod contains:
// - header (the nmethod structure)
// [Relocation]
// - relocation information
// - constant part (doubles, longs and floats used in nmethod)
// - oop table
// [Code]
// - code body
// - exception handler
// - stub code
// [Debugging information]
// - oop array
// - data array
// - pcs
// [Exception handler table]
// - handler entry point array
// [Implicit Null Pointer exception table]
// - implicit null table array
class Dependencies;
class ExceptionHandlerTable;
class ImplicitExceptionTable;
class AbstractCompiler;
class xmlStream;
friend class VMStructs;
friend class NMethodSweeper;
friend class CodeCache; // scavengable oops
private:
// Shared fields for all nmethod's
// To support simple linked-list chaining of nmethods:
// offsets for entry points
// Offsets for different nmethod parts
int _exception_offset;
// All deoptee's will resume execution at this location described by
// this offset.
int _deoptimize_offset;
// All deoptee's at a MethodHandle call site will resume execution
// at this location described by this offset.
// Offset of the unwind handler if it exists
#ifdef HAVE_DTRACE_H
int _trap_offset;
#endif // def HAVE_DTRACE_H
int _consts_offset;
int _stub_offset;
int _scopes_data_offset;
int _scopes_pcs_offset;
int _dependencies_offset;
int _nmethod_end_offset;
// location in frame (offset for sp) that deopt can store the original
// pc during a deopt.
int _orig_pc_offset;
// protected by CodeCache_lock
// used by jvmti to track if an unload event has been posted for this nmethod.
bool _unload_reported;
// set during construction
// Protected by Patching_lock
#ifdef ASSERT
#endif
enum { alive = 0,
// Nmethod Flushing lock. If non-zero, then the nmethod is not removed
// and is not made into a zombie. However, once the nmethod is made into
// a zombie, it will be locked one final time if CompiledMethodUnload
// event processing needs to be done.
// not_entrant method removal. Each mark_sweep pass will update
// this mark to current sweep invocation count if it is seen on the
// stack. An not_entrant method can be removed when there is no
// more activations, i.e., when the _stack_traversal_mark is less than
// current sweep traversal index.
long _stack_traversal_mark;
// These are used for compiled synchronized native methods to
// locate the owner and stack slot for the BasicLock so that we can
// properly revoke the bias of the owner if necessary. They are
// needed because there is no debug information for compiled native
// wrappers and the oop maps are insufficient to allow
// frame::retrieve_receiver() to work. Currently they are expected
// to be byte offsets from the Java stack pointer for maximum code
// sharing between platforms. Note that currently biased locking
// will never cause Class instances to be biased but this code
// handles the static synchronized case as well.
// JVMTI's GetLocalInstance() also uses these offsets to find the receiver
// for non-static native wrapper frames.
friend class nmethodLocker;
// For native wrappers
int nmethod_size,
int compile_id,
int frame_size,
#ifdef HAVE_DTRACE_H
// For native wrappers
int nmethod_size,
int frame_size);
#endif // def HAVE_DTRACE_H
// Creation support
int nmethod_size,
int compile_id,
int entry_bci,
int orig_pc_offset,
int frame_size,
int comp_level);
// helper methods
// Returns true if this thread changed the state of the nmethod or
// false if another thread performed the transition.
bool make_not_entrant_or_zombie(unsigned int state);
void inc_decompile_count();
// Used to manipulate the exception cache
// Inform external interfaces that a compiled method has been unloaded
void post_compiled_method_unload();
// Initailize fields to their default values
void init_defaults();
public:
// create nmethod with entry_bci
int compile_id,
int entry_bci,
int orig_pc_offset,
int frame_size,
int comp_level);
int compile_id,
int vep_offset,
int frame_complete,
int frame_size,
#ifdef HAVE_DTRACE_H
// The method we generate for a dtrace probe has to look
// like an nmethod as far as the rest of the system is concerned
// which is somewhat unfortunate.
int vep_offset,
int trap_offset,
int frame_complete,
int frame_size);
#endif // def HAVE_DTRACE_H
// accessors
// type info
bool is_nmethod() const { return true; }
bool is_compiled_by_c1() const;
bool is_compiled_by_c2() const;
bool is_compiled_by_shark() const;
// boundaries for different parts
address unwind_handler_begin () const { return _unwind_handler_offset != -1 ? (header_begin() + _unwind_handler_offset) : NULL; }
// Sizes
int scopes_pcs_size () const { return (intptr_t) scopes_pcs_end () - (intptr_t) scopes_pcs_begin (); }
int total_size () const;
// Containment
bool consts_contains (address addr) const { return consts_begin () <= addr && addr < consts_end (); }
bool scopes_data_contains (address addr) const { return scopes_data_begin () <= addr && addr < scopes_data_end (); }
bool scopes_pcs_contains (PcDesc* addr) const { return scopes_pcs_begin () <= addr && addr < scopes_pcs_end (); }
bool handler_table_contains(address addr) const { return handler_table_begin() <= addr && addr < handler_table_end(); }
bool nul_chk_table_contains(address addr) const { return nul_chk_table_begin() <= addr && addr < nul_chk_table_end(); }
// entry points
// flag accessing and manipulation
// Make the nmethod non entrant. The nmethod will continue to be
// alive. It is used when an uncommon trap happens. Returns true
// if this thread changed the state of the nmethod or false if
// another thread performed the transition.
// used by jvmti to track if the unload event has been reported
void set_has_flushed_dependencies() {
}
// Support for oops in scopes and relocs:
// Note: index 0 is reserved for null.
// relocation indexes are biased by 1 (because 0 is reserved)
}
// Relocation support
private:
public:
void verify_oop_relocations();
// Scavengable oop support
protected:
// assertion-checking and pruning logic uses the bits of _scavenge_root_state
#ifndef PRODUCT
// N.B. there is no positive marked query, and we only use the not_marked query for asserts.
#endif //PRODUCT
public:
// Sweeper support
// Exception cache support
// implicit exceptions support
// On-stack replacement support
address osr_entry() const { assert(is_osr_method(), "wrong kind of nmethod"); return _osr_entry_point; }
void invalidate_osr_method();
// tells whether frames described by this nmethod can be deoptimized
// note: native wrappers cannot be deoptimized.
// Inline cache support
void clear_inline_caches();
void cleanup_inline_caches();
}
// unlink and deallocate this nmethod
// Only NMethodSweeper class is expected to use this. NMethodSweeper is not
protected:
void flush();
public:
// When true is returned, it is unsafe to remove this nmethod even if
// it is a zombie, since the VM or the ServiceThread might still be
// using it.
// See comment at definition of _last_seen_on_stack
void mark_as_seen_on_stack();
bool can_not_entrant_be_converted();
// Evolution support. We make old (discarded) compiled methods point to new methodOops.
// GC support
bool unloading_occurred);
OopClosure* f);
bool detect_scavenge_root_oops();
bool test_set_oops_do_mark();
static void oops_do_marking_prologue();
static void oops_do_marking_epilogue();
// ScopeDesc for an instruction
private:
address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); }
return desc;
}
}
public:
// ScopeDesc retrieval operation
// pc_desc_near returns the first PcDesc at or after the givne pc.
public:
// copying of debugging information
// Deopt
// Return true is the PC is one would expect if the frame is being deopted.
// MethodHandle
// jvmti support:
void post_compiled_method_load_event();
// verify operations
void verify();
void verify_scopes();
// printing support
void print() const;
void print_code();
void print_nmethod(bool print_code);
// need to re-define this from CodeBlob else the overload hides it
// Logging
void log_new_nmethod() const;
void log_state_change() const;
// Prints block-level comments, including nmethod specific block labels:
}
// Prints a comment for one native instruction (reloc info, pc desc)
// Compiler task identification. Note that all OSR methods
// are numbered in an independent sequence if CICountOSR is true,
// and native method wrappers are also numbered independently if
// CICountNative is true.
const char* compile_kind() const;
// For debugging
// CompiledIC* IC_at(char* p) const;
// PrimitiveIC* primitiveIC_at(char* p) const;
// tells if any of this method's dependencies have been invalidated
// (this is expensive!)
bool check_all_dependencies();
// tells if this compiled method is dependent on the given changes,
// and the changes have invalidated it
// Evolution support. Tells if this compiled method is dependent on any of
// methods m() of class dependee, such that if m() in dependee is replaced,
// this compiled method will have to be deoptimized.
// Fast breakpoint support. Tells if this compiled method is
// dependent on the given method. Returns true if this nmethod
// corresponds to the given method as well.
// is it ok to patch at address?
// UseBiasedLocking support
return _native_receiver_sp_offset;
}
return _native_basic_lock_sp_offset;
}
// support for code generation
};
// Locks an nmethod so its code will not get removed and it will not
// be made into a zombie, even if it is a not_entrant method. After the
// nmethod becomes a zombie, if CompiledMethodUnload event processing
// needs to be done, then lock_nmethod() is used directly to keep the
// generated code from being reused too early.
public:
// note: nm can be NULL
// Only JvmtiDeferredEvent::compiled_method_unload_event()
// should pass zombie_ok == true.
}
};
#endif // SHARE_VM_CODE_NMETHOD_HPP